mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-29 04:20:20 +00:00
a2dp sink: start extracting code from demo to a2dp layer
This commit is contained in:
parent
de804f9e40
commit
7050d2ca52
@ -169,8 +169,9 @@ typedef struct {
|
||||
#ifdef HAVE_BTSTACK_STDIN
|
||||
// mac 2011: static bd_addr_t remote = {0x04, 0x0C, 0xCE, 0xE4, 0x85, 0xD3};
|
||||
// pts: static bd_addr_t remote = {0x00, 0x1B, 0xDC, 0x08, 0x0A, 0xA5};
|
||||
// mac 2013:
|
||||
static const char * device_addr_string = "00:1B:DC:08:0A:A5";
|
||||
// mac 2013: static const char * device_addr_string = "00:1B:DC:08:0A:A5";
|
||||
// iPhone 5S:
|
||||
static const char * device_addr_string = "54:E4:3A:26:A2:39";
|
||||
#endif
|
||||
|
||||
// bt dongle: -u 02-02 static bd_addr_t remote = {0x00, 0x02, 0x72, 0xDC, 0x31, 0xC1};
|
||||
@ -183,6 +184,8 @@ static adtvp_media_codec_information_sbc_t sbc_capability;
|
||||
static avdtp_media_codec_configuration_sbc_t sbc_configuration;
|
||||
static avdtp_stream_endpoint_t * local_stream_endpoint;
|
||||
|
||||
static uint8_t local_seid = 0;
|
||||
|
||||
#ifdef HAVE_BTSTACK_STDIN
|
||||
static uint16_t remote_configuration_bitmap;
|
||||
static avdtp_capabilities_t remote_configuration;
|
||||
@ -1049,20 +1052,11 @@ int btstack_main(int argc, const char * argv[]){
|
||||
|
||||
l2cap_init();
|
||||
// Initialize AVDTP Sink
|
||||
avdtp_sink_init();
|
||||
avdtp_sink_register_packet_handler(&packet_handler);
|
||||
a2dp_sink_init();
|
||||
a2dp_sink_register_packet_handler(&packet_handler);
|
||||
a2dp_sink_register_media_handler(&handle_l2cap_media_data_packet);
|
||||
|
||||
//#ifndef SMG_BI
|
||||
local_stream_endpoint = avdtp_sink_create_stream_endpoint(AVDTP_SINK, AVDTP_AUDIO);
|
||||
local_stream_endpoint->sep.seid = 1;
|
||||
avdtp_sink_register_media_transport_category(local_stream_endpoint->sep.seid);
|
||||
avdtp_sink_register_media_codec_category(local_stream_endpoint->sep.seid, AVDTP_AUDIO, AVDTP_CODEC_SBC, media_sbc_codec_capabilities, sizeof(media_sbc_codec_capabilities));
|
||||
//#endif
|
||||
// uint8_t cp_type_lsb, uint8_t cp_type_msb, const uint8_t * cp_type_value, uint8_t cp_type_value_len
|
||||
// avdtp_sink_register_content_protection_category(seid, 2, 2, NULL, 0);
|
||||
|
||||
avdtp_sink_register_media_handler(&handle_l2cap_media_data_packet);
|
||||
printf("reistered media handler\n");
|
||||
local_seid = 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));
|
||||
|
||||
// Initialize AVRCP COntroller
|
||||
avrcp_controller_init();
|
||||
|
@ -176,6 +176,8 @@ static uint16_t avdtp_cid = 0;
|
||||
static uint8_t sdp_avdtp_sink_service_buffer[150];
|
||||
static avdtp_sep_t sep;
|
||||
|
||||
static avdtp_context_t adtvp_sink_context;
|
||||
|
||||
static adtvp_media_codec_information_sbc_t sbc_capability;
|
||||
static avdtp_media_codec_configuration_sbc_t sbc_configuration;
|
||||
static avdtp_stream_endpoint_t * local_stream_endpoint;
|
||||
@ -788,7 +790,7 @@ int btstack_main(int argc, const char * argv[]){
|
||||
|
||||
l2cap_init();
|
||||
// Initialize AVDTP Sink
|
||||
avdtp_sink_init();
|
||||
avdtp_sink_init(&adtvp_sink_context);
|
||||
avdtp_sink_register_packet_handler(&packet_handler);
|
||||
|
||||
//#ifndef SMG_BI
|
||||
|
@ -168,7 +168,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
media_tracker.a2dp_cid, media_tracker.local_seid, a2dp_subevent_stream_established_get_remote_seid(packet));
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_START_ACCEPTED:
|
||||
case A2DP_SUBEVENT_STREAM_STARTED:
|
||||
if (local_seid != media_tracker.local_seid) break;
|
||||
if (!a2dp_source_stream_endpoint_ready(media_tracker.local_seid)) break;
|
||||
a2dp_fill_audio_buffer_timer_start(&media_tracker);
|
||||
@ -386,11 +386,10 @@ int btstack_main(int argc, const char * argv[]){
|
||||
hci_add_event_handler(&hci_event_callback_registration);
|
||||
|
||||
l2cap_init();
|
||||
// Initialize AVDTP Sink
|
||||
// Initialize AVDTP Source
|
||||
a2dp_source_init();
|
||||
a2dp_source_register_packet_handler(&packet_handler);
|
||||
|
||||
//#ifndef SMG_BI
|
||||
local_seid = a2dp_source_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));
|
||||
|
||||
// Initialize SDP
|
||||
|
@ -1262,7 +1262,7 @@ typedef uint8_t sm_key_t[16];
|
||||
/** AVDTP Subevent */
|
||||
|
||||
/**
|
||||
* @format 1H111
|
||||
* @format 12111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1272,7 +1272,7 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_ACCEPT 0x01
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1281,7 +1281,7 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_REJECT 0x02
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1290,7 +1290,7 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT 0x03
|
||||
|
||||
/**
|
||||
* @format 1HB1
|
||||
* @format 12B1
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param bd_addr
|
||||
@ -1299,14 +1299,14 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED 0x04
|
||||
|
||||
/**
|
||||
* @format 1H
|
||||
* @format 12
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
*/
|
||||
#define AVDTP_SUBEVENT_SIGNALING_CONNECTION_RELEASED 0x05
|
||||
|
||||
/**
|
||||
* @format 1H1111
|
||||
* @format 121111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param seid 0x01 – 0x3E
|
||||
@ -1317,7 +1317,7 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_SEP_FOUND 0x06
|
||||
|
||||
/**
|
||||
* @format 1H1111111111
|
||||
* @format 121111111111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1334,7 +1334,7 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY 0x07
|
||||
|
||||
/**
|
||||
* @format 1H1112LV
|
||||
* @format 121112LV
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1347,7 +1347,7 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY 0x08
|
||||
|
||||
/**
|
||||
* @format 1H111121111111
|
||||
* @format 12111121111111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1366,7 +1366,7 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION 0x09
|
||||
|
||||
/**
|
||||
* @format 1H11112LV
|
||||
* @format 1211112LV
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1380,7 +1380,7 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION 0x0A
|
||||
|
||||
/**
|
||||
* @format 1H111
|
||||
* @format 12111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1390,14 +1390,14 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED 0x0B
|
||||
|
||||
/**
|
||||
* @format 1H
|
||||
* @format 12
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
*/
|
||||
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED 0x0C
|
||||
|
||||
/**
|
||||
* @format 1H12
|
||||
* @format 1212
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
@ -1407,48 +1407,60 @@ typedef uint8_t sm_key_t[16];
|
||||
|
||||
|
||||
/** A2DP Subevent */
|
||||
/* Stream goes through following states:
|
||||
* - OPEN - indicated with A2DP_SUBEVENT_STREAM_ESTABLISHED event
|
||||
* - START - indicated with A2DP_SUBEVENT_STREAM_STARTED event
|
||||
* - SUSPEND - indicated with A2DP_SUBEVENT_STREAM_SUSPENDED event
|
||||
* - ABORT/STOP - indicated with A2DP_SUBEVENT_STREAM_RELEASED event
|
||||
|
||||
OPEN state will be followed by ABORT/STOP. Stream is ready but media transfer is not started.
|
||||
START can come only after the stream is OPENED, and indicates that media transfer is started.
|
||||
SUSPEND is optional, it pauses the stream.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @format 1H111
|
||||
* @format 121 Sent only by A2DP source.
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param local_seid
|
||||
*/
|
||||
#define A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW 0x01
|
||||
|
||||
/**
|
||||
* @format 12111 Stream is opened byt not started.
|
||||
* @param subevent_code
|
||||
* @param a2dp_cid
|
||||
* @param local_seid
|
||||
* @param remote_seid
|
||||
* @param status
|
||||
*/
|
||||
#define A2DP_SUBEVENT_STREAM_ESTABLISHED 0x01
|
||||
#define A2DP_SUBEVENT_STREAM_ESTABLISHED 0x02
|
||||
|
||||
/**
|
||||
* @format 1H1
|
||||
* @format 121 Indicates that media transfer is started.
|
||||
* @param subevent_code
|
||||
* @param a2dp_cid
|
||||
* @param local_seid
|
||||
*/
|
||||
#define A2DP_SUBEVENT_STREAM_START_ACCEPTED 0x02
|
||||
#define A2DP_SUBEVENT_STREAM_STARTED 0x03
|
||||
|
||||
/**
|
||||
* @format 1H1
|
||||
* @format 121 Stream is paused.
|
||||
* @param subevent_code
|
||||
* @param a2dp_cid
|
||||
* @param local_seid
|
||||
*/
|
||||
#define A2DP_SUBEVENT_STREAM_SUSPENDED 0x03
|
||||
#define A2DP_SUBEVENT_STREAM_SUSPENDED 0x04
|
||||
|
||||
/**
|
||||
* @format 1H1
|
||||
* @format 121 Stream is released.
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param local_seid
|
||||
*/
|
||||
#define A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW 0x04
|
||||
#define A2DP_SUBEVENT_STREAM_RELEASED 0x05
|
||||
|
||||
|
||||
/**
|
||||
* @format 1H1
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param local_seid
|
||||
*/
|
||||
#define A2DP_SUBEVENT_STREAM_RELEASED 0x05
|
||||
|
||||
/** AVRCP Subevent */
|
||||
|
||||
|
@ -3983,9 +3983,9 @@ static inline hci_con_handle_t ancs_subevent_client_disconnected_get_handle(cons
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_ACCEPT
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_accept_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_accept_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4020,9 +4020,9 @@ static inline uint8_t avdtp_subevent_signaling_accept_get_status(const uint8_t *
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_REJECT
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_reject_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_reject_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4048,9 +4048,9 @@ static inline uint8_t avdtp_subevent_signaling_reject_get_signal_identifier(cons
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_general_reject_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_general_reject_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4076,9 +4076,9 @@ static inline uint8_t avdtp_subevent_signaling_general_reject_get_signal_identif
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_connection_established_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_connection_established_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4104,9 +4104,9 @@ static inline uint8_t avdtp_subevent_signaling_connection_established_get_status
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_CONNECTION_RELEASED
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_connection_released_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_connection_released_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
|
||||
@ -4114,9 +4114,9 @@ static inline hci_con_handle_t avdtp_subevent_signaling_connection_released_get_
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_SEP_FOUND
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_sep_found_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_sep_found_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4160,9 +4160,9 @@ static inline uint8_t avdtp_subevent_signaling_sep_found_get_sep_type(const uint
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_media_codec_sbc_capability_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_media_codec_sbc_capability_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4260,9 +4260,9 @@ static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_capability_get_ma
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_media_codec_other_capability_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_media_codec_other_capability_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4324,9 +4324,9 @@ static inline const uint8_t * avdtp_subevent_signaling_media_codec_other_capabil
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_media_codec_sbc_configuration_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_media_codec_sbc_configuration_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4442,9 +4442,9 @@ static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_configuration_get
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_signaling_media_codec_other_configuration_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_signaling_media_codec_other_configuration_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4515,9 +4515,9 @@ static inline const uint8_t * avdtp_subevent_signaling_media_codec_other_configu
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_streaming_connection_established_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_streaming_connection_established_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4552,9 +4552,9 @@ static inline uint8_t avdtp_subevent_streaming_connection_established_get_status
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_STREAMING_CONNECTION_RELEASED
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_streaming_connection_released_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_streaming_connection_released_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
|
||||
@ -4562,9 +4562,9 @@ static inline hci_con_handle_t avdtp_subevent_streaming_connection_released_get_
|
||||
* @brief Get field avdtp_cid from event AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avdtp_subevent_streaming_can_send_media_packet_now_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t avdtp_subevent_streaming_can_send_media_packet_now_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4586,13 +4586,32 @@ 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 A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline uint16_t a2dp_subevent_streaming_can_send_media_packet_now_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field local_seid from event A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW
|
||||
* @param event packet
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t a2dp_subevent_streaming_can_send_media_packet_now_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field a2dp_cid from event A2DP_SUBEVENT_STREAM_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return a2dp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t a2dp_subevent_stream_established_get_a2dp_cid(const uint8_t * event){
|
||||
static inline uint16_t a2dp_subevent_stream_established_get_a2dp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4624,21 +4643,21 @@ static inline uint8_t a2dp_subevent_stream_established_get_status(const uint8_t
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field a2dp_cid from event A2DP_SUBEVENT_STREAM_START_ACCEPTED
|
||||
* @brief Get field a2dp_cid from event A2DP_SUBEVENT_STREAM_STARTED
|
||||
* @param event packet
|
||||
* @return a2dp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t a2dp_subevent_stream_start_accepted_get_a2dp_cid(const uint8_t * event){
|
||||
static inline uint16_t a2dp_subevent_stream_started_get_a2dp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field local_seid from event A2DP_SUBEVENT_STREAM_START_ACCEPTED
|
||||
* @brief Get field local_seid from event A2DP_SUBEVENT_STREAM_STARTED
|
||||
* @param event packet
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t a2dp_subevent_stream_start_accepted_get_local_seid(const uint8_t * event){
|
||||
static inline uint8_t a2dp_subevent_stream_started_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
|
||||
@ -4646,9 +4665,9 @@ static inline uint8_t a2dp_subevent_stream_start_accepted_get_local_seid(const u
|
||||
* @brief Get field a2dp_cid from event A2DP_SUBEVENT_STREAM_SUSPENDED
|
||||
* @param event packet
|
||||
* @return a2dp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t a2dp_subevent_stream_suspended_get_a2dp_cid(const uint8_t * event){
|
||||
static inline uint16_t a2dp_subevent_stream_suspended_get_a2dp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4661,32 +4680,13 @@ static inline uint8_t a2dp_subevent_stream_suspended_get_local_seid(const uint8_
|
||||
return event[5];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field avdtp_cid from event A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
*/
|
||||
static inline hci_con_handle_t a2dp_subevent_streaming_can_send_media_packet_now_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field local_seid from event A2DP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW
|
||||
* @param event packet
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t a2dp_subevent_streaming_can_send_media_packet_now_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field avdtp_cid from event A2DP_SUBEVENT_STREAM_RELEASED
|
||||
* @param event packet
|
||||
* @return avdtp_cid
|
||||
* @note: btstack_type H
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t a2dp_subevent_stream_released_get_avdtp_cid(const uint8_t * event){
|
||||
static inline uint16_t a2dp_subevent_stream_released_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
|
@ -51,7 +51,14 @@
|
||||
static const char * default_a2dp_sink_service_name = "BTstack A2DP Sink Service";
|
||||
static const char * default_a2dp_sink_service_provider_name = "BTstack A2DP Sink Service Provider";
|
||||
|
||||
// static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
static avdtp_context_t a2dp_sink_context;
|
||||
|
||||
static a2dp_state_t app_state = A2DP_IDLE;
|
||||
static avdtp_stream_endpoint_context_t sc;
|
||||
static uint16_t avdtp_cid = 0;
|
||||
// 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);
|
||||
|
||||
void a2dp_sink_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t supported_features, const char * service_name, const char * service_provider_name){
|
||||
uint8_t* attribute;
|
||||
@ -131,3 +138,149 @@ void a2dp_sink_create_sdp_record(uint8_t * service, uint32_t service_record_han
|
||||
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311);
|
||||
de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
|
||||
}
|
||||
|
||||
void a2dp_sink_register_packet_handler(btstack_packet_handler_t callback){
|
||||
avdtp_sink_register_packet_handler(callback);
|
||||
return;
|
||||
if (callback == NULL){
|
||||
log_error("a2dp_sink_register_packet_handler called with NULL callback");
|
||||
return;
|
||||
}
|
||||
avdtp_sink_register_packet_handler(&packet_handler);
|
||||
a2dp_sink_context.a2dp_callback = callback;
|
||||
}
|
||||
|
||||
void a2dp_sink_register_media_handler(void (*callback)(avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size)){
|
||||
if (callback == NULL){
|
||||
log_error("a2dp_sink_register_media_handler called with NULL callback");
|
||||
return;
|
||||
}
|
||||
avdtp_sink_register_media_handler(callback);
|
||||
}
|
||||
|
||||
void a2dp_sink_init(void){
|
||||
avdtp_sink_init(&a2dp_sink_context);
|
||||
l2cap_register_service(&packet_handler, BLUETOOTH_PROTOCOL_AVDTP, 0xffff, LEVEL_0);
|
||||
}
|
||||
|
||||
uint8_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){
|
||||
avdtp_stream_endpoint_t * local_stream_endpoint = avdtp_sink_create_stream_endpoint(AVDTP_SINK, media_type);
|
||||
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 local_stream_endpoint->sep.seid;
|
||||
}
|
||||
|
||||
void a2dp_sink_establish_stream(bd_addr_t bd_addr, uint8_t local_seid){
|
||||
sc.local_stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_sink_context);
|
||||
if (!sc.local_stream_endpoint){
|
||||
log_error(" no local_stream_endpoint for seid %d", local_seid);
|
||||
return;
|
||||
}
|
||||
avdtp_sink_connect(bd_addr);
|
||||
}
|
||||
|
||||
void a2dp_sink_disconnect(uint16_t a2dp_cid){
|
||||
avdtp_disconnect(a2dp_cid, &a2dp_sink_context);
|
||||
}
|
||||
|
||||
|
||||
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
|
||||
UNUSED(channel);
|
||||
UNUSED(size);
|
||||
|
||||
bd_addr_t event_addr;
|
||||
switch (packet_type) {
|
||||
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (hci_event_packet_get_type(packet)) {
|
||||
case HCI_EVENT_PIN_CODE_REQUEST:
|
||||
// inform about pin code request
|
||||
printf("Pin code request - using '0000'\n");
|
||||
hci_event_pin_code_request_get_bd_addr(packet, event_addr);
|
||||
hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
|
||||
break;
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
// connection closed -> quit test app
|
||||
app_state = A2DP_IDLE;
|
||||
printf("\n --- avdtp_test: HCI_EVENT_DISCONNECTION_COMPLETE ---\n");
|
||||
break;
|
||||
case HCI_EVENT_AVDTP_META:
|
||||
switch (packet[2]){
|
||||
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
|
||||
app_state = A2DP_CONNECTED;
|
||||
avdtp_cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
|
||||
printf("\n --- avdtp_test: AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, cid 0x%02x ---\n", avdtp_cid);
|
||||
break;
|
||||
case AVDTP_SUBEVENT_SIGNALING_SEP_FOUND:
|
||||
if (app_state < A2DP_CONNECTED) return;
|
||||
// sep.seid = avdtp_subevent_signaling_sep_found_get_seid(packet);
|
||||
// sep.in_use = avdtp_subevent_signaling_sep_found_get_in_use(packet);
|
||||
// sep.media_type = avdtp_subevent_signaling_sep_found_get_media_type(packet);
|
||||
// sep.type = avdtp_subevent_signaling_sep_found_get_sep_type(packet);
|
||||
// printf("Found sep: seid %u, in_use %d, media type %d, sep type %d (1-SNK)\n", sep.seid, sep.in_use, sep.media_type, sep.type);
|
||||
break;
|
||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY:
|
||||
if (app_state < A2DP_CONNECTED) return;
|
||||
// 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_CODEC_SBC_CONFIGURATION:{
|
||||
if (app_state < A2DP_CONNECTED) return;
|
||||
// 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);
|
||||
// // // TODO: use actual config
|
||||
// btstack_sbc_encoder_init(&local_stream_endpoint->sbc_encoder_state, SBC_MODE_STANDARD, 16, 8, 2, 44100, 53);
|
||||
|
||||
// if (sbc_configuration.reconfigure){
|
||||
// media_processing_close();
|
||||
// media_processing_init(sbc_configuration);
|
||||
// } else {
|
||||
// media_processing_init(sbc_configuration);
|
||||
// }
|
||||
break;
|
||||
}
|
||||
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
|
||||
app_state = A2DP_STREAMING_OPENED;
|
||||
break;
|
||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY:
|
||||
printf(" received non SBC codec. not implemented\n");
|
||||
break;
|
||||
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
||||
break;
|
||||
default:
|
||||
printf(" not implemented\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// other packet type
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,14 +58,63 @@ extern "C" {
|
||||
* @brief A2DP Sink service record.
|
||||
* @param service
|
||||
* @param service_record_handle
|
||||
* @param supported_features 16-bit bitmap, see AVDTP_SINK_SF_* values in avdtp.h
|
||||
* @param supported_features 16-bit bitmap, see a2dp_SINK_SF_* values in avdtp.h
|
||||
* @param service_name
|
||||
* @param service_provider_name
|
||||
*/
|
||||
void a2dp_sink_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t supported_features, const char * service_name, const char * service_provider_name);
|
||||
|
||||
/**
|
||||
* @brief Set up A2DP Sink device.
|
||||
*/
|
||||
void a2dp_sink_init(void);
|
||||
|
||||
uint8_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);
|
||||
|
||||
/**
|
||||
* @brief Register callback for the A2DP Sink client.
|
||||
* @param callback
|
||||
*/
|
||||
void a2dp_sink_register_packet_handler(btstack_packet_handler_t callback);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register media handler for the A2DP Sink client.
|
||||
* @param callback
|
||||
*/
|
||||
void a2dp_sink_register_media_handler(void (*callback)(avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size));
|
||||
|
||||
/**
|
||||
* @brief Open stream
|
||||
* @param avdtp_cid
|
||||
* @param local_seid
|
||||
*/
|
||||
void a2dp_sink_establish_stream(bd_addr_t bd_addr, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Start stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void a2dp_sink_start_stream(uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Suspend stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void a2dp_sink_pause(uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Abort stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void a2dp_sink_stop_stream(uint8_t local_seid);
|
||||
|
||||
void a2dp_sink_disconnect(uint16_t a2dp_cid);
|
||||
/* API_END */
|
||||
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -49,35 +49,12 @@
|
||||
#include "avdtp_source.h"
|
||||
#include "a2dp_source.h"
|
||||
|
||||
#define AVDTP_MEDIA_PAYLOAD_HEADER_SIZE 12
|
||||
|
||||
static const char * default_a2dp_source_service_name = "BTstack A2DP Source Service";
|
||||
static const char * default_a2dp_source_service_provider_name = "BTstack A2DP Source Service Provider";
|
||||
static avdtp_context_t a2dp_source_context;
|
||||
|
||||
#define AVDTP_MEDIA_PAYLOAD_HEADER_SIZE 12
|
||||
|
||||
typedef struct {
|
||||
// to app
|
||||
uint32_t fill_audio_ring_buffer_timeout_ms;
|
||||
uint32_t time_audio_data_sent; // ms
|
||||
uint32_t acc_num_missed_samples;
|
||||
uint32_t samples_ready;
|
||||
btstack_timer_source_t fill_audio_ring_buffer_timer;
|
||||
btstack_ring_buffer_t sbc_ring_buffer;
|
||||
btstack_sbc_encoder_state_t sbc_encoder_state;
|
||||
|
||||
int reconfigure;
|
||||
int num_channels;
|
||||
int sampling_frequency;
|
||||
int channel_mode;
|
||||
int block_length;
|
||||
int subbands;
|
||||
int allocation_method;
|
||||
int min_bitpool_value;
|
||||
int max_bitpool_value;
|
||||
avdtp_stream_endpoint_t * local_stream_endpoint;
|
||||
avdtp_sep_t * active_remote_sep;
|
||||
} avdtp_stream_endpoint_context_t;
|
||||
|
||||
static a2dp_state_t app_state = A2DP_IDLE;
|
||||
static avdtp_stream_endpoint_context_t sc;
|
||||
static uint16_t avdtp_cid = 0;
|
||||
@ -340,26 +317,13 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_A2DP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = A2DP_SUBEVENT_STREAM_START_ACCEPTED;
|
||||
event[pos++] = A2DP_SUBEVENT_STREAM_STARTED;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
||||
(*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
break;
|
||||
}
|
||||
case AVDTP_SI_CLOSE:{
|
||||
uint8_t event[6];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_A2DP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = A2DP_SUBEVENT_STREAM_RELEASED;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
log_info("send A2DP_SUBEVENT_STREAM_RELEASED to app");
|
||||
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
||||
(*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
break;
|
||||
}
|
||||
case AVDTP_SI_SUSPEND:{
|
||||
uint8_t event[6];
|
||||
int pos = 0;
|
||||
@ -372,6 +336,20 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
(*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
break;
|
||||
}
|
||||
case AVDTP_SI_ABORT:
|
||||
case AVDTP_SI_CLOSE:{
|
||||
uint8_t event[6];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_A2DP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = A2DP_SUBEVENT_STREAM_RELEASED;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
log_info("send A2DP_SUBEVENT_STREAM_RELEASED to app");
|
||||
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
||||
(*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -443,8 +421,8 @@ void a2dp_source_establish_stream(bd_addr_t bd_addr, uint8_t local_seid){
|
||||
avdtp_source_connect(bd_addr);
|
||||
}
|
||||
|
||||
void a2dp_source_disconnect(uint16_t con_handle){
|
||||
avdtp_disconnect(con_handle, &a2dp_source_context);
|
||||
void a2dp_source_disconnect(uint16_t local_seid){
|
||||
avdtp_disconnect(local_seid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
void a2dp_source_start_stream(uint8_t int_seid){
|
||||
|
@ -101,7 +101,7 @@ void a2dp_source_pause_stream(uint8_t int_seid);
|
||||
void a2dp_source_release_stream(uint8_t int_seid);
|
||||
|
||||
/**
|
||||
* @brief Disconnect from device with connection handle.
|
||||
* @brief Disconnect from device with cid.
|
||||
* @param avdtp_cid
|
||||
*/
|
||||
void a2dp_source_disconnect(uint16_t avdtp_cid);
|
||||
|
@ -339,7 +339,7 @@ static void avdtp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c
|
||||
case BLUETOOTH_SERVICE_CLASS_AUDIO_SOURCE:
|
||||
if (sdp_query_context.query_role != AVDTP_SOURCE) {
|
||||
sdp_query_context.connection->state = AVDTP_SIGNALING_CONNECTION_IDLE;
|
||||
avdtp_signaling_emit_connection_established(sdp_query_context.avdtp_callback, sdp_query_context.connection->l2cap_signaling_cid, sdp_query_context.connection->remote_addr, 0);
|
||||
avdtp_signaling_emit_connection_established(sdp_query_context.avdtp_callback, sdp_query_context.connection->l2cap_signaling_cid, sdp_query_context.connection->remote_addr, SDP_SERVICE_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
// log_info("SDP Attribute 0x%04x: AVDTP SOURCE protocol UUID: 0x%04x", sdp_event_query_attribute_byte_get_attribute_id(packet), uuid);
|
||||
@ -348,7 +348,7 @@ static void avdtp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c
|
||||
case BLUETOOTH_SERVICE_CLASS_AUDIO_SINK:
|
||||
if (sdp_query_context.query_role != AVDTP_SINK) {
|
||||
sdp_query_context.connection->state = AVDTP_SIGNALING_CONNECTION_IDLE;
|
||||
avdtp_signaling_emit_connection_established(sdp_query_context.avdtp_callback, sdp_query_context.connection->l2cap_signaling_cid, sdp_query_context.connection->remote_addr, 0);
|
||||
avdtp_signaling_emit_connection_established(sdp_query_context.avdtp_callback, sdp_query_context.connection->l2cap_signaling_cid, sdp_query_context.connection->remote_addr, SDP_SERVICE_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
// log_info("SDP Attribute 0x%04x: AVDTP SINK protocol UUID: 0x%04x", sdp_event_query_attribute_byte_get_attribute_id(packet), uuid);
|
||||
@ -498,7 +498,9 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
case L2CAP_EVENT_CHANNEL_OPENED:
|
||||
// inform about new l2cap connection
|
||||
l2cap_event_channel_opened_get_address(packet, event_addr);
|
||||
local_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||
if (l2cap_event_channel_opened_get_status(packet)){
|
||||
avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->l2cap_signaling_cid, event_addr, l2cap_event_channel_opened_get_status(packet));
|
||||
log_error("L2CAP connection to connection %s failed. status code 0x%02x",
|
||||
bd_addr_to_str(event_addr), l2cap_event_channel_opened_get_status(packet));
|
||||
break;
|
||||
@ -510,7 +512,6 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
}
|
||||
|
||||
con_handle = l2cap_event_channel_opened_get_handle(packet);
|
||||
local_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||
|
||||
log_info("L2CAP_EVENT_CHANNEL_OPENED: Channel successfully opened: %s, handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x",
|
||||
bd_addr_to_str(event_addr), con_handle, psm, local_cid, l2cap_event_channel_opened_get_remote_cid(packet));
|
||||
|
@ -470,6 +470,29 @@ typedef struct avdtp_stream_endpoint {
|
||||
uint16_t sequence_number;
|
||||
} avdtp_stream_endpoint_t;
|
||||
|
||||
typedef struct {
|
||||
// to app
|
||||
uint32_t fill_audio_ring_buffer_timeout_ms;
|
||||
uint32_t time_audio_data_sent; // ms
|
||||
uint32_t acc_num_missed_samples;
|
||||
uint32_t samples_ready;
|
||||
btstack_timer_source_t fill_audio_ring_buffer_timer;
|
||||
btstack_ring_buffer_t sbc_ring_buffer;
|
||||
btstack_sbc_encoder_state_t sbc_encoder_state;
|
||||
|
||||
int reconfigure;
|
||||
int num_channels;
|
||||
int sampling_frequency;
|
||||
int channel_mode;
|
||||
int block_length;
|
||||
int subbands;
|
||||
int allocation_method;
|
||||
int min_bitpool_value;
|
||||
int max_bitpool_value;
|
||||
avdtp_stream_endpoint_t * local_stream_endpoint;
|
||||
avdtp_sep_t * active_remote_sep;
|
||||
} avdtp_stream_endpoint_context_t;
|
||||
|
||||
typedef struct {
|
||||
btstack_linked_list_t connections;
|
||||
btstack_linked_list_t stream_endpoints;
|
||||
|
@ -49,47 +49,47 @@
|
||||
#include "avdtp_initiator.h"
|
||||
#include "avdtp_acceptor.h"
|
||||
|
||||
static avdtp_context_t avdtp_sink_context;
|
||||
static avdtp_context_t * avdtp_sink_context;
|
||||
|
||||
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
|
||||
void avdtp_sink_register_media_transport_category(uint8_t seid){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, &avdtp_sink_context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_sink_context);
|
||||
avdtp_register_media_transport_category(stream_endpoint);
|
||||
}
|
||||
|
||||
void avdtp_sink_register_reporting_category(uint8_t seid){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, &avdtp_sink_context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_sink_context);
|
||||
avdtp_register_reporting_category(stream_endpoint);
|
||||
}
|
||||
|
||||
void avdtp_sink_register_delay_reporting_category(uint8_t seid){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, &avdtp_sink_context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_sink_context);
|
||||
avdtp_register_delay_reporting_category(stream_endpoint);
|
||||
}
|
||||
|
||||
void avdtp_sink_register_recovery_category(uint8_t seid, uint8_t maximum_recovery_window_size, uint8_t maximum_number_media_packets){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, &avdtp_sink_context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_sink_context);
|
||||
avdtp_register_recovery_category(stream_endpoint, maximum_recovery_window_size, maximum_number_media_packets);
|
||||
}
|
||||
|
||||
void avdtp_sink_register_content_protection_category(uint8_t seid, uint16_t cp_type, const uint8_t * cp_type_value, uint8_t cp_type_value_len){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, &avdtp_sink_context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_sink_context);
|
||||
avdtp_register_content_protection_category(stream_endpoint, cp_type, cp_type_value, cp_type_value_len);
|
||||
}
|
||||
|
||||
void avdtp_sink_register_header_compression_category(uint8_t seid, uint8_t back_ch, uint8_t media, uint8_t recovery){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, &avdtp_sink_context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_sink_context);
|
||||
avdtp_register_header_compression_category(stream_endpoint, back_ch, media, recovery);
|
||||
}
|
||||
|
||||
void avdtp_sink_register_media_codec_category(uint8_t seid, avdtp_media_type_t media_type, avdtp_media_codec_type_t media_codec_type, uint8_t * media_codec_info, uint16_t media_codec_info_len){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, &avdtp_sink_context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_sink_context);
|
||||
avdtp_register_media_codec_category(stream_endpoint, media_type, media_codec_type, media_codec_info, media_codec_info_len);
|
||||
}
|
||||
|
||||
void avdtp_sink_register_multiplexing_category(uint8_t seid, uint8_t fragmentation){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, &avdtp_sink_context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(seid, avdtp_sink_context);
|
||||
avdtp_register_multiplexing_category(stream_endpoint, fragmentation);
|
||||
}
|
||||
|
||||
@ -103,21 +103,26 @@ void avdtp_sink_register_multiplexing_category(uint8_t seid, uint8_t fragmentati
|
||||
// TODO remove
|
||||
|
||||
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
avdtp_packet_handler(packet_type, channel, packet, size, &avdtp_sink_context);
|
||||
avdtp_packet_handler(packet_type, channel, packet, size, avdtp_sink_context);
|
||||
}
|
||||
|
||||
// TODO: find out which security level is needed, and replace LEVEL_0 in avdtp_sink_init
|
||||
void avdtp_sink_init(void){
|
||||
avdtp_sink_context.stream_endpoints = NULL;
|
||||
avdtp_sink_context.connections = NULL;
|
||||
avdtp_sink_context.stream_endpoints_id_counter = 0;
|
||||
avdtp_sink_context.packet_handler = packet_handler;
|
||||
void avdtp_sink_init(avdtp_context_t * avdtp_context){
|
||||
if (!avdtp_context){
|
||||
log_error("avdtp_source_context is NULL");
|
||||
return;
|
||||
}
|
||||
avdtp_sink_context = avdtp_context;
|
||||
avdtp_sink_context->stream_endpoints = NULL;
|
||||
avdtp_sink_context->connections = NULL;
|
||||
avdtp_sink_context->stream_endpoints_id_counter = 0;
|
||||
avdtp_sink_context->packet_handler = packet_handler;
|
||||
|
||||
l2cap_register_service(&packet_handler, BLUETOOTH_PROTOCOL_AVDTP, 0xffff, LEVEL_0);
|
||||
}
|
||||
|
||||
avdtp_stream_endpoint_t * avdtp_sink_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type){
|
||||
return avdtp_create_stream_endpoint(sep_type, media_type, &avdtp_sink_context);
|
||||
return avdtp_create_stream_endpoint(sep_type, media_type, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_register_media_handler(void (*callback)(avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size)){
|
||||
@ -125,7 +130,7 @@ void avdtp_sink_register_media_handler(void (*callback)(avdtp_stream_endpoint_t
|
||||
log_error("avdtp_sink_register_media_handler called with NULL callback");
|
||||
return;
|
||||
}
|
||||
avdtp_sink_context.handle_media_data = callback;
|
||||
avdtp_sink_context->handle_media_data = callback;
|
||||
}
|
||||
|
||||
void avdtp_sink_register_packet_handler(btstack_packet_handler_t callback){
|
||||
@ -133,58 +138,58 @@ void avdtp_sink_register_packet_handler(btstack_packet_handler_t callback){
|
||||
log_error("avdtp_sink_register_packet_handler called with NULL callback");
|
||||
return;
|
||||
}
|
||||
avdtp_sink_context.avdtp_callback = callback;
|
||||
avdtp_sink_context->avdtp_callback = callback;
|
||||
}
|
||||
|
||||
void avdtp_sink_connect(bd_addr_t remote){
|
||||
avdtp_connect(remote, AVDTP_SOURCE, &avdtp_sink_context);
|
||||
avdtp_connect(remote, AVDTP_SOURCE, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_disconnect(uint16_t avdtp_cid){
|
||||
avdtp_disconnect(avdtp_cid, &avdtp_sink_context);
|
||||
avdtp_disconnect(avdtp_cid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid){
|
||||
avdtp_open_stream(avdtp_cid, int_seid, acp_seid, &avdtp_sink_context);
|
||||
avdtp_open_stream(avdtp_cid, int_seid, acp_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_start_stream(uint8_t int_seid){
|
||||
avdtp_start_stream(int_seid, &avdtp_sink_context);
|
||||
avdtp_start_stream(int_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_stop_stream(uint8_t int_seid){
|
||||
avdtp_stop_stream(int_seid, &avdtp_sink_context);
|
||||
avdtp_stop_stream(int_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_abort_stream(uint8_t int_seid){
|
||||
avdtp_abort_stream(int_seid, &avdtp_sink_context);
|
||||
avdtp_abort_stream(int_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_suspend(uint8_t int_seid){
|
||||
avdtp_suspend_stream(int_seid, &avdtp_sink_context);
|
||||
avdtp_suspend_stream(int_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_discover_stream_endpoints(uint16_t avdtp_cid){
|
||||
avdtp_discover_stream_endpoints(avdtp_cid, &avdtp_sink_context);
|
||||
avdtp_discover_stream_endpoints(avdtp_cid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_get_capabilities(uint16_t avdtp_cid, uint8_t acp_seid){
|
||||
avdtp_get_capabilities(avdtp_cid, acp_seid, &avdtp_sink_context);
|
||||
avdtp_get_capabilities(avdtp_cid, acp_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_get_all_capabilities(uint16_t avdtp_cid, uint8_t acp_seid){
|
||||
avdtp_get_all_capabilities(avdtp_cid, acp_seid, &avdtp_sink_context);
|
||||
avdtp_get_all_capabilities(avdtp_cid, acp_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid){
|
||||
avdtp_get_configuration(avdtp_cid, acp_seid, &avdtp_sink_context);
|
||||
avdtp_get_configuration(avdtp_cid, acp_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_set_configuration(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){
|
||||
avdtp_set_configuration(avdtp_cid, int_seid, acp_seid, configured_services_bitmap, configuration, &avdtp_sink_context);
|
||||
avdtp_set_configuration(avdtp_cid, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){
|
||||
avdtp_reconfigure(avdtp_cid, int_seid, acp_seid, configured_services_bitmap, configuration, &avdtp_sink_context);
|
||||
avdtp_reconfigure(avdtp_cid, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_sink_context);
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ extern "C" {
|
||||
/**
|
||||
* @brief Set up AVDTP Sink device.
|
||||
*/
|
||||
void avdtp_sink_init(void);
|
||||
void avdtp_sink_init(avdtp_context_t * avdtp_context);
|
||||
|
||||
// returns avdtp_stream_endpoint_t *
|
||||
avdtp_stream_endpoint_t * avdtp_sink_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type);
|
||||
|
Loading…
x
Reference in New Issue
Block a user