mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-09 12:39:56 +00:00
avrcp browsing: add draft connect/disconnect
This commit is contained in:
parent
f65a5459ae
commit
f12a3722fc
@ -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 $@
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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"]]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user