Merge remote-tracking branch 'espressif/master'

This commit is contained in:
Mark Webb-Johnson 2018-02-13 13:27:55 +08:00
commit 8d8d62da9e
335 changed files with 16772 additions and 9415 deletions

3
.gitignore vendored
View file

@ -18,6 +18,9 @@ GPATH
# eclipse setting
.settings
# MacOS directory files
.DS_Store
# Example project files
examples/**/sdkconfig
examples/**/sdkconfig.old

View file

@ -446,22 +446,21 @@ assign_test:
- components/idf_test/*/CIConfigs
- components/idf_test/*/TC.sqlite
- $EXAMPLE_CONFIG_OUTPUT_PATH
- tools/unit-test-app/output
expire_in: 1 mos
before_script: *add_gitlab_key_before
script:
# first move test bins together: test_bins/CHIP_SDK/TestApp/bin_files
- mkdir -p $OUTPUT_BIN_PATH
# copy and rename folder name to "UT_config"
- for CONFIG in $(ls $UT_BIN_PATH); do cp -r "$UT_BIN_PATH/$CONFIG" "$OUTPUT_BIN_PATH/UT_$CONFIG"; done
- cp -r SSC/ssc_bin/* $OUTPUT_BIN_PATH
# assign example tests
- python $TEST_FW_PATH/CIAssignExampleTest.py $IDF_PATH/examples $IDF_PATH/.gitlab-ci.yml $EXAMPLE_CONFIG_OUTPUT_PATH
# assign unit test cases
- python $TEST_FW_PATH/CIAssignUnitTest.py $IDF_PATH/components/idf_test/unit_test/TestCaseAll.yml $IDF_PATH/.gitlab-ci.yml $IDF_PATH/components/idf_test/unit_test/CIConfigs
# clone test script to assign tests
- git clone $TEST_SCRIPT_REPOSITORY
- cd auto_test_script
- python $CHECKOUT_REF_SCRIPT auto_test_script
# assign unit test cases
- python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/unit_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/test_bins
# assgin integration test cases
- python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/integration_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/test_bins
@ -493,6 +492,17 @@ assign_test:
# run test
- python Runner.py $TEST_CASE_PATH -c $CONFIG_FILE
.unit_test_template: &unit_test_template
<<: *example_test_template
stage: unit_test
dependencies:
- assign_test
variables:
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
TEST_CASE_PATH: "$CI_PROJECT_DIR/tools/unit-test-app"
CONFIG_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/CIConfigs/$CI_JOB_NAME.yml"
LOG_PATH: "$CI_PROJECT_DIR/TEST_LOGS"
.test_template: &test_template
stage: test
when: on_success
@ -530,18 +540,6 @@ assign_test:
# run test
- python CIRunner.py -l "$LOG_PATH/$CI_JOB_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE
# template for unit test jobs
.unit_test_template: &unit_test_template
<<: *test_template
allow_failure: false
stage: unit_test
variables:
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF"
LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test"
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/ModuleDefinition.yml"
CONFIG_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/CIConfigs/$CI_JOB_NAME.yml"
nvs_compatible_test:
<<: *test_template
artifacts:

4
.gitmodules vendored
View file

@ -33,3 +33,7 @@
[submodule "components/spiffs/spiffs"]
path = components/spiffs/spiffs
url = https://github.com/pellepl/spiffs.git
[submodule "components/json/cJSON"]
path = components/json/cJSON
url = https://github.com/DaveGamble/cJSON.git

View file

@ -64,33 +64,37 @@ config SYSVIEW_ENABLE
Enables supporrt for SEGGER SystemView tracing functionality.
choice SYSVIEW_TS_SOURCE
prompt "ESP32 timer to use as SystemView timestamp source"
prompt "Timer to use as timestamp source"
depends on SYSVIEW_ENABLE
default SYSVIEW_TS_SOURCE_TIMER_00
default SYSVIEW_TS_SOURCE_CCOUNT if FREERTOS_UNICORE && !PM_ENABLE
default SYSVIEW_TS_SOURCE_TIMER_00 if !FREERTOS_UNICORE && !PM_ENABLE
default SYSVIEW_TS_SOURCE_ESP_TIMER if PM_ENABLE
help
SystemView needs to use a hardware timer as the source of timestamps
when tracing
This option selects HW timer for it.
when tracing. This option selects the timer for it.
config SYSVIEW_TS_SOURCE_CCOUNT
bool "CPU cycle counter (CCOUNT)"
depends on FREERTOS_UNICORE && !PM_ENABLE
config SYSVIEW_TS_SOURCE_TIMER_00
bool "Timer 0, Group 0"
help
Select this to use timer 0 of group 0
depends on !PM_ENABLE
config SYSVIEW_TS_SOURCE_TIMER_01
bool "Timer 1, Group 0"
help
Select this to use timer 1 of group 0
depends on !PM_ENABLE
config SYSVIEW_TS_SOURCE_TIMER_10
bool "Timer 0, Group 1"
help
Select this to use timer 0 of group 1
depends on !PM_ENABLE
config SYSVIEW_TS_SOURCE_TIMER_11
bool "Timer 1, Group 1"
help
Select this to use timer 1 of group 1
depends on !PM_ENABLE
config SYSVIEW_TS_SOURCE_ESP_TIMER
bool "esp_timer high resolution timer"
endchoice

View file

@ -64,9 +64,6 @@ Revision: $Rev: 3734 $
#include "freertos/FreeRTOS.h"
#include "SEGGER_SYSVIEW.h"
#include "rom/ets_sys.h"
#if CONFIG_FREERTOS_UNICORE == 0
#include "driver/timer.h"
#endif
#include "esp_app_trace.h"
#include "esp_app_trace_util.h"
#include "esp_intr_alloc.h"
@ -86,10 +83,49 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
// The target device name
#define SYSVIEW_DEVICE_NAME "ESP32"
// Determine which timer to use as timestamp source
#if CONFIG_SYSVIEW_TS_SOURCE_CCOUNT
#define TS_USE_CCOUNT 1
#elif CONFIG_SYSVIEW_TS_SOURCE_ESP_TIMER
#define TS_USE_ESP_TIMER 1
#else
#define TS_USE_TIMERGROUP 1
#endif
#if TS_USE_TIMERGROUP
#include "driver/timer.h"
// Timer group timer divisor
#define SYSVIEW_TIMER_DIV 2
// Frequency of the timestamp.
#define SYSVIEW_TIMESTAMP_FREQ (esp_clk_apb_freq() / SYSVIEW_TIMER_DIV)
// Timer ID and group ID
#if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_01)
#define TS_TIMER_ID 0
#else
#define TS_TIMER_ID 1
#endif // TIMER_00 || TIMER_01
#if defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_00) || defined(CONFIG_SYSVIEW_TS_SOURCE_TIMER_10)
#define TS_TIMER_GROUP 0
#else
#define TS_TIMER_GROUP 1
#endif // TIMER_00 || TIMER_10
#endif // TS_USE_TIMERGROUP
#if TS_USE_ESP_TIMER
// esp_timer provides 1us resolution
#define SYSVIEW_TIMESTAMP_FREQ (1000000)
#endif // TS_USE_ESP_TIMER
#if TS_USE_CCOUNT
// CCOUNT is incremented at CPU frequency
#define SYSVIEW_TIMESTAMP_FREQ (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000)
#endif // TS_USE_CCOUNT
// System Frequency.
#define SYSVIEW_CPU_FREQ (esp_clk_cpu_freq())
@ -103,11 +139,8 @@ extern const SEGGER_SYSVIEW_OS_API SYSVIEW_X_OS_TraceAPI;
#define SYSTICK_INTR_ID (ETS_INTERNAL_TIMER1_INTR_SOURCE+ETS_INTERNAL_INTR_SOURCE_OFF)
#endif
static timer_idx_t s_ts_timer_idx;
static timer_group_t s_ts_timer_group;
// SystemView is single core specific: it implies that SEGGER_SYSVIEW_LOCK()
// disables IRQs (disables rescheduling globaly). So we can not use finite timeouts for locks and return error
// disables IRQs (disables rescheduling globally). So we can not use finite timeouts for locks and return error
// in case of expiration, because error will not be handled and SEGGER's code will go further implying that
// everything is fine, so for multi-core env we have to wait on underlying lock forever
#define SEGGER_LOCK_WAIT_TMO ESP_APPTRACE_TMO_INFINITE
@ -213,35 +246,24 @@ static void _cbSendSystemDesc(void) {
*/
static void SEGGER_SYSVIEW_TS_Init()
{
timer_config_t config;
#if CONFIG_SYSVIEW_TS_SOURCE_TIMER_00
s_ts_timer_group = TIMER_GROUP_0;
s_ts_timer_idx = TIMER_0;
#endif
#if CONFIG_SYSVIEW_TS_SOURCE_TIMER_01
s_ts_timer_group = TIMER_GROUP_0;
s_ts_timer_idx = TIMER_1;
#endif
#if CONFIG_SYSVIEW_TS_SOURCE_TIMER_10
s_ts_timer_group = TIMER_GROUP_1;
s_ts_timer_idx = TIMER_0;
#endif
#if CONFIG_SYSVIEW_TS_SOURCE_TIMER_11
s_ts_timer_group = TIMER_GROUP_1;
s_ts_timer_idx = TIMER_1;
#endif
config.alarm_en = 0;
config.auto_reload = 0;
config.counter_dir = TIMER_COUNT_UP;
config.divider = SYSVIEW_TIMER_DIV;
config.counter_en = 0;
/*Configure timer*/
timer_init(s_ts_timer_group, s_ts_timer_idx, &config);
/*Load counter value */
timer_set_counter_value(s_ts_timer_group, s_ts_timer_idx, 0x00000000ULL);
/*Enable timer interrupt*/
timer_start(s_ts_timer_group, s_ts_timer_idx);
/* We only need to initialize something if we use Timer Group.
* esp_timer and ccount can be used as is.
*/
#if TS_USE_TIMERGROUP
timer_config_t config = {
.alarm_en = 0,
.auto_reload = 0,
.counter_dir = TIMER_COUNT_UP,
.divider = SYSVIEW_TIMER_DIV,
.counter_en = 0
};
/* Configure timer */
timer_init(TS_TIMER_GROUP, TS_TIMER_ID, &config);
/* Load counter value */
timer_set_counter_value(TS_TIMER_GROUP, TS_TIMER_ID, 0x00000000ULL);
/* Start counting */
timer_start(TS_TIMER_GROUP, TS_TIMER_ID);
#endif // TS_USE_TIMERGROUP
}
void SEGGER_SYSVIEW_Conf(void) {
@ -296,12 +318,14 @@ void SEGGER_SYSVIEW_Conf(void) {
U32 SEGGER_SYSVIEW_X_GetTimestamp()
{
#if CONFIG_FREERTOS_UNICORE == 0
#if TS_USE_TIMERGROUP
uint64_t ts = 0;
timer_get_counter_value(s_ts_timer_group, s_ts_timer_idx, &ts);
return (U32)ts; // return lower part of counter value
#else
timer_get_counter_value(TS_TIMER_GROUP, TS_TIMER_ID, &ts);
return (U32) ts; // return lower part of counter value
#elif TS_USE_CCOUNT
return portGET_RUN_TIME_COUNTER_VALUE();
#elif TS_USE_ESP_TIMER
return (U32) esp_timer_get_time(); // return lower part of counter value
#endif
}

View file

@ -83,3 +83,77 @@ config AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
Maximum delay between reconnection attempts. If the exponentially increased delay
interval reaches this value, the client will stop automatically attempting to reconnect.
menu "Thing Shadow"
depends on AWS_IOT_SDK
config AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
bool "Override Shadow RX buffer size"
depends on AWS_IOT_SDK
default n
help
Allows setting a different Thing Shadow RX buffer
size. This is the maximum size of a Thing Shadow
message in bytes, plus one.
If not overridden, the default value is the MQTT RX Buffer length plus one. If overriden, do not set higher than the default value.
config AWS_IOT_SHADOW_MAX_SIZE_OF_RX_BUFFER
int "Maximum RX Buffer (bytes)"
depends on AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
default 513
range 32 65536
help
Allows setting a different Thing Shadow RX buffer size.
This is the maximum size of a Thing Shadow message in bytes,
plus one.
config AWS_IOT_SHADOW_MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES
int "Maximum unique client ID size (bytes)"
depends on AWS_IOT_SDK
default 80
range 4 1000
help
Maximum size of the Unique Client Id.
config AWS_IOT_SHADOW_MAX_SIMULTANEOUS_ACKS
int "Maximum simultaneous responses"
depends on AWS_IOT_SDK
default 10
range 1 100
help
At any given time we will wait for this many responses. This will correlate to the rate at which the shadow actions are requested
config AWS_IOT_SHADOW_MAX_SIMULTANEOUS_THINGNAMES
int "Maximum simultaneous Thing Name operations"
depends on AWS_IOT_SDK
default 10
range 1 100
help
We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any given time
config AWS_IOT_SHADOW_MAX_JSON_TOKEN_EXPECTED
int "Maximum expected JSON tokens"
depends on AWS_IOT_SDK
default 120
help
These are the max tokens that is expected to be in the Shadow JSON document. Includes the metadata which is published
config AWS_IOT_SHADOW_MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME
int "Maximum topic length (not including Thing Name)"
depends on AWS_IOT_SDK
default 60
range 10 1000
help
All shadow actions have to be published or subscribed to a topic which is of the format $aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing Name
config AWS_IOT_SHADOW_MAX_SIZE_OF_THING_NAME
int "Maximum Thing Name length"
depends on AWS_IOT_SDK
default 20
range 4 1000
help
Maximum length of a Thing Name.
endmenu # Thing Shadow

@ -1 +1 @@
Subproject commit 7132505b00d2dd57f48478e75efa636021919aae
Subproject commit 8bf852db77c360eebfa4b800754fdb90e29ea43e

View file

@ -42,15 +42,20 @@
#define AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS CONFIG_AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS ///< Maximum number of topic filters the MQTT client can handle at any given time. This should be increased appropriately when using Thing Shadow
// Thing Shadow specific configs
#define SHADOW_MAX_SIZE_OF_RX_BUFFER (AWS_IOT_MQTT_RX_BUF_LEN + 1) ///< Maximum size of the SHADOW buffer to store the received Shadow message
#ifdef CONFIG_AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
#define SHADOW_MAX_SIZE_OF_RX_BUFFER CONFIG AWS_IOT_SHADOW_MAX_SIZE_OF_RX_BUFFER ///< Maximum size of the SHADOW buffer to store the received Shadow message, including NULL termianting byte
#else
#define SHADOW_MAX_SIZE_OF_RX_BUFFER (AWS_IOT_MQTT_RX_BUF_LEN + 1)
#endif
#define MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES 80 ///< Maximum size of the Unique Client Id. For More info on the Client Id refer \ref response "Acknowledgments"
#define MAX_SIZE_CLIENT_ID_WITH_SEQUENCE (MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES + 10) ///< This is size of the extra sequence number that will be appended to the Unique client Id
#define MAX_SIZE_CLIENT_TOKEN_CLIENT_SEQUENCE (MAX_SIZE_CLIENT_ID_WITH_SEQUENCE + 20) ///< This is size of the the total clientToken key and value pair in the JSON
#define MAX_ACKS_TO_COMEIN_AT_ANY_GIVEN_TIME 10 ///< At Any given time we will wait for this many responses. This will correlate to the rate at which the shadow actions are requested
#define MAX_THINGNAME_HANDLED_AT_ANY_GIVEN_TIME 10 ///< We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any given time
#define MAX_JSON_TOKEN_EXPECTED 120 ///< These are the max tokens that is expected to be in the Shadow JSON document. Include the metadata that gets published
#define MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME 60 ///< All shadow actions have to be published or subscribed to a topic which is of the formablogt $aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing Name
#define MAX_SIZE_OF_THING_NAME 20 ///< The Thing Name should not be bigger than this value. Modify this if the Thing Name needs to be bigger
#define MAX_ACKS_TO_COMEIN_AT_ANY_GIVEN_TIME CONFIG_AWS_IOT_SHADOW_MAX_SIMULTANEOUS_ACKS ///< At Any given time we will wait for this many responses. This will correlate to the rate at which the shadow actions are requested
#define MAX_THINGNAME_HANDLED_AT_ANY_GIVEN_TIME CONFIG_AWS_IOT_SHADOW_MAX_SIMULTANEOUS_THINGNAMES ///< We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any given time
#define MAX_JSON_TOKEN_EXPECTED CONFIG_AWS_IOT_SHADOW_MAX_JSON_TOKEN_EXPECTED ///< These are the max tokens that is expected to be in the Shadow JSON document. Include the metadata that gets published
#define MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME CONFIG_AWS_IOT_SHADOW_MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME ///< All shadow actions have to be published or subscribed to a topic which is of the formablogt $aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing Name
#define MAX_SIZE_OF_THING_NAME CONFIG_AWS_IOT_SHADOW_MAX_SIZE_OF_THING_NAME ///< The Thing Name should not be bigger than this value. Modify this if the Thing Name needs to be bigger
#define MAX_SHADOW_TOPIC_LENGTH_BYTES (MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME + MAX_SIZE_OF_THING_NAME) ///< This size includes the length of topic with Thing Name
// Auto Reconnect specific config

View file

@ -11,50 +11,76 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "esp_flash_partitions.h"
#include "esp_log.h"
#include "rom/spi_flash.h"
#include "rom/md5_hash.h"
#include "esp_flash_data_types.h"
static const char *TAG = "flash_parts";
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
{
int num_parts;
uint32_t chip_size = g_rom_flashchip.chip_size;
*num_partitions = 0;
int md5_found = 0;
int num_parts;
uint32_t chip_size = g_rom_flashchip.chip_size;
*num_partitions = 0;
for(num_parts = 0; num_parts < ESP_PARTITION_TABLE_MAX_ENTRIES; num_parts++) {
const esp_partition_info_t *part = &partition_table[num_parts];
for (num_parts = 0; num_parts < ESP_PARTITION_TABLE_MAX_ENTRIES; num_parts++) {
const esp_partition_info_t *part = &partition_table[num_parts];
if (part->magic == 0xFFFF
&& part->type == PART_TYPE_END
&& part->subtype == PART_SUBTYPE_END) {
/* TODO: check md5 */
ESP_LOGD(TAG, "partition table verified, %d entries", num_parts);
*num_partitions = num_parts;
return ESP_OK;
}
if (part->magic == ESP_PARTITION_MAGIC) {
const esp_partition_pos_t *pos = &part->pos;
if (pos->offset > chip_size || pos->offset + pos->size > chip_size) {
if (log_errors) {
ESP_LOGE(TAG, "partition %d invalid - offset 0x%x size 0x%x exceeds flash chip size 0x%x",
num_parts, pos->offset, pos->size, chip_size);
}
return ESP_ERR_INVALID_SIZE;
}
} else if (part->magic == ESP_PARTITION_MAGIC_MD5) {
if (md5_found) {
if (log_errors) {
ESP_LOGE(TAG, "Only one MD5 checksum is allowed");
}
return ESP_ERR_INVALID_STATE;
}
if (part->magic != ESP_PARTITION_MAGIC) {
if (log_errors) {
ESP_LOGE(TAG, "partition %d invalid magic number 0x%x", num_parts, part->magic);
struct MD5Context context;
unsigned char digest[16];
MD5Init(&context);
MD5Update(&context, (unsigned char *) partition_table, num_parts * sizeof(esp_partition_info_t));
MD5Final(digest, &context);
unsigned char *md5sum = ((unsigned char *) part) + 16; // skip the 2B magic number and the 14B fillup bytes
if (memcmp(md5sum, digest, sizeof(digest)) != 0) {
if (log_errors) {
ESP_LOGE(TAG, "Incorrect MD5 checksum");
}
return ESP_ERR_INVALID_STATE;
}
//MD5 checksum matches and we continue with the next interation in
//order to detect the end of the partition table
md5_found = 1;
} else if (part->magic == 0xFFFF
&& part->type == PART_TYPE_END
&& part->subtype == PART_SUBTYPE_END) {
ESP_LOGD(TAG, "partition table verified, %d entries", num_parts);
*num_partitions = num_parts - md5_found; //do not count the partition where the MD5 checksum is held
return ESP_OK;
} else {
if (log_errors) {
ESP_LOGE(TAG, "partition %d invalid magic number 0x%x", num_parts, part->magic);
}
return ESP_ERR_INVALID_STATE;
}
return ESP_ERR_INVALID_STATE;
}
const esp_partition_pos_t *pos = &part->pos;
if (pos->offset > chip_size || pos->offset + pos->size > chip_size) {
if (log_errors) {
ESP_LOGE(TAG, "partition %d invalid - offset 0x%x size 0x%x exceeds flash chip size 0x%x",
num_parts, pos->offset, pos->size, chip_size);
}
return ESP_ERR_INVALID_SIZE;
if (log_errors) {
ESP_LOGE(TAG, "partition table has no terminating entry, not valid");
}
}
if (log_errors) {
ESP_LOGE(TAG, "partition table has no terminating entry, not valid");
}
return ESP_ERR_INVALID_STATE;
return ESP_ERR_INVALID_STATE;
}

View file

@ -113,19 +113,39 @@ config CLASSIC_BT_ENABLED
help
For now this option needs "SMP_ENABLE" to be set to yes
config A2DP_SNK_ENABLED
bool "A2DP(SINK)"
config A2DP_ENABLE
bool "A2DP"
depends on CLASSIC_BT_ENABLED
default n
help
This option is used to enable/disable Advanced Audio Distribution Profile(Sink)
Advanced Audio Distrubution Profile
choice A2DP_ROLE
prompt "A2DP ROLE config"
depends on A2DP_ENABLE
config A2DP_SINK_ENABLE
bool "SINK"
config A2DP_SRC_ENABLE
bool "SOURCE"
endchoice
config A2DP_SINK_TASK_STACK_SIZE
int "A2DP sink (audio stream decoding) task stack size"
depends on A2DP_ENABLE && A2DP_SINK_ENABLE
default 2048
config A2DP_SOURCE_TASK_STACK_SIZE
int "A2DP source (audio stream encoding) task stack size"
depends on A2DP_ENABLE && A2DP_SRC_ENABLE
default 2048
config BT_SPP_ENABLED
bool "SPP Profile"
bool "SPP"
depends on CLASSIC_BT_ENABLED
default n
help
This enables the SPP Profile
This enables the Serial Port Profile
config GATTS_ENABLE
bool "Include GATT server module(GATTS)"
@ -163,6 +183,20 @@ config BT_ACL_CONNECTIONS
help
Maximum BT/BLE connection count
config BT_ALLOCATION_FROM_SPIRAM_FIRST
bool "BT/BLE will first malloc the memory from the PSRAM"
depends on BLUEDROID_ENABLED
default n
help
This select can save the internal RAM if there have the PSRAM
config BT_BLE_DYNAMIC_ENV_MEMORY
bool "Use dynamic memory allocation in BT/BLE stack"
depends on BLUEDROID_ENABLED
default n
help
This select can make the allocation of memory will become more flexible
config SMP_ENABLE
bool
depends on BLUEDROID_ENABLED

View file

@ -22,20 +22,7 @@
#if BTC_AV_INCLUDED
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (callback == NULL) {
return ESP_FAIL;
}
btc_profile_cb_set(BTC_PID_A2DP, callback);
return ESP_OK;
}
#if BTC_AV_SINK_INCLUDED
esp_err_t esp_a2d_sink_init(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
@ -43,7 +30,7 @@ esp_err_t esp_a2d_sink_init(void)
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_INIT_EVT;
@ -58,9 +45,9 @@ esp_err_t esp_a2d_sink_deinit(void)
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_DEINIT_EVT;
@ -70,7 +57,7 @@ esp_err_t esp_a2d_sink_deinit(void)
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback)
esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
@ -82,11 +69,11 @@ esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback)
msg.act = BTC_AV_SINK_API_REG_DATA_CB_EVT;
btc_av_args_t arg;
memset(&arg, 0, sizeof(btc_av_args_t));
memset(&arg, 0, sizeof(btc_av_args_t));
arg.data_cb = callback;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_msg_t), NULL);
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
@ -95,17 +82,17 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_av_args_t arg;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_CONNECT_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
/* Switch to BTC context */
memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t));
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
@ -117,10 +104,10 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_API_DISCONNECT_EVT;
@ -130,4 +117,139 @@ esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
#endif /* BTC_AV_SINK_INCLUDED */
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (callback == NULL) {
return ESP_FAIL;
}
btc_profile_cb_set(BTC_PID_A2DP, callback);
return ESP_OK;
}
esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_av_args_t arg;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_API_MEDIA_CTRL_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
/* Switch to BTC context */
arg.ctrl = ctrl;
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
#if BTC_AV_SRC_INCLUDED
esp_err_t esp_a2d_source_init(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SRC_API_INIT_EVT;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_source_deinit(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SRC_API_DEINIT_EVT;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_av_args_t arg;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SRC_API_CONNECT_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
/* Switch to BTC context */
memcpy(&(arg.src_connect), remote_bda, sizeof(bt_bdaddr_t));
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
bt_status_t stat;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SRC_API_DISCONNECT_EVT;
/* Switch to BTC context */
stat = btc_transfer_context(&msg, NULL, 0, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SRC_API_REG_DATA_CB_EVT;
btc_av_args_t arg;
memset(&arg, 0, sizeof(btc_av_args_t));
arg.src_data_cb = callback;
/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}
#endif /* BTC_AV_SRC_INCLUDED */
#endif /* #if BTC_AV_INCLUDED */

View file

@ -22,6 +22,7 @@
#include "btc_main.h"
#include "future.h"
#include "btc_gatts.h"
#include "btc_gatt_util.h"
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
{
@ -57,6 +58,23 @@ esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list)
{
btc_msg_t msg;
btc_blufi_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_BLUFI;
msg.act = BTC_BLUFI_ACT_SEND_WIFI_LIST;
arg.wifi_list.apCount = apCount;
arg.wifi_list.list = list;
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_blufi_profile_init(void)
{
@ -103,7 +121,24 @@ esp_err_t esp_blufi_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTS;
msg.act = BTC_GATTS_ACT_CLOSE;
arg.close.conn_id = conn_id;
arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state)
{
btc_msg_t msg;
btc_blufi_args_t arg;
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_BLUFI;
msg.act = BTC_BLUFI_ACT_SEND_ERR_INFO;
arg.blufi_err_infor.state = state;
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View file

@ -16,7 +16,7 @@
#include "esp_gatt_common_api.h"
#include "esp_bt_main.h"
#include "esp_gatt_defs.h"
#include "btc_main.h"
#include "btc_gatt_common.h"
/**
* @brief This function is called to set local MTU,
@ -32,7 +32,7 @@
esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu)
{
btc_msg_t msg;
btc_ble_main_args_t arg;
btc_ble_gatt_com_args_t arg;
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
@ -41,9 +41,9 @@ esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu)
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_MAIN_INIT;
msg.pid = BTC_PID_GATT_COMMON;
msg.act = BTC_GATT_ACT_SET_LOCAL_MTU;
arg.set_mtu.mtu = mtu;
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_main_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatt_com_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View file

@ -67,11 +67,28 @@ typedef enum {
ESP_A2D_AUDIO_STATE_STARTED, /*!< audio stream datapath started */
} esp_a2d_audio_state_t;
/// A2DP media control command acknowledgement code
typedef enum {
ESP_A2D_MEDIA_CTRL_ACK_SUCCESS = 0, /*!< media control command is acknowledged with success */
ESP_A2D_MEDIA_CTRL_ACK_FAILURE, /*!< media control command is acknowledged with failure */
ESP_A2D_MEDIA_CTRL_ACK_BUSY, /*!< media control command is rejected, as previous command is not yet acknowledged */
} esp_a2d_media_ctrl_ack_t;
/// A2DP media control commands
typedef enum {
ESP_A2D_MEDIA_CTRL_NONE = 0, /*!< dummy command */
ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY, /*!< check whether AVDTP is connected, only used in A2DP source */
ESP_A2D_MEDIA_CTRL_START, /*!< command to set up media transmission channel */
ESP_A2D_MEDIA_CTRL_STOP, /*!< command to stop media transmission */
ESP_A2D_MEDIA_CTRL_SUSPEND, /*!< command to suspend media transmission */
} esp_a2d_media_ctrl_t;
/// A2DP callback events
typedef enum {
ESP_A2D_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */
ESP_A2D_AUDIO_STATE_EVT = 1, /*!< audio stream transmission state changed event */
ESP_A2D_AUDIO_CFG_EVT = 2 /*!< audio codec is configured */
ESP_A2D_AUDIO_STATE_EVT, /*!< audio stream transmission state changed event */
ESP_A2D_AUDIO_CFG_EVT, /*!< audio codec is configured, only used for A2DP SINK */
ESP_A2D_MEDIA_CTRL_ACK_EVT, /*!< acknowledge event in response to media control commands */
} esp_a2d_cb_event_t;
/// A2DP state callback parameters
@ -84,7 +101,7 @@ typedef union {
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
esp_a2d_disc_rsn_t disc_rsn; /*!< reason of disconnection for "DISCONNECTED" */
} conn_stat; /*!< A2DP connection status */
/**
* @brief ESP_A2D_AUDIO_STATE_EVT
*/
@ -92,7 +109,7 @@ typedef union {
esp_a2d_audio_state_t state; /*!< one of the values from esp_a2d_audio_state_t */
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
} audio_stat; /*!< audio stream playing state */
/**
* @brief ESP_A2D_AUDIO_CFG_EVT
*/
@ -100,32 +117,52 @@ typedef union {
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
esp_a2d_mcc_t mcc; /*!< A2DP media codec capability information */
} audio_cfg; /*!< media codec configuration infomation */
/**
* @brief ESP_A2D_MEDIA_CTRL_ACK_EVT
*/
struct media_ctrl_stat_param {
esp_a2d_media_ctrl_t cmd; /*!< media control commands to acknowledge */
esp_a2d_media_ctrl_ack_t status; /*!< acknowledgement to media control commands */
} media_ctrl_stat; /*!< status in acknowledgement to media control commands */
} esp_a2d_cb_param_t;
/**
* @brief A2DP profile callback function type
*
* @param event : Event type
*
* @param param : Pointer to callback parameter
*/
typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
/**
* @brief A2DP profile data callback function
*
* @param[in] buf : data received from A2DP source device and is PCM format decoder from SBC decoder;
* buf references to a static memory block and can be overwritten by upcoming data
*
* @param[in] len : size(in bytes) in buf
*/
typedef void (* esp_a2d_sink_data_cb_t)(const uint8_t *buf, uint32_t len);
/**
* @brief A2DP source data read callback function
*
* @param[in] buf : buffer to be filled with PCM data stream from higer layer
*
* @param[in] len : size(in bytes) of data block to be copied to buf. -1 is an indication to user
* that data buffer shall be flushed
*
* @return size of bytes read successfully, if the argumetn len is -1, this value is ignored.
*
*/
typedef void (* esp_a2d_data_cb_t)(const uint8_t *buf, uint32_t len);
typedef int32_t (* esp_a2d_source_data_cb_t)(uint8_t *buf, int32_t len);
/**
* @brief Register application callback function to A2DP module. This function should be called
* only after esp_bluedroid_enable() completes successfully
*
* @param[in] callback: A2DP sink event callback function
* only after esp_bluedroid_enable() completes successfully, used by both A2DP source
* and sink.
*
* @param[in] callback: A2DP event callback function
*
* @return
* - ESP_OK: success
@ -138,10 +175,11 @@ esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback);
/**
* @brief Register A2DP sink data output function; For now the output is PCM data stream decoded
* from SBC format. This function should be called only after esp_bluedroid_enable()
* completes successfully
*
* @param[in] callback: A2DP data callback function
* from SBC format. This function should be called only after esp_bluedroid_enable()
* completes successfully, used only by A2DP sink. The callback is invoked in the context
* of A2DP sink task whose stack size is configurable through menuconfig
*
* @param[in] callback: A2DP sink data callback function
*
* @return
* - ESP_OK: success
@ -149,7 +187,7 @@ esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback);
* - ESP_FAIL: if callback is a NULL function pointer
*
*/
esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback);
esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback);
/**
@ -157,7 +195,7 @@ esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback);
* @brief Initialize the bluetooth A2DP sink module. This function should be called
* after esp_bluedroid_enable() completes successfully
*
* @return
* @return
* - ESP_OK: if the initialization request is sent successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
@ -168,10 +206,10 @@ esp_err_t esp_a2d_sink_init(void);
/**
*
* @brief De-initialize for A2DP sink module. This function
* @brief De-initialize for A2DP sink module. This function
* should be called only after esp_bluedroid_enable() completes successfully
*
* @return
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
@ -182,11 +220,11 @@ esp_err_t esp_a2d_sink_deinit(void);
/**
*
* @brief Connect the remote bluetooth device bluetooth, must after esp_a2d_sink_init()
* @brief Connect to remote bluetooth A2DP source device, must after esp_a2d_sink_init()
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* @return
* - ESP_OK: connect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
@ -197,10 +235,10 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda);
/**
*
* @brief Disconnect the remote bluetooth device
* @brief Disconnect from the remote A2DP source device
*
* @param[in] remote_bda: remote bluetooth device address
* @return
* @return
* - ESP_OK: disconnect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
@ -208,6 +246,94 @@ esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda);
*/
esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda);
/**
*
* @brief media control commands; this API can be used for both A2DP sink and source
*
* @param[in] ctrl: control commands for A2DP data channel
* @return
* - ESP_OK: control command is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl);
/**
*
* @brief Initialize the bluetooth A2DP source module. This function should be called
* after esp_bluedroid_enable() completes successfully
*
* @return
* - ESP_OK: if the initialization request is sent successfully
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_source_init(void);
/**
*
* @brief De-initialize for A2DP source module. This function
* should be called only after esp_bluedroid_enable() completes successfully
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_source_deinit(void);
/**
* @brief Register A2DP source data input function; For now the input is PCM data stream.
* This function should be called only after esp_bluedroid_enable() completes
* successfully. The callback is invoked in the context of A2DP source task whose
* stack size is configurable through menuconfig
*
* @param[in] callback: A2DP source data callback function
*
* @return
* - ESP_OK: success
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: if callback is a NULL function pointer
*
*/
esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback);
/**
*
* @brief Connect to remote A2DP sink device, must after esp_a2d_source_init()
*
* @param[in] remote_bda: remote bluetooth device address
*
* @return
* - ESP_OK: connect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda);
/**
*
* @brief Disconnect from the remote A2DP sink device
*
* @param[in] remote_bda: remote bluetooth device address
* @return
* - ESP_OK: disconnect request is sent to lower layer
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
* - ESP_FAIL: others
*
*/
esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda);
#ifdef __cplusplus
}
#endif

