From 598f5579d70d3048103afcc9f461f6b5473b947e Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Wed, 16 Nov 2016 16:19:03 +0100 Subject: [PATCH] avdtp: handle multiple can send now --- test/avdtp/avdtp.h | 5 +- test/avdtp/avdtp_acceptor.c | 26 +++--- test/avdtp/avdtp_acceptor.h | 4 +- test/avdtp/avdtp_initiator.c | 20 ++--- test/avdtp/avdtp_initiator.h | 4 +- test/avdtp/avdtp_sink.c | 165 ++++++++++++++++++++++++----------- 6 files changed, 143 insertions(+), 81 deletions(-) diff --git a/test/avdtp/avdtp.h b/test/avdtp/avdtp.h index 5cd0a72a1..f21abb2f1 100644 --- a/test/avdtp/avdtp.h +++ b/test/avdtp/avdtp.h @@ -367,7 +367,10 @@ typedef enum { typedef struct { bd_addr_t remote_addr; + uint16_t l2cap_signaling_cid; + btstack_linked_list_t can_send_now_signaling_channel_requests; + btstack_linked_list_t stream_endpoints; uint16_t stream_endpoints_id_counter; @@ -380,7 +383,7 @@ typedef struct { uint8_t query_seid; avdtp_service_mode_t service_mode; -} avdtp_device_t; +} avdtp_connection_t; #if defined __cplusplus } diff --git a/test/avdtp/avdtp_acceptor.c b/test/avdtp/avdtp_acceptor.c index 8c7af4655..8e389f99e 100644 --- a/test/avdtp/avdtp_acceptor.c +++ b/test/avdtp/avdtp_acceptor.c @@ -227,7 +227,7 @@ int avdtp_acceptor_stream_config_subsm_is_done(avdtp_stream_endpoint_t * stream return stream_endpoint->acceptor_config_state == AVDTP_ACCEPTOR_STREAM_CONFIG_DONE; } -int avdtp_acceptor_stream_config_subsm(avdtp_device_t * device, avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size){ +int avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size){ avdtp_signaling_packet_header_t signaling_header; avdtp_read_signaling_header(&signaling_header, packet, size); @@ -238,7 +238,7 @@ int avdtp_acceptor_stream_config_subsm(avdtp_device_t * device, avdtp_stream_end int i = 2; avdtp_sep_t sep; - device->acceptor_transaction_label = signaling_header.transaction_label; + connection->acceptor_transaction_label = signaling_header.transaction_label; int request_to_send = 1; switch (stream_endpoint->acceptor_config_state){ @@ -254,12 +254,12 @@ int avdtp_acceptor_stream_config_subsm(avdtp_device_t * device, avdtp_stream_end break; case AVDTP_SI_GET_CAPABILITIES: printf(" ACP -> AVDTP_ACCEPTOR_W2_ANSWER_GET_CAPABILITIES\n"); - device->query_seid = packet[2] >> 2; + connection->query_seid = packet[2] >> 2; stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_W2_ANSWER_GET_CAPABILITIES; break; case AVDTP_SI_SET_CONFIGURATION: printf(" ACP -> AVDTP_ACCEPTOR_W2_ANSWER_SET_CONFIGURATION\n"); - device->query_seid = packet[2] >> 2; + connection->query_seid = packet[2] >> 2; sep.seid = packet[3] >> 2; // find or add sep for (i=0; i < stream_endpoint->remote_seps_num; i++){ @@ -278,7 +278,7 @@ int avdtp_acceptor_stream_config_subsm(avdtp_device_t * device, avdtp_stream_end stream_endpoint->unknown_signal_identifier = signaling_header.signal_identifier; break; } - l2cap_request_can_send_now_event(device->l2cap_signaling_cid); + l2cap_request_can_send_now_event(connection->l2cap_signaling_cid); break; case AVDTP_ACCEPTOR_STREAM_CONFIG_DONE: printf(" ACP: AVDTP_ACCEPTOR_W2_ANSWER_SET_CONFIGURATION\n"); @@ -298,35 +298,35 @@ static int avdtp_acceptor_send_response_reject(uint16_t cid, avdtp_signal_ident return l2cap_send(cid, command, sizeof(command)); } -int avdtp_acceptor_stream_config_subsm_run(avdtp_device_t * device, avdtp_stream_endpoint_t * stream_endpoint){ +int avdtp_acceptor_stream_config_subsm_run(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint){ int sent = 1; // printf("acceptor run: state %d\n", stream_endpoint->acceptor_config_state); switch (stream_endpoint->acceptor_config_state){ case AVDTP_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS: printf(" AVDTP_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS -> AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE\n"); stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE; - avdtp_acceptor_send_seps_response(device->l2cap_signaling_cid, device->acceptor_transaction_label, (avdtp_stream_endpoint_t *)&device->stream_endpoints); + avdtp_acceptor_send_seps_response(connection->l2cap_signaling_cid, connection->acceptor_transaction_label, (avdtp_stream_endpoint_t *)&connection->stream_endpoints); break; case AVDTP_ACCEPTOR_W2_ANSWER_GET_CAPABILITIES: - if (device->query_seid != stream_endpoint->sep.seid) return 0; + if (connection->query_seid != stream_endpoint->sep.seid) return 0; printf(" AVDTP_ACCEPTOR_W2_ANSWER_GET_CAPABILITIES -> AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE\n"); stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE; - avdtp_acceptor_send_capabilities_response(device->l2cap_signaling_cid, device->acceptor_transaction_label, stream_endpoint->sep); + avdtp_acceptor_send_capabilities_response(connection->l2cap_signaling_cid, connection->acceptor_transaction_label, stream_endpoint->sep); break; case AVDTP_ACCEPTOR_W2_ANSWER_GET_ALL_CAPABILITIES: - if (device->query_seid != stream_endpoint->sep.seid) return 0; + if (connection->query_seid != stream_endpoint->sep.seid) return 0; printf(" AVDTP_ACCEPTOR_W2_ANSWER_GET_ALL_CAPABILITIES -> AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE\n"); stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE; - avdtp_acceptor_send_all_capabilities_response(device->l2cap_signaling_cid, device->acceptor_transaction_label, stream_endpoint->sep); + avdtp_acceptor_send_all_capabilities_response(connection->l2cap_signaling_cid, connection->acceptor_transaction_label, stream_endpoint->sep); break; case AVDTP_ACCEPTOR_W2_REJECT_UNKNOWN_CMD: stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE; - avdtp_acceptor_send_response_reject(device->l2cap_signaling_cid, stream_endpoint->unknown_signal_identifier, device->acceptor_transaction_label); + avdtp_acceptor_send_response_reject(connection->l2cap_signaling_cid, stream_endpoint->unknown_signal_identifier, connection->acceptor_transaction_label); break; case AVDTP_ACCEPTOR_W2_ANSWER_SET_CONFIGURATION: printf(" AVDTP_ACCEPTOR_W2_ANSWER_SET_CONFIGURATION -> AVDTP_ACCEPTOR_STREAM_CONFIG_DONE\n"); stream_endpoint->acceptor_config_state = AVDTP_ACCEPTOR_STREAM_CONFIG_DONE; - avdtp_acceptor_send_accept_response(device->l2cap_signaling_cid, AVDTP_SI_SET_CONFIGURATION, device->acceptor_transaction_label); + avdtp_acceptor_send_accept_response(connection->l2cap_signaling_cid, AVDTP_SI_SET_CONFIGURATION, connection->acceptor_transaction_label); break; case AVDTP_ACCEPTOR_STREAM_CONFIG_IDLE: break; diff --git a/test/avdtp/avdtp_acceptor.h b/test/avdtp/avdtp_acceptor.h index 43040a5cc..88d78738f 100644 --- a/test/avdtp/avdtp_acceptor.h +++ b/test/avdtp/avdtp_acceptor.h @@ -53,8 +53,8 @@ extern "C" { void avdtp_acceptor_stream_config_subsm_init(avdtp_stream_endpoint_t * stream_endpoint); int avdtp_acceptor_stream_config_subsm_is_done(avdtp_stream_endpoint_t * stream_endpoint); -int avdtp_acceptor_stream_config_subsm(avdtp_device_t * device, avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size); -int avdtp_acceptor_stream_config_subsm_run(avdtp_device_t * device, avdtp_stream_endpoint_t * stream_endpoint); +int avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size); +int avdtp_acceptor_stream_config_subsm_run(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint); int avdtp_acceptor_send_accept_response(uint16_t cid, avdtp_signal_identifier_t identifier, uint8_t transaction_label); #if defined __cplusplus diff --git a/test/avdtp/avdtp_initiator.c b/test/avdtp/avdtp_initiator.c index 7964da257..cb228b2e7 100644 --- a/test/avdtp/avdtp_initiator.c +++ b/test/avdtp/avdtp_initiator.c @@ -78,9 +78,9 @@ int avdtp_initiator_stream_config_subsm_is_done(avdtp_stream_endpoint_t * stream return stream_endpoint->initiator_config_state == AVDTP_INITIATOR_STREAM_CONFIG_DONE; } -int avdtp_initiator_stream_config_subsm(avdtp_device_t * device, avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size){ +int avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size){ return 0; - if (avdtp_initiator_stream_config_subsm_run(device, stream_endpoint)) return 1; + if (avdtp_initiator_stream_config_subsm_run(connection, stream_endpoint)) return 1; int i; int responded = 1; avdtp_sep_t sep; @@ -92,8 +92,8 @@ int avdtp_initiator_stream_config_subsm(avdtp_device_t * device, avdtp_stream_en case AVDTP_INITIATOR_W4_SEPS_DISCOVERED: printf(" AVDTP_INITIATOR_W4_SEPS_DISCOVERED -> AVDTP_INITIATOR_W2_GET_CAPABILITIES\n"); - if (signaling_header.transaction_label != device->initiator_transaction_label){ - printf("unexpected transaction label, got %d, expected %d\n", signaling_header.transaction_label, device->initiator_transaction_label); + if (signaling_header.transaction_label != connection->initiator_transaction_label){ + printf("unexpected transaction label, got %d, expected %d\n", signaling_header.transaction_label, connection->initiator_transaction_label); return 0; } if (signaling_header.signal_identifier != AVDTP_SI_DISCOVER) { @@ -122,8 +122,8 @@ int avdtp_initiator_stream_config_subsm(avdtp_device_t * device, avdtp_stream_en // sep.seid, sep.in_use, sep.media_type, sep.type); } stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_GET_CAPABILITIES; - device->initiator_transaction_label++; - l2cap_request_can_send_now_event(device->l2cap_signaling_cid); + connection->initiator_transaction_label++; + l2cap_request_can_send_now_event(connection->l2cap_signaling_cid); responded = 1; break; case AVDTP_INITIATOR_W4_CAPABILITIES: @@ -143,7 +143,7 @@ int avdtp_initiator_stream_config_subsm(avdtp_device_t * device, avdtp_stream_en return responded; } -int avdtp_initiator_stream_config_subsm_run(avdtp_device_t * device, avdtp_stream_endpoint_t * stream_endpoint){ +int avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint){ return 0; int sent = 1; switch (stream_endpoint->initiator_config_state){ @@ -151,17 +151,17 @@ int avdtp_initiator_stream_config_subsm_run(avdtp_device_t * device, avdtp_strea case AVDTP_INITIATOR_W2_DISCOVER_SEPS: printf(" AVDTP_INITIATOR_STREAM_CONFIG_IDLE | AVDTP_INITIATOR_W2_DISCOVER_SEPS -> AVDTP_INITIATOR_W4_SEPS_DISCOVERED\n"); stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W4_SEPS_DISCOVERED; - avdtp_initiator_send_signaling_cmd(device->l2cap_signaling_cid, AVDTP_SI_DISCOVER, device->initiator_transaction_label); + avdtp_initiator_send_signaling_cmd(connection->l2cap_signaling_cid, AVDTP_SI_DISCOVER, connection->initiator_transaction_label); break; case AVDTP_INITIATOR_W2_GET_CAPABILITIES: printf(" AVDTP_INITIATOR_W2_GET_CAPABILITIES -> AVDTP_INITIATOR_W4_CAPABILITIES\n"); stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W4_CAPABILITIES; - avdtp_initiator_send_get_capabilities_cmd(device->l2cap_signaling_cid, device->initiator_transaction_label, device->query_seid); + avdtp_initiator_send_get_capabilities_cmd(connection->l2cap_signaling_cid, connection->initiator_transaction_label, connection->query_seid); break; case AVDTP_INITIATOR_W2_GET_ALL_CAPABILITIES: printf(" AVDTP_INITIATOR_W2_GET_ALL_CAPABILITIES -> AVDTP_INITIATOR_W4_ALL_CAPABILITIES\n"); stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W4_ALL_CAPABILITIES; - avdtp_initiator_send_get_all_capabilities_cmd(device->l2cap_signaling_cid, device->initiator_transaction_label, device->query_seid); + avdtp_initiator_send_get_all_capabilities_cmd(connection->l2cap_signaling_cid, connection->initiator_transaction_label, connection->query_seid); break; default: sent = 0; diff --git a/test/avdtp/avdtp_initiator.h b/test/avdtp/avdtp_initiator.h index 033646da3..e795f3cb6 100644 --- a/test/avdtp/avdtp_initiator.h +++ b/test/avdtp/avdtp_initiator.h @@ -53,8 +53,8 @@ extern "C" { void avdtp_initiator_stream_config_subsm_init(avdtp_stream_endpoint_t * stream_endpoint); int avdtp_initiator_stream_config_subsm_is_done(avdtp_stream_endpoint_t * stream_endpoint); -int avdtp_initiator_stream_config_subsm(avdtp_device_t * device, avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size); -int avdtp_initiator_stream_config_subsm_run(avdtp_device_t * device, avdtp_stream_endpoint_t * stream_endpoint); +int avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size); +int avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint); #if defined __cplusplus } diff --git a/test/avdtp/avdtp_sink.c b/test/avdtp/avdtp_sink.c index 4805d7f5f..65762248b 100644 --- a/test/avdtp/avdtp_sink.c +++ b/test/avdtp/avdtp_sink.c @@ -52,14 +52,66 @@ static const char * default_avdtp_sink_service_name = "BTstack AVDTP Sink Service"; static const char * default_avdtp_sink_service_provider_name = "BTstack AVDTP Sink Service Provider"; -static avdtp_device_t avdtp_sink; +// TODO list of devices +//static btstack_linked_list_t avdtp_connections; +static avdtp_connection_t avdtp_sink; -static void avdtp_state_init(avdtp_device_t * device){ - device->stream_endpoints = NULL; - device->service_mode = AVDTP_BASIC_SERVICE_MODE; - device->state = AVDTP_DEVICE_IDLE; - device->stream_endpoints_id_counter = 0; - device->disconnect = 0; +static void avdtp_sink_run_for_connection(void * context); + +/* START: tracking can send now requests pro l2cap cid */ + +// TODO: move tracking of can send now down to L2CAP + +static btstack_linked_list_t * avdtp_sink_get_clients_waiting_for_can_send(uint16_t l2cap_cid, avdtp_connection_t * connection){ + btstack_linked_list_t *clients = NULL; + if (l2cap_cid == connection->l2cap_signaling_cid) { + clients = &connection->can_send_now_signaling_channel_requests; + } + return clients; +} + +// TODO list of connections +static void avdtp_sink_handle_can_send_now(uint16_t l2cap_cid, avdtp_connection_t * connection){ + btstack_linked_list_t * clients = avdtp_sink_get_clients_waiting_for_can_send(l2cap_cid, connection); + if (!clients) return; + + while (!btstack_linked_list_empty(clients)){ + // handle first client + btstack_context_callback_registration_t * client = (btstack_context_callback_registration_t*) clients; + btstack_linked_list_remove(clients, (btstack_linked_item_t *) client); + client->callback(client->context); + + // request again if needed + if (!l2cap_can_send_packet_now(l2cap_cid)){ + if (!btstack_linked_list_empty(clients)){ + l2cap_request_can_send_now_event(l2cap_cid); + } + return; + } + } +} + +static void avdtp_sink_register_can_send_now_callback(uint16_t l2cap_cid, avdtp_connection_t * connection, btstack_context_callback_registration_t * callback_registration){ + btstack_linked_list_t * clients = avdtp_sink_get_clients_waiting_for_can_send(l2cap_cid, connection); + if (!clients) return; + + if (l2cap_can_send_packet_now(l2cap_cid)){ + callback_registration->callback(callback_registration->context); + return; + } + btstack_linked_list_add_tail(clients, (btstack_linked_item_t*) callback_registration); + l2cap_request_can_send_now_event(l2cap_cid); +} + +/* END: tracking can send now requests pro l2cap cid */ + + +static void avdtp_state_init(avdtp_connection_t * connection){ + connection->stream_endpoints = NULL; + connection->service_mode = AVDTP_BASIC_SERVICE_MODE; + connection->state = AVDTP_DEVICE_IDLE; + connection->stream_endpoints_id_counter = 0; + connection->disconnect = 0; } static btstack_packet_handler_t avdtp_sink_callback; @@ -333,6 +385,11 @@ static void handle_l2cap_signaling_data_packet(uint8_t *packet, uint16_t size){ stream_endpoint->state = AVDTP_W2_ANSWER_OPEN_STREAM; avdtp_sink.acceptor_transaction_label = signaling_header.transaction_label; l2cap_request_can_send_now_event(avdtp_sink.l2cap_signaling_cid); + + btstack_context_callback_registration_t callback_registration; + callback_registration.callback = &avdtp_sink_run_for_connection; + callback_registration.context = (void*)stream_endpoint; + avdtp_sink_register_can_send_now_callback(avdtp_sink.l2cap_signaling_cid, &avdtp_sink, &callback_registration); break; default: request_to_send = 0; @@ -477,7 +534,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe l2cap_event_channel_opened_get_address(packet, event_addr); if (l2cap_event_channel_opened_get_status(packet)){ - log_error("L2CAP connection to device %s failed. status code 0x%02x", + log_error("L2CAP connection to connection %s failed. status code 0x%02x", bd_addr_to_str(event_addr), l2cap_event_channel_opened_get_status(packet)); break; } @@ -581,6 +638,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe case HCI_EVENT_DISCONNECTION_COMPLETE: break; case L2CAP_EVENT_CAN_SEND_NOW: + avdtp_sink_handle_can_send_now(channel, &avdtp_sink); break; default: printf("unknown HCI event type %02x\n", hci_event_packet_get_type(packet)); @@ -618,47 +676,11 @@ void avdtp_sink_register_packet_handler(btstack_packet_handler_t callback){ avdtp_sink_callback = callback; } -static void avdtp_sink_run_for_stream_endpoint(avdtp_stream_endpoint_t * stream_endpoint){ - if (stream_endpoint->state < AVDTP_OPEN){ - if (stream_endpoint->state == AVDTP_CONFIGURATION_SUBSTATEMACHINE){ - if (avdtp_initiator_stream_config_subsm_is_done(stream_endpoint) || avdtp_acceptor_stream_config_subsm_is_done(stream_endpoint)){ - printf("AVDTP_CONFIGURATION_SUBSTATEMACHINE -> AVDTP_CONFIGURED\n"); - stream_endpoint->state = AVDTP_CONFIGURED; - } - } - - // signaling - if (!l2cap_can_send_packet_now(avdtp_sink.l2cap_signaling_cid)) { - //printf("avdtp_sink_run: request cannot send for 0x%02x\n", avdtp_sink.l2cap_signaling_cid); - return; - } - - switch (stream_endpoint->state){ - case AVDTP_CONFIGURATION_SUBSTATEMACHINE: - if (!avdtp_acceptor_stream_config_subsm_run(&avdtp_sink, stream_endpoint)) { - if (!avdtp_initiator_stream_config_subsm_run(&avdtp_sink, stream_endpoint)) break; - } - return; - case AVDTP_W2_ANSWER_OPEN_STREAM: - printf("AVDTP_W2_ANSWER_OPEN_STREAM -> AVDTP_OPEN\n"); - stream_endpoint->state = AVDTP_W4_L2CAP_FOR_MEDIA_CONNECTED; - avdtp_acceptor_send_accept_response(avdtp_sink.l2cap_signaling_cid, AVDTP_SI_OPEN, avdtp_sink.acceptor_transaction_label); - break; - case AVDTP_W2_ANSWER_START_SINGLE_STREAM: - printf("AVDTP_W2_ANSWER_START_SINGLE_STREAM -> AVDTP_W4_STREAMING_CONNECTION_OPEN\n"); - stream_endpoint->state = AVDTP_W4_STREAMING_CONNECTION_OPEN; - avdtp_acceptor_send_accept_response(avdtp_sink.l2cap_signaling_cid, AVDTP_SI_START, avdtp_sink.acceptor_transaction_label); - break; - default: - printf("avdtp_sink_run: state %d -> NOT IMPLEMENTED\n", stream_endpoint->state); - break; - } - } -} +static void avdtp_sink_run_for_connection(void * context){ + avdtp_connection_t * connection = (avdtp_connection_t *) context; -static void avdtp_sink_run(void){ btstack_linked_list_iterator_t it; - btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avdtp_sink.stream_endpoints); + btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) connection->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); @@ -685,21 +707,58 @@ static void avdtp_sink_run(void){ } } - if (avdtp_sink.disconnect == 1){ - avdtp_sink.disconnect = 0; - avdtp_sink.state = AVDTP_W4_L2CAP_FOR_SIGNALING_DISCONNECTED; + if (connection->disconnect == 1){ + connection->disconnect = 0; + connection->state = AVDTP_W4_L2CAP_FOR_SIGNALING_DISCONNECTED; l2cap_disconnect(avdtp_sink.l2cap_signaling_cid, 0); return; } - btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avdtp_sink.stream_endpoints); + btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) connection->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); - avdtp_sink_run_for_stream_endpoint(stream_endpoint); - // l2cap_request_can_send_now_event(avdtp_sink.l2cap_signaling_cid); + if (stream_endpoint->state < AVDTP_OPEN){ + if (stream_endpoint->state == AVDTP_CONFIGURATION_SUBSTATEMACHINE){ + if (avdtp_initiator_stream_config_subsm_is_done(stream_endpoint) || avdtp_acceptor_stream_config_subsm_is_done(stream_endpoint)){ + printf("AVDTP_CONFIGURATION_SUBSTATEMACHINE -> AVDTP_CONFIGURED\n"); + stream_endpoint->state = AVDTP_CONFIGURED; + } + } + + // signaling + if (!l2cap_can_send_packet_now(connection->l2cap_signaling_cid)) { + //printf("avdtp_sink_run: request cannot send for 0x%02x\n", avdtp_sink.l2cap_signaling_cid); + return; + } + + switch (stream_endpoint->state){ + case AVDTP_CONFIGURATION_SUBSTATEMACHINE: + if (!avdtp_acceptor_stream_config_subsm_run(connection, stream_endpoint)) { + if (!avdtp_initiator_stream_config_subsm_run(connection, stream_endpoint)) break; + } + return; + case AVDTP_W2_ANSWER_OPEN_STREAM: + printf("AVDTP_W2_ANSWER_OPEN_STREAM -> AVDTP_OPEN\n"); + stream_endpoint->state = AVDTP_W4_L2CAP_FOR_MEDIA_CONNECTED; + avdtp_acceptor_send_accept_response(connection->l2cap_signaling_cid, AVDTP_SI_OPEN, connection->acceptor_transaction_label); + break; + case AVDTP_W2_ANSWER_START_SINGLE_STREAM: + printf("AVDTP_W2_ANSWER_START_SINGLE_STREAM -> AVDTP_W4_STREAMING_CONNECTION_OPEN\n"); + stream_endpoint->state = AVDTP_W4_STREAMING_CONNECTION_OPEN; + avdtp_acceptor_send_accept_response(connection->l2cap_signaling_cid, AVDTP_SI_START, connection->acceptor_transaction_label); + break; + default: + printf("avdtp_sink_run: state %d -> NOT IMPLEMENTED\n", stream_endpoint->state); + break; + } + } } } +static void avdtp_sink_run(void){ + avdtp_sink_run_for_connection((void*)&avdtp_sink); +} + void avdtp_sink_connect(bd_addr_t bd_addr){ if (avdtp_sink.state != AVDTP_DEVICE_IDLE) return; memcpy(avdtp_sink.remote_addr, bd_addr, 6);