avdtp: handle multiple can send now

This commit is contained in:
Milanka Ringwald 2016-11-16 16:19:03 +01:00
parent 13bf22c958
commit 598f5579d7
6 changed files with 143 additions and 81 deletions

View File

@ -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
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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
}

View File

@ -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);