View file

@ -50,6 +50,8 @@ typedef enum {
ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY, /*<! When Phone send Client Private key to ESP32, this event happen */
ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY, /*<! When Phone send Server Private key to ESP32, this event happen */
ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE, /*<! When Phone send Disconnect key to ESP32, this event happen */
ESP_BLUFI_EVENT_GET_WIFI_LIST, /*<! When Phone send get wifi list command to ESP32, this event happen */
ESP_BLUFI_EVENT_REPORT_ERROR, /*<! When Blufi report error, this event happen */
} esp_blufi_cb_event_t;
/// BLUFI config status
@ -61,15 +63,27 @@ typedef enum {
/// BLUFI init status
typedef enum {
ESP_BLUFI_INIT_OK = 0,
ESP_BLUFI_INIT_FAILED = 0,
ESP_BLUFI_INIT_FAILED,
} esp_blufi_init_state_t;
/// BLUFI deinit status
typedef enum {
ESP_BLUFI_DEINIT_OK = 0,
ESP_BLUFI_DEINIT_FAILED = 0,
ESP_BLUFI_DEINIT_FAILED,
} esp_blufi_deinit_state_t;
typedef enum {
ESP_BLUFI_SEQUENCE_ERROR = 0,
ESP_BLUFI_CHECKSUM_ERROR,
ESP_BLUFI_DECRYPT_ERROR,
ESP_BLUFI_ENCRYPT_ERROR,
ESP_BLUFI_INIT_SECURITY_ERROR,
ESP_BLUFI_DH_MALLOC_ERROR,
ESP_BLUFI_DH_PARAM_ERROR,
ESP_BLUFI_READ_PARAM_ERROR,
ESP_BLUFI_MAKE_PUBLIC_ERROR,
} esp_blufi_error_state_t;
/**
* @brief BLUFI extra information structure
*/
@ -93,6 +107,12 @@ typedef struct {
bool softap_channel_set; /*!< is channel of softap interface set */
} esp_blufi_extra_info_t;
/** @brief Description of an WiFi AP */
typedef struct {
uint8_t ssid[33]; /**< SSID of AP */
int8_t rssi; /**< signal strength of AP */
} esp_blufi_ap_record_t;
/**
* @brief BLUFI callback parameters union
*/
@ -247,6 +267,13 @@ typedef union {
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */
int pkey_len; /*!< Client Private key length */
} server_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY */
/**
* @brief
* ESP_BLUFI_EVENT_REPORT_ERROR
*/
struct blufi_get_error_evt_param {
esp_blufi_error_state_t state; /*!< Blufi error state */
} report_error; /*!< Blufi callback param of ESP_BLUFI_EVENT_REPORT_ERROR */
} esp_blufi_cb_param_t;
@ -347,6 +374,17 @@ esp_err_t esp_blufi_profile_deinit(void);
*/
esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info);
/**
*
* @brief This function is called to send wifi list
* @param apCount : wifi list count
* @param list : wifi list
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list);
/**
*
* @brief Get BLUFI profile version
@ -368,6 +406,16 @@ uint16_t esp_blufi_get_version(void);
*
*/
esp_err_t esp_blufi_close(esp_gatt_if_t gatts_if, uint16_t conn_id);
/**
*
* @brief This function is called to send blufi error information
* @param state : error state
*
* @return ESP_OK - success, other - failed
*
*/
esp_err_t esp_blufi_send_error_info(esp_blufi_error_state_t state);
#ifdef __cplusplus
}
#endif

View file

@ -32,6 +32,8 @@
/* AV control block */
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_AR_CB bta_ar_cb;
#else
tBTA_AR_CB *bta_ar_cb_ptr;
#endif
/*******************************************************************************

View file

@ -1268,6 +1268,11 @@ void bta_av_disable(tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data)
hdr.layer_specific = xx + 1;
bta_av_api_deregister((tBTA_AV_DATA *)&hdr);
}
bta_sys_free_timer(&p_cb->sig_tmr);
memset(&p_cb->sig_tmr, 0, sizeof(TIMER_LIST_ENT));
bta_sys_free_timer(&p_cb->acp_sig_tmr);
memset(&p_cb->acp_sig_tmr, 0, sizeof(TIMER_LIST_ENT));
}
/*******************************************************************************

View file

@ -194,6 +194,8 @@ const tBTA_AV_NSM_ACT bta_av_nsm_act[] = {
/* AV control block */
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_AV_CB bta_av_cb;
#else
tBTA_AV_CB *bta_av_cb_ptr;
#endif
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)

View file

@ -28,7 +28,7 @@
#include "a2d_sbc.h"
#include "bta_av_sbc.h"
#include "utl.h"
#include "bt_utils.h"
#include "bt_defs.h"
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)

View file

@ -282,6 +282,47 @@ void bta_dm_enable(tBTA_DM_MSG *p_data)
}
}
/*******************************************************************************
*
* Function bta_dm_init_cb
*
* Description Initializes the bta_dm_cb control block
*
*
* Returns void
*
******************************************************************************/
void bta_dm_init_cb(void)
{
memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
}
/*******************************************************************************
*
* Function bta_dm_deinit_cb
*
* Description De-initializes the bta_dm_cb control block
*
*
* Returns void
*
******************************************************************************/
void bta_dm_deinit_cb(void)
{
bta_sys_free_timer(&bta_dm_cb.disable_timer);
#if ( BTA_EIR_CANNED_UUID_LIST != TRUE )
bta_sys_free_timer(&bta_dm_cb.app_ready_timer);
#endif
#if BTM_SSR_INCLUDED == TRUE
for (size_t i = 0; i < BTA_DM_NUM_PM_TIMER; i++) {
for (size_t j = 0; j < BTA_DM_PM_MODE_TIMER_MAX; j++) {
bta_sys_free_timer(&bta_dm_cb.pm_timer[i].timer[j]);
}
}
#endif
memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
}
/*******************************************************************************
**
** Function bta_dm_sys_hw_cback
@ -318,7 +359,15 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
}
/* reinitialize the control block */
memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
bta_dm_deinit_cb();
bta_sys_free_timer(&bta_dm_search_cb.search_timer);
#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
bta_sys_free_timer(&bta_dm_search_cb.gatt_close_timer);
#endif
#endif
memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb));
/* unregister from SYS */
bta_sys_hw_unregister( BTA_SYS_HW_BLUETOOTH );
@ -332,11 +381,18 @@ static void bta_dm_sys_hw_cback( tBTA_SYS_HW_EVT status )
/* save security callback */
temp_cback = bta_dm_cb.p_sec_cback;
/* make sure the control block is properly initialized */
memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
bta_dm_init_cb();
/* and retrieve the callback */
bta_dm_cb.p_sec_cback = temp_cback;
bta_dm_cb.is_bta_dm_active = TRUE;
bta_sys_free_timer(&bta_dm_search_cb.search_timer);
#if ((defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
#if ((defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE) && SDP_INCLUDED == TRUE)
bta_sys_free_timer(&bta_dm_search_cb.gatt_close_timer);
#endif
#endif
/* hw is ready, go on with BTA DM initialization */
memset(&bta_dm_search_cb, 0x00, sizeof(bta_dm_search_cb));
#if (BTM_SSR_INCLUDED == TRUE)
@ -2589,7 +2645,7 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
return BTM_NOT_AUTHORIZED;
}
}
@ -4126,6 +4182,8 @@ static void bta_dm_observe_results_cb (tBTM_INQ_RESULTS *p_inq, UINT8 *p_eir)
result.inq_res.flag = p_inq->flag;
result.inq_res.adv_data_len = p_inq->adv_data_len;
result.inq_res.scan_rsp_len = p_inq->scan_rsp_len;
memcpy(result.inq_res.dev_class, p_inq->dev_class, sizeof(DEV_CLASS));
result.inq_res.ble_evt_type = p_inq->ble_evt_type;
/* application will parse EIR to find out remote device name */
result.inq_res.p_eir = p_eir;
@ -4282,7 +4340,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
} else {
sec_event.auth_cmpl.success = TRUE;
if (!p_data->complt.smp_over_br) {
}
}
@ -5338,7 +5396,7 @@ static void bta_ble_energy_info_cmpl(tBTM_BLE_TX_TIME_MS tx_time,
if (BTA_SUCCESS == st) {
ctrl_state = bta_dm_pm_obtain_controller_state();
}
#endif
#endif
if (bta_dm_cb.p_energy_info_cback) {
bta_dm_cb.p_energy_info_cback(tx_time, rx_time, idle_time, energy_used, ctrl_state, st);
}

View file

@ -25,6 +25,8 @@
#include "bta_api.h"
#include "bta_sys.h"
#include "bta_dm_int.h"
#include "allocator.h"
#include <string.h>
/*****************************************************************************
@ -35,6 +37,10 @@
tBTA_DM_CB bta_dm_cb;
tBTA_DM_SEARCH_CB bta_dm_search_cb;
tBTA_DM_DI_CB bta_dm_di_cb;
#else
tBTA_DM_CB *bta_dm_cb_ptr;
tBTA_DM_SEARCH_CB *bta_dm_search_cb_ptr;
tBTA_DM_DI_CB *bta_dm_di_cb_ptr;
#endif
@ -346,6 +352,18 @@ void bta_dm_sm_disable( )
bta_sys_deregister( BTA_ID_DM );
}
void bta_dm_sm_deinit(void)
{
memset(&bta_dm_cb, 0, sizeof(tBTA_DM_CB));
memset(&bta_dm_search_cb, 0, sizeof(tBTA_DM_SEARCH_CB));
memset(&bta_dm_di_cb, 0, sizeof(tBTA_DM_DI_CB));
#if BTA_DYNAMIC_MEMORY
FREE_AND_RESET(bta_dm_cb_ptr);
FREE_AND_RESET(bta_dm_search_cb_ptr);
FREE_AND_RESET(bta_dm_di_cb_ptr);
#endif /* #if BTA_DYNAMIC_MEMORY */
}
/*******************************************************************************
**

View file

@ -48,8 +48,6 @@
#if GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE
static osi_mutex_t write_ccc_mutex;
/*****************************************************************************
** Constants
*****************************************************************************/
@ -129,9 +127,9 @@ static void bta_gattc_enable(tBTA_GATTC_CB *p_cb)
memset(&bta_gattc_cb, 0, sizeof(tBTA_GATTC_CB));
p_cb->state = BTA_GATTC_STATE_ENABLED;
// Create a write ccc mutex when the gatt client enable
osi_mutex_new(&write_ccc_mutex);
osi_mutex_new(&bta_gattc_cb.write_ccc_mutex);
} else {
APPL_TRACE_DEBUG("GATTC is arelady enabled");
APPL_TRACE_DEBUG("GATTC is already enabled");
}
}
@ -157,7 +155,7 @@ void bta_gattc_disable(tBTA_GATTC_CB *p_cb)
return;
}
// Free the write ccc mutex when the gatt client disable
osi_mutex_free(&write_ccc_mutex);
osi_mutex_free(&bta_gattc_cb.write_ccc_mutex);
for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
if (p_cb->cl_rcb[i].in_use) {
@ -1644,8 +1642,8 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
else if ((transport == BT_TRANSPORT_LE) && (connected == FALSE) && (p_conn != NULL)){
p_conn->service_change_ccc_written = FALSE;
if (p_conn->ccc_timer_used == TRUE){
assert(write_ccc_mutex != NULL);
osi_mutex_lock(&write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
assert(bta_gattc_cb.write_ccc_mutex != NULL);
osi_mutex_lock(&bta_gattc_cb.write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
if (p_conn->service_change_ccc_timer.param != 0) {
osi_free((void *)p_conn->service_change_ccc_timer.param);
@ -1653,7 +1651,7 @@ static void bta_gattc_conn_cback(tGATT_IF gattc_if, BD_ADDR bda, UINT16 conn_id,
}
bta_sys_stop_timer(&(p_conn->service_change_ccc_timer));
p_conn->ccc_timer_used = FALSE;
osi_mutex_unlock(&write_ccc_mutex);
osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
}
}
@ -2173,7 +2171,7 @@ void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg)
cb_data.reg_oper.client_if = p_msg->api_listen.client_if;
cb_data.reg_oper.status = BTM_BleBroadcast(p_msg->api_listen.start, NULL);
//TODO need modify callback if used
if (p_clreg && p_clreg->p_cback) {
(*p_clreg->p_cback)(BTA_GATTC_LISTEN_EVT, &cb_data);
}
@ -2354,14 +2352,14 @@ static void bta_gattc_wait4_service_change_ccc_cback (TIMER_LIST_ENT *p_tle)
BOOLEAN start_ccc_timer = FALSE;
UINT32 new_timeout;
assert(write_ccc_mutex != NULL);
osi_mutex_lock(&write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
assert(bta_gattc_cb.write_ccc_mutex != NULL);
osi_mutex_lock(&bta_gattc_cb.write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
tBTA_GATTC_WAIT_CCC_TIMER *p_timer_param = (tBTA_GATTC_WAIT_CCC_TIMER*) p_tle->param;
p_tle->param = (TIMER_PARAM_TYPE)0;
if (p_timer_param == NULL){
APPL_TRACE_ERROR("p_timer_param is NULL in %s\n", __func__);
osi_mutex_unlock(&write_ccc_mutex);
osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
return;
}
@ -2369,7 +2367,7 @@ static void bta_gattc_wait4_service_change_ccc_cback (TIMER_LIST_ENT *p_tle)
if (p_conn == NULL){
APPL_TRACE_ERROR("p_conn is NULL in %s\n", __func__);
osi_free(p_timer_param);
osi_mutex_unlock(&write_ccc_mutex);
osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
return;
}
@ -2401,7 +2399,7 @@ static void bta_gattc_wait4_service_change_ccc_cback (TIMER_LIST_ENT *p_tle)
}
osi_free(p_timer_param);
osi_mutex_unlock(&write_ccc_mutex);
osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
}
#endif

View file

@ -29,6 +29,7 @@
#include <string.h>
#include "bta_gattc_int.h"
#include "allocator.h"
/*****************************************************************************
@ -237,6 +238,8 @@ const tBTA_GATTC_ST_TBL bta_gattc_st_tbl[] = {
/* GATTC control block */
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_GATTC_CB bta_gattc_cb;
#else
tBTA_GATTC_CB *bta_gattc_cb_ptr;
#endif
#if BTA_GATT_DEBUG == TRUE
@ -493,4 +496,12 @@ static char *gattc_state_code(tBTA_GATTC_STATE state_code)
}
#endif /* Debug Functions */
void bta_gattc_deinit(void)
{
#if BTA_DYNAMIC_MEMORY
memset(bta_gattc_cb_ptr, 0, sizeof(tBTA_GATTC_CB));
FREE_AND_RESET(bta_gattc_cb_ptr);
#endif /* #if BTA_DYNAMIC_MEMORY */
}
#endif /* GATTC_INCLUDED == TRUE && BLE_INCLUDED == TRUE */

View file

@ -862,6 +862,10 @@ BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
if (p_conn != NULL) {
p_conn->in_use = FALSE;
memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
osi_mutex_lock(&bta_gattc_cb.write_ccc_mutex, OSI_MUTEX_MAX_TIMEOUT);
bta_sys_free_timer(&p_conn->service_change_ccc_timer);
p_conn->ccc_timer_used = FALSE;
osi_mutex_unlock(&bta_gattc_cb.write_ccc_mutex);
return TRUE;
}
return FALSE;

View file

@ -29,6 +29,7 @@
#include <string.h>
#include "bta_gatts_int.h"
#include "allocator.h"
/* type for service building action functions */
typedef void (*tBTA_GATTS_SRVC_ACT)(tBTA_GATTS_SRVC_CB *p_rcb, tBTA_GATTS_DATA *p_data);
@ -46,6 +47,8 @@ const tBTA_GATTS_SRVC_ACT bta_gatts_srvc_build_act[] = {
/* GATTS control block */
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_GATTS_CB bta_gatts_cb;
#else
tBTA_GATTS_CB *bta_gatts_cb_ptr;
#endif
/*******************************************************************************
@ -135,4 +138,12 @@ BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg)
return (TRUE);
}
void bta_gatts_deinit(void)
{
memset(&bta_gatts_cb, 0, sizeof(tBTA_GATTS_CB));
#if BTA_DYNAMIC_MEMORY
FREE_AND_RESET(bta_gatts_cb_ptr);
#endif /* #if BTA_DYNAMIC_MEMORY */
}
#endif /* GATTS_INCLUDED */

View file

@ -245,6 +245,8 @@ const tBTA_HH_ST_TBL bta_hh_st_tbl[] = {
*****************************************************************************/
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_HH_CB bta_hh_cb;
#else
tBTA_HH_CB *bta_hh_cb_ptr;
#endif
/*****************************************************************************
** Static functions

View file

@ -1130,6 +1130,7 @@ extern tBTA_DM_DI_CB *bta_dm_di_cb_ptr;
extern BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg);
extern void bta_dm_sm_disable( void );
extern void bta_dm_sm_deinit(void);
extern BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg);
extern void bta_dm_search_sm_disable( void );

View file

@ -30,6 +30,7 @@
#include "bta_gattc_ci.h"
#include "bta_gattc_co.h"
#include "fixed_queue.h"
#include "mutex.h"
/*****************************************************************************
** Constants and data types
@ -357,8 +358,8 @@ enum {
};
typedef struct {
UINT8 state;
UINT8 state;
osi_mutex_t write_ccc_mutex;
tBTA_GATTC_CONN conn_track[BTA_GATTC_CONN_MAX];
tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX];
tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX];
@ -514,5 +515,6 @@ extern BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda);
extern bool bta_gattc_cache_load(tBTA_GATTC_CLCB *p_clcb);
extern void bta_gattc_cache_reset(BD_ADDR server_bda);
extern void bta_gattc_deinit(void);
#endif /* BTA_GATTC_INT_H */

View file

@ -249,7 +249,7 @@ extern UINT8 bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB *p_cb, tBTA_GATT
extern UINT8 bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB *p_cb, UINT8 rcb_idx);
extern tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB *p_cb, UINT16 service_id);
extern tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB *p_cb, UINT16 attr_id);
extern void bta_gatts_deinit(void);
#endif /* BTA_GATTS_INT_H */

View file

@ -224,6 +224,7 @@ extern UINT16 bta_sys_get_sys_features(void);
extern void bta_sys_sendmsg(void *p_msg);
extern void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms);
extern void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle);
extern void bta_sys_free_timer(TIMER_LIST_ENT *p_tle);
extern void bta_sys_disable(tBTA_SYS_HW_MODULE module);
extern UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle);

View file

@ -37,6 +37,8 @@
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_SDP_CB bta_sdp_cb;
#else
tBTA_SDP_CB *bta_sdp_cb_ptr;
#endif
/* state machine action enumeration list */

View file

@ -48,6 +48,8 @@
/* system manager control block definition */
#if BTA_DYNAMIC_MEMORY == FALSE
tBTA_SYS_CB bta_sys_cb;
#else
tBTA_SYS_CB *bta_sys_cb_ptr;
#endif
static hash_map_t *bta_alarm_hash_map;
@ -190,6 +192,9 @@ void bta_sys_free(void)
{
hash_map_free(bta_alarm_hash_map);
osi_mutex_free(&bta_alarm_lock);
#if BTA_DYNAMIC_MEMORY
FREE_AND_RESET(bta_sys_cb_ptr);
#endif
}
/*******************************************************************************
@ -652,6 +657,28 @@ void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle)
osi_alarm_cancel(alarm);
}
/*******************************************************************************
**
** Function bta_sys_free_timer
**
** Description Stop and free a BTA timer.
**
** Returns void
**
*******************************************************************************/
void bta_sys_free_timer(TIMER_LIST_ENT *p_tle)
{
assert(p_tle != NULL);
osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
if (alarm == NULL) {
LOG_DEBUG("%s expected alarm was not in bta alarm hash map.", __func__);
return;
}
osi_alarm_cancel(alarm);
hash_map_erase(bta_alarm_hash_map, p_tle);
}
/*******************************************************************************
**
** Function bta_sys_disable

View file

@ -23,8 +23,13 @@
#if (SMP_INCLUDED == TRUE)
//the maximum nubmer of bonded devices
#define BONED_DEVICES_MAX_COUNT (BTM_SEC_MAX_DEVICE_RECORDS)
static void _btc_storage_save(void)
{
uint16_t addr_section_count = 0;
const btc_config_section_iter_t *need_remove_iter = NULL;
const btc_config_section_iter_t *iter = btc_config_section_begin();
while (iter != btc_config_section_end()) {
@ -48,10 +53,25 @@ static void _btc_storage_save(void)
btc_config_remove_section(section);
continue;
}
if(addr_section_count == BONED_DEVICES_MAX_COUNT) {
need_remove_iter = iter;
}
addr_section_count ++;
iter = btc_config_section_next(iter);
}
/*exceeded the maximum nubmer of bonded devices, delete them */
if (need_remove_iter) {
while(need_remove_iter != btc_config_section_end()) {
const char *need_remove_section = btc_config_section_name(need_remove_iter);
if (!string_is_bdaddr(need_remove_section)) {
need_remove_iter = btc_config_section_next(need_remove_iter);
continue;
}
need_remove_iter = btc_config_section_next(need_remove_iter);
BTIF_TRACE_WARNING("exceeded the maximum nubmer of bonded devices, delete the last device info : %s", need_remove_section);
btc_config_remove_section(need_remove_section);
}
}
btc_config_flush();
}

