avdtp: forward A2DP_SUBEVENT_SIGNALING_DELAY_REPORT as event to client app; change a2dp sink return value of a2dp_sink_create_stream_endpoint from status to stream endpoint

This commit is contained in:
Milanka Ringwald 2019-09-20 14:19:40 +02:00
parent 32c78405d2
commit 8b94010e12
7 changed files with 57 additions and 22 deletions

View File

@ -161,10 +161,11 @@ static uint8_t companies[] = {
0x00, 0x19, 0x58 //BT SIG registered CompanyID
};
#ifdef HAVE_BTSTACK_STDIN
// pts: static bd_addr_t remote = {0x00, 0x1B, 0xDC, 0x08, 0x0A, 0xA5};
// pts:
static const char * device_addr_string = "00:1B:DC:08:E2:72";
// mac 2013: static const char * device_addr_string = "84:38:35:65:d1:15";
// iPhone 5S:
static const char * device_addr_string = "54:E4:3A:26:A2:39";
// static const char * device_addr_string = "54:E4:3A:26:A2:39";
#endif
static uint8_t sdp_avdtp_sink_service_buffer[150];
@ -234,13 +235,14 @@ static int a2dp_and_avrcp_setup(void){
a2dp_sink_register_packet_handler(&a2dp_sink_packet_handler);
a2dp_sink_register_media_handler(&handle_l2cap_media_data_packet);
uint8_t status = a2dp_sink_create_stream_endpoint(AVDTP_AUDIO,
AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities),
media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration), &a2dp_local_seid);
if (status != ERROR_CODE_SUCCESS){
printf("A2DP Sink : not enough memory to create local stream endpoint\n");
avdtp_stream_endpoint_t * local_stream_endpoint = a2dp_sink_create_stream_endpoint(AVDTP_AUDIO,
AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities),
media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));
if (!local_stream_endpoint){
printf("A2DP Sink: not enough memory to create local stream endpoint\n");
return 1;
}
a2dp_local_seid = avdtp_local_seid(local_stream_endpoint);
// Initialize AVRCP Controller
avrcp_controller_init();
avrcp_controller_register_packet_handler(&avrcp_controller_packet_handler);
@ -934,6 +936,8 @@ static void show_usage(void){
printf("d - AVRCP Target create connection to addr %s\n", bd_addr_to_str(device_addr));
printf("D - AVRCP Target disconnect\n");
printf("w - delay report\n");
printf("\n--- Bluetooth AVRCP Commands %s ---\n", bd_addr_to_str(iut_address));
printf("O - get play status\n");
printf("j - get now playing info\n");
@ -999,6 +1003,10 @@ static void stdin_process(char cmd){
case '\n':
case '\r':
break;
case 'w':
printf("Send delay report\n");
avdtp_sink_delay_report(a2dp_cid, a2dp_local_seid, 100);
break;
// Volume Control
case 't':
volume_percentage = volume_percentage <= 90 ? volume_percentage + 10 : 100;

View File

@ -139,10 +139,11 @@ typedef struct {
static btstack_packet_callback_registration_t hci_event_callback_registration;
// pts: static const char * device_addr_string = "00:1B:DC:08:0A:A5";
// pts:
static const char * device_addr_string = "00:1B:DC:08:E2:72";
// mac 2013: static const char * device_addr_string = "84:38:35:65:d1:15";
// phone 2013: static const char * device_addr_string = "D8:BB:2C:DF:F0:F2";
// Minijambox:
static const char * device_addr_string = "00:21:3C:AC:F7:38";
// Minijambox: static const char * device_addr_string = "00:21:3C:AC:F7:38";
// Philips SHB9100: static const char * device_addr_string = "00:22:37:05:FD:E8";
// RT-B6: static const char * device_addr_string = "00:75:58:FF:C9:7D";
// BT dongle: static const char * device_addr_string = "00:1A:7D:DA:71:0A";
@ -252,7 +253,6 @@ static int a2dp_source_and_avrcp_services_init(void){
return 1;
}
media_tracker.local_seid = avdtp_local_seid(local_stream_endpoint);
// Initialize AVRCP Target.
avrcp_target_init();
avrcp_target_register_packet_handler(&avrcp_target_packet_handler);
@ -502,6 +502,12 @@ static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, ui
break;
}
case A2DP_SUBEVENT_SIGNALING_DELAY_REPORT:
printf("A2DP Source: received delay report of %d.%0d ms, local seid %d\n",
avdtp_subevent_signaling_delay_report_get_delay_100us(packet)/10, avdtp_subevent_signaling_delay_report_get_delay_100us(packet)%10,
avdtp_subevent_signaling_delay_report_get_local_seid(packet));
break;
case A2DP_SUBEVENT_STREAM_ESTABLISHED:
a2dp_subevent_stream_established_get_bd_addr(packet, address);
status = a2dp_subevent_stream_established_get_status(packet);

View File

@ -161,21 +161,20 @@ void a2dp_sink_init(void){
avdtp_sink_init(&a2dp_sink_context);
}
uint8_t a2dp_sink_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type,
avdtp_stream_endpoint_t * a2dp_sink_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type,
uint8_t * codec_capabilities, uint16_t codec_capabilities_len,
uint8_t * media_codec_info, uint16_t media_codec_info_len, uint8_t * local_seid){
*local_seid = 0;
uint8_t * media_codec_info, uint16_t media_codec_info_len){
avdtp_stream_endpoint_t * local_stream_endpoint = avdtp_sink_create_stream_endpoint(AVDTP_SINK, media_type);
if (!local_stream_endpoint){
return BTSTACK_MEMORY_ALLOC_FAILED;
return NULL;
}
*local_seid = avdtp_local_seid(local_stream_endpoint);
avdtp_sink_register_media_transport_category(avdtp_stream_endpoint_seid(local_stream_endpoint));
avdtp_sink_register_media_codec_category(avdtp_stream_endpoint_seid(local_stream_endpoint), media_type, media_codec_type,
codec_capabilities, codec_capabilities_len);
local_stream_endpoint->remote_configuration.media_codec.media_codec_information = media_codec_info;
local_stream_endpoint->remote_configuration.media_codec.media_codec_information_len = media_codec_info_len;
return ERROR_CODE_SUCCESS;
avdtp_sink_register_delay_reporting_category(avdtp_stream_endpoint_seid(local_stream_endpoint));
return local_stream_endpoint;
}
uint8_t a2dp_sink_establish_stream(bd_addr_t bd_addr, uint8_t local_seid, uint16_t * avdtp_cid){

View File

@ -78,13 +78,12 @@ void a2dp_sink_init(void);
* @param codec_capabilities_len media codec capabilities length
* @param codec_configuration default media codec configuration
* @param codec_configuration_len media codec configuration length
* @param out_local_seid Assigned stream endpoint ID used in further A2DP commands.
*
* @return status ERROR_CODE_SUCCESS if sucessful
* @return local_stream_endpoint
*/
uint8_t a2dp_sink_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type,
avdtp_stream_endpoint_t * a2dp_sink_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type,
uint8_t * codec_capabilities, uint16_t codec_capabilities_len,
uint8_t * codec_configuration, uint16_t codec_configuration_len, uint8_t * out_local_seid);
uint8_t * codec_configuration, uint16_t codec_configuration_len);
/**
* @brief Register callback for the A2DP Sink client. It will receive following subevents of HCI_EVENT_A2DP_META HCI event type:

View File

@ -213,6 +213,7 @@ static void a2dp_signaling_emit_reconfigured(btstack_packet_handler_t callback,
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
UNUSED(channel);
UNUSED(size);
@ -267,6 +268,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
uint8_t max_bitpool_value = avdtp_choose_sbc_max_bitpool_value(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_max_bitpool_value(packet));
uint8_t min_bitpool_value = avdtp_choose_sbc_min_bitpool_value(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_min_bitpool_value(packet));
sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_information[0] = (sampling_frequency << 4) | channel_mode;
sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_information[1] = (block_length << 4) | (subbands << 2) | allocation_method;
sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_information[2] = min_bitpool_value;
@ -276,6 +278,16 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
sc.local_stream_endpoint->remote_configuration.media_codec.media_type = AVDTP_AUDIO;
sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_type = AVDTP_CODEC_SBC;
// printf(" - num_channels: %d\n", num_channels);
printf(" - sampling_frequency: %d\n", sampling_frequency);
printf(" - channel_mode: %d\n", channel_mode);
printf(" - block_length: %d\n", block_length);
printf(" - subbands: %d\n", subbands);
printf(" - allocation_method: %d\n", allocation_method);
printf(" - bitpool_value orig [%d, %d] \n", avdtp_subevent_signaling_media_codec_sbc_capability_get_min_bitpool_value(packet), avdtp_subevent_signaling_media_codec_sbc_capability_get_max_bitpool_value(packet));
printf(" - bitpool_value [%d, %d] \n", min_bitpool_value, max_bitpool_value);
printf("\n");
app_state = A2DP_W2_SET_CONFIGURATION;
break;
}
@ -307,6 +319,11 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
case AVDTP_SUBEVENT_SIGNALING_CAPABILITY_DONE:
break;
case AVDTP_SUBEVENT_SIGNALING_DELAY_REPORT:
// forward packet:
packet[2] = A2DP_SUBEVENT_SIGNALING_DELAY_REPORT;
(*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, packet, size);
break;
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
// TODO check cid
sc.sampling_frequency = avdtp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
@ -472,9 +489,11 @@ avdtp_stream_endpoint_t * a2dp_source_create_stream_endpoint(avdtp_media_type_t
avdtp_source_register_media_transport_category(avdtp_stream_endpoint_seid(local_stream_endpoint));
avdtp_source_register_media_codec_category(avdtp_stream_endpoint_seid(local_stream_endpoint), media_type, media_codec_type,
codec_capabilities, codec_capabilities_len);
local_stream_endpoint->remote_configuration.media_codec.media_codec_information = media_codec_info;
local_stream_endpoint->remote_configuration.media_codec.media_codec_information_len = media_codec_info_len;
sc.local_stream_endpoint = local_stream_endpoint;
avdtp_source_register_delay_reporting_category(avdtp_stream_endpoint_seid(local_stream_endpoint));
return local_stream_endpoint;
}

View File

@ -78,9 +78,8 @@ void a2dp_source_init(void);
* @param codec_capabilities_len Media codec capabilities length.
* @param codec_configuration Default media codec configuration.
* @param codec_configuration_len Media codec configuration length.
* @param out_local_seid Assigned stream endpoint ID used in further A2DP commands.
*
* @return status ERROR_CODE_SUCCESS if sucessful.
* @return local_stream_endpoint
*/
avdtp_stream_endpoint_t * a2dp_source_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type,
uint8_t * codec_capabilities, uint16_t codec_capabilities_len,

