mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-23 19:20:51 +00:00
a2dp source demo: cleanup
This commit is contained in:
parent
9413b167ec
commit
67673f1cc2
@ -46,25 +46,32 @@
|
||||
#include "hxcmod.h"
|
||||
#include "mods/mod.h"
|
||||
|
||||
#define NUM_CHANNELS 2
|
||||
#define A2DP_SAMPLE_RATE 44100
|
||||
#define BYTES_PER_AUDIO_SAMPLE (2*NUM_CHANNELS)
|
||||
#define FILL_AUDIO_BUFFER_TIMEOUT_MS 10
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265
|
||||
#endif
|
||||
#define TABLE_SIZE_441HZ 100
|
||||
|
||||
typedef struct {
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
} paTestData;
|
||||
#define NUM_CHANNELS 2
|
||||
#define A2DP_SAMPLE_RATE 44100
|
||||
#define BYTES_PER_AUDIO_SAMPLE (2*NUM_CHANNELS)
|
||||
#define AUDIO_TIMEOUT_MS 10
|
||||
#define TABLE_SIZE_441HZ 100
|
||||
|
||||
typedef enum {
|
||||
STREAM_SINE,
|
||||
STREAM_MOD
|
||||
} stream_data_source_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t a2dp_cid;
|
||||
uint8_t local_seid;
|
||||
|
||||
uint32_t time_audio_data_sent; // ms
|
||||
uint32_t acc_num_missed_samples;
|
||||
uint32_t samples_ready;
|
||||
btstack_timer_source_t audio_timer;
|
||||
uint8_t streaming;
|
||||
int max_media_payload_size;
|
||||
|
||||
uint8_t sbc_storage[1030];
|
||||
uint16_t sbc_storage_count;
|
||||
uint8_t sbc_ready_to_send;
|
||||
} a2dp_media_sending_context_t;
|
||||
|
||||
static uint8_t media_sbc_codec_capabilities[] = {
|
||||
(AVDTP_SBC_44100 << 4) | AVDTP_SBC_STEREO,
|
||||
@ -88,135 +95,47 @@ static const int16_t sine_int16[] = {
|
||||
static char * device_name = "A2DP Source BTstack";
|
||||
|
||||
#ifdef HAVE_BTSTACK_STDIN
|
||||
// mac 2011: static bd_addr_t remote = {0x04, 0x0C, 0xCE, 0xE4, 0x85, 0xD3};
|
||||
// pts: static bd_addr_t remote = {0x00, 0x1B, 0xDC, 0x08, 0x0A, 0xA5};
|
||||
// mac 2013: static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xd1, 0x15};
|
||||
// phone 2013: static bd_addr_t remote = {0xD8, 0xBB, 0x2C, 0xDF, 0xF0, 0xF2};
|
||||
// mac 2011: static const char * device_addr_string = "04:0C:CE:E4:85:D3";
|
||||
// pts: static const char * device_addr_string = "00:1B:DC:08:0A:A5";
|
||||
// mac 2013: static const char * device_addr_string = "84:38:35:65:d1:15";
|
||||
// phone 2013: static const char * device_addr_string = "D8:BB:2C:DF:F0:F2";
|
||||
// minijambox:
|
||||
static bd_addr_t remote = {0x00, 0x21, 0x3c, 0xac, 0xf7, 0x38};
|
||||
// head phones: static bd_addr_t remote = {0x00, 0x18, 0x09, 0x28, 0x50, 0x18};
|
||||
// bt dongle: -u 02-04-01
|
||||
// static bd_addr_t remote = {0x00, 0x15, 0x83, 0x5F, 0x9D, 0x46};
|
||||
static const char * device_addr_string = "00:21:3C:AC:F7:38";
|
||||
// head phones: static const char * device_addr_string = "00:18:09:28:50:18";
|
||||
// bt dongle: static const char * device_addr_string = "00:15:83:5F:9D:46";
|
||||
#endif
|
||||
|
||||
static uint8_t sdp_avdtp_source_service_buffer[150];
|
||||
static bd_addr_t device_addr;
|
||||
static uint8_t sdp_a2dp_source_service_buffer[150];
|
||||
static uint8_t media_sbc_codec_configuration[4];
|
||||
|
||||
typedef struct {
|
||||
uint16_t a2dp_cid;
|
||||
uint8_t local_seid;
|
||||
|
||||
uint32_t time_audio_data_sent; // ms
|
||||
uint32_t acc_num_missed_samples;
|
||||
uint32_t samples_ready;
|
||||
btstack_timer_source_t fill_audio_buffer_timer;
|
||||
uint8_t streaming;
|
||||
|
||||
int max_media_payload_size;
|
||||
|
||||
uint8_t sbc_storage[1030];
|
||||
uint16_t sbc_storage_count;
|
||||
uint8_t sbc_ready_to_send;
|
||||
|
||||
} a2dp_media_sending_context_t;
|
||||
|
||||
static a2dp_media_sending_context_t media_tracker;
|
||||
|
||||
static paTestData sin_data;
|
||||
static stream_data_source_t data_source;
|
||||
|
||||
static int hxcmod_initialized = 0;
|
||||
static int sine_phase;
|
||||
|
||||
static int hxcmod_initialized;
|
||||
static modcontext mod_context;
|
||||
static tracker_buffer_state trkbuf;
|
||||
|
||||
static uint8_t local_seid = 0;
|
||||
stream_data_source_t data_source = STREAM_SINE;
|
||||
|
||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
|
||||
static void a2dp_fill_audio_buffer_timer_start(a2dp_media_sending_context_t * context);
|
||||
static void a2dp_fill_audio_buffer_timer_stop(a2dp_media_sending_context_t * context);
|
||||
static void a2dp_fill_audio_buffer_timer_pause(a2dp_media_sending_context_t * context);
|
||||
|
||||
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
UNUSED(channel);
|
||||
UNUSED(size);
|
||||
uint8_t status;
|
||||
switch (packet_type) {
|
||||
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (hci_event_packet_get_type(packet)) {
|
||||
case HCI_EVENT_A2DP_META:
|
||||
switch (packet[2]){
|
||||
case A2DP_SUBEVENT_STREAM_ESTABLISHED:
|
||||
status = a2dp_subevent_stream_established_get_status(packet);
|
||||
if (status){
|
||||
printf("Stream establishment failed: status 0x%02x.\n", status);
|
||||
break;
|
||||
}
|
||||
media_tracker.local_seid = a2dp_subevent_stream_established_get_local_seid(packet);
|
||||
media_tracker.a2dp_cid = a2dp_subevent_stream_established_get_a2dp_cid(packet);
|
||||
printf("Stream established: a2dp cid 0x%02x, local seid %d, remote seid %d.\n",
|
||||
media_tracker.a2dp_cid, media_tracker.local_seid, a2dp_subevent_stream_established_get_remote_seid(packet));
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:{
|
||||
if (local_seid != media_tracker.local_seid) break;
|
||||
|
||||
int num_bytes_in_frame = btstack_sbc_encoder_sbc_buffer_length();
|
||||
int bytes_in_storage = media_tracker.sbc_storage_count;
|
||||
uint8_t num_frames = bytes_in_storage / num_bytes_in_frame;
|
||||
|
||||
a2dp_source_stream_send_media_payload(media_tracker.local_seid, media_tracker.sbc_storage, bytes_in_storage, num_frames, 0);
|
||||
media_tracker.sbc_storage_count = 0;
|
||||
media_tracker.sbc_ready_to_send = 0;
|
||||
break;
|
||||
}
|
||||
case A2DP_SUBEVENT_STREAM_STARTED:
|
||||
if (local_seid != media_tracker.local_seid) break;
|
||||
if (!a2dp_source_stream_endpoint_ready(media_tracker.a2dp_cid, media_tracker.local_seid)) break;
|
||||
a2dp_fill_audio_buffer_timer_start(&media_tracker);
|
||||
printf("Stream started.\n");
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_SUSPENDED:
|
||||
printf("Stream paused.\n");
|
||||
a2dp_fill_audio_buffer_timer_pause(&media_tracker);
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_RELEASED:
|
||||
printf("Stream released.\n");
|
||||
a2dp_fill_audio_buffer_timer_stop(&media_tracker);
|
||||
break;
|
||||
default:
|
||||
printf("AVDTP Source demo: event 0x%02x is not implemented\n", packet[2]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// other packet type
|
||||
break;
|
||||
}
|
||||
static void a2dp_demo_send_media_packet(void){
|
||||
int num_bytes_in_frame = btstack_sbc_encoder_sbc_buffer_length();
|
||||
int bytes_in_storage = media_tracker.sbc_storage_count;
|
||||
uint8_t num_frames = bytes_in_storage / num_bytes_in_frame;
|
||||
a2dp_source_stream_send_media_payload(media_tracker.local_seid, media_tracker.sbc_storage, bytes_in_storage, num_frames, 0);
|
||||
media_tracker.sbc_storage_count = 0;
|
||||
media_tracker.sbc_ready_to_send = 0;
|
||||
}
|
||||
|
||||
static void produce_sine_audio(int16_t * pcm_buffer, void *user_data, int num_samples_to_write){
|
||||
paTestData *data = (paTestData*)user_data;
|
||||
static void produce_sine_audio(int16_t * pcm_buffer, int num_samples_to_write){
|
||||
int count;
|
||||
for (count = 0; count < num_samples_to_write ; count++){
|
||||
pcm_buffer[count * 2] = sine_int16[data->left_phase];
|
||||
pcm_buffer[count * 2 + 1] = sine_int16[data->right_phase];
|
||||
|
||||
data->left_phase += 1;
|
||||
if (data->left_phase >= TABLE_SIZE_441HZ){
|
||||
data->left_phase -= TABLE_SIZE_441HZ;
|
||||
pcm_buffer[count * 2] = sine_int16[sine_phase];
|
||||
pcm_buffer[count * 2 + 1] = sine_int16[sine_phase];
|
||||
sine_phase++;
|
||||
if (sine_phase >= TABLE_SIZE_441HZ){
|
||||
sine_phase -= TABLE_SIZE_441HZ;
|
||||
}
|
||||
data->right_phase += 1;
|
||||
if (data->right_phase >= TABLE_SIZE_441HZ){
|
||||
data->right_phase -= TABLE_SIZE_441HZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,7 +146,7 @@ static void produce_mod_audio(int16_t * pcm_buffer, int num_samples_to_write){
|
||||
static void produce_audio(int16_t * pcm_buffer, int num_samples){
|
||||
switch (data_source){
|
||||
case STREAM_SINE:
|
||||
produce_sine_audio(pcm_buffer, &sin_data, num_samples);
|
||||
produce_sine_audio(pcm_buffer, num_samples);
|
||||
break;
|
||||
case STREAM_MOD:
|
||||
produce_mod_audio(pcm_buffer, num_samples);
|
||||
@ -258,13 +177,13 @@ static int fill_sbc_audio_buffer(a2dp_media_sending_context_t * context){
|
||||
return total_num_bytes_read;
|
||||
}
|
||||
|
||||
static void avdtp_fill_audio_buffer_timeout_handler(btstack_timer_source_t * timer){
|
||||
static void avdtp_audio_timeout_handler(btstack_timer_source_t * timer){
|
||||
a2dp_media_sending_context_t * context = (a2dp_media_sending_context_t *) btstack_run_loop_get_timer_context(timer);
|
||||
btstack_run_loop_set_timer(&context->fill_audio_buffer_timer, FILL_AUDIO_BUFFER_TIMEOUT_MS);
|
||||
btstack_run_loop_add_timer(&context->fill_audio_buffer_timer);
|
||||
btstack_run_loop_set_timer(&context->audio_timer, AUDIO_TIMEOUT_MS);
|
||||
btstack_run_loop_add_timer(&context->audio_timer);
|
||||
uint32_t now = btstack_run_loop_get_time_ms();
|
||||
|
||||
uint32_t update_period_ms = FILL_AUDIO_BUFFER_TIMEOUT_MS;
|
||||
uint32_t update_period_ms = AUDIO_TIMEOUT_MS;
|
||||
if (context->time_audio_data_sent > 0){
|
||||
update_period_ms = now - context->time_audio_data_sent;
|
||||
}
|
||||
@ -290,40 +209,102 @@ static void avdtp_fill_audio_buffer_timeout_handler(btstack_timer_source_t * tim
|
||||
}
|
||||
}
|
||||
|
||||
static void a2dp_fill_audio_buffer_timer_start(a2dp_media_sending_context_t * context){
|
||||
static void a2dp_demo_timer_start(a2dp_media_sending_context_t * context){
|
||||
context->max_media_payload_size = a2dp_max_media_payload_size(context->local_seid);
|
||||
context->sbc_storage_count = 0;
|
||||
context->sbc_ready_to_send = 0;
|
||||
context->streaming = 1;
|
||||
btstack_run_loop_remove_timer(&context->fill_audio_buffer_timer);
|
||||
btstack_run_loop_set_timer_handler(&context->fill_audio_buffer_timer, avdtp_fill_audio_buffer_timeout_handler);
|
||||
btstack_run_loop_set_timer_context(&context->fill_audio_buffer_timer, context);
|
||||
btstack_run_loop_set_timer(&context->fill_audio_buffer_timer, FILL_AUDIO_BUFFER_TIMEOUT_MS);
|
||||
btstack_run_loop_add_timer(&context->fill_audio_buffer_timer);
|
||||
btstack_run_loop_remove_timer(&context->audio_timer);
|
||||
btstack_run_loop_set_timer_handler(&context->audio_timer, avdtp_audio_timeout_handler);
|
||||
btstack_run_loop_set_timer_context(&context->audio_timer, context);
|
||||
btstack_run_loop_set_timer(&context->audio_timer, AUDIO_TIMEOUT_MS);
|
||||
btstack_run_loop_add_timer(&context->audio_timer);
|
||||
}
|
||||
|
||||
static void a2dp_fill_audio_buffer_timer_stop(a2dp_media_sending_context_t * context){
|
||||
static void a2dp_demo_timer_stop(a2dp_media_sending_context_t * context){
|
||||
context->time_audio_data_sent = 0;
|
||||
context->acc_num_missed_samples = 0;
|
||||
context->samples_ready = 0;
|
||||
context->streaming = 1;
|
||||
context->sbc_storage_count = 0;
|
||||
context->sbc_ready_to_send = 0;
|
||||
btstack_run_loop_remove_timer(&context->fill_audio_buffer_timer);
|
||||
btstack_run_loop_remove_timer(&context->audio_timer);
|
||||
}
|
||||
|
||||
static void a2dp_fill_audio_buffer_timer_pause(a2dp_media_sending_context_t * context){
|
||||
// context->time_audio_data_sent = 0;
|
||||
btstack_run_loop_remove_timer(&context->fill_audio_buffer_timer);
|
||||
static void a2dp_demo_timer_pause(a2dp_media_sending_context_t * context){
|
||||
btstack_run_loop_remove_timer(&context->audio_timer);
|
||||
}
|
||||
|
||||
|
||||
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
UNUSED(channel);
|
||||
UNUSED(size);
|
||||
uint8_t status;
|
||||
uint8_t local_seid;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (hci_event_packet_get_type(packet)) {
|
||||
case HCI_EVENT_A2DP_META:
|
||||
switch (packet[2]){
|
||||
case A2DP_SUBEVENT_STREAM_ESTABLISHED:
|
||||
status = a2dp_subevent_stream_established_get_status(packet);
|
||||
if (status){
|
||||
printf("Stream establishment failed: status 0x%02x.\n", status);
|
||||
break;
|
||||
}
|
||||
local_seid = a2dp_subevent_stream_established_get_local_seid(packet);
|
||||
if (local_seid != media_tracker.local_seid){
|
||||
printf("Stream establishment failed: wrong local seid %d, expected %d.\n", local_seid, media_tracker.local_seid);
|
||||
break;
|
||||
}
|
||||
|
||||
media_tracker.a2dp_cid = a2dp_subevent_stream_established_get_a2dp_cid(packet);
|
||||
printf("Stream established: a2dp cid 0x%02x, local seid %d, remote seid %d.\n",
|
||||
media_tracker.a2dp_cid, media_tracker.local_seid, a2dp_subevent_stream_established_get_remote_seid(packet));
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_STARTED:
|
||||
a2dp_demo_timer_start(&media_tracker);
|
||||
printf("Stream started.\n");
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:
|
||||
a2dp_demo_send_media_packet();
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_SUSPENDED:
|
||||
printf("Stream paused.\n");
|
||||
a2dp_demo_timer_pause(&media_tracker);
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_RELEASED:
|
||||
printf("Stream released.\n");
|
||||
a2dp_demo_timer_stop(&media_tracker);
|
||||
break;
|
||||
default:
|
||||
printf("AVDTP Source demo: event 0x%02x is not implemented\n", packet[2]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// other packet type
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BTSTACK_STDIN
|
||||
|
||||
static void show_usage(void){
|
||||
bd_addr_t iut_address;
|
||||
gap_local_bd_addr(iut_address);
|
||||
printf("\n--- Bluetooth AVDTP SOURCE Test Console %s ---\n", bd_addr_to_str(iut_address));
|
||||
printf("c - create connection to addr %s\n", bd_addr_to_str(remote));
|
||||
printf("\n--- Bluetooth A2DP Source Test Console %s ---\n", bd_addr_to_str(iut_address));
|
||||
printf("c - create connection to addr %s\n", device_addr_string);
|
||||
printf("x - start streaming sine\n");
|
||||
if (hxcmod_initialized){
|
||||
printf("z - start streaming '%s'\n", mod_name);
|
||||
@ -337,8 +318,8 @@ static void show_usage(void){
|
||||
static void stdin_process(char cmd){
|
||||
switch (cmd){
|
||||
case 'c':
|
||||
printf("Creating L2CAP Connection to %s, PSM_AVDTP\n", bd_addr_to_str(remote));
|
||||
a2dp_source_establish_stream(remote, local_seid, &media_tracker.a2dp_cid);
|
||||
printf("Creating L2CAP Connection to %s, PSM_AVDTP\n", device_addr_string);
|
||||
a2dp_source_establish_stream(device_addr, media_tracker.local_seid, &media_tracker.a2dp_cid);
|
||||
break;
|
||||
case 'x':
|
||||
printf("Playing sine.\n");
|
||||
@ -371,22 +352,18 @@ int btstack_main(int argc, const char * argv[]){
|
||||
UNUSED(argc);
|
||||
(void)argv;
|
||||
|
||||
/* Register for HCI events */
|
||||
hci_event_callback_registration.callback = &packet_handler;
|
||||
hci_add_event_handler(&hci_event_callback_registration);
|
||||
|
||||
l2cap_init();
|
||||
// Initialize AVDTP Source
|
||||
a2dp_source_init();
|
||||
a2dp_source_register_packet_handler(&packet_handler);
|
||||
|
||||
local_seid = a2dp_source_create_stream_endpoint(AVDTP_AUDIO, AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities), media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));
|
||||
media_tracker.local_seid = a2dp_source_create_stream_endpoint(AVDTP_AUDIO, AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities), media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));
|
||||
|
||||
// Initialize SDP
|
||||
sdp_init();
|
||||
memset(sdp_avdtp_source_service_buffer, 0, sizeof(sdp_avdtp_source_service_buffer));
|
||||
a2dp_source_create_sdp_record(sdp_avdtp_source_service_buffer, 0x10002, 1, NULL, NULL);
|
||||
sdp_register_service(sdp_avdtp_source_service_buffer);
|
||||
memset(sdp_a2dp_source_service_buffer, 0, sizeof(sdp_a2dp_source_service_buffer));
|
||||
a2dp_source_create_sdp_record(sdp_a2dp_source_service_buffer, 0x10002, 1, NULL, NULL);
|
||||
sdp_register_service(sdp_a2dp_source_service_buffer);
|
||||
|
||||
gap_set_local_name(device_name);
|
||||
gap_discoverable_control(1);
|
||||
@ -399,11 +376,12 @@ int btstack_main(int argc, const char * argv[]){
|
||||
printf("loaded mod '%s', size %u\n", mod_name, mod_len);
|
||||
}
|
||||
|
||||
// turn on!
|
||||
hci_power_control(HCI_POWER_ON);
|
||||
|
||||
#ifdef HAVE_BTSTACK_STDIN
|
||||
// parse human readable Bluetooth address
|
||||
sscanf_bd_addr(device_addr_string, device_addr);
|
||||
btstack_stdin_setup(stdin_process);
|
||||
#endif
|
||||
// turn on!
|
||||
hci_power_control(HCI_POWER_ON);
|
||||
return 0;
|
||||
}
|
||||
|
@ -62,10 +62,6 @@
|
||||
|
||||
#include "sco_demo_util.h"
|
||||
|
||||
#ifdef HAVE_BTSTACK_STDIN
|
||||
#include "btstack_stdin.h"
|
||||
#endif
|
||||
|
||||
uint8_t hfp_service_buffer[150];
|
||||
const uint8_t rfcomm_channel_nr = 1;
|
||||
const char hfp_hf_service_name[] = "BTstack HFP HF Demo";
|
||||
|
@ -459,10 +459,6 @@ uint8_t a2dp_source_start_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_start_stream(avdtp_cid, local_seid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
uint8_t a2dp_source_release_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_stop_stream(avdtp_cid, local_seid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
uint8_t a2dp_source_pause_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_suspend_stream(avdtp_cid, local_seid, &a2dp_source_context);
|
||||
}
|
||||
@ -477,7 +473,6 @@ uint8_t a2dp_source_stream_endpoint_ready(uint16_t avdtp_cid, uint8_t local_seid
|
||||
return (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING);
|
||||
}
|
||||
|
||||
|
||||
static void a2dp_source_setup_media_header(uint8_t * media_packet, int size, int *offset, uint8_t marker, uint16_t sequence_number){
|
||||
if (size < AVDTP_MEDIA_PAYLOAD_HEADER_SIZE){
|
||||
log_error("small outgoing buffer");
|
||||
|
@ -95,13 +95,6 @@ uint8_t a2dp_source_start_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
*/
|
||||
uint8_t a2dp_source_pause_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Close stream
|
||||
* @param avdtp_cid
|
||||
* @param seid
|
||||
*/
|
||||
uint8_t a2dp_source_release_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Disconnect from device with cid.
|
||||
* @param avdtp_cid
|
||||
|
Loading…
x
Reference in New Issue
Block a user