avdtp source test: emit all received capabilities

This commit is contained in:
Milanka Ringwald 2017-12-20 14:48:13 +01:00
parent c4218671d7
commit 67ae582d9f
10 changed files with 751 additions and 103 deletions

View File

@ -1367,6 +1367,94 @@ typedef uint8_t sm_key_t[16];
*/
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY 0x08
/**
* @format 1211
* @param subevent_code
* @param avdtp_cid
* @param local_seid
* @param remote_seid
*/
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY 0x09
/**
* @format 1211
* @param subevent_code
* @param avdtp_cid
* @param local_seid
* @param remote_seid
*/
#define AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY 0x0A
/**
* @format 1211111
* @param subevent_code
* @param avdtp_cid
* @param local_seid
* @param remote_seid
* @param recovery_type
* @param maximum_recovery_window_size
* @param maximum_number_media_packets
*/
#define AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY 0x0B
/**
* @format 12112LV
* @param subevent_code
* @param avdtp_cid
* @param local_seid
* @param remote_seid
* @param cp_type
* @param cp_type_value_len
* @param cp_type_value
*/
#define AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY 0x0C
/**
* @format 121111111111
* @param subevent_code
* @param avdtp_cid
* @param local_seid
* @param remote_seid
* @param fragmentation
* @param transport_identifiers_num
* @param transport_session_identifier_1
* @param transport_session_identifier_2
* @param transport_session_identifier_3
* @param tcid_1
* @param tcid_2
* @param tcid_3
*/
#define AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY 0x0D
/**
* @format 1211
* @param subevent_code
* @param avdtp_cid
* @param local_seid
* @param remote_seid
*/
#define AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY 0x0E
/**
* @format 1211111
* @param subevent_code
* @param avdtp_cid
* @param local_seid
* @param remote_seid
* @param back_ch
* @param media
* @param recovery
*/
#define AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY 0x0F
/**
* @format 12111121111111
* @param subevent_code
@ -1384,7 +1472,7 @@ typedef uint8_t sm_key_t[16];
* @param min_bitpool_value
* @param max_bitpool_value
*/
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION 0x09
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION 0x10
/**
* @format 1211112LV
@ -1398,7 +1486,7 @@ typedef uint8_t sm_key_t[16];
* @param media_codec_information_len
* @param media_codec_information
*/
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION 0x0A
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION 0x11
/**
* @format 12B111
@ -1409,7 +1497,7 @@ typedef uint8_t sm_key_t[16];
* @param remote_seid
* @param status 0 == OK
*/
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED 0x0B
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED 0x12
/**
* @format 121
@ -1417,7 +1505,7 @@ typedef uint8_t sm_key_t[16];
* @param avdtp_cid
* @param local_seid
*/
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED 0x0C
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED 0x13
/**
* @format 1212
@ -1426,7 +1514,7 @@ typedef uint8_t sm_key_t[16];
* @param local_seid
* @param sequence_number
*/
#define AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW 0x0D
#define AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW 0x14
/** A2DP Subevent */

View File

