mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 22:20:37 +00:00
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:
parent
32c78405d2
commit
8b94010e12
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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){
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user