introduce flags for suspend, abort, close

This commit is contained in:
Milanka Ringwald 2017-04-25 17:12:36 +02:00
parent 46e6b06306
commit 60ec20d049
11 changed files with 197 additions and 185 deletions

View File

@ -352,7 +352,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
case A2DP_STREAMING_OPENED:
if (!a2dp_source_context.a2dp_callback) return;
switch (signal_identifier){
case AVDTP_SI_START:{
case AVDTP_SI_START:{
uint8_t event[6];
int pos = 0;
event[pos++] = HCI_EVENT_A2DP_META;
@ -372,11 +372,11 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
event[pos++] = A2DP_SUBEVENT_STREAM_RELEASED;
little_endian_store_16(event, pos, avdtp_cid);
pos += 2;
printf("send A2DP_SUBEVENT_STREAM_RELEASED to app\n");
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
(*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
break;
}
case AVDTP_SI_SUSPEND:{
uint8_t event[6];
int pos = 0;
@ -472,13 +472,17 @@ void a2dp_source_release_stream(uint8_t int_seid){
avdtp_stop_stream(int_seid, &a2dp_source_context);
}
void a2dp_source_pause_stream(uint8_t int_seid){
avdtp_suspend_stream(int_seid, &a2dp_source_context);
}
uint8_t a2dp_source_stream_endpoint_ready(uint8_t local_seid){
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
if (!stream_endpoint) {
printf("no stream_endpoint");
return 0;
}
return (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING || stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING_W2_SEND);
return (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING);
}
@ -544,14 +548,15 @@ static void a2dp_source_copy_media_payload(uint8_t * media_packet, int size, int
media_packet[sbc_header_index] = (fragmentation << 7) | (starting_packet << 6) | (last_packet << 5) | num_frames;
*offset = pos;
}
void a2dp_source_stream_endpoint_request_can_send_now(uint8_t local_seid){
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
if (!stream_endpoint) {
printf("no stream_endpoint");
return;
}
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_STREAMING_W2_SEND;
avdtp_request_can_send_now_self(stream_endpoint->connection, stream_endpoint->l2cap_media_cid);
stream_endpoint->send_stream = 1;
avdtp_request_can_send_now_initiator(stream_endpoint->connection, stream_endpoint->l2cap_media_cid);
}
void a2dp_source_stream_send_media_payload(uint8_t int_seid, btstack_ring_buffer_t * sbc_ring_buffer, uint8_t marker){

View File

@ -73,7 +73,7 @@ uint8_t a2dp_source_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_
uint8_t * codec_configuration, uint16_t codec_configuration_len);
/**
* @brief Start stream
* @brief Open stream
* @param avdtp_cid
* @param seid
*/
@ -91,6 +91,13 @@ void a2dp_source_start_stream(uint8_t int_seid);
* @param avdtp_cid
* @param seid
*/
void a2dp_source_pause_stream(uint8_t int_seid);
/**
* @brief Close stream
* @param avdtp_cid
* @param seid
*/
void a2dp_source_release_stream(uint8_t int_seid);
/**

View File

@ -422,10 +422,6 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
if (!connection) {
stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(channel, context);
if (!stream_endpoint->connection) break;
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING_W2_SEND){
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_STREAMING;
avdtp_streaming_emit_can_send_media_packet_now(context->avdtp_callback, stream_endpoint->l2cap_media_cid, stream_endpoint->sep.seid, stream_endpoint->sequence_number);
}
connection = stream_endpoint->connection;
}
avdtp_handle_can_send_now(connection, channel, context);
@ -491,19 +487,13 @@ void avdtp_start_stream(uint8_t int_seid, avdtp_context_t * context){
printf("avdtp_start_stream: no stream_endpoint with seid %d found\n", int_seid);
return;
}
avdtp_connection_t * connection = stream_endpoint->connection;
if (!connection){
printf("avdtp_start_stream: no connection for seid %d found\n", int_seid);
printf("avdtp_stop_stream: no connection for seid %d found\n",stream_endpoint->sep.seid);
return;
}
if (stream_endpoint->remote_sep_index == 0xFF) return;
if (stream_endpoint->state < AVDTP_STREAM_ENDPOINT_OPENED) return;
connection->initiator_transaction_label++;
connection->acp_seid = stream_endpoint->connection->remote_seps[stream_endpoint->remote_sep_index].seid;
connection->int_seid = stream_endpoint->sep.seid;
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_STREAMING_START;
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->start_stream) return;
stream_endpoint->start_stream = 1;
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
}
@ -513,67 +503,46 @@ void avdtp_stop_stream(uint8_t int_seid, avdtp_context_t * context){
printf("avdtp_stop_stream: no stream_endpoint with seid %d found\n", int_seid);
return;
}
if (stream_endpoint->remote_sep_index == 0xFF) return;
switch (stream_endpoint->state){
case AVDTP_STREAM_ENDPOINT_OPENED:
case AVDTP_STREAM_ENDPOINT_STREAMING:
if (!stream_endpoint->connection){
printf("avdtp_stop_stream: no connection for seid %d found\n",stream_endpoint->sep.seid);
return;
}
printf(" AVDTP_INITIATOR_W2_STREAMING_STOP \n");
stream_endpoint->connection->initiator_transaction_label++;
stream_endpoint->connection->acp_seid = stream_endpoint->connection->remote_seps[stream_endpoint->remote_sep_index].seid;
stream_endpoint->connection->int_seid = stream_endpoint->sep.seid;
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_STREAMING_STOP;
avdtp_request_can_send_now_initiator(stream_endpoint->connection, stream_endpoint->connection->l2cap_signaling_cid);
break;
default:
break;
avdtp_connection_t * connection = stream_endpoint->connection;
if (!connection){
printf("avdtp_stop_stream: no connection for seid %d found\n",stream_endpoint->sep.seid);
return;
}
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->stop_stream) return;
stream_endpoint->stop_stream = 1;
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
}
void avdtp_abort_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context){
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
if (!connection){
printf("avdtp_abort_stream: no connection for signaling cid 0x%02x found\n", avdtp_cid);
return;
}
if (avdtp_find_remote_sep(connection, acp_seid) == 0xFF){
printf("avdtp_abort_stream: no remote sep for seid %d found\n", acp_seid);
return;
}
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) {
printf("avdtp_abort_stream: wrong connection state %d\n", connection->state);
return;
}
void avdtp_abort_stream(uint8_t int_seid, avdtp_context_t * context){
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
if (!stream_endpoint) {
printf("avdtp_abort_stream: no stream_endpoint with seid %d found\n", int_seid);
return;
}
if (stream_endpoint->remote_sep_index == 0xFF) return;
switch (stream_endpoint->state){
case AVDTP_STREAM_ENDPOINT_CONFIGURED:
case AVDTP_STREAM_ENDPOINT_CLOSING:
case AVDTP_STREAM_ENDPOINT_OPENED:
case AVDTP_STREAM_ENDPOINT_STREAMING:
printf(" AVDTP_INITIATOR_W2_STREAMING_ABORT \n");
connection->initiator_transaction_label++;
connection->acp_seid = acp_seid;
connection->int_seid = stream_endpoint->sep.seid;
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_STREAMING_ABORT;
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
break;
default:
break;
avdtp_connection_t * connection = stream_endpoint->connection;
if (!connection){
printf("avdtp_abort_stream: no connection for seid %d found\n",stream_endpoint->sep.seid);
return;
}
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->abort_stream) return;
stream_endpoint->abort_stream = 1;
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
}
void avdtp_suspend_stream(uint8_t int_seid, avdtp_context_t * context){
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
if (!stream_endpoint) {
printf("avdtp_abort_stream: no stream_endpoint with seid %d found\n", int_seid);
return;
}
avdtp_connection_t * connection = stream_endpoint->connection;
if (!connection){
printf("avdtp_abort_stream: no connection for seid %d found\n",stream_endpoint->sep.seid);
return;
}
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->suspend_stream) return;
stream_endpoint->suspend_stream = 1;
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
}
void avdtp_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * context){
@ -697,31 +666,6 @@ void avdtp_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, u
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
}
void avdtp_suspend(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context){
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
if (!connection){
printf("avdtp_suspend: no connection for signaling cid 0x%02x found\n", avdtp_cid);
return;
}
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return;
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, context);
if (!stream_endpoint) {
log_error("avdtp_reconfigure: no initiator stream endpoint for seid %d\n", int_seid);
return;
}
if (stream_endpoint->remote_sep_index == 0xFF){
log_error("avdtp_reconfigure: no associated remote sep\n");
return;
}
connection->initiator_transaction_label++;
connection->acp_seid = acp_seid;
connection->int_seid = stream_endpoint->sep.seid;
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_SUSPEND_STREAM_WITH_SEID;
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
}
uint8_t avdtp_remote_seps_num(uint16_t avdtp_cid, avdtp_context_t * context){
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
if (!connection){

View File

@ -283,7 +283,6 @@ typedef enum {
AVDTP_STREAM_ENDPOINT_OPENED,
AVDTP_STREAM_ENDPOINT_STREAMING,
AVDTP_STREAM_ENDPOINT_STREAMING_W2_SEND,
AVDTP_STREAM_ENDPOINT_CLOSING,
AVDTP_STREAM_ENDPOINT_ABORTING,
@ -298,8 +297,6 @@ typedef enum {
AVDTP_INITIATOR_W2_OPEN_STREAM,
AVDTP_INITIATOR_W2_STREAMING_START,
AVDTP_INITIATOR_W2_STREAMING_STOP,
AVDTP_INITIATOR_W2_STREAMING_ABORT,
AVDTP_INITIATOR_FRAGMENTATED_COMMAND,
AVDTP_INITIATOR_W4_ANSWER
@ -462,6 +459,12 @@ typedef struct avdtp_stream_endpoint {
// register request for media L2cap connection release
uint8_t media_disconnect;
uint8_t media_connect;
uint8_t start_stream;
uint8_t stop_stream;
uint8_t send_stream;
uint8_t abort_stream;
uint8_t suspend_stream;
uint16_t sequence_number;
} avdtp_stream_endpoint_t;
@ -493,7 +496,8 @@ void avdtp_disconnect(uint16_t avdtp_cid, avdtp_context_t * context);
void avdtp_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context);
void avdtp_start_stream(uint8_t int_seid, avdtp_context_t * context);
void avdtp_stop_stream (uint8_t int_seid, avdtp_context_t * context);
void avdtp_abort_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context);
void avdtp_abort_stream(uint8_t int_seid, avdtp_context_t * context);
void avdtp_suspend_stream(uint8_t int_seid, avdtp_context_t * context);
void avdtp_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * context);
void avdtp_get_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context);
@ -501,7 +505,6 @@ void avdtp_get_all_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_cont
void avdtp_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context);
void avdtp_set_configuration(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context);
void avdtp_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context);
void avdtp_suspend(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context);
uint8_t avdtp_remote_seps_num(uint16_t avdtp_cid, avdtp_context_t * context);
avdtp_sep_t * avdtp_remote_sep(uint16_t avdtp_cid, uint8_t index, avdtp_context_t * context);

View File

@ -88,7 +88,6 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
switch (connection->signaling_packet.message_type){
case AVDTP_RESPONSE_ACCEPT_MSG:
printf(" INT: AVDTP_RESPONSE_ACCEPT_MSG: ");
switch (connection->signaling_packet.signal_identifier){
case AVDTP_SI_DISCOVER:{
printf("AVDTP_SI_DISCOVER\n");
@ -229,7 +228,9 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
status = 1;
printf(" AVDTP_RESPONSE_ACCEPT_MSG, signal %d not implemented\n", connection->signaling_packet.signal_identifier);
break;
}
}
avdtp_signaling_emit_accept(context->avdtp_callback, connection->l2cap_signaling_cid, 0, connection->signaling_packet.signal_identifier, status);
connection->initiator_transaction_label++;
break;
case AVDTP_RESPONSE_REJECT_MSG:
printf(" AVDTP_RESPONSE_REJECT_MSG signal %d\n", connection->signaling_packet.signal_identifier);
@ -242,11 +243,6 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
default:
break;
}
avdtp_signaling_emit_accept(context->avdtp_callback, connection->l2cap_signaling_cid, 0, connection->signaling_packet.signal_identifier, status);
connection->initiator_transaction_label++;
// connection->int_seid = 0;
// connection->acp_seid = 0;
}
void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, avdtp_context_t * context){
@ -292,6 +288,64 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
avdtp_initiator_stream_endpoint_state_t stream_endpoint_state = stream_endpoint->initiator_config_state;
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W4_ANSWER;
if (stream_endpoint->start_stream){
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_OPENED){
stream_endpoint->start_stream = 0;
connection->int_seid = stream_endpoint->sep.seid;
connection->acp_seid = connection->remote_seps[stream_endpoint->remote_sep_index].seid;
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_START, connection->initiator_transaction_label++, connection->acp_seid);
return;
}
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
return;
}
if (stream_endpoint->stop_stream){
if (stream_endpoint->state >= AVDTP_STREAM_ENDPOINT_OPENED){
stream_endpoint->stop_stream = 0;
connection->int_seid = stream_endpoint->sep.seid;
connection->acp_seid = connection->remote_seps[stream_endpoint->remote_sep_index].seid;
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_CLOSE, connection->initiator_transaction_label++, connection->acp_seid);
return;
}
}
if (stream_endpoint->abort_stream){
switch (stream_endpoint->state){
case AVDTP_STREAM_ENDPOINT_CONFIGURED:
case AVDTP_STREAM_ENDPOINT_CLOSING:
case AVDTP_STREAM_ENDPOINT_OPENED:
case AVDTP_STREAM_ENDPOINT_STREAMING:
stream_endpoint->abort_stream = 0;
connection->int_seid = stream_endpoint->sep.seid;
connection->acp_seid = connection->remote_seps[stream_endpoint->remote_sep_index].seid;
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_ABORTING;
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_ABORT, connection->initiator_transaction_label++, connection->acp_seid);
return;
default:
break;
}
}
if (stream_endpoint->suspend_stream){
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING){
stream_endpoint->suspend_stream = 0;
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_STREAMING;
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_SUSPEND, connection->initiator_transaction_label, connection->acp_seid);
return;
}
}
if (stream_endpoint->send_stream){
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING){
stream_endpoint->send_stream = 0;
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_STREAMING;
avdtp_streaming_emit_can_send_media_packet_now(context->avdtp_callback, stream_endpoint->l2cap_media_cid, stream_endpoint->sep.seid, stream_endpoint->sequence_number);
return;
}
}
switch (stream_endpoint_state){
case AVDTP_INITIATOR_W2_SET_CONFIGURATION:
@ -336,31 +390,15 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_OPEN, connection->initiator_transaction_label, connection->acp_seid);
break;
default:
sent = 0;
break;
}
break;
case AVDTP_INITIATOR_W2_SUSPEND_STREAM_WITH_SEID:
printf(" INT: AVDTP_INITIATOR_W4_SUSPEND_STREAM_WITH_SEID\n");
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_SUSPEND, connection->initiator_transaction_label, connection->acp_seid);
break;
case AVDTP_INITIATOR_W2_STREAMING_START:
printf(" INT: AVDTP_INITIATOR_W4_STREAMING_START\n");
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_START, connection->initiator_transaction_label, connection->acp_seid);
break;
case AVDTP_INITIATOR_W2_STREAMING_STOP:
printf(" INT: AVDTP_INITIATOR_W4_STREAMING_STOP\n");
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_CLOSE, connection->initiator_transaction_label, connection->acp_seid);
break;
case AVDTP_INITIATOR_W2_STREAMING_ABORT:
printf(" INT: AVDTP_INITIATOR_W4_STREAMING_ABORT\n");
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_ABORTING;
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_ABORT, connection->initiator_transaction_label, connection->acp_seid);
break;
default:
sent = 0;
break;
}
// check fragmentation
if (connection->signaling_packet.packet_type != AVDTP_SINGLE_PACKET && connection->signaling_packet.packet_type != AVDTP_END_PACKET){
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);

View File

@ -163,8 +163,12 @@ void avdtp_sink_stop_stream(uint8_t int_seid){
avdtp_stop_stream(int_seid, &avdtp_sink_context);
}
void avdtp_sink_abort_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid){
avdtp_abort_stream(avdtp_cid, int_seid, acp_seid, &avdtp_sink_context);
void avdtp_sink_abort_stream(uint8_t int_seid){
avdtp_abort_stream(int_seid, &avdtp_sink_context);
}
void avdtp_sink_suspend(uint8_t int_seid){
avdtp_suspend_stream(int_seid, &avdtp_sink_context);
}
void avdtp_sink_discover_stream_endpoints(uint16_t avdtp_cid){
@ -191,6 +195,3 @@ void avdtp_sink_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_se
avdtp_reconfigure(avdtp_cid, int_seid, acp_seid, configured_services_bitmap, configuration, &avdtp_sink_context);
}
void avdtp_sink_suspend(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid){
avdtp_suspend(avdtp_cid, int_seid, acp_seid, &avdtp_sink_context);
}

View File

@ -130,13 +130,6 @@ void avdtp_sink_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_se
*/
void avdtp_sink_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid);
/**
* @brief Suspend stream
* @param avdtp_cid
* @param seid
*/
void avdtp_sink_suspend(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
/**
* @brief Open stream
@ -145,26 +138,30 @@ void avdtp_sink_suspend(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
*/
void avdtp_sink_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
/**
* @brief Start stream
* @param avdtp_cid
* @param seid
*/
void avdtp_sink_start_stream(uint8_t int_seid);
/**
* @brief Start stream
* @param avdtp_cid
* @param seid
* @param local_seid
*/
void avdtp_sink_abort_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
void avdtp_sink_start_stream(uint8_t local_seid);
/**
* @brief Abort stream
* @param local_seid
*/
void avdtp_sink_abort_stream(uint8_t local_seid);
/**
* @brief Start stream
* @param avdtp_cid
* @param seid
* @param local_seid
*/
void avdtp_sink_stop_stream(uint8_t int_seid);
void avdtp_sink_stop_stream(uint8_t local_seid);
/**
* @brief Suspend stream
* @param local_seid
*/
void avdtp_sink_suspend(uint8_t local_seid);
/* API_END */

View File

@ -133,8 +133,12 @@ void avdtp_source_stop_stream(uint8_t int_seid){
avdtp_stop_stream(int_seid, avdtp_source_context);
}
void avdtp_source_abort_stream(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid){
avdtp_abort_stream(con_handle, int_seid, acp_seid, avdtp_source_context);
void avdtp_source_abort_stream(uint8_t int_seid){
avdtp_abort_stream(int_seid, avdtp_source_context);
}
void avdtp_source_suspend(uint8_t int_seid){
avdtp_suspend_stream(int_seid, avdtp_source_context);
}
void avdtp_source_discover_stream_endpoints(uint16_t con_handle){
@ -161,10 +165,6 @@ void avdtp_source_reconfigure(uint16_t con_handle, uint8_t int_seid, uint8_t acp
avdtp_reconfigure(con_handle, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_source_context);
}
void avdtp_source_suspend(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid){
avdtp_suspend(con_handle, int_seid, acp_seid, avdtp_source_context);
}
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
avdtp_packet_handler(packet_type, channel, packet, size, avdtp_source_context);
}

View File

@ -116,13 +116,6 @@ void avdtp_source_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_
*/
void avdtp_source_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid);
/**
* @brief Suspend stream
* @param avdtp_cid
* @param seid
*/
void avdtp_source_suspend(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
/**
* @brief Open stream
@ -133,24 +126,28 @@ void avdtp_source_open_stream(uint16_t con_handle, uint8_t int_seid, uint8_t acp
/**
* @brief Start stream
* @param avdtp_cid
* @param seid
* @param local_seid
*/
void avdtp_source_start_stream(uint8_t int_seid);
void avdtp_source_start_stream(uint8_t local_seid);
/**
* @brief Abort stream
* @param local_seid
*/
void avdtp_source_abort_stream(uint8_t local_seid);
/**
* @brief Start stream
* @param avdtp_cid
* @param seid
* @param local_seid
*/
void avdtp_source_abort_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
void avdtp_source_stop_stream(uint8_t local_seid);
/**
* @brief Start stream
* @param avdtp_cid
* @param seid
* @brief Suspend stream
* @param local_seid
*/
void avdtp_source_stop_stream(uint8_t int_seid);
void avdtp_source_suspend(uint8_t local_seid);
avdtp_stream_endpoint_t * avdtp_source_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type);

View File

@ -609,7 +609,7 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
break;
case 'A':
app_state = AVDTP_APPLICATION_W2_ABORT_STREAM_WITH_SEID;
avdtp_sink_abort_stream(avdtp_cid, local_stream_endpoint->sep.seid, sep.seid);
avdtp_sink_abort_stream(local_stream_endpoint->sep.seid);
break;
case 'S':
app_state = AVDTP_APPLICATION_W2_STOP_STREAM_WITH_SEID;
@ -617,7 +617,7 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
break;
case 'P':
app_state = AVDTP_APPLICATION_W2_SUSPEND_STREAM_WITH_SEID;
avdtp_sink_suspend(avdtp_cid, local_stream_endpoint->sep.seid, sep.seid);
avdtp_sink_suspend(local_stream_endpoint->sep.seid);
break;
case '\n':

View File

@ -110,13 +110,14 @@ static uint8_t sbc_storage[44100*4];
typedef struct {
uint16_t a2dp_cid;
uint8_t local_seid;
uint8_t remote_seid;
uint32_t fill_audio_ring_buffer_timeout_ms;
uint32_t time_audio_data_sent; // ms
uint32_t acc_num_missed_samples;
uint32_t samples_ready;
btstack_timer_source_t fill_audio_ring_buffer_timer;
uint32_t paused_at_ms;
uint8_t paused;
btstack_ring_buffer_t sbc_ring_buffer;
} a2dp_media_sending_context_t;
@ -136,6 +137,7 @@ static btstack_packet_callback_registration_t hci_event_callback_registration;
static void a2dp_fill_audio_ring_buffer_timer_start(a2dp_media_sending_context_t * context);
static void a2dp_fill_audio_ring_buffer_timer_stop(a2dp_media_sending_context_t * context);
static void a2dp_fill_audio_ring_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);
@ -149,17 +151,16 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
switch (packet[2]){
case A2DP_SUBEVENT_STREAM_ESTABLISHED:
media_tracker.local_seid = a2dp_subevent_stream_established_get_local_seid(packet);
media_tracker.remote_seid = a2dp_subevent_stream_established_get_remote_seid(packet);
media_tracker.a2dp_cid = a2dp_subevent_stream_established_get_a2dp_cid(packet);
printf(" --- application --- A2DP_SUBEVENT_STREAM_ESTABLISHED, a2dp_cid 0x%02x, local seid %d, remote seid %d\n",
media_tracker.a2dp_cid, media_tracker.local_seid, media_tracker.remote_seid);
media_tracker.a2dp_cid, media_tracker.local_seid, a2dp_subevent_stream_established_get_remote_seid(packet));
break;
case A2DP_SUBEVENT_STREAM_START_ACCEPTED:
if (local_seid != media_tracker.local_seid) break;
if (!a2dp_source_stream_endpoint_ready(media_tracker.local_seid)) break;
printf(" --- application --- A2DP_SUBEVENT_STREAM_START_ACCEPTED, local seid %d\n", media_tracker.local_seid);
a2dp_fill_audio_ring_buffer_timer_start(&media_tracker);
printf(" --- application --- A2DP_SUBEVENT_STREAM_START_ACCEPTED, local seid %d\n", media_tracker.local_seid);
break;
case A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:
@ -169,15 +170,15 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
a2dp_source_stream_endpoint_request_can_send_now(media_tracker.local_seid);
}
break;
case A2DP_SUBEVENT_STREAM_SUSPENDED:
if (local_seid != media_tracker.local_seid) break;
printf(" --- application --- A2DP_SUBEVENT_STREAM_SUSPENDED, local seid %d\n", media_tracker.local_seid);
a2dp_fill_audio_ring_buffer_timer_stop(&media_tracker);
a2dp_fill_audio_ring_buffer_timer_pause(&media_tracker);
break;
case A2DP_SUBEVENT_STREAM_RELEASED:
printf(" --- application --- A2DP_SUBEVENT_STREAM_RELEASED, local seid %d\n", media_tracker.local_seid);
a2dp_fill_audio_ring_buffer_timer_stop(&media_tracker);
break;
default:
printf(" --- application --- not implemented\n");
@ -281,8 +282,14 @@ static void avdtp_fill_audio_ring_buffer_timeout_handler(btstack_timer_source_t
uint32_t update_period_ms = context->fill_audio_ring_buffer_timeout_ms;
if (context->time_audio_data_sent > 0){
update_period_ms = now - context->time_audio_data_sent;
if (context->paused_at_ms > 0){
update_period_ms = context->paused_at_ms - context->time_audio_data_sent;
context->paused_at_ms = 0;
} else {
update_period_ms = now - context->time_audio_data_sent;
}
}
uint32_t num_samples = (update_period_ms * 44100) / 1000;
context->acc_num_missed_samples += (update_period_ms * 44100) % 1000;
@ -310,6 +317,14 @@ static void a2dp_fill_audio_ring_buffer_timer_start(a2dp_media_sending_context_t
}
static void a2dp_fill_audio_ring_buffer_timer_stop(a2dp_media_sending_context_t * context){
context->paused_at_ms = 0;
context->time_audio_data_sent = 0;
btstack_run_loop_remove_timer(&context->fill_audio_ring_buffer_timer);
}
static void a2dp_fill_audio_ring_buffer_timer_pause(a2dp_media_sending_context_t * context){
context->paused_at_ms = btstack_run_loop_get_time_ms();
context->time_audio_data_sent = 0;
btstack_run_loop_remove_timer(&context->fill_audio_ring_buffer_timer);
}
@ -336,10 +351,15 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
a2dp_source_disconnect(media_tracker.a2dp_cid);
break;
case 'x':
printf(" --- application --- a2dp_source_stream_data_start --- local seid %d, remote seid %d\n", media_tracker.local_seid, media_tracker.remote_seid);
printf(" --- application --- call a2dp_source_stream_data_start --- local seid %d\n", media_tracker.local_seid);
a2dp_source_start_stream(media_tracker.local_seid);
break;
case 'X':
case 'p':
printf(" --- application --- call a2dp_source_stream_data_pause --- local seid %d\n", media_tracker.local_seid);
a2dp_source_pause_stream(media_tracker.local_seid);
break;
case 'X':
printf(" --- application --- call a2dp_source_release_stream --- local seid %d\n", media_tracker.local_seid);
a2dp_source_release_stream(media_tracker.local_seid);
break;
default: