mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-31 00:32:52 +00:00
avrcp_browsing: reuse avrcp sdp query
This commit is contained in:
parent
ef9778eeed
commit
2f0acaf70c
@ -384,12 +384,65 @@ static void avrcp_browsing_packet_handler(uint8_t packet_type, uint16_t channel,
|
||||
|
||||
}
|
||||
|
||||
void avrcp_browsing_init(void){
|
||||
if (avrcp_browsing_l2cap_service_registered) return;
|
||||
int status = l2cap_register_service(&avrcp_browsing_packet_handler, PSM_AVCTP_BROWSING, 0xffff, LEVEL_2);
|
||||
static void avrcp_browsing_handle_sdp_query_complete(avrcp_connection_t * connection, uint8_t status){
|
||||
|
||||
if (status != ERROR_CODE_SUCCESS) return;
|
||||
avrcp_browsing_l2cap_service_registered = true;
|
||||
if (connection->browsing_connection == NULL) {
|
||||
return;
|
||||
}
|
||||
if (connection->browsing_connection->state != AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE){
|
||||
return;
|
||||
}
|
||||
|
||||
// l2cap available?
|
||||
if (status == ERROR_CODE_SUCCESS){
|
||||
if (connection->browsing_l2cap_psm == 0){
|
||||
status = SDP_SERVICE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == ERROR_CODE_SUCCESS) {
|
||||
// ready to connect
|
||||
connection->browsing_connection->state = AVCTP_CONNECTION_W2_L2CAP_CONNECT;
|
||||
|
||||
// check if both events have been handled
|
||||
avrcp_connection_t *connection_with_opposite_role;
|
||||
switch (connection->role) {
|
||||
case AVRCP_CONTROLLER:
|
||||
connection_with_opposite_role = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET,
|
||||
connection->avrcp_cid);
|
||||
break;
|
||||
case AVRCP_TARGET:
|
||||
connection_with_opposite_role = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER,
|
||||
connection->avrcp_cid);
|
||||
break;
|
||||
default:
|
||||
btstack_assert(false);
|
||||
return;
|
||||
}
|
||||
if (connection_with_opposite_role->browsing_connection->state == AVCTP_CONNECTION_W4_L2CAP_CONNECTED) {
|
||||
|
||||
connection->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
|
||||
connection_with_opposite_role->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
|
||||
|
||||
l2cap_ertm_create_channel(avrcp_browsing_packet_handler,
|
||||
connection->remote_addr,
|
||||
connection->browsing_l2cap_psm,
|
||||
&connection->browsing_connection->ertm_config,
|
||||
connection->browsing_connection->ertm_buffer,
|
||||
connection->browsing_connection->ertm_buffer_size,
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
avrcp_browsing_finalize_connection(connection);
|
||||
avrcp_browsing_emit_connection_established(connection->avrcp_browsing_cid, connection->remote_addr, status);
|
||||
}
|
||||
}
|
||||
|
||||
void avrcp_browsing_init(void){
|
||||
avrcp_register_browsing_sdp_query_complete_handler(&avrcp_browsing_handle_sdp_query_complete);
|
||||
if (avrcp_browsing_l2cap_service_registered) return;
|
||||
uint8_t status = l2cap_register_service(&avrcp_browsing_packet_handler, PSM_AVCTP_BROWSING, 0xffff, LEVEL_2);
|
||||
avrcp_browsing_l2cap_service_registered = status == ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avrcp_browsing_deinit(void){
|
||||
@ -404,101 +457,6 @@ void avrcp_browsing_deinit(void){
|
||||
avrcp_browsing_l2cap_service_registered = false;
|
||||
}
|
||||
|
||||
static void avrcp_browsing_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
UNUSED(packet_type);
|
||||
UNUSED(channel);
|
||||
UNUSED(size);
|
||||
|
||||
avrcp_connection_t * avrcp_target_connection = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_TARGET, avrcp_browsing_sdp_query_context.browsing_cid);
|
||||
avrcp_connection_t * avrcp_controller_connection = avrcp_get_connection_for_browsing_cid_for_role(AVRCP_CONTROLLER, avrcp_browsing_sdp_query_context.browsing_cid);
|
||||
|
||||
if ((avrcp_target_connection == NULL) || (avrcp_target_connection->browsing_connection == NULL)) return;
|
||||
if (avrcp_target_connection->browsing_connection->state != AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE) return;
|
||||
|
||||
if ((avrcp_controller_connection == NULL) || (avrcp_controller_connection->browsing_connection == NULL)) return;
|
||||
if (avrcp_controller_connection->browsing_connection->state != AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE) return;
|
||||
|
||||
|
||||
uint8_t status;
|
||||
uint16_t browsing_l2cap_psm;
|
||||
|
||||
switch (hci_event_packet_get_type(packet)){
|
||||
case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
|
||||
avrcp_handle_sdp_client_query_attribute_value(packet);
|
||||
break;
|
||||
|
||||
case SDP_EVENT_QUERY_COMPLETE:
|
||||
status = sdp_event_query_complete_get_status(packet);
|
||||
|
||||
if (status != ERROR_CODE_SUCCESS){
|
||||
avrcp_browsing_emit_connection_established(avrcp_target_connection->avrcp_browsing_cid, avrcp_browsing_sdp_addr, status);
|
||||
avrcp_browsing_finalize_connection(avrcp_target_connection);
|
||||
avrcp_browsing_finalize_connection(avrcp_controller_connection);
|
||||
break;
|
||||
}
|
||||
|
||||
browsing_l2cap_psm = avrcp_sdp_query_browsing_l2cap_psm();
|
||||
if (!browsing_l2cap_psm){
|
||||
avrcp_browsing_emit_connection_established(avrcp_target_connection->avrcp_browsing_cid, avrcp_browsing_sdp_addr, SDP_SERVICE_NOT_FOUND);
|
||||
avrcp_browsing_finalize_connection(avrcp_target_connection);
|
||||
avrcp_browsing_finalize_connection(avrcp_controller_connection);
|
||||
break;
|
||||
}
|
||||
|
||||
l2cap_ertm_create_channel(avrcp_browsing_packet_handler, avrcp_browsing_sdp_addr, browsing_l2cap_psm,
|
||||
&avrcp_controller_connection->browsing_connection->ertm_config,
|
||||
avrcp_controller_connection->browsing_connection->ertm_buffer,
|
||||
avrcp_controller_connection->browsing_connection->ertm_buffer_size, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// register the SDP Query request to check if there is another connection waiting for the query
|
||||
// ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
|
||||
(void) sdp_client_register_query_callback(&avrcp_browsing_handle_sdp_client_query_request);
|
||||
}
|
||||
|
||||
static void avrcp_browsing_handle_start_sdp_client_query(void * context){
|
||||
UNUSED(context);
|
||||
// TODO
|
||||
|
||||
btstack_linked_list_t connections = avrcp_get_connections();
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &connections);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it);
|
||||
if (connection->browsing_connection == NULL) continue;
|
||||
if (connection->browsing_connection->state != AVCTP_CONNECTION_W2_SEND_SDP_QUERY) continue;
|
||||
connection->browsing_connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
|
||||
|
||||
// prevent triggering SDP query twice (for each role once)
|
||||
avrcp_connection_t * connection_with_opposite_role;
|
||||
switch (connection->role){
|
||||
case AVRCP_CONTROLLER:
|
||||
connection_with_opposite_role = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_TARGET, connection->avrcp_cid);
|
||||
break;
|
||||
case AVRCP_TARGET:
|
||||
connection_with_opposite_role = avrcp_get_connection_for_avrcp_cid_for_role(AVRCP_CONTROLLER, connection->avrcp_cid);
|
||||
break;
|
||||
default:
|
||||
btstack_assert(false);
|
||||
return;
|
||||
}
|
||||
if (connection->browsing_connection != NULL){
|
||||
connection_with_opposite_role->browsing_connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
|
||||
}
|
||||
|
||||
avrcp_browsing_sdp_query_context.browsing_l2cap_psm = 0;
|
||||
avrcp_browsing_sdp_query_context.browsing_version = 0;
|
||||
avrcp_browsing_sdp_query_context.browsing_cid = connection->avrcp_browsing_cid;
|
||||
|
||||
sdp_client_query_uuid16(&avrcp_browsing_handle_sdp_client_query_result, (uint8_t *) connection->remote_addr, BLUETOOTH_PROTOCOL_AVCTP);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t avrcp_browsing_connect(bd_addr_t remote_addr, uint8_t * ertm_buffer, uint32_t ertm_buffer_size, l2cap_ertm_config_t * ertm_config, uint16_t * avrcp_browsing_cid){
|
||||
btstack_assert(avrcp_browsing_controller_packet_handler != NULL);
|
||||
btstack_assert(avrcp_browsing_target_packet_handler != NULL);
|
||||
@ -538,12 +496,10 @@ uint8_t avrcp_browsing_connect(bd_addr_t remote_addr, uint8_t * ertm_buffer, uin
|
||||
|
||||
if (connection_controller->browsing_l2cap_psm == 0){
|
||||
memcpy(avrcp_browsing_sdp_addr, remote_addr, 6);
|
||||
connection_controller->browsing_connection->state = AVCTP_CONNECTION_W2_SEND_SDP_QUERY;
|
||||
connection_target->browsing_connection->state = AVCTP_CONNECTION_W2_SEND_SDP_QUERY;
|
||||
avrcp_browsing_handle_sdp_client_query_request.callback = &avrcp_browsing_handle_start_sdp_client_query;
|
||||
connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
|
||||
connection_target->browsing_connection->state = AVCTP_CONNECTION_W4_SDP_QUERY_COMPLETE;
|
||||
|
||||
// ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
|
||||
(void) sdp_client_register_query_callback(&avrcp_browsing_handle_sdp_client_query_request);
|
||||
avrcp_trigger_sdp_query(connection_controller, connection_target);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
} else {
|
||||
connection_controller->browsing_connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
|
||||
|
Loading…
x
Reference in New Issue
Block a user