View file

@ -429,8 +429,8 @@ void btc_dm_sec_cb_handler(btc_msg_t *msg)
switch (msg->act) {
case BTA_DM_ENABLE_EVT: {
btc_clear_services_mask();
btc_storage_load_bonded_devices();
#if (SMP_INCLUDED == TRUE)
btc_storage_load_bonded_devices();
//load the bonding device to the btm layer
btc_storage_load_bonded_ble_devices();
#endif ///SMP_INCLUDED == TRUE

View file

@ -20,7 +20,10 @@
#include "btc_config.h"
#include "alarm.h"
#include "btc_ble_storage.h"
#include "bta_gatt_common.h"
#include "btc_gap_ble.h"
#include "bta_gattc_int.h"
#include "bta_gatts_int.h"
#include "bta_dm_int.h"
static future_t *main_future[BTC_MAIN_FUTURE_NUM];
@ -57,8 +60,8 @@ static void btc_init_bluetooth(void)
osi_alarm_create_mux();
osi_alarm_init();
bte_main_boot_entry(btc_init_callback);
btc_config_init();
#if (SMP_INCLUDED)
btc_config_init();
//load the ble local key whitch has been store in the flash
btc_dm_load_ble_local_keys();
#endif /* #if (SMP_INCLUDED) */
@ -67,18 +70,23 @@ static void btc_init_bluetooth(void)
static void btc_deinit_bluetooth(void)
{
btc_gap_ble_deinit();
bta_dm_sm_deinit();
#if (GATTC_INCLUDED)
bta_gattc_deinit();
#endif /* #if (GATTC_INCLUDED) */
#if (GATTS_INCLUDED)
bta_gatts_deinit();
#endif /* #if (GATTS_INCLUDED) */
bte_main_shutdown();
#if (SMP_INCLUDED)
btc_config_clean_up();
#endif
osi_alarm_deinit();
osi_alarm_delete_mux();
future_ready(*btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE), FUTURE_SUCCESS);
}
static void btc_set_local_mtu(uint16_t mtu)
{
BTA_GATT_SetLocalMTU(mtu);
}
void btc_main_call_handler(btc_msg_t *msg)
{
LOG_DEBUG("%s act %d\n", __func__, msg->act);
@ -96,12 +104,6 @@ void btc_main_call_handler(btc_msg_t *msg)
case BTC_MAIN_ACT_DISABLE:
btc_disable_bluetooth();
break;
case BTC_GATT_ACT_SET_LOCAL_MTU:
{
btc_ble_main_args_t *arg = (btc_ble_main_args_t *)(msg->arg);
btc_set_local_mtu(arg->set_mtu.mtu);
break;
}
default:
LOG_ERROR("%s UNKNOWN ACT %d\n", __func__, msg->act);
break;

View file

@ -24,20 +24,21 @@
#include "btc_dev.h"
#include "btc_gatts.h"
#include "btc_gattc.h"
#include "btc_gatt_common.h"
#include "btc_gap_ble.h"
#include "btc_blufi_prf.h"
#include "btc_dm.h"
#include "btc_alarm.h"
#include "bta_gatt_api.h"
#if CONFIG_CLASSIC_BT_ENABLED
#include "btc_profile_queue.h"
#if (BTC_GAP_BT_INCLUDED == TRUE)
#include "btc_gap_bt.h"
#endif /* BTC_GAP_BT_INCLUDED == TRUE */
#include "btc_profile_queue.h"
#if BTC_AV_INCLUDED
#include "btc_av.h"
#include "btc_avrc.h"
#endif /* #if BTC_AV_INCLUDED */
#endif /* #if BTC_AV_INCLUDED */
#if CONFIG_BT_SPP_ENABLED
#include "btc_spp.h"
#endif /* #if CONFIG_BT_SPP_ENABLED */
@ -48,33 +49,36 @@ static xTaskHandle xBtcTaskHandle = NULL;
static xQueueHandle xBtcQueue = 0;
static btc_func_t profile_tab[BTC_PID_NUM] = {
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
[BTC_PID_DEV] = {btc_dev_call_handler, NULL },
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
[BTC_PID_DEV] = {btc_dev_call_handler, NULL },
#if (GATTS_INCLUDED == TRUE)
[BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler },
[BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler },
#endif ///GATTS_INCLUDED == TRUE
#if (GATTC_INCLUDED == TRUE)
[BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler },
[BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler },
#endif ///GATTC_INCLUDED == TRUE
[BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler },
[BTC_PID_BLE_HID] = {NULL, NULL},
[BTC_PID_SPPLIKE] = {NULL, NULL},
#if (GATTS_INCLUDED == TRUE || GATTC_INCLUDED == TRUE)
[BTC_PID_GATT_COMMON] = {btc_gatt_com_call_handler, NULL },
#endif //GATTC_INCLUDED == TRUE || GATTS_INCLUDED == TRUE
[BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler },
[BTC_PID_BLE_HID] = {NULL, NULL},
[BTC_PID_SPPLIKE] = {NULL, NULL},
#if (GATTS_INCLUDED == TRUE)
[BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler },
[BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler },
#endif ///GATTS_INCLUDED == TRUE
[BTC_PID_DM_SEC] = {NULL, btc_dm_sec_cb_handler },
[BTC_PID_ALARM] = {btc_alarm_handler, NULL },
[BTC_PID_DM_SEC] = {NULL, btc_dm_sec_cb_handler },
[BTC_PID_ALARM] = {btc_alarm_handler, NULL },
#if CONFIG_CLASSIC_BT_ENABLED
#if (BTC_GAP_BT_INCLUDED == TRUE)
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, NULL },
[BTC_PID_GAP_BT] = {btc_gap_bt_call_handler, NULL },
#endif /* (BTC_GAP_BT_INCLUDED == TRUE) */
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
[BTC_PID_PRF_QUE] = {btc_profile_queue_handler, NULL },
#if BTC_AV_INCLUDED
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
[BTC_PID_AVRC] = {btc_avrc_call_handler, NULL },
[BTC_PID_A2DP] = {btc_a2dp_call_handler, btc_a2dp_cb_handler },
[BTC_PID_AVRC] = {btc_avrc_call_handler, NULL },
#endif /* #if BTC_AV_INCLUDED */
#if CONFIG_BT_SPP_ENABLED
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
[BTC_PID_SPP] = {btc_spp_call_handler, btc_spp_cb_handler },
#endif /* #if CONFIG_BT_SPP_ENABLED */
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
};

View file

@ -26,7 +26,6 @@ typedef enum {
BTC_MAIN_ACT_DEINIT,
BTC_MAIN_ACT_ENABLE,
BTC_MAIN_ACT_DISABLE,
BTC_GATT_ACT_SET_LOCAL_MTU,
} btc_main_act_t;
typedef enum {
@ -61,13 +60,5 @@ bt_status_t btc_init_bluetooth(future_t *future);
void btc_deinit_bluetooth(future_t *future);
#endif
/* btc_ble_gattc_args_t */
typedef union {
//BTC_GATT_ACT_SET_LOCAL_MTU,
struct set_mtu_arg {
uint16_t mtu;
} set_mtu;
} btc_ble_main_args_t;
void btc_main_call_handler(btc_msg_t *msg);
#endif /* __BTC_BT_MAIN_H__ */

View file

@ -41,6 +41,7 @@ typedef enum {
#if (GATTC_INCLUDED == TRUE)
BTC_PID_GATTC,
#endif ///GATTC_INCLUDED == TRUE
BTC_PID_GATT_COMMON,
BTC_PID_GAP_BLE,
BTC_PID_BLE_HID,
BTC_PID_SPPLIKE,

View file

@ -31,6 +31,7 @@
#include "btc_blufi_prf.h"
#include "btc_task.h"
#include "btc_manage.h"
#include "btc_gatt_util.h"
#include "blufi_int.h"
@ -209,6 +210,9 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
break;
case BTA_GATTS_CONF_EVT:
LOG_DEBUG("CONIRM EVT\n");
if (p_data && p_data->req_data.value){
osi_free(p_data->req_data.value);
}
/* Nothing */
break;
case BTA_GATTS_CREATE_EVT:
@ -276,7 +280,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
msg.pid = BTC_PID_BLUFI;
msg.act = ESP_BLUFI_EVENT_BLE_CONNECT;
memcpy(param.connect.remote_bda, p_data->conn.remote_bda, sizeof(esp_bd_addr_t));
param.connect.conn_id=p_data->conn.conn_id;
param.connect.conn_id=BTC_GATT_GET_CONN_ID(p_data->conn.conn_id);
param.connect.server_if=p_data->conn.server_if;
btc_transfer_context(&msg, &param, sizeof(esp_blufi_cb_param_t), NULL);
break;
@ -359,6 +363,17 @@ static void btc_blufi_send_notify(uint8_t *pkt, int pkt_len)
pkt, rsp);
}
void btc_blufi_report_error(esp_blufi_error_state_t state)
{
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_BLUFI;
msg.act = ESP_BLUFI_EVENT_REPORT_ERROR;
esp_blufi_cb_param_t param;
param.report_error.state = state;
btc_transfer_context(&msg, &param, sizeof(esp_blufi_cb_param_t), NULL);
}
static void btc_blufi_recv_handler(uint8_t *data, int len)
{
struct blufi_hdr *hdr = (struct blufi_hdr *)data;
@ -367,6 +382,7 @@ static void btc_blufi_recv_handler(uint8_t *data, int len)
if (hdr->seq != blufi_env.recv_seq) {
LOG_ERROR("%s seq %d is not expect %d\n", __func__, hdr->seq, blufi_env.recv_seq + 1);
btc_blufi_report_error(ESP_BLUFI_SEQUENCE_ERROR);
return;
}
@ -378,6 +394,7 @@ static void btc_blufi_recv_handler(uint8_t *data, int len)
ret = blufi_env.cbs->decrypt_func(hdr->seq, hdr->data, hdr->data_len);
if (ret != hdr->data_len) { /* enc must be success and enc len must equal to plain len */
LOG_ERROR("%s decrypt error %d\n", __func__, ret);
btc_blufi_report_error(ESP_BLUFI_DECRYPT_ERROR);
return;
}
}
@ -389,6 +406,7 @@ static void btc_blufi_recv_handler(uint8_t *data, int len)
checksum_pkt = hdr->data[hdr->data_len] | (((uint16_t) hdr->data[hdr->data_len + 1]) << 8);
if (checksum != checksum_pkt) {
LOG_ERROR("%s checksum error %04x, pkt %04x\n", __func__, checksum, checksum_pkt);
btc_blufi_report_error(ESP_BLUFI_CHECKSUM_ERROR);
return;
}
}
@ -464,7 +482,7 @@ void btc_blufi_send_encap(uint8_t type, uint8_t *data, int total_data_len)
checksum = blufi_env.cbs->checksum_func(hdr->seq, &hdr->seq, hdr->data_len + 2);
memcpy(&hdr->data[hdr->data_len], &checksum, 2);
}
} else if (!BLUFI_TYPE_IS_DATA_NEG(hdr->type)) {
} else if (!BLUFI_TYPE_IS_DATA_NEG(hdr->type) && !BLUFI_TYPE_IS_DATA_ERROR_INFO(hdr->type)) {
if ((blufi_env.sec_mode & BLUFI_DATA_SEC_MODE_CHECK_MASK)
&& (blufi_env.cbs && blufi_env.cbs->checksum_func)) {
hdr->fc |= BLUFI_FC_CHECK;
@ -479,6 +497,7 @@ void btc_blufi_send_encap(uint8_t type, uint8_t *data, int total_data_len)
hdr->fc |= BLUFI_FC_ENC;
} else {
LOG_ERROR("%s encrypt error %d\n", __func__, ret);
btc_blufi_report_error(ESP_BLUFI_ENCRYPT_ERROR);
osi_free(hdr);
return;
}
@ -574,6 +593,40 @@ static void btc_blufi_wifi_conn_report(uint8_t opmode, uint8_t sta_conn_state, u
osi_free(data);
}
void btc_blufi_send_wifi_list(uint16_t apCount, esp_blufi_ap_record_t *list)
{
uint8_t type;
uint8_t *data;
int data_len;
uint8_t *p;
// malloc size: (len + RSSI + ssid buffer) * apCount;
uint malloc_size = (1 + 1 + sizeof(list->ssid)) * apCount;
p = data = osi_malloc(malloc_size);
if (data == NULL) {
LOG_ERROR("malloc error\n");
return;
}
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST);
for (int i = 0; i < apCount; ++i)
{
uint len = strlen((const char *)list[i].ssid);
data_len = (p - data);
//current_len + ssid + rssi + total_len_value
if((data_len + len + 1 + 1) > malloc_size) {
LOG_ERROR("%s len error", __func__);
osi_free(data);
return;
}
*p++ = len + 1; // length of ssid + rssi
*p++ = list[i].rssi;
memcpy(p, list[i].ssid, len);
p = p + len;
}
data_len = (p - data);
btc_blufi_send_encap(type, data, data_len);
osi_free(data);
}
static void btc_blufi_send_ack(uint8_t seq)
{
uint8_t type;
@ -584,6 +637,28 @@ static void btc_blufi_send_ack(uint8_t seq)
btc_blufi_send_encap(type, &data, 1);
}
static void btc_blufi_send_error_info(uint8_t state)
{
uint8_t type;
uint8_t *data;
int data_len;
uint8_t *p;
data_len = 1;
p = data = osi_malloc(data_len);
if (data == NULL) {
return;
}
type = BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO);
*p++ = state;
if (p - data > data_len) {
LOG_ERROR("%s len error %d %d\n", __func__, (int)(p - data), data_len);
}
btc_blufi_send_encap(type, data, data_len);
osi_free(data);
}
void btc_blufi_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
@ -737,6 +812,9 @@ void btc_blufi_cb_handler(btc_msg_t *msg)
case ESP_BLUFI_EVENT_GET_WIFI_STATUS:
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_GET_WIFI_STATUS, NULL);
break;
case ESP_BLUFI_EVENT_GET_WIFI_LIST:
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_GET_WIFI_LIST, NULL);
break;
case ESP_BLUFI_EVENT_DEAUTHENTICATE_STA:
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_DEAUTHENTICATE_STA, NULL);
break;
@ -785,6 +863,9 @@ void btc_blufi_cb_handler(btc_msg_t *msg)
case ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE:
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE, param);
break;
case ESP_BLUFI_EVENT_REPORT_ERROR:
btc_blufi_cb_to_app(ESP_BLUFI_EVENT_REPORT_ERROR, param);
break;
default:
LOG_ERROR("%s UNKNOWN %d\n", __func__, msg->act);
break;
@ -867,6 +948,19 @@ void btc_blufi_call_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
}
break;
}
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{
esp_blufi_ap_record_t *list = src->wifi_list.list;
src->wifi_list.list = NULL;
if (list == NULL || src->wifi_list.apCount <= 0) {
break;
}
dst->wifi_list.list = (esp_blufi_ap_record_t *)osi_malloc(sizeof(esp_blufi_ap_record_t) * src->wifi_list.apCount);
if (dst->wifi_list.list == NULL) {
break;
}
memcpy(dst->wifi_list.list, list, sizeof(esp_blufi_ap_record_t) * src->wifi_list.apCount);
break;
}
default:
break;
}
@ -898,6 +992,13 @@ void btc_blufi_call_deep_free(btc_msg_t *msg)
osi_free(info);
break;
}
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{
esp_blufi_ap_record_t *list = (esp_blufi_ap_record_t *)arg->wifi_list.list;
if (list){
osi_free(list);
}
break;
}
default:
break;
}
@ -921,6 +1022,13 @@ void btc_blufi_call_handler(btc_msg_t *msg)
arg->wifi_conn_report.extra_info,
arg->wifi_conn_report.extra_info_len);
break;
case BTC_BLUFI_ACT_SEND_WIFI_LIST:{
btc_blufi_send_wifi_list(arg->wifi_list.apCount, arg->wifi_list.list);
break;
}
case BTC_BLUFI_ACT_SEND_ERR_INFO:
btc_blufi_send_error_info(arg->blufi_err_infor.state);
break;
default:
LOG_ERROR("%s UNKNOWN %d\n", __func__, msg->act);
break;

View file

@ -106,6 +106,12 @@ void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len)
msg.act = ESP_BLUFI_EVENT_RECV_SLAVE_DISCONNECT_BLE;
btc_transfer_context(&msg, NULL, 0, NULL);
break;
case BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST:
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_BLUFI;
msg.act = ESP_BLUFI_EVENT_GET_WIFI_LIST;
btc_transfer_context(&msg, NULL, 0, NULL);
break;
default:
LOG_ERROR("%s Unkown Ctrl pkt %02x\n", __func__, type);
break;

View file

@ -16,7 +16,7 @@
#define __BLUFI_INT_H__
#define BTC_BLUFI_GREAT_VER 0x01 //Version + Subversion
#define BTC_BLUFI_SUB_VER 0x00 //Version + Subversion
#define BTC_BLUFI_SUB_VER 0x01 //Version + Subversion
#define BTC_BLUFI_VERSION ((BTC_BLUFI_GREAT_VER<<8)|BTC_BLUFI_SUB_VER) //Version + Subversion
/* service engine control block */
@ -93,6 +93,7 @@ typedef struct blufi_frag_hdr blufi_frag_hdr_t;
#define BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA 0x06
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION 0x07
#define BLUFI_TYPE_CTRL_SUBTYPE_DISCONNECT_BLE 0x08
#define BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST 0x09
#define BLUFI_TYPE_DATA 0x1
#define BLUFI_TYPE_DATA_SUBTYPE_NEG 0x00
@ -111,7 +112,9 @@ typedef struct blufi_frag_hdr blufi_frag_hdr_t;
#define BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY 0x0d
#define BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY 0x0e
#define BLUFI_TYPE_DATA_SUBTYPE_WIFI_REP 0x0f
#define BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION 0x10
#define BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION 0x10
#define BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST 0x11
#define BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO 0x12
#define BLUFI_TYPE_IS_CTRL(type) (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_CTRL)
#define BLUFI_TYPE_IS_DATA(type) (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_DATA)
@ -140,6 +143,7 @@ typedef struct blufi_frag_hdr blufi_frag_hdr_t;
#define BLUFI_TYPE_IS_DATA_SERVER_CERT(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT)
#define BLUFI_TYPE_IS_DATA_CLIENT_PRIV_KEY(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY)
#define BLUFI_TYPE_IS_DATA_SERVER_PRIV_KEY(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY)
#define BLUFI_TYPE_IS_DATA_ERROR_INFO(type) (BLUFI_TYPE_IS_DATA((type)) && BLUFI_GET_SUBTYPE((type)) == BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO)
// packet frame control
#define BLUFI_FC_ENC_MASK 0x01

View file

@ -23,6 +23,8 @@ typedef enum {
BTC_BLUFI_ACT_INIT = 0,
BTC_BLUFI_ACT_DEINIT,
BTC_BLUFI_ACT_SEND_CFG_REPORT,
BTC_BLUFI_ACT_SEND_WIFI_LIST,
BTC_BLUFI_ACT_SEND_ERR_INFO,
} btc_blufi_act_t;
typedef union {
@ -33,6 +35,19 @@ typedef union {
esp_blufi_extra_info_t *extra_info;
int extra_info_len;
} wifi_conn_report;
/*
BTC_BLUFI_ACT_SEND_WIFI_LIST
*/
struct blufi_wifi_list {
uint16_t apCount;
esp_blufi_ap_record_t *list;
} wifi_list;
/*
BTC_BLUFI_ACT_SEND_ERR_INFO
*/
struct blufi_error_infor {
esp_blufi_error_state_t state;
} blufi_err_infor;
} btc_blufi_args_t;
void btc_blufi_cb_handler(btc_msg_t *msg);

View file

@ -31,7 +31,8 @@
#include "bta_av_co.h"
#include "bta_av_ci.h"
#include "bta_av_sbc.h"
#include "btc_media.h"
#include "btc_a2dp.h"
#include "btc_a2dp_source.h"
#include "btc_av_co.h"
#include "btc_util.h"
#include "mutex.h"
@ -954,12 +955,13 @@ extern void bta_av_co_audio_stop(tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type)
void *bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type, UINT32 *p_len,
UINT32 *p_timestamp)
{
#if BTC_AV_SRC_INCLUDED
BT_HDR *p_buf;
UNUSED(p_len);
FUNC_TRACE();
p_buf = btc_media_aa_readbuf();
p_buf = btc_a2dp_source_audio_readbuf();
if (p_buf != NULL) {
switch (codec_type) {
case BTA_AV_CODEC_SBC:
@ -992,6 +994,9 @@ void *bta_av_co_audio_src_data_path(tBTA_AV_CODEC codec_type, UINT32 *p_len,
#endif
}
return p_buf;
#else /* BTC_AV_SRC_INCLUDED */
return NULL;
#endif /* BTC_AV_SRC_INCLUDED */
}
/*******************************************************************************
@ -1379,7 +1384,7 @@ static BOOLEAN bta_av_co_audio_media_supports_config(UINT8 codec_type, const UIN
** Returns TRUE if all opened devices support this codec, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_audio_codec_supported(tBTC_STATUS *p_status)
BOOLEAN bta_av_co_audio_codec_supported(tBTC_AV_STATUS *p_status)
{
UINT8 index;
UINT8 snk_index;
@ -1449,7 +1454,7 @@ BOOLEAN bta_av_co_audio_codec_supported(tBTC_STATUS *p_status)
}
}
*p_status = BTC_SUCCESS;
*p_status = BTC_AV_SUCCESS;
return TRUE;
}
@ -1488,7 +1493,7 @@ void bta_av_co_audio_codec_reset(void)
** Returns TRUE if successful, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_audio_set_codec(const tBTC_AV_MEDIA_FEEDINGS *p_feeding, tBTC_STATUS *p_status)
BOOLEAN bta_av_co_audio_set_codec(const tBTC_AV_MEDIA_FEEDINGS *p_feeding, tBTC_AV_STATUS *p_status)
{
tA2D_SBC_CIE sbc_config;
tBTC_AV_CODEC_INFO new_cfg;
@ -1555,7 +1560,7 @@ BOOLEAN bta_av_co_audio_set_codec(const tBTC_AV_MEDIA_FEEDINGS *p_feeding, tBTC_
/* Check all devices support it */
*p_status = BTC_SUCCESS;
*p_status = BTC_AV_SUCCESS;
return bta_av_co_audio_codec_supported(p_status);
}

View file

@ -0,0 +1,153 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*****************************************************************************
*
* Filename: btc_a2dp.c
*
*****************************************************************************/
#include "bt_target.h"
#include "bt_trace.h"
#include "bta_api.h"
#include "bta_av_api.h"
#include "btc_av.h"
#include "btc_av_co.h"
#include "btc_a2dp.h"
#include "btc_a2dp_control.h"
#include "btc_a2dp_sink.h"
#include "btc_a2dp_source.h"
#if BTC_AV_INCLUDED
/*****************************************************************************
**
** Function btc_a2dp_on_init
**
*******************************************************************************/
void btc_a2dp_on_init(void)
{
//tput_mon(1, 0, 1);
}
/*****************************************************************************
**
** Function btc_a2dp_on_idle
**
*******************************************************************************/
void btc_a2dp_on_idle(void)
{
APPL_TRACE_EVENT("## ON A2DP IDLE ## peer_sep = %d", btc_av_get_peer_sep());
#if BTC_AV_SRC_INCLUDED
if (btc_av_get_peer_sep() == AVDT_TSEP_SNK) {
btc_a2dp_source_on_idle();
}
#endif // BTC_AV_SRC_INCLUDED
bta_av_co_init();
#if BTC_AV_SINK_INCLUDED
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC) {
btc_a2dp_sink_on_idle();
}
#endif // BTC_AV_SINK_INCLUDED
}
/*****************************************************************************
**
** Function btc_a2dp_on_started
**
** Description
**
** Returns
**
*******************************************************************************/
BOOLEAN btc_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start)
{
BOOLEAN ack = FALSE;
APPL_TRACE_EVENT("## ON A2DP STARTED ##");
#if BTC_AV_SRC_INCLUDED
if (p_av == NULL) {
/* ack back a local start request */
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
return TRUE;
}
if (p_av->status == BTA_AV_SUCCESS) {
if (p_av->suspending == FALSE) {
if (p_av->initiator) {
if (pending_start) {
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
ack = TRUE;
}
} else {
/* we were remotely started, make sure codec
is setup before datapath is started */
btc_a2dp_source_setup_codec();
}
/* media task is autostarted upon a2dp audiopath connection */
}
} else if (pending_start) {
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
ack = TRUE;
}
#endif /* BTC_AV_SRC_INCLUDED */
return ack;
}
/*****************************************************************************
**
** Function btc_a2dp_on_stopped
**
*******************************************************************************/
void btc_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av)
{
APPL_TRACE_EVENT("## ON A2DP STOPPED ##");
#if BTC_AV_SINK_INCLUDED
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC) {
btc_a2dp_sink_on_stopped(p_av);
return;
}
#endif // BTC_AV_SINK_INCLUDED
#if BTC_AV_SRC_INCLUDED
btc_a2dp_source_on_stopped(p_av);
#endif // BTC_AV_SRC_INCLUDED
}
/*****************************************************************************
**
** Function btc_a2dp_on_suspended
**
*******************************************************************************/
void btc_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av)
{
APPL_TRACE_EVENT("## ON A2DP SUSPENDED ##");
#if BTC_AV_SINK_INCLUDED
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC) {
btc_a2dp_sink_on_suspended(p_av);
return;
}
#endif // BTC_AV_SINK_INCLUDED
#if BTC_AV_SRC_INCLUDED
btc_a2dp_source_on_suspended(p_av);
#endif // BTC_AV_SRC_INCLUDED
}
#endif /* #if BTC_AV_INCLUDED */

View file

