From f12a3722fc85b5ee7c999fffc84d872d20325944 Mon Sep 17 00:00:00 2001 From: Milanka Ringwald Date: Fri, 3 Nov 2017 16:57:10 +0100 Subject: [PATCH] avrcp browsing: add draft connect/disconnect --- example/Makefile.inc | 4 +++ port/libusb/btstack_config.h | 2 ++ src/btstack_memory.c | 44 ++++++++++++++++++++++++++++++-- src/btstack_memory.h | 4 +++ src/classic/avrcp.c | 22 ++++++++-------- src/classic/avrcp.h | 23 +++++++++++++++-- tool/btstack_memory_generator.py | 3 ++- 7 files changed, 87 insertions(+), 15 deletions(-) diff --git a/example/Makefile.inc b/example/Makefile.inc index fd8e78ec0..090520ce3 100644 --- a/example/Makefile.inc +++ b/example/Makefile.inc @@ -107,6 +107,7 @@ HXCMOD_PLAYER = \ ${BTSTACK_ROOT}/3rd-party/hxcmod-player/mods/nao-deceased_by_disease.c \ EXAMPLES = \ + avrcp_browsing_client \ a2dp_sink_demo \ a2dp_source_demo \ ancs_client_demo \ @@ -275,6 +276,9 @@ a2dp_source_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} ${SBC_E a2dp_sink_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} ${SBC_ENCODER_OBJ} ${SBC_DECODER_OBJ} ${AVDTP_OBJ} avrcp.o avrcp_controller.o a2dp_sink_demo.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ +avrcp_browsing_client: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} avrcp.o avrcp_controller.o avrcp_browsing_controller.o avrcp_browsing_client.c + ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ + dut_mode_classic: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} dut_mode_classic.c ${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@ diff --git a/port/libusb/btstack_config.h b/port/libusb/btstack_config.h index cfaec6053..d9732848f 100644 --- a/port/libusb/btstack_config.h +++ b/port/libusb/btstack_config.h @@ -25,6 +25,8 @@ #define ENABLE_SCO_OVER_HCI #define ENABLE_SDP_DES_DUMP +// #define ENABLE_L2CAP_ENHANCED_RETRANSMISSION_MODE + // BTstack configuration. buffers, sizes, ... #define HCI_ACL_PAYLOAD_SIZE (1691 + 4) #define HCI_INCOMING_PRE_BUFFER_SIZE 14 // sizeof BNEP header, avoid memcpy diff --git a/src/btstack_memory.c b/src/btstack_memory.c index 52ab0fd8e..6be1b8d3c 100644 --- a/src/btstack_memory.c +++ b/src/btstack_memory.c @@ -35,8 +35,6 @@ * */ -#define __BTSTACK_FILE__ "btstack_memory.c" - /* * btstack_memory.h @@ -595,6 +593,45 @@ void btstack_memory_avrcp_connection_free(avrcp_connection_t *avrcp_connection){ #endif + +// MARK: avrcp_browsing_connection_t +#if !defined(HAVE_MALLOC) && !defined(MAX_NR_AVRCP_BROWSING_CONNECTIONS) + #if defined(MAX_NO_AVRCP_BROWSING_CONNECTIONS) + #error "Deprecated MAX_NO_AVRCP_BROWSING_CONNECTIONS defined instead of MAX_NR_AVRCP_BROWSING_CONNECTIONS. Please update your btstack_config.h to use MAX_NR_AVRCP_BROWSING_CONNECTIONS." + #else + #define MAX_NR_AVRCP_BROWSING_CONNECTIONS 0 + #endif +#endif + +#ifdef MAX_NR_AVRCP_BROWSING_CONNECTIONS +#if MAX_NR_AVRCP_BROWSING_CONNECTIONS > 0 +static avrcp_browsing_connection_t avrcp_browsing_connection_storage[MAX_NR_AVRCP_BROWSING_CONNECTIONS]; +static btstack_memory_pool_t avrcp_browsing_connection_pool; +avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){ + return (avrcp_browsing_connection_t *) btstack_memory_pool_get(&avrcp_browsing_connection_pool); +} +void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){ + btstack_memory_pool_free(&avrcp_browsing_connection_pool, avrcp_browsing_connection); +} +#else +avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){ + return NULL; +} +void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){ + // silence compiler warning about unused parameter in a portable way + (void) avrcp_browsing_connection; +}; +#endif +#elif defined(HAVE_MALLOC) +avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void){ + return (avrcp_browsing_connection_t*) malloc(sizeof(avrcp_browsing_connection_t)); +} +void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection){ + free(avrcp_browsing_connection); +} +#endif + + #ifdef ENABLE_BLE // MARK: gatt_client_t @@ -756,6 +793,9 @@ void btstack_memory_init(void){ #if MAX_NR_AVRCP_CONNECTIONS > 0 btstack_memory_pool_create(&avrcp_connection_pool, avrcp_connection_storage, MAX_NR_AVRCP_CONNECTIONS, sizeof(avrcp_connection_t)); #endif +#if MAX_NR_AVRCP_BROWSING_CONNECTIONS > 0 + btstack_memory_pool_create(&avrcp_browsing_connection_pool, avrcp_browsing_connection_storage, MAX_NR_AVRCP_BROWSING_CONNECTIONS, sizeof(avrcp_browsing_connection_t)); +#endif #ifdef ENABLE_BLE #if MAX_NR_GATT_CLIENTS > 0 btstack_memory_pool_create(&gatt_client_pool, gatt_client_storage, MAX_NR_GATT_CLIENTS, sizeof(gatt_client_t)); diff --git a/src/btstack_memory.h b/src/btstack_memory.h index f0730a740..406763cba 100644 --- a/src/btstack_memory.h +++ b/src/btstack_memory.h @@ -131,6 +131,10 @@ void btstack_memory_avdtp_connection_free(avdtp_connection_t *avdtp_connection avrcp_connection_t * btstack_memory_avrcp_connection_get(void); void btstack_memory_avrcp_connection_free(avrcp_connection_t *avrcp_connection); +// avrcp_browsing_connection +avrcp_browsing_connection_t * btstack_memory_avrcp_browsing_connection_get(void); +void btstack_memory_avrcp_browsing_connection_free(avrcp_browsing_connection_t *avrcp_browsing_connection); + #ifdef ENABLE_BLE // gatt_client, whitelist_entry, sm_lookup_entry gatt_client_t * btstack_memory_gatt_client_get(void); diff --git a/src/classic/avrcp.c b/src/classic/avrcp.c index 7f78e90cd..caf25fa12 100644 --- a/src/classic/avrcp.c +++ b/src/classic/avrcp.c @@ -88,7 +88,6 @@ static const char * default_avrcp_target_service_provider_name = "BTstack AVRCP static uint16_t avrcp_cid_counter = 0; static avrcp_context_t * sdp_query_context; -static int record_id = -1; static uint8_t attribute_value[1000]; static const unsigned int attribute_value_buffer_size = sizeof(attribute_value); @@ -358,7 +357,7 @@ void avrcp_request_can_send_now(avrcp_connection_t * connection, uint16_t l2cap_ } -static uint16_t avdtp_get_next_avrcp_cid(void){ +static uint16_t avrcp_get_next_cid(void){ avrcp_cid_counter++; if (avrcp_cid_counter == 0){ avrcp_cid_counter = 1; @@ -375,7 +374,7 @@ static avrcp_connection_t * avrcp_create_connection(bd_addr_t remote_addr, avrcp memset(connection, 0, sizeof(avrcp_connection_t)); connection->state = AVCTP_CONNECTION_IDLE; connection->transaction_label = 0xFF; - connection->avrcp_cid = avdtp_get_next_avrcp_cid(); + connection->avrcp_cid = avrcp_get_next_cid(); memcpy(connection->remote_addr, remote_addr, 6); btstack_linked_list_add(&context->connections, (btstack_linked_item_t *) connection); return connection; @@ -412,7 +411,7 @@ void avrcp_emit_connection_closed(btstack_packet_handler_t callback, uint16_t av static void avrcp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ avrcp_connection_t * connection = get_avrcp_connection_for_avrcp_cid(sdp_query_context->avrcp_cid, sdp_query_context); if (!connection) return; - if (connection->state != AVCTP_SIGNALING_W4_SDP_QUERY_COMPLETE) return; + if (connection->state != AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE) return; UNUSED(packet_type); UNUSED(channel); UNUSED(size); @@ -424,8 +423,9 @@ static void avrcp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c switch (hci_event_packet_get_type(packet)){ case SDP_EVENT_QUERY_ATTRIBUTE_VALUE: // Handle new SDP record - if (sdp_event_query_attribute_byte_get_record_id(packet) != record_id) { - record_id = sdp_event_query_attribute_byte_get_record_id(packet); + if (sdp_event_query_attribute_byte_get_record_id(packet) != sdp_query_context->record_id) { + sdp_query_context->record_id = sdp_event_query_attribute_byte_get_record_id(packet); + sdp_query_context->parse_sdp_record = 0; // log_info("SDP Record: Nr: %d", record_id); } @@ -443,14 +443,14 @@ static void avrcp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c switch (uuid){ case BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL_TARGET: if (sdp_query_context->role == AVRCP_CONTROLLER) { - sdp_query_context->role_supported = 1; + sdp_query_context->parse_sdp_record = 1; break; } break; case BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL: case BLUETOOTH_SERVICE_CLASS_AV_REMOTE_CONTROL_CONTROLLER: if (sdp_query_context->role == AVRCP_TARGET) { - sdp_query_context->role_supported = 1; + sdp_query_context->parse_sdp_record = 1; break; } break; @@ -461,6 +461,7 @@ static void avrcp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c break; case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST: { + if (!sdp_query_context->parse_sdp_record) break; // log_info("SDP Attribute: 0x%04x", sdp_event_query_attribute_byte_get_attribute_id(packet)); for (des_iterator_init(&des_list_it, attribute_value); des_iterator_has_more(&des_list_it); des_iterator_next(&des_list_it)) { uint8_t *des_element; @@ -495,6 +496,7 @@ static void avrcp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c break; case BLUETOOTH_ATTRIBUTE_ADDITIONAL_PROTOCOL_DESCRIPTOR_LISTS: { // log_info("SDP Attribute: 0x%04x", sdp_event_query_attribute_byte_get_attribute_id(packet)); + if (!sdp_query_context->parse_sdp_record) break; if (de_get_element_type(attribute_value) != DE_DES) break; des_iterator_t des_list_0_it; @@ -553,7 +555,7 @@ static void avrcp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c break; } - if (!sdp_query_context->role_supported || !sdp_query_context->avrcp_l2cap_psm){ + if (!sdp_query_context->parse_sdp_record || !sdp_query_context->avrcp_l2cap_psm){ connection->state = AVCTP_CONNECTION_IDLE; avrcp_emit_connection_established(sdp_query_context->avrcp_callback, connection->avrcp_cid, connection->remote_addr, SDP_SERVICE_NOT_FOUND); btstack_linked_list_remove(&sdp_query_context->connections, (btstack_linked_item_t*) connection); @@ -656,7 +658,7 @@ uint8_t avrcp_connect(bd_addr_t bd_addr, avrcp_context_t * context, uint16_t * a if (!avrcp_cid) return L2CAP_LOCAL_CID_DOES_NOT_EXIST; *avrcp_cid = connection->avrcp_cid; - connection->state = AVCTP_SIGNALING_W4_SDP_QUERY_COMPLETE; + connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE; context->avrcp_l2cap_psm = 0; context->avrcp_version = 0; diff --git a/src/classic/avrcp.h b/src/classic/avrcp.h index 9549769be..d19b2cb4e 100644 --- a/src/classic/avrcp.h +++ b/src/classic/avrcp.h @@ -238,7 +238,7 @@ typedef enum{ typedef enum { AVCTP_CONNECTION_IDLE, - AVCTP_SIGNALING_W4_SDP_QUERY_COMPLETE, + AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE, AVCTP_CONNECTION_W4_L2CAP_CONNECTED, AVCTP_CONNECTION_OPENED, AVCTP_W2_SEND_PRESS_COMMAND, @@ -376,14 +376,33 @@ typedef struct { btstack_packet_handler_t packet_handler; // SDP query + uint8_t parse_sdp_record; + uint32_t record_id; uint16_t avrcp_cid; uint16_t avrcp_l2cap_psm; uint16_t avrcp_version; uint16_t avrcp_browsing_l2cap_psm; uint16_t avrcp_browsing_version; - uint8_t role_supported; } avrcp_context_t; +// BROWSING +typedef struct { + btstack_linked_item_t item; + bd_addr_t remote_addr; + uint16_t l2cap_browsing_cid; + uint16_t browsing_cid; + + avctp_connection_state_t state; + uint8_t wait_to_send; + uint8_t transaction_label; + + uint8_t * ertm_buffer; + uint32_t ertm_buffer_size; + l2cap_ertm_config_t ertm_config; +} avrcp_browsing_connection_t; + +// BROWSING END + const char * avrcp_subunit2str(uint16_t index); const char * avrcp_event2str(uint16_t index); const char * avrcp_operation2str(uint8_t index); diff --git a/tool/btstack_memory_generator.py b/tool/btstack_memory_generator.py index e480141c0..97336847b 100755 --- a/tool/btstack_memory_generator.py +++ b/tool/btstack_memory_generator.py @@ -181,7 +181,8 @@ list_of_structs = [ ["service_record_item"], ["avdtp_stream_endpoint"], ["avdtp_connection"], - ["avrcp_connection"] + ["avrcp_connection"], + ["avrcp_browsing_connection"] ] list_of_le_structs = [["gatt_client", "whitelist_entry", "sm_lookup_entry"]]