mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-26 03:35:20 +00:00
avdtp: introduced avdtp cid on connect; cmd functions return now status; use local and remote sedi in events instead of initiator and acceptor seid
This commit is contained in:
parent
f39cc24ddf
commit
4ccacc40ad
@ -169,9 +169,10 @@ 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";
|
||||
// iPhone 5S:
|
||||
static const char * device_addr_string = "54:E4:3A:26:A2:39";
|
||||
// mac 2013:
|
||||
// mac 2013:
|
||||
static const char * device_addr_string = "84:38:35:65:d1:15";
|
||||
// iPhone 5S: static const char * device_addr_string = "54:E4:3A:26:A2:39";
|
||||
#endif
|
||||
|
||||
// bt dongle: -u 02-02 static bd_addr_t remote = {0x00, 0x02, 0x72, 0xDC, 0x31, 0xC1};
|
||||
@ -719,6 +720,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
UNUSED(channel);
|
||||
UNUSED(size);
|
||||
uint8_t status;
|
||||
uint16_t cid;
|
||||
|
||||
switch (packet_type) {
|
||||
case HCI_EVENT_PACKET:
|
||||
@ -750,60 +752,61 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
break;
|
||||
}
|
||||
case A2DP_SUBEVENT_STREAM_ESTABLISHED:
|
||||
cid = a2dp_subevent_stream_established_get_a2dp_cid(packet);
|
||||
if (cid != a2dp_cid) break;
|
||||
status = a2dp_subevent_stream_established_get_status(packet);
|
||||
if (status != 0){
|
||||
printf(" -- a2dp sink demo: streaming connection cannot be established, status 0x%02X\n", status);
|
||||
app_state = AVDTP_APPLICATION_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: check it it the correct a2dp cid
|
||||
a2dp_cid = a2dp_subevent_stream_established_get_a2dp_cid(packet);
|
||||
printf(" -- a2dp sink demo: streaming connection is established, a2dp cid 0x%02X\n", status);
|
||||
local_seid = a2dp_subevent_stream_established_get_local_seid(packet);
|
||||
printf(" -- a2dp sink demo: streaming connection is established, a2dp cid 0x%02X, local_seid %d\n", a2dp_cid, local_seid);
|
||||
app_state = AVDTP_APPLICATION_STREAMING;
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_STARTED:
|
||||
cid = a2dp_subevent_stream_started_get_a2dp_cid(packet);
|
||||
if (cid != a2dp_cid) break;
|
||||
status = a2dp_subevent_stream_started_get_status(packet);
|
||||
if (status != 0){
|
||||
printf(" -- a2dp sink demo: stream cannot be started, status 0x%02X\n", status);
|
||||
app_state = AVDTP_APPLICATION_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: check it it the correct a2dp cid
|
||||
a2dp_cid = a2dp_subevent_stream_started_get_a2dp_cid(packet);
|
||||
printf(" -- a2dp sink demo: streaming, a2dp cid 0x%02X\n", status);
|
||||
local_seid = a2dp_subevent_stream_started_get_local_seid(packet);
|
||||
printf(" -- a2dp sink demo: stream started, a2dp cid 0x%02X, local_seid %d\n", a2dp_cid, local_seid);
|
||||
|
||||
// started
|
||||
// media_processing_init(sbc_configuration);
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_SUSPENDED:
|
||||
cid = a2dp_subevent_stream_suspended_get_a2dp_cid(packet);
|
||||
if (cid != a2dp_cid) break;
|
||||
status = a2dp_subevent_stream_suspended_get_status(packet);
|
||||
if (status != 0){
|
||||
printf(" -- a2dp sink demo: stream cannot be paused, status 0x%02X\n", status);
|
||||
break;
|
||||
}
|
||||
// TODO: check it it the correct a2dp cid
|
||||
a2dp_cid = a2dp_subevent_stream_started_get_a2dp_cid(packet);
|
||||
printf(" -- a2dp sink demo: stream paused, a2dp cid 0x%02X\n", status);
|
||||
|
||||
local_seid = a2dp_subevent_stream_suspended_get_local_seid(packet);
|
||||
printf(" -- a2dp sink demo: stream paused, a2dp cid 0x%02X, local_seid %d\n", a2dp_cid, local_seid);
|
||||
|
||||
// paused/stopped
|
||||
// media_processing_close();
|
||||
break;
|
||||
break;
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_RELEASED:
|
||||
cid = a2dp_subevent_stream_released_get_a2dp_cid(packet);
|
||||
if (cid != a2dp_cid) break;
|
||||
status = a2dp_subevent_stream_released_get_status(packet);
|
||||
if (status != 0){
|
||||
printf(" -- a2dp sink demo: stream cannot be released, status 0x%02X\n", status);
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: check it it the correct a2dp cid
|
||||
a2dp_cid = a2dp_subevent_stream_released_get_a2dp_cid(packet);
|
||||
local_seid = a2dp_subevent_stream_released_get_local_seid(packet);
|
||||
app_state = AVDTP_APPLICATION_IDLE;
|
||||
printf(" -- a2dp sink demo: stream released, a2dp cid 0x%02X\n", status);
|
||||
printf(" -- a2dp sink demo: stream released, a2dp cid 0x%02X, local_seid %d\n", a2dp_cid, local_seid);
|
||||
|
||||
// paused/stopped
|
||||
media_processing_close();
|
||||
@ -881,7 +884,7 @@ static void stdin_process(char cmd){
|
||||
switch (cmd){
|
||||
case 'b':
|
||||
printf("Creating L2CAP Connection to %s, PSM_AVDTP\n", bd_addr_to_str(device_addr));
|
||||
a2dp_sink_establish_stream(device_addr, local_seid);
|
||||
a2dp_sink_establish_stream(device_addr, local_seid, &a2dp_cid);
|
||||
break;
|
||||
case 'B':
|
||||
printf("Disconnect\n");
|
||||
|
@ -174,11 +174,12 @@ static bd_addr_t remote = {0x84, 0x38, 0x35, 0x65, 0xd1, 0x15};
|
||||
|
||||
static uint16_t avdtp_cid = 0;
|
||||
static uint8_t sdp_avdtp_sink_service_buffer[150];
|
||||
static avdtp_sep_t sep;
|
||||
// static avdtp_sep_t sep;
|
||||
static uint8_t local_seid;
|
||||
static uint8_t remote_seid;
|
||||
|
||||
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;
|
||||
|
||||
@ -190,6 +191,7 @@ static avdtp_capabilities_t remote_configuration;
|
||||
typedef enum {
|
||||
AVDTP_APPLICATION_IDLE,
|
||||
AVDTP_APPLICATION_CONNECTED,
|
||||
AVDTP_APPLICATION_STREAM_ESTABLISHED,
|
||||
AVDTP_APPLICATION_STREAMING
|
||||
} avdtp_application_state_t;
|
||||
|
||||
@ -552,16 +554,6 @@ static void handle_l2cap_media_data_packet(avdtp_stream_endpoint_t * stream_endp
|
||||
#endif
|
||||
}
|
||||
|
||||
static void dump_sbc_capability(adtvp_media_codec_information_sbc_t media_codec_sbc){
|
||||
printf("Received media codec capability:\n");
|
||||
printf(" - sampling_frequency: 0x%02x\n", media_codec_sbc.sampling_frequency_bitmap);
|
||||
printf(" - channel_mode: 0x%02x\n", media_codec_sbc.channel_mode_bitmap);
|
||||
printf(" - block_length: 0x%02x\n", media_codec_sbc.block_length_bitmap);
|
||||
printf(" - subbands: 0x%02x\n", media_codec_sbc.subbands_bitmap);
|
||||
printf(" - allocation_method: 0x%02x\n", media_codec_sbc.allocation_method_bitmap);
|
||||
printf(" - bitpool_value [%d, %d] \n", media_codec_sbc.min_bitpool_value, media_codec_sbc.max_bitpool_value);
|
||||
}
|
||||
|
||||
static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t configuration){
|
||||
printf("Received media codec configuration:\n");
|
||||
printf(" - num_channels: %d\n", configuration.num_channels);
|
||||
@ -575,15 +567,17 @@ static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t configu
|
||||
|
||||
|
||||
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) {
|
||||
|
||||
uint16_t cid;
|
||||
uint8_t status;
|
||||
uint8_t seid;
|
||||
|
||||
switch (packet_type){
|
||||
case HCI_EVENT_PACKET:
|
||||
switch (hci_event_packet_get_type(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");
|
||||
@ -593,34 +587,16 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||
// connection closed -> quit test app
|
||||
app_state = AVDTP_APPLICATION_IDLE;
|
||||
printf("\n --- avdtp_test: HCI_EVENT_DISCONNECTION_COMPLETE ---\n");
|
||||
printf("\n --- AVDTP Sink Demo: HCI_EVENT_DISCONNECTION_COMPLETE ---\n");
|
||||
media_processing_close();
|
||||
break;
|
||||
case HCI_EVENT_AVDTP_META:
|
||||
switch (packet[2]){
|
||||
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
|
||||
cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
|
||||
if (cid != avdtp_cid) break;
|
||||
app_state = AVDTP_APPLICATION_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 < AVDTP_APPLICATION_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 < AVDTP_APPLICATION_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);
|
||||
printf("\n --- AVDTP Sink Demo: AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, cid 0x%02x ---\n", cid);
|
||||
break;
|
||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
|
||||
if (app_state < AVDTP_APPLICATION_CONNECTED) return;
|
||||
@ -646,16 +622,36 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
|
||||
app_state = AVDTP_APPLICATION_STREAMING;
|
||||
break;
|
||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY:
|
||||
printf(" received non SBC codec. not implemented\n");
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
||||
// signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||
// cid = avdtp_subevent_signaling_accept_get_avdtp_cid(packet);
|
||||
// loc_seid = avdtp_subevent_signaling_accept_get_local_seid(packet);
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY:
|
||||
printf("\n --- AVDTP Sink Demo: received non SBC codec. not implemented\n");
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
|
||||
status = avdtp_subevent_streaming_connection_established_get_status(packet);
|
||||
if (status){
|
||||
printf("\n --- AVDTP Sink Demo: Stream establish failed with status 0x%02x\n", status);
|
||||
break;
|
||||
}
|
||||
seid = avdtp_subevent_streaming_connection_established_get_local_seid(packet);
|
||||
if (seid != local_seid){
|
||||
printf("\n --- AVDTP Sink Demo:strema establich with wrong local seid, received %d, expected %d seid\n", seid, local_seid);
|
||||
break;
|
||||
}
|
||||
remote_seid = avdtp_subevent_streaming_connection_established_get_remote_seid(packet);
|
||||
app_state = AVDTP_APPLICATION_STREAMING;
|
||||
printf("\n --- AVDTP Sink Demo: Stream established \n");
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
printf(" not implemented\n");
|
||||
printf("\n --- AVDTP Sink Demo: not implemented %02x\n", packet[2]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -674,19 +670,21 @@ static void show_usage(void){
|
||||
bd_addr_t iut_address;
|
||||
gap_local_bd_addr(iut_address);
|
||||
printf("\n--- Bluetooth AVDTP SINK Test Console %s ---\n", bd_addr_to_str(iut_address));
|
||||
printf("c - create connection to addr %s\n", bd_addr_to_str(remote));
|
||||
printf("c - establish stream to addr %s\n", bd_addr_to_str(remote));
|
||||
printf("C - disconnect\n");
|
||||
printf("d - discover stream endpoints\n");
|
||||
printf("g - get capabilities\n");
|
||||
printf("a - get all capabilities\n");
|
||||
printf("s - set configuration\n");
|
||||
printf("f - get configuration\n");
|
||||
printf("R - reconfigure stream with %d\n", sep.seid);
|
||||
printf("o - open stream with seid %d\n", sep.seid);
|
||||
printf("m - start stream with %d\n", sep.seid);
|
||||
printf("A - abort stream with %d\n", sep.seid);
|
||||
printf("S - stop stream with %d\n", sep.seid);
|
||||
printf("P - suspend stream with %d\n", sep.seid);
|
||||
if (remote_seid){
|
||||
printf("R - reconfigure stream with %d\n", remote_seid);
|
||||
printf("o - open stream with seid %d\n", remote_seid);
|
||||
printf("m - start stream with %d\n", remote_seid);
|
||||
printf("A - abort stream with %d\n", remote_seid);
|
||||
printf("S - stop stream with %d\n", remote_seid);
|
||||
printf("P - suspend stream with %d\n", remote_seid);
|
||||
}
|
||||
printf("Ctrl-c - exit\n");
|
||||
printf("---\n");
|
||||
}
|
||||
@ -712,11 +710,11 @@ static uint8_t media_sbc_codec_reconfiguration[] = {
|
||||
};
|
||||
|
||||
static void stdin_process(char cmd){
|
||||
sep.seid = 1;
|
||||
uint8_t status = 0;
|
||||
switch (cmd){
|
||||
case 'c':
|
||||
printf("Creating L2CAP Connection to %s, BLUETOOTH_PROTOCOL_AVDTP\n", bd_addr_to_str(remote));
|
||||
avdtp_sink_connect(remote);
|
||||
avdtp_sink_connect(remote, &avdtp_cid);
|
||||
break;
|
||||
case 'C':
|
||||
printf("Disconnect\n");
|
||||
@ -726,13 +724,13 @@ static void stdin_process(char cmd){
|
||||
avdtp_sink_discover_stream_endpoints(avdtp_cid);
|
||||
break;
|
||||
case 'g':
|
||||
avdtp_sink_get_capabilities(avdtp_cid, sep.seid);
|
||||
avdtp_sink_get_capabilities(avdtp_cid, remote_seid);
|
||||
break;
|
||||
case 'a':
|
||||
avdtp_sink_get_all_capabilities(avdtp_cid, sep.seid);
|
||||
avdtp_sink_get_all_capabilities(avdtp_cid, remote_seid);
|
||||
break;
|
||||
case 'f':
|
||||
avdtp_sink_get_configuration(avdtp_cid, sep.seid);
|
||||
avdtp_sink_get_configuration(avdtp_cid, remote_seid);
|
||||
break;
|
||||
case 's':
|
||||
remote_configuration_bitmap = store_bit16(remote_configuration_bitmap, AVDTP_MEDIA_CODEC, 1);
|
||||
@ -740,7 +738,7 @@ static void stdin_process(char cmd){
|
||||
remote_configuration.media_codec.media_codec_type = AVDTP_CODEC_SBC;
|
||||
remote_configuration.media_codec.media_codec_information_len = sizeof(media_sbc_codec_configuration);
|
||||
remote_configuration.media_codec.media_codec_information = media_sbc_codec_configuration;
|
||||
avdtp_sink_set_configuration(avdtp_cid, local_stream_endpoint->sep.seid, sep.seid, remote_configuration_bitmap, remote_configuration);
|
||||
avdtp_sink_set_configuration(avdtp_cid, avdtp_local_seid(local_stream_endpoint), remote_seid, remote_configuration_bitmap, remote_configuration);
|
||||
break;
|
||||
case 'R':
|
||||
remote_configuration_bitmap = store_bit16(remote_configuration_bitmap, AVDTP_MEDIA_CODEC, 1);
|
||||
@ -748,22 +746,27 @@ static void stdin_process(char cmd){
|
||||
remote_configuration.media_codec.media_codec_type = AVDTP_CODEC_SBC;
|
||||
remote_configuration.media_codec.media_codec_information_len = sizeof(media_sbc_codec_reconfiguration);
|
||||
remote_configuration.media_codec.media_codec_information = media_sbc_codec_reconfiguration;
|
||||
avdtp_sink_reconfigure(avdtp_cid, local_stream_endpoint->sep.seid, sep.seid, remote_configuration_bitmap, remote_configuration);
|
||||
avdtp_sink_reconfigure(avdtp_cid, avdtp_local_seid(local_stream_endpoint), remote_seid, remote_configuration_bitmap, remote_configuration);
|
||||
break;
|
||||
case 'o':
|
||||
avdtp_sink_open_stream(avdtp_cid, local_stream_endpoint->sep.seid, sep.seid);
|
||||
printf("avdtp_sink_open_stream: cid %d, local seid %d, remote seid %d\n", avdtp_cid, avdtp_local_seid(local_stream_endpoint), remote_seid);
|
||||
status = avdtp_sink_open_stream(avdtp_cid, avdtp_local_seid(local_stream_endpoint), remote_seid);
|
||||
break;
|
||||
case 'm':
|
||||
avdtp_sink_start_stream(local_stream_endpoint->sep.seid);
|
||||
printf("avdtp_sink_start_stream: cid %d, local seid %d, remote seid %d\n", avdtp_cid, avdtp_local_seid(local_stream_endpoint), remote_seid);
|
||||
status = avdtp_sink_start_stream(avdtp_cid, avdtp_local_seid(local_stream_endpoint));
|
||||
break;
|
||||
case 'A':
|
||||
avdtp_sink_abort_stream(local_stream_endpoint->sep.seid);
|
||||
printf("avdtp_sink_abort_stream: cid %d, local seid %d, remote seid %d\n", avdtp_cid, avdtp_local_seid(local_stream_endpoint), remote_seid);
|
||||
status = avdtp_sink_abort_stream(avdtp_cid, avdtp_local_seid(local_stream_endpoint));
|
||||
break;
|
||||
case 'S':
|
||||
avdtp_sink_stop_stream(local_stream_endpoint->sep.seid);
|
||||
printf("avdtp_sink_stop_stream: cid %d, local seid %d, remote seid %d\n", avdtp_cid, avdtp_local_seid(local_stream_endpoint), remote_seid);
|
||||
status = avdtp_sink_stop_stream(avdtp_cid, avdtp_local_seid(local_stream_endpoint));
|
||||
break;
|
||||
case 'P':
|
||||
avdtp_sink_suspend(local_stream_endpoint->sep.seid);
|
||||
printf("avdtp_sink_suspend: cid %d, local seid %d, remote seid %d\n", avdtp_cid, avdtp_local_seid(local_stream_endpoint), remote_seid);
|
||||
status = avdtp_sink_suspend(avdtp_cid, avdtp_local_seid(local_stream_endpoint));
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
@ -774,6 +777,9 @@ static void stdin_process(char cmd){
|
||||
break;
|
||||
|
||||
}
|
||||
if (status != 0){
|
||||
printf("Command failed with status %d\n", status);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -795,9 +801,11 @@ int btstack_main(int argc, const char * argv[]){
|
||||
|
||||
//#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));
|
||||
local_stream_endpoint->sep.seid = 5;
|
||||
local_seid = local_stream_endpoint->sep.seid;
|
||||
|
||||
avdtp_sink_register_media_transport_category(avdtp_local_seid(local_stream_endpoint));
|
||||
avdtp_sink_register_media_codec_category(avdtp_local_seid(local_stream_endpoint), 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);
|
||||
|
@ -171,7 +171,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
|
||||
case A2DP_SUBEVENT_STREAM_STARTED:
|
||||
if (local_seid != media_tracker.local_seid) break;
|
||||
if (!a2dp_source_stream_endpoint_ready(media_tracker.local_seid)) break;
|
||||
if (!a2dp_source_stream_endpoint_ready(media_tracker.a2dp_cid, media_tracker.local_seid)) break;
|
||||
a2dp_fill_audio_buffer_timer_start(&media_tracker);
|
||||
printf(" --- application --- A2DP_SUBEVENT_STREAM_START_ACCEPTED, local seid %d\n", media_tracker.local_seid);
|
||||
break;
|
||||
@ -349,7 +349,7 @@ static void stdin_process(char cmd){
|
||||
switch (cmd){
|
||||
case 'c':
|
||||
printf("Creating L2CAP Connection to %s, PSM_AVDTP\n", bd_addr_to_str(remote));
|
||||
a2dp_source_establish_stream(remote, local_seid);
|
||||
a2dp_source_establish_stream(remote, local_seid, &media_tracker.a2dp_cid);
|
||||
break;
|
||||
case 'C':
|
||||
printf("Disconnect\n");
|
||||
@ -358,20 +358,20 @@ static void stdin_process(char cmd){
|
||||
case 'x':
|
||||
printf("Stream sine, local seid %d\n", media_tracker.local_seid);
|
||||
data_source = STREAM_SINE;
|
||||
a2dp_source_start_stream(media_tracker.local_seid);
|
||||
a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
|
||||
break;
|
||||
case 'z':
|
||||
printf("Stream mode, local seid %d\n", media_tracker.local_seid);
|
||||
data_source = STREAM_MOD;
|
||||
a2dp_source_start_stream(media_tracker.local_seid);
|
||||
a2dp_source_start_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
|
||||
break;
|
||||
case 'p':
|
||||
printf("Pause stream, local seid %d\n", media_tracker.local_seid);
|
||||
a2dp_source_pause_stream(media_tracker.local_seid);
|
||||
a2dp_source_pause_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
|
||||
break;
|
||||
case 'X':
|
||||
printf("Close stream, local seid %d\n", media_tracker.local_seid);
|
||||
a2dp_source_release_stream(media_tracker.local_seid);
|
||||
a2dp_source_release_stream(media_tracker.a2dp_cid, media_tracker.local_seid);
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
|
@ -177,6 +177,13 @@ typedef uint8_t sm_key_t[16];
|
||||
#define OBEX_CONNECT_FAILED 0xB1
|
||||
#define OBEX_DISCONNECTED 0xB2
|
||||
#define OBEX_NOT_FOUND 0xB3
|
||||
|
||||
#define AVDTP_SEID_DOES_NOT_EXIST 0xC0
|
||||
#define AVDTP_CONNECTION_DOES_NOT_EXIST 0xC1
|
||||
#define AVDTP_CONNECTION_IN_WRONG_STATE 0xC2
|
||||
#define AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE 0xC3
|
||||
#define AVDTP_MEDIA_CONNECTION_DOES_NOT_EXIST 0xC4
|
||||
|
||||
/* ENUM_END */
|
||||
|
||||
// DAEMON COMMANDS
|
||||
@ -1274,7 +1281,7 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param local_seid
|
||||
* @param signal_identifier
|
||||
*/
|
||||
#define AVDTP_SUBEVENT_SIGNALING_REJECT 0x02
|
||||
@ -1283,7 +1290,7 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param local_seid
|
||||
* @param signal_identifier
|
||||
*/
|
||||
#define AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT 0x03
|
||||
@ -1308,7 +1315,7 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 121111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param seid 0x01 – 0x3E
|
||||
* @param remote_seid 0x01 – 0x3E
|
||||
* @param in_use 0-not in use, 1-in use
|
||||
* @param media_type 0-audio, 1-video, 2-multimedia
|
||||
* @param sep_type 0-source, 1-sink
|
||||
@ -1319,8 +1326,8 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 121111111111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param acp_seid
|
||||
* @param local_seid
|
||||
* @param remote_seid
|
||||
* @param media_type
|
||||
* @param sampling_frequency_bitmap
|
||||
* @param channel_mode_bitmap
|
||||
@ -1336,8 +1343,8 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 121112LV
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param acp_seid
|
||||
* @param local_seid
|
||||
* @param remote_seid
|
||||
* @param media_type
|
||||
* @param media_codec_type
|
||||
* @param media_codec_information_len
|
||||
@ -1349,8 +1356,8 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 12111121111111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param acp_seid
|
||||
* @param local_seid
|
||||
* @param remote_seid
|
||||
* @param reconfigure
|
||||
* @param media_type
|
||||
* @param sampling_frequency
|
||||
@ -1368,8 +1375,8 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 1211112LV
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param acp_seid
|
||||
* @param local_seid
|
||||
* @param remote_seid
|
||||
* @param reconfigure
|
||||
* @param media_type
|
||||
* @param media_codec_type
|
||||
@ -1382,8 +1389,8 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 12111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param acp_seid
|
||||
* @param local_seid
|
||||
* @param remote_seid
|
||||
* @param status 0 == OK
|
||||
*/
|
||||
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED 0x0B
|
||||
@ -1399,7 +1406,7 @@ typedef uint8_t sm_key_t[16];
|
||||
* @format 1212
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param local_seid
|
||||
* @param sequence_number
|
||||
*/
|
||||
#define AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW 0x0D
|
||||
|
@ -4017,12 +4017,12 @@ static inline uint16_t avdtp_subevent_signaling_reject_get_avdtp_cid(const uint8
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_SIGNALING_REJECT
|
||||
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_REJECT
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_reject_get_int_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_reject_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
@ -4045,12 +4045,12 @@ static inline uint16_t avdtp_subevent_signaling_general_reject_get_avdtp_cid(con
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT
|
||||
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_general_reject_get_int_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_general_reject_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
@ -4111,12 +4111,12 @@ static inline uint16_t avdtp_subevent_signaling_sep_found_get_avdtp_cid(const ui
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field seid from event AVDTP_SUBEVENT_SIGNALING_SEP_FOUND
|
||||
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_SEP_FOUND
|
||||
* @param event packet
|
||||
* @return seid
|
||||
* @return remote_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_sep_found_get_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_sep_found_get_remote_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
@ -4157,21 +4157,21 @@ static inline uint16_t avdtp_subevent_signaling_media_codec_sbc_capability_get_a
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY
|
||||
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_capability_get_int_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_capability_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
* @brief Get field acp_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY
|
||||
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY
|
||||
* @param event packet
|
||||
* @return acp_seid
|
||||
* @return remote_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_capability_get_acp_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_capability_get_remote_seid(const uint8_t * event){
|
||||
return event[6];
|
||||
}
|
||||
/**
|
||||
@ -4257,21 +4257,21 @@ static inline uint16_t avdtp_subevent_signaling_media_codec_other_capability_get
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY
|
||||
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_other_capability_get_int_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_other_capability_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
* @brief Get field acp_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY
|
||||
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY
|
||||
* @param event packet
|
||||
* @return acp_seid
|
||||
* @return remote_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_other_capability_get_acp_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_other_capability_get_remote_seid(const uint8_t * event){
|
||||
return event[6];
|
||||
}
|
||||
/**
|
||||
@ -4321,21 +4321,21 @@ static inline uint16_t avdtp_subevent_signaling_media_codec_sbc_configuration_ge
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION
|
||||
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_configuration_get_int_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_configuration_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
* @brief Get field acp_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION
|
||||
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION
|
||||
* @param event packet
|
||||
* @return acp_seid
|
||||
* @return remote_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_configuration_get_acp_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_sbc_configuration_get_remote_seid(const uint8_t * event){
|
||||
return event[6];
|
||||
}
|
||||
/**
|
||||
@ -4439,21 +4439,21 @@ static inline uint16_t avdtp_subevent_signaling_media_codec_other_configuration_
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION
|
||||
* @brief Get field local_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_other_configuration_get_int_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_other_configuration_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
* @brief Get field acp_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION
|
||||
* @brief Get field remote_seid from event AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION
|
||||
* @param event packet
|
||||
* @return acp_seid
|
||||
* @return remote_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_other_configuration_get_acp_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_signaling_media_codec_other_configuration_get_remote_seid(const uint8_t * event){
|
||||
return event[6];
|
||||
}
|
||||
/**
|
||||
@ -4512,21 +4512,21 @@ static inline uint16_t avdtp_subevent_streaming_connection_established_get_avdtp
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED
|
||||
* @brief Get field local_seid from event AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_streaming_connection_established_get_int_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_streaming_connection_established_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
* @brief Get field acp_seid from event AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED
|
||||
* @brief Get field remote_seid from event AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return acp_seid
|
||||
* @return remote_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_streaming_connection_established_get_acp_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_streaming_connection_established_get_remote_seid(const uint8_t * event){
|
||||
return event[6];
|
||||
}
|
||||
/**
|
||||
@ -4559,12 +4559,12 @@ static inline uint16_t avdtp_subevent_streaming_can_send_media_packet_now_get_av
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW
|
||||
* @brief Get field local_seid from event AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @return local_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_streaming_can_send_media_packet_now_get_int_seid(const uint8_t * event){
|
||||
static inline uint8_t avdtp_subevent_streaming_can_send_media_packet_now_get_local_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
|
@ -55,8 +55,6 @@ 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);
|
||||
|
||||
@ -139,6 +137,23 @@ void a2dp_sink_create_sdp_record(uint8_t * service, uint32_t service_record_han
|
||||
de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
|
||||
}
|
||||
|
||||
static inline uint16_t a2dp_cid(void){
|
||||
if (!sc.local_stream_endpoint) return 0;
|
||||
if (!sc.local_stream_endpoint->connection) return 0;
|
||||
return sc.local_stream_endpoint->connection->avdtp_cid;
|
||||
}
|
||||
|
||||
static inline uint8_t local_seid(void){
|
||||
if (!sc.local_stream_endpoint) return 0;
|
||||
return sc.local_stream_endpoint->sep.seid;
|
||||
}
|
||||
|
||||
static inline uint8_t remote_seid(void){
|
||||
if (!sc.local_stream_endpoint) return 0;
|
||||
if (!sc.local_stream_endpoint->connection) return 0;
|
||||
return sc.local_stream_endpoint->connection->remote_seps[sc.local_stream_endpoint->remote_sep_index].seid;
|
||||
}
|
||||
|
||||
void a2dp_sink_register_packet_handler(btstack_packet_handler_t callback){
|
||||
// avdtp_sink_register_packet_handler(callback);
|
||||
// return;
|
||||
@ -176,25 +191,32 @@ uint8_t a2dp_sink_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_me
|
||||
return local_stream_endpoint->sep.seid;
|
||||
}
|
||||
|
||||
void a2dp_sink_establish_stream(bd_addr_t bd_addr, uint8_t local_seid){
|
||||
uint8_t a2dp_sink_establish_stream(bd_addr_t bd_addr, uint8_t local_seid, uint16_t * avdtp_cid){
|
||||
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;
|
||||
return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
}
|
||||
avdtp_sink_connect(bd_addr);
|
||||
return avdtp_sink_connect(bd_addr, avdtp_cid);
|
||||
}
|
||||
|
||||
void a2dp_sink_disconnect(uint16_t a2dp_cid){
|
||||
avdtp_disconnect(a2dp_cid, &a2dp_sink_context);
|
||||
}
|
||||
|
||||
static void a2dp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint8_t * event, uint16_t event_size){
|
||||
static void a2dp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t cid, uint8_t local_seid, uint8_t remote_seid, uint8_t status){
|
||||
if (!callback) return;
|
||||
if (event_size < 8) return;
|
||||
event[0] = HCI_EVENT_A2DP_META;
|
||||
event[2] = A2DP_SUBEVENT_STREAM_ESTABLISHED;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, event_size);
|
||||
uint8_t event[8];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_A2DP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = A2DP_SUBEVENT_STREAM_ESTABLISHED;
|
||||
little_endian_store_16(event, pos, cid);
|
||||
pos += 2;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = remote_seid;
|
||||
event[pos++] = status;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static inline void a2dp_signaling_emit_media_codec_sbc(btstack_packet_handler_t callback, uint8_t * event, uint16_t event_size){
|
||||
@ -233,37 +255,43 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
uint8_t status;
|
||||
uint8_t signal_identifier;
|
||||
uint16_t cid;
|
||||
uint8_t local_seid;
|
||||
uint8_t loc_seid;
|
||||
|
||||
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");
|
||||
log_info("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 --- a2dp sink: HCI_EVENT_DISCONNECTION_COMPLETE ---\n");
|
||||
printf("\na2dp sink: HCI_EVENT_DISCONNECTION_COMPLETE ---\n");
|
||||
break;
|
||||
case HCI_EVENT_AVDTP_META:
|
||||
switch (packet[2]){
|
||||
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
|
||||
cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
|
||||
if (cid != a2dp_cid()){
|
||||
a2dp_streaming_emit_connection_established(a2dp_sink_context.a2dp_callback, a2dp_cid(), local_seid(), remote_seid(), ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER);
|
||||
break;
|
||||
}
|
||||
|
||||
status = avdtp_subevent_signaling_connection_established_get_status(packet);
|
||||
if (status != 0){
|
||||
log_info(" --- a2dp sink --- AVDTP_SUBEVENT_SIGNALING_CONNECTION could not be established, status %d ---", status);
|
||||
a2dp_streaming_emit_connection_established(a2dp_sink_context.a2dp_callback, a2dp_cid(), local_seid(), remote_seid(), status);
|
||||
break;
|
||||
}
|
||||
app_state = A2DP_CONNECTED;
|
||||
avdtp_cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
|
||||
log_info(" --- a2dp sink --- AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, avdtp cid 0x%02x ---", avdtp_cid);
|
||||
log_info("a2dp sink: AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, avdtp cid 0x%02x ---", a2dp_cid());
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION:
|
||||
log_info(" --- a2dp sink --- received non SBC codec. not implemented");
|
||||
log_info("a2dp sink: received non SBC codec. not implemented");
|
||||
avdtp_signaling_emit_media_codec_other(a2dp_sink_context.a2dp_callback, packet, size);
|
||||
break;
|
||||
|
||||
@ -279,7 +307,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
} else {
|
||||
app_state = A2DP_STREAMING_OPENED;
|
||||
}
|
||||
a2dp_streaming_emit_connection_established(a2dp_sink_context.a2dp_callback, packet, size);
|
||||
a2dp_streaming_emit_connection_established(a2dp_sink_context.a2dp_callback, a2dp_cid(), local_seid(), remote_seid(), 0);
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
||||
@ -287,19 +315,18 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
status = 0;
|
||||
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||
cid = avdtp_subevent_signaling_accept_get_avdtp_cid(packet);
|
||||
local_seid = avdtp_subevent_signaling_accept_get_local_seid(packet);
|
||||
printf(" --- a2dp sink --- Accepted %d, a2dp sink cid 0x%2x, local seid %d\n", signal_identifier, cid, local_seid);
|
||||
loc_seid = avdtp_subevent_signaling_accept_get_local_seid(packet);
|
||||
|
||||
switch (signal_identifier){
|
||||
case AVDTP_SI_START:
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_STARTED, local_seid, status);
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_STARTED, loc_seid, status);
|
||||
break;
|
||||
case AVDTP_SI_SUSPEND:
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_SUSPENDED, local_seid, status);
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_SUSPENDED, loc_seid, status);
|
||||
break;
|
||||
case AVDTP_SI_ABORT:
|
||||
case AVDTP_SI_CLOSE:
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_RELEASED, local_seid, status);
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_RELEASED, loc_seid, status);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -312,19 +339,18 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
status = 1;
|
||||
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||
cid = avdtp_subevent_signaling_accept_get_avdtp_cid(packet);
|
||||
local_seid = avdtp_subevent_signaling_accept_get_local_seid(packet);
|
||||
printf(" --- a2dp sink --- Rejected %d, a2dp sink cid 0x%2x, local seid %d\n", signal_identifier, cid, local_seid);
|
||||
|
||||
loc_seid = avdtp_subevent_signaling_accept_get_local_seid(packet);
|
||||
|
||||
switch (signal_identifier){
|
||||
case AVDTP_SI_START:
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_STARTED, local_seid, status);
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_STARTED, loc_seid, status);
|
||||
break;
|
||||
case AVDTP_SI_SUSPEND:
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_SUSPENDED, local_seid, status);
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_SUSPENDED, loc_seid, status);
|
||||
break;
|
||||
case AVDTP_SI_ABORT:
|
||||
case AVDTP_SI_CLOSE:
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_RELEASED, local_seid, status);
|
||||
a2dp_emit_stream_event(a2dp_sink_context.a2dp_callback, cid, A2DP_SUBEVENT_STREAM_RELEASED, loc_seid, status);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -332,7 +358,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
break;
|
||||
default:
|
||||
app_state = A2DP_IDLE;
|
||||
log_info(" --- a2dp sink --- not implemented");
|
||||
log_info("a2dp sink: not implemented");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -88,10 +88,12 @@ void a2dp_sink_register_media_handler(void (*callback)(avdtp_stream_endpoint_t *
|
||||
|
||||
/**
|
||||
* @brief Open stream
|
||||
* @param avdtp_cid
|
||||
* @param bd_addr
|
||||
* @param local_seid
|
||||
* @param avdtp_cid
|
||||
*/
|
||||
void a2dp_sink_establish_stream(bd_addr_t bd_addr, uint8_t local_seid);
|
||||
uint8_t a2dp_sink_establish_stream(bd_addr_t bd_addr, uint8_t local_seid, uint16_t * avdtp_cid);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start stream
|
||||
|
@ -57,7 +57,6 @@ static avdtp_context_t a2dp_source_context;
|
||||
|
||||
static a2dp_state_t app_state = A2DP_IDLE;
|
||||
static avdtp_stream_endpoint_context_t sc;
|
||||
static 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);
|
||||
@ -141,6 +140,23 @@ void a2dp_source_create_sdp_record(uint8_t * service, uint32_t service_record_ha
|
||||
de_add_number(service, DE_UINT, DE_SIZE_16, supported_features);
|
||||
}
|
||||
|
||||
static inline uint16_t a2dp_cid(void){
|
||||
if (!sc.local_stream_endpoint) return 0;
|
||||
if (!sc.local_stream_endpoint->connection) return 0;
|
||||
return sc.local_stream_endpoint->connection->avdtp_cid;
|
||||
}
|
||||
|
||||
static inline uint8_t local_seid(void){
|
||||
if (!sc.local_stream_endpoint) return 0;
|
||||
return sc.local_stream_endpoint->sep.seid;
|
||||
}
|
||||
|
||||
static inline uint8_t remote_seid(void){
|
||||
if (!sc.local_stream_endpoint) return 0;
|
||||
if (!sc.local_stream_endpoint->connection) return 0;
|
||||
return sc.local_stream_endpoint->connection->remote_seps[sc.local_stream_endpoint->remote_sep_index].seid;
|
||||
}
|
||||
|
||||
static void a2dp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t cid, uint8_t local_seid, uint8_t remote_seid, uint8_t status){
|
||||
if (!callback) return;
|
||||
uint8_t event[8];
|
||||
@ -176,8 +192,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
uint8_t signal_identifier;
|
||||
uint8_t status;
|
||||
avdtp_sep_t sep;
|
||||
uint8_t int_seid;
|
||||
uint8_t acp_seid;
|
||||
uint8_t loc_seid;
|
||||
uint8_t rem_seid;
|
||||
uint16_t cid;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
@ -190,37 +207,55 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
case HCI_EVENT_AVDTP_META:
|
||||
switch (packet[2]){
|
||||
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
|
||||
avdtp_cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
|
||||
cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
|
||||
if (cid != a2dp_cid()){
|
||||
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, a2dp_cid(), local_seid(), remote_seid(), ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER);
|
||||
break;
|
||||
}
|
||||
status = avdtp_subevent_signaling_connection_established_get_status(packet);
|
||||
if (status != 0){
|
||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_SIGNALING_CONNECTION could not be established, status %d ---", status);
|
||||
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, a2dp_cid(), local_seid(), remote_seid(), status);
|
||||
break;
|
||||
}
|
||||
sc.active_remote_sep = NULL;
|
||||
next_remote_sep_index_to_query = 0;
|
||||
app_state = A2DP_W2_DISCOVER_SEPS;
|
||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, avdtp cid 0x%02x ---", avdtp_cid);
|
||||
avdtp_source_discover_stream_endpoints(avdtp_cid);
|
||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, avdtp cid 0x%02x ---", a2dp_cid());
|
||||
avdtp_source_discover_stream_endpoints(a2dp_cid());
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
|
||||
status = avdtp_subevent_streaming_connection_established_get_status(packet);
|
||||
avdtp_cid = avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet);
|
||||
int_seid = avdtp_subevent_streaming_connection_established_get_int_seid(packet);
|
||||
acp_seid = avdtp_subevent_streaming_connection_established_get_acp_seid(packet);
|
||||
|
||||
if (status != 0){
|
||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_STREAMING_CONNECTION could not be established, status %d ---", status);
|
||||
cid = avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet);
|
||||
|
||||
if (cid != a2dp_cid()){
|
||||
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, a2dp_cid(), local_seid(), remote_seid(), ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER);
|
||||
break;
|
||||
}
|
||||
|
||||
loc_seid = avdtp_subevent_streaming_connection_established_get_local_seid(packet);
|
||||
if (loc_seid != local_seid()){
|
||||
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, a2dp_cid(), local_seid(), remote_seid(), ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER);
|
||||
break;
|
||||
}
|
||||
|
||||
rem_seid = avdtp_subevent_streaming_connection_established_get_remote_seid(packet);
|
||||
if (status != 0){
|
||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_STREAMING_CONNECTION could not be established, status %d ---", status);
|
||||
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, a2dp_cid(), local_seid(), rem_seid, status);
|
||||
break;
|
||||
}
|
||||
|
||||
app_state = A2DP_STREAMING_OPENED;
|
||||
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, avdtp_cid, int_seid, acp_seid, 0);
|
||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED --- avdtp_cid 0x%02x, local seid %d, remote seid %d", avdtp_cid, int_seid, acp_seid);
|
||||
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, a2dp_cid(), local_seid(), remote_seid(), 0);
|
||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED --- avdtp_cid 0x%02x, local seid %d, remote seid %d", a2dp_cid(), local_seid(), remote_seid());
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_SEP_FOUND:
|
||||
// TODO check cid
|
||||
if (app_state != A2DP_W2_DISCOVER_SEPS) return;
|
||||
sep.seid = avdtp_subevent_signaling_sep_found_get_seid(packet);
|
||||
sep.seid = avdtp_subevent_signaling_sep_found_get_remote_seid(packet);
|
||||
sep.in_use = avdtp_subevent_signaling_sep_found_get_in_use(packet);
|
||||
sep.media_type = (avdtp_media_type_t) avdtp_subevent_signaling_sep_found_get_media_type(packet);
|
||||
sep.type = (avdtp_sep_type_t) avdtp_subevent_signaling_sep_found_get_sep_type(packet);
|
||||
@ -228,6 +263,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY:{
|
||||
// TODO check cid
|
||||
if (!sc.local_stream_endpoint) return;
|
||||
uint8_t sampling_frequency = avdtp_choose_sbc_sampling_frequency(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet));
|
||||
uint8_t channel_mode = avdtp_choose_sbc_channel_mode(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet));
|
||||
@ -255,6 +291,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
|
||||
// TODO check cid
|
||||
sc.sampling_frequency = avdtp_subevent_signaling_media_codec_sbc_configuration_get_sampling_frequency(packet);
|
||||
sc.block_length = avdtp_subevent_signaling_media_codec_sbc_configuration_get_block_length(packet);
|
||||
sc.subbands = avdtp_subevent_signaling_media_codec_sbc_configuration_get_subbands(packet);
|
||||
@ -264,26 +301,27 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
break;
|
||||
}
|
||||
case AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:
|
||||
a2dp_streaming_emit_can_send_media_packet_now(a2dp_source_context.a2dp_callback, avdtp_cid, 0);
|
||||
a2dp_streaming_emit_can_send_media_packet_now(a2dp_source_context.a2dp_callback, a2dp_cid(), 0);
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
||||
// TODO check cid
|
||||
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||
log_info(" --- a2dp source --- Accepted %d", signal_identifier);
|
||||
|
||||
switch (app_state){
|
||||
case A2DP_W2_DISCOVER_SEPS:
|
||||
app_state = A2DP_W2_GET_ALL_CAPABILITIES;
|
||||
sc.active_remote_sep = avdtp_source_remote_sep(avdtp_cid, next_remote_sep_index_to_query++);
|
||||
sc.active_remote_sep = avdtp_source_remote_sep(a2dp_cid(), next_remote_sep_index_to_query++);
|
||||
log_info(" --- a2dp source --- Query get caps for seid %d", sc.active_remote_sep->seid);
|
||||
avdtp_source_get_capabilities(avdtp_cid, sc.active_remote_sep->seid);
|
||||
avdtp_source_get_capabilities(a2dp_cid(), sc.active_remote_sep->seid);
|
||||
break;
|
||||
case A2DP_W2_GET_CAPABILITIES:
|
||||
case A2DP_W2_GET_ALL_CAPABILITIES:
|
||||
if (next_remote_sep_index_to_query < avdtp_source_remote_seps_num(avdtp_cid)){
|
||||
sc.active_remote_sep = avdtp_source_remote_sep(avdtp_cid, next_remote_sep_index_to_query++);
|
||||
if (next_remote_sep_index_to_query < avdtp_source_remote_seps_num(a2dp_cid())){
|
||||
sc.active_remote_sep = avdtp_source_remote_sep(a2dp_cid(), next_remote_sep_index_to_query++);
|
||||
log_info(" --- a2dp source --- Query get caps for seid %d", sc.active_remote_sep->seid);
|
||||
avdtp_source_get_capabilities(avdtp_cid, sc.active_remote_sep->seid);
|
||||
avdtp_source_get_capabilities(a2dp_cid(), sc.active_remote_sep->seid);
|
||||
} else {
|
||||
log_info(" --- a2dp source --- No more remote seps found");
|
||||
app_state = A2DP_IDLE;
|
||||
@ -292,12 +330,12 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
case A2DP_W2_SET_CONFIGURATION:{
|
||||
if (!sc.local_stream_endpoint) return;
|
||||
app_state = A2DP_W2_GET_CONFIGURATION;
|
||||
avdtp_source_set_configuration(avdtp_cid, avdtp_stream_endpoint_seid(sc.local_stream_endpoint), sc.active_remote_sep->seid, sc.local_stream_endpoint->remote_configuration_bitmap, sc.local_stream_endpoint->remote_configuration);
|
||||
avdtp_source_set_configuration(a2dp_cid(), avdtp_stream_endpoint_seid(sc.local_stream_endpoint), sc.active_remote_sep->seid, sc.local_stream_endpoint->remote_configuration_bitmap, sc.local_stream_endpoint->remote_configuration);
|
||||
break;
|
||||
}
|
||||
case A2DP_W2_GET_CONFIGURATION:
|
||||
app_state = A2DP_W2_OPEN_STREAM_WITH_SEID;
|
||||
avdtp_source_get_configuration(avdtp_cid, sc.active_remote_sep->seid);
|
||||
avdtp_source_get_configuration(a2dp_cid(), sc.active_remote_sep->seid);
|
||||
break;
|
||||
case A2DP_W2_OPEN_STREAM_WITH_SEID:{
|
||||
app_state = A2DP_W4_OPEN_STREAM_WITH_SEID;
|
||||
@ -305,7 +343,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
sc.block_length, sc.subbands,
|
||||
sc.allocation_method, sc.sampling_frequency,
|
||||
sc.max_bitpool_value);
|
||||
avdtp_source_open_stream(avdtp_cid, avdtp_stream_endpoint_seid(sc.local_stream_endpoint), sc.active_remote_sep->seid);
|
||||
avdtp_source_open_stream(a2dp_cid(), avdtp_stream_endpoint_seid(sc.local_stream_endpoint), sc.active_remote_sep->seid);
|
||||
break;
|
||||
}
|
||||
case A2DP_STREAMING_OPENED:
|
||||
@ -317,7 +355,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
event[pos++] = HCI_EVENT_A2DP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = A2DP_SUBEVENT_STREAM_STARTED;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
little_endian_store_16(event, pos, a2dp_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));
|
||||
@ -329,7 +367,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
event[pos++] = HCI_EVENT_A2DP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = A2DP_SUBEVENT_STREAM_SUSPENDED;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
little_endian_store_16(event, pos, a2dp_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));
|
||||
@ -342,7 +380,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
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);
|
||||
little_endian_store_16(event, pos, a2dp_cid());
|
||||
pos += 2;
|
||||
log_info("send A2DP_SUBEVENT_STREAM_RELEASED to app");
|
||||
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
||||
@ -411,37 +449,38 @@ uint8_t a2dp_source_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_
|
||||
return local_stream_endpoint->sep.seid;
|
||||
}
|
||||
|
||||
void a2dp_source_establish_stream(bd_addr_t bd_addr, uint8_t local_seid){
|
||||
uint8_t a2dp_source_establish_stream(bd_addr_t bd_addr, uint8_t local_seid, uint16_t * avdtp_cid){
|
||||
sc.local_stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
|
||||
if (!sc.local_stream_endpoint){
|
||||
log_error(" no local_stream_endpoint for seid %d", local_seid);
|
||||
return;
|
||||
return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
}
|
||||
avdtp_source_connect(bd_addr);
|
||||
return avdtp_source_connect(bd_addr, avdtp_cid);
|
||||
}
|
||||
|
||||
void a2dp_source_disconnect(uint16_t local_seid){
|
||||
avdtp_disconnect(local_seid, &a2dp_source_context);
|
||||
uint8_t a2dp_source_disconnect(uint16_t avdtp_cid){
|
||||
return avdtp_disconnect(avdtp_cid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
void a2dp_source_start_stream(uint8_t int_seid){
|
||||
avdtp_start_stream(int_seid, &a2dp_source_context);
|
||||
uint8_t a2dp_source_start_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_start_stream(avdtp_cid, local_seid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
void a2dp_source_release_stream(uint8_t int_seid){
|
||||
avdtp_stop_stream(int_seid, &a2dp_source_context);
|
||||
uint8_t a2dp_source_release_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_stop_stream(avdtp_cid, local_seid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
void a2dp_source_pause_stream(uint8_t int_seid){
|
||||
avdtp_suspend_stream(int_seid, &a2dp_source_context);
|
||||
uint8_t a2dp_source_pause_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_suspend_stream(avdtp_cid, local_seid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
uint8_t a2dp_source_stream_endpoint_ready(uint8_t local_seid){
|
||||
uint8_t a2dp_source_stream_endpoint_ready(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("No stream_endpoint with seid %d", local_seid);
|
||||
return 0;
|
||||
}
|
||||
if (!stream_endpoint->connection || stream_endpoint->connection->avdtp_cid != avdtp_cid) return 0;
|
||||
return (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING);
|
||||
}
|
||||
|
||||
@ -486,14 +525,14 @@ void a2dp_source_stream_endpoint_request_can_send_now(uint8_t local_seid){
|
||||
avdtp_request_can_send_now_initiator(stream_endpoint->connection, stream_endpoint->l2cap_media_cid);
|
||||
}
|
||||
|
||||
int a2dp_max_media_payload_size(uint8_t int_seid){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, &a2dp_source_context);
|
||||
int a2dp_max_media_payload_size(uint8_t local_seid){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("no stream_endpoint found for seid %d", int_seid);
|
||||
log_error("no stream_endpoint found for seid %d", local_seid);
|
||||
return 0;
|
||||
}
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
log_error("no media cid found for seid %d", int_seid);
|
||||
log_error("no media cid found for seid %d", local_seid);
|
||||
return 0;
|
||||
}
|
||||
return l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid) - AVDTP_MEDIA_PAYLOAD_HEADER_SIZE;
|
||||
@ -512,15 +551,15 @@ static void a2dp_source_copy_media_payload(uint8_t * media_packet, int size, int
|
||||
*offset = pos;
|
||||
}
|
||||
|
||||
int a2dp_source_stream_send_media_payload(uint8_t int_seid, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames, uint8_t marker){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, &a2dp_source_context);
|
||||
int a2dp_source_stream_send_media_payload(uint8_t local_seid, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames, uint8_t marker){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("no stream_endpoint found for seid %d", int_seid);
|
||||
log_error("no stream_endpoint found for seid %d", local_seid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
log_error("no media cid found for seid %d", int_seid);
|
||||
log_error("no media cid found for seid %d", local_seid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -74,47 +74,48 @@ uint8_t a2dp_source_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_
|
||||
|
||||
/**
|
||||
* @brief Open stream
|
||||
* @param bd_addr
|
||||
* @param local_seid
|
||||
* @param avdtp_cid
|
||||
* @param seid
|
||||
*/
|
||||
void a2dp_source_establish_stream(bd_addr_t bd_addr, uint8_t local_seid);
|
||||
uint8_t a2dp_source_establish_stream(bd_addr_t bd_addr, uint8_t local_seid, uint16_t * avdtp_cid);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start stream
|
||||
* @param avdtp_cid
|
||||
* @param seid
|
||||
*/
|
||||
void a2dp_source_start_stream(uint8_t int_seid);
|
||||
uint8_t a2dp_source_start_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Start stream
|
||||
* @param avdtp_cid
|
||||
* @param seid
|
||||
*/
|
||||
void a2dp_source_pause_stream(uint8_t int_seid);
|
||||
uint8_t a2dp_source_pause_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Close stream
|
||||
* @param avdtp_cid
|
||||
* @param seid
|
||||
*/
|
||||
void a2dp_source_release_stream(uint8_t int_seid);
|
||||
uint8_t a2dp_source_release_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Disconnect from device with cid.
|
||||
* @param avdtp_cid
|
||||
*/
|
||||
void a2dp_source_disconnect(uint16_t avdtp_cid);
|
||||
|
||||
uint8_t a2dp_source_disconnect(uint16_t avdtp_cid);
|
||||
|
||||
// size for media (does not include media header)
|
||||
int a2dp_max_media_payload_size(uint8_t int_seid);
|
||||
int a2dp_max_media_payload_size(uint8_t local_seid);
|
||||
|
||||
uint8_t a2dp_source_stream_endpoint_ready(uint8_t local_seid);
|
||||
uint8_t a2dp_source_stream_endpoint_ready(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
void a2dp_source_stream_endpoint_request_can_send_now(uint8_t local_seid);
|
||||
|
||||
int a2dp_source_stream_send_media_payload(uint8_t int_seid, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames, uint8_t marker);
|
||||
int a2dp_source_stream_send_media_payload(uint8_t local_seid, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames, uint8_t marker);
|
||||
|
||||
/* API_END */
|
||||
|
||||
|
@ -61,11 +61,28 @@ typedef struct {
|
||||
} avdtp_sdp_query_context_t;
|
||||
|
||||
static avdtp_sdp_query_context_t sdp_query_context;
|
||||
static uint16_t avdtp_cid_counter = 0;
|
||||
|
||||
static void (*handle_media_data)(avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size);
|
||||
static void avdtp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
|
||||
void avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_context_t * avdtp_context){
|
||||
static uint16_t avdtp_get_next_avdtp_cid(){
|
||||
avdtp_cid_counter++;
|
||||
if (avdtp_cid_counter == 0){
|
||||
avdtp_cid_counter = 1;
|
||||
}
|
||||
return avdtp_cid_counter;
|
||||
}
|
||||
|
||||
static uint16_t avdtp_get_next_local_seid(avdtp_context_t * context){
|
||||
context->stream_endpoints_id_counter++;
|
||||
if (context->stream_endpoints_id_counter == 0){
|
||||
context->stream_endpoints_id_counter = 1;
|
||||
}
|
||||
return context->stream_endpoints_id_counter;
|
||||
}
|
||||
|
||||
uint8_t avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_context_t * avdtp_context, uint16_t * avdtp_cid){
|
||||
sdp_query_context.connection = NULL;
|
||||
avdtp_connection_t * connection = avdtp_connection_for_bd_addr(remote, avdtp_context);
|
||||
if (!connection){
|
||||
@ -73,8 +90,14 @@ void avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_context_
|
||||
}
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_IDLE){
|
||||
log_error("avdtp_connect: sink in wrong state,");
|
||||
return;
|
||||
return BTSTACK_MEMORY_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
if (!avdtp_cid) return L2CAP_LOCAL_CID_DOES_NOT_EXIST;
|
||||
|
||||
*avdtp_cid = avdtp_get_next_avdtp_cid();
|
||||
connection->avdtp_cid = *avdtp_cid;
|
||||
|
||||
connection->state = AVDTP_SIGNALING_W4_SDP_QUERY_COMPLETE;
|
||||
sdp_query_context.connection = connection;
|
||||
sdp_query_context.query_role = query_role;
|
||||
@ -82,6 +105,7 @@ void avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_context_
|
||||
sdp_query_context.packet_handler = avdtp_context->packet_handler;
|
||||
|
||||
sdp_client_query_uuid16(&avdtp_handle_sdp_client_query_result, remote, BLUETOOTH_PROTOCOL_AVDTP);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avdtp_register_media_transport_category(avdtp_stream_endpoint_t * stream_endpoint){
|
||||
@ -189,7 +213,7 @@ void avdtp_handle_can_send_now(avdtp_connection_t * connection, uint16_t l2cap_c
|
||||
if (stream_endpoint->connection == connection){
|
||||
if (stream_endpoint->state >= AVDTP_STREAM_ENDPOINT_OPENED && stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_DISCONNECTED){
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_DISCONNECTED;
|
||||
avdtp_request_can_send_now_self(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_self(connection, connection->tl2cap_signaling_cid);
|
||||
l2cap_disconnect(stream_endpoint->l2cap_media_cid, 0);
|
||||
return;
|
||||
}
|
||||
@ -197,7 +221,7 @@ void avdtp_handle_can_send_now(avdtp_connection_t * connection, uint16_t l2cap_c
|
||||
}
|
||||
connection->disconnect = 0;
|
||||
connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED;
|
||||
l2cap_disconnect(connection->l2cap_signaling_cid, 0);
|
||||
l2cap_disconnect(connection->tl2cap_signaling_cid, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -223,8 +247,7 @@ avdtp_connection_t * avdtp_create_connection(bd_addr_t remote_addr, avdtp_contex
|
||||
avdtp_stream_endpoint_t * avdtp_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type, avdtp_context_t * context){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = btstack_memory_avdtp_stream_endpoint_get();
|
||||
memset(stream_endpoint, 0, sizeof(avdtp_stream_endpoint_t));
|
||||
context->stream_endpoints_id_counter++;
|
||||
stream_endpoint->sep.seid = context->stream_endpoints_id_counter;
|
||||
stream_endpoint->sep.seid = avdtp_get_next_local_seid(context);
|
||||
stream_endpoint->sep.media_type = media_type;
|
||||
stream_endpoint->sep.type = sep_type;
|
||||
btstack_linked_list_add(&context->stream_endpoints, (btstack_linked_item_t *) stream_endpoint);
|
||||
@ -246,6 +269,7 @@ static void handle_l2cap_data_packet_for_signaling_connection(avdtp_connection_t
|
||||
|
||||
static void stream_endpoint_state_machine(avdtp_connection_t * connection, avdtp_stream_endpoint_t * stream_endpoint, uint8_t packet_type, uint8_t event, uint8_t *packet, uint16_t size, avdtp_context_t * context){
|
||||
uint16_t local_cid;
|
||||
uint8_t status;
|
||||
switch (packet_type){
|
||||
case L2CAP_DATA_PACKET:{
|
||||
int offset = avdtp_read_signaling_header(&connection->signaling_packet, packet, size);
|
||||
@ -260,13 +284,24 @@ static void stream_endpoint_state_machine(avdtp_connection_t * connection, avdtp
|
||||
switch (event){
|
||||
case L2CAP_EVENT_CHANNEL_OPENED:
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_CONNECTED) return;
|
||||
if (stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_CONNECTED){
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed - stream endpoint in wrong state %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d\n", stream_endpoint->state, connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE);
|
||||
break;
|
||||
}
|
||||
status = l2cap_event_channel_opened_get_status(packet);
|
||||
if (status){
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED failed with status %d, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d\n", status, connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), status);
|
||||
break;
|
||||
}
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_OPENED;
|
||||
stream_endpoint->connection = connection;
|
||||
stream_endpoint->l2cap_media_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||
stream_endpoint->media_con_handle = l2cap_event_channel_opened_get_handle(packet);
|
||||
log_info(" -> AVDTP_STREAM_ENDPOINT_OPENED, media con handle 0x%02x, l2cap_media_cid 0x%02x", stream_endpoint->media_con_handle, stream_endpoint->l2cap_media_cid);
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->l2cap_signaling_cid, stream_endpoint->sep.seid, connection->remote_seps[stream_endpoint->remote_sep_index].seid, 0);
|
||||
|
||||
printf(" -> AVDTP_STREAM_ENDPOINT_OPENED, avdtp cid 0x%02x, l2cap_media_cid 0x%02x, local seid %d, remote seid %d\n", connection->avdtp_cid, stream_endpoint->l2cap_media_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint));
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), avdtp_remote_seid(stream_endpoint), 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -339,7 +374,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, SDP_SERVICE_NOT_FOUND);
|
||||
avdtp_signaling_emit_connection_established(sdp_query_context.avdtp_callback, sdp_query_context.connection->avdtp_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 +383,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, SDP_SERVICE_NOT_FOUND);
|
||||
avdtp_signaling_emit_connection_established(sdp_query_context.avdtp_callback, sdp_query_context.connection->avdtp_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);
|
||||
@ -394,7 +429,7 @@ static void avdtp_handle_sdp_client_query_result(uint8_t packet_type, uint16_t c
|
||||
}
|
||||
if (!avdtp_l2cap_psm) {
|
||||
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, L2CAP_SERVICE_DOES_NOT_EXIST);
|
||||
avdtp_signaling_emit_connection_established(sdp_query_context.avdtp_callback, sdp_query_context.connection->avdtp_cid, sdp_query_context.connection->remote_addr, L2CAP_SERVICE_DOES_NOT_EXIST);
|
||||
break;
|
||||
}
|
||||
sdp_query_context.connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED;
|
||||
@ -430,7 +465,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
// log_info("avdtp_packet_handler packet type %02x, event %02x ", packet_type, hci_event_packet_get_type(packet));
|
||||
switch (packet_type) {
|
||||
case L2CAP_DATA_PACKET:
|
||||
connection = avdtp_connection_for_l2cap_signaling_cid(channel, context);
|
||||
connection = avdtp_connection_for_tl2cap_signaling_cid(channel, context);
|
||||
if (connection){
|
||||
handle_l2cap_data_packet_for_signaling_connection(connection, packet, size, context);
|
||||
break;
|
||||
@ -443,7 +478,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
break;
|
||||
}
|
||||
|
||||
if (channel == stream_endpoint->connection->l2cap_signaling_cid){
|
||||
if (channel == stream_endpoint->connection->tl2cap_signaling_cid){
|
||||
stream_endpoint_state_machine(stream_endpoint->connection, stream_endpoint, L2CAP_DATA_PACKET, 0, packet, size, context);
|
||||
break;
|
||||
}
|
||||
@ -500,7 +535,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
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));
|
||||
avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->avdtp_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;
|
||||
@ -521,14 +556,13 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
connection = avdtp_connection_for_bd_addr(event_addr, context);
|
||||
if (!connection) break;
|
||||
|
||||
if (connection->l2cap_signaling_cid == 0) {
|
||||
if (connection->tl2cap_signaling_cid == 0) {
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED) break;
|
||||
connection->l2cap_signaling_cid = local_cid;
|
||||
connection->con_handle = con_handle;
|
||||
connection->tl2cap_signaling_cid = local_cid;
|
||||
connection->query_seid = 0;
|
||||
connection->state = AVDTP_SIGNALING_CONNECTION_OPENED;
|
||||
log_info(" -> AVDTP_SIGNALING_CONNECTION_OPENED, connection %p", connection);
|
||||
avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->l2cap_signaling_cid, event_addr, 0);
|
||||
avdtp_signaling_emit_connection_established(context->avdtp_callback, connection->avdtp_cid, event_addr, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -543,7 +577,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
case L2CAP_EVENT_CHANNEL_CLOSED:
|
||||
// data: event (8), len(8), channel (16)
|
||||
local_cid = l2cap_event_channel_closed_get_local_cid(packet);
|
||||
connection = avdtp_connection_for_l2cap_signaling_cid(local_cid, context);
|
||||
connection = avdtp_connection_for_tl2cap_signaling_cid(local_cid, context);
|
||||
log_info(" -> L2CAP_EVENT_CHANNEL_CLOSED signaling cid 0x%0x", local_cid);
|
||||
|
||||
stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(local_cid, context);
|
||||
@ -574,7 +608,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
break;
|
||||
|
||||
case L2CAP_EVENT_CAN_SEND_NOW:
|
||||
connection = avdtp_connection_for_l2cap_signaling_cid(channel, context);
|
||||
connection = avdtp_connection_for_tl2cap_signaling_cid(channel, context);
|
||||
if (!connection) {
|
||||
stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(channel, context);
|
||||
if (!stream_endpoint->connection) break;
|
||||
@ -594,120 +628,155 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
}
|
||||
}
|
||||
|
||||
void avdtp_disconnect(uint16_t avdtp_cid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
if (!connection) return;
|
||||
if (connection->state == AVDTP_SIGNALING_CONNECTION_IDLE) return;
|
||||
if (connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED) return;
|
||||
uint8_t avdtp_disconnect(uint16_t avdtp_cid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection) return BTSTACK_MEMORY_ALLOC_FAILED;
|
||||
if (connection->state == AVDTP_SIGNALING_CONNECTION_IDLE) return AVDTP_CONNECTION_IN_WRONG_STATE;
|
||||
if (connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED) return AVDTP_CONNECTION_IN_WRONG_STATE;
|
||||
|
||||
connection->disconnect = 1;
|
||||
avdtp_request_can_send_now_self(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_self(connection, connection->tl2cap_signaling_cid);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avdtp_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
uint8_t avdtp_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_media_connect: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
return;
|
||||
return AVDTP_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
if (avdtp_find_remote_sep(connection, acp_seid) == 0xFF){
|
||||
log_error("avdtp_media_connect: no remote sep for seid %d found", acp_seid);
|
||||
return;
|
||||
return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) {
|
||||
log_error("avdtp_media_connect: wrong connection state %d", connection->state);
|
||||
return;
|
||||
return AVDTP_CONNECTION_IN_WRONG_STATE;
|
||||
}
|
||||
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_media_connect: no stream_endpoint with seid %d found", int_seid);
|
||||
return;
|
||||
return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (stream_endpoint->state < AVDTP_STREAM_ENDPOINT_CONFIGURED) return;
|
||||
if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return;
|
||||
if (stream_endpoint->state < AVDTP_STREAM_ENDPOINT_CONFIGURED) return AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE;
|
||||
if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
|
||||
connection->initiator_transaction_label++;
|
||||
connection->acp_seid = acp_seid;
|
||||
connection->int_seid = stream_endpoint->sep.seid;
|
||||
connection->local_seid = stream_endpoint->sep.seid;
|
||||
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_OPEN_STREAM;
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_W2_REQUEST_OPEN_STREAM;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avdtp_start_stream(uint8_t int_seid, avdtp_context_t * context){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_start_stream: no stream_endpoint with seid %d found", int_seid);
|
||||
return;
|
||||
}
|
||||
avdtp_connection_t * connection = stream_endpoint->connection;
|
||||
uint8_t avdtp_start_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_start_stream: no connection for seid %d found",stream_endpoint->sep.seid);
|
||||
return;
|
||||
log_error("avdtp_start_stream: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
return AVDTP_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(local_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_start_stream: no stream_endpoint with seid %d found", local_seid);
|
||||
return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
log_error("avdtp_start_stream: no media connection for stream_endpoint with seid %d found", local_seid);
|
||||
return AVDTP_MEDIA_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX || stream_endpoint->start_stream){
|
||||
return AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE;
|
||||
}
|
||||
|
||||
if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX || stream_endpoint->start_stream) return;
|
||||
stream_endpoint->start_stream = 1;
|
||||
connection->int_seid = int_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
connection->local_seid = local_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avdtp_stop_stream(uint8_t int_seid, avdtp_context_t * context){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_stop_stream: no stream_endpoint with seid %d found", int_seid);
|
||||
return;
|
||||
}
|
||||
avdtp_connection_t * connection = stream_endpoint->connection;
|
||||
uint8_t avdtp_stop_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_stop_stream: no connection for seid %d found",stream_endpoint->sep.seid);
|
||||
return;
|
||||
log_error("avdtp_stop_stream: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
return AVDTP_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->stop_stream) return;
|
||||
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(local_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_stop_stream: no stream_endpoint with seid %d found", local_seid);
|
||||
return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
log_error("avdtp_stop_stream: no media connection for stream_endpoint with seid %d found", local_seid);
|
||||
return AVDTP_MEDIA_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->stop_stream) return ERROR_CODE_SUCCESS;
|
||||
|
||||
stream_endpoint->stop_stream = 1;
|
||||
connection->int_seid = int_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
connection->local_seid = local_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avdtp_abort_stream(uint8_t int_seid, avdtp_context_t * context){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_abort_stream: no stream_endpoint with seid %d found", int_seid);
|
||||
return;
|
||||
}
|
||||
avdtp_connection_t * connection = stream_endpoint->connection;
|
||||
|
||||
uint8_t avdtp_abort_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_abort_stream: no connection for seid %d found",stream_endpoint->sep.seid);
|
||||
return;
|
||||
log_error("avdtp_abort_stream: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
return AVDTP_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->abort_stream) return;
|
||||
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(local_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_abort_stream: no stream_endpoint with seid %d found", local_seid);
|
||||
return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
log_error("avdtp_abort_stream: no media connection for stream_endpoint with seid %d found", local_seid);
|
||||
return AVDTP_MEDIA_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->stop_stream) return ERROR_CODE_SUCCESS;
|
||||
|
||||
stream_endpoint->abort_stream = 1;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avdtp_suspend_stream(uint8_t int_seid, avdtp_context_t * context){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_abort_stream: no stream_endpoint with seid %d found", int_seid);
|
||||
return;
|
||||
}
|
||||
avdtp_connection_t * connection = stream_endpoint->connection;
|
||||
uint8_t avdtp_suspend_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_abort_stream: no connection for seid %d found",stream_endpoint->sep.seid);
|
||||
return;
|
||||
log_error("avdtp_suspend_stream: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
return AVDTP_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->suspend_stream) return;
|
||||
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(local_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_suspend_stream: no stream_endpoint with seid %d found", local_seid);
|
||||
return AVDTP_SEID_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
log_error("avdtp_suspend_stream: no media connection for stream_endpoint with seid %d found", local_seid);
|
||||
return AVDTP_MEDIA_CONNECTION_DOES_NOT_EXIST;
|
||||
}
|
||||
if (stream_endpoint->remote_sep_index == 0xFF || stream_endpoint->stop_stream) return ERROR_CODE_SUCCESS;
|
||||
|
||||
stream_endpoint->suspend_stream = 1;
|
||||
connection->int_seid = int_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
connection->local_seid = local_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avdtp_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_discover_stream_endpoints: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
return;
|
||||
@ -718,7 +787,7 @@ void avdtp_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * conte
|
||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE:
|
||||
connection->initiator_transaction_label++;
|
||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_DISCOVER_SEPS;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
break;
|
||||
default:
|
||||
log_error("avdtp_discover_stream_endpoints: wrong state");
|
||||
@ -728,9 +797,9 @@ void avdtp_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * conte
|
||||
|
||||
|
||||
void avdtp_get_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_get_capabilities: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
log_error("avdtp_get_capabilities: no connection for AVDTP cid 0x%02x found", avdtp_cid);
|
||||
return;
|
||||
}
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||
@ -738,14 +807,14 @@ void avdtp_get_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_
|
||||
connection->initiator_transaction_label++;
|
||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES;
|
||||
connection->acp_seid = acp_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
}
|
||||
|
||||
|
||||
void avdtp_get_all_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_get_all_capabilities: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
log_error("avdtp_get_all_capabilities: no connection for AVDTP cid 0x%02x found", avdtp_cid);
|
||||
return;
|
||||
}
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||
@ -753,13 +822,13 @@ void avdtp_get_all_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_cont
|
||||
connection->initiator_transaction_label++;
|
||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES;
|
||||
connection->acp_seid = acp_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
}
|
||||
|
||||
void avdtp_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_get_configuration: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
log_error("avdtp_get_configuration: no connection for AVDTP cid 0x%02x found", avdtp_cid);
|
||||
return;
|
||||
}
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||
@ -767,46 +836,46 @@ void avdtp_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context
|
||||
connection->initiator_transaction_label++;
|
||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CONFIGURATION;
|
||||
connection->acp_seid = acp_seid;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
}
|
||||
|
||||
void avdtp_set_configuration(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
void avdtp_set_configuration(uint16_t avdtp_cid, uint8_t local_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_set_configuration: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
log_error("avdtp_set_configuration: no connection for AVDTP cid 0x%02x found", avdtp_cid);
|
||||
return;
|
||||
}
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||
if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return;
|
||||
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_set_configuration: no initiator stream endpoint for seid %d", int_seid);
|
||||
log_error("avdtp_set_configuration: no initiator stream endpoint for seid %d", local_seid);
|
||||
return;
|
||||
}
|
||||
|
||||
connection->initiator_transaction_label++;
|
||||
connection->acp_seid = acp_seid;
|
||||
connection->int_seid = int_seid;
|
||||
connection->local_seid = local_seid;
|
||||
stream_endpoint->remote_capabilities_bitmap = configured_services_bitmap;
|
||||
stream_endpoint->remote_capabilities = configuration;
|
||||
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_SET_CONFIGURATION;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
}
|
||||
|
||||
void avdtp_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
void avdtp_reconfigure(uint16_t avdtp_cid, uint8_t local_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_reconfigure: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
log_error("avdtp_reconfigure: no connection for AVDTP cid 0x%02x found", avdtp_cid);
|
||||
return;
|
||||
}
|
||||
//TODO: if opened only app capabilities, enable reconfigure for not opened
|
||||
if (connection->state < AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||
if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) return;
|
||||
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, context);
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, context);
|
||||
if (!stream_endpoint) {
|
||||
log_error("avdtp_reconfigure: no initiator stream endpoint for seid %d", int_seid);
|
||||
log_error("avdtp_reconfigure: no initiator stream endpoint for seid %d", local_seid);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -817,26 +886,26 @@ void avdtp_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, u
|
||||
|
||||
connection->initiator_transaction_label++;
|
||||
connection->acp_seid = acp_seid;
|
||||
connection->int_seid = stream_endpoint->sep.seid;
|
||||
connection->local_seid = stream_endpoint->sep.seid;
|
||||
stream_endpoint->remote_capabilities_bitmap = configured_services_bitmap;
|
||||
stream_endpoint->remote_capabilities = configuration;
|
||||
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID;
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
}
|
||||
|
||||
uint8_t avdtp_remote_seps_num(uint16_t avdtp_cid, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_suspend: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
log_error("avdtp_suspend: no connection for AVDTP cid 0x%02x found", avdtp_cid);
|
||||
return 0;
|
||||
}
|
||||
return connection->remote_seps_num;
|
||||
}
|
||||
|
||||
avdtp_sep_t * avdtp_remote_sep(uint16_t avdtp_cid, uint8_t index, avdtp_context_t * context){
|
||||
avdtp_connection_t * connection = avdtp_connection_for_l2cap_signaling_cid(avdtp_cid, context);
|
||||
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||
if (!connection){
|
||||
log_error("avdtp_suspend: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||
log_error("avdtp_suspend: no connection for AVDTP cid 0x%02x found", avdtp_cid);
|
||||
return NULL;
|
||||
}
|
||||
return &connection->remote_seps[index];
|
||||
|
@ -376,11 +376,10 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
btstack_linked_item_t item;
|
||||
|
||||
bd_addr_t remote_addr;
|
||||
hci_con_handle_t con_handle;
|
||||
|
||||
uint16_t l2cap_signaling_cid;
|
||||
uint16_t avdtp_cid;
|
||||
uint16_t tl2cap_signaling_cid;
|
||||
avdtp_service_mode_t service_mode;
|
||||
|
||||
avdtp_connection_state_t state;
|
||||
@ -396,7 +395,7 @@ typedef struct {
|
||||
uint8_t initiator_transaction_label;
|
||||
uint8_t acceptor_transaction_label;
|
||||
uint8_t query_seid;
|
||||
uint8_t int_seid;
|
||||
uint8_t local_seid;
|
||||
uint8_t acp_seid;
|
||||
|
||||
uint8_t wait_to_send_acceptor;
|
||||
@ -517,20 +516,20 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
avdtp_connection_t * avdtp_create_connection(bd_addr_t remote_addr, avdtp_context_t * context);
|
||||
avdtp_stream_endpoint_t * avdtp_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type, avdtp_context_t * context);
|
||||
|
||||
void avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_context_t * context);
|
||||
void avdtp_disconnect(uint16_t avdtp_cid, avdtp_context_t * context);
|
||||
void avdtp_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, avdtp_context_t * context);
|
||||
void avdtp_start_stream(uint8_t int_seid, avdtp_context_t * context);
|
||||
void avdtp_stop_stream (uint8_t int_seid, avdtp_context_t * context);
|
||||
void avdtp_abort_stream(uint8_t int_seid, avdtp_context_t * context);
|
||||
void avdtp_suspend_stream(uint8_t int_seid, avdtp_context_t * context);
|
||||
uint8_t avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_context_t * context, uint16_t * avdtp_cid);
|
||||
uint8_t avdtp_disconnect(uint16_t avdtp_cid, avdtp_context_t * context);
|
||||
uint8_t avdtp_open_stream(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_context_t * context);
|
||||
uint8_t avdtp_start_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context);
|
||||
uint8_t avdtp_stop_stream (uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context);
|
||||
uint8_t avdtp_abort_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context);
|
||||
uint8_t avdtp_suspend_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context);
|
||||
|
||||
void avdtp_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * context);
|
||||
void avdtp_get_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context);
|
||||
void avdtp_get_all_capabilities(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context);
|
||||
void avdtp_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid, avdtp_context_t * context);
|
||||
void avdtp_set_configuration(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context);
|
||||
void avdtp_reconfigure(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context);
|
||||
void avdtp_get_capabilities(uint16_t avdtp_cid, uint8_t remote_seid, avdtp_context_t * context);
|
||||
void avdtp_get_all_capabilities(uint16_t avdtp_cid, uint8_t remote_seid, avdtp_context_t * context);
|
||||
void avdtp_get_configuration(uint16_t avdtp_cid, uint8_t remote_seid, avdtp_context_t * context);
|
||||
void avdtp_set_configuration(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context);
|
||||
void avdtp_reconfigure(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, avdtp_context_t * context);
|
||||
uint8_t avdtp_remote_seps_num(uint16_t avdtp_cid, avdtp_context_t * context);
|
||||
avdtp_sep_t * avdtp_remote_sep(uint16_t avdtp_cid, uint8_t index, avdtp_context_t * context);
|
||||
|
||||
|
@ -87,7 +87,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
connection->error_code = BAD_LENGTH;
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->tl2cap_signaling_cid);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||
log_info(" ACP: AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS");
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS;
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->tl2cap_signaling_cid);
|
||||
return;
|
||||
case AVDTP_SI_GET_CAPABILITIES:
|
||||
case AVDTP_SI_GET_ALL_CAPABILITIES:
|
||||
@ -122,7 +122,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
}
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->tl2cap_signaling_cid);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -145,7 +145,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
connection->reject_service_category = connection->query_seid;
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->tl2cap_signaling_cid);
|
||||
return;
|
||||
}
|
||||
// deal with first susspended seid
|
||||
@ -158,7 +158,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
connection->num_suspended_seids = 0;
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->tl2cap_signaling_cid);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -167,7 +167,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_GENERAL_REJECT_WITH_ERROR_CODE;
|
||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||
log_info("AVDTP_CMD_MSG signal %d not implemented, general reject", connection->signaling_packet.signal_identifier);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->tl2cap_signaling_cid);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -248,14 +248,14 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
if (get_bit16(sep.configured_service_categories, AVDTP_MEDIA_CODEC)){
|
||||
switch (sep.configuration.media_codec.media_codec_type){
|
||||
case AVDTP_CODEC_SBC:
|
||||
avdtp_signaling_emit_media_codec_sbc_configuration(context->avdtp_callback, connection->con_handle, connection->int_seid, connection->acp_seid, sep.configuration.media_codec);
|
||||
avdtp_signaling_emit_media_codec_sbc_configuration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->acp_seid, sep.configuration.media_codec);
|
||||
break;
|
||||
default:
|
||||
avdtp_signaling_emit_media_codec_other_configuration(context->avdtp_callback, connection->con_handle, connection->int_seid, connection->acp_seid, sep.configuration.media_codec);
|
||||
avdtp_signaling_emit_media_codec_other_configuration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->acp_seid, sep.configuration.media_codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
avdtp_signaling_emit_accept(context->avdtp_callback, connection->con_handle, connection->int_seid, connection->signaling_packet.signal_identifier, 0);
|
||||
avdtp_signaling_emit_accept(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->signaling_packet.signal_identifier);
|
||||
break;
|
||||
}
|
||||
case AVDTP_SI_RECONFIGURE:{
|
||||
@ -292,14 +292,14 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
if (get_bit16(sep.configured_service_categories, AVDTP_MEDIA_CODEC)){
|
||||
switch (sep.capabilities.media_codec.media_codec_type){
|
||||
case AVDTP_CODEC_SBC:
|
||||
avdtp_signaling_emit_media_codec_sbc_reconfiguration(context->avdtp_callback, connection->con_handle, connection->int_seid, connection->acp_seid, sep.capabilities.media_codec);
|
||||
avdtp_signaling_emit_media_codec_sbc_reconfiguration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->acp_seid, sep.capabilities.media_codec);
|
||||
break;
|
||||
default:
|
||||
avdtp_signaling_emit_media_codec_other_reconfiguration(context->avdtp_callback, connection->con_handle, connection->int_seid, connection->acp_seid, sep.capabilities.media_codec);
|
||||
avdtp_signaling_emit_media_codec_other_reconfiguration(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->acp_seid, sep.capabilities.media_codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
avdtp_signaling_emit_accept(context->avdtp_callback, connection->con_handle, connection->int_seid, connection->signaling_packet.signal_identifier, 0);
|
||||
avdtp_signaling_emit_accept(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->signaling_packet.signal_identifier);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -402,7 +402,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
||||
if (!request_to_send){
|
||||
log_info(" ACP: NOT IMPLEMENTED");
|
||||
}
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->tl2cap_signaling_cid);
|
||||
}
|
||||
|
||||
static int avdtp_acceptor_send_seps_response(uint16_t cid, uint8_t transaction_label, avdtp_stream_endpoint_t * endpoints){
|
||||
@ -460,19 +460,19 @@ void avdtp_acceptor_stream_config_subsm_run(avdtp_connection_t * connection, avd
|
||||
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS:
|
||||
connection->state = AVDTP_SIGNALING_CONNECTION_OPENED;
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
||||
avdtp_acceptor_send_seps_response(connection->l2cap_signaling_cid, connection->acceptor_transaction_label, (avdtp_stream_endpoint_t *) stream_endpoints);
|
||||
avdtp_acceptor_send_seps_response(connection->tl2cap_signaling_cid, connection->acceptor_transaction_label, (avdtp_stream_endpoint_t *) stream_endpoints);
|
||||
break;
|
||||
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE:
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
||||
avdtp_acceptor_send_response_reject_with_error_code(connection->l2cap_signaling_cid, connection->reject_signal_identifier, connection->error_code, connection->acceptor_transaction_label);
|
||||
avdtp_acceptor_send_response_reject_with_error_code(connection->tl2cap_signaling_cid, connection->reject_signal_identifier, connection->error_code, connection->acceptor_transaction_label);
|
||||
break;
|
||||
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE:
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
||||
avdtp_acceptor_send_response_reject_service_category(connection->l2cap_signaling_cid, connection->reject_signal_identifier, connection->reject_service_category, connection->error_code, connection->acceptor_transaction_label);
|
||||
avdtp_acceptor_send_response_reject_service_category(connection->tl2cap_signaling_cid, connection->reject_signal_identifier, connection->reject_service_category, connection->error_code, connection->acceptor_transaction_label);
|
||||
break;
|
||||
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_GENERAL_REJECT_WITH_ERROR_CODE:
|
||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
||||
avdtp_acceptor_send_response_general_reject(connection->l2cap_signaling_cid, connection->reject_signal_identifier, connection->acceptor_transaction_label);
|
||||
avdtp_acceptor_send_response_general_reject(connection->tl2cap_signaling_cid, connection->reject_signal_identifier, connection->acceptor_transaction_label);
|
||||
break;
|
||||
default:
|
||||
sent = 0;
|
||||
@ -489,7 +489,7 @@ void avdtp_acceptor_stream_config_subsm_run(avdtp_connection_t * connection, avd
|
||||
uint8_t reject_service_category = connection->reject_service_category;
|
||||
avdtp_signal_identifier_t reject_signal_identifier = connection->reject_signal_identifier;
|
||||
uint8_t error_code = connection->error_code;
|
||||
uint16_t cid = stream_endpoint->connection ? stream_endpoint->connection->l2cap_signaling_cid : connection->l2cap_signaling_cid;
|
||||
uint16_t cid = stream_endpoint->connection ? stream_endpoint->connection->tl2cap_signaling_cid : connection->tl2cap_signaling_cid;
|
||||
uint8_t trid = stream_endpoint->connection ? stream_endpoint->connection->acceptor_transaction_label : connection->acceptor_transaction_label;
|
||||
|
||||
avdtp_acceptor_stream_endpoint_state_t acceptor_config_state = stream_endpoint->acceptor_config_state;
|
||||
@ -603,10 +603,9 @@ void avdtp_acceptor_stream_config_subsm_run(avdtp_connection_t * connection, avd
|
||||
log_info(" ACP: NOT IMPLEMENTED");
|
||||
sent = 0;
|
||||
}
|
||||
avdtp_signaling_emit_accept(context->avdtp_callback, connection->con_handle, connection->int_seid, connection->signaling_packet.signal_identifier, status);
|
||||
|
||||
avdtp_signaling_emit_accept(context->avdtp_callback, connection->avdtp_cid, avdtp_local_seid(stream_endpoint), connection->signaling_packet.signal_identifier);
|
||||
// check fragmentation
|
||||
if (connection->signaling_packet.packet_type != AVDTP_SINGLE_PACKET && connection->signaling_packet.packet_type != AVDTP_END_PACKET){
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_acceptor(connection, connection->tl2cap_signaling_cid);
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
|
||||
} else {
|
||||
stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(connection->acp_seid, context);
|
||||
if (!stream_endpoint){
|
||||
stream_endpoint = avdtp_stream_endpoint_with_seid(connection->int_seid, context);
|
||||
stream_endpoint = avdtp_stream_endpoint_with_seid(connection->local_seid, context);
|
||||
}
|
||||
if (!stream_endpoint) return;
|
||||
sep.seid = connection->acp_seid;
|
||||
@ -117,22 +117,22 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
|
||||
if (avdtp_find_remote_sep(connection, sep.seid) == 0xFF){
|
||||
connection->remote_seps[connection->remote_seps_num++] = sep;
|
||||
}
|
||||
avdtp_signaling_emit_sep(context->avdtp_callback, connection->l2cap_signaling_cid, sep);
|
||||
avdtp_signaling_emit_sep(context->avdtp_callback, connection->avdtp_cid, sep);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case AVDTP_SI_GET_CAPABILITIES:
|
||||
case AVDTP_SI_GET_ALL_CAPABILITIES:
|
||||
log_info("AVDTP_SI_GET(_ALL)_CAPABILITIES int %d, acp %d", connection->int_seid, connection->acp_seid);
|
||||
log_info("AVDTP_SI_GET(_ALL)_CAPABILITIES int %d, acp %d", connection->local_seid, connection->acp_seid);
|
||||
sep.registered_service_categories = avdtp_unpack_service_capabilities(connection, &sep.capabilities, packet+offset, size-offset);
|
||||
if (get_bit16(sep.registered_service_categories, AVDTP_MEDIA_CODEC)){
|
||||
switch (sep.capabilities.media_codec.media_codec_type){
|
||||
case AVDTP_CODEC_SBC:
|
||||
avdtp_signaling_emit_media_codec_sbc_capability(context->avdtp_callback, connection->l2cap_signaling_cid, connection->int_seid, connection->acp_seid, sep.capabilities.media_codec);
|
||||
avdtp_signaling_emit_media_codec_sbc_capability(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->acp_seid, sep.capabilities.media_codec);
|
||||
break;
|
||||
default:
|
||||
avdtp_signaling_emit_media_codec_other_capability(context->avdtp_callback, connection->l2cap_signaling_cid, connection->int_seid, connection->acp_seid, sep.capabilities.media_codec);
|
||||
avdtp_signaling_emit_media_codec_other_capability(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->acp_seid, sep.capabilities.media_codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -144,10 +144,10 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
|
||||
if (get_bit16(sep.configured_service_categories, AVDTP_MEDIA_CODEC)){
|
||||
switch (sep.configuration.media_codec.media_codec_type){
|
||||
case AVDTP_CODEC_SBC:
|
||||
avdtp_signaling_emit_media_codec_sbc_configuration(context->avdtp_callback, connection->l2cap_signaling_cid, connection->int_seid, connection->acp_seid, sep.configuration.media_codec);
|
||||
avdtp_signaling_emit_media_codec_sbc_configuration(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->acp_seid, sep.configuration.media_codec);
|
||||
break;
|
||||
default:
|
||||
avdtp_signaling_emit_media_codec_other_configuration(context->avdtp_callback, connection->l2cap_signaling_cid, connection->int_seid, connection->acp_seid, sep.configuration.media_codec);
|
||||
avdtp_signaling_emit_media_codec_other_configuration(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->acp_seid, sep.configuration.media_codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -228,16 +228,16 @@ void avdtp_initiator_stream_config_subsm(avdtp_connection_t * connection, uint8_
|
||||
log_info(" AVDTP_RESPONSE_ACCEPT_MSG, signal %d not implemented", connection->signaling_packet.signal_identifier);
|
||||
break;
|
||||
}
|
||||
avdtp_signaling_emit_accept(context->avdtp_callback, connection->l2cap_signaling_cid, 0, connection->signaling_packet.signal_identifier, status);
|
||||
avdtp_signaling_emit_accept(context->avdtp_callback, connection->avdtp_cid, 0, connection->signaling_packet.signal_identifier);
|
||||
connection->initiator_transaction_label++;
|
||||
break;
|
||||
case AVDTP_RESPONSE_REJECT_MSG:
|
||||
log_info(" AVDTP_RESPONSE_REJECT_MSG signal %d", connection->signaling_packet.signal_identifier);
|
||||
avdtp_signaling_emit_reject(context->avdtp_callback, connection->l2cap_signaling_cid, connection->int_seid, connection->signaling_packet.signal_identifier);
|
||||
avdtp_signaling_emit_reject(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->signaling_packet.signal_identifier);
|
||||
return;
|
||||
case AVDTP_GENERAL_REJECT_MSG:
|
||||
log_info(" AVDTP_GENERAL_REJECT_MSG signal %d", connection->signaling_packet.signal_identifier);
|
||||
avdtp_signaling_emit_general_reject(context->avdtp_callback, connection->l2cap_signaling_cid, connection->int_seid, connection->signaling_packet.signal_identifier);
|
||||
avdtp_signaling_emit_general_reject(context->avdtp_callback, connection->avdtp_cid, connection->local_seid, connection->signaling_packet.signal_identifier);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
@ -250,22 +250,22 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_DISCOVER_SEPS:
|
||||
log_info(" INT: AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_DISCOVER_SEPS");
|
||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W4_ANSWER;
|
||||
avdtp_initiator_send_signaling_cmd(connection->l2cap_signaling_cid, AVDTP_SI_DISCOVER, connection->initiator_transaction_label);
|
||||
avdtp_initiator_send_signaling_cmd(connection->tl2cap_signaling_cid, AVDTP_SI_DISCOVER, connection->initiator_transaction_label);
|
||||
break;
|
||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES:
|
||||
log_info(" INT: AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES");
|
||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W4_ANSWER;
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_GET_CAPABILITIES, connection->initiator_transaction_label, connection->acp_seid);
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->tl2cap_signaling_cid, AVDTP_SI_GET_CAPABILITIES, connection->initiator_transaction_label, connection->acp_seid);
|
||||
break;
|
||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES:
|
||||
log_info(" INT: AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES");
|
||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W4_ANSWER;
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_GET_ALL_CAPABILITIES, connection->initiator_transaction_label, connection->acp_seid);
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->tl2cap_signaling_cid, AVDTP_SI_GET_ALL_CAPABILITIES, connection->initiator_transaction_label, connection->acp_seid);
|
||||
break;
|
||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CONFIGURATION:
|
||||
log_info(" INT: AVDTP_INITIATOR_W4_GET_CONFIGURATION");
|
||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W4_ANSWER;
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_GET_CONFIGURATION, connection->initiator_transaction_label, connection->acp_seid);
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->tl2cap_signaling_cid, AVDTP_SI_GET_CONFIGURATION, connection->initiator_transaction_label, connection->acp_seid);
|
||||
break;
|
||||
default:
|
||||
sent = 0;
|
||||
@ -279,7 +279,7 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
|
||||
stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(connection->acp_seid, context);
|
||||
if (!stream_endpoint){
|
||||
stream_endpoint = avdtp_stream_endpoint_with_seid(connection->int_seid, context);
|
||||
stream_endpoint = avdtp_stream_endpoint_with_seid(connection->local_seid, context);
|
||||
}
|
||||
if (!stream_endpoint) return;
|
||||
|
||||
@ -289,9 +289,9 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
if (stream_endpoint->start_stream){
|
||||
stream_endpoint->start_stream = 0;
|
||||
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_OPENED){
|
||||
connection->int_seid = stream_endpoint->sep.seid;
|
||||
connection->local_seid = stream_endpoint->sep.seid;
|
||||
connection->acp_seid = connection->remote_seps[stream_endpoint->remote_sep_index].seid;
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_START, connection->initiator_transaction_label++, connection->acp_seid);
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->tl2cap_signaling_cid, AVDTP_SI_START, connection->initiator_transaction_label++, connection->acp_seid);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
@ -300,9 +300,9 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
if (stream_endpoint->stop_stream){
|
||||
stream_endpoint->stop_stream = 0;
|
||||
if (stream_endpoint->state >= AVDTP_STREAM_ENDPOINT_OPENED){
|
||||
connection->int_seid = stream_endpoint->sep.seid;
|
||||
connection->local_seid = stream_endpoint->sep.seid;
|
||||
connection->acp_seid = connection->remote_seps[stream_endpoint->remote_sep_index].seid;
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_CLOSE, connection->initiator_transaction_label++, connection->acp_seid);
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->tl2cap_signaling_cid, AVDTP_SI_CLOSE, connection->initiator_transaction_label++, connection->acp_seid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -314,10 +314,10 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
case AVDTP_STREAM_ENDPOINT_CLOSING:
|
||||
case AVDTP_STREAM_ENDPOINT_OPENED:
|
||||
case AVDTP_STREAM_ENDPOINT_STREAMING:
|
||||
connection->int_seid = stream_endpoint->sep.seid;
|
||||
connection->local_seid = stream_endpoint->sep.seid;
|
||||
connection->acp_seid = connection->remote_seps[stream_endpoint->remote_sep_index].seid;
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_ABORTING;
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_ABORT, connection->initiator_transaction_label++, connection->acp_seid);
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->tl2cap_signaling_cid, AVDTP_SI_ABORT, connection->initiator_transaction_label++, connection->acp_seid);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
@ -328,7 +328,7 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
stream_endpoint->suspend_stream = 0;
|
||||
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING){
|
||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_STREAMING;
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_SUSPEND, connection->initiator_transaction_label, connection->acp_seid);
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->tl2cap_signaling_cid, AVDTP_SI_SUSPEND, connection->initiator_transaction_label, connection->acp_seid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -346,10 +346,10 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
switch (stream_endpoint_state){
|
||||
case AVDTP_INITIATOR_W2_SET_CONFIGURATION:
|
||||
case AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID:{
|
||||
log_info(" INT: AVDTP_INITIATOR_W2_(RE)CONFIGURATION bitmap, int seid %d, acp seid %d", connection->int_seid, connection->acp_seid);
|
||||
log_info(" INT: AVDTP_INITIATOR_W2_(RE)CONFIGURATION bitmap, int seid %d, acp seid %d", connection->local_seid, connection->acp_seid);
|
||||
// log_info_hexdump( connection->remote_capabilities.media_codec.media_codec_information, connection->remote_capabilities.media_codec.media_codec_information_len);
|
||||
connection->signaling_packet.acp_seid = connection->acp_seid;
|
||||
connection->signaling_packet.int_seid = connection->int_seid;
|
||||
connection->signaling_packet.int_seid = connection->local_seid;
|
||||
|
||||
connection->signaling_packet.signal_identifier = AVDTP_SI_SET_CONFIGURATION;
|
||||
|
||||
@ -360,30 +360,30 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
avdtp_prepare_capabilities(&connection->signaling_packet, connection->initiator_transaction_label, stream_endpoint->remote_capabilities_bitmap, stream_endpoint->remote_capabilities, connection->signaling_packet.signal_identifier);
|
||||
l2cap_reserve_packet_buffer();
|
||||
uint8_t * out_buffer = l2cap_get_outgoing_buffer();
|
||||
uint16_t pos = avdtp_signaling_create_fragment(connection->l2cap_signaling_cid, &connection->signaling_packet, out_buffer);
|
||||
uint16_t pos = avdtp_signaling_create_fragment(connection->tl2cap_signaling_cid, &connection->signaling_packet, out_buffer);
|
||||
if (connection->signaling_packet.packet_type != AVDTP_SINGLE_PACKET && connection->signaling_packet.packet_type != AVDTP_END_PACKET){
|
||||
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_FRAGMENTATED_COMMAND;
|
||||
log_info(" INT: fragmented");
|
||||
}
|
||||
l2cap_send_prepared(connection->l2cap_signaling_cid, pos);
|
||||
l2cap_send_prepared(connection->tl2cap_signaling_cid, pos);
|
||||
break;
|
||||
}
|
||||
case AVDTP_INITIATOR_FRAGMENTATED_COMMAND:{
|
||||
l2cap_reserve_packet_buffer();
|
||||
uint8_t * out_buffer = l2cap_get_outgoing_buffer();
|
||||
uint16_t pos = avdtp_signaling_create_fragment(connection->l2cap_signaling_cid, &connection->signaling_packet, out_buffer);
|
||||
uint16_t pos = avdtp_signaling_create_fragment(connection->tl2cap_signaling_cid, &connection->signaling_packet, out_buffer);
|
||||
if (connection->signaling_packet.packet_type != AVDTP_SINGLE_PACKET && connection->signaling_packet.packet_type != AVDTP_END_PACKET){
|
||||
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_FRAGMENTATED_COMMAND;
|
||||
log_info(" INT: fragmented");
|
||||
}
|
||||
l2cap_send_prepared(connection->l2cap_signaling_cid, pos);
|
||||
l2cap_send_prepared(connection->tl2cap_signaling_cid, pos);
|
||||
break;
|
||||
}
|
||||
case AVDTP_INITIATOR_W2_OPEN_STREAM:
|
||||
switch (stream_endpoint->state){
|
||||
case AVDTP_STREAM_ENDPOINT_W2_REQUEST_OPEN_STREAM:
|
||||
log_info(" INT: AVDTP_STREAM_ENDPOINT_W2_REQUEST_OPEN_STREAM");
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->l2cap_signaling_cid, AVDTP_SI_OPEN, connection->initiator_transaction_label, connection->acp_seid);
|
||||
avdtp_initiator_send_signaling_cmd_with_seid(connection->tl2cap_signaling_cid, AVDTP_SI_OPEN, connection->initiator_transaction_label, connection->acp_seid);
|
||||
break;
|
||||
default:
|
||||
sent = 0;
|
||||
@ -397,6 +397,6 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
||||
|
||||
// check fragmentation
|
||||
if (connection->signaling_packet.packet_type != AVDTP_SINGLE_PACKET && connection->signaling_packet.packet_type != AVDTP_END_PACKET){
|
||||
avdtp_request_can_send_now_initiator(connection, connection->l2cap_signaling_cid);
|
||||
avdtp_request_can_send_now_initiator(connection, connection->tl2cap_signaling_cid);
|
||||
}
|
||||
}
|
||||
|
@ -141,55 +141,55 @@ void avdtp_sink_register_packet_handler(btstack_packet_handler_t callback){
|
||||
avdtp_sink_context->avdtp_callback = callback;
|
||||
}
|
||||
|
||||
void avdtp_sink_connect(bd_addr_t remote){
|
||||
avdtp_connect(remote, AVDTP_SOURCE, avdtp_sink_context);
|
||||
uint8_t avdtp_sink_connect(bd_addr_t remote, uint16_t * avdtp_cid){
|
||||
return avdtp_connect(remote, AVDTP_SOURCE, avdtp_sink_context, avdtp_cid);
|
||||
}
|
||||
|
||||
void avdtp_sink_disconnect(uint16_t avdtp_cid){
|
||||
avdtp_disconnect(avdtp_cid, avdtp_sink_context);
|
||||
uint8_t avdtp_sink_disconnect(uint16_t avdtp_cid){
|
||||
return 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);
|
||||
uint8_t avdtp_sink_open_stream(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
|
||||
return avdtp_open_stream(avdtp_cid, local_seid, remote_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_start_stream(uint8_t int_seid){
|
||||
avdtp_start_stream(int_seid, avdtp_sink_context);
|
||||
uint8_t avdtp_sink_start_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_start_stream(avdtp_cid, local_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_stop_stream(uint8_t int_seid){
|
||||
avdtp_stop_stream(int_seid, avdtp_sink_context);
|
||||
uint8_t avdtp_sink_stop_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_stop_stream(avdtp_cid, local_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_abort_stream(uint8_t int_seid){
|
||||
avdtp_abort_stream(int_seid, avdtp_sink_context);
|
||||
uint8_t avdtp_sink_abort_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_abort_stream(avdtp_cid, local_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_suspend(uint8_t int_seid){
|
||||
avdtp_suspend_stream(int_seid, avdtp_sink_context);
|
||||
uint8_t avdtp_sink_suspend(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_suspend_stream(avdtp_cid, local_seid, avdtp_sink_context);
|
||||
}
|
||||
|
||||
void avdtp_sink_discover_stream_endpoints(uint16_t avdtp_cid){
|
||||
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);
|
||||
void avdtp_sink_get_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||
avdtp_get_capabilities(avdtp_cid, remote_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);
|
||||
void avdtp_sink_get_all_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||
avdtp_get_all_capabilities(avdtp_cid, remote_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);
|
||||
void avdtp_sink_get_configuration(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||
avdtp_get_configuration(avdtp_cid, remote_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);
|
||||
void avdtp_sink_set_configuration(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){
|
||||
avdtp_set_configuration(avdtp_cid, local_seid, remote_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);
|
||||
void avdtp_sink_reconfigure(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){
|
||||
avdtp_reconfigure(avdtp_cid, local_seid, remote_seid, configured_services_bitmap, configuration, avdtp_sink_context);
|
||||
}
|
||||
|
||||
|
@ -83,15 +83,16 @@ void avdtp_sink_register_packet_handler(btstack_packet_handler_t callback);
|
||||
/**
|
||||
* @brief Connect to device with a bluetooth address. (and perform configuration?)
|
||||
* @param bd_addr
|
||||
* @param avdtp_cid Assigned avdtp cid
|
||||
*/
|
||||
void avdtp_sink_connect(bd_addr_t bd_addr);
|
||||
uint8_t avdtp_sink_connect(bd_addr_t bd_addr, uint16_t * avdtp_cid);
|
||||
|
||||
void avdtp_sink_register_media_handler(void (*callback)(avdtp_stream_endpoint_t * stream_endpoint, uint8_t *packet, uint16_t size));
|
||||
/**
|
||||
* @brief Disconnect from device with connection handle.
|
||||
* @param avdtp_cid
|
||||
*/
|
||||
void avdtp_sink_disconnect(uint16_t avdtp_cid);
|
||||
uint8_t avdtp_sink_disconnect(uint16_t avdtp_cid);
|
||||
|
||||
/**
|
||||
* @brief Discover stream endpoints
|
||||
@ -136,32 +137,32 @@ void avdtp_sink_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid);
|
||||
* @param avdtp_cid
|
||||
* @param seid
|
||||
*/
|
||||
void avdtp_sink_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
|
||||
uint8_t avdtp_sink_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void avdtp_sink_start_stream(uint8_t local_seid);
|
||||
uint8_t avdtp_sink_start_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Abort stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void avdtp_sink_abort_stream(uint8_t local_seid);
|
||||
uint8_t avdtp_sink_abort_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Start stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void avdtp_sink_stop_stream(uint8_t local_seid);
|
||||
uint8_t avdtp_sink_stop_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Suspend stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void avdtp_sink_suspend(uint8_t local_seid);
|
||||
uint8_t avdtp_sink_suspend(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/* API_END */
|
||||
|
||||
|
@ -105,56 +105,56 @@ void avdtp_source_register_packet_handler(btstack_packet_handler_t callback){
|
||||
avdtp_source_context->avdtp_callback = callback;
|
||||
}
|
||||
|
||||
void avdtp_source_connect(bd_addr_t remote){
|
||||
avdtp_connect(remote, AVDTP_SINK, avdtp_source_context);
|
||||
uint8_t avdtp_source_connect(bd_addr_t remote, uint16_t * avdtp_cid){
|
||||
return avdtp_connect(remote, AVDTP_SINK, avdtp_source_context, avdtp_cid);
|
||||
}
|
||||
|
||||
void avdtp_source_disconnect(uint16_t con_handle){
|
||||
avdtp_disconnect(con_handle, avdtp_source_context);
|
||||
uint8_t avdtp_source_disconnect(uint16_t avdtp_cid){
|
||||
return avdtp_disconnect(avdtp_cid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_open_stream(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid){
|
||||
avdtp_open_stream(con_handle, int_seid, acp_seid, avdtp_source_context);
|
||||
uint8_t avdtp_source_open_stream(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
|
||||
return avdtp_open_stream(avdtp_cid, local_seid, remote_seid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_start_stream(uint8_t int_seid){
|
||||
avdtp_start_stream(int_seid, avdtp_source_context);
|
||||
uint8_t avdtp_source_start_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_start_stream(avdtp_cid, local_seid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_stop_stream(uint8_t int_seid){
|
||||
avdtp_stop_stream(int_seid, avdtp_source_context);
|
||||
uint8_t avdtp_source_stop_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_stop_stream(avdtp_cid, local_seid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_abort_stream(uint8_t int_seid){
|
||||
avdtp_abort_stream(int_seid, avdtp_source_context);
|
||||
uint8_t avdtp_source_abort_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_abort_stream(avdtp_cid, local_seid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_suspend(uint8_t int_seid){
|
||||
avdtp_suspend_stream(int_seid, avdtp_source_context);
|
||||
uint8_t avdtp_source_suspend(uint16_t avdtp_cid, uint8_t local_seid){
|
||||
return avdtp_suspend_stream(avdtp_cid, local_seid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_discover_stream_endpoints(uint16_t con_handle){
|
||||
avdtp_discover_stream_endpoints(con_handle, avdtp_source_context);
|
||||
void avdtp_source_discover_stream_endpoints(uint16_t avdtp_cid){
|
||||
avdtp_discover_stream_endpoints(avdtp_cid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_get_capabilities(uint16_t con_handle, uint8_t acp_seid){
|
||||
avdtp_get_capabilities(con_handle, acp_seid, avdtp_source_context);
|
||||
void avdtp_source_get_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||
avdtp_get_capabilities(avdtp_cid, remote_seid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_get_all_capabilities(uint16_t con_handle, uint8_t acp_seid){
|
||||
avdtp_get_all_capabilities(con_handle, acp_seid, avdtp_source_context);
|
||||
void avdtp_source_get_all_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||
avdtp_get_all_capabilities(avdtp_cid, remote_seid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_get_configuration(uint16_t con_handle, uint8_t acp_seid){
|
||||
avdtp_get_configuration(con_handle, acp_seid, avdtp_source_context);
|
||||
void avdtp_source_get_configuration(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||
avdtp_get_configuration(avdtp_cid, remote_seid, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_set_configuration(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){
|
||||
avdtp_set_configuration(con_handle, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_source_context);
|
||||
void avdtp_source_set_configuration(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){
|
||||
avdtp_set_configuration(avdtp_cid, local_seid, remote_seid, configured_services_bitmap, configuration, avdtp_source_context);
|
||||
}
|
||||
|
||||
void avdtp_source_reconfigure(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){
|
||||
avdtp_reconfigure(con_handle, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_source_context);
|
||||
void avdtp_source_reconfigure(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration){
|
||||
avdtp_reconfigure(avdtp_cid, local_seid, remote_seid, configured_services_bitmap, configuration, avdtp_source_context);
|
||||
}
|
||||
|
||||
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
|
@ -70,14 +70,15 @@ void avdtp_source_register_packet_handler(btstack_packet_handler_t callback);
|
||||
/**
|
||||
* @brief Connect to device with a bluetooth address. (and perform configuration?)
|
||||
* @param bd_addr
|
||||
* @param avdtp_cid Assigned avdtp cid
|
||||
*/
|
||||
void avdtp_source_connect(bd_addr_t bd_addr);
|
||||
uint8_t avdtp_source_connect(bd_addr_t bd_addr, uint16_t * avdtp_cid);
|
||||
|
||||
/**
|
||||
* @brief Disconnect from device with connection handle.
|
||||
* @param avdtp_cid
|
||||
*/
|
||||
void avdtp_source_disconnect(uint16_t avdtp_cid);
|
||||
uint8_t avdtp_source_disconnect(uint16_t avdtp_cid);
|
||||
|
||||
/**
|
||||
* @brief Discover stream endpoints
|
||||
@ -122,31 +123,31 @@ void avdtp_source_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid);
|
||||
* @param avdtp_cid
|
||||
* @param seid
|
||||
*/
|
||||
void avdtp_source_open_stream(uint16_t con_handle, uint8_t int_seid, uint8_t acp_seid);
|
||||
uint8_t avdtp_source_open_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid);
|
||||
|
||||
/**
|
||||
* @brief Start stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void avdtp_source_start_stream(uint8_t local_seid);
|
||||
uint8_t avdtp_source_start_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Abort stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void avdtp_source_abort_stream(uint8_t local_seid);
|
||||
uint8_t avdtp_source_abort_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Start stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void avdtp_source_stop_stream(uint8_t local_seid);
|
||||
uint8_t avdtp_source_stop_stream(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
/**
|
||||
* @brief Suspend stream
|
||||
* @param local_seid
|
||||
*/
|
||||
void avdtp_source_suspend(uint8_t local_seid);
|
||||
uint8_t avdtp_source_suspend(uint16_t avdtp_cid, uint8_t local_seid);
|
||||
|
||||
|
||||
avdtp_stream_endpoint_t * avdtp_source_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type);
|
||||
|
@ -81,12 +81,23 @@ avdtp_connection_t * avdtp_connection_for_bd_addr(bd_addr_t addr, avdtp_context_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
avdtp_connection_t * avdtp_connection_for_l2cap_signaling_cid(uint16_t l2cap_cid, avdtp_context_t * context){
|
||||
avdtp_connection_t * avdtp_connection_for_avdtp_cid(uint16_t avdtp_cid, avdtp_context_t * context){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &context->connections);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
avdtp_connection_t * connection = (avdtp_connection_t *)btstack_linked_list_iterator_next(&it);
|
||||
if (connection->l2cap_signaling_cid != l2cap_cid) continue;
|
||||
if (connection->avdtp_cid != avdtp_cid) continue;
|
||||
return connection;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
avdtp_connection_t * avdtp_connection_for_tl2cap_signaling_cid(uint16_t l2cap_cid, avdtp_context_t * context){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, &context->connections);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
avdtp_connection_t * connection = (avdtp_connection_t *)btstack_linked_list_iterator_next(&it);
|
||||
if (connection->tl2cap_signaling_cid != l2cap_cid) continue;
|
||||
return connection;
|
||||
}
|
||||
return NULL;
|
||||
@ -506,7 +517,7 @@ void avdtp_streaming_emit_can_send_media_packet_now(btstack_packet_handler_t cal
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint8_t status){
|
||||
void avdtp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, uint8_t status){
|
||||
if (!callback) return;
|
||||
uint8_t event[8];
|
||||
int pos = 0;
|
||||
@ -515,8 +526,8 @@ void avdtp_streaming_emit_connection_established(btstack_packet_handler_t callba
|
||||
event[pos++] = AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = acp_seid;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = remote_seid;
|
||||
event[pos++] = status;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
@ -537,22 +548,21 @@ void avdtp_signaling_emit_sep(btstack_packet_handler_t callback, uint16_t avdtp_
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_accept(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, avdtp_signal_identifier_t identifier, uint8_t status){
|
||||
void avdtp_signaling_emit_accept(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, avdtp_signal_identifier_t identifier){
|
||||
if (!callback) return;
|
||||
uint8_t event[8];
|
||||
uint8_t event[7];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVDTP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = AVDTP_SUBEVENT_SIGNALING_ACCEPT;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = identifier;
|
||||
event[pos++] = status;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, avdtp_signal_identifier_t identifier){
|
||||
void avdtp_signaling_emit_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, avdtp_signal_identifier_t identifier){
|
||||
if (!callback) return;
|
||||
uint8_t event[7];
|
||||
int pos = 0;
|
||||
@ -561,12 +571,12 @@ void avdtp_signaling_emit_reject(btstack_packet_handler_t callback, uint16_t avd
|
||||
event[pos++] = AVDTP_SUBEVENT_SIGNALING_REJECT;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = identifier;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_general_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, avdtp_signal_identifier_t identifier){
|
||||
void avdtp_signaling_emit_general_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, avdtp_signal_identifier_t identifier){
|
||||
if (!callback) return;
|
||||
uint8_t event[7];
|
||||
int pos = 0;
|
||||
@ -575,12 +585,12 @@ void avdtp_signaling_emit_general_reject(btstack_packet_handler_t callback, uint
|
||||
event[pos++] = AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = identifier;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_media_codec_sbc_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
void avdtp_signaling_emit_media_codec_sbc_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
if (!callback) return;
|
||||
uint8_t event[15];
|
||||
int pos = 0;
|
||||
@ -589,8 +599,8 @@ void avdtp_signaling_emit_media_codec_sbc_capability(btstack_packet_handler_t ca
|
||||
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = acp_seid;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = remote_seid;
|
||||
event[pos++] = media_codec.media_type;
|
||||
event[pos++] = media_codec.media_codec_information[0] >> 4;
|
||||
event[pos++] = media_codec.media_codec_information[0] & 0x0F;
|
||||
@ -602,7 +612,7 @@ void avdtp_signaling_emit_media_codec_sbc_capability(btstack_packet_handler_t ca
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_media_codec_other_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
void avdtp_signaling_emit_media_codec_other_capability(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
if (!callback) return;
|
||||
uint8_t event[111];
|
||||
int pos = 0;
|
||||
@ -611,8 +621,8 @@ void avdtp_signaling_emit_media_codec_other_capability(btstack_packet_handler_t
|
||||
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = acp_seid;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = remote_seid;
|
||||
event[pos++] = media_codec.media_type;
|
||||
little_endian_store_16(event, pos, media_codec.media_codec_type);
|
||||
pos += 2;
|
||||
@ -626,7 +636,7 @@ void avdtp_signaling_emit_media_codec_other_capability(btstack_packet_handler_t
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static inline void avdtp_signaling_emit_media_codec_sbc(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec, uint8_t reconfigure){
|
||||
static inline void avdtp_signaling_emit_media_codec_sbc(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec, uint8_t reconfigure){
|
||||
if (!callback) return;
|
||||
uint8_t event[16+2];
|
||||
int pos = 0;
|
||||
@ -636,8 +646,8 @@ static inline void avdtp_signaling_emit_media_codec_sbc(btstack_packet_handler_t
|
||||
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = acp_seid;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = remote_seid;
|
||||
event[pos++] = reconfigure;
|
||||
|
||||
uint8_t num_channels = 0;
|
||||
@ -706,17 +716,17 @@ static inline void avdtp_signaling_emit_media_codec_sbc(btstack_packet_handler_t
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_media_codec_sbc_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
void avdtp_signaling_emit_media_codec_sbc_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
if (!callback) return;
|
||||
avdtp_signaling_emit_media_codec_sbc(callback, avdtp_cid, int_seid, acp_seid, media_codec, 0);
|
||||
avdtp_signaling_emit_media_codec_sbc(callback, avdtp_cid, local_seid, remote_seid, media_codec, 0);
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_media_codec_sbc_reconfiguration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
void avdtp_signaling_emit_media_codec_sbc_reconfiguration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
if (!callback) return;
|
||||
avdtp_signaling_emit_media_codec_sbc(callback, avdtp_cid, int_seid, acp_seid, media_codec, 1);
|
||||
avdtp_signaling_emit_media_codec_sbc(callback, avdtp_cid, local_seid, remote_seid, media_codec, 1);
|
||||
}
|
||||
|
||||
static inline void avdtp_signaling_emit_media_codec_other(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec, uint8_t reconfigure){
|
||||
static inline void avdtp_signaling_emit_media_codec_other(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec, uint8_t reconfigure){
|
||||
uint8_t event[112];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVDTP_META;
|
||||
@ -724,8 +734,8 @@ static inline void avdtp_signaling_emit_media_codec_other(btstack_packet_handler
|
||||
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = acp_seid;
|
||||
event[pos++] = local_seid;
|
||||
event[pos++] = remote_seid;
|
||||
event[pos++] = reconfigure;
|
||||
|
||||
event[pos++] = media_codec.media_type;
|
||||
@ -742,14 +752,14 @@ static inline void avdtp_signaling_emit_media_codec_other(btstack_packet_handler
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_media_codec_other_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
void avdtp_signaling_emit_media_codec_other_configuration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
if (!callback) return;
|
||||
avdtp_signaling_emit_media_codec_other(callback, avdtp_cid, int_seid, acp_seid, media_codec, 0);
|
||||
avdtp_signaling_emit_media_codec_other(callback, avdtp_cid, local_seid, remote_seid, media_codec, 0);
|
||||
}
|
||||
|
||||
void avdtp_signaling_emit_media_codec_other_reconfiguration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
void avdtp_signaling_emit_media_codec_other_reconfiguration(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, adtvp_media_codec_capabilities_t media_codec){
|
||||
if (!callback) return;
|
||||
avdtp_signaling_emit_media_codec_other(callback, avdtp_cid, int_seid, acp_seid, media_codec, 1);
|
||||
avdtp_signaling_emit_media_codec_other(callback, avdtp_cid, local_seid, remote_seid, media_codec, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -790,4 +800,16 @@ uint8_t avdtp_find_remote_sep(avdtp_connection_t * connection, uint8_t remote_se
|
||||
}
|
||||
return AVDTP_INVALID_SEP_INDEX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t avdtp_local_seid(avdtp_stream_endpoint_t * stream_endpoint){
|
||||
if (!stream_endpoint) return 0;
|
||||
return stream_endpoint->sep.seid;
|
||||
|
||||
}
|
||||
|
||||
uint8_t avdtp_remote_seid(avdtp_stream_endpoint_t * stream_endpoint){
|
||||
if (!stream_endpoint) return 0;
|
||||
if (!stream_endpoint->connection) return 0;
|
||||
return stream_endpoint->connection->remote_seps[stream_endpoint->remote_sep_index].seid;
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ extern "C" {
|
||||
#define AVDTP_INVALID_SEP_INDEX 0xff
|
||||
|
||||
avdtp_connection_t * avdtp_connection_for_bd_addr(bd_addr_t addr, avdtp_context_t * context);
|
||||
avdtp_connection_t * avdtp_connection_for_l2cap_signaling_cid(uint16_t l2cap_cid, avdtp_context_t * context);
|
||||
avdtp_connection_t * avdtp_connection_for_avdtp_cid(uint16_t l2cap_cid, avdtp_context_t * context);
|
||||
avdtp_connection_t * avdtp_connection_for_tl2cap_signaling_cid(uint16_t l2cap_cid, avdtp_context_t * context);
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_for_l2cap_cid(uint16_t l2cap_cid, avdtp_context_t * context);
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_with_seid(uint8_t seid, avdtp_context_t * context);
|
||||
avdtp_stream_endpoint_t * avdtp_stream_endpoint_associated_with_acp_seid(uint16_t acp_seid, avdtp_context_t * context);
|
||||
@ -80,7 +81,7 @@ int avdtp_signaling_create_fragment(uint16_t cid, avdtp_signaling_packet_t * sig
|
||||
void avdtp_signaling_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, bd_addr_t addr, uint8_t status);
|
||||
void avdtp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint8_t status);
|
||||
void avdtp_signaling_emit_sep(btstack_packet_handler_t callback, uint16_t avdtp_cid, avdtp_sep_t sep);
|
||||
void avdtp_signaling_emit_accept(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t seid, avdtp_signal_identifier_t identifier, uint8_t status);
|
||||
void avdtp_signaling_emit_accept(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t seid, avdtp_signal_identifier_t identifier);
|
||||
void avdtp_signaling_emit_general_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, avdtp_signal_identifier_t identifier);
|
||||
void avdtp_signaling_emit_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, avdtp_signal_identifier_t identifier);
|
||||
void avdtp_streaming_emit_can_send_media_packet_now(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint16_t sequence_number);
|
||||
@ -101,6 +102,10 @@ uint8_t avdtp_get_index_of_remote_stream_endpoint_with_seid(avdtp_stream_endpoin
|
||||
void avdtp_initialize_stream_endpoint(avdtp_stream_endpoint_t * stream_endpoint);
|
||||
uint8_t avdtp_find_remote_sep(avdtp_connection_t * connection, uint8_t remote_seid);
|
||||
|
||||
// uint16_t avdtp_cid(avdtp_stream_endpoint_t * stream_endpoint);
|
||||
uint8_t avdtp_local_seid(avdtp_stream_endpoint_t * stream_endpoint);
|
||||
uint8_t avdtp_remote_seid(avdtp_stream_endpoint_t * stream_endpoint);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user