@ -0,0 +1,220 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*****************************************************************************
*
* Filename: btc_a2dp_control.c
*
*****************************************************************************/
#include "bt_target.h"
#include <string.h>
#include "bt_trace.h"
#include "bta_api.h"
#include "bta_av_api.h"
#include "btc_manage.h"
#include "btc_av.h"
#include "btc_a2dp.h"
#include "btc_a2dp_control.h"
#include "btc_a2dp_sink.h"
#include "btc_a2dp_source.h"
#include "esp_a2dp_api.h"
#if BTC_AV_INCLUDED
typedef struct {
BOOLEAN data_channel_open;
UINT8 a2dp_cmd_pending; /* we can have max one command pending */
} tBTC_AA_CTRL_CB;
static tBTC_AA_CTRL_CB btc_aa_ctrl_cb;
static inline void btc_a2d_cb_to_app(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
{
esp_a2d_cb_t btc_a2d_cb = (esp_a2d_cb_t)btc_profile_cb_get(BTC_PID_A2DP);
if (btc_a2d_cb) {
btc_a2d_cb(event, param);
}
}
static inline void a2dp_cmd_acknowledge(int cmd, int status)
{
esp_a2d_cb_param_t param;
param.media_ctrl_stat.cmd = cmd;
param.media_ctrl_stat.status = status;
btc_a2d_cb_to_app(ESP_A2D_MEDIA_CTRL_ACK_EVT, &param);
}
void btc_a2dp_control_command_ack(int status)
{
/* sanity check */
if (btc_aa_ctrl_cb.a2dp_cmd_pending == ESP_A2D_MEDIA_CTRL_NONE) {
APPL_TRACE_ERROR("warning : no command pending, ignore ack");
return;
}
/* clear pending */
int cmd = btc_aa_ctrl_cb.a2dp_cmd_pending;
btc_aa_ctrl_cb.a2dp_cmd_pending = ESP_A2D_MEDIA_CTRL_NONE;
a2dp_cmd_acknowledge(cmd, status);
}
static void btc_a2dp_datapath_open(void)
{
#if BTC_AV_SRC_INCLUDED
if (btc_av_get_peer_sep() == AVDT_TSEP_SNK) {
/* Start the media task to encode SBC */
btc_a2dp_source_start_audio_req();
/* make sure we update any changed sbc encoder params */
btc_a2dp_source_encoder_update();
}
#endif
btc_aa_ctrl_cb.data_channel_open = TRUE;
}
BOOLEAN btc_a2dp_control_get_datachnl_stat(void)
{
return btc_aa_ctrl_cb.data_channel_open;
}
void btc_a2dp_control_set_datachnl_stat(BOOLEAN open)
{
btc_aa_ctrl_cb.data_channel_open = open;
}
static void btc_a2dp_dispatch_datapath_evt(uint32_t dp_evt)
{
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_DATAPATH_CTRL_EVT;
btc_av_args_t arg;
memset(&arg, 0, sizeof(btc_av_args_t));
arg.dp_evt = dp_evt;
/* Switch to BTC context */
APPL_TRACE_DEBUG("%s sig %u act %u, dp_evt %u\n", __func__, msg.sig, msg.act, arg.dp_evt);
btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
}
void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl)
{
APPL_TRACE_DEBUG("BTC MEDIA (A2DP-DATA) EVENT %u", ctrl);
if (btc_aa_ctrl_cb.a2dp_cmd_pending != ESP_A2D_MEDIA_CTRL_NONE) {
APPL_TRACE_DEBUG("un-acked a2dp cmd: %u", btc_aa_ctrl_cb.a2dp_cmd_pending);
a2dp_cmd_acknowledge(ctrl, ESP_A2D_MEDIA_CTRL_ACK_BUSY);
return;
}
btc_aa_ctrl_cb.a2dp_cmd_pending = ctrl;
switch (ctrl) {
case ESP_A2D_MEDIA_CTRL_CHECK_SRC_RDY:
#if BTC_AV_SRC_INCLUDED
if (btc_a2dp_source_is_task_shutting_down()) {
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
} else if ((btc_av_stream_ready() == TRUE) ||
(btc_av_stream_started_ready() == TRUE)) {
/* check whether av is ready to setup a2dp datapath */
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
} else {
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
}
#else /* BTC_AV_SRC_INCLUDED */
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
#endif /* #if BTC_AV_SRC_INCLUDED */
break;
case ESP_A2D_MEDIA_CTRL_START:
if (btc_av_stream_ready() == TRUE ) {
/* post start event and wait for audio path to open */
btc_dispatch_sm_event(BTC_AV_START_STREAM_REQ_EVT, NULL, 0);
btc_a2dp_dispatch_datapath_evt(BTC_AV_DATAPATH_OPEN_EVT);
#if (BTC_AV_SINK_INCLUDED == TRUE)
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC) {
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
}
#endif
} else if (btc_av_stream_started_ready()) {
btc_a2dp_dispatch_datapath_evt(BTC_AV_DATAPATH_OPEN_EVT);
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
} else {
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
}
break;
case ESP_A2D_MEDIA_CTRL_STOP:
#if BTC_AV_SRC_INCLUDED
if (btc_av_get_peer_sep() == AVDT_TSEP_SNK && !btc_a2dp_source_is_streaming()) {
/* we are already stopped, just ack back*/
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
break;
}
#endif /* BTC_AV_SRC_INCLUDED */
btc_dispatch_sm_event(BTC_AV_STOP_STREAM_REQ_EVT, NULL, 0);
#if (BTC_AV_SINK_INCLUDED == TRUE)
if (btc_av_get_peer_sep() == AVDT_TSEP_SRC) {
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
}
#endif
break;
case ESP_A2D_MEDIA_CTRL_SUSPEND:
/* local suspend */
if (btc_av_stream_started_ready()) {
btc_dispatch_sm_event(BTC_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
} else {
/* we are not in started state; just ack back ok. This can happen if we are
remotely suspended; clear REMOTE SUSPEND Flag */
btc_av_clear_remote_suspend_flag();
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_SUCCESS);
}
break;
default :
APPL_TRACE_ERROR("### A2DP-MEDIA EVENT %u NOT HANDLED ###", ctrl);
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
break;
}
}
void btc_a2dp_control_datapath_ctrl(uint32_t dp_evt)
{
switch (dp_evt) {
case BTC_AV_DATAPATH_OPEN_EVT: {
btc_a2dp_datapath_open();
break;
}
default:
break;
}
return;
}
bool btc_a2dp_control_init(void)
{
memset(&btc_aa_ctrl_cb, 0, sizeof(tBTC_AA_CTRL_CB));
return true;
}
void btc_a2dp_control_cleanup(void)
{
memset(&btc_aa_ctrl_cb, 0, sizeof(tBTC_AA_CTRL_CB));
}
#endif /* #if BTC_AV_INCLUDED */

View file

@ -0,0 +1,763 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/******************************************************************************
**
** Name: btc_a2dp_sink.c
**
******************************************************************************/
#include "bt_target.h"
#include "bt_trace.h"
#include <string.h>
#include <stdint.h>
#include "bt_defs.h"
#include "allocator.h"
#include "mutex.h"
#include "thread.h"
#include "fixed_queue.h"
#include "a2d_api.h"
#include "a2d_sbc.h"
#include "bta_av_api.h"
#include "bta_av_ci.h"
#include "btc_av_co.h"
#include "btc_a2dp.h"
#include "btc_a2dp_control.h"
#include "btc_a2dp_sink.h"
#include "btc_manage.h"
#include "btc_av.h"
#include "btc_util.h"
#include "esp_a2dp_api.h"
#include "oi_codec_sbc.h"
#include "oi_status.h"
#if (BTC_AV_SINK_INCLUDED == TRUE)
/*****************************************************************************
** Constants
*****************************************************************************/
/* BTC media cmd event definition : BTC_MEDIA_TASK_CMD */
enum {
BTC_MEDIA_TASK_SINK_INIT,
BTC_MEDIA_TASK_SINK_CLEAN_UP,
BTC_MEDIA_FLUSH_AA_RX,
BTC_MEDIA_AUDIO_SINK_CFG_UPDATE,
BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK,
};
enum {
BTC_A2DP_SINK_STATE_OFF = 0,
BTC_A2DP_SINK_STATE_ON = 1,
BTC_A2DP_SINK_STATE_SHUTTING_DOWN = 2
};
enum {
BTC_A2DP_SINK_DATA_EVT = 0,
};
/*
* CONGESTION COMPENSATION CTRL ::
*
* Thus setting controls how many buffers we will hold in media task
* during temp link congestion. Together with the stack buffer queues
* it controls much temporary a2dp link congestion we can
* compensate for. It however also depends on the default run level of sinks
* jitterbuffers. Depending on type of sink this would vary.
* Ideally the (SRC) max tx buffer capacity should equal the sinks
* jitterbuffer runlevel including any intermediate buffers on the way
* towards the sinks codec.
*/
/* fixme -- define this in pcm time instead of buffer count */
/* The typical runlevel of the tx queue size is ~1 buffer
but due to link flow control or thread preemption in lower
layers we might need to temporarily buffer up data */
/* 5 frames is equivalent to 6.89*5*2.9 ~= 100 ms @ 44.1 khz, 20 ms mediatick */
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (5)
typedef struct {
UINT16 num_frames_to_be_processed;
UINT16 len;
UINT16 offset;
UINT16 layer_specific;
} tBT_SBC_HDR;
typedef struct {
BOOLEAN rx_flush; /* discards any incoming data when true */
UINT8 channel_count;
fixed_queue_t *RxSbcQ;
UINT32 sample_rate;
} tBTC_A2DP_SINK_CB;
static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context);
static void btc_a2dp_sink_thread_cleanup(UNUSED_ATTR void *context);
static void btc_a2dp_sink_flush_q(fixed_queue_t *p_q);
static void btc_a2dp_sink_rx_flush(void);
static int btc_a2dp_sink_get_track_frequency(UINT8 frequency);
static int btc_a2dp_sink_get_track_channel_count(UINT8 channeltype);
/* Handle incoming media packets A2DP SINK streaming*/
static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg);
static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg);
static void btc_a2dp_sink_handle_clear_track(void);
static BOOLEAN btc_a2dp_sink_clear_track(void);
static void btc_a2dp_sink_task_handler(void *arg);
static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context);
static tBTC_A2DP_SINK_CB btc_aa_snk_cb;
static int btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF;
static xTaskHandle btc_aa_snk_task_hdl = NULL;
static QueueHandle_t btc_aa_snk_data_queue = NULL;
static QueueHandle_t btc_aa_snk_ctrl_queue = NULL;
static QueueSetHandle_t btc_aa_snk_queue_set;
static esp_a2d_sink_data_cb_t bt_aa_snk_data_cb = NULL;
void btc_a2dp_sink_reg_data_cb(esp_a2d_sink_data_cb_t callback)
{
// todo: critical section protection
bt_aa_snk_data_cb = callback;
}
static inline void btc_a2d_data_cb_to_app(const uint8_t *data, uint32_t len)
{
// todo: critical section protection
if (bt_aa_snk_data_cb) {
bt_aa_snk_data_cb(data, len);
}
}
OI_CODEC_SBC_DECODER_CONTEXT context;
OI_UINT32 contextData[CODEC_DATA_WORDS(2, SBC_CODEC_FAST_FILTER_BUFFERS)];
OI_INT16 pcmData[15 * SBC_MAX_SAMPLES_PER_FRAME * SBC_MAX_CHANNELS];
/*****************************************************************************
** Misc helper functions
*****************************************************************************/
static inline void btc_a2d_cb_to_app(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param)
{
esp_a2d_cb_t btc_aa_cb = (esp_a2d_cb_t)btc_profile_cb_get(BTC_PID_A2DP);
if (btc_aa_cb) {
btc_aa_cb(event, param);
}
}
/*****************************************************************************
** BTC ADAPTATION
*****************************************************************************/
static void btc_a2dp_sink_ctrl_post(uint32_t sig, void *par)
{
BtTaskEvt_t *evt = (BtTaskEvt_t *)osi_malloc(sizeof(BtTaskEvt_t));
if (evt == NULL) {
return;
}
evt->sig = sig;
evt->par = par;
if (xQueueSend(btc_aa_snk_ctrl_queue, &evt, portMAX_DELAY) != pdTRUE) {
APPL_TRACE_WARNING("btc_aa_snk_ctrl_queue failed, sig 0x%x\n", sig);
}
}
static void btc_a2dp_sink_ctrl_handler(BtTaskEvt_t *e)
{
if (e == NULL) {
return;
}
switch (e->sig) {
case BTC_MEDIA_TASK_SINK_INIT:
btc_a2dp_sink_thread_init(NULL);
break;
case BTC_MEDIA_TASK_SINK_CLEAN_UP:
btc_a2dp_sink_thread_cleanup(NULL);
break;
case BTC_MEDIA_AUDIO_SINK_CFG_UPDATE:
btc_a2dp_sink_handle_decoder_reset(e->par);
break;
case BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK:
btc_a2dp_sink_handle_clear_track();
break;
case BTC_MEDIA_FLUSH_AA_RX:
btc_a2dp_sink_rx_flush();
break;
default:
APPL_TRACE_WARNING("media task unhandled evt: 0x%x\n", e->sig);
}
if (e->par != NULL) {
osi_free(e->par);
}
}
static void btc_a2dp_sink_task_handler(void *arg)
{
QueueSetMemberHandle_t xActivatedMember;
BtTaskEvt_t *e = NULL;
for (;;) {
xActivatedMember = xQueueSelectFromSet(btc_aa_snk_queue_set, portMAX_DELAY);
if (xActivatedMember == btc_aa_snk_data_queue) {
int32_t data_evt;
xQueueReceive(xActivatedMember, &data_evt, 0);
if (data_evt == BTC_A2DP_SINK_DATA_EVT) {
btc_a2dp_sink_data_ready(NULL);
}
} else if (xActivatedMember == btc_aa_snk_ctrl_queue) {
xQueueReceive(xActivatedMember, &e, 0);
btc_a2dp_sink_ctrl_handler(e);
osi_free(e);
}
}
}
bool btc_a2dp_sink_startup(void)
{
if (btc_a2dp_sink_state != BTC_A2DP_SINK_STATE_OFF) {
APPL_TRACE_ERROR("warning : media task already running");
return false;
}
APPL_TRACE_EVENT("## A2DP SINK START MEDIA THREAD ##");
btc_aa_snk_queue_set = xQueueCreateSet(BTC_A2DP_SINK_TASK_QUEUE_SET_LEN);
configASSERT(btc_aa_snk_queue_set);
btc_aa_snk_data_queue = xQueueCreate(BTC_A2DP_SINK_DATA_QUEUE_LEN, sizeof(int32_t));
configASSERT(btc_aa_snk_data_queue);
xQueueAddToSet(btc_aa_snk_data_queue, btc_aa_snk_queue_set);
btc_aa_snk_ctrl_queue = xQueueCreate(BTC_A2DP_SINK_CTRL_QUEUE_LEN, sizeof(void *));
configASSERT(btc_aa_snk_ctrl_queue);
xQueueAddToSet(btc_aa_snk_ctrl_queue, btc_aa_snk_queue_set);
if (!btc_aa_snk_data_queue || !btc_aa_snk_ctrl_queue || !btc_aa_snk_queue_set ) {
goto error_exit;
}
xTaskCreatePinnedToCore(btc_a2dp_sink_task_handler, BTC_A2DP_SINK_TASK_NAME, BTC_A2DP_SINK_TASK_STACK_SIZE, NULL, BTC_A2DP_SINK_TASK_PRIO, &btc_aa_snk_task_hdl, BTC_A2DP_SINK_TASK_PINNED_TO_CORE);
if (btc_aa_snk_task_hdl == NULL) {
goto error_exit;
}
btc_a2dp_sink_ctrl_post(BTC_MEDIA_TASK_SINK_INIT, NULL);
APPL_TRACE_EVENT("## A2DP SINK MEDIA THREAD STARTED ##\n");
return true;
error_exit:;
APPL_TRACE_ERROR("%s unable to start up media thread\n", __func__);
if (btc_aa_snk_task_hdl != NULL) {
vTaskDelete(btc_aa_snk_task_hdl);
btc_aa_snk_task_hdl = NULL;
}
if (btc_aa_snk_data_queue) {
vQueueDelete(btc_aa_snk_data_queue);
btc_aa_snk_data_queue = NULL;
}
if (btc_aa_snk_ctrl_queue) {
vQueueDelete(btc_aa_snk_ctrl_queue);
btc_aa_snk_ctrl_queue = NULL;
}
return false;
}
void btc_a2dp_sink_shutdown(void)
{
APPL_TRACE_EVENT("## A2DP SINK STOP MEDIA THREAD ##\n");
// Exit thread
btc_a2dp_sink_ctrl_post(BTC_MEDIA_TASK_SINK_CLEAN_UP, NULL);
vTaskDelete(btc_aa_snk_task_hdl);
btc_aa_snk_task_hdl = NULL;
vQueueDelete(btc_aa_snk_data_queue);
btc_aa_snk_data_queue = NULL;
vQueueDelete(btc_aa_snk_ctrl_queue);
btc_aa_snk_ctrl_queue = NULL;
}
/*****************************************************************************
**
** Function btc_a2dp_sink_on_idle
**
*******************************************************************************/
void btc_a2dp_sink_on_idle(void)
{
btc_aa_snk_cb.rx_flush = TRUE;
btc_a2dp_sink_rx_flush_req();
btc_a2dp_sink_clear_track();
APPL_TRACE_DEBUG("Stopped BT track");
}
/*****************************************************************************
**
** Function btc_a2dp_sink_on_stopped
**
*******************************************************************************/
void btc_a2dp_sink_on_stopped(tBTA_AV_SUSPEND *p_av)
{
btc_aa_snk_cb.rx_flush = TRUE;
btc_a2dp_sink_rx_flush_req();
btc_a2dp_control_set_datachnl_stat(FALSE);
}
/*****************************************************************************
**
** Function btc_a2dp_on_suspended
**
*******************************************************************************/
void btc_a2dp_sink_on_suspended(tBTA_AV_SUSPEND *p_av)
{
btc_aa_snk_cb.rx_flush = TRUE;
btc_a2dp_sink_rx_flush_req();
return;
}
static void btc_a2dp_sink_data_post(int32_t data_type)
{
if (xQueueSend(btc_aa_snk_data_queue, &data_type, 0) != pdTRUE) {
APPL_TRACE_DEBUG("Media data Q filled\n");
}
}
/*******************************************************************************
**
** Function btc_a2dp_sink_clear_track
**
** Description
**
** Returns TRUE is success
**
*******************************************************************************/
static BOOLEAN btc_a2dp_sink_clear_track(void)
{
btc_a2dp_sink_ctrl_post(BTC_MEDIA_AUDIO_SINK_CLEAR_TRACK, NULL);
return TRUE;
}
/* when true media task discards any rx frames */
void btc_a2dp_sink_set_rx_flush(BOOLEAN enable)
{
APPL_TRACE_EVENT("## DROP RX %d ##\n", enable);
btc_aa_snk_cb.rx_flush = enable;
}
/*****************************************************************************
**
** Function btc_a2dp_sink_reset_decoder
**
** Description
**
** Returns
**
*******************************************************************************/
void btc_a2dp_sink_reset_decoder(UINT8 *p_av)
{
APPL_TRACE_EVENT("btc reset decoder");
APPL_TRACE_DEBUG("btc reset decoder p_codec_info[%x:%x:%x:%x:%x:%x]\n",
p_av[1], p_av[2], p_av[3],
p_av[4], p_av[5], p_av[6]);
tBTC_MEDIA_SINK_CFG_UPDATE *p_buf;
if (NULL == (p_buf = osi_malloc(sizeof(tBTC_MEDIA_SINK_CFG_UPDATE)))) {
APPL_TRACE_ERROR("btc reset decoder No Buffer ");
return;
}
memcpy(p_buf->codec_info, p_av, AVDT_CODEC_SIZE);
btc_a2dp_sink_ctrl_post(BTC_MEDIA_AUDIO_SINK_CFG_UPDATE, p_buf);
}
static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
{
tBT_SBC_HDR *p_msg;
if (fixed_queue_is_empty(btc_aa_snk_cb.RxSbcQ)) {
APPL_TRACE_DEBUG(" QUE EMPTY ");
} else {
if (btc_aa_snk_cb.rx_flush == TRUE) {
btc_a2dp_sink_flush_q(btc_aa_snk_cb.RxSbcQ);
return;
}
while ((p_msg = (tBT_SBC_HDR *)fixed_queue_try_peek_first(btc_aa_snk_cb.RxSbcQ)) != NULL ) {
btc_a2dp_sink_handle_inc_media(p_msg);
p_msg = (tBT_SBC_HDR *)fixed_queue_try_dequeue(btc_aa_snk_cb.RxSbcQ);
if ( p_msg == NULL ) {
APPL_TRACE_ERROR("Insufficient data in que ");
break;
}
osi_free(p_msg);
}
APPL_TRACE_DEBUG(" Process Frames - ");
}
}
/*******************************************************************************
**
** Function btc_a2dp_sink_handle_decoder_reset
**
** Description
**
** Returns void
**
*******************************************************************************/
static void btc_a2dp_sink_handle_decoder_reset(tBTC_MEDIA_SINK_CFG_UPDATE *p_msg)
{
tBTC_MEDIA_SINK_CFG_UPDATE *p_buf = p_msg;
tA2D_STATUS a2d_status;
tA2D_SBC_CIE sbc_cie;
OI_STATUS status;
UINT32 freq_multiple = 48 * 20; /* frequency multiple for 20ms of data , initialize with 48K*/
UINT32 num_blocks = 16;
UINT32 num_subbands = 8;
APPL_TRACE_EVENT("%s p_codec_info[%x:%x:%x:%x:%x:%x]\n", __FUNCTION__,
p_buf->codec_info[1], p_buf->codec_info[2], p_buf->codec_info[3],
p_buf->codec_info[4], p_buf->codec_info[5], p_buf->codec_info[6]);
a2d_status = A2D_ParsSbcInfo(&sbc_cie, p_buf->codec_info, FALSE);
if (a2d_status != A2D_SUCCESS) {
APPL_TRACE_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
return;
}
btc_aa_snk_cb.sample_rate = btc_a2dp_sink_get_track_frequency(sbc_cie.samp_freq);
btc_aa_snk_cb.channel_count = btc_a2dp_sink_get_track_channel_count(sbc_cie.ch_mode);
btc_aa_snk_cb.rx_flush = FALSE;
APPL_TRACE_EVENT("Reset to sink role");
status = OI_CODEC_SBC_DecoderReset(&context, contextData, sizeof(contextData), 2, 2, FALSE);
if (!OI_SUCCESS(status)) {
APPL_TRACE_ERROR("OI_CODEC_SBC_DecoderReset failed with error code %d\n", status);
}
btc_a2dp_control_set_datachnl_stat(TRUE);
switch (sbc_cie.samp_freq) {
case A2D_SBC_IE_SAMP_FREQ_16:
APPL_TRACE_DEBUG("\tsamp_freq:%d (16000)\n", sbc_cie.samp_freq);
freq_multiple = 16 * 20;
break;
case A2D_SBC_IE_SAMP_FREQ_32:
APPL_TRACE_DEBUG("\tsamp_freq:%d (32000)\n", sbc_cie.samp_freq);
freq_multiple = 32 * 20;
break;
case A2D_SBC_IE_SAMP_FREQ_44:
APPL_TRACE_DEBUG("\tsamp_freq:%d (44100)\n", sbc_cie.samp_freq);
freq_multiple = 441 * 2;
break;
case A2D_SBC_IE_SAMP_FREQ_48:
APPL_TRACE_DEBUG("\tsamp_freq:%d (48000)\n", sbc_cie.samp_freq);
freq_multiple = 48 * 20;
break;
default:
APPL_TRACE_DEBUG(" Unknown Frequency ");
break;
}
switch (sbc_cie.ch_mode) {
case A2D_SBC_IE_CH_MD_MONO:
APPL_TRACE_DEBUG("\tch_mode:%d (Mono)\n", sbc_cie.ch_mode);
break;
case A2D_SBC_IE_CH_MD_DUAL:
APPL_TRACE_DEBUG("\tch_mode:%d (DUAL)\n", sbc_cie.ch_mode);
break;
case A2D_SBC_IE_CH_MD_STEREO:
APPL_TRACE_DEBUG("\tch_mode:%d (STEREO)\n", sbc_cie.ch_mode);
break;
case A2D_SBC_IE_CH_MD_JOINT:
APPL_TRACE_DEBUG("\tch_mode:%d (JOINT)\n", sbc_cie.ch_mode);
break;
default:
APPL_TRACE_DEBUG(" Unknown Mode ");
break;
}
switch (sbc_cie.block_len) {
case A2D_SBC_IE_BLOCKS_4:
APPL_TRACE_DEBUG("\tblock_len:%d (4)\n", sbc_cie.block_len);
num_blocks = 4;
break;
case A2D_SBC_IE_BLOCKS_8:
APPL_TRACE_DEBUG("\tblock_len:%d (8)\n", sbc_cie.block_len);
num_blocks = 8;
break;
case A2D_SBC_IE_BLOCKS_12:
APPL_TRACE_DEBUG("\tblock_len:%d (12)\n", sbc_cie.block_len);
num_blocks = 12;
break;
case A2D_SBC_IE_BLOCKS_16:
APPL_TRACE_DEBUG("\tblock_len:%d (16)\n", sbc_cie.block_len);
num_blocks = 16;
break;
default:
APPL_TRACE_DEBUG(" Unknown BlockLen ");
break;
}
switch (sbc_cie.num_subbands) {
case A2D_SBC_IE_SUBBAND_4:
APPL_TRACE_DEBUG("\tnum_subbands:%d (4)\n", sbc_cie.num_subbands);
num_subbands = 4;
break;
case A2D_SBC_IE_SUBBAND_8:
APPL_TRACE_DEBUG("\tnum_subbands:%d (8)\n", sbc_cie.num_subbands);
num_subbands = 8;
break;
default:
APPL_TRACE_DEBUG(" Unknown SubBands ");
break;
}
switch (sbc_cie.alloc_mthd) {
case A2D_SBC_IE_ALLOC_MD_S:
APPL_TRACE_DEBUG("\talloc_mthd:%d (SNR)\n", sbc_cie.alloc_mthd);
break;
case A2D_SBC_IE_ALLOC_MD_L:
APPL_TRACE_DEBUG("\talloc_mthd:%d (Loudness)\n", sbc_cie.alloc_mthd);
break;
default:
APPL_TRACE_DEBUG(" Unknown Allocation Method");
break;
}
APPL_TRACE_EVENT("\tBit pool Min:%d Max:%d\n", sbc_cie.min_bitpool, sbc_cie.max_bitpool);
int frames_to_process = ((freq_multiple) / (num_blocks * num_subbands)) + 1;
APPL_TRACE_EVENT(" Frames to be processed in 20 ms %d\n", frames_to_process);
}
/*******************************************************************************
**
** Function btc_a2dp_sink_handle_inc_media
**
** Description
**
** Returns void
**
*******************************************************************************/
static void btc_a2dp_sink_handle_inc_media(tBT_SBC_HDR *p_msg)
{
UINT8 *sbc_start_frame = ((UINT8 *)(p_msg + 1) + p_msg->offset + 1);
int count;
UINT32 pcmBytes, availPcmBytes;
OI_INT16 *pcmDataPointer = pcmData; /*Will be overwritten on next packet receipt*/
OI_STATUS status;
int num_sbc_frames = p_msg->num_frames_to_be_processed;
UINT32 sbc_frame_len = p_msg->len - 1;
availPcmBytes = 2 * sizeof(pcmData);
if (btc_av_get_peer_sep() == AVDT_TSEP_SNK || (btc_aa_snk_cb.rx_flush)) {
APPL_TRACE_DEBUG(" State Changed happened in this tick ");
return;
}
// ignore data if no one is listening
if (!btc_a2dp_control_get_datachnl_stat()) {
return;
}
APPL_TRACE_DEBUG("Number of sbc frames %d, frame_len %d\n", num_sbc_frames, sbc_frame_len);
for (count = 0; count < num_sbc_frames && sbc_frame_len != 0; count ++) {
pcmBytes = availPcmBytes;
status = OI_CODEC_SBC_DecodeFrame(&context, (const OI_BYTE **)&sbc_start_frame,
(OI_UINT32 *)&sbc_frame_len,
(OI_INT16 *)pcmDataPointer,
(OI_UINT32 *)&pcmBytes);
if (!OI_SUCCESS(status)) {
APPL_TRACE_ERROR("Decoding failure: %d\n", status);
break;
}
availPcmBytes -= pcmBytes;
pcmDataPointer += pcmBytes / 2;
p_msg->offset += (p_msg->len - 1) - sbc_frame_len;
p_msg->len = sbc_frame_len + 1;
}
btc_a2d_data_cb_to_app((uint8_t *)pcmData, (2 * sizeof(pcmData) - availPcmBytes));
}
/*******************************************************************************
**
** Function btc_a2dp_sink_rx_flush_req
**
** Description
**
** Returns TRUE is success
**
*******************************************************************************/
BOOLEAN btc_a2dp_sink_rx_flush_req(void)
{
if (fixed_queue_is_empty(btc_aa_snk_cb.RxSbcQ) == TRUE) { /* Que is already empty */
return TRUE;
}
btc_a2dp_sink_ctrl_post(BTC_MEDIA_FLUSH_AA_RX, NULL);
return TRUE;
}
/*******************************************************************************
**
** Function btc_a2dp_sink_rx_flush
**
** Description
**
** Returns void
**
*******************************************************************************/
static void btc_a2dp_sink_rx_flush(void)
{
/* Flush all enqueued SBC buffers (encoded) */
APPL_TRACE_DEBUG("btc_a2dp_sink_rx_flush");
btc_a2dp_sink_flush_q(btc_aa_snk_cb.RxSbcQ);
}
static int btc_a2dp_sink_get_track_frequency(UINT8 frequency)
{
int freq = 48000;
switch (frequency) {
case A2D_SBC_IE_SAMP_FREQ_16:
freq = 16000;
break;
case A2D_SBC_IE_SAMP_FREQ_32:
freq = 32000;
break;
case A2D_SBC_IE_SAMP_FREQ_44:
freq = 44100;
break;
case A2D_SBC_IE_SAMP_FREQ_48:
freq = 48000;
break;
}
return freq;
}
static int btc_a2dp_sink_get_track_channel_count(UINT8 channeltype)
{
int count = 1;
switch (channeltype) {
case A2D_SBC_IE_CH_MD_MONO:
count = 1;
break;
case A2D_SBC_IE_CH_MD_DUAL:
case A2D_SBC_IE_CH_MD_STEREO:
case A2D_SBC_IE_CH_MD_JOINT:
count = 2;
break;
}
return count;
}
/*******************************************************************************
**
** Function btc_a2dp_sink_enque_buf
**
** Description This function is called by the av_co to fill A2DP Sink Queue
**
**
** Returns size of the queue
*******************************************************************************/
UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_pkt)
{
tBT_SBC_HDR *p_msg;
if (btc_aa_snk_cb.rx_flush == TRUE) { /* Flush enabled, do not enque*/
return fixed_queue_length(btc_aa_snk_cb.RxSbcQ);
}
if (fixed_queue_length(btc_aa_snk_cb.RxSbcQ) >= MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ) {
APPL_TRACE_WARNING("Pkt dropped\n");
return fixed_queue_length(btc_aa_snk_cb.RxSbcQ);
}
APPL_TRACE_DEBUG("btc_a2dp_sink_enque_buf + ");
/* allocate and Queue this buffer */
if ((p_msg = (tBT_SBC_HDR *) osi_malloc(sizeof(tBT_SBC_HDR) +
p_pkt->offset + p_pkt->len)) != NULL) {
memcpy(p_msg, p_pkt, (sizeof(BT_HDR) + p_pkt->offset + p_pkt->len));
p_msg->num_frames_to_be_processed = (*((UINT8 *)(p_msg + 1) + p_msg->offset)) & 0x0f;
APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
fixed_queue_enqueue(btc_aa_snk_cb.RxSbcQ, p_msg);
btc_a2dp_sink_data_post(BTC_A2DP_SINK_DATA_EVT);
} else {
/* let caller deal with a failed allocation */
APPL_TRACE_WARNING("btc_a2dp_sink_enque_buf No Buffer left - ");
}
return fixed_queue_length(btc_aa_snk_cb.RxSbcQ);
}
static void btc_a2dp_sink_handle_clear_track (void)
{
APPL_TRACE_DEBUG("%s", __FUNCTION__);
}
/*******************************************************************************
**
** Function btc_a2dp_sink_flush_q
**
** Description
**
** Returns void
**
*******************************************************************************/
static void btc_a2dp_sink_flush_q(fixed_queue_t *p_q)
{
while (! fixed_queue_is_empty(p_q)) {
osi_free(fixed_queue_try_dequeue(p_q));
}
}
static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context)
{
APPL_TRACE_EVENT("%s\n", __func__);
memset(&btc_aa_snk_cb, 0, sizeof(btc_aa_snk_cb));
btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_ON;
btc_aa_snk_cb.RxSbcQ = fixed_queue_new(SIZE_MAX);
btc_a2dp_control_init();
}
static void btc_a2dp_sink_thread_cleanup(UNUSED_ATTR void *context)
{
/* make sure no channels are restarted while shutting down */
btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_SHUTTING_DOWN;
btc_a2dp_control_set_datachnl_stat(FALSE);
/* Clear task flag */
btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_OFF;
btc_a2dp_control_cleanup();
fixed_queue_free(btc_aa_snk_cb.RxSbcQ, osi_free_func);
}
#endif /* BTC_AV_SINK_INCLUDED */

