mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-14 01:27:41 +00:00
introduce flags for suspend, abort, close
This commit is contained in:
parent
46e6b06306
commit
60ec20d049
@ -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){
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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){
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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':
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user