diff --git a/components/bt/host/bluedroid/api/esp_bluedroid_hci.c b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c index 59c1ab268b1..486af894490 100644 --- a/components/bt/host/bluedroid/api/esp_bluedroid_hci.c +++ b/components/bt/host/bluedroid/api/esp_bluedroid_hci.c @@ -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); diff --git a/components/bt/host/bluedroid/api/esp_gap_bt_api.c b/components/bt/host/bluedroid/api/esp_gap_bt_api.c index 49a3acd9727..fa833544136 100644 --- a/components/bt/host/bluedroid/api/esp_gap_bt_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_bt_api.c @@ -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; diff --git a/components/bt/host/bluedroid/api/esp_hidd_api.c b/components/bt/host/bluedroid/api/esp_hidd_api.c index fafda6ad581..85752546f7d 100644 --- a/components/bt/host/bluedroid/api/esp_hidd_api.c +++ b/components/bt/host/bluedroid/api/esp_hidd_api.c @@ -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; diff --git a/components/bt/host/bluedroid/api/esp_hidh_api.c b/components/bt/host/bluedroid/api/esp_hidh_api.c index 9b367ec3176..6ff561b1044 100644 --- a/components/bt/host/bluedroid/api/esp_hidh_api.c +++ b/components/bt/host/bluedroid/api/esp_hidh_api.c @@ -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; diff --git a/components/bt/host/bluedroid/api/esp_l2cap_bt_api.c b/components/bt/host/bluedroid/api/esp_l2cap_bt_api.c index 54f79396b3f..47de117fb83 100644 --- a/components/bt/host/bluedroid/api/esp_l2cap_bt_api.c +++ b/components/bt/host/bluedroid/api/esp_l2cap_bt_api.c @@ -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; diff --git a/components/bt/host/bluedroid/api/esp_spp_api.c b/components/bt/host/bluedroid/api/esp_spp_api.c index fe6b9e4db7e..cd6501b9f8f 100644 --- a/components/bt/host/bluedroid/api/esp_spp_api.c +++ b/components/bt/host/bluedroid/api/esp_spp_api.c @@ -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); @@ -33,8 +33,8 @@ esp_err_t esp_spp_register_callback(esp_spp_cb_t callback) 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 || @@ -56,7 +56,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; @@ -69,11 +69,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)); @@ -92,10 +96,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)) { @@ -117,8 +125,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; @@ -145,8 +153,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) { @@ -182,8 +190,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; @@ -196,8 +204,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)) { @@ -228,7 +236,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; @@ -240,7 +248,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; diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h index bbd6ec2893a..89ced2a6145 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_bt_api.h @@ -618,11 +618,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) { @@ -667,6 +667,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); diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 3199e8df2b9..cf67a8e7bea 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -3882,7 +3882,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 ) { diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index de753df9253..bfd81a04c53 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -583,7 +583,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) { @@ -593,11 +592,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) @@ -615,7 +611,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) { @@ -628,7 +623,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); } - } diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c index cf60dc13705..158c3483d17 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_co.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_co.c @@ -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__); } diff --git a/components/bt/host/bluedroid/bta/hd/bta_hd_act.c b/components/bt/host/bluedroid/bta/hd/bta_hd_act.c index 18bc0493801..16937bbd2c3 100644 --- a/components/bt/host/bluedroid/bta/hd/bta_hd_act.c +++ b/components/bt/host/bluedroid/bta/hd/bta_hd_act.c @@ -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) { diff --git a/components/bt/host/bluedroid/bta/hd/bta_hd_api.c b/components/bt/host/bluedroid/bta/hd/bta_hd_api.c index ea27978984c..89b91e2f85c 100644 --- a/components/bt/host/bluedroid/bta/hd/bta_hd_api.c +++ b/components/bt/host/bluedroid/bta/hd/bta_hd_api.c @@ -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, ¶m); + } + 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); } diff --git a/components/bt/host/bluedroid/bta/hd/bta_hd_main.c b/components/bt/host/bluedroid/bta/hd/bta_hd_main.c index 2379aefd678..c8681461070 100644 --- a/components/bt/host/bluedroid/bta/hd/bta_hd_main.c +++ b/components/bt/host/bluedroid/bta/hd/bta_hd_main.c @@ -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; diff --git a/components/bt/host/bluedroid/bta/hh/bta_hh_act.c b/components/bt/host/bluedroid/bta/hh/bta_hh_act.c index 568003dbccb..7addc2f41db 100644 --- a/components/bt/host/bluedroid/bta/hh/bta_hh_act.c +++ b/components/bt/host/bluedroid/bta/hh/bta_hh_act.c @@ -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", @@ -831,7 +838,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) */ @@ -957,6 +964,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 */ @@ -1003,6 +1011,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 { diff --git a/components/bt/host/bluedroid/bta/hh/bta_hh_api.c b/components/bt/host/bluedroid/bta/hh/bta_hh_api.c index 8550a0e06e1..4dc676c0a80 100644 --- a/components/bt/host/bluedroid/bta/hh/bta_hh_api.c +++ b/components/bt/host/bluedroid/bta/hh/bta_hh_api.c @@ -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; diff --git a/components/bt/host/bluedroid/bta/hh/bta_hh_main.c b/components/bt/host/bluedroid/bta/hh/bta_hh_main.c index 48c25c3eacc..e47ddec0891 100644 --- a/components/bt/host/bluedroid/bta/hh/bta_hh_main.c +++ b/components/bt/host/bluedroid/bta/hh/bta_hh_main.c @@ -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: diff --git a/components/bt/host/bluedroid/bta/hh/bta_hh_utils.c b/components/bt/host/bluedroid/bta/hh/bta_hh_utils.c index 6650e404c65..9768cbb0260 100644 --- a/components/bt/host/bluedroid/bta/hh/bta_hh_utils.c +++ b/components/bt/host/bluedroid/bta/hh/bta_hh_utils.c @@ -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)) { diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c index 78fc08b04d1..b803de9896e 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_act.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_act.c @@ -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, ¶m, 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, ¶m, 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; diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_api.c b/components/bt/host/bluedroid/bta/jv/bta_jv_api.c index 4909859772f..093b79bd86c 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_api.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_api.c @@ -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)); diff --git a/components/bt/host/bluedroid/bta/jv/bta_jv_main.c b/components/bt/host/bluedroid/bta/jv/bta_jv_main.c index 69324a8625a..577111b4a34 100644 --- a/components/bt/host/bluedroid/bta/jv/bta_jv_main.c +++ b/components/bt/host/bluedroid/bta/jv/bta_jv_main.c @@ -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 diff --git a/components/bt/host/bluedroid/btc/core/btc_util.c b/components/bt/host/bluedroid/btc/core/btc_util.c index e22efce3a8d..2aaed2a17e0 100644 --- a/components/bt/host/bluedroid/btc/core/btc_util.c +++ b/components/bt/host/bluedroid/btc/core/btc_util.c @@ -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; diff --git a/components/bt/host/bluedroid/btc/include/btc/btc_util.h b/components/bt/host/bluedroid/btc/include/btc/btc_util.h index 1b96d6f48ca..bd5741a77d8 100644 --- a/components/bt/host/bluedroid/btc/include/btc/btc_util.h +++ b/components/bt/host/bluedroid/btc/include/btc/btc_util.h @@ -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); diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c index 7102cf9e717..8ff3b7c6983 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_bt.c @@ -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, ¶m); + 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, ¶m); + } } 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, ¶m); - } 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, ¶m); + } 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, ¶m); 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, ¶m); } @@ -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, ¶m); 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, ¶m, 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}; @@ -1233,7 +1276,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: { @@ -1345,7 +1388,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; @@ -1536,6 +1579,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)); @@ -1596,6 +1640,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; diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c index 4e23c7f8e31..eae8a1eeb77 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c @@ -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, ¶m); } @@ -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, ¶m); } @@ -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); diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c index 9a787421323..cda6db3dff2 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c @@ -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, ¶m); } @@ -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, ¶m); } @@ -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, ¶m); @@ -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, ¶m); } @@ -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(¶m, &p_data->dscp_info); + if (!btc_hh_cb_copy_hid_info(¶m, &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, ¶m); diff --git a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c index ed31e6cf768..485ae797db4 100644 --- a/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c +++ b/components/bt/host/bluedroid/btc/profile/std/l2cap/btc_l2cap.c @@ -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, ¶m); + } 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, ¶m); } @@ -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, ¶m); @@ -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, ¶m); } @@ -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,6 +1364,12 @@ static void btc_l2cap_vfs_register(void) break; } + if (l2cap_local_param.l2cap_vfs_id != -1) { + BTC_TRACE_WARNING("l2cap vfs id already registered\n"); + ret = ESP_BT_L2CAP_SUCCESS; + break; + } + static const esp_vfs_fs_ops_t vfs = { .write = l2cap_vfs_write, .close = l2cap_vfs_close, diff --git a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c index 85cba1601af..3950b3f3f3d 100644 --- a/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c +++ b/components/bt/host/bluedroid/btc/profile/std/spp/btc_spp.c @@ -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, ¶m); } @@ -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, ¶m); } @@ -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, ¶m); @@ -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; + } + static const esp_vfs_fs_ops_t vfs = { .write = spp_vfs_write, .close = spp_vfs_close, diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index 2d0dec20f92..e82b6d1f152 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -2489,11 +2489,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 diff --git a/components/bt/host/bluedroid/device/controller.c b/components/bt/host/bluedroid/device/controller.c index d2076102e9b..dc3bce3bf9c 100644 --- a/components/bt/host/bluedroid/device/controller.c +++ b/components/bt/host/bluedroid/device/controller.c @@ -438,6 +438,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); @@ -609,6 +615,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, diff --git a/components/bt/host/bluedroid/device/include/device/controller.h b/components/bt/host/bluedroid/device/include/device/controller.h index 610c9afafc7..39258394ecb 100644 --- a/components/bt/host/bluedroid/device/include/device/controller.h +++ b/components/bt/host/bluedroid/device/include/device/controller.h @@ -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); diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 26f13d8fff5..d24f558b153 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -293,8 +293,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); @@ -464,6 +470,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--; diff --git a/components/bt/host/bluedroid/hci/hci_layer.c b/components/bt/host/bluedroid/hci/hci_layer.c index f2286651a76..9e6435b10fb 100644 --- a/components/bt/host/bluedroid/hci/hci_layer.c +++ b/components/bt/host/bluedroid/hci/hci_layer.c @@ -222,14 +222,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)) @@ -412,10 +416,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) { @@ -424,9 +434,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); } } @@ -749,11 +757,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 diff --git a/components/bt/host/bluedroid/hci/hci_packet_factory.c b/components/bt/host/bluedroid/hci/hci_packet_factory.c index f710046d0e4..abee5fa3b3a 100644 --- a/components/bt/host/bluedroid/hci/hci_packet_factory.c +++ b/components/bt/host/bluedroid/hci/hci_packet_factory.c @@ -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) diff --git a/components/bt/host/bluedroid/hci/hci_packet_parser.c b/components/bt/host/bluedroid/hci/hci_packet_parser.c index 87c8499f8e6..62c182e944a 100644 --- a/components/bt/host/bluedroid/hci/hci_packet_parser.c +++ b/components/bt/host/bluedroid/hci/hci_packet_parser.c @@ -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); diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index cc22fb5e4e8..ca75ff92623 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -54,6 +54,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 */ @@ -61,7 +62,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; @@ -90,14 +91,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); @@ -189,38 +192,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; } @@ -399,8 +402,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); @@ -601,7 +608,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) /* Remove and free the ACL connection data */ list_remove(btm_cb.p_acl_db_list, p); @@ -704,14 +714,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); } } } @@ -910,7 +919,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); @@ -952,14 +961,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", @@ -1060,10 +1075,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) /******************************************************************************* @@ -1076,23 +1093,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) { @@ -1137,6 +1163,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; @@ -1186,7 +1215,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; @@ -1244,7 +1273,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 */ @@ -1303,6 +1332,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); @@ -1319,6 +1353,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)); @@ -1346,7 +1381,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 */ @@ -1522,7 +1557,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; } @@ -1533,10 +1571,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"); @@ -1729,7 +1767,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; } @@ -1755,13 +1793,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 @@ -1983,13 +2020,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; } @@ -2030,7 +2066,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); } @@ -2132,7 +2168,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; @@ -2156,10 +2193,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) @@ -2211,13 +2249,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); @@ -2230,12 +2268,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; @@ -2248,7 +2290,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 */ @@ -2262,8 +2304,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; } } @@ -2293,6 +2337,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) { @@ -2480,7 +2525,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"); @@ -2502,10 +2547,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; } @@ -2528,11 +2575,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; @@ -2588,6 +2634,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 */ @@ -2622,8 +2669,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); } } } @@ -2774,23 +2822,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); } @@ -2800,13 +2848,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); } } } @@ -2821,8 +2869,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) } diff --git a/components/bt/host/bluedroid/stack/btm/btm_bredr_pwr_ctrl.c b/components/bt/host/bluedroid/stack/btm/btm_bredr_pwr_ctrl.c index 77ebbb1e6a4..af8bc85a6ac 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_bredr_pwr_ctrl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_bredr_pwr_ctrl.c @@ -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) diff --git a/components/bt/host/bluedroid/stack/btm/btm_dev.c b/components/bt/host/bluedroid/stack/btm/btm_dev.c index d272c47a2f4..afc2685cf04 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/host/bluedroid/stack/btm/btm_dev.c @@ -22,6 +22,7 @@ * ******************************************************************************/ + #include #include #include //#include @@ -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; } @@ -470,6 +476,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; @@ -566,16 +579,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); } @@ -764,6 +779,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); } /******************************************************************************* @@ -775,5 +791,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; + } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index c58e22bf11f..e711ff9806d 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -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); } } @@ -633,8 +644,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); } @@ -643,6 +652,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); } @@ -689,7 +700,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) @@ -723,6 +734,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) */ @@ -767,51 +782,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; @@ -820,7 +852,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 */ } @@ -895,16 +927,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); @@ -930,16 +975,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); } @@ -979,6 +1030,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 @@ -1063,7 +1122,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; @@ -1140,6 +1199,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); @@ -1159,7 +1219,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; @@ -1230,6 +1290,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); } diff --git a/components/bt/host/bluedroid/stack/btm/btm_inq.c b/components/bt/host/bluedroid/stack/btm/btm_inq.c index 4a2e7201c76..d5c196dec89 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_inq.c +++ b/components/bt/host/bluedroid/stack/btm/btm_inq.c @@ -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; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_main.c b/components/bt/host/bluedroid/stack/btm/btm_main.c index 5392ac4b557..9fabc529a40 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_main.c +++ b/components/bt/host/bluedroid/stack/btm/btm_main.c @@ -25,6 +25,7 @@ #include "stack/bt_types.h" #include "common/bt_target.h" +#include #include #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 diff --git a/components/bt/host/bluedroid/stack/btm/btm_pm.c b/components/bt/host/bluedroid/stack/btm/btm_pm.c index 9391976a4e6..7824a14019a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_pm.c +++ b/components/bt/host/bluedroid/stack/btm/btm_pm.c @@ -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; diff --git a/components/bt/host/bluedroid/stack/btm/btm_sec.c b/components/bt/host/bluedroid/stack/btm/btm_sec.c index b6f9f5194cd..52461ec9bfc 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sec.c @@ -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) @@ -755,6 +773,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++; } } @@ -791,6 +812,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++; } } @@ -881,12 +905,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) { @@ -1023,7 +1046,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 @@ -1322,8 +1346,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) @@ -1401,7 +1425,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"); @@ -1416,6 +1439,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); @@ -1441,9 +1469,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); } } @@ -1491,14 +1527,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; @@ -1635,7 +1673,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) */ @@ -1957,7 +1997,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++) { @@ -2015,6 +2055,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 */ @@ -2127,6 +2168,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; @@ -2462,6 +2509,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); @@ -2548,8 +2601,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) { @@ -2901,7 +2960,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; @@ -3022,7 +3081,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) @@ -3030,20 +3089,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, @@ -3261,6 +3318,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]); @@ -3306,6 +3367,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); @@ -3664,11 +3730,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; @@ -3690,13 +3760,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); @@ -4283,6 +4357,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"); @@ -4409,8 +4487,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 */ @@ -4546,7 +4622,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); } @@ -4625,8 +4701,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 */ @@ -4673,8 +4749,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 @@ -4777,6 +4851,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. */ @@ -4923,6 +5001,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", @@ -4965,7 +5044,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; @@ -5137,6 +5216,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; @@ -5487,7 +5572,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; @@ -5539,7 +5624,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 @@ -5693,6 +5780,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 */ @@ -5759,15 +5850,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 } @@ -5790,7 +5883,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); } @@ -5941,9 +6034,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); @@ -5954,7 +6052,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)) ) { @@ -5970,30 +6067,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; } @@ -6012,6 +6109,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); @@ -6049,10 +6150,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; } @@ -6183,7 +6289,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)); } } } diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 0d0120051e3..b6a1f657528 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -1097,7 +1097,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); @@ -1109,8 +1109,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 @@ -1147,12 +1147,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 ++ @@ -1319,8 +1319,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); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 5c44f26d21e..6634e24d684 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -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); @@ -1189,9 +1190,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) @@ -1353,10 +1354,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); @@ -2446,9 +2447,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); } /******************************************************************************* @@ -2474,9 +2475,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) */ diff --git a/components/bt/host/bluedroid/stack/gap/gap_api.c b/components/bt/host/bluedroid/stack/gap/gap_api.c index 75d5b5d1db2..101469f4b6c 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_api.c +++ b/components/bt/host/bluedroid/stack/gap/gap_api.c @@ -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; } diff --git a/components/bt/host/bluedroid/stack/gap/gap_conn.c b/components/bt/host/bluedroid/stack/gap/gap_conn.c index 61a4684daf8..8669b991411 100644 --- a/components/bt/host/bluedroid/stack/gap/gap_conn.c +++ b/components/bt/host/bluedroid/stack/gap/gap_conn.c @@ -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 */ diff --git a/components/bt/host/bluedroid/stack/hcic/hcicmds.c b/components/bt/host/bluedroid/stack/hcic/hcicmds.c index 3839fe316e7..fea8bbf1eab 100644 --- a/components/bt/host/bluedroid/stack/hcic/hcicmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hcicmds.c @@ -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, diff --git a/components/bt/host/bluedroid/stack/hid/hidd_api.c b/components/bt/host/bluedroid/stack/hid/hidd_api.c index 347ef7ebc28..368d6eee6fa 100644 --- a/components/bt/host/bluedroid/stack/hid/hidd_api.c +++ b/components/bt/host/bluedroid/stack/hid/hidd_api.c @@ -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; diff --git a/components/bt/host/bluedroid/stack/hid/hidd_conn.c b/components/bt/host/bluedroid/stack/hid/hidd_conn.c index 576d82bdbfb..2d4f878ddf9 100644 --- a/components/bt/host/bluedroid/stack/hid/hidd_conn.c +++ b/components/bt/host/bluedroid/stack/hid/hidd_conn.c @@ -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; } diff --git a/components/bt/host/bluedroid/stack/hid/hidh_api.c b/components/bt/host/bluedroid/stack/hid/hidh_api.c index ec072845ea6..944615e3f37 100644 --- a/components/bt/host/bluedroid/stack/hid/hidh_api.c +++ b/components/bt/host/bluedroid/stack/hid/hidh_api.c @@ -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; } diff --git a/components/bt/host/bluedroid/stack/hid/hidh_conn.c b/components/bt/host/bluedroid/stack/hid/hidh_conn.c index 170bfce7e92..57697c9b9d4 100644 --- a/components/bt/host/bluedroid/stack/hid/hidh_conn.c +++ b/components/bt/host/bluedroid/stack/hid/hidh_conn.c @@ -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) diff --git a/components/bt/host/bluedroid/stack/include/stack/gap_api.h b/components/bt/host/bluedroid/stack/include/stack/gap_api.h index 81d353d0228..527a7903c15 100644 --- a/components/bt/host/bluedroid/stack/include/stack/gap_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/gap_api.h @@ -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); diff --git a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h index 6622e6bd434..a52740054b3 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcidefs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcidefs.h @@ -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) diff --git a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h index 30b2f5794e8..92166d2eecb 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h +++ b/components/bt/host/bluedroid/stack/include/stack/hcimsgs.h @@ -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 diff --git a/components/bt/host/bluedroid/stack/include/stack/hidd_api.h b/components/bt/host/bluedroid/stack/include/stack/hidd_api.h index 3e99db9da15..69f0380bf36 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hidd_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/hidd_api.h @@ -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); /******************************************************************************* * diff --git a/components/bt/host/bluedroid/stack/include/stack/hidh_api.h b/components/bt/host/bluedroid/stack/include/stack/hidh_api.h index 2445163db5a..87103c7b096 100644 --- a/components/bt/host/bluedroid/stack/include/stack/hidh_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/hidh_api.h @@ -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 ); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h index 705b11048bd..2bcd20ad29d 100644 --- a/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h +++ b/components/bt/host/bluedroid/stack/l2cap/include/l2c_int.h @@ -755,7 +755,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); diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c index c0487f16a5c..f5cb85b48f9 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_api.c @@ -285,8 +285,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); + } } @@ -434,8 +440,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) { @@ -684,7 +695,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])), @@ -716,9 +728,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); @@ -730,7 +745,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; } @@ -829,7 +844,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) { @@ -945,6 +960,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); } @@ -1046,7 +1063,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))); @@ -1171,14 +1188,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]", @@ -1191,8 +1207,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]); @@ -1200,6 +1214,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; } } } @@ -2020,7 +2035,7 @@ BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle transport = BT_TRANSPORT_LE; } #endif - if (fixed_cid L2CAP_LAST_FIXED_CHNL)) { return (FALSE); } @@ -2066,6 +2081,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) { @@ -2166,7 +2186,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; diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_csm.c b/components/bt/host/bluedroid/stack/l2cap/l2c_csm.c index 9f6192102f4..528d1a71555 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_csm.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_csm.c @@ -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) /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_fcr.c b/components/bt/host/bluedroid/stack/l2cap/l2c_fcr.c index 684825f487f..92105a7d7be 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_fcr.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_fcr.c @@ -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; } } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index 1a74d33dcec..df5de6d6eb3 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -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) { @@ -606,10 +608,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); @@ -780,6 +784,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 */ @@ -802,8 +807,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; } } } @@ -837,6 +844,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; @@ -975,7 +986,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 @@ -984,7 +995,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; @@ -1032,10 +1043,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); } } @@ -1395,7 +1405,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 */ @@ -1636,7 +1655,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; diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c index 221109a1b66..f552a57ab56 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_main.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_main.c @@ -358,8 +358,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; @@ -460,8 +461,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; @@ -534,14 +537,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); @@ -666,13 +669,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); @@ -869,10 +871,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; } @@ -937,15 +940,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; diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c b/components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c index d3a108bdc44..c260f1442d8 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_ucd.c @@ -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); } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c index 2cf6443dccb..a64cdfef63b 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_utils.c @@ -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"); } @@ -444,10 +448,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); } @@ -654,7 +662,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; } @@ -711,7 +719,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; } @@ -809,7 +817,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; } @@ -1002,6 +1010,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); @@ -1021,7 +1033,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); @@ -1211,14 +1223,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 { @@ -1468,6 +1477,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) ) { @@ -1523,7 +1536,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; + } } } } @@ -1834,6 +1850,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) @@ -2598,7 +2615,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) { @@ -2686,7 +2706,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) @@ -2765,9 +2785,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; @@ -2844,11 +2864,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; @@ -2955,7 +2970,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) { @@ -2977,7 +2993,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, @@ -3165,6 +3181,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 ) { @@ -3290,6 +3311,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)) { @@ -3490,11 +3516,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; } diff --git a/components/bt/host/bluedroid/stack/l2cap/l2cap_client.c b/components/bt/host/bluedroid/stack/l2cap/l2cap_client.c index 3e8ae9c51f9..a4bf820903e 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2cap_client.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2cap_client.c @@ -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) {