File diff suppressed because it is too large Load diff

View file

@ -23,21 +23,21 @@
#include <string.h>
#include "bt_trace.h"
#include "bt_defs.h"
#include "esp_bt_defs.h"
#include "esp_a2dp_api.h"
#include "allocator.h"
#include "btu.h"
#include "bta_av_api.h"
#include "btc_dm.h"
#include "btc_common.h"
#include "btc_manage.h"
#include "btc_av.h"
#include "btc_avrc.h"
#include "btc_util.h"
#include "btc_profile_queue.h"
#include "bta_api.h"
#include "btc_media.h"
#include "bta_av_api.h"
#include "btu.h"
#include "bt_utils.h"
#include "btc_common.h"
#include "btc_manage.h"
#include "btc_a2dp.h"
#include "btc_a2dp_control.h"
#include "btc_a2dp_sink.h"
#include "btc_a2dp_source.h"
#include "esp_a2dp_api.h"
#if BTC_AV_INCLUDED
@ -116,6 +116,18 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *data);
static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *data);
static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *data);
#if BTC_AV_SRC_INCLUDED
static bt_status_t btc_a2d_src_init(void);
static bt_status_t btc_a2d_src_connect(bt_bdaddr_t *remote_bda);
static void btc_a2d_src_deinit(void);
#endif /* BTC_AV_SRC_INCLUDED */
#if BTC_AV_SINK_INCLUDED
static bt_status_t btc_a2d_sink_init(void);
static bt_status_t btc_a2d_sink_connect(bt_bdaddr_t *remote_bda);
static void btc_a2d_sink_deinit(void);
#endif /* BTC_AV_SINK_INCLUDED */
static const btc_sm_handler_t btc_av_state_handlers[] = {
btc_av_state_idle_handler,
btc_av_state_opening_handler,
@ -226,6 +238,7 @@ static void btc_initiate_av_open_tmr_hdlr(TIMER_LIST_ENT *tle)
******************************************************************************/
static void btc_report_connection_state(esp_a2d_connection_state_t state, bt_bdaddr_t *bd_addr, int disc_rsn)
{
// todo: add callback for SRC
esp_a2d_cb_param_t param;
memset(&param, 0, sizeof(esp_a2d_cb_param_t));
@ -242,6 +255,7 @@ static void btc_report_connection_state(esp_a2d_connection_state_t state, bt_bda
static void btc_report_audio_state(esp_a2d_audio_state_t state, bt_bdaddr_t *bd_addr)
{
// todo: add callback for SRC
esp_a2d_cb_param_t param;
memset(&param, 0, sizeof(esp_a2d_cb_param_t));
@ -389,7 +403,6 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
btc_av_cb.edr = p_bta_data->open.edr;
btc_av_cb.peer_sep = p_bta_data->open.sep;
btc_a2dp_set_peer_sep(p_bta_data->open.sep);
} else {
LOG_WARN("BTA_AV_OPEN_EVT::FAILED status: %d\n",
p_bta_data->open.status );
@ -401,7 +414,13 @@ static BOOLEAN btc_av_state_opening_handler(btc_sm_event_t event, void *p_data)
btc_report_connection_state(state, &(btc_av_cb.peer_bda), 0);
/* change state to open/idle based on the status */
btc_sm_change_state(btc_av_cb.sm_handle, av_state);
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
/* if queued PLAY command, send it now */
/* necessary to add this?
btc_rc_check_handle_pending_play(p_bta_data->open.bd_addr,
(p_bta_data->open.status == BTA_AV_SUCCESS));
*/
} else if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
/* Bring up AVRCP connection too */
BTA_AvOpenRc(btc_av_cb.bta_handle);
}
@ -473,17 +492,33 @@ static BOOLEAN btc_av_state_closing_handler(btc_sm_event_t event, void *p_data)
switch (event) {
case BTC_SM_ENTER_EVT:
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
btc_a2dp_set_rx_flush(TRUE);
#if BTC_AV_SRC_INCLUDED
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
/* immediately stop transmission of frames */
btc_a2dp_source_set_tx_flush(TRUE);
/* wait for audioflinger to stop a2dp */
}
#endif /* BTC_AV_SRC_INCLUDED */
#if BTC_AV_SINK_INCLUDED
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
btc_a2dp_sink_set_rx_flush(TRUE);
}
#endif /* BTC_AV_SINK_INCLUDED */
break;
case BTA_AV_STOP_EVT:
case BTC_AV_STOP_STREAM_REQ_EVT:
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
btc_a2dp_set_rx_flush(TRUE);
#if BTC_AV_SRC_INCLUDED
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
/* immediately flush any pending tx frames while suspend is pending */
btc_a2dp_source_set_tx_flush(TRUE);
}
#endif /* BTC_AV_SRC_INCLUDED */
#if BTC_AV_SINK_INCLUDED
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
btc_a2dp_sink_set_rx_flush(TRUE);
}
#endif /* BTC_AV_SINK_INCLUDED */
btc_a2dp_on_stopped(NULL);
break;
@ -548,6 +583,11 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
break;
case BTC_AV_START_STREAM_REQ_EVT:
#if BTC_AV_SRC_INCLUDED
if (btc_av_cb.peer_sep != AVDT_TSEP_SRC) {
btc_a2dp_source_setup_codec();
}
#endif /* BTC_AV_SRC_INCLUDED */
BTA_AvStart();
btc_av_cb.flags |= BTC_AV_FLAG_PENDING_START;
break;
@ -559,21 +599,44 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
if ((p_av->start.status == BTA_SUCCESS) && (p_av->start.suspending == TRUE)) {
return TRUE;
}
#if BTC_AV_SRC_INCLUDED
/* if remote tries to start a2dp when DUT is a2dp source
* then suspend. In case a2dp is sink and call is active
* then disconnect the AVDTP channel
*/
if (!(btc_av_cb.flags & BTC_AV_FLAG_PENDING_START)) {
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
LOG_INFO("%s: trigger suspend as remote initiated!!", __FUNCTION__);
btc_dispatch_sm_event(BTC_AV_SUSPEND_STREAM_REQ_EVT, NULL, 0);
}
}
/* In case peer is A2DP SRC we do not want to ack commands on UIPC*/
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
if (btc_a2dp_on_started(&p_av->start,
((btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) != 0))) {
/* only clear pending flag after acknowledgement */
btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_START;
}
}
#endif /* BTC_AV_SRC_INCLUDED */
/* remain in open state if status failed */
if (p_av->start.status != BTA_AV_SUCCESS) {
return FALSE;
}
#if BTC_AV_SINK_INCLUDED
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
btc_a2dp_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
btc_a2dp_sink_set_rx_flush(FALSE); /* remove flush state, ready for streaming*/
}
#endif /* BTC_AV_SINK_INCLUDED */
#if BTC_AV_SRC_INCLUDED
/* change state to started, send acknowledgement if start is pending */
if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) {
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
btc_a2dp_on_started(NULL, TRUE);
}
/* pending start flag will be cleared when exit current state */
}
#endif /* BTC_AV_SRC_INCLUDED */
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_STARTED);
} break;
@ -599,6 +662,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
/* change state to idle, send acknowledgement if start is pending */
if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) {
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
/* pending start flag will be cleared when exit current state */
}
btc_sm_change_state(btc_av_cb.sm_handle, BTC_AV_STATE_IDLE);
@ -612,6 +676,7 @@ static BOOLEAN btc_av_state_opened_handler(btc_sm_event_t event, void *p_data)
BTA_AvStart();
} else if (btc_av_cb.flags & BTC_AV_FLAG_PENDING_START) {
btc_av_cb.flags &= ~BTC_AV_FLAG_PENDING_START;
btc_a2dp_control_command_ack(ESP_A2D_MEDIA_CTRL_ACK_FAILURE);
}
break;
@ -665,17 +730,23 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
/* increase the a2dp consumer task priority temporarily when start
** audio playing, to avoid overflow the audio packet queue. */
adjust_priority_a2dp(TRUE);
// adjust_priority_a2dp(TRUE);
break;
case BTC_SM_EXIT_EVT:
/* restore the a2dp consumer task priority when stop audio playing. */
adjust_priority_a2dp(FALSE);
// adjust_priority_a2dp(FALSE);
break;
case BTC_AV_START_STREAM_REQ_EVT:
#if BTC_AV_SRC_INCLUDED
/* we were remotely started, just ack back the local request */
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
btc_a2dp_on_started(NULL, TRUE);
}
#endif /* BTC_AV_SRC_INCLUDED */
break;
/* fixme -- use suspend = true always to work around issue with BTA AV */
@ -689,12 +760,18 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
/* if we were remotely suspended but suspend locally, local suspend
always overrides */
btc_av_cb.flags &= ~BTC_AV_FLAG_REMOTE_SUSPEND;
#if BTC_AV_SRC_INCLUDED
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
/* immediately stop transmission of frames while suspend is pending */
btc_a2dp_source_set_tx_flush(TRUE);
}
#endif /* BTC_AV_SRC_INCLUDED */
#if BTC_AV_SINK_INCLUDED
if (btc_av_cb.peer_sep == AVDT_TSEP_SRC) {
btc_a2dp_set_rx_flush(TRUE);
btc_a2dp_sink_set_rx_flush(TRUE);
btc_a2dp_on_stopped(NULL);
}
#endif /* BTC_AV_SINK_INCLUDED */
BTA_AvStop(TRUE);
break;
@ -724,7 +801,12 @@ static BOOLEAN btc_av_state_started_handler(btc_sm_event_t event, void *p_data)
/* if not successful, remain in current state */
if (p_av->suspend.status != BTA_AV_SUCCESS) {
btc_av_cb.flags &= ~BTC_AV_FLAG_LOCAL_SUSPEND_PENDING;
#if BTC_AV_SRC_INCLUDED
if (btc_av_cb.peer_sep == AVDT_TSEP_SNK) {
/* suspend failed, reset back tx flush state */
btc_a2dp_source_set_tx_flush(FALSE);
}
#endif /* BTC_AV_SRC_INCLUDED */
return FALSE;
}
@ -855,62 +937,6 @@ static void btc_av_event_free_data(btc_sm_event_t event, void *p_data)
}
}
static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
{
bt_status_t stat;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_A2DP;
msg.act = (uint8_t) event;
stat = btc_transfer_context(&msg, p_data, sizeof(tBTA_AV), btc_av_event_deep_copy);
if (stat) {
LOG_ERROR("%s transfer failed\n", __func__);
}
}
static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
{
btc_sm_state_t state;
UINT8 que_len;
tA2D_STATUS a2d_status;
tA2D_SBC_CIE sbc_cie;
if (event == BTA_AV_MEDIA_DATA_EVT) { /* Switch to BTC_MEDIA context */
state = btc_sm_get_state(btc_av_cb.sm_handle);
if ( (state == BTC_AV_STATE_STARTED) || /* send SBC packets only in Started State */
(state == BTC_AV_STATE_OPENED) ) {
que_len = btc_media_sink_enque_buf((BT_HDR *)p_data);
LOG_DEBUG(" Packets in Que %d\n", que_len);
} else {
return;
}
}
if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
/* send a command to BT Media Task */
btc_reset_decoder((UINT8 *)p_data);
/* currently only supportes SBC */
a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
if (a2d_status == A2D_SUCCESS) {
btc_msg_t msg;
btc_av_args_t arg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_CONFIG_REQ_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
arg.mcc.type = ESP_A2D_MCT_SBC;
memcpy(arg.mcc.cie.sbc, (uint8_t *)p_data + 3, ESP_A2D_CIE_LEN_SBC);
btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
} else {
LOG_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
}
}
}
/*******************************************************************************
**
** Function btc_av_init
@ -921,10 +947,21 @@ static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
**
*******************************************************************************/
bt_status_t btc_av_init(void)
static bt_status_t btc_av_init(int service_id)
{
if (btc_av_cb.sm_handle == NULL) {
if (!btc_a2dp_start_media_task()) {
bool stat = false;
if (service_id == BTA_A2DP_SOURCE_SERVICE_ID) {
#if BTC_AV_SRC_INCLUDED
stat = btc_a2dp_source_startup();
#endif
} else if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
#if BTC_AV_SINK_INCLUDED
stat = btc_a2dp_sink_startup();
#endif
}
if (!stat) {
return BT_STATUS_FAIL;
}
@ -933,30 +970,17 @@ bt_status_t btc_av_init(void)
btc_sm_init((const btc_sm_handler_t *)btc_av_state_handlers, BTC_AV_STATE_IDLE);
btc_dm_enable_service(BTA_A2DP_SOURCE_SERVICE_ID);
#if (BTA_AV_SINK_INCLUDED == TRUE)
btc_dm_enable_service(BTA_A2DP_SINK_SERVICE_ID);
#endif
if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
btc_dm_enable_service(BTA_A2DP_SINK_SERVICE_ID);
}
btc_a2dp_on_init();
return BT_STATUS_SUCCESS;
}
return BT_STATUS_SUCCESS;
}
/*******************************************************************************
**
** Function init_sink
**
** Description Initializes the AV interface for sink mode
**
** Returns bt_status_t
**
*******************************************************************************/
bt_status_t btc_a2d_sink_init(void)
{
LOG_DEBUG("%s()\n", __func__);
return btc_av_init();
return BT_STATUS_FAIL;
}
/*******************************************************************************
@ -981,33 +1005,34 @@ static bt_status_t connect_int(bt_bdaddr_t *bd_addr, uint16_t uuid)
return BT_STATUS_SUCCESS;
}
bt_status_t btc_a2d_sink_connect(bt_bdaddr_t *remote_bda)
{
LOG_DEBUG("%s\n", __FUNCTION__);
CHECK_BTAV_INIT();
return btc_queue_connect(UUID_SERVCLASS_AUDIO_SINK, remote_bda, connect_int);
}
/*******************************************************************************
**
** Function cleanup
** Function clean_up
**
** Description Shuts down the AV interface and does the cleanup
**
** Returns None
**
*******************************************************************************/
static void btc_a2d_sink_deinit(void)
static void clean_up(int service_id)
{
LOG_DEBUG("%s\n", __FUNCTION__);
btc_a2dp_stop_media_task();
if (service_id == BTA_A2DP_SOURCE_SERVICE_ID) {
#if BTC_AV_SRC_INCLUDED
btc_a2dp_source_shutdown();
#endif /* BTC_AV_SRC_INCLUDED */
} else if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
#if BTC_AV_SINK_INCLUDED
btc_a2dp_sink_shutdown();
#endif /* BTC_AV_SINK_INCLUDED */
}
btc_dm_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
#if (BTA_AV_SINK_INCLUDED == TRUE)
btc_dm_disable_service(BTA_A2DP_SINK_SERVICE_ID);
#endif
if (service_id == BTA_A2DP_SINK_SERVICE_ID) {
btc_dm_disable_service(BTA_A2DP_SINK_SERVICE_ID);
}
/* Also shut down the AV state machine */
btc_sm_shutdown(btc_av_cb.sm_handle);
@ -1100,6 +1125,70 @@ void btc_dispatch_sm_event(btc_av_sm_event_t event, void *p_data, int len)
btc_transfer_context(&msg, p_data, len, NULL);
}
static void bte_av_callback(tBTA_AV_EVT event, tBTA_AV *p_data)
{
bt_status_t stat;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_A2DP;
msg.act = (uint8_t) event;
stat = btc_transfer_context(&msg, p_data, sizeof(tBTA_AV), btc_av_event_deep_copy);
if (stat) {
LOG_ERROR("%s transfer failed\n", __func__);
}
}
#if BTC_AV_SINK_INCLUDED
static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
{
btc_sm_state_t state;
UINT8 que_len;
tA2D_STATUS a2d_status;
tA2D_SBC_CIE sbc_cie;
if (event == BTA_AV_MEDIA_DATA_EVT) { /* Switch to BTC_MEDIA context */
state = btc_sm_get_state(btc_av_cb.sm_handle);
if ( (state == BTC_AV_STATE_STARTED) || /* send SBC packets only in Started State */
(state == BTC_AV_STATE_OPENED) ) {
que_len = btc_a2dp_sink_enque_buf((BT_HDR *)p_data);
LOG_DEBUG(" Packets in Que %d\n", que_len);
} else {
return;
}
}
if (event == BTA_AV_MEDIA_SINK_CFG_EVT) {
/* send a command to BT Media Task */
btc_a2dp_sink_reset_decoder((UINT8 *)p_data);
/* currently only supportes SBC */
a2d_status = A2D_ParsSbcInfo(&sbc_cie, (UINT8 *)p_data, FALSE);
if (a2d_status == A2D_SUCCESS) {
btc_msg_t msg;
btc_av_args_t arg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_A2DP;
msg.act = BTC_AV_SINK_CONFIG_REQ_EVT;
memset(&arg, 0, sizeof(btc_av_args_t));
arg.mcc.type = ESP_A2D_MCT_SBC;
memcpy(arg.mcc.cie.sbc, (uint8_t *)p_data + 3, ESP_A2D_CIE_LEN_SBC);
btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
} else {
LOG_ERROR("ERROR dump_codec_info A2D_ParsSbcInfo fail:%d\n", a2d_status);
}
}
}
#else
static void bte_av_media_callback(tBTA_AV_EVT event, tBTA_AV_MEDIA *p_data)
{
LOG_WARN("%s : event %u\n", __func__, event);
}
#endif
/*******************************************************************************
**
** Function btc_av_execute_service
@ -1163,6 +1252,21 @@ BOOLEAN btc_av_is_connected(void)
return ((state == BTC_AV_STATE_OPENED) || (state == BTC_AV_STATE_STARTED));
}
/*******************************************************************************
*
* Function btc_av_get_peer_sep
*
* Description Get the stream endpoint type.
*
* Returns The stream endpoint type: either AVDT_TSEP_SRC or
* AVDT_TSEP_SNK.
*
******************************************************************************/
uint8_t btc_av_get_peer_sep(void)
{
return btc_av_cb.peer_sep;
}
/*******************************************************************************
**
** Function btc_av_is_peer_edr
@ -1204,6 +1308,7 @@ void btc_a2dp_call_handler(btc_msg_t *msg)
{
btc_av_args_t *arg = (btc_av_args_t *)(msg->arg);
switch (msg->act) {
#if BTC_AV_SINK_INCLUDED
case BTC_AV_SINK_CONFIG_REQ_EVT: {
btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, (void *)(msg->arg));
break;
@ -1232,6 +1337,45 @@ void btc_a2dp_call_handler(btc_msg_t *msg)
btc_a2dp_sink_reg_data_cb(arg->data_cb);
break;
}
#endif /* BTC_AV_SINK_INCLUDED */
#if BTC_AV_SRC_INCLUDED
case BTC_AV_SRC_API_INIT_EVT: {
btc_a2d_src_init();
break;
}
case BTC_AV_SRC_API_DEINIT_EVT: {
btc_a2d_src_deinit();
break;
}
case BTC_AV_SRC_API_CONNECT_EVT: {
btc_a2d_src_connect(&arg->src_connect);
break;
}
case BTC_AV_SRC_API_DISCONNECT_EVT: {
CHECK_BTAV_INIT();
btc_sm_dispatch(btc_av_cb.sm_handle, BTC_AV_DISCONNECT_REQ_EVT, NULL);
break;
}
case BTC_AV_SRC_API_REG_DATA_CB_EVT: {
btc_a2dp_src_reg_data_cb(arg->src_data_cb);
break;
}
#endif /* BTC_AV_SRC_INCLUDED */
case BTC_AV_API_MEDIA_CTRL_EVT: {
btc_a2dp_control_media_ctrl(arg->ctrl);
break;
}
case BTC_AV_DATAPATH_CTRL_EVT: {
btc_a2dp_control_datapath_ctrl(arg->dp_evt);
break;
}
// case BTC_AV_DISCONNECT_REQ_EVT:
case BTC_AV_START_STREAM_REQ_EVT:
case BTC_AV_STOP_STREAM_REQ_EVT:
case BTC_AV_SUSPEND_STREAM_REQ_EVT: {
btc_sm_dispatch(btc_av_cb.sm_handle, msg->act, NULL);
break;
}
default:
LOG_WARN("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
}
@ -1243,4 +1387,70 @@ void btc_a2dp_cb_handler(btc_msg_t *msg)
btc_av_event_free_data(msg->act, msg->arg);
}
#if BTC_AV_SINK_INCLUDED
/*******************************************************************************
**
** Function init_sink
**
** Description Initializes the AV interface for sink mode
**
** Returns bt_status_t
**
*******************************************************************************/
static bt_status_t btc_a2d_sink_init(void)
{
LOG_DEBUG("%s()\n", __func__);
return btc_av_init(BTA_A2DP_SINK_SERVICE_ID);
}
static bt_status_t btc_a2d_sink_connect(bt_bdaddr_t *remote_bda)
{
LOG_DEBUG("%s\n", __FUNCTION__);
CHECK_BTAV_INIT();
return btc_queue_connect(UUID_SERVCLASS_AUDIO_SINK, remote_bda, connect_int);
}
static void btc_a2d_sink_deinit(void)
{
clean_up(BTA_A2DP_SINK_SERVICE_ID);
}
#endif /* BTC_AV_SINK_INCLUDED */
#if BTC_AV_SRC_INCLUDED
/*******************************************************************************
**
** Function btc_a2d_src_init
**
** Description Initializes the AV interface for source mode
**
** Returns bt_status_t
**
*******************************************************************************/
static bt_status_t btc_a2d_src_init(void)
{
LOG_DEBUG("%s()\n", __func__);
return btc_av_init(BTA_A2DP_SOURCE_SERVICE_ID);
}
static void btc_a2d_src_deinit(void)
{
clean_up(BTA_A2DP_SOURCE_SERVICE_ID);
}
static bt_status_t btc_a2d_src_connect(bt_bdaddr_t *remote_bda)
{
LOG_DEBUG("%s\n", __FUNCTION__);
CHECK_BTAV_INIT();
return btc_queue_connect(UUID_SERVCLASS_AUDIO_SOURCE, remote_bda, connect_int);
}
#endif /* BTC_AV_SRC_INCLUDED */
#endif /* #if BTC_AV_INCLUDED */

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,7 @@
#ifndef __BTC_AV_CO_H__
#define __BTC_AV_CO_H__
#include "btc_media.h"
#include "btc_a2dp.h"
#if (BTA_AV_INCLUDED == TRUE)
/*******************************************************************************
@ -93,7 +93,7 @@ void bta_av_co_audio_codec_reset(void);
** Returns TRUE if all opened devices support this codec, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_audio_codec_supported(tBTC_STATUS *p_status);
BOOLEAN bta_av_co_audio_codec_supported(tBTC_AV_STATUS *p_status);
/*******************************************************************************
**
@ -106,7 +106,7 @@ BOOLEAN bta_av_co_audio_codec_supported(tBTC_STATUS *p_status);
** Returns TRUE if successful, FALSE otherwise
**
*******************************************************************************/
BOOLEAN bta_av_co_audio_set_codec(const tBTC_AV_MEDIA_FEEDINGS *p_feeding, tBTC_STATUS *p_status);
BOOLEAN bta_av_co_audio_set_codec(const tBTC_AV_MEDIA_FEEDINGS *p_feeding, tBTC_AV_STATUS *p_status);
/*******************************************************************************
**

View file

@ -1164,3 +1164,9 @@ void btc_gap_callback_init(void)
BTM_BleRegiseterConnParamCallback(btc_update_conn_param_callback);
}
void btc_gap_ble_deinit(void)
{
btc_cleanup_adv_data(&gl_bta_adv_data);
btc_cleanup_adv_data(&gl_bta_scan_rsp_data);
}

View file

@ -0,0 +1,47 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "btc_task.h"
#include "btc_main.h"
#include "btc_dm.h"
#include "future.h"
#include "esp_err.h"
#include "btc_config.h"
#include "alarm.h"
#include "btc_ble_storage.h"
#include "btc_gatt_common.h"
#include "bta_gatt_common.h"
static void btc_set_local_mtu(uint16_t mtu)
{
BTA_GATT_SetLocalMTU(mtu);
}
void btc_gatt_com_call_handler(btc_msg_t *msg)
{
LOG_DEBUG("%s act %d\n", __func__, msg->act);
switch (msg->act) {
case BTC_GATT_ACT_SET_LOCAL_MTU:
{
btc_ble_gatt_com_args_t *arg = (btc_ble_gatt_com_args_t *)(msg->arg);
btc_set_local_mtu(arg->set_mtu.mtu);
break;
}
default:
LOG_ERROR("%s UNKNOWN ACT %d\n", __func__, msg->act);
break;
}
}

View file

@ -0,0 +1,108 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
*
* Filename: btc_a2dp.h
*
* Description: Common definitions for A2DP
*
*******************************************************************************/
#ifndef __BTC_A2DP_H__
#define __BTC_A2DP_H__
#include <stdbool.h>
#include "bt_target.h"
#include "bta_api.h"
#include "btc_av_api.h"
#include "esp_a2dp_api.h"
#if BTC_AV_INCLUDED
/*******************************************************************************
** Constants
*******************************************************************************/
#define BTC_AV_SUCCESS (0)
/**
* AV (Audio Video source) Errors
*/
#define BTC_ERROR_SRV_AV_NOT_ENABLED 700 /* AV is not enabled */
#define BTC_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED 701 /* Requested Feeding not supported */
#define BTC_ERROR_SRV_AV_BUSY 702 /* Another operation ongoing */
#define BTC_ERROR_SRV_AV_NOT_OPENED 703 /* No AV link opened */
#define BTC_ERROR_SRV_AV_NOT_STARTED 704 /* AV is not started */
#define BTC_ERROR_SRV_AV_CP_NOT_SUPPORTED 705 /* Content protection is not supported by all headsets */
/* Transcoding definition for TxTranscoding and RxTranscoding */
#define BTC_MEDIA_TRSCD_OFF 0
#define BTC_MEDIA_TRSCD_PCM_2_SBC 1 /* Tx */
/*******************************************************************************
** Data types
*******************************************************************************/
typedef int tBTC_AV_STATUS;
/*******************************************************************************
** Public functions
*******************************************************************************/
void btc_a2dp_on_init(void);
/*******************************************************************************
**
** Function btc_a2dp_on_idle
**
** Description Process 'idle' request from BTC AV state machine during
** initialization
**
*******************************************************************************/
void btc_a2dp_on_idle(void);
/*******************************************************************************
**
** Function btc_a2dp_on_started
**
** Description Process 'start' request from BTC AV state machine to prepare
** for A2DP streaming
**
** Return TRUE if an ACK for the local command is sent
**
*******************************************************************************/
BOOLEAN btc_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start);
/*******************************************************************************
**
** Function btc_a2dp_on_stopped
**
** Description Process 'stop' request from BTC AV state machine to stop
** A2DP streaming
**
*******************************************************************************/
void btc_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av);
/*******************************************************************************
**
** Function btc_a2dp_on_suspended
**
** Description Process 'stop' request from BTC AV state machine to suspend
** A2DP streaming
**
*******************************************************************************/
void btc_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av);
#endif /* #if BTC_AV_INCLUDED */
#endif /* __BTC_A2DP_H__ */

