From 59b604775574cd7dd60af3a60e6ad9ecdee67a66 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Mon, 21 Nov 2016 14:17:13 +0100 Subject: [PATCH] avdtp: removed globa avdtp_sink --- test/avdtp/avdtp.h | 13 ++--- test/avdtp/avdtp_sink.c | 103 +++++++++++++++++++++++++--------------- test/avdtp/avdtp_sink.h | 2 +- test/avdtp/avdtp_test.c | 2 +- 4 files changed, 75 insertions(+), 45 deletions(-) diff --git a/test/avdtp/avdtp.h b/test/avdtp/avdtp.h index 0d0fece47..81438a8cf 100644 --- a/test/avdtp/avdtp.h +++ b/test/avdtp/avdtp.h @@ -330,19 +330,20 @@ typedef struct { typedef enum { - AVDTP_DEVICE_IDLE, - AVDTP_W4_L2CAP_FOR_SIGNALING_CONNECTED, - AVDTP_DEVICE_CONNECTED, - AVDTP_W4_L2CAP_FOR_SIGNALING_DISCONNECTED -} avdtp_device_state_t; + AVDTP_SIGNALING_CONNECTION_IDLE, + AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED, + AVDTP_SIGNALING_CONNECTION_OPENED, + AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED +} avdtp_connection_state_t; typedef struct { btstack_linked_item_t item; bd_addr_t remote_addr; + hci_con_handle_t con_handle; uint16_t l2cap_signaling_cid; - avdtp_device_state_t state; + avdtp_connection_state_t state; avdtp_service_mode_t service_mode; uint8_t disconnect; diff --git a/test/avdtp/avdtp_sink.c b/test/avdtp/avdtp_sink.c index 39f9fac10..afa9ed022 100644 --- a/test/avdtp/avdtp_sink.c +++ b/test/avdtp/avdtp_sink.c @@ -54,7 +54,6 @@ static const char * default_avdtp_sink_service_provider_name = "BTstack AVDTP Si // TODO list of devices static btstack_linked_list_t avdtp_connections; -static avdtp_connection_t avdtp_sink; static uint16_t stream_endpoints_id_counter; static void avdtp_sink_run_for_connection(void * context); @@ -106,13 +105,6 @@ static void avdtp_sink_register_can_send_now_callback(uint16_t l2cap_cid, avdtp_ /* END: tracking can send now requests pro l2cap cid */ - -static void avdtp_state_init(avdtp_connection_t * connection){ - connection->service_mode = AVDTP_BASIC_SERVICE_MODE; - connection->state = AVDTP_DEVICE_IDLE; - connection->disconnect = 0; -} - static btstack_packet_handler_t avdtp_sink_callback; static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size); static void avdtp_sink_run(void); @@ -222,7 +214,18 @@ static avdtp_stream_endpoint_t * get_avdtp_stream_endpoint_for_connection(avdtp_ return NULL; } -uint8_t avdtp_sink_register_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type){ +static avdtp_connection_t * avdtp_sink_create_connection(bd_addr_t remote_addr, hci_con_handle_t con_handle, uint16_t local_cid){ + avdtp_connection_t * connection = btstack_memory_avdtp_connection_get(); + connection->l2cap_signaling_cid = local_cid; + connection->con_handle = con_handle; + connection->state = AVDTP_SIGNALING_CONNECTION_IDLE; + connection->initiator_transaction_label++; + memcpy(connection->remote_addr, remote_addr, 6); + btstack_linked_list_add(&avdtp_connections, (btstack_linked_item_t *) connection); + return connection; +} + +uint8_t avdtp_sink_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type){ avdtp_stream_endpoint_t * stream_endpoint = btstack_memory_avdtp_stream_endpoint_get(); stream_endpoints_id_counter++; stream_endpoint->sep.seid = stream_endpoints_id_counter; @@ -233,7 +236,6 @@ uint8_t avdtp_sink_register_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_med return stream_endpoint->sep.seid; } - void avdtp_sink_register_media_transport_category(uint8_t seid){ avdtp_stream_endpoint_t * stream_endpoint = get_avdtp_stream_endpoint_for_seid(seid); if (!stream_endpoint){ @@ -336,14 +338,36 @@ void avdtp_sink_register_multiplexing_category(uint8_t seid, uint8_t fragmentati // } + +static avdtp_connection_t * get_avdtp_connection_for_bd_addr(bd_addr_t addr){ + btstack_linked_list_iterator_t it; + btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avdtp_connections); + while (btstack_linked_list_iterator_has_next(&it)){ + avdtp_connection_t * connection = (avdtp_connection_t *)btstack_linked_list_iterator_next(&it); + if (memcmp(addr, connection->remote_addr, 6) != 0) continue; + return connection; + } + return NULL; +} + +static avdtp_connection_t * get_avdtp_connection_for_con_handle(hci_con_handle_t con_handle){ + btstack_linked_list_iterator_t it; + btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avdtp_connections); + while (btstack_linked_list_iterator_has_next(&it)){ + avdtp_connection_t * connection = (avdtp_connection_t *)btstack_linked_list_iterator_next(&it); + if (connection->con_handle != con_handle) continue; + return connection; + } + return NULL; +} + static avdtp_connection_t * get_avdtp_connection_for_l2cap_cid(uint16_t l2cap_cid){ btstack_linked_list_iterator_t it; btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avdtp_connections); while (btstack_linked_list_iterator_has_next(&it)){ avdtp_connection_t * connection = (avdtp_connection_t *)btstack_linked_list_iterator_next(&it); - if (connection->l2cap_signaling_cid == l2cap_cid){ - return connection; - } + if (connection->l2cap_signaling_cid != l2cap_cid) continue; + return connection; } return NULL; } @@ -409,7 +433,7 @@ static void handle_l2cap_signaling_data_packet(avdtp_connection_t * connection, printf("AVDTP_CONFIGURED -> AVDTP_W2_ANSWER_OPEN_STREAM %d\n", signaling_header.transaction_label); if (stream_endpoint->sep.seid != packet[2] >> 2) return; stream_endpoint->state = AVDTP_W2_ANSWER_OPEN_STREAM; - avdtp_sink.acceptor_transaction_label = signaling_header.transaction_label; + connection->acceptor_transaction_label = signaling_header.transaction_label; l2cap_request_can_send_now_event(connection->l2cap_signaling_cid); btstack_context_callback_registration_t callback_registration; @@ -430,7 +454,7 @@ static void handle_l2cap_signaling_data_packet(avdtp_connection_t * connection, if (stream_endpoint->sep.seid != packet[2] >> 2) return; stream_endpoint->sep.in_use = 1; stream_endpoint->state = AVDTP_W2_ANSWER_START_SINGLE_STREAM; - avdtp_sink.acceptor_transaction_label = signaling_header.transaction_label; + connection->acceptor_transaction_label = signaling_header.transaction_label; l2cap_request_can_send_now_event(connection->l2cap_signaling_cid); break; default: @@ -453,15 +477,10 @@ static void handle_l2cap_signaling_data_packet(avdtp_connection_t * connection, } } -static void avdtp_sink_handle_open_connection(uint16_t local_cid, hci_con_handle_t con_handle, bd_addr_t event_addr){ +static void avdtp_sink_handle_open_connection(bd_addr_t remote_addr, hci_con_handle_t con_handle, uint16_t local_cid){ avdtp_connection_t * connection = get_avdtp_connection_for_l2cap_cid(local_cid); if (!connection){ - connection = btstack_memory_avdtp_connection_get(); - connection->l2cap_signaling_cid = local_cid; - connection->state = AVDTP_DEVICE_CONNECTED; - connection->initiator_transaction_label++; - memcpy(connection->remote_addr, event_addr, 6); - btstack_linked_list_add(&avdtp_connections, (btstack_linked_item_t *) connection); + avdtp_sink_create_connection(remote_addr, con_handle, local_cid); l2cap_request_can_send_now_event(local_cid); // TODO register can send now } @@ -559,7 +578,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe if (psm != PSM_AVDTP) break; - avdtp_sink_handle_open_connection(local_cid, con_handle, event_addr); + avdtp_sink_handle_open_connection(event_addr, con_handle, local_cid); break; case L2CAP_EVENT_CHANNEL_CLOSED: @@ -598,7 +617,14 @@ 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); + connection = get_avdtp_connection_for_l2cap_cid(channel); + if (!connection) { + stream_endpoint = get_avdtp_stream_endpoint_for_l2cap_cid(channel); + if (!stream_endpoint->connection) break; + connection = stream_endpoint->connection; + break; + } + avdtp_sink_handle_can_send_now(channel, connection); break; default: printf("unknown HCI event type %02x\n", hci_event_packet_get_type(packet)); @@ -616,10 +642,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe // TODO: find out which security level is needed, and replace LEVEL_0 in avdtp_sink_init void avdtp_sink_init(void){ - avdtp_state_init(&avdtp_sink); stream_endpoints = NULL; - stream_endpoints_id_counter = 0; avdtp_connections = NULL; + stream_endpoints_id_counter = 0; l2cap_register_service(&packet_handler, PSM_AVDTP, 0xffff, LEVEL_0); } @@ -641,11 +666,9 @@ void avdtp_sink_register_packet_handler(btstack_packet_handler_t callback){ static void avdtp_sink_run_for_connection(void * context){ avdtp_connection_t * connection = (avdtp_connection_t *) context; - - if (connection->disconnect == 1){ connection->disconnect = 0; - connection->state = AVDTP_W4_L2CAP_FOR_SIGNALING_DISCONNECTED; + connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED; l2cap_disconnect(connection->l2cap_signaling_cid, 0); return; } @@ -680,7 +703,7 @@ static void avdtp_sink_run(void){ } } - avdtp_sink_run_for_connection((void*)&avdtp_sink); + // avdtp_sink_run_for_connection((void*)&avdtp_sink); btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) 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); @@ -722,18 +745,24 @@ static void avdtp_sink_run(void){ } } + + 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); - avdtp_sink.state = AVDTP_W4_L2CAP_FOR_SIGNALING_CONNECTED; - l2cap_create_channel(packet_handler, avdtp_sink.remote_addr, PSM_AVDTP, 0xffff, NULL); + avdtp_connection_t * connection = get_avdtp_connection_for_bd_addr(bd_addr); + if (!connection){ + connection = avdtp_sink_create_connection(bd_addr,0,0); + } + if (connection->state != AVDTP_SIGNALING_CONNECTION_IDLE) return; + connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED; + l2cap_create_channel(packet_handler, connection->remote_addr, PSM_AVDTP, 0xffff, NULL); } void avdtp_sink_disconnect(uint16_t con_handle){ - if (avdtp_sink.state == AVDTP_DEVICE_IDLE) return; - if (avdtp_sink.state == AVDTP_W4_L2CAP_FOR_SIGNALING_DISCONNECTED) return; + avdtp_connection_t * connection = get_avdtp_connection_for_con_handle(con_handle); + if (connection->state == AVDTP_SIGNALING_CONNECTION_IDLE) return; + if (connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED) return; - avdtp_sink.disconnect = 1; + connection->disconnect = 1; btstack_linked_list_iterator_t it; btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &stream_endpoints); diff --git a/test/avdtp/avdtp_sink.h b/test/avdtp/avdtp_sink.h index 21bf55328..5506401c9 100644 --- a/test/avdtp/avdtp_sink.h +++ b/test/avdtp/avdtp_sink.h @@ -73,7 +73,7 @@ void a2dp_sink_create_sdp_record(uint8_t * service, uint32_t service_record_han void avdtp_sink_init(void); // returns sep_id -uint8_t avdtp_sink_register_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type); +uint8_t avdtp_sink_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type); void avdtp_sink_register_media_transport_category(uint8_t seid); void avdtp_sink_register_reporting_category(uint8_t seid); diff --git a/test/avdtp/avdtp_test.c b/test/avdtp/avdtp_test.c index e754a09e2..b059e0168 100644 --- a/test/avdtp/avdtp_test.c +++ b/test/avdtp/avdtp_test.c @@ -376,7 +376,7 @@ int btstack_main(int argc, const char * argv[]){ avdtp_sink_init(); avdtp_sink_register_packet_handler(&packet_handler); - uint8_t seid = avdtp_sink_register_stream_endpoint(AVDTP_SINK, AVDTP_AUDIO); + uint8_t seid = avdtp_sink_create_stream_endpoint(AVDTP_SINK, AVDTP_AUDIO); avdtp_sink_register_media_transport_category(seid); avdtp_sink_register_media_codec_category(seid, AVDTP_AUDIO, AVDTP_CODEC_SBC, media_sbc_codec_info, sizeof(media_sbc_codec_info));