a2dp sink: start extracting code from demo to a2dp layer

This commit is contained in:
Milanka Ringwald 2017-07-07 14:09:31 +02:00
parent de804f9e40
commit 7050d2ca52
13 changed files with 398 additions and 182 deletions

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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);
}
/**

View File

@ -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;
}
}

View File

@ -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

View File

@ -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){

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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);
}

View File

@ -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);