View file

@ -0,0 +1,110 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
*
* Filename: btc_a2dp_control.h
*
*******************************************************************************/
#ifndef __BTC_A2DP_CONTROL_H__
#define __BTC_A2DP_CONTROL_H__
#include <stdbool.h>
#include "bt_target.h"
#include "bta_api.h"
#include "btc_av_api.h"
#include "esp_a2dp_api.h"
#if BTC_AV_INCLUDED
/*******************************************************************************
** Public functions
*******************************************************************************/
/*******************************************************************************
**
** Function btc_a2dp_control_media_ctrl
**
** Description Handle the media_ctrl command
**
*******************************************************************************/
void btc_a2dp_control_media_ctrl(esp_a2d_media_ctrl_t ctrl);
/*******************************************************************************
**
** Function btc_a2dp_control_datapath_ctrl
**
** Description Handle the media datapath event, which is adapted from UIPC
** data channel from bluedroid
**
*******************************************************************************/
void btc_a2dp_control_datapath_ctrl(uint32_t dp_evt);
/*******************************************************************************
**
** Function btc_a2dp_control_command_ack
**
** Description Acknowledge the pending media_ctrl command
**
*******************************************************************************/
void btc_a2dp_control_command_ack(int status);
/*******************************************************************************
**
** Function btc_a2dp_control_get_datachnl_stat
**
** Description Check whether the data channel state is open
**
** Return TRUE if the data channel state is open
**
*******************************************************************************/
BOOLEAN btc_a2dp_control_get_datachnl_stat(void);
/*******************************************************************************
**
** Function btc_a2dp_control_set_datachnl_stat
**
** Description Set the data channel state flag
**
*******************************************************************************/
void btc_a2dp_control_set_datachnl_stat(BOOLEAN open);
/*******************************************************************************
**
** Function btc_a2dp_control_init
**
** Description Initialize the A2DP control module. It should be called during
** the startup stage of A2DP streaming.
**
*******************************************************************************/
bool btc_a2dp_control_init(void);
/*******************************************************************************
**
** Function btc_a2dp_control_cleanup
**
** Description Cleanup the A2DP control module
**
*******************************************************************************/
void btc_a2dp_control_cleanup(void);
#endif /* #if BTC_AV_INCLUDED */
#endif /* __BTC_A2DP_CONTROL_H__ */

View file

@ -0,0 +1,139 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*******************************************************************************
*
* Filename: btc_a2dp_sink.h
*
*******************************************************************************/
#ifndef __BTC_A2DP_SINK_H__
#define __BTC_A2DP_SINK_H__
#include <stdbool.h>
#include "bt_target.h"
#include "bta_api.h"
#include "btc_av_api.h"
#include "esp_a2dp_api.h"
#if BTC_AV_SINK_INCLUDED
/*******************************************************************************
** Data types
*******************************************************************************/
typedef struct {
BT_HDR hdr;
UINT8 codec_info[AVDT_CODEC_SIZE];
} tBTC_MEDIA_SINK_CFG_UPDATE;
/*******************************************************************************
** Public functions
*******************************************************************************/
/*******************************************************************************
**
** Function btc_a2dp_sink_startup
**
** Description Initialize and startup the A2DP sink module. This function
** should be called by the BTC AV state machine prior to using
** the module.
**
** Returns true if success
**
*******************************************************************************/
bool btc_a2dp_sink_startup(void);
/*******************************************************************************
**
** Function btc_a2dp_sink_shutdown
**
** Description Shutdown and cleanup the A2DP sink module
**
*******************************************************************************/
void btc_a2dp_sink_shutdown(void);
/*******************************************************************************
**
** Function btc_a2dp_sink_rx_flush_req
**
** Description Request to flush audio decoding pipe
**
** Returns TRUE if success
**
*******************************************************************************/
BOOLEAN btc_a2dp_sink_rx_flush_req(void);
/*******************************************************************************
**
** Function btc_a2dp_sink_enque_buf
**
** Description Enqueue a Advance Audio media buffer to be processed by btc media task.
**
** Returns size of the queue
**
*******************************************************************************/
UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_buf);
/*******************************************************************************
**
** Function btc_a2dp_sink_on_idle
**
** Description Process 'idle' request from the BTC AV state machine during
** initialization
**
*******************************************************************************/
void btc_a2dp_sink_on_idle(void);
/*******************************************************************************
**
** Function btc_a2dp_sink_on_stopped
**
** Description Process 'stop' request from the BTC AV state machine to stop
** A2DP streaming
**
*******************************************************************************/
void btc_a2dp_sink_on_stopped(tBTA_AV_SUSPEND *p_av);
/*******************************************************************************
**
** Function btc_a2dp_sink_on_suspended
**
** Description Process 'suspend' request from the BTC AV state machine to
** suspend A2DP streaming
**
*******************************************************************************/
void btc_a2dp_sink_on_suspended(tBTA_AV_SUSPEND *p_av);
/*******************************************************************************
**
** Function btc_a2dp_sink_set_rx_flush
**
** Description enable/disabel discarding of received A2DP frames
**
*******************************************************************************/
void btc_a2dp_sink_set_rx_flush(BOOLEAN enable);
/*******************************************************************************
**
** Function btc_a2dp_sink_reset_decoder
**
** Description Reset decoder parameters according to configuration from remote
** device
**
*******************************************************************************/
void btc_a2dp_sink_reset_decoder(UINT8 *p_av);
#endif /* #if BTC_AV_SINK_INCLUDED */
#endif /* __BTC_A2DP_SINK_H__ */

View file

