avrcp browsing: add draft connect/disconnect

This commit is contained in:
Milanka Ringwald 2017-11-03 16:57:10 +01:00
parent f65a5459ae
commit f12a3722fc
7 changed files with 87 additions and 15 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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