View File

@ -193,27 +193,32 @@ uint8_t avdtp_sink_reconfigure(uint16_t avdtp_cid, uint8_t local_seid, uint8_t r
}
uint8_t avdtp_sink_delay_report(uint16_t avdtp_cid, uint8_t local_seid, uint16_t delay_ms){
printf("send delay_report\n");
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, avdtp_sink_context);
if (!connection){
log_error("delay_report: no connection for signaling cid 0x%02x found", avdtp_cid);
return AVDTP_CONNECTION_DOES_NOT_EXIST;
}
printf("send delay_report 1\n");
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED ||
connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) {
log_error("delay_report: connection in wrong state, state %d, initiator state %d", connection->state, connection->initiator_connection_state);
return AVDTP_CONNECTION_IN_WRONG_STATE;
}
printf("send delay_report 2\n");
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(local_seid, avdtp_sink_context);
if (!stream_endpoint) {
log_error("delay_report: no stream_endpoint with seid %d found", local_seid);
return AVDTP_SEID_DOES_NOT_EXIST;
}
printf("send delay_report 3\n");
if (stream_endpoint->state < AVDTP_STREAM_ENDPOINT_CONFIGURED){
log_error("Stream endpoint seid %d in wrong state %d", local_seid, stream_endpoint->state);
return AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE;
}
printf("send delay_report 4\n");
connection->initiator_transaction_label++;
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_SEND_DELAY_REPORT;