@ -14,46 +14,24 @@
/*******************************************************************************
*
* Filename: btc_media.h
*
* Description: This is the audio module for the BTC system.
* Filename: btc_a2dp_source.h
*
*******************************************************************************/
#ifndef __BTC_MEDIA_H__
#define __BTC_MEDIA_H__
#ifndef __BTC_A2DP_SOURCE_H__
#define __BTC_A2DP_SOURCE_H__
#include <stdbool.h>
#include "bt_target.h"
#include "bta_api.h"
#include "btc_av_api.h"
#include "esp_a2dp_api.h"
#if (BTA_AV_INCLUDED == TRUE)
/*******************************************************************************
** Constants
*******************************************************************************/
#define BTC_SUCCESS (0)
/**
* AV (Audio Video source) Errors
*/
#define BTC_ERROR_SRV_AV_NOT_ENABLED 700 /* AV is not enabled */
#define BTC_ERROR_SRV_AV_FEEDING_NOT_SUPPORTED 701 /* Requested Feeding not supported */
#define BTC_ERROR_SRV_AV_BUSY 702 /* Another operation ongoing */
#define BTC_ERROR_SRV_AV_NOT_OPENED 703 /* No AV link opened */
#define BTC_ERROR_SRV_AV_NOT_STARTED 704 /* AV is not started */
#define BTC_ERROR_SRV_AV_CP_NOT_SUPPORTED 705 /* Content protection is not supported by all headsets */
/* Transcoding definition for TxTranscoding and RxTranscoding */
#define BTC_MEDIA_TRSCD_OFF 0
#define BTC_MEDIA_TRSCD_PCM_2_SBC 1 /* Tx */
#if BTC_AV_SRC_INCLUDED
/*******************************************************************************
** Data types
*******************************************************************************/
typedef int tBTC_STATUS;
/* tBTC_MEDIA_INIT_AUDIO msg structure */
typedef struct {
BT_HDR hdr;
@ -65,7 +43,6 @@ typedef struct {
UINT16 MtuSize; /* peer mtu size */
} tBTC_MEDIA_INIT_AUDIO;
#if (BTA_AV_INCLUDED == TRUE)
/* tBTC_MEDIA_UPDATE_AUDIO msg structure */
typedef struct {
BT_HDR hdr;
@ -81,187 +58,187 @@ typedef struct {
tBTC_AV_MEDIA_FEEDINGS feeding;
} tBTC_MEDIA_INIT_AUDIO_FEEDING;
typedef struct {
BT_HDR hdr;
UINT8 codec_info[AVDT_CODEC_SIZE];
} tBTC_MEDIA_SINK_CFG_UPDATE;
#endif
/*******************************************************************************
** Public functions
*******************************************************************************/
/*******************************************************************************
**
** Function btc_av_task
** Function btc_a2dp_source_startup
**
** Description
** Description Initialize and startup the A2DP source module. This function
** should be called by the BTC AV state machine prior to using
** the module
**
** Returns void
** Returns TRUE is success
**
*******************************************************************************/
extern void btc_media_task(void);
bool btc_a2dp_source_startup(void);
/*******************************************************************************
**
** Function btc_media_task_enc_init_req
** Function btc_a2dp_source_shutdown
**
** Description Shutdown and cleanup the A2DP source module.
**
*******************************************************************************/
void btc_a2dp_source_shutdown(void);
/*******************************************************************************
**
** Function btc_a2dp_source_enc_init_req
**
** Description Request to initialize the media task encoder
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_enc_init_req(tBTC_MEDIA_INIT_AUDIO *p_msg);
BOOLEAN btc_a2dp_source_enc_init_req(tBTC_MEDIA_INIT_AUDIO *p_msg);
/*******************************************************************************
**
** Function btc_media_task_enc_update_req
** Function btc_a2dp_source_enc_udpate_req
**
** Description Request to update the media task encoder
**
** Returns TRUE is success
**
*******************************************************************************/
#if (BTA_AV_INCLUDED == TRUE)
extern BOOLEAN btc_media_task_enc_update_req(tBTC_MEDIA_UPDATE_AUDIO *p_msg);
#endif
BOOLEAN btc_a2dp_source_enc_update_req(tBTC_MEDIA_UPDATE_AUDIO *p_msg);
/*******************************************************************************
**
** Function btc_media_task_start_aa_req
** Function btc_a2dp_source_start_audio_req
**
** Description Request to start audio encoding task
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_start_aa_req(void);
BOOLEAN btc_a2dp_source_start_audio_req(void);
/*******************************************************************************
**
** Function btc_media_task_stop_aa_req
** Function btc_a2dp_source_stop_audio_req
**
** Description Request to stop audio encoding task
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_stop_aa_req(void);
BOOLEAN btc_a2dp_source_stop_audio_req(void);
/*******************************************************************************
**
** Function btc_media_task_aa_rx_flush_req
**
** Description Request to flush audio decoding pipe
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_aa_rx_flush_req(void);
/*******************************************************************************
**
** Function btc_media_task_aa_tx_flush_req
** Function btc_a2dp_source_tx_flush_req
**
** Description Request to flush audio encoding pipe
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_aa_tx_flush_req(void);
BOOLEAN btc_a2dp_source_tx_flush_req(void);
/*******************************************************************************
**
** Function btc_media_aa_readbuf
** Function btc_a2dp_source_audio_readbuf
**
** Description Read an audio buffer from the BTC media TX queue
**
** Returns pointer on a aa buffer ready to send
**
*******************************************************************************/
extern BT_HDR *btc_media_aa_readbuf(void);
BT_HDR *btc_a2dp_source_audio_readbuf(void);
/*******************************************************************************
**
** Function btc_media_sink_enque_buf
**
** Description This function is called by the av_co to fill A2DP Sink Queue
**
**
** Returns size of the queue
*******************************************************************************/
UINT8 btc_media_sink_enque_buf(BT_HDR *p_buf);
/*******************************************************************************
**
** Function btc_media_aa_writebuf
**
** Description Enqueue a Advance Audio media buffer to be processed by btc media task.
**
** Returns TRUE is success
**
*******************************************************************************/
extern void btc_media_aa_writebuf(BT_HDR *pBuf, UINT32 timestamp, UINT16 seq_num);
/*******************************************************************************
**
** Function btc_media_av_writebuf
**
** Description Enqueue a video media buffer to be processed by btc media task.
**
** Returns TRUE is success
**
*******************************************************************************/
extern BOOLEAN btc_media_av_writebuf(UINT8 *p_media, UINT32 media_len,
UINT32 timestamp, UINT16 seq_num);
#if (BTA_AV_INCLUDED == TRUE)
/*******************************************************************************
**
** Function btc_media_task_audio_feeding_init_req
** Function btc_a2dp_source_audio_feeding_init_req
**
** Description Request to initialize audio feeding
**
** Returns TRUE is success
** Returns TRUE if success
**
*******************************************************************************/
extern BOOLEAN btc_media_task_audio_feeding_init_req(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_msg);
#endif
BOOLEAN btc_a2dp_source_audio_feeding_init_req(tBTC_MEDIA_INIT_AUDIO_FEEDING *p_msg);
/*******************************************************************************
**
** Function dump_codec_info
** Function btc_a2dp_source_is_streaming
**
** Description Decode and display codec_info (for debug)
**
** Returns void
** Description Check whether A2DP source is in streaming state
**
*******************************************************************************/
extern void dump_codec_info(unsigned char *p_codec);
bool btc_a2dp_source_is_streaming(void);
/**
* Local adaptation helper functions between btc and media task
*/
/*******************************************************************************
**
** Function btc_a2dp_source_is_task_shutting_down
**
** Description Check whether A2DP source media task is shutting down
**
*******************************************************************************/
bool btc_a2dp_source_is_task_shutting_down(void);
bool btc_a2dp_start_media_task(void);
void btc_a2dp_stop_media_task(void);
void btc_a2dp_on_init(void);
void btc_a2dp_setup_codec(void);
void btc_a2dp_on_idle(void);
BOOLEAN btc_a2dp_on_started(tBTA_AV_START *p_av, BOOLEAN pending_start);
void btc_a2dp_on_stop_req(void);
void btc_a2dp_on_stopped(tBTA_AV_SUSPEND *p_av);
void btc_a2dp_on_suspend(void);
void btc_a2dp_on_suspended(tBTA_AV_SUSPEND *p_av);
void btc_a2dp_set_rx_flush(BOOLEAN enable);
void btc_media_check_iop_exceptions(UINT8 *peer_bda);
void btc_reset_decoder(UINT8 *p_av);
/*******************************************************************************
**
** Function btc_a2dp_source_on_idle
**
** Description Request 'idle' request from BTC AV state machine during
** initialization
**
*******************************************************************************/
void btc_a2dp_source_on_idle(void);
int btc_a2dp_get_track_frequency(UINT8 frequency);
int btc_a2dp_get_track_channel_count(UINT8 channeltype);
void btc_a2dp_set_peer_sep(UINT8 sep);
#endif ///BTA_AV_INCLUDED == TRUE
#endif
/*******************************************************************************
**
** Function btc_a2dp_source_on_stopped
**
** Description Process 'stop' request from the BTC AV state machine to stop
** A2DP streaming
**
*******************************************************************************/
void btc_a2dp_source_on_stopped(tBTA_AV_SUSPEND *p_av);
/*******************************************************************************
**
** Function btc_a2dp_source_on_suspended
**
** Description Process 'suspend' request from the BTC AV state machine to stop
** A2DP streaming
**
*******************************************************************************/
void btc_a2dp_source_on_suspended(tBTA_AV_SUSPEND *p_av);
/*******************************************************************************
**
** Function btc_a2dp_source_setup_codec
**
** Description initialize the encoder parameters
**
*******************************************************************************/
void btc_a2dp_source_setup_codec(void);
/*******************************************************************************
**
** Function btc_a2dp_source_set_tx_flush
**
** Description enable/disable discarding of transmitted frames
**
*******************************************************************************/
void btc_a2dp_source_set_tx_flush(BOOLEAN enable);
/*******************************************************************************
**
** Function btc_a2dp_source_encoder_update
**
** Description update changed SBC encoder parameters
**
*******************************************************************************/
void btc_a2dp_source_encoder_update(void);
#endif /* #if BTC_AV_SRC_INCLUDED */
#endif /* __BTC_A2DP_SOURCE_H__ */

View file

@ -25,17 +25,23 @@
#ifndef __BTC_AV_H__
#define __BTC_AV_H__
#include "bt_target.h"
#include "esp_a2dp_api.h"
#include "btc_task.h"
#include "btc_common.h"
#include "btc_sm.h"
#include "bta_av_api.h"
#if (BTA_AV_INCLUDED == TRUE)
#if (BTC_AV_INCLUDED == TRUE)
/*******************************************************************************
** Type definitions for callback functions
********************************************************************************/
enum {
BTC_AV_DATAPATH_OPEN_EVT, // original UIPC_OPEN_EVT for data channel in bluedroid
BTC_AV_DATAPATH_MAX_EVT,
};
typedef enum {
BTC_AV_CONNECT_REQ_EVT = BTA_AV_MAX_EVT,
BTC_AV_DISCONNECT_REQ_EVT,
@ -46,21 +52,44 @@ typedef enum {
} btc_av_sm_event_t;
typedef enum {
#if BTC_AV_SINK_INCLUDED
BTC_AV_SINK_API_INIT_EVT = 0,
BTC_AV_SINK_API_DEINIT_EVT,
BTC_AV_SINK_API_CONNECT_EVT,
BTC_AV_SINK_API_DISCONNECT_EVT,
BTC_AV_SINK_API_REG_DATA_CB_EVT,
#endif /* BTC_AV_SINK_INCLUDED */
#if BTC_AV_SRC_INCLUDED
BTC_AV_SRC_API_INIT_EVT,
BTC_AV_SRC_API_DEINIT_EVT,
BTC_AV_SRC_API_CONNECT_EVT,
BTC_AV_SRC_API_DISCONNECT_EVT,
BTC_AV_SRC_API_REG_DATA_CB_EVT,
#endif /* BTC_AV_SRC_INCLUDED */
BTC_AV_API_MEDIA_CTRL_EVT,
BTC_AV_DATAPATH_CTRL_EVT,
} btc_av_act_t;
/* btc_av_args_t */
typedef union {
#if BTC_AV_SINK_INCLUDED
// BTC_AV_SINK_CONFIG_REQ_EVT -- internal event
esp_a2d_mcc_t mcc;
// BTC_AV_SINK_API_CONNECT_EVT
bt_bdaddr_t connect;
// BTC_AV_SINK_API_REG_DATA_CB_EVT
esp_a2d_data_cb_t data_cb;
esp_a2d_sink_data_cb_t data_cb;
#endif /* BTC_AV_SINK_INCLUDED */
#if BTC_AV_SRC_INCLUDED
// BTC_AV_SRC_API_REG_DATA_CB_EVT
esp_a2d_source_data_cb_t src_data_cb;
// BTC_AV_SRC_API_CONNECT
bt_bdaddr_t src_connect;
#endif /* BTC_AV_SRC_INCLUDED */
// BTC_AV_API_MEDIA_CTRL_EVT
esp_a2d_media_ctrl_t ctrl;
// BTC_AV_DATAPATH_CTRL_EVT
uint32_t dp_evt;
} btc_av_args_t;
/*******************************************************************************
@ -71,7 +100,9 @@ void btc_a2dp_call_handler(btc_msg_t *msg);
void btc_a2dp_cb_handler(btc_msg_t *msg);
void btc_a2dp_sink_reg_data_cb(esp_a2d_data_cb_t callback);
void btc_a2dp_sink_reg_data_cb(esp_a2d_sink_data_cb_t callback);
void btc_a2dp_src_reg_data_cb(esp_a2d_source_data_cb_t callback);
/*******************************************************************************
**
** Function btc_av_get_sm_handle
@ -121,18 +152,6 @@ BOOLEAN btc_av_stream_started_ready(void);
/* used to pass events to AV statemachine from other tasks */
void btc_dispatch_sm_event(btc_av_sm_event_t event, void *p_data, int len);
/*******************************************************************************
**
** Function btc_av_init
**
** Description Initializes btc AV if not already done
**
** Returns bt_status_t
**
*******************************************************************************/
bt_status_t btc_av_init(void);
/*******************************************************************************
**
** Function btc_av_is_connected
@ -146,6 +165,19 @@ bt_status_t btc_av_init(void);
BOOLEAN btc_av_is_connected(void);
/*******************************************************************************
*
* Function btc_av_get_peer_sep
*
* Description Get the stream endpoint type.
*
* Returns The stream endpoint type: either AVDT_TSEP_SRC or
* AVDT_TSEP_SNK.
*
******************************************************************************/
uint8_t btc_av_get_peer_sep(void);
/*******************************************************************************
**
** Function btc_av_is_peer_edr
@ -171,6 +203,6 @@ BOOLEAN btc_av_is_peer_edr(void);
********************************************************************************/
void btc_av_clear_remote_suspend_flag(void);
#endif ///BTA_AV_INCLUDED == TRUE
#endif ///BTC_AV_INCLUDED == TRUE
#endif /* __BTC_AV_H__ */

View file

@ -27,8 +27,6 @@
#include "bt_target.h"
#include "bta_av_api.h"
#include "btc_media.h"
#include "a2d_api.h"
#include "a2d_sbc.h"

View file

@ -160,5 +160,6 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_callback_init(void);
void btc_gap_ble_deinit(void);
#endif /* __BTC_GAP_BLE_H__ */

View file

@ -0,0 +1,37 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __BTC_GATT_COMMON_H__
#define __BTC_GATT_COMMON_H__
#include "future.h"
#include "bt_types.h"
#include "bta_api.h"
#include "btc_main.h"
#include "btc_task.h"
typedef enum {
BTC_GATT_ACT_SET_LOCAL_MTU = 0,
} btc_gatt_com_act_t;
/* btc_ble_gattc_args_t */
typedef union {
//BTC_GATT_ACT_SET_LOCAL_MTU,
struct set_mtu_arg {
uint16_t mtu;
} set_mtu;
} btc_ble_gatt_com_args_t;
void btc_gatt_com_call_handler(btc_msg_t *msg);
#endif /* __BTC_GATT_COMMON_H__ */

View file

@ -24,7 +24,7 @@
#include "bta_dm_ci.h"
#include "btc_dm.h"
#if (defined(BTIF_INCLUDED) && BTIF_INCLUDED == TRUE)
#include "bt_utils.h"
#include "bt_defs.h"
#if (BTM_OOB_INCLUDED == TRUE)
#include "btif_dm.h"
#endif

View file

@ -27,6 +27,7 @@
#include "sbc_encoder.h"
#include "sbc_enc_func_declare.h"
/*#include <math.h>*/
#if (defined(SBC_ENC_INCLUDED) && SBC_ENC_INCLUDED == TRUE)
#if (SBC_IS_64_MULT_IN_WINDOW_ACCU == TRUE)
#define WIND_4_SUBBANDS_0_1 (SINT32)0x01659F45 /* gas32CoeffFor4SBs[8] = -gas32CoeffFor4SBs[32] = 0x01659F45 */

View file

@ -39,81 +39,57 @@
#include "dyn_mem.h" /* defines static and/or dynamic memory for components */
/******************************************************************************
**
** Classic BT features
**
******************************************************************************/
#if CONFIG_CLASSIC_BT_ENABLED
#define CLASSIC_BT_INCLUDED TRUE
#define BTC_SM_INCLUDED TRUE
#define BTC_PRF_QUEUE_INCLUDED TRUE
#define BTC_GAP_BT_INCLUDED TRUE
#define BTA_SDP_INCLUDED TRUE
#define BTA_PAN_INCLUDED FALSE
#define BTA_HH_INCLUDED FALSE
#define SDP_INCLUDED TRUE
#if CONFIG_A2DP_SNK_ENABLED
#if CONFIG_A2DP_ENABLE
#define BTA_AR_INCLUDED TRUE
#define BTA_AV_INCLUDED TRUE
#define BTA_AV_SINK_INCLUDED TRUE
#define AVDT_INCLUDED TRUE
#define A2D_INCLUDED TRUE
#define AVCT_INCLUDED TRUE
#define AVRC_INCLUDED TRUE
#define BTC_AV_INCLUDED TRUE
#endif /* CONFIG_A2DP_ENABLE */
#if CONFIG_A2DP_SINK_ENABLE
#define BTA_AV_SINK_INCLUDED TRUE
#define BTC_AV_SINK_INCLUDED TRUE
#define SBC_DEC_INCLUDED TRUE
#else
#define BTA_AR_INCLUDED FALSE
#define BTA_AV_INCLUDED FALSE
#define BTA_AV_SINK_INCLUDED FALSE
#define AVDT_INCLUDED FALSE
#define A2D_INCLUDED FALSE
#define AVCT_INCLUDED FALSE
#define AVRC_INCLUDED FALSE
#define BTC_AV_INCLUDED FALSE
#define SBC_DEC_INCLUDED FALSE
#endif /* CONFIG_A2DP_SNK_ENABLED */
#endif /* CONFIG_A2DP_SINK_ENABLE */
#if CONFIG_A2DP_SRC_ENABLE
#define BTC_AV_SRC_INCLUDED TRUE
#define SBC_ENC_INCLUDED TRUE
#endif /* CONFIG_A2DP_SRC_ENABLE */
#if CONFIG_BT_SPP_ENABLED
#define RFCOMM_INCLUDED TRUE
#define BTA_JV_INCLUDED TRUE
#define BTC_SPP_INCLUDED TRUE
#else /* #if CONFIG_BT_SPP_ENABLED */
#define RFCOMM_INCLUDED FALSE
#define BTA_JV_INCLUDED FALSE
#define BTC_SPP_INCLUDED FALSE
#endif /* #if CONFIG_BT_SPP_ENABLED */
#define PAN_INCLUDED FALSE
#define HID_HOST_INCLUDED FALSE
#define SBC_ENC_INCLUDED FALSE
#define MCA_INCLUDED FALSE
#define BTC_SM_INCLUDED TRUE
#define BTC_PRF_QUEUE_INCLUDED TRUE
#define BTC_GAP_BT_INCLUDED TRUE
#else /* #if CONFIG_CLASSIC_BT_ENABLED */
#define CLASSIC_BT_INCLUDED FALSE
#define BTA_SDP_INCLUDED FALSE
#define BTA_PAN_INCLUDED FALSE
#define BTA_HH_INCLUDED FALSE
#define BTA_AR_INCLUDED FALSE
#define BTA_AV_INCLUDED FALSE
#define BTA_AV_SINK_INCLUDED FALSE
#define SDP_INCLUDED FALSE
#define RFCOMM_INCLUDED FALSE
#define BTA_JV_INCLUDED FALSE
#define BTC_SPP_INCLUDED FALSE
#define PAN_INCLUDED FALSE
#define HID_HOST_INCLUDED FALSE
#define AVDT_INCLUDED FALSE
#define A2D_INCLUDED FALSE
#define AVCT_INCLUDED FALSE
#define AVRC_INCLUDED FALSE
#define SBC_DEC_INCLUDED FALSE
#define SBC_ENC_INCLUDED FALSE
#define MCA_INCLUDED FALSE
#define BTC_SM_INCLUDED FALSE
#define BTC_PRF_QUEUE_INCLUDED FALSE
#define BTC_GAP_BT_INCLUDED FALSE
#define BTC_AV_INCLUDED FALSE
#endif /* CONFIG_BT_SPP_ENABLED */
#endif /* #if CONFIG_CLASSIC_BT_ENABLED */
#ifndef CLASSIC_BT_INCLUDED
#define CLASSIC_BT_INCLUDED FALSE
#endif /* CLASSIC_BT_INCLUDED */
/******************************************************************************
**
** BLE features
**
******************************************************************************/
#if (CONFIG_GATTS_ENABLE)
#define GATTS_INCLUDED TRUE
#else
@ -164,16 +140,62 @@
#define BTIF_INCLUDED FALSE
#endif
/******************************************************************************
**
** BTC-layer components
**
******************************************************************************/
#ifndef BTC_GAP_BT_INCLUDED
#define BTC_GAP_BT_INCLUDED FALSE
#endif
#ifndef BTC_PRF_QUEUE_INCLUDED
#define BTC_PRF_QUEUE_INCLUDED FALSE
#endif
#ifndef BTC_SM_INCLUDED
#define BTC_SM_INCLUDED FALSE
#endif
#ifndef BTC_AV_INCLUDED
#define BTC_AV_INCLUDED FALSE
#endif
#ifndef BTC_AV_SINK_INCLUDED
#define BTC_AV_SINK_INCLUDED FALSE
#endif
#ifndef BTC_AV_SRC_INCLUDED
#define BTC_AV_SRC_INCLUDED FALSE
#endif
#ifndef BTC_SPP_INCLUDED
#define BTC_SPP_INCLUDED FALSE
#endif
#ifndef SBC_DEC_INCLUDED
#define SBC_DEC_INCLUDED FALSE
#endif
#ifndef SBC_ENC_INCLUDED
#define SBC_ENC_INCLUDED FALSE
#endif
/******************************************************************************
**
** BTA-layer components
**
******************************************************************************/
#ifndef BTA_INCLUDED
#define BTA_INCLUDED TRUE
#endif
#ifndef BTA_PAN_INCLUDED
#define BTA_PAN_INCLUDED FALSE//TRUE
#define BTA_PAN_INCLUDED FALSE
#endif
#ifndef BTA_HH_INCLUDED
#define BTA_HH_INCLUDED FALSE//TRUE
#define BTA_HH_INCLUDED FALSE
#endif
#ifndef BTA_HH_ROLE
@ -181,21 +203,47 @@
#endif
#ifndef BTA_HH_LE_INCLUDED
#define BTA_HH_LE_INCLUDED FALSE//TRUE
#define BTA_HH_LE_INCLUDED FALSE
#endif
#ifndef BTA_AR_INCLUDED
#define BTA_AR_INCLUDED TRUE//TRUE
#define BTA_AR_INCLUDED FALSE
#endif
#ifndef BTA_AV_INCLUDED
#define BTA_AV_INCLUDED TRUE//TRUE
#define BTA_AV_INCLUDED FALSE
#endif
#ifndef BTA_AV_SINK_INCLUDED
#define BTA_AV_SINK_INCLUDED TRUE//FALSE
#define BTA_AV_SINK_INCLUDED FALSE
#endif
#ifndef BTA_JV_INCLUDED
#define BTA_JV_INCLUDED FALSE
#endif
#ifndef BTA_SDP_INCLUDED
#define BTA_SDP_INCLUDED FALSE
#endif
/******************************************************************************
**
** Stack-layer components
**
******************************************************************************/
#ifndef AVCT_INCLUDED
#define AVCT_INCLUDED FALSE
#endif
#ifndef AVDT_INCLUDED
#define AVDT_INCLUDED FALSE
#endif
/******************************************************************************
**
** Parameter Configurations for components
**
******************************************************************************/
#ifndef BTA_DISABLE_DELAY
#define BTA_DISABLE_DELAY 200 /* in milliseconds */
#endif
@ -1071,7 +1119,7 @@
******************************************************************************/
#ifndef SDP_INCLUDED
#define SDP_INCLUDED FALSE //TRUE
#define SDP_INCLUDED FALSE
#endif
/* This is set to enable SDP server functionality. */
@ -1458,7 +1506,7 @@ Range: 2 octets
******************************************************************************/
#ifndef PAN_INCLUDED
#define PAN_INCLUDED FALSE//TRUE
#define PAN_INCLUDED FALSE
#endif
/* This will enable the PANU role */
@ -1603,7 +1651,7 @@ Range: 2 octets
** Definitions for HID-Host
*/
#ifndef HID_HOST_INCLUDED
#define HID_HOST_INCLUDED FALSE//TRUE
#define HID_HOST_INCLUDED FALSE
#endif
#ifndef HID_HOST_MAX_DEVICES
@ -1630,7 +1678,7 @@ Range: 2 octets
* A2DP Definitions
*/
#ifndef A2D_INCLUDED
#define A2D_INCLUDED FALSE//TRUE
#define A2D_INCLUDED FALSE
#endif
/******************************************************************************
@ -1655,7 +1703,7 @@ Range: 2 octets
**
******************************************************************************/
#ifndef AVRC_INCLUDED
#define AVRC_INCLUDED TRUE
#define AVRC_INCLUDED FALSE
#endif
#ifndef AVRC_METADATA_INCLUDED

View file

@ -26,6 +26,7 @@
#include "bt_target.h"
#include <string.h>
/* Stack Configuation Related Init Definaton
* TODO: Now Just Unmask these defination until stack layer is OK
*/
@ -59,6 +60,14 @@
#include "a2d_api.h"
#endif
#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE)
#include "avdt_int.h"
#endif
#if (defined(AVCT_INCLUDED) && AVCT_INCLUDED == TRUE)
#include "avct_int.h"
#endif
#if (defined(HID_HOST_INCLUDED) && HID_HOST_INCLUDED == TRUE)
#include "hidh_api.h"
#endif
@ -78,8 +87,13 @@
#if BTA_INCLUDED == TRUE && BTA_DYNAMIC_MEMORY == TRUE
#include "bta_api.h"
#include "bta_sys.h"
#include "allocator.h"
#include "bta_ag_int.h"
//#include "bta_ag_int.h"
#if BTA_SDP_INCLUDED == TRUE
#include "bta_sdp_int.h"
#endif
#if BTA_HS_INCLUDED == TRUE
#include "bta_hs_int.h"
@ -119,9 +133,9 @@ tBTA_JV_CB *bta_jv_cb_ptr = NULL;
#include "bta_sys_int.h"
// control block for patch ram downloading
#include "bta_prm_int.h"
//#include "bta_prm_int.h"
#endif // BTA_INCLUDED
#endif // BTA_INCLUDED == TRUE && BTA_DYNAMIC_MEMORY == TRUE
/*****************************************************************************
@ -169,6 +183,20 @@ void BTE_InitStack(void)
AVRC_Init();
#endif
#if (defined(AVDT_INCLUDED) && AVDT_INCLUDED == TRUE && AVDT_DYNAMIC_MEMORY == TRUE)
if ((avdt_cb_ptr = (tAVDT_CB *)osi_malloc(sizeof(tAVDT_CB))) == NULL) {
return;
}
memset((void *)avdt_cb_ptr, 0, sizeof(tAVDT_CB));
#endif
#if (defined(AVCT_INCLUDED) && AVCT_INCLUDED == TRUE && AVCT_DYNAMIC_MEMORY == TRUE)
if ((avct_cb_ptr = (tAVCT_CB *)osi_malloc(sizeof(tAVCT_CB))) == NULL) {
return;
}
memset((void *)avct_cb_ptr, 0, sizeof(tAVCT_CB));
#endif
#if (defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE)
GAP_Init();
#endif
@ -183,29 +211,66 @@ void BTE_InitStack(void)
//BTA Modules
#if (BTA_INCLUDED == TRUE && BTA_DYNAMIC_MEMORY == TRUE)
if ((bta_sys_cb_ptr = (tBTA_SYS_CB *)osi_malloc(sizeof(tBTA_SYS_CB))) == NULL) {
return;
}
if ((bta_dm_cb_ptr = (tBTA_DM_CB *)osi_malloc(sizeof(tBTA_DM_CB))) == NULL) {
return;
}
if ((bta_dm_search_cb_ptr = (tBTA_DM_SEARCH_CB *)osi_malloc(sizeof(tBTA_DM_SEARCH_CB))) == NULL) {
return;
}
if ((bta_dm_di_cb_ptr = (tBTA_DM_DI_CB *)osi_malloc(sizeof(tBTA_DM_DI_CB))) == NULL) {
return;
}
memset((void *)bta_sys_cb_ptr, 0, sizeof(tBTA_SYS_CB));
memset((void *)bta_dm_cb_ptr, 0, sizeof(tBTA_DM_CB));
memset((void *)bta_dm_search_cb_ptr, 0, sizeof(tBTA_DM_SEARCH_CB));
memset((void *)bta_dm_di_cb_ptr, 0, sizeof(tBTA_DM_DI_CB));
memset((void *)bta_prm_cb_ptr, 0, sizeof(tBTA_PRM_CB));
memset((void *)bta_ag_cb_ptr, 0, sizeof(tBTA_AG_CB));
//memset((void *)bta_prm_cb_ptr, 0, sizeof(tBTA_PRM_CB));
//memset((void *)bta_ag_cb_ptr, 0, sizeof(tBTA_AG_CB));
#if BTA_HS_INCLUDED == TRUE
memset((void *)bta_hs_cb_ptr, 0, sizeof(tBTA_HS_CB));
#endif
#if BTA_SDP_INCLUDED == TRUE
if ((bta_sdp_cb_ptr = (tBTA_SDP_CB *)osi_malloc(sizeof(tBTA_SDP_CB))) == NULL) {
return;
}
memset((void *)bta_sdp_cb_ptr, 0, sizeof(tBTA_SDP_CB));
#endif
#if BTA_AR_INCLUDED==TRUE
if ((bta_ar_cb_ptr = (tBTA_AR_CB *)osi_malloc(sizeof(tBTA_AR_CB))) == NULL) {
return;
}
memset((void *)bta_ar_cb_ptr, 0, sizeof(tBTA_AR_CB));
#endif
#if BTA_AV_INCLUDED==TRUE
if ((bta_av_cb_ptr = (tBTA_AV_CB *)osi_malloc(sizeof(tBTA_AV_CB))) == NULL) {
return;
}
memset((void *)bta_av_cb_ptr, 0, sizeof(tBTA_AV_CB));
#endif
#if BTA_HH_INCLUDED==TRUE
if ((bta_hh_cb_ptr = (tBTA_HH_CB *)osi_malloc(sizeof(tBTA_HH_CB))) == NULL) {
return;
}
memset((void *)bta_hh_cb_ptr, 0, sizeof(tBTA_HH_CB));
#endif
#if BTA_HL_INCLUDED==TRUE
memset((void *)bta_hl_cb_ptr, 0, sizeof(tBTA_HL_CB));
#endif
#if BTA_GATT_INCLUDED==TRUE
#if GATTC_INCLUDED==TRUE
if ((bta_gattc_cb_ptr = (tBTA_GATTC_CB *)osi_malloc(sizeof(tBTA_GATTC_CB))) == NULL) {
return;
}
memset((void *)bta_gattc_cb_ptr, 0, sizeof(tBTA_GATTC_CB));
#endif
#if GATTS_INCLUDED == TRUE
if ((bta_gatts_cb_ptr = (tBTA_GATTS_CB *)osi_malloc(sizeof(tBTA_GATTS_CB))) == NULL) {
return;
}
memset((void *)bta_gattc_cb_ptr, 0, sizeof(tBTA_GATTC_CB));
//
memset((void *)bta_gatts_cb_ptr, 0, sizeof(tBTA_GATTS_CB));
#endif
#if BTA_PAN_INCLUDED==TRUE

View file

@ -47,6 +47,7 @@ static int alarm_state;
static struct alarm_t alarm_cbs[ALARM_CBS_NUM];
static osi_alarm_err_t alarm_free(osi_alarm_t *alarm);
static osi_alarm_err_t alarm_set(osi_alarm_t *alarm, period_ms_t timeout, bool is_periodic);
int osi_alarm_create_mux(void)
{
@ -207,7 +208,7 @@ end:
return;
}
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
static osi_alarm_err_t alarm_set(osi_alarm_t *alarm, period_ms_t timeout, bool is_periodic)
{
assert(alarm_mutex != NULL);
@ -226,19 +227,34 @@ osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
}
int64_t timeout_us = 1000 * (int64_t)timeout;
esp_err_t stat = esp_timer_start_once(alarm->alarm_hdl, (uint64_t)timeout_us);
esp_err_t stat;
if (is_periodic) {
stat = esp_timer_start_periodic(alarm->alarm_hdl, (uint64_t)timeout_us);
} else {
stat = esp_timer_start_once(alarm->alarm_hdl, (uint64_t)timeout_us);
}
if (stat != ESP_OK) {
LOG_ERROR("%s failed to start timer, err 0x%x\n", __func__, stat);
ret = OSI_ALARM_ERR_FAIL;
goto end;
}
alarm->deadline_us = timeout_us + esp_timer_get_time();
alarm->deadline_us = is_periodic ? 0 : (timeout_us + esp_timer_get_time());
end:
osi_mutex_unlock(&alarm_mutex);
return ret;
}
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout)
{
return alarm_set(alarm, timeout, false);
}
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period)
{
return alarm_set(alarm, period, true);
}
osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm)
{
int ret = OSI_ALARM_ERR_PASS;

View file

@ -132,26 +132,40 @@ void *osi_malloc_func(size_t size)
{
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
void *p;
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
#else
p = malloc(size);
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
osi_mem_dbg_record(p, size, __func__, __LINE__);
return p;
#else
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
#else
return malloc(size);
#endif
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
#endif /* #ifdef CONFIG_BLUEDROID_MEM_DEBUG */
}
void *osi_calloc_func(size_t size)
{
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
void *p;
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
p = heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
#else
p = calloc(1, size);
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
osi_mem_dbg_record(p, size, __func__, __LINE__);
return p;
#else
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
return heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL);
#else
return calloc(1, size);
#endif
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
#endif /* #ifdef CONFIG_BLUEDROID_MEM_DEBUG */
}
void osi_free_func(void *ptr)

View file

@ -28,8 +28,9 @@
#include "list.h"
#include "bt_trace.h"
#define CONFIG_FILE_MAX_SIZE (2048)
#define CONFIG_KEY "bt_cfg_key"
#define CONFIG_FILE_MAX_SIZE (1536)//1.5k
#define CONFIG_FILE_DEFAULE_LENGTH (2048)
#define CONFIG_KEY "bt_cfg_key"
typedef struct {
char *key;
char *value;
@ -134,7 +135,7 @@ bool config_has_key(const config_t *config, const char *section, const char *key
}
bool config_has_key_in_section(config_t *config, char *key, char *key_value)
{
{
LOG_DEBUG("key = %s, value = %s", key, key_value);
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
const section_t *section = (const section_t *)list_node(node);
@ -302,6 +303,78 @@ const char *config_section_name(const config_section_node_t *node)
return section->name;
}
static int get_config_size(const config_t *config)
{
assert(config != NULL);
int w_len = 0, total_size = 0;
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
const section_t *section = (const section_t *)list_node(node);
w_len = strlen(section->name) + strlen("[]\n");// format "[section->name]\n"
total_size += w_len;
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) {
const entry_t *entry = (const entry_t *)list_node(enode);
w_len = strlen(entry->key) + strlen(entry->value) + strlen(" = \n");// format "entry->key = entry->value\n"
total_size += w_len;
}
// Only add a separating newline if there are more sections.
if (list_next(node) != list_end(config->sections)) {
total_size ++; //'\n'
} else {
break;
}
}
total_size ++; //'\0'
return total_size;
}
static int get_config_size_from_flash(nvs_handle fp)
{
assert(fp != 0);
esp_err_t err;
char *keyname = osi_calloc(sizeof(CONFIG_KEY) + 1);
if (!keyname){
LOG_ERROR("%s, malloc error\n", __func__);
return 0;
}
size_t length = CONFIG_FILE_DEFAULE_LENGTH;
size_t total_length = 0;
uint16_t i = 0;
snprintf(keyname, sizeof(CONFIG_KEY) + 1, "%s%d", CONFIG_KEY, 0);
err = nvs_get_blob(fp, keyname, NULL, &length);
if (err == ESP_ERR_NVS_NOT_FOUND) {
osi_free(keyname);
return 0;
}
if (err != ESP_OK) {
LOG_ERROR("%s, error %d\n", __func__, err);
osi_free(keyname);
return 0;
}
total_length += length;
while (length == CONFIG_FILE_MAX_SIZE) {
length = CONFIG_FILE_DEFAULE_LENGTH;
snprintf(keyname, sizeof(CONFIG_KEY) + 1, "%s%d", CONFIG_KEY, ++i);
err = nvs_get_blob(fp, keyname, NULL, &length);
if (err == ESP_ERR_NVS_NOT_FOUND) {
break;
}
if (err != ESP_OK) {
LOG_ERROR("%s, error %d\n", __func__, err);
osi_free(keyname);
return 0;
}
total_length += length;
}
osi_free(keyname);
return total_length;
}
bool config_save(const config_t *config, const char *filename)
{
assert(config != NULL);
@ -312,8 +385,10 @@ bool config_save(const config_t *config, const char *filename)
int err_code = 0;
nvs_handle fp;
char *line = osi_calloc(1024);
char *buf = osi_calloc(CONFIG_FILE_MAX_SIZE);
if (!line || !buf) {
char *keyname = osi_calloc(sizeof(CONFIG_KEY) + 1);
int config_size = get_config_size(config);
char *buf = osi_calloc(config_size + 100);
if (!line || !buf || !keyname) {
err_code |= 0x01;
goto error;
}
@ -333,45 +408,53 @@ bool config_save(const config_t *config, const char *filename)
const section_t *section = (const section_t *)list_node(node);
w_cnt = snprintf(line, 1024, "[%s]\n", section->name);
LOG_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, w_cnt + w_cnt_total);
if (w_cnt + w_cnt_total < CONFIG_FILE_MAX_SIZE) {
memcpy(buf + w_cnt_total, line, w_cnt);
w_cnt_total += w_cnt;
} else {
break;
}
memcpy(buf + w_cnt_total, line, w_cnt);
w_cnt_total += w_cnt;
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) {
const entry_t *entry = (const entry_t *)list_node(enode);
LOG_DEBUG("(key, val): (%s, %s)\n", entry->key, entry->value);
w_cnt = snprintf(line, 1024, "%s = %s\n", entry->key, entry->value);
LOG_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, w_cnt + w_cnt_total);
if (w_cnt + w_cnt_total < CONFIG_FILE_MAX_SIZE) {
memcpy(buf + w_cnt_total, line, w_cnt);
w_cnt_total += w_cnt;
} else {
break;
}
memcpy(buf + w_cnt_total, line, w_cnt);
w_cnt_total += w_cnt;
}
// Only add a separating newline if there are more sections.
if (list_next(node) != list_end(config->sections)) {
if (1 + w_cnt_total < CONFIG_FILE_MAX_SIZE) {
buf[w_cnt_total] = '\n';
w_cnt_total += 1;
}
buf[w_cnt_total] = '\n';
w_cnt_total += 1;
} else {
break;
}
}
buf[w_cnt_total] = '\0';
err = nvs_set_blob(fp, CONFIG_KEY, buf, w_cnt_total);
if (err != ESP_OK) {
nvs_close(fp);
err_code |= 0x04;
goto error;
if (w_cnt_total < CONFIG_FILE_MAX_SIZE) {
snprintf(keyname, sizeof(CONFIG_KEY)+1, "%s%d", CONFIG_KEY, 0);
err = nvs_set_blob(fp, keyname, buf, w_cnt_total);
if (err != ESP_OK) {
nvs_close(fp);
err_code |= 0x04;
goto error;
}
}else {
uint count = (w_cnt_total / CONFIG_FILE_MAX_SIZE);
for (int i = 0; i <= count; i++)
{
snprintf(keyname, sizeof(CONFIG_KEY)+1, "%s%d", CONFIG_KEY, i);
if (i == count) {
err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, w_cnt_total - i*CONFIG_FILE_MAX_SIZE);
LOG_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, w_cnt_total - i*CONFIG_FILE_MAX_SIZE);
}else {
err = nvs_set_blob(fp, keyname, buf + i*CONFIG_FILE_MAX_SIZE, CONFIG_FILE_MAX_SIZE);
LOG_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, CONFIG_FILE_MAX_SIZE);
}
if (err != ESP_OK) {
nvs_close(fp);
err_code |= 0x04;
goto error;
}
}
}
err = nvs_commit(fp);
@ -384,6 +467,7 @@ bool config_save(const config_t *config, const char *filename)
nvs_close(fp);
osi_free(line);
osi_free(buf);
osi_free(keyname);
return true;
error:
@ -393,6 +477,9 @@ error:
if (line) {
osi_free(line);
}
if (keyname) {
osi_free(keyname);
}
if (err_code) {
LOG_ERROR("%s, err_code: 0x%x\n", __func__, err_code);
}
@ -423,19 +510,23 @@ static void config_parse(nvs_handle fp, config_t *config)
assert(fp != 0);
assert(config != NULL);
esp_err_t err;
int line_num = 0;
int err_code = 0;
uint16_t i = 0;
size_t length = CONFIG_FILE_DEFAULE_LENGTH;
size_t total_length = 0;
char *line = osi_calloc(1024);
char *section = osi_calloc(1024);
char *buf = osi_calloc(CONFIG_FILE_MAX_SIZE);
if (!line || !section || !buf) {
char *keyname = osi_calloc(sizeof(CONFIG_KEY) + 1);
int buf_size = get_config_size_from_flash(fp);
char *buf = osi_calloc(buf_size + 100);
if (!line || !section || !buf || !keyname) {
err_code |= 0x01;
goto error;
}
esp_err_t err;
size_t length = CONFIG_FILE_MAX_SIZE;
err = nvs_get_blob(fp, CONFIG_KEY, buf, &length);
snprintf(keyname, sizeof(CONFIG_KEY)+1, "%s%d", CONFIG_KEY, 0);
err = nvs_get_blob(fp, keyname, buf, &length);
if (err == ESP_ERR_NVS_NOT_FOUND) {
goto error;
}
@ -443,12 +534,26 @@ static void config_parse(nvs_handle fp, config_t *config)
err_code |= 0x02;
goto error;
}
total_length += length;
while (length == CONFIG_FILE_MAX_SIZE) {
length = CONFIG_FILE_DEFAULE_LENGTH;
snprintf(keyname, sizeof(CONFIG_KEY) + 1, "%s%d", CONFIG_KEY, ++i);
err = nvs_get_blob(fp, keyname, buf + CONFIG_FILE_MAX_SIZE * i, &length);
if (err == ESP_ERR_NVS_NOT_FOUND) {
break;
}
if (err != ESP_OK) {
err_code |= 0x02;
goto error;
}
total_length += length;
}
char *p_line_end;
char *p_line_bgn = buf;
strcpy(section, CONFIG_DEFAULT_SECTION);
while ( (p_line_bgn < buf + length - 1) && (p_line_end = strchr(p_line_bgn, '\n'))) {
while ( (p_line_bgn < buf + total_length - 1) && (p_line_end = strchr(p_line_bgn, '\n'))) {
// get one line
int line_len = p_line_end - p_line_bgn;
@ -496,6 +601,9 @@ error:
if (section) {
osi_free(section);
}
if (keyname) {
osi_free(keyname);
}
if (err_code) {
LOG_ERROR("%s returned with err code: %d\n", __func__, err_code);
}

View file

@ -57,6 +57,9 @@ void osi_alarm_free(osi_alarm_t *alarm);
// |alarm| and |cb| may not be NULL.
osi_alarm_err_t osi_alarm_set(osi_alarm_t *alarm, period_ms_t timeout);
// Sets an periodic alarm to fire |cb| each given |period|.
osi_alarm_err_t osi_alarm_set_periodic(osi_alarm_t *alarm, period_ms_t period);
// This function cancels the |alarm| if it was previously set. When this call
// returns, the caller has a guarantee that the callback is not in progress and
// will not be called if it hasn't already been called. This function is idempotent.
@ -65,6 +68,7 @@ osi_alarm_err_t osi_alarm_cancel(osi_alarm_t *alarm);
// Figure out how much time until next expiration.
// Returns 0 if not armed. |alarm| may not be NULL.
// only for oneshot alarm, not for periodic alarm
// TODO: Remove this function once PM timers can be re-factored
period_ms_t osi_alarm_get_remaining_ms(const osi_alarm_t *alarm);

View file

@ -21,6 +21,7 @@
#include <stddef.h>
#include <stdlib.h>
#include "esp_heap_caps.h"
#include "sdkconfig.h"
typedef void *(*alloc_fn)(size_t size);
@ -48,11 +49,13 @@ void osi_mem_dbg_record(void *p, int size, const char *func, int line);
void osi_mem_dbg_clean(void *p, const char *func, int line);
void osi_mem_dbg_show(void);
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
#define osi_malloc(size) \
({ \
void *p; \
\
p = malloc((size)); \
p = heap_caps_malloc_prefer(size, 2, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
@ -60,12 +63,64 @@ void osi_mem_dbg_show(void);
#define osi_calloc(size) \
({ \
void *p; \
\
p = heap_caps_calloc_prefer(1, size, 2, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#else
#define osi_malloc(size) \
({ \
void *p; \
p = malloc((size)); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#define osi_calloc(size) \
({ \
void *p; \
p = calloc(1, (size)); \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
})
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
#if 0
#define osi_malloc(size) \
do { \
void *p; \
\
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST \
p = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
#else \
p = malloc((size)); \
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */ \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
}while(0)
#define osi_calloc(size) \
do { \
void *p; \
\
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST \
p = heap_caps_calloc_prefer(1, size, 2, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, \
MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL); \
#else \
p = calloc(1, (size)); \
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */ \
osi_mem_dbg_record(p, size, __func__, __LINE__); \
(void *)p; \
} while(0)
#endif
#define osi_free(ptr) \
do { \
void *tmp_point = (void *)(ptr); \
@ -75,10 +130,24 @@ do { \
#else
#if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST
#define osi_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#define osi_calloc(size) heap_caps_calloc_prefer(1, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#else
#define osi_malloc(size) malloc((size))
#define osi_calloc(size) calloc(1, (size))
#endif /* #if CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST */
#define osi_free(p) free((p))
#endif /* CONFIG_BLUEDROID_MEM_DEBUG */
#define FREE_AND_RESET(a) \
do { \
if (a) { \
osi_free(a); \
a = NULL; \
} \
}while (0)
#endif /* _ALLOCATOR_H_ */

View file

@ -83,13 +83,21 @@ typedef enum {
#define BTC_TASK_PRIO (configMAX_PRIORITIES - 6)
#define BTC_TASK_QUEUE_LEN 60
#define BTC_MEDIA_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTC_MEDIA_TASK_STACK_SIZE (CONFIG_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE)
#define BTC_MEDIA_TASK_NAME "BtcMediaT"
#define BTC_MEDIA_TASK_PRIO (configMAX_PRIORITIES - 3)
#define BTC_MEDIA_DATA_QUEUE_LEN (1)
#define BTC_MEDIA_CTRL_QUEUE_LEN (5)
#define BTC_MEDIA_TASK_QUEUE_SET_LEN (BTC_MEDIA_DATA_QUEUE_LEN + BTC_MEDIA_CTRL_QUEUE_LEN)
#define BTC_A2DP_SINK_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTC_A2DP_SINK_TASK_STACK_SIZE (CONFIG_A2DP_SINK_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
#define BTC_A2DP_SINK_TASK_NAME "BtA2dSinkT"
#define BTC_A2DP_SINK_TASK_PRIO (configMAX_PRIORITIES - 3)
#define BTC_A2DP_SINK_DATA_QUEUE_LEN (3)
#define BTC_A2DP_SINK_CTRL_QUEUE_LEN (5)
#define BTC_A2DP_SINK_TASK_QUEUE_SET_LEN (BTC_A2DP_SINK_DATA_QUEUE_LEN + BTC_A2DP_SINK_CTRL_QUEUE_LEN)
#define BTC_A2DP_SOURCE_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define BTC_A2DP_SOURCE_TASK_STACK_SIZE (CONFIG_A2DP_SOURCE_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) // by menuconfig
#define BTC_A2DP_SOURCE_TASK_NAME "BtA2dSourceT"
#define BTC_A2DP_SOURCE_TASK_PRIO (configMAX_PRIORITIES - 3)
#define BTC_A2DP_SOURCE_DATA_QUEUE_LEN (3)
#define BTC_A2DP_SOURCE_CTRL_QUEUE_LEN (5)
#define BTC_A2DP_SOURCE_TASK_QUEUE_SET_LEN (BTC_A2DP_SOURCE_DATA_QUEUE_LEN + BTC_A2DP_SOURCE_CTRL_QUEUE_LEN)
#define TASK_POST_NON_BLOCKING (0)
#define TASK_POST_BLOCKING (portMAX_DELAY)

View file

@ -27,6 +27,7 @@
#include "a2d_api.h"
#include "a2d_int.h"
#include "avdt_api.h"
#include "allocator.h"
#if (defined(A2D_INCLUDED) && A2D_INCLUDED == TRUE)
@ -35,6 +36,8 @@
*****************************************************************************/
#if A2D_DYNAMIC_MEMORY == FALSE
tA2D_CB a2d_cb;
#else
tA2D_CB *a2d_cb_ptr;
#endif
@ -374,6 +377,9 @@ UINT8 A2D_BitsSet(UINT8 num)
*******************************************************************************/
void A2D_Init(void)
{
#if (A2D_DYNAMIC_MEMORY)
a2d_cb_ptr = (tA2D_CB *)osi_malloc(sizeof(tA2D_CB));
#endif /* #if (A2D_DYNAMIC_MEMORY) */
memset(&a2d_cb, 0, sizeof(tA2D_CB));
a2d_cb.avdt_sdp_ver = AVDT_VERSION;

View file

@ -29,7 +29,7 @@
#include "a2d_api.h"
#include "a2d_int.h"
#include "a2d_sbc.h"
#include "bt_utils.h"
#include "bt_defs.h"
#if (defined(A2D_INCLUDED) && A2D_INCLUDED == TRUE)

View file

@ -25,7 +25,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "l2c_api.h"
#include "l2cdefs.h"
#include "btm_api.h"
@ -38,6 +38,8 @@
/* Control block for AVCT */
#if AVCT_DYNAMIC_MEMORY == FALSE
tAVCT_CB avct_cb;
#else
tAVCT_CB *avct_cb_ptr;
#endif
/*******************************************************************************

View file

@ -25,7 +25,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avct_api.h"
#include "avct_int.h"
#include "l2c_api.h"

View file

@ -26,7 +26,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avct_api.h"
#include "avct_int.h"
#include "allocator.h"

View file

@ -25,7 +25,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avct_api.h"
#include "avct_int.h"
#include "btm_api.h"

View file

@ -28,7 +28,7 @@
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avdt_api.h"
#include "avdtc_api.h"
#include "avdt_int.h"

View file

@ -39,6 +39,8 @@
/* Control block for AVDT */
#if AVDT_DYNAMIC_MEMORY == FALSE
tAVDT_CB avdt_cb;
#else
tAVDT_CB *avdt_cb_ptr;
#endif
/*******************************************************************************

View file

@ -26,7 +26,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avdt_api.h"
#include "avdtc_api.h"
#include "avdt_int.h"
@ -407,7 +407,7 @@ void avdt_ccb_dealloc(tAVDT_CCB *p_ccb, tAVDT_CCB_EVT *p_data)
UNUSED(p_data);
AVDT_TRACE_DEBUG("avdt_ccb_dealloc %d\n", avdt_ccb_to_idx(p_ccb));
btu_stop_timer(&p_ccb->timer_entry);
btu_free_timer(&p_ccb->timer_entry);
fixed_queue_free(p_ccb->cmd_q, NULL);
fixed_queue_free(p_ccb->rsp_q, NULL);
memset(p_ccb, 0, sizeof(tAVDT_CCB));

View file

@ -26,7 +26,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avdt_api.h"
#include "avdtc_api.h"
#include "avdt_int.h"

View file

@ -25,7 +25,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avdt_api.h"
#include "avdtc_api.h"
#include "avdt_int.h"

View file

@ -29,7 +29,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avdt_api.h"
#include "avdtc_api.h"
#include "avdt_int.h"

View file

@ -26,7 +26,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avdt_api.h"
#include "avdtc_api.h"
#include "avdt_int.h"
@ -644,7 +644,7 @@ void avdt_scb_dealloc(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
UNUSED(p_data);
AVDT_TRACE_DEBUG("avdt_scb_dealloc hdl=%d\n", avdt_scb_to_hdl(p_scb));
btu_stop_timer(&p_scb->timer_entry);
btu_free_timer(&p_scb->timer_entry);
#if AVDT_MULTIPLEXING == TRUE
/* free fragments we're holding, if any; it shouldn't happen */

View file

@ -26,7 +26,7 @@
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "avdt_api.h"
#include "avdtc_api.h"
#include "avdt_int.h"

View file

@ -20,7 +20,7 @@
#include "avrc_api.h"
#include "avrc_defs.h"
#include "avrc_int.h"
#include "bt_utils.h"
#include "bt_defs.h"
#include "allocator.h"
#if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE)

View file

@ -20,7 +20,7 @@
#include "avrc_api.h"
#include "avrc_defs.h"
#include "avrc_int.h"
#include "bt_utils.h"
#include "bt_defs.h"
#if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE)

View file

@ -25,6 +25,7 @@
#include "bt_target.h"
#include "avrc_api.h"
#include "avrc_int.h"
#include "allocator.h"
#if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE)
@ -41,6 +42,8 @@
*****************************************************************************/
#if AVRC_DYNAMIC_MEMORY == FALSE
tAVRC_CB avrc_cb;
#else
tAVRC_CB *avrc_cb_ptr;
#endif
/* update AVRC_NUM_PROTO_ELEMS if this constant is changed */
@ -342,6 +345,9 @@ UINT8 AVRC_SetTraceLevel (UINT8 new_level)
*******************************************************************************/
void AVRC_Init(void)
{
#if AVRC_DYNAMIC_MEMORY
avrc_cb_ptr = (tAVRC_CB *)osi_malloc(sizeof(tAVRC_CB));
#endif /* #if AVRC_DYNAMIC_MEMORY */
memset(&avrc_cb, 0, sizeof(tAVRC_CB));
#if defined(AVRC_INITIAL_TRACE_LEVEL)

View file

@ -596,7 +596,12 @@ void btm_ble_refresh_local_resolvable_private_addr(BD_ADDR pseudo_addr,
BD_ADDR dummy_bda = {0};
if (p != NULL) {
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
/*
* Temporary solutions for pair with random address:
* use BLE_ADDR_RANDOM when adverting with random adress or in privacy mode
* We will do futher work here
*/
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE || btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type == BLE_ADDR_RANDOM) {
p->conn_addr_type = BLE_ADDR_RANDOM;
if (memcmp(local_rpa, dummy_bda, BD_ADDR_LEN)) {
memcpy(p->conn_addr, local_rpa, BD_ADDR_LEN);

View file

@ -517,7 +517,13 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s
evt_type = p_cb->scan_rsp ? BTM_BLE_CONNECT_EVT : BTM_BLE_NON_CONNECT_EVT;
}
#endif
// if adv state is BTM_BLE_ADV_PENDING, return immediately
if (p_cb->state == BTM_BLE_ADV_PENDING) {
if (p_stop_adv_cback) {
(*p_stop_adv_cback)(HCI_ERR_ILLEGAL_COMMAND);
}
return BTM_BUSY;
}
if (start && p_cb->adv_mode == BTM_BLE_ADV_DISABLE) {
/* update adv params */
if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min :
@ -538,7 +544,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s
}
status = btm_ble_start_adv ();
} else if (!start) {
} else if (!start && p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
//save the stop adv callback to the BTM env.
p_cb->p_stop_adv_cb = p_stop_adv_cback;
status = btm_ble_stop_adv();
@ -546,9 +552,14 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start, tBTM_START_STOP_ADV_CMPL_CBACK *p_s
btm_ble_disable_resolving_list(BTM_BLE_RL_ADV, TRUE);
#endif
} else {
status = BTM_WRONG_MODE;
BTM_TRACE_ERROR("Can not %s Broadcast, device %s in Broadcast mode",
(start ? "Start" : "Stop"), (start ? "already" : "not"));
/*
1. start adv when adv has already started (not used)
2. stop adv shen adv has already stoped
*/
status = BTM_SUCCESS;
if (p_stop_adv_cback) {
(*p_stop_adv_cback)(status);
}
}
return status;
}
@ -736,6 +747,22 @@ BOOLEAN BTM_BleConfigPrivacy(BOOLEAN privacy_mode, tBTM_SET_LOCAL_PRIVACY_CBACK
if (!controller_get_interface()->supports_ble()) {
return FALSE;
}
/*
* Temporary solutions for pair with random address:
* can't set privacy when advertising, scaning or using static random address
* We will do futher work here
*/
if (p_cb->privacy_mode == BTM_PRIVACY_NONE
&& random_cb->own_addr_type == BLE_ADDR_RANDOM) {
BTM_TRACE_ERROR("Have set random adress, can't set privacy ");
return FALSE;
}
if (!(p_cb->inq_var.state != BTM_BLE_STOP_SCAN && p_cb->inq_var.state != BTM_BLE_STOP_ADV)) {
BTM_TRACE_ERROR("Advertising or scaning now, can't set privacy ");
return FALSE;
}
#if (defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE && GATTS_INCLUDED == TRUE)
uint8_t addr_resolution = 0;
#endif /* defined(GAP_INCLUDED) && GAP_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */
@ -1165,6 +1192,16 @@ tBTM_STATUS BTM_BleSetAdvParamsStartAdv(UINT16 adv_int_min, UINT16 adv_int_max,
return BTM_ILLEGAL_VALUE;
}
/*
* Temporary solutions for pair with random address:
* can't set advertising with BLE_ADDR_PUBLIC when having set random adress or in privacy mode
* We will do futher work here
*/
if (btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type == BLE_ADDR_RANDOM && own_bda_type == BLE_ADDR_PUBLIC) {
BTM_TRACE_ERROR ("own_addr_type is BLE_ADDR_RANDOM but use BLE_ADDR_PUBLIC\n");
return BTM_ILLEGAL_VALUE;
}
if (!BTM_BLE_ISVALID_PARAM(adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) ||
!BTM_BLE_ISVALID_PARAM(adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX)) {
return BTM_ILLEGAL_VALUE;
@ -1191,8 +1228,23 @@ tBTM_STATUS BTM_BleSetAdvParamsStartAdv(UINT16 adv_int_min, UINT16 adv_int_max,
}
BTM_TRACE_EVENT ("update params for an active adv\n");
btm_ble_stop_adv();
// if adv state is BTM_BLE_ADV_PENDING, return immediately
if (p_cb->state == BTM_BLE_ADV_PENDING) {
if (p_cb->p_adv_cb) {
(*p_cb->p_adv_cb)(HCI_ERR_ILLEGAL_COMMAND);
}
return BTM_BUSY;
}
/* host will stop adv first and then start adv again if adv has already started
it will get callback twice.
*/
if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
p_cb->adv_callback_twice = TRUE;
}
tBTM_STATUS status = btm_ble_stop_adv();
if (status != BTM_SUCCESS) {
p_cb->adv_callback_twice = FALSE;
}
/* update adv params */
btsnd_hcic_ble_write_adv_params (adv_int_min,
@ -1315,6 +1367,19 @@ void BTM_BleSetScanFilterParams(tGATT_IF client_if, UINT32 scan_interval, UINT32
return;
}
/*
* Temporary solutions for pair with random address:
* can't set scan with BLE_ADDR_PUBLIC when having set random adress or in privacy mode
* We will do futher work here
*/
if (btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type == BLE_ADDR_RANDOM && addr_type_own == BLE_ADDR_PUBLIC) {
BTM_TRACE_ERROR ("own_addr_type is BLE_ADDR_RANDOM but use BLE_ADDR_PUBLIC\n");
if (scan_setup_status_cback != NULL) {
scan_setup_status_cback(client_if, BTM_ILLEGAL_VALUE);
}
return;
}
/* If not supporting extended scan support, use the older range for checking */
if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) {
max_scan_interval = BTM_BLE_SCAN_INT_MAX;
@ -1500,6 +1565,24 @@ BOOLEAN BTM_BleSetRandAddress(BD_ADDR rand_addr)
if (rand_addr == NULL)
return set_flag;
/*
* Temporary solutions for pair with random address:
* can't set rand address when advertising, scaning or in privacy mode
* We will do futher work here
*/
#if BLE_PRIVACY_SPT == TRUE
if (btm_cb.ble_ctr_cb.privacy_mode != BTM_PRIVACY_NONE) {
BTM_TRACE_ERROR("privacy_mode is not BTM_PRIVACY_NONE ");
return set_flag;
}
#endif
if (!(btm_cb.ble_ctr_cb.inq_var.state != BTM_BLE_STOP_SCAN && btm_cb.ble_ctr_cb.inq_var.state != BTM_BLE_STOP_ADV)) {
BTM_TRACE_ERROR("Advertising or scaning now, can't set randaddress ");
return FALSE;
}
memcpy(btm_cb.ble_ctr_cb.addr_mgnt_cb.private_addr, rand_addr, BD_ADDR_LEN);
btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type = BLE_ADDR_RANDOM;
//send the set random address to the controller
set_flag = btsnd_hcic_ble_set_random_addr(rand_addr);
return set_flag;
@ -3297,13 +3380,13 @@ tBTM_STATUS btm_ble_start_adv(void)
#endif
if (p_cb->afp != AP_SCAN_CONN_ALL) {
//find the device in the btm dev buffer and write it to the controller white list
btm_execute_wl_dev_operation();
btm_execute_wl_dev_operation();
btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV;
}
if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE)) {
p_cb->adv_mode = BTM_BLE_ADV_ENABLE;
p_cb->state = BTM_BLE_ADVERTISING;
p_cb->state = BTM_BLE_ADV_PENDING;
btm_ble_adv_states_operation(btm_ble_set_topology_mask, p_cb->evt_type);
rt = BTM_SUCCESS;
BTM_TRACE_EVENT ("BTM_SUCCESS\n");
@ -3332,7 +3415,7 @@ tBTM_STATUS btm_ble_stop_adv(void)
if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) {
p_cb->fast_adv_on = FALSE;
p_cb->adv_mode = BTM_BLE_ADV_DISABLE;
p_cb->state = BTM_BLE_STOP_ADV;
p_cb->state = BTM_BLE_ADV_PENDING;
btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV;
/* clear all adv states */
@ -3506,9 +3589,23 @@ void btm_ble_write_adv_enable_complete(UINT8 *p)
// callback to the APP after receive the adv complete from the controller.
if (p_cb->p_adv_cb && p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
(*p_cb->p_adv_cb)(status);
if (p_cb->adv_callback_twice) {
p_cb->adv_callback_twice = FALSE;
}else {
p_cb->state = BTM_BLE_ADVERTISING;
(*p_cb->p_adv_cb)(status);
}
} else if (p_cb->p_stop_adv_cb && p_cb->adv_mode == BTM_BLE_ADV_DISABLE) {
p_cb->state = BTM_BLE_STOP_ADV;
(*p_cb->p_stop_adv_cb)(status);
}else {
// p_cb->p_adv_cb is NULL or p_cb->p_stop_adv_cb is NULL
if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
p_cb->state = BTM_BLE_ADVERTISING;
}else {
p_cb->state = BTM_BLE_STOP_ADV;
}
p_cb->adv_callback_twice = FALSE;
}
/* if write adv enable/disbale not succeed */
if (*p != HCI_SUCCESS) {
@ -3651,6 +3748,9 @@ void btm_ble_init (void)
BTM_TRACE_DEBUG("%s", __func__);
btu_free_timer(&p_cb->obs_timer_ent);
btu_free_timer(&p_cb->scan_timer_ent);
btu_free_timer(&p_cb->inq_var.fast_adv_timer);
memset(p_cb, 0, sizeof(tBTM_BLE_CB));
memset(&(btm_cb.cmn_ble_vsc_cb), 0 , sizeof(tBTM_BLE_VSC_CB));
btm_cb.cmn_ble_vsc_cb.values_read = FALSE;

View file

@ -533,7 +533,7 @@ void btm_read_local_name_complete (UINT8 *p, UINT16 evt_len)
UINT8 status;
UNUSED(evt_len);
btu_stop_timer (&btm_cb.devcb.rln_timer);
btu_free_timer (&btm_cb.devcb.rln_timer);
/* If there was a callback address for read local name, call it */
btm_cb.devcb.p_rln_cmpl_cb = NULL;

View file

@ -1359,6 +1359,12 @@ void btm_inq_db_init (void)
#if 0 /* cleared in btm_init; put back in if called from anywhere else! */
memset (&btm_cb.btm_inq_vars, 0, sizeof (tBTM_INQUIRY_VAR_ST));
#endif
btu_free_timer(&btm_cb.btm_inq_vars.rmt_name_timer_ent);
memset(&btm_cb.btm_inq_vars.rmt_name_timer_ent, 0, sizeof(TIMER_LIST_ENT));
btu_free_timer(&btm_cb.btm_inq_vars.inq_timer_ent);
memset(&btm_cb.btm_inq_vars.inq_timer_ent, 0, sizeof(TIMER_LIST_ENT));
btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
}

View file

@ -33,6 +33,8 @@
*/
#if BTM_DYNAMIC_MEMORY == FALSE
tBTM_CB btm_cb;
#else
tBTM_CB *btm_cb_ptr;
#endif
/*******************************************************************************
@ -49,9 +51,11 @@ tBTM_CB btm_cb;
*******************************************************************************/
void btm_init (void)
{
#if BTM_DYNAMIC_MEMORY
btm_cb_ptr = (tBTM_CB *)osi_malloc(sizeof(tBTM_CB));
#endif /* #if BTM_DYNAMIC_MEMORY */
/* All fields are cleared; nonzero fields are reinitialized in appropriate function */
memset(&btm_cb, 0, sizeof(tBTM_CB));
btm_cb.page_queue = fixed_queue_new(SIZE_MAX);
btm_cb.sec_pending_q = fixed_queue_new(SIZE_MAX);
@ -87,4 +91,7 @@ void btm_free(void)
{
fixed_queue_free(btm_cb.page_queue, osi_free_func);
fixed_queue_free(btm_cb.sec_pending_q, osi_free_func);
#if BTM_DYNAMIC_MEMORY
FREE_AND_RESET(btm_cb_ptr);
#endif
}

View file

@ -119,12 +119,15 @@ void btu_free_core(void)
l2c_free();
#if BLE_INCLUDED == TRUE
#if (defined(GATTS_INCLUDED) && GATTS_INCLUDED == true)
#if (defined(GATT_INCLUDED) && GATT_INCLUDED == true)
gatt_free();
#endif
btm_ble_free();
#endif
btm_free();
#if SMP_INCLUDED == TRUE
SMP_Free();
#endif
}
/*****************************************************************************
@ -141,6 +144,9 @@ void btu_free_core(void)
******************************************************************************/
void BTU_StartUp(void)
{
#if BTU_DYNAMIC_MEMORY
btu_cb_ptr = (tBTU_CB *)osi_malloc(sizeof(tBTU_CB));
#endif /* #if BTU_DYNAMIC_MEMORY */
memset (&btu_cb, 0, sizeof (tBTU_CB));
btu_cb.trace_level = HCI_INITIAL_TRACE_LEVEL;
@ -182,6 +188,9 @@ error_exit:;
void BTU_ShutDown(void)
{
#if BTU_DYNAMIC_MEMORY
FREE_AND_RESET(btu_cb_ptr);
#endif
btu_task_shut_down();
hash_map_free(btu_general_alarm_hash_map);

View file

@ -91,6 +91,8 @@ extern void BTE_InitStack(void);
*/
#if BTU_DYNAMIC_MEMORY == FALSE
tBTU_CB btu_cb;
#else
tBTU_CB *btu_cb_ptr;
#endif
extern hash_map_t *btu_general_alarm_hash_map;
@ -511,15 +513,12 @@ void btu_free_timer(TIMER_LIST_ENT *p_tle)
{
assert(p_tle != NULL);
if (p_tle->in_use == FALSE) {
return;
}
p_tle->in_use = FALSE;
// Get the alarm for the timer list entry.
osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
if (alarm == NULL) {
LOG_WARN("%s Unable to find expected alarm in hashmap", __func__);
LOG_DEBUG("%s Unable to find expected alarm in hashmap", __func__);
return;
}
osi_alarm_cancel(alarm);
@ -613,6 +612,23 @@ void btu_stop_quick_timer(TIMER_LIST_ENT *p_tle)
}
osi_alarm_cancel(alarm);
}
void btu_free_quick_timer(TIMER_LIST_ENT *p_tle)
{
assert(p_tle != NULL);
p_tle->in_use = FALSE;
// Get the alarm for the timer list entry.
osi_alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
if (alarm == NULL) {
LOG_DEBUG("%s Unable to find expected alarm in hashmap", __func__);
return;
}
osi_alarm_cancel(alarm);
hash_map_erase(btu_l2cap_alarm_hash_map, p_tle);
}
#endif /* defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) */
void btu_oneshot_alarm_cb(void *data)

View file

@ -77,6 +77,8 @@ static const tL2CAP_APPL_INFO dyn_info = {
#if GATT_DYNAMIC_MEMORY == FALSE
tGATT_CB gatt_cb;
#else
tGATT_CB *gatt_cb_ptr;
#endif
tGATT_DEFAULT gatt_default;
@ -94,9 +96,9 @@ tGATT_DEFAULT gatt_default;
void gatt_init (void)
{
tL2CAP_FIXED_CHNL_REG fixed_reg;
GATT_TRACE_DEBUG("gatt_init()");
#if GATT_DYNAMIC_MEMORY
gatt_cb_ptr = (tGATT_CB *)osi_malloc(sizeof(tGATT_CB));
#endif /* #if GATT_DYNAMIC_MEMORY */
memset (&gatt_cb, 0, sizeof(tGATT_CB));
memset (&fixed_reg, 0, sizeof(tL2CAP_FIXED_CHNL_REG));
@ -152,7 +154,7 @@ void gatt_init (void)
** Returns void
**
*******************************************************************************/
#if (GATTS_INCLUDED == TRUE)
#if (GATT_INCLUDED == TRUE)
void gatt_free(void)
{
int i;
@ -172,13 +174,26 @@ void gatt_free(void)
fixed_queue_free(gatt_cb.tcb[i].pending_ind_q, NULL);
gatt_cb.tcb[i].pending_ind_q = NULL;
btu_free_timer(&gatt_cb.tcb[i].conf_timer_ent);
memset(&gatt_cb.tcb[i].conf_timer_ent, 0, sizeof(TIMER_LIST_ENT));
btu_free_timer(&gatt_cb.tcb[i].ind_ack_timer_ent);
memset(&gatt_cb.tcb[i].ind_ack_timer_ent, 0, sizeof(TIMER_LIST_ENT));
#if (GATTS_INCLUDED == TRUE)
fixed_queue_free(gatt_cb.tcb[i].sr_cmd.multi_rsp_q, NULL);
gatt_cb.tcb[i].sr_cmd.multi_rsp_q = NULL;
#endif /* #if (GATTS_INCLUDED == TRUE) */
}
#if (GATTS_INCLUDED == TRUE)
for (i = 0; i < GATT_MAX_SR_PROFILES; i++) {
gatt_free_hdl_buffer(&gatt_cb.hdl_list[i]);
}
#endif /* #if (GATTS_INCLUDED == TRUE) */
#if GATT_DYNAMIC_MEMORY
FREE_AND_RESET(gatt_cb_ptr);
#endif /* #if GATT_DYNAMIC_MEMORY */
}
#endif ///GATTS_INCLUDED == TRUE

View file

@ -1683,6 +1683,7 @@ tGATT_CLCB *gatt_clcb_alloc (UINT16 conn_id)
void gatt_clcb_dealloc (tGATT_CLCB *p_clcb)
{
if (p_clcb && p_clcb->in_use) {
btu_free_timer(&p_clcb->rsp_timer_ent);
memset(p_clcb, 0, sizeof(tGATT_CLCB));
}
}
@ -2211,8 +2212,8 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
}
}
btu_stop_timer (&p_tcb->ind_ack_timer_ent);
btu_stop_timer (&p_tcb->conf_timer_ent);
btu_free_timer (&p_tcb->ind_ack_timer_ent);
btu_free_timer (&p_tcb->conf_timer_ent);
gatt_free_pending_ind(p_tcb);
gatt_free_pending_enc_queue(p_tcb);
gatt_free_pending_prepare_write_queue(p_tcb);

Some files were not shown because too many files have changed in this diff Show more