a2dp source: fix walk through dicovered remote seps for finding SBC media codec capapbility

This commit is contained in:
Milanka Ringwald 2018-02-20 15:50:26 +01:00
parent 5c4f31389d
commit 578eda3e1c
7 changed files with 90 additions and 37 deletions

View File

@ -138,11 +138,10 @@ static btstack_packet_callback_registration_t hci_event_callback_registration;
// 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";
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";
// BT dongle: static const char * device_addr_string = "00:1A:7D:DA:71:0A";
// Sony MDR-ZX330BT static const char * device_addr_string = "00:18:09:28:50:18";
static bd_addr_t device_addr;
@ -636,8 +635,7 @@ static void show_usage(void){
printf("B - AVDTP Source disconnect\n");
printf("c - AVRCP Target create connection to addr %s\n", device_addr_string);
printf("C - AVRCP Target disconnect\n");
printf("0 - AVRCP reset now playing info\n");
printf("x - start streaming sine\n");
if (hxcmod_initialized){
printf("z - start streaming '%s'\n", mod_name);
@ -672,16 +670,6 @@ static void stdin_process(char cmd){
case '\r':
break;
case 't':
printf("STREAM_PTS_TEST.\n");
data_source = STREAM_PTS_TEST;
if (avrcp_connected){
avrcp_target_set_now_playing_info(avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t));
}
if (!media_tracker.stream_opened) break;
status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
break;
case 'x':
if (avrcp_connected){
avrcp_target_set_now_playing_info(avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t));
@ -700,17 +688,13 @@ static void stdin_process(char cmd){
if (!media_tracker.stream_opened) break;
status = a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
break;
case 'p':
if (!media_tracker.connected) break;
if (!media_tracker.stream_opened) break;
printf("Pause stream.\n");
status = a2dp_source_pause_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
break;
case '0':
if (avrcp_connected){
avrcp_target_set_now_playing_info(avrcp_cid, NULL, sizeof(tracks)/sizeof(avrcp_track_t));
printf("Reset now playing info\n");
}
break;
default:
show_usage();
return;

View File

@ -1539,6 +1539,16 @@ typedef uint8_t sm_key_t[16];
*/
#define AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW 0x14
/**
* @format 1211
* @param subevent_code
* @param avdtp_cid
* @param local_seid
* @param remote_seid
*/
#define AVDTP_SUBEVENT_SIGNALING_CAPABILITY_DONE 0x15
/** A2DP Subevent */
/* Stream goes through following states:

View File

@ -5012,6 +5012,34 @@ static inline uint16_t avdtp_subevent_streaming_can_send_media_packet_now_get_se
return little_endian_read_16(event, 6);
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_CAPABILITY_DONE
* @param event packet
* @return avdtp_cid
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_capability_done_get_avdtp_cid(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_CAPABILITY_DONE
* @param event packet
* @return local_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_capability_done_get_local_seid(const uint8_t * event){
return event[5];
}
/**
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_CAPABILITY_DONE
* @param event packet
* @return remote_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_capability_done_get_remote_seid(const uint8_t * event){
return event[6];
}
/**
* @brief Get field a2dp_cid from event A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW
* @param event packet

View File

@ -57,7 +57,6 @@ static avdtp_context_t a2dp_source_context;
static a2dp_state_t app_state = A2DP_IDLE;
static avdtp_stream_endpoint_context_t sc;
static int next_remote_sep_index_to_query = 0;
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
@ -189,7 +188,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
}
sc.active_remote_sep = NULL;
next_remote_sep_index_to_query = 0;
sc.active_remote_sep_index = 0;
uint8_t event[11];
int pos = 0;
event[pos++] = HCI_EVENT_A2DP_META;
@ -243,6 +242,30 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
log_info("received non SBC codec. not implemented");
break;
case AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY:
log_info("received, but not forwarded: AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY, remote seid %d\n", avdtp_subevent_signaling_media_transport_capability_get_remote_seid(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY:
log_info("received, but not forwarded: AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY, remote seid %d\n", avdtp_subevent_signaling_reporting_capability_get_remote_seid(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY:
log_info("received, but not forwarded: AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY, remote seid %d\n", avdtp_subevent_signaling_delay_reporting_capability_get_remote_seid(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY:
log_info("received, but not forwarded: AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY, remote seid %d\n", avdtp_subevent_signaling_recovery_capability_get_remote_seid(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY:
log_info("received, but not forwarded: AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY, remote seid %d\n", avdtp_subevent_signaling_content_protection_capability_get_remote_seid(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY:
log_info("received, but not forwarded: AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY, remote seid %d\n", avdtp_subevent_signaling_header_compression_capability_get_remote_seid(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY:
log_info("received, but not forwarded: AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY, remote seid %d\n", avdtp_subevent_signaling_multiplexing_capability_get_remote_seid(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_CAPABILITY_DONE:
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);
@ -288,8 +311,10 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
switch (app_state){
case A2DP_W2_DISCOVER_SEPS:
case A2DP_W2_GET_CAPABILITIES:
case A2DP_W2_GET_ALL_CAPABILITIES:
app_state = A2DP_W2_GET_ALL_CAPABILITIES;
sc.active_remote_sep = avdtp_source_remote_sep(cid, next_remote_sep_index_to_query++);
sc.active_remote_sep = avdtp_source_remote_sep(cid, sc.active_remote_sep_index++);
if (!sc.active_remote_sep) {
app_state = A2DP_IDLE;
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, cid, sc.remote_addr, 0, 0, AVDTP_SEID_DOES_NOT_EXIST);
@ -297,18 +322,6 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
}
avdtp_source_get_capabilities(cid, sc.active_remote_sep->seid);
break;
case A2DP_W2_GET_CAPABILITIES:
case A2DP_W2_GET_ALL_CAPABILITIES:
if (next_remote_sep_index_to_query < avdtp_source_remote_seps_num(cid)){
sc.active_remote_sep = avdtp_source_remote_sep(cid, next_remote_sep_index_to_query++);
// printf("Query get caps for seid %d\n", sc.active_remote_sep->seid);
avdtp_source_get_capabilities(cid, sc.active_remote_sep->seid);
} else {
// printf("No more remote seps found\n");
app_state = A2DP_IDLE;
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, cid, sc.remote_addr, 0, 0, AVDTP_SEID_DOES_NOT_EXIST);
}
break;
case A2DP_W2_SET_CONFIGURATION:{
if (!sc.local_stream_endpoint) return;
app_state = A2DP_IDLE;

View File

@ -1027,6 +1027,8 @@ avdtp_sep_t * avdtp_remote_sep(uint16_t avdtp_cid, uint8_t index, avdtp_context_
log_error("avdtp_suspend: no connection for AVDTP cid 0x%02x found", avdtp_cid);
return NULL;
}
if (index == AVDTP_INVALID_SEP_INDEX) return NULL;
if (index >= connection->remote_seps_num || index >= AVDTP_MAX_NUM_SEPS) return NULL;
return &connection->remote_seps[index];
}

View File

@ -502,6 +502,7 @@ typedef struct {
int min_bitpool_value;
int max_bitpool_value;
avdtp_stream_endpoint_t * local_stream_endpoint;
uint8_t active_remote_sep_index;
avdtp_sep_t * active_remote_sep;
} avdtp_stream_endpoint_context_t;

View File

@ -928,6 +928,20 @@ static inline void avdtp_signaling_emit_media_codec_other(btstack_packet_handler
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static void avdtp_signaling_emit_capability_done(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
if (!callback) return;
uint8_t event[7];
int pos = 0;
event[pos++] = HCI_EVENT_AVDTP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = AVDTP_SUBEVENT_SIGNALING_CAPABILITY_DONE;
little_endian_store_16(event, pos, avdtp_cid);
pos += 2;
event[pos++] = local_seid;
event[pos++] = remote_seid;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
void avdtp_signaling_emit_media_codec_other_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
if (!callback) return;
avdtp_signaling_emit_media_codec_other(callback, avdtp_cid, local_seid, remote_seid, media_codec, 0);
@ -971,6 +985,7 @@ void avdtp_emit_capabilities(btstack_packet_handler_t callback, uint16_t avdtp_c
if (get_bit16(registered_service_categories, AVDTP_DELAY_REPORTING)){
avdtp_signaling_emit_delay_reporting_capability(callback, avdtp_cid, local_seid, remote_seid);
}
avdtp_signaling_emit_capability_done(callback, avdtp_cid, local_seid, remote_seid);
}
void avdtp_emit_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_capabilities_t * configuration, uint16_t configured_service_categories){