mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-19 16:21:06 +00:00
avdtp: on connect request, check if streaming is already established
This commit is contained in:
parent
04cd6488fb
commit
a0b8a58cf8
@ -109,7 +109,6 @@ uint8_t avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_conte
|
||||
if (!avdtp_cid) {
|
||||
return L2CAP_LOCAL_CID_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
avdtp_context->avdtp_cid = connection->avdtp_cid;
|
||||
|
||||
uint8_t err;
|
||||
@ -127,9 +126,15 @@ uint8_t avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_conte
|
||||
btstack_memory_avdtp_connection_free(connection);
|
||||
}
|
||||
return err;
|
||||
case AVDTP_SIGNALING_CONNECTION_OPENED:
|
||||
case AVDTP_SIGNALING_CONNECTION_OPENED:{
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_signaling_cid(connection->l2cap_signaling_cid, avdtp_context);
|
||||
if (stream_endpoint){
|
||||
avdtp_streaming_emit_connection_established(avdtp_context->avdtp_callback, connection->avdtp_cid, remote, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), 0);
|
||||
break;
|
||||
}
|
||||
avdtp_signaling_emit_connection_established(avdtp_context->avdtp_callback, avdtp_context->avdtp_cid, connection->remote_addr, ERROR_CODE_SUCCESS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log_error("avdtp_connect: sink in wrong state");
|
||||
return AVDTP_CONNECTION_IN_WRONG_STATE;
|
||||
@ -335,36 +340,32 @@ static void stream_endpoint_state_machine(avdtp_connection_t * connection, avdtp
|
||||
switch (event){
|
||||
case L2CAP_EVENT_CHANNEL_OPENED:
|
||||
l2cap_event_channel_opened_get_address(packet, address);
|
||||
if (stream_endpoint->l2cap_media_cid != 0){
|
||||
log_error("stream_endpoint_state_machine: channel already opened\n");
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, address, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), L2CAP_SERVICE_ALREADY_REGISTERED);
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
status = l2cap_event_channel_opened_get_status(packet);
|
||||
if (status){
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed with status %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", status, connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_IDLE;
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, address, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), status);
|
||||
break;
|
||||
}
|
||||
if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_CONNECTED){
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed - stream endpoint in wrong state %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", stream_endpoint->state, connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, address, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE);
|
||||
break;
|
||||
}
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_OPENED;
|
||||
stream_endpoint->connection = connection;
|
||||
stream_endpoint->l2cap_media_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||
stream_endpoint->media_con_handle = l2cap_event_channel_opened_get_handle(packet);
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, address, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_CONNECTED){
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed - stream endpoint in wrong state %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", stream_endpoint->state, connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, address, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE);
|
||||
break;
|
||||
}
|
||||
|
||||
status = l2cap_event_channel_opened_get_status(packet);
|
||||
if (status){
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed with status %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", status, connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_IDLE;
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, address, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), status);
|
||||
break;
|
||||
}
|
||||
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_OPENED;
|
||||
stream_endpoint->connection = connection;
|
||||
stream_endpoint->l2cap_media_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||
stream_endpoint->media_con_handle = l2cap_event_channel_opened_get_handle(packet);
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d", connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, address, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), 0);
|
||||
break;
|
||||
|
||||
case L2CAP_EVENT_CHANNEL_CLOSED:
|
||||
local_cid = l2cap_event_channel_closed_get_local_cid(packet);
|
||||
log_info("L2CAP_EVENT_CHANNEL_CLOSED stream endpoint sm: media cid 0x%02x, local cid 0x%02x\n", stream_endpoint->l2cap_media_cid , local_cid);
|
||||
if (stream_endpoint->l2cap_media_cid == local_cid){
|
||||
avdtp_streaming_emit_connection_released(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint));
|
||||
stream_endpoint->l2cap_media_cid = 0;
|
||||
@ -606,42 +607,46 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
break;
|
||||
|
||||
case L2CAP_EVENT_CHANNEL_OPENED:
|
||||
psm = l2cap_event_channel_opened_get_psm(packet);
|
||||
if (psm != BLUETOOTH_PROTOCOL_AVDTP){
|
||||
log_info("unexpected PSM - Not implemented yet, avdtp sink: L2CAP_EVENT_CHANNEL_OPENED");
|
||||
return;
|
||||
}
|
||||
|
||||
status = l2cap_event_channel_opened_get_status(packet);
|
||||
// inform about new l2cap connection
|
||||
l2cap_event_channel_opened_get_address(packet, event_addr);
|
||||
local_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||
if (status){
|
||||
log_error("L2CAP connection to %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status);
|
||||
if (connection){
|
||||
connection = avdtp_connection_for_bd_addr(event_addr, context);
|
||||
|
||||
log_info("L2CAP_EVENT_CHANNEL_OPENED: status %d, cid 0x%02x , signaling connection %p \n", status, local_cid, connection);
|
||||
connection = avdtp_connection_for_bd_addr(event_addr, context);
|
||||
if (!connection){
|
||||
log_info("L2CAP_EVENT_CHANNEL_OPENED 2: status %d, signaling connection %p \n", status, connection);
|
||||
break;
|
||||
}
|
||||
|
||||
if (connection->l2cap_signaling_cid == 0) {
|
||||
if (status){
|
||||
log_info("L2CAP connection to %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status);
|
||||
connection->state = AVDTP_SIGNALING_CONNECTION_IDLE;
|
||||
connection->l2cap_signaling_cid = 0;
|
||||
avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, event_addr, l2cap_event_channel_opened_get_status(packet));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
psm = l2cap_event_channel_opened_get_psm(packet);
|
||||
if (psm != BLUETOOTH_PROTOCOL_AVDTP){
|
||||
log_error("unexpected PSM - Not implemented yet, avdtp sink: L2CAP_EVENT_CHANNEL_OPENED");
|
||||
return;
|
||||
}
|
||||
// log_info("L2CAP_EVENT_CHANNEL_OPENED: Channel successfully opened: %s, handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x",
|
||||
// bd_addr_to_str(event_addr), l2cap_event_channel_opened_get_handle(packet), psm, local_cid, l2cap_event_channel_opened_get_remote_cid(packet));
|
||||
|
||||
if (psm != BLUETOOTH_PROTOCOL_AVDTP) break;
|
||||
|
||||
connection = avdtp_connection_for_bd_addr(event_addr, context);
|
||||
if (!connection) break;
|
||||
|
||||
if (connection->l2cap_signaling_cid == 0) {
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED) break;
|
||||
}
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED) {
|
||||
log_info("L2CAP connection to %s failed. status code 0x%02x", bd_addr_to_str(event_addr), status);
|
||||
avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, event_addr, AVDTP_CONNECTION_IN_WRONG_STATE);
|
||||
break;
|
||||
}
|
||||
connection->l2cap_signaling_cid = local_cid;
|
||||
connection->local_seid = 0;
|
||||
connection->state = AVDTP_SIGNALING_CONNECTION_OPENED;
|
||||
log_info(" -> AVDTP_SIGNALING_CONNECTION_OPENED, connection %p, avdtp_cid 0x%02x", connection, connection->avdtp_cid);
|
||||
log_info(" -> AVDTP_SIGNALING_CONNECTION_OPENED, connection %p, avdtp_cid 0x%02x", connection, local_cid);
|
||||
avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, event_addr, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
stream_endpoint = avdtp_stream_endpoint_for_seid(connection->local_seid, context);
|
||||
if (!stream_endpoint){
|
||||
log_info("L2CAP_EVENT_CHANNEL_OPENED: stream_endpoint not found");
|
||||
@ -657,10 +662,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
log_info("received L2CAP_EVENT_CHANNEL_CLOSED, cid 0x%2x, %p, %p\n", local_cid, connection, stream_endpoint);
|
||||
|
||||
if (stream_endpoint){
|
||||
if (!connection){
|
||||
connection = stream_endpoint->connection;
|
||||
}
|
||||
stream_endpoint_state_machine(connection, stream_endpoint, HCI_EVENT_PACKET, L2CAP_EVENT_CHANNEL_CLOSED, packet, size, context);
|
||||
stream_endpoint_state_machine(stream_endpoint->connection, stream_endpoint, HCI_EVENT_PACKET, L2CAP_EVENT_CHANNEL_CLOSED, packet, size, context);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -144,6 +144,20 @@ avdtp_stream_endpoint_t * avdtp_stream_endpoint_for_l2cap_cid(uint16_t l2cap_cid
|
||||
return NULL;
|
||||
}
|
||||
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_for_signaling_cid(uint16_t l2cap_cid, avdtp_context_t * context){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &context->stream_endpoints);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = (avdtp_stream_endpoint_t *)btstack_linked_list_iterator_next(&it);
|
||||
if (stream_endpoint->connection){
|
||||
if (stream_endpoint->connection->l2cap_signaling_cid == l2cap_cid){
|
||||
return stream_endpoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_with_seid(uint8_t seid, avdtp_context_t * context){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &context->stream_endpoints);
|
||||
@ -811,14 +825,17 @@ void avdtp_signaling_emit_media_codec_other_reconfiguration(btstack_packet_handl
|
||||
|
||||
|
||||
void avdtp_request_can_send_now_acceptor(avdtp_connection_t * connection, uint16_t l2cap_cid){
|
||||
if (!connection) return;
|
||||
connection->wait_to_send_acceptor = 1;
|
||||
l2cap_request_can_send_now_event(l2cap_cid);
|
||||
}
|
||||
void avdtp_request_can_send_now_initiator(avdtp_connection_t * connection, uint16_t l2cap_cid){
|
||||
if (!connection) return;
|
||||
connection->wait_to_send_initiator = 1;
|
||||
l2cap_request_can_send_now_event(l2cap_cid);
|
||||
}
|
||||
void avdtp_request_can_send_now_self(avdtp_connection_t * connection, uint16_t l2cap_cid){
|
||||
if (!connection) return;
|
||||
connection->wait_to_send_self = 1;
|
||||
l2cap_request_can_send_now_event(l2cap_cid);
|
||||
}
|
||||
@ -863,6 +880,7 @@ uint8_t avdtp_remote_seid(avdtp_stream_endpoint_t * stream_endpoint){
|
||||
|
||||
void a2dp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t cid, bd_addr_t addr, uint8_t local_seid, uint8_t remote_seid, uint8_t status){
|
||||
if (!callback) return;
|
||||
printf("emit A2DP_SUBEVENT_STREAM_ESTABLISHED\n");
|
||||
uint8_t event[14];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_A2DP_META;
|
||||
|
@ -61,6 +61,7 @@ avdtp_stream_endpoint_t * avdtp_stream_endpoint_for_l2cap_cid(uint16_t l2cap_cid
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_with_seid(uint8_t seid, avdtp_context_t * context);
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_associated_with_acp_seid(uint16_t acp_seid, avdtp_context_t * context);
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_for_seid(uint16_t seid, avdtp_context_t * context);
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_for_signaling_cid(uint16_t l2cap_cid, avdtp_context_t * context);
|
||||
|
||||
static inline uint8_t avdtp_header(uint8_t tr_label, avdtp_packet_type_t packet_type, avdtp_message_type_t msg_type){
|
||||
return (tr_label<<4) | ((uint8_t)packet_type<<2) | (uint8_t)msg_type;
|
||||
|
Loading…
x
Reference in New Issue
Block a user