@ -4319,6 +4319,355 @@ static inline const uint8_t * avdtp_subevent_signaling_media_codec_other_capabil
return &event[12];
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY
* @param event packet
* @return avdtp_cid
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_media_transport_capability_get_avdtp_cid(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY
* @param event packet
* @return local_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_media_transport_capability_get_local_seid(const uint8_t * event){
return event[5];
}
/**
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY
* @param event packet
* @return remote_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_media_transport_capability_get_remote_seid(const uint8_t * event){
return event[6];
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY
* @param event packet
* @return avdtp_cid
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_reporting_capability_get_avdtp_cid(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY
* @param event packet
* @return local_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_reporting_capability_get_local_seid(const uint8_t * event){
return event[5];
}
/**
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY
* @param event packet
* @return remote_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_reporting_capability_get_remote_seid(const uint8_t * event){
return event[6];
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY
* @param event packet
* @return avdtp_cid
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_recovery_capability_get_avdtp_cid(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY
* @param event packet
* @return local_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_recovery_capability_get_local_seid(const uint8_t * event){
return event[5];
}
/**
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY
* @param event packet
* @return remote_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_recovery_capability_get_remote_seid(const uint8_t * event){
return event[6];
}
/**
* @brief Get field recovery_type from event AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY
* @param event packet
* @return recovery_type
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_recovery_capability_get_recovery_type(const uint8_t * event){
return event[7];
}
/**
* @brief Get field maximum_recovery_window_size from event AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY
* @param event packet
* @return maximum_recovery_window_size
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_recovery_capability_get_maximum_recovery_window_size(const uint8_t * event){
return event[8];
}
/**
* @brief Get field maximum_number_media_packets from event AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY
* @param event packet
* @return maximum_number_media_packets
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_recovery_capability_get_maximum_number_media_packets(const uint8_t * event){
return event[9];
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY
* @param event packet
* @return avdtp_cid
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_content_protection_capability_get_avdtp_cid(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY
* @param event packet
* @return local_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_content_protection_capability_get_local_seid(const uint8_t * event){
return event[5];
}
/**
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY
* @param event packet
* @return remote_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_content_protection_capability_get_remote_seid(const uint8_t * event){
return event[6];
}
/**
* @brief Get field cp_type from event AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY
* @param event packet
* @return cp_type
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_content_protection_capability_get_cp_type(const uint8_t * event){
return little_endian_read_16(event, 7);
}
/**
* @brief Get field cp_type_value_len from event AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY
* @param event packet
* @return cp_type_value_len
* @note: btstack_type L
*/
static inline int avdtp_subevent_signaling_content_protection_capability_get_cp_type_value_len(const uint8_t * event){
return little_endian_read_16(event, 9);
}
/**
* @brief Get field cp_type_value from event AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY
* @param event packet
* @return cp_type_value
* @note: btstack_type V
*/
static inline const uint8_t * avdtp_subevent_signaling_content_protection_capability_get_cp_type_value(const uint8_t * event){
return &event[11];
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return avdtp_cid
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_multiplexing_capability_get_avdtp_cid(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return local_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_local_seid(const uint8_t * event){
return event[5];
}
/**
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return remote_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_remote_seid(const uint8_t * event){
return event[6];
}
/**
* @brief Get field fragmentation from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return fragmentation
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_fragmentation(const uint8_t * event){
return event[7];
}
/**
* @brief Get field transport_identifiers_num from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return transport_identifiers_num
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_transport_identifiers_num(const uint8_t * event){
return event[8];
}
/**
* @brief Get field transport_session_identifier_1 from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return transport_session_identifier_1
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_1(const uint8_t * event){
return event[9];
}
/**
* @brief Get field transport_session_identifier_2 from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return transport_session_identifier_2
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_2(const uint8_t * event){
return event[10];
}
/**
* @brief Get field transport_session_identifier_3 from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return transport_session_identifier_3
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_3(const uint8_t * event){
return event[11];
}
/**
* @brief Get field tcid_1 from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return tcid_1
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_tcid_1(const uint8_t * event){
return event[12];
}
/**
* @brief Get field tcid_2 from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return tcid_2
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_tcid_2(const uint8_t * event){
return event[13];
}
/**
* @brief Get field tcid_3 from event AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY
* @param event packet
* @return tcid_3
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_multiplexing_capability_get_tcid_3(const uint8_t * event){
return event[14];
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY
* @param event packet
* @return avdtp_cid
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_delay_reporting_capability_get_avdtp_cid(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY
* @param event packet
* @return local_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_delay_reporting_capability_get_local_seid(const uint8_t * event){
return event[5];
}
/**
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY
* @param event packet
* @return remote_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_delay_reporting_capability_get_remote_seid(const uint8_t * event){
return event[6];
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY
* @param event packet
* @return avdtp_cid
* @note: btstack_type 2
*/
static inline uint16_t avdtp_subevent_signaling_header_compression_capability_get_avdtp_cid(const uint8_t * event){
return little_endian_read_16(event, 3);
}
/**
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY
* @param event packet
* @return local_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_header_compression_capability_get_local_seid(const uint8_t * event){
return event[5];
}
/**
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY
* @param event packet
* @return remote_seid
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_header_compression_capability_get_remote_seid(const uint8_t * event){
return event[6];
}
/**
* @brief Get field back_ch from event AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY
* @param event packet
* @return back_ch
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_header_compression_capability_get_back_ch(const uint8_t * event){
return event[7];
}
/**
* @brief Get field media from event AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY
* @param event packet
* @return media
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_header_compression_capability_get_media(const uint8_t * event){
return event[8];
}
/**
* @brief Get field recovery from event AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY
* @param event packet
* @return recovery
* @note: btstack_type 1
*/
static inline uint8_t avdtp_subevent_signaling_header_compression_capability_get_recovery(const uint8_t * event){
return event[9];
}
/**
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION
* @param event packet

View File

@ -232,8 +232,8 @@ void avdtp_register_content_protection_category(avdtp_stream_endpoint_t * stream
uint16_t bitmap = store_bit16(stream_endpoint->sep.registered_service_categories, AVDTP_CONTENT_PROTECTION, 1);
stream_endpoint->sep.registered_service_categories = bitmap;
stream_endpoint->sep.capabilities.content_protection.cp_type = cp_type;
stream_endpoint->sep.capabilities.content_protection.cp_type_value = cp_type_value;
stream_endpoint->sep.capabilities.content_protection.cp_type_value_len = cp_type_value_len;
memcpy(stream_endpoint->sep.capabilities.content_protection.cp_type_value, cp_type_value, btstack_min(cp_type_value_len, AVDTP_MAX_CONTENT_PROTECTION_TYPE_VALUE_LEN));
stream_endpoint->sep.capabilities.content_protection.cp_type_value_len = btstack_min(cp_type_value_len, AVDTP_MAX_CONTENT_PROTECTION_TYPE_VALUE_LEN);
}
void avdtp_register_header_compression_category(avdtp_stream_endpoint_t * stream_endpoint, uint8_t back_ch, uint8_t media, uint8_t recovery){
@ -1089,6 +1089,7 @@ uint8_t avdtp_stream_endpoint_seid(avdtp_stream_endpoint_t * stream_endpoint){
return stream_endpoint->sep.seid;
}
uint8_t avdtp_choose_sbc_subbands(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_subbands_bitmap){
if (!stream_endpoint) return 0;
uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information;
uint8_t subbands_bitmap = ((media_codec[1] >> 2) & 0x03) & remote_subbands_bitmap;
@ -1102,6 +1103,7 @@ uint8_t avdtp_choose_sbc_subbands(avdtp_stream_endpoint_t * stream_endpoint, uin
}
uint8_t avdtp_choose_sbc_block_length(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_block_length_bitmap){
if (!stream_endpoint) return 0;
uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information;
uint8_t block_length_bitmap = (media_codec[1] >> 4) & remote_block_length_bitmap;
@ -1119,6 +1121,7 @@ uint8_t avdtp_choose_sbc_block_length(avdtp_stream_endpoint_t * stream_endpoint,
}
uint8_t avdtp_choose_sbc_sampling_frequency(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_sampling_frequency_bitmap){
if (!stream_endpoint) return 0;
uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information;
uint8_t sampling_frequency_bitmap = (media_codec[0] >> 4) & remote_sampling_frequency_bitmap;
@ -1136,11 +1139,13 @@ uint8_t avdtp_choose_sbc_sampling_frequency(avdtp_stream_endpoint_t * stream_end
}
uint8_t avdtp_choose_sbc_max_bitpool_value(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_max_bitpool_value){
if (!stream_endpoint) return 0;
uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information;
return btstack_min(media_codec[3], remote_max_bitpool_value);
}
uint8_t avdtp_choose_sbc_min_bitpool_value(avdtp_stream_endpoint_t * stream_endpoint, uint8_t remote_min_bitpool_value){
if (!stream_endpoint) return 0;
uint8_t * media_codec = stream_endpoint->sep.capabilities.media_codec.media_codec_information;
return btstack_max(media_codec[2], remote_min_bitpool_value);
}

View File

@ -58,8 +58,9 @@
extern "C" {
#endif
#define MAX_NUM_SEPS 10
#define MAX_CSRC_NUM 15
#define AVDTP_MAX_NUM_SEPS 10
#define AVDTP_MAX_CSRC_NUM 15
#define AVDTP_MAX_CONTENT_PROTECTION_TYPE_VALUE_LEN 10
// Supported Features
#define AVDTP_SOURCE_SF_Player 0x0001
@ -182,7 +183,7 @@ typedef struct {
typedef struct {
uint16_t cp_type;
uint16_t cp_type_value_len;
const uint8_t * cp_type_value;
uint8_t cp_type_value[AVDTP_MAX_CONTENT_PROTECTION_TYPE_VALUE_LEN];
} adtvp_content_protection_t;
typedef struct{
@ -265,7 +266,7 @@ typedef struct {
uint32_t timestamp;
uint32_t synchronization_source;
uint32_t csrc_list[MAX_CSRC_NUM];
uint32_t csrc_list[AVDTP_MAX_CSRC_NUM];
} avdtp_media_packet_header_t;
typedef enum {
@ -403,7 +404,7 @@ typedef struct {
uint8_t wait_to_send_initiator;
uint8_t wait_to_send_self;
uint8_t suspended_seids[MAX_NUM_SEPS];
uint8_t suspended_seids[AVDTP_MAX_NUM_SEPS];
uint8_t num_suspended_seids;
uint8_t reject_service_category;
@ -411,7 +412,7 @@ typedef struct {
uint8_t error_code;
// store configurations with remote seps
avdtp_sep_t remote_seps[MAX_NUM_SEPS];
avdtp_sep_t remote_seps[AVDTP_MAX_NUM_SEPS];
uint8_t remote_seps_num;
// store current role

View File

@ -260,17 +260,8 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
connection->remote_seps[stream_endpoint->remote_sep_index] = sep;
log_info("ACP: add seid %d, to %p", connection->remote_seps[stream_endpoint->remote_sep_index].seid, stream_endpoint);
}
if (get_bit16(sep.configured_service_categories, AVDTP_MEDIA_CODEC)){
switch (sep.configuration.media_codec.media_codec_type){
case AVDTP_CODEC_SBC:
avdtp_signaling_emit_media_codec_sbc_configuration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint),
sep.configuration.media_codec.media_type, sep.configuration.media_codec.media_codec_information);
break;
default:
avdtp_signaling_emit_media_codec_other_configuration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), sep.configuration.media_codec);
break;
}
}
avdtp_emit_configuration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), &sep.configuration, sep.configured_service_categories);
avdtp_signaling_emit_accept(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->signaling_packet.signal_identifier);
break;
}
@ -301,17 +292,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
stream_endpoint->connection->remote_seps[stream_endpoint->remote_sep_index] = sep;
log_info("ACP: update seid %d, to %p", stream_endpoint->connection->remote_seps[stream_endpoint->remote_sep_index].seid, stream_endpoint);
if (get_bit16(sep.configured_service_categories, AVDTP_MEDIA_CODEC)){
switch (sep.capabilities.media_codec.media_codec_type){
case AVDTP_CODEC_SBC:
avdtp_signaling_emit_media_codec_sbc_reconfiguration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint),
sep.configuration.media_codec.media_type, sep.configuration.media_codec.media_codec_information);
break;
default:
avdtp_signaling_emit_media_codec_other_reconfiguration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), sep.configuration.media_codec);
break;
}
}
avdtp_emit_configuration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), &sep.configuration, sep.configured_service_categories);
avdtp_signaling_emit_accept(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->signaling_packet.signal_identifier);
break;
}
@ -419,7 +400,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
}
static int avdtp_acceptor_send_seps_response(uint16_t cid, uint8_t transaction_label, avdtp_stream_endpoint_t * endpoints){
uint8_t command[2+2*MAX_NUM_SEPS];
uint8_t command[2+2*AVDTP_MAX_NUM_SEPS];
int pos = 0;
command[pos++] = avdtp_header(transaction_label, AVDTP_SINGLE_PACKET, AVDTP_RESPONSE_ACCEPT_MSG);
command[pos++] = (uint8_t)AVDTP_SI_DISCOVER;

View File

@ -120,20 +120,8 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
case AVDTP_SI_GET_CAPABILITIES:
case AVDTP_SI_GET_ALL_CAPABILITIES:
log_info("initiator AVDTP_SI_GET_CAPABILITIES \n");
sep.registered_service_categories = avdtp_unpack_service_capabilities(connection, &sep.capabilities, packet+offset, size-offset);
if (get_bit16(sep.registered_service_categories, AVDTP_MEDIA_CODEC)){
switch (sep.capabilities.media_codec.media_codec_type){
case AVDTP_CODEC_SBC:
log_info("initiator avdtp_signaling_emit_media_codec_sbc_capability, local_seid %d, remote_seid %d\n", connection->local_seid, connection->remote_seid);
avdtp_signaling_emit_media_codec_sbc_capability(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->remote_seid, sep.capabilities.media_codec);
break;
default:
log_info("initiator avdtp_signaling_emit_media_codec_other_capability \n");
avdtp_signaling_emit_media_codec_other_capability(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->remote_seid, sep.capabilities.media_codec);
break;
}
}
avdtp_emit_capabilities(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->remote_seid, &sep.capabilities, sep.registered_service_categories);
break;
case AVDTP_SI_GET_CONFIGURATION:

View File

@ -356,17 +356,18 @@ uint16_t avdtp_unpack_service_capabilities(avdtp_connection_t * connection, avdt
int i;
avdtp_service_category_t category = (avdtp_service_category_t)packet[pos++];
uint8_t cap_len = packet[pos++];
if (cap_len > size - pos){
connection->reject_service_category = category;
connection->error_code = BAD_LENGTH;
return 0;
}
if (avdtp_unpack_service_capabilities_has_errors(connection, category, cap_len)) return 0;
int processed_cap_len = 0;
int rfa = 0;
while (pos < size){
if (cap_len > size - pos){
connection->reject_service_category = category;
connection->error_code = BAD_LENGTH;
return 0;
}
rfa = 0;
processed_cap_len = pos;
switch(category){
@ -420,8 +421,11 @@ uint16_t avdtp_unpack_service_capabilities(avdtp_connection_t * connection, avdt
break;
}
processed_cap_len = pos - processed_cap_len;
// printf("processed category %d, cap_len %d, processed_cap_len %d, rfa %d\n", category, cap_len, processed_cap_len, rfa);
if (cap_len == processed_cap_len){
// printf("pos %d, size %d \n", rfa, size - 2);
if (!rfa) {
registered_service_categories = store_bit16(registered_service_categories, category, 1);
}
@ -429,7 +433,10 @@ uint16_t avdtp_unpack_service_capabilities(avdtp_connection_t * connection, avdt
//int old_pos = pos;
category = (avdtp_service_category_t)packet[pos++];
cap_len = packet[pos++];
if (avdtp_unpack_service_capabilities_has_errors(connection, category, cap_len)) return 0;
if (avdtp_unpack_service_capabilities_has_errors(connection, category, cap_len)){
log_error("avdtp_unpack_service_capabilities_has_errors");
return 0;
}
}
}
}
@ -654,7 +661,7 @@ void avdtp_signaling_emit_general_reject(btstack_packet_handler_t callback, uint
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
void avdtp_signaling_emit_media_codec_sbc_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
static void avdtp_signaling_emit_media_codec_sbc_capability(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;
uint8_t event[15];
int pos = 0;
@ -676,9 +683,119 @@ void avdtp_signaling_emit_media_codec_sbc_capability(btstack_packet_handler_t ca
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
void avdtp_signaling_emit_media_codec_other_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
static inline void avdtp_signaling_emit_capability(btstack_packet_handler_t callback, uint8_t capability_subevent_id, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
if (!callback) return;
uint8_t event[111];
uint8_t event[7];
int pos = 0;
event[pos++] = HCI_EVENT_AVDTP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = capability_subevent_id;
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));
}
static void avdtp_signaling_emit_media_transport_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
avdtp_signaling_emit_capability(callback, AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY, avdtp_cid, local_seid, remote_seid);
}
static void avdtp_signaling_emit_reporting_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
avdtp_signaling_emit_capability(callback, AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY, avdtp_cid, local_seid, remote_seid);
}
static void avdtp_signaling_emit_delay_reporting_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
avdtp_signaling_emit_capability(callback, AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY, avdtp_cid, local_seid, remote_seid);
}
static void avdtp_signaling_emit_recovery_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_recovery_capabilities_t * recovery){
if (!callback) return;
uint8_t event[10];
int pos = 0;
event[pos++] = HCI_EVENT_AVDTP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY;
little_endian_store_16(event, pos, avdtp_cid);
pos += 2;
event[pos++] = local_seid;
event[pos++] = remote_seid;
event[pos++] = recovery->recovery_type;
event[pos++] = recovery->maximum_recovery_window_size;
event[pos++] = recovery->maximum_number_media_packets;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static void avdtp_signaling_emit_content_protection_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_content_protection_t * content_protection){
if (!callback) return;
uint8_t event[22];
int pos = 0;
event[pos++] = HCI_EVENT_AVDTP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY;
little_endian_store_16(event, pos, avdtp_cid);
pos += 2;
event[pos++] = local_seid;
event[pos++] = remote_seid;
little_endian_store_16(event, pos, content_protection->cp_type);
pos += 2;
little_endian_store_16(event, pos, content_protection->cp_type_value_len);
pos += 2;
//TODO: reserve place for value
if (content_protection->cp_type_value_len < 10){
memcpy(event+pos, content_protection->cp_type_value, content_protection->cp_type_value_len);
}
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static void avdtp_signaling_emit_header_compression_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_header_compression_capabilities_t * header_compression){
if (!callback) return;
uint8_t event[10];
int pos = 0;
event[pos++] = HCI_EVENT_AVDTP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY;
little_endian_store_16(event, pos, avdtp_cid);
pos += 2;
event[pos++] = local_seid;
event[pos++] = remote_seid;
event[pos++] = header_compression->back_ch;
event[pos++] = header_compression->media;
event[pos++] = header_compression->recovery;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static void avdtp_signaling_emit_content_multiplexing_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_multiplexing_mode_capabilities_t * multiplexing_mode){
if (!callback) return;
uint8_t event[15];
int pos = 0;
event[pos++] = HCI_EVENT_AVDTP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY;
little_endian_store_16(event, pos, avdtp_cid);
pos += 2;
event[pos++] = local_seid;
event[pos++] = remote_seid;
event[pos++] = multiplexing_mode->fragmentation;
event[pos++] = multiplexing_mode->transport_identifiers_num;
int i;
for (i = 0; i < 3; i++){
event[pos++] = multiplexing_mode->transport_session_identifiers[i];
}
for (i = 0; i < 3; i++){
event[pos++] = multiplexing_mode->tcid[i];
}
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static void avdtp_signaling_emit_media_codec_other_capability(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;
uint8_t event[111];
int pos = 0;
event[pos++] = HCI_EVENT_AVDTP_META;
event[pos++] = sizeof(event) - 2;
@ -791,6 +908,7 @@ void avdtp_signaling_emit_media_codec_sbc_reconfiguration(btstack_packet_handler
avdtp_signaling_emit_media_codec_sbc(callback, avdtp_cid, local_seid, remote_seid, media_type, media_codec_information, 1);
}
static inline void avdtp_signaling_emit_media_codec_other(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec, uint8_t reconfigure){
uint8_t event[MAX_MEDIA_CODEC_INFORMATION_LENGTH + 13];
int pos = 0;
@ -824,6 +942,55 @@ void avdtp_signaling_emit_media_codec_other_reconfiguration(btstack_packet_handl
avdtp_signaling_emit_media_codec_other(callback, avdtp_cid, local_seid, remote_seid, media_codec, 1);
}
void avdtp_emit_capabilities(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_capabilities_t * capabilities, uint16_t registered_service_categories){
if (get_bit16(registered_service_categories, AVDTP_MEDIA_CODEC)){
switch (capabilities->media_codec.media_codec_type){
case AVDTP_CODEC_SBC:
avdtp_signaling_emit_media_codec_sbc_capability(callback, avdtp_cid, local_seid, remote_seid, capabilities->media_codec);
break;
default:
avdtp_signaling_emit_media_codec_other_capability(callback, avdtp_cid, local_seid, remote_seid, capabilities->media_codec);
break;
}
}
if (get_bit16(registered_service_categories, AVDTP_MEDIA_TRANSPORT)){
avdtp_signaling_emit_media_transport_capability(callback, avdtp_cid, local_seid, remote_seid);
}
if (get_bit16(registered_service_categories, AVDTP_REPORTING)){
avdtp_signaling_emit_reporting_capability(callback, avdtp_cid, local_seid, remote_seid);
}
if (get_bit16(registered_service_categories, AVDTP_RECOVERY)){
avdtp_signaling_emit_recovery_capability(callback, avdtp_cid, local_seid, remote_seid, &capabilities->recovery);
}
if (get_bit16(registered_service_categories, AVDTP_CONTENT_PROTECTION)){
avdtp_signaling_emit_content_protection_capability(callback, avdtp_cid, local_seid, remote_seid, &capabilities->content_protection);
}
if (get_bit16(registered_service_categories, AVDTP_HEADER_COMPRESSION)){
avdtp_signaling_emit_header_compression_capability(callback, avdtp_cid, local_seid, remote_seid, &capabilities->header_compression);
}
if (get_bit16(registered_service_categories, AVDTP_MULTIPLEXING)){
avdtp_signaling_emit_content_multiplexing_capability(callback, avdtp_cid, local_seid, remote_seid, &capabilities->multiplexing_mode);
}
if (get_bit16(registered_service_categories, AVDTP_DELAY_REPORTING)){
avdtp_signaling_emit_delay_reporting_capability(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){
if (get_bit16(configured_service_categories, AVDTP_MEDIA_CODEC)){
switch (configuration->media_codec.media_codec_type){
case AVDTP_CODEC_SBC:
avdtp_signaling_emit_media_codec_sbc_configuration(callback, avdtp_cid, local_seid, remote_seid,
configuration->media_codec.media_type, configuration->media_codec.media_codec_information);
break;
default:
avdtp_signaling_emit_media_codec_other_configuration(callback, avdtp_cid, local_seid, remote_seid, configuration->media_codec);
break;
}
}
}
uint8_t avdtp_request_can_send_now_acceptor(avdtp_connection_t * connection, uint16_t l2cap_cid){
if (!connection) return AVDTP_CONNECTION_DOES_NOT_EXIST;

View File

@ -90,8 +90,9 @@ void avdtp_signaling_emit_general_reject(btstack_packet_handler_t callback, uint
void avdtp_signaling_emit_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, avdtp_signal_identifier_t identifier);
void avdtp_streaming_emit_can_send_media_packet_now(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint16_t sequence_number);
void avdtp_signaling_emit_media_codec_sbc_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec);
void avdtp_signaling_emit_media_codec_other_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec);
void avdtp_emit_capabilities(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);
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);
void avdtp_signaling_emit_media_codec_sbc_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_media_type_t media_type, const uint8_t * media_codec_information);
void avdtp_signaling_emit_media_codec_other_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec);
void avdtp_signaling_emit_media_codec_sbc_reconfiguration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_media_type_t media_type, const uint8_t * media_codec_information);

View File

@ -552,7 +552,6 @@ static int read_media_data_header(uint8_t *packet, int size, int *offset, avdtp_
}
static void dump_sbc_capability(adtvp_media_codec_information_sbc_t media_codec_sbc){
printf("Received media codec capability:\n");
printf(" - sampling_frequency: 0x%02x\n", media_codec_sbc.sampling_frequency_bitmap);
printf(" - channel_mode: 0x%02x\n", media_codec_sbc.channel_mode_bitmap);
printf(" - block_length: 0x%02x\n", media_codec_sbc.block_length_bitmap);
@ -562,7 +561,6 @@ static void dump_sbc_capability(adtvp_media_codec_information_sbc_t media_codec_
}
static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t configuration){
printf("Received media codec configuration:\n");
printf(" - num_channels: %d\n", configuration.num_channels);
printf(" - sampling_frequency: %d\n", configuration.sampling_frequency);
printf(" - channel_mode: %d\n", configuration.channel_mode);

View File

@ -131,6 +131,7 @@ static uint16_t remote_configuration_bitmap;
static avdtp_capabilities_t remote_configuration;
static avdtp_context_t a2dp_source_context;
static btstack_sbc_encoder_state_t sbc_encoder_state;
static uint8_t is_cmd_triggered_localy = 0;
static btstack_packet_callback_registration_t hci_event_callback_registration;
@ -399,6 +400,26 @@ static void initialize_sbc_encoder(void){
sc.max_bitpool_value, sc.channel_mode);
}
static void dump_sbc_capability(adtvp_media_codec_information_sbc_t media_codec_sbc){
printf(" - sampling_frequency: 0x%02x\n", media_codec_sbc.sampling_frequency_bitmap);
printf(" - channel_mode: 0x%02x\n", media_codec_sbc.channel_mode_bitmap);
printf(" - block_length: 0x%02x\n", media_codec_sbc.block_length_bitmap);
printf(" - subbands: 0x%02x\n", media_codec_sbc.subbands_bitmap);
printf(" - allocation_method: 0x%02x\n", media_codec_sbc.allocation_method_bitmap);
printf(" - bitpool_value [%d, %d] \n", media_codec_sbc.min_bitpool_value, media_codec_sbc.max_bitpool_value);
}
static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t configuration){
printf("Received media codec configuration:\n");
printf(" - num_channels: %d\n", configuration.num_channels);
printf(" - sampling_frequency: %d\n", configuration.sampling_frequency);
printf(" - channel_mode: %d\n", configuration.channel_mode);
printf(" - block_length: %d\n", configuration.block_length);
printf(" - subbands: %d\n", configuration.subbands);
printf(" - allocation_method: %d\n", configuration.allocation_method);
printf(" - bitpool_value [%d, %d] \n", configuration.min_bitpool_value, configuration.max_bitpool_value);
}
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
if (packet_type != HCI_EVENT_PACKET) return;
if (hci_event_packet_get_type(packet) != HCI_EVENT_AVDTP_META) return;
@ -440,31 +461,71 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
break;
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY:{
// TODO check cid
if (!sc.local_stream_endpoint) return;
uint8_t sampling_frequency = avdtp_choose_sbc_sampling_frequency(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet));
uint8_t channel_mode = avdtp_choose_sbc_channel_mode(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet));
uint8_t block_length = avdtp_choose_sbc_block_length(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_block_length_bitmap(packet));
uint8_t subbands = avdtp_choose_sbc_subbands(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_subbands_bitmap(packet));
uint8_t allocation_method = avdtp_choose_sbc_allocation_method(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_allocation_method_bitmap(packet));
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;
sc.local_stream_endpoint->remote_configuration.media_codec.media_codec_information[3] = max_bitpool_value;
sc.local_stream_endpoint->remote_configuration_bitmap = store_bit16(sc.local_stream_endpoint->remote_configuration_bitmap, AVDTP_MEDIA_CODEC, 1);
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("CAPABILITY - MEDIA_CODEC_SBC: \n");
adtvp_media_codec_information_sbc_t sbc_capability;
sbc_capability.sampling_frequency_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet);
sbc_capability.channel_mode_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet);
sbc_capability.block_length_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_block_length_bitmap(packet);
sbc_capability.subbands_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_subbands_bitmap(packet);
sbc_capability.allocation_method_bitmap = avdtp_subevent_signaling_media_codec_sbc_capability_get_allocation_method_bitmap(packet);
sbc_capability.min_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_capability_get_min_bitpool_value(packet);
sbc_capability.max_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_capability_get_max_bitpool_value(packet);
dump_sbc_capability(sbc_capability);
break;
}
case AVDTP_SUBEVENT_SIGNALING_MEDIA_TRANSPORT_CAPABILITY:
printf("CAPABILITY - MEDIA_TRANSPORT supported on remote.\n");
break;
case AVDTP_SUBEVENT_SIGNALING_REPORTING_CAPABILITY:
printf("CAPABILITY - REPORTING supported on remote.\n");
break;
case AVDTP_SUBEVENT_SIGNALING_RECOVERY_CAPABILITY:
printf("CAPABILITY - RECOVERY supported on remote: \n");
printf(" - recovery_type %d\n", avdtp_subevent_signaling_recovery_capability_get_recovery_type(packet));
printf(" - maximum_recovery_window_size %d\n", avdtp_subevent_signaling_recovery_capability_get_maximum_recovery_window_size(packet));
printf(" - maximum_number_media_packets %d\n", avdtp_subevent_signaling_recovery_capability_get_maximum_number_media_packets(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_CONTENT_PROTECTION_CAPABILITY:
printf("CAPABILITY - CONTENT_PROTECTION supported on remote: \n");
printf(" - cp_type %d\n", avdtp_subevent_signaling_content_protection_capability_get_cp_type(packet));
printf(" - cp_type_value_len %d\n", avdtp_subevent_signaling_content_protection_capability_get_cp_type_value_len(packet));
printf(" - cp_type_value \'%s\'\n", avdtp_subevent_signaling_content_protection_capability_get_cp_type_value(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_MULTIPLEXING_CAPABILITY:
printf("CAPABILITY - MULTIPLEXING supported on remote: \n");
printf(" - fragmentation %d\n", avdtp_subevent_signaling_multiplexing_capability_get_fragmentation(packet));
printf(" - transport_identifiers_num %d\n", avdtp_subevent_signaling_multiplexing_capability_get_transport_identifiers_num(packet));
printf(" - transport_session_identifier_1 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_1(packet));
printf(" - transport_session_identifier_2 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_2(packet));
printf(" - transport_session_identifier_3 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_transport_session_identifier_3(packet));
printf(" - tcid_1 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_tcid_1(packet));
printf(" - tcid_2 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_tcid_2(packet));
printf(" - tcid_3 %d\n", avdtp_subevent_signaling_multiplexing_capability_get_tcid_3(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_DELAY_REPORTING_CAPABILITY:
printf("CAPABILITY - DELAY_REPORTING supported on remote.\n");
break;
case AVDTP_SUBEVENT_SIGNALING_HEADER_COMPRESSION_CAPABILITY:
printf("CAPABILITY - HEADER_COMPRESSION supported on remote: \n");
printf(" - back_ch %d\n", avdtp_subevent_signaling_header_compression_capability_get_back_ch(packet));
printf(" - media %d\n", avdtp_subevent_signaling_header_compression_capability_get_media(packet));
printf(" - recovery %d\n", avdtp_subevent_signaling_header_compression_capability_get_recovery(packet));
break;
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
// TODO check cid
printf(" AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION \n");
avdtp_media_codec_configuration_sbc_t sbc_configuration;
sbc_configuration.reconfigure = avdtp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
sbc_configuration.num_channels = avdtp_subevent_signaling_media_codec_sbc_configuration_get_num_channels(packet);
sbc_configuration.sampling_frequency = avdtp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
sbc_configuration.channel_mode = avdtp_subevent_signaling_media_codec_sbc_configuration_get_channel_mode(packet);
sbc_configuration.block_length = avdtp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
sbc_configuration.subbands = avdtp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
sbc_configuration.allocation_method = avdtp_subevent_signaling_media_codec_sbc_configuration_get_allocation_method(packet);
sbc_configuration.min_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_configuration_get_min_bitpool_value(packet);
sbc_configuration.max_bitpool_value = avdtp_subevent_signaling_media_codec_sbc_configuration_get_max_bitpool_value(packet);
sbc_configuration.frames_per_buffer = sbc_configuration.subbands * sbc_configuration.block_length;
dump_sbc_configuration(sbc_configuration);
sc.sampling_frequency = avdtp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
sc.block_length = avdtp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
sc.subbands = avdtp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
@ -486,8 +547,11 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
// TODO check cid
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
printf("Accepted %s\n", avdtp_si2str(signal_identifier));
if (is_cmd_triggered_localy){
is_cmd_triggered_localy = 0;
printf("AVDTP Source command accepted\n");
}
switch (signal_identifier){
case AVDTP_SI_OPEN:
initialize_sbc_encoder();
@ -581,30 +645,32 @@ static void show_usage(void){
static void stdin_process(char cmd){
uint8_t status = ERROR_CODE_SUCCESS;
is_cmd_triggered_localy = 1;
switch (cmd){
case 'c':
printf("Establish AVDTP Source connection to %s\n", device_addr_string);
avdtp_source_connect(device_addr, &media_tracker.avdtp_cid);
status = avdtp_source_connect(device_addr, &media_tracker.avdtp_cid);
break;
case 'C':
printf("Disconnect AVDTP Source\n");
avdtp_source_disconnect(media_tracker.avdtp_cid);
status = avdtp_source_disconnect(media_tracker.avdtp_cid);
break;
case 'd':
printf("Discover stream endpoints of %s\n", device_addr_string);
avdtp_source_discover_stream_endpoints(media_tracker.avdtp_cid);
status = avdtp_source_discover_stream_endpoints(media_tracker.avdtp_cid);
break;
case 'g':
printf("Get capabilities of stream endpoint with seid %d\n", media_tracker.remote_seid);
avdtp_source_get_capabilities(media_tracker.avdtp_cid, media_tracker.remote_seid);
status = avdtp_source_get_capabilities(media_tracker.avdtp_cid, media_tracker.remote_seid);
break;
case 'a':
printf("Get all capabilities of stream endpoint with seid %d\n", media_tracker.remote_seid);
avdtp_source_get_all_capabilities(media_tracker.avdtp_cid, media_tracker.remote_seid);
status = avdtp_source_get_all_capabilities(media_tracker.avdtp_cid, media_tracker.remote_seid);
break;
case 'f':
printf("Get configuration of stream endpoint with seid %d\n", media_tracker.remote_seid);
avdtp_source_get_configuration(media_tracker.avdtp_cid, media_tracker.remote_seid);
status = avdtp_source_get_configuration(media_tracker.avdtp_cid, media_tracker.remote_seid);
break;
case 's':
printf("Set configuration of stream endpoint with seid %d\n", media_tracker.remote_seid);
@ -615,7 +681,7 @@ static void stdin_process(char cmd){
remote_configuration.media_codec.media_codec_information = (uint8_t *)media_sbc_codec_configuration;
initialize_streaming_context(media_sbc_codec_configuration);
avdtp_source_set_configuration(media_tracker.avdtp_cid, media_tracker.local_seid, media_tracker.remote_seid, remote_configuration_bitmap, remote_configuration);
status = avdtp_source_set_configuration(media_tracker.avdtp_cid, media_tracker.local_seid, media_tracker.remote_seid, remote_configuration_bitmap, remote_configuration);
break;
case 'R':
printf("Reconfigure stream endpoint with seid %d\n", media_tracker.remote_seid);
@ -626,32 +692,32 @@ static void stdin_process(char cmd){
remote_configuration.media_codec.media_codec_information = (uint8_t *)media_sbc_codec_reconfiguration;
initialize_streaming_context(media_sbc_codec_reconfiguration);
avdtp_source_reconfigure(media_tracker.avdtp_cid, media_tracker.local_seid, media_tracker.remote_seid, remote_configuration_bitmap, remote_configuration);
status = avdtp_source_reconfigure(media_tracker.avdtp_cid, media_tracker.local_seid, media_tracker.remote_seid, remote_configuration_bitmap, remote_configuration);
break;
case 'o':
printf("Establish stream between local %d and remote %d seid\n", media_tracker.local_seid, media_tracker.remote_seid);
initialize_sbc_encoder();
avdtp_source_open_stream(media_tracker.avdtp_cid, media_tracker.local_seid, media_tracker.remote_seid);
status = avdtp_source_open_stream(media_tracker.avdtp_cid, media_tracker.local_seid, media_tracker.remote_seid);
break;
case 'm':
printf("Start stream between local %d and remote %d seid, \n", media_tracker.local_seid, media_tracker.remote_seid);
avdtp_source_start_stream(media_tracker.avdtp_cid, media_tracker.local_seid);
status = avdtp_source_start_stream(media_tracker.avdtp_cid, media_tracker.local_seid);
break;
case 'A':
printf("Abort stream between local %d and remote %d seid\n", media_tracker.local_seid, media_tracker.remote_seid);
avdtp_source_abort_stream(media_tracker.avdtp_cid, media_tracker.local_seid);
status = avdtp_source_abort_stream(media_tracker.avdtp_cid, media_tracker.local_seid);
break;
case 'S':
printf("Release stream between local %d and remote %d seid\n", media_tracker.local_seid, media_tracker.remote_seid);
avdtp_source_stop_stream(media_tracker.avdtp_cid, media_tracker.local_seid);
status = avdtp_source_stop_stream(media_tracker.avdtp_cid, media_tracker.local_seid);
break;
case 'P':
printf("Susspend stream between local %d and remote %d seid\n", media_tracker.local_seid, media_tracker.remote_seid);
avdtp_source_suspend(media_tracker.avdtp_cid, media_tracker.local_seid);
status = avdtp_source_suspend(media_tracker.avdtp_cid, media_tracker.local_seid);
break;
case 'X':
printf("Stop streaming\n");
avdtp_source_stop_stream(media_tracker.avdtp_cid, media_tracker.local_seid);
status = avdtp_source_stop_stream(media_tracker.avdtp_cid, media_tracker.local_seid);
break;
case '\n':
@ -662,6 +728,9 @@ static void stdin_process(char cmd){
break;
}
if (status != ERROR_CODE_SUCCESS){
printf("AVDTP Sink cmd \'%c\' failed, status 0x%02x\n", cmd, status);
}
}
#endif
@ -680,9 +749,10 @@ int btstack_main(int argc, const char * argv[]){
avdtp_source_init(&a2dp_source_context);
avdtp_source_register_packet_handler(&packet_handler);
avdtp_stream_endpoint_t * local_stream_endpoint = a2dp_source_create_stream_endpoint(AVDTP_AUDIO, AVDTP_CODEC_SBC, (uint8_t *)media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities), (uint8_t *)media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));
media_tracker.local_seid = avdtp_local_seid(local_stream_endpoint);
sc.local_stream_endpoint = a2dp_source_create_stream_endpoint(AVDTP_AUDIO, AVDTP_CODEC_SBC, (uint8_t *) media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities), (uint8_t*) media_sbc_codec_configuration, sizeof(media_sbc_codec_configuration));
media_tracker.local_seid = avdtp_local_seid(sc.local_stream_endpoint);
media_tracker.remote_seid = 1;
// Initialize SDP
sdp_init();