mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-05 00:40:19 +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
|
#ifdef HAVE_BTSTACK_STDIN
|
||||||
// mac 2011: static bd_addr_t remote = {0x04, 0x0C, 0xCE, 0xE4, 0x85, 0xD3};
|
// 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};
|
// pts: static bd_addr_t remote = {0x00, 0x1B, 0xDC, 0x08, 0x0A, 0xA5};
|
||||||
// mac 2013: static const char * device_addr_string = "00:1B:DC:08:0A:A5";
|
// mac 2013:
|
||||||
// iPhone 5S:
|
// mac 2013:
|
||||||
static const char * device_addr_string = "54:E4:3A:26:A2:39";
|
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
|
#endif
|
||||||
|
|
||||||
// bt dongle: -u 02-02 static bd_addr_t remote = {0x00, 0x02, 0x72, 0xDC, 0x31, 0xC1};
|
// 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(channel);
|
||||||
UNUSED(size);
|
UNUSED(size);
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
uint16_t cid;
|
||||||
|
|
||||||
switch (packet_type) {
|
switch (packet_type) {
|
||||||
case HCI_EVENT_PACKET:
|
case HCI_EVENT_PACKET:
|
||||||
@ -750,60 +752,61 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case A2DP_SUBEVENT_STREAM_ESTABLISHED:
|
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);
|
status = a2dp_subevent_stream_established_get_status(packet);
|
||||||
if (status != 0){
|
if (status != 0){
|
||||||
printf(" -- a2dp sink demo: streaming connection cannot be established, status 0x%02X\n", status);
|
printf(" -- a2dp sink demo: streaming connection cannot be established, status 0x%02X\n", status);
|
||||||
app_state = AVDTP_APPLICATION_IDLE;
|
app_state = AVDTP_APPLICATION_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
local_seid = a2dp_subevent_stream_established_get_local_seid(packet);
|
||||||
// TODO: check it it the correct a2dp cid
|
printf(" -- a2dp sink demo: streaming connection is established, a2dp cid 0x%02X, local_seid %d\n", a2dp_cid, local_seid);
|
||||||
a2dp_cid = a2dp_subevent_stream_established_get_a2dp_cid(packet);
|
|
||||||
printf(" -- a2dp sink demo: streaming connection is established, a2dp cid 0x%02X\n", status);
|
|
||||||
app_state = AVDTP_APPLICATION_STREAMING;
|
app_state = AVDTP_APPLICATION_STREAMING;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case A2DP_SUBEVENT_STREAM_STARTED:
|
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);
|
status = a2dp_subevent_stream_started_get_status(packet);
|
||||||
if (status != 0){
|
if (status != 0){
|
||||||
printf(" -- a2dp sink demo: stream cannot be started, status 0x%02X\n", status);
|
printf(" -- a2dp sink demo: stream cannot be started, status 0x%02X\n", status);
|
||||||
app_state = AVDTP_APPLICATION_IDLE;
|
app_state = AVDTP_APPLICATION_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
local_seid = a2dp_subevent_stream_started_get_local_seid(packet);
|
||||||
// TODO: check it it the correct a2dp cid
|
printf(" -- a2dp sink demo: stream started, a2dp cid 0x%02X, local_seid %d\n", a2dp_cid, local_seid);
|
||||||
a2dp_cid = a2dp_subevent_stream_started_get_a2dp_cid(packet);
|
|
||||||
printf(" -- a2dp sink demo: streaming, a2dp cid 0x%02X\n", status);
|
|
||||||
|
|
||||||
// started
|
// started
|
||||||
// media_processing_init(sbc_configuration);
|
// media_processing_init(sbc_configuration);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case A2DP_SUBEVENT_STREAM_SUSPENDED:
|
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);
|
status = a2dp_subevent_stream_suspended_get_status(packet);
|
||||||
if (status != 0){
|
if (status != 0){
|
||||||
printf(" -- a2dp sink demo: stream cannot be paused, status 0x%02X\n", status);
|
printf(" -- a2dp sink demo: stream cannot be paused, status 0x%02X\n", status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO: check it it the correct a2dp cid
|
local_seid = a2dp_subevent_stream_suspended_get_local_seid(packet);
|
||||||
a2dp_cid = a2dp_subevent_stream_started_get_a2dp_cid(packet);
|
printf(" -- a2dp sink demo: stream paused, a2dp cid 0x%02X, local_seid %d\n", a2dp_cid, local_seid);
|
||||||
printf(" -- a2dp sink demo: stream paused, a2dp cid 0x%02X\n", status);
|
|
||||||
|
|
||||||
// paused/stopped
|
// paused/stopped
|
||||||
// media_processing_close();
|
// media_processing_close();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case A2DP_SUBEVENT_STREAM_RELEASED:
|
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);
|
status = a2dp_subevent_stream_released_get_status(packet);
|
||||||
if (status != 0){
|
if (status != 0){
|
||||||
printf(" -- a2dp sink demo: stream cannot be released, status 0x%02X\n", status);
|
printf(" -- a2dp sink demo: stream cannot be released, status 0x%02X\n", status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
local_seid = a2dp_subevent_stream_released_get_local_seid(packet);
|
||||||
// TODO: check it it the correct a2dp cid
|
|
||||||
a2dp_cid = a2dp_subevent_stream_released_get_a2dp_cid(packet);
|
|
||||||
app_state = AVDTP_APPLICATION_IDLE;
|
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
|
// paused/stopped
|
||||||
media_processing_close();
|
media_processing_close();
|
||||||
@ -881,7 +884,7 @@ static void stdin_process(char cmd){
|
|||||||
switch (cmd){
|
switch (cmd){
|
||||||
case 'b':
|
case 'b':
|
||||||
printf("Creating L2CAP Connection to %s, PSM_AVDTP\n", bd_addr_to_str(device_addr));
|
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;
|
break;
|
||||||
case 'B':
|
case 'B':
|
||||||
printf("Disconnect\n");
|
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 uint16_t avdtp_cid = 0;
|
||||||
static uint8_t sdp_avdtp_sink_service_buffer[150];
|
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 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_media_codec_configuration_sbc_t sbc_configuration;
|
||||||
static avdtp_stream_endpoint_t * local_stream_endpoint;
|
static avdtp_stream_endpoint_t * local_stream_endpoint;
|
||||||
|
|
||||||
@ -190,6 +191,7 @@ static avdtp_capabilities_t remote_configuration;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
AVDTP_APPLICATION_IDLE,
|
AVDTP_APPLICATION_IDLE,
|
||||||
AVDTP_APPLICATION_CONNECTED,
|
AVDTP_APPLICATION_CONNECTED,
|
||||||
|
AVDTP_APPLICATION_STREAM_ESTABLISHED,
|
||||||
AVDTP_APPLICATION_STREAMING
|
AVDTP_APPLICATION_STREAMING
|
||||||
} avdtp_application_state_t;
|
} avdtp_application_state_t;
|
||||||
|
|
||||||
@ -552,16 +554,6 @@ static void handle_l2cap_media_data_packet(avdtp_stream_endpoint_t * stream_endp
|
|||||||
#endif
|
#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){
|
static void dump_sbc_configuration(avdtp_media_codec_configuration_sbc_t configuration){
|
||||||
printf("Received media codec configuration:\n");
|
printf("Received media codec configuration:\n");
|
||||||
printf(" - num_channels: %d\n", configuration.num_channels);
|
printf(" - num_channels: %d\n", configuration.num_channels);
|
||||||
@ -575,13 +567,15 @@ 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){
|
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||||
|
|
||||||
UNUSED(channel);
|
UNUSED(channel);
|
||||||
UNUSED(size);
|
UNUSED(size);
|
||||||
|
|
||||||
bd_addr_t event_addr;
|
bd_addr_t event_addr;
|
||||||
switch (packet_type) {
|
uint16_t cid;
|
||||||
|
uint8_t status;
|
||||||
|
uint8_t seid;
|
||||||
|
|
||||||
|
switch (packet_type){
|
||||||
case HCI_EVENT_PACKET:
|
case HCI_EVENT_PACKET:
|
||||||
switch (hci_event_packet_get_type(packet)){
|
switch (hci_event_packet_get_type(packet)){
|
||||||
case HCI_EVENT_PIN_CODE_REQUEST:
|
case HCI_EVENT_PIN_CODE_REQUEST:
|
||||||
@ -593,34 +587,16 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
|||||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||||
// connection closed -> quit test app
|
// connection closed -> quit test app
|
||||||
app_state = AVDTP_APPLICATION_IDLE;
|
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();
|
media_processing_close();
|
||||||
break;
|
break;
|
||||||
case HCI_EVENT_AVDTP_META:
|
case HCI_EVENT_AVDTP_META:
|
||||||
switch (packet[2]){
|
switch (packet[2]){
|
||||||
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
|
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;
|
app_state = AVDTP_APPLICATION_CONNECTED;
|
||||||
avdtp_cid = avdtp_subevent_signaling_connection_established_get_avdtp_cid(packet);
|
printf("\n --- AVDTP Sink Demo: AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, cid 0x%02x ---\n", cid);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
|
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
|
||||||
if (app_state < AVDTP_APPLICATION_CONNECTED) return;
|
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;
|
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:
|
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;
|
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:
|
default:
|
||||||
printf(" not implemented\n");
|
printf("\n --- AVDTP Sink Demo: not implemented %02x\n", packet[2]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -674,19 +670,21 @@ static void show_usage(void){
|
|||||||
bd_addr_t iut_address;
|
bd_addr_t iut_address;
|
||||||
gap_local_bd_addr(iut_address);
|
gap_local_bd_addr(iut_address);
|
||||||
printf("\n--- Bluetooth AVDTP SINK Test Console %s ---\n", bd_addr_to_str(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("C - disconnect\n");
|
||||||
printf("d - discover stream endpoints\n");
|
printf("d - discover stream endpoints\n");
|
||||||
printf("g - get capabilities\n");
|
printf("g - get capabilities\n");
|
||||||
printf("a - get all capabilities\n");
|
printf("a - get all capabilities\n");
|
||||||
printf("s - set configuration\n");
|
printf("s - set configuration\n");
|
||||||
printf("f - get configuration\n");
|
printf("f - get configuration\n");
|
||||||
printf("R - reconfigure stream with %d\n", sep.seid);
|
if (remote_seid){
|
||||||
printf("o - open stream with seid %d\n", sep.seid);
|
printf("R - reconfigure stream with %d\n", remote_seid);
|
||||||
printf("m - start stream with %d\n", sep.seid);
|
printf("o - open stream with seid %d\n", remote_seid);
|
||||||
printf("A - abort stream with %d\n", sep.seid);
|
printf("m - start stream with %d\n", remote_seid);
|
||||||
printf("S - stop stream with %d\n", sep.seid);
|
printf("A - abort stream with %d\n", remote_seid);
|
||||||
printf("P - suspend stream with %d\n", sep.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("Ctrl-c - exit\n");
|
||||||
printf("---\n");
|
printf("---\n");
|
||||||
}
|
}
|
||||||
@ -712,11 +710,11 @@ static uint8_t media_sbc_codec_reconfiguration[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void stdin_process(char cmd){
|
static void stdin_process(char cmd){
|
||||||
sep.seid = 1;
|
uint8_t status = 0;
|
||||||
switch (cmd){
|
switch (cmd){
|
||||||
case 'c':
|
case 'c':
|
||||||
printf("Creating L2CAP Connection to %s, BLUETOOTH_PROTOCOL_AVDTP\n", bd_addr_to_str(remote));
|
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;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
printf("Disconnect\n");
|
printf("Disconnect\n");
|
||||||
@ -726,13 +724,13 @@ static void stdin_process(char cmd){
|
|||||||
avdtp_sink_discover_stream_endpoints(avdtp_cid);
|
avdtp_sink_discover_stream_endpoints(avdtp_cid);
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
avdtp_sink_get_capabilities(avdtp_cid, sep.seid);
|
avdtp_sink_get_capabilities(avdtp_cid, remote_seid);
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
avdtp_sink_get_all_capabilities(avdtp_cid, sep.seid);
|
avdtp_sink_get_all_capabilities(avdtp_cid, remote_seid);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
avdtp_sink_get_configuration(avdtp_cid, sep.seid);
|
avdtp_sink_get_configuration(avdtp_cid, remote_seid);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
remote_configuration_bitmap = store_bit16(remote_configuration_bitmap, AVDTP_MEDIA_CODEC, 1);
|
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_type = AVDTP_CODEC_SBC;
|
||||||
remote_configuration.media_codec.media_codec_information_len = sizeof(media_sbc_codec_configuration);
|
remote_configuration.media_codec.media_codec_information_len = sizeof(media_sbc_codec_configuration);
|
||||||
remote_configuration.media_codec.media_codec_information = 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;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
remote_configuration_bitmap = store_bit16(remote_configuration_bitmap, AVDTP_MEDIA_CODEC, 1);
|
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_type = AVDTP_CODEC_SBC;
|
||||||
remote_configuration.media_codec.media_codec_information_len = sizeof(media_sbc_codec_reconfiguration);
|
remote_configuration.media_codec.media_codec_information_len = sizeof(media_sbc_codec_reconfiguration);
|
||||||
remote_configuration.media_codec.media_codec_information = 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;
|
break;
|
||||||
case 'o':
|
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;
|
break;
|
||||||
case 'm':
|
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;
|
break;
|
||||||
case 'A':
|
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;
|
break;
|
||||||
case 'S':
|
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;
|
break;
|
||||||
case 'P':
|
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;
|
break;
|
||||||
|
|
||||||
case '\n':
|
case '\n':
|
||||||
@ -774,6 +777,9 @@ static void stdin_process(char cmd){
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (status != 0){
|
||||||
|
printf("Command failed with status %d\n", status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -795,9 +801,11 @@ int btstack_main(int argc, const char * argv[]){
|
|||||||
|
|
||||||
//#ifndef SMG_BI
|
//#ifndef SMG_BI
|
||||||
local_stream_endpoint = avdtp_sink_create_stream_endpoint(AVDTP_SINK, AVDTP_AUDIO);
|
local_stream_endpoint = avdtp_sink_create_stream_endpoint(AVDTP_SINK, AVDTP_AUDIO);
|
||||||
local_stream_endpoint->sep.seid = 1;
|
local_stream_endpoint->sep.seid = 5;
|
||||||
avdtp_sink_register_media_transport_category(local_stream_endpoint->sep.seid);
|
local_seid = 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));
|
|
||||||
|
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
|
//#endif
|
||||||
// uint8_t cp_type_lsb, uint8_t cp_type_msb, const uint8_t * cp_type_value, uint8_t cp_type_value_len
|
// uint8_t cp_type_lsb, uint8_t cp_type_msb, const uint8_t * cp_type_value, uint8_t cp_type_value_len
|
||||||
// avdtp_sink_register_content_protection_category(seid, 2, 2, NULL, 0);
|
// avdtp_sink_register_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:
|
case A2DP_SUBEVENT_STREAM_STARTED:
|
||||||
if (local_seid != media_tracker.local_seid) break;
|
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);
|
a2dp_fill_audio_buffer_timer_start(&media_tracker);
|
||||||
printf(" --- application --- A2DP_SUBEVENT_STREAM_START_ACCEPTED, local seid %d\n", media_tracker.local_seid);
|
printf(" --- application --- A2DP_SUBEVENT_STREAM_START_ACCEPTED, local seid %d\n", media_tracker.local_seid);
|
||||||
break;
|
break;
|
||||||
@ -349,7 +349,7 @@ static void stdin_process(char cmd){
|
|||||||
switch (cmd){
|
switch (cmd){
|
||||||
case 'c':
|
case 'c':
|
||||||
printf("Creating L2CAP Connection to %s, PSM_AVDTP\n", bd_addr_to_str(remote));
|
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;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
printf("Disconnect\n");
|
printf("Disconnect\n");
|
||||||
@ -358,20 +358,20 @@ static void stdin_process(char cmd){
|
|||||||
case 'x':
|
case 'x':
|
||||||
printf("Stream sine, local seid %d\n", media_tracker.local_seid);
|
printf("Stream sine, local seid %d\n", media_tracker.local_seid);
|
||||||
data_source = STREAM_SINE;
|
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;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
printf("Stream mode, local seid %d\n", media_tracker.local_seid);
|
printf("Stream mode, local seid %d\n", media_tracker.local_seid);
|
||||||
data_source = STREAM_MOD;
|
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;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
printf("Pause stream, local seid %d\n", media_tracker.local_seid);
|
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;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
printf("Close stream, local seid %d\n", media_tracker.local_seid);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
show_usage();
|
show_usage();
|
||||||
|
@ -177,6 +177,13 @@ typedef uint8_t sm_key_t[16];
|
|||||||
#define OBEX_CONNECT_FAILED 0xB1
|
#define OBEX_CONNECT_FAILED 0xB1
|
||||||
#define OBEX_DISCONNECTED 0xB2
|
#define OBEX_DISCONNECTED 0xB2
|
||||||
#define OBEX_NOT_FOUND 0xB3
|
#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 */
|
/* ENUM_END */
|
||||||
|
|
||||||
// DAEMON COMMANDS
|
// DAEMON COMMANDS
|
||||||
@ -1274,7 +1281,7 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 1211
|
* @format 1211
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param int_seid
|
* @param local_seid
|
||||||
* @param signal_identifier
|
* @param signal_identifier
|
||||||
*/
|
*/
|
||||||
#define AVDTP_SUBEVENT_SIGNALING_REJECT 0x02
|
#define AVDTP_SUBEVENT_SIGNALING_REJECT 0x02
|
||||||
@ -1283,7 +1290,7 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 1211
|
* @format 1211
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param int_seid
|
* @param local_seid
|
||||||
* @param signal_identifier
|
* @param signal_identifier
|
||||||
*/
|
*/
|
||||||
#define AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT 0x03
|
#define AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT 0x03
|
||||||
@ -1308,7 +1315,7 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 121111
|
* @format 121111
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param seid 0x01 – 0x3E
|
* @param remote_seid 0x01 – 0x3E
|
||||||
* @param in_use 0-not in use, 1-in use
|
* @param in_use 0-not in use, 1-in use
|
||||||
* @param media_type 0-audio, 1-video, 2-multimedia
|
* @param media_type 0-audio, 1-video, 2-multimedia
|
||||||
* @param sep_type 0-source, 1-sink
|
* @param sep_type 0-source, 1-sink
|
||||||
@ -1319,8 +1326,8 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 121111111111
|
* @format 121111111111
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param int_seid
|
* @param local_seid
|
||||||
* @param acp_seid
|
* @param remote_seid
|
||||||
* @param media_type
|
* @param media_type
|
||||||
* @param sampling_frequency_bitmap
|
* @param sampling_frequency_bitmap
|
||||||
* @param channel_mode_bitmap
|
* @param channel_mode_bitmap
|
||||||
@ -1336,8 +1343,8 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 121112LV
|
* @format 121112LV
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param int_seid
|
* @param local_seid
|
||||||
* @param acp_seid
|
* @param remote_seid
|
||||||
* @param media_type
|
* @param media_type
|
||||||
* @param media_codec_type
|
* @param media_codec_type
|
||||||
* @param media_codec_information_len
|
* @param media_codec_information_len
|
||||||
@ -1349,8 +1356,8 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 12111121111111
|
* @format 12111121111111
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param int_seid
|
* @param local_seid
|
||||||
* @param acp_seid
|
* @param remote_seid
|
||||||
* @param reconfigure
|
* @param reconfigure
|
||||||
* @param media_type
|
* @param media_type
|
||||||
* @param sampling_frequency
|
* @param sampling_frequency
|
||||||
@ -1368,8 +1375,8 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 1211112LV
|
* @format 1211112LV
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param int_seid
|
* @param local_seid
|
||||||
* @param acp_seid
|
* @param remote_seid
|
||||||
* @param reconfigure
|
* @param reconfigure
|
||||||
* @param media_type
|
* @param media_type
|
||||||
* @param media_codec_type
|
* @param media_codec_type
|
||||||
@ -1382,8 +1389,8 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 12111
|
* @format 12111
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param int_seid
|
* @param local_seid
|
||||||
* @param acp_seid
|
* @param remote_seid
|
||||||
* @param status 0 == OK
|
* @param status 0 == OK
|
||||||
*/
|
*/
|
||||||
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED 0x0B
|
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED 0x0B
|
||||||
@ -1399,7 +1406,7 @@ typedef uint8_t sm_key_t[16];
|
|||||||
* @format 1212
|
* @format 1212
|
||||||
* @param subevent_code
|
* @param subevent_code
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param int_seid
|
* @param local_seid
|
||||||
* @param sequence_number
|
* @param sequence_number
|
||||||
*/
|
*/
|
||||||
#define AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW 0x0D
|
#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);
|
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
|
* @param event packet
|
||||||
* @return int_seid
|
* @return local_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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);
|
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
|
* @param event packet
|
||||||
* @return int_seid
|
* @return local_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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);
|
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
|
* @param event packet
|
||||||
* @return seid
|
* @return remote_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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);
|
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
|
* @param event packet
|
||||||
* @return int_seid
|
* @return local_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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
|
* @param event packet
|
||||||
* @return acp_seid
|
* @return remote_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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);
|
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
|
* @param event packet
|
||||||
* @return int_seid
|
* @return local_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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
|
* @param event packet
|
||||||
* @return acp_seid
|
* @return remote_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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);
|
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
|
* @param event packet
|
||||||
* @return int_seid
|
* @return local_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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
|
* @param event packet
|
||||||
* @return acp_seid
|
* @return remote_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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);
|
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
|
* @param event packet
|
||||||
* @return int_seid
|
* @return local_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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
|
* @param event packet
|
||||||
* @return acp_seid
|
* @return remote_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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);
|
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
|
* @param event packet
|
||||||
* @return int_seid
|
* @return local_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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
|
* @param event packet
|
||||||
* @return acp_seid
|
* @return remote_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
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);
|
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
|
* @param event packet
|
||||||
* @return int_seid
|
* @return local_seid
|
||||||
* @note: btstack_type 1
|
* @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];
|
return event[5];
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -55,8 +55,6 @@ static avdtp_context_t a2dp_sink_context;
|
|||||||
|
|
||||||
static a2dp_state_t app_state = A2DP_IDLE;
|
static a2dp_state_t app_state = A2DP_IDLE;
|
||||||
static avdtp_stream_endpoint_context_t sc;
|
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);
|
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);
|
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){
|
void a2dp_sink_register_packet_handler(btstack_packet_handler_t callback){
|
||||||
// avdtp_sink_register_packet_handler(callback);
|
// avdtp_sink_register_packet_handler(callback);
|
||||||
// return;
|
// 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;
|
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);
|
sc.local_stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_sink_context);
|
||||||
if (!sc.local_stream_endpoint){
|
if (!sc.local_stream_endpoint){
|
||||||
log_error(" no local_stream_endpoint for seid %d", local_seid);
|
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){
|
void a2dp_sink_disconnect(uint16_t a2dp_cid){
|
||||||
avdtp_disconnect(a2dp_cid, &a2dp_sink_context);
|
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 (!callback) return;
|
||||||
if (event_size < 8) return;
|
uint8_t event[8];
|
||||||
event[0] = HCI_EVENT_A2DP_META;
|
int pos = 0;
|
||||||
event[2] = A2DP_SUBEVENT_STREAM_ESTABLISHED;
|
event[pos++] = HCI_EVENT_A2DP_META;
|
||||||
(*callback)(HCI_EVENT_PACKET, 0, event, event_size);
|
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){
|
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 status;
|
||||||
uint8_t signal_identifier;
|
uint8_t signal_identifier;
|
||||||
uint16_t cid;
|
uint16_t cid;
|
||||||
uint8_t local_seid;
|
uint8_t loc_seid;
|
||||||
|
|
||||||
switch (packet_type) {
|
switch (packet_type) {
|
||||||
case HCI_EVENT_PACKET:
|
case HCI_EVENT_PACKET:
|
||||||
switch (hci_event_packet_get_type(packet)) {
|
switch (hci_event_packet_get_type(packet)) {
|
||||||
case HCI_EVENT_PIN_CODE_REQUEST:
|
case HCI_EVENT_PIN_CODE_REQUEST:
|
||||||
// inform about 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_event_pin_code_request_get_bd_addr(packet, event_addr);
|
||||||
hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
|
hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
|
||||||
break;
|
break;
|
||||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||||
// connection closed -> quit test app
|
// connection closed -> quit test app
|
||||||
app_state = A2DP_IDLE;
|
app_state = A2DP_IDLE;
|
||||||
printf("\n --- a2dp sink: HCI_EVENT_DISCONNECTION_COMPLETE ---\n");
|
printf("\na2dp sink: HCI_EVENT_DISCONNECTION_COMPLETE ---\n");
|
||||||
break;
|
break;
|
||||||
case HCI_EVENT_AVDTP_META:
|
case HCI_EVENT_AVDTP_META:
|
||||||
switch (packet[2]){
|
switch (packet[2]){
|
||||||
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
|
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);
|
status = avdtp_subevent_signaling_connection_established_get_status(packet);
|
||||||
if (status != 0){
|
if (status != 0){
|
||||||
log_info(" --- a2dp sink --- AVDTP_SUBEVENT_SIGNALING_CONNECTION could not be established, status %d ---", status);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
app_state = A2DP_CONNECTED;
|
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 ---", a2dp_cid());
|
||||||
log_info(" --- a2dp sink --- AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, avdtp cid 0x%02x ---", avdtp_cid);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION:
|
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);
|
avdtp_signaling_emit_media_codec_other(a2dp_sink_context.a2dp_callback, packet, size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -279,7 +307,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
|||||||
} else {
|
} else {
|
||||||
app_state = A2DP_STREAMING_OPENED;
|
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;
|
break;
|
||||||
|
|
||||||
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
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;
|
status = 0;
|
||||||
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||||
cid = avdtp_subevent_signaling_accept_get_avdtp_cid(packet);
|
cid = avdtp_subevent_signaling_accept_get_avdtp_cid(packet);
|
||||||
local_seid = avdtp_subevent_signaling_accept_get_local_seid(packet);
|
loc_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);
|
|
||||||
|
|
||||||
switch (signal_identifier){
|
switch (signal_identifier){
|
||||||
case AVDTP_SI_START:
|
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;
|
break;
|
||||||
case AVDTP_SI_SUSPEND:
|
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;
|
break;
|
||||||
case AVDTP_SI_ABORT:
|
case AVDTP_SI_ABORT:
|
||||||
case AVDTP_SI_CLOSE:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -312,19 +339,18 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
|||||||
status = 1;
|
status = 1;
|
||||||
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||||
cid = avdtp_subevent_signaling_accept_get_avdtp_cid(packet);
|
cid = avdtp_subevent_signaling_accept_get_avdtp_cid(packet);
|
||||||
local_seid = avdtp_subevent_signaling_accept_get_local_seid(packet);
|
loc_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);
|
|
||||||
|
|
||||||
switch (signal_identifier){
|
switch (signal_identifier){
|
||||||
case AVDTP_SI_START:
|
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;
|
break;
|
||||||
case AVDTP_SI_SUSPEND:
|
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;
|
break;
|
||||||
case AVDTP_SI_ABORT:
|
case AVDTP_SI_ABORT:
|
||||||
case AVDTP_SI_CLOSE:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -332,7 +358,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
app_state = A2DP_IDLE;
|
app_state = A2DP_IDLE;
|
||||||
log_info(" --- a2dp sink --- not implemented");
|
log_info("a2dp sink: not implemented");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -88,10 +88,12 @@ void a2dp_sink_register_media_handler(void (*callback)(avdtp_stream_endpoint_t *
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Open stream
|
* @brief Open stream
|
||||||
* @param avdtp_cid
|
* @param bd_addr
|
||||||
* @param local_seid
|
* @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
|
* @brief Start stream
|
||||||
|
@ -57,7 +57,6 @@ static avdtp_context_t a2dp_source_context;
|
|||||||
|
|
||||||
static a2dp_state_t app_state = A2DP_IDLE;
|
static a2dp_state_t app_state = A2DP_IDLE;
|
||||||
static avdtp_stream_endpoint_context_t sc;
|
static avdtp_stream_endpoint_context_t sc;
|
||||||
static uint16_t avdtp_cid = 0;
|
|
||||||
static int next_remote_sep_index_to_query = 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);
|
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);
|
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){
|
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 (!callback) return;
|
||||||
uint8_t event[8];
|
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 signal_identifier;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
avdtp_sep_t sep;
|
avdtp_sep_t sep;
|
||||||
uint8_t int_seid;
|
uint8_t loc_seid;
|
||||||
uint8_t acp_seid;
|
uint8_t rem_seid;
|
||||||
|
uint16_t cid;
|
||||||
|
|
||||||
switch (packet_type) {
|
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:
|
case HCI_EVENT_AVDTP_META:
|
||||||
switch (packet[2]){
|
switch (packet[2]){
|
||||||
case AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
|
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);
|
status = avdtp_subevent_signaling_connection_established_get_status(packet);
|
||||||
if (status != 0){
|
if (status != 0){
|
||||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_SIGNALING_CONNECTION could not be established, status %d ---", status);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
sc.active_remote_sep = NULL;
|
sc.active_remote_sep = NULL;
|
||||||
next_remote_sep_index_to_query = 0;
|
next_remote_sep_index_to_query = 0;
|
||||||
app_state = A2DP_W2_DISCOVER_SEPS;
|
app_state = A2DP_W2_DISCOVER_SEPS;
|
||||||
log_info(" --- a2dp source --- AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, avdtp cid 0x%02x ---", avdtp_cid);
|
log_info(" --- a2dp source --- AVDTP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED, avdtp cid 0x%02x ---", a2dp_cid());
|
||||||
avdtp_source_discover_stream_endpoints(avdtp_cid);
|
avdtp_source_discover_stream_endpoints(a2dp_cid());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
|
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
|
||||||
status = avdtp_subevent_streaming_connection_established_get_status(packet);
|
status = avdtp_subevent_streaming_connection_established_get_status(packet);
|
||||||
avdtp_cid = avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet);
|
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){
|
if (cid != a2dp_cid()){
|
||||||
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(), remote_seid(), ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER);
|
||||||
break;
|
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;
|
app_state = A2DP_STREAMING_OPENED;
|
||||||
a2dp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, avdtp_cid, int_seid, acp_seid, 0);
|
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", avdtp_cid, int_seid, acp_seid);
|
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;
|
break;
|
||||||
|
|
||||||
case AVDTP_SUBEVENT_SIGNALING_SEP_FOUND:
|
case AVDTP_SUBEVENT_SIGNALING_SEP_FOUND:
|
||||||
|
// TODO check cid
|
||||||
if (app_state != A2DP_W2_DISCOVER_SEPS) return;
|
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.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.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);
|
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;
|
break;
|
||||||
|
|
||||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY:{
|
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY:{
|
||||||
|
// TODO check cid
|
||||||
if (!sc.local_stream_endpoint) return;
|
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 sampling_frequency = avdtp_choose_sbc_sampling_frequency(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_sampling_frequency_bitmap(packet));
|
||||||
uint8_t channel_mode = avdtp_choose_sbc_channel_mode(sc.local_stream_endpoint, avdtp_subevent_signaling_media_codec_sbc_capability_get_channel_mode_bitmap(packet));
|
uint8_t 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;
|
break;
|
||||||
|
|
||||||
case AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION:{
|
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.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.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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:
|
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;
|
break;
|
||||||
|
|
||||||
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
||||||
|
// TODO check cid
|
||||||
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||||
log_info(" --- a2dp source --- Accepted %d", signal_identifier);
|
log_info(" --- a2dp source --- Accepted %d", signal_identifier);
|
||||||
|
|
||||||
switch (app_state){
|
switch (app_state){
|
||||||
case A2DP_W2_DISCOVER_SEPS:
|
case A2DP_W2_DISCOVER_SEPS:
|
||||||
app_state = A2DP_W2_GET_ALL_CAPABILITIES;
|
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);
|
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;
|
break;
|
||||||
case A2DP_W2_GET_CAPABILITIES:
|
case A2DP_W2_GET_CAPABILITIES:
|
||||||
case A2DP_W2_GET_ALL_CAPABILITIES:
|
case A2DP_W2_GET_ALL_CAPABILITIES:
|
||||||
if (next_remote_sep_index_to_query < avdtp_source_remote_seps_num(avdtp_cid)){
|
if (next_remote_sep_index_to_query < avdtp_source_remote_seps_num(a2dp_cid())){
|
||||||
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);
|
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 {
|
} else {
|
||||||
log_info(" --- a2dp source --- No more remote seps found");
|
log_info(" --- a2dp source --- No more remote seps found");
|
||||||
app_state = A2DP_IDLE;
|
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:{
|
case A2DP_W2_SET_CONFIGURATION:{
|
||||||
if (!sc.local_stream_endpoint) return;
|
if (!sc.local_stream_endpoint) return;
|
||||||
app_state = A2DP_W2_GET_CONFIGURATION;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case A2DP_W2_GET_CONFIGURATION:
|
case A2DP_W2_GET_CONFIGURATION:
|
||||||
app_state = A2DP_W2_OPEN_STREAM_WITH_SEID;
|
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;
|
break;
|
||||||
case A2DP_W2_OPEN_STREAM_WITH_SEID:{
|
case A2DP_W2_OPEN_STREAM_WITH_SEID:{
|
||||||
app_state = A2DP_W4_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.block_length, sc.subbands,
|
||||||
sc.allocation_method, sc.sampling_frequency,
|
sc.allocation_method, sc.sampling_frequency,
|
||||||
sc.max_bitpool_value);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case A2DP_STREAMING_OPENED:
|
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++] = HCI_EVENT_A2DP_META;
|
||||||
event[pos++] = sizeof(event) - 2;
|
event[pos++] = sizeof(event) - 2;
|
||||||
event[pos++] = A2DP_SUBEVENT_STREAM_STARTED;
|
event[pos++] = A2DP_SUBEVENT_STREAM_STARTED;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, a2dp_cid());
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
||||||
(*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
(*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++] = HCI_EVENT_A2DP_META;
|
||||||
event[pos++] = sizeof(event) - 2;
|
event[pos++] = sizeof(event) - 2;
|
||||||
event[pos++] = A2DP_SUBEVENT_STREAM_SUSPENDED;
|
event[pos++] = A2DP_SUBEVENT_STREAM_SUSPENDED;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, a2dp_cid());
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
||||||
(*a2dp_source_context.a2dp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
(*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++] = HCI_EVENT_A2DP_META;
|
||||||
event[pos++] = sizeof(event) - 2;
|
event[pos++] = sizeof(event) - 2;
|
||||||
event[pos++] = A2DP_SUBEVENT_STREAM_RELEASED;
|
event[pos++] = A2DP_SUBEVENT_STREAM_RELEASED;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, a2dp_cid());
|
||||||
pos += 2;
|
pos += 2;
|
||||||
log_info("send A2DP_SUBEVENT_STREAM_RELEASED to app");
|
log_info("send A2DP_SUBEVENT_STREAM_RELEASED to app");
|
||||||
event[pos++] = avdtp_stream_endpoint_seid(sc.local_stream_endpoint);
|
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;
|
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);
|
sc.local_stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
|
||||||
if (!sc.local_stream_endpoint){
|
if (!sc.local_stream_endpoint){
|
||||||
log_error(" no local_stream_endpoint for seid %d", local_seid);
|
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){
|
uint8_t a2dp_source_disconnect(uint16_t avdtp_cid){
|
||||||
avdtp_disconnect(local_seid, &a2dp_source_context);
|
return avdtp_disconnect(avdtp_cid, &a2dp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void a2dp_source_start_stream(uint8_t int_seid){
|
uint8_t a2dp_source_start_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_start_stream(int_seid, &a2dp_source_context);
|
return avdtp_start_stream(avdtp_cid, local_seid, &a2dp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void a2dp_source_release_stream(uint8_t int_seid){
|
uint8_t a2dp_source_release_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_stop_stream(int_seid, &a2dp_source_context);
|
return avdtp_stop_stream(avdtp_cid, local_seid, &a2dp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void a2dp_source_pause_stream(uint8_t int_seid){
|
uint8_t a2dp_source_pause_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_suspend_stream(int_seid, &a2dp_source_context);
|
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);
|
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
|
||||||
if (!stream_endpoint) {
|
if (!stream_endpoint) {
|
||||||
log_error("No stream_endpoint with seid %d", local_seid);
|
log_error("No stream_endpoint with seid %d", local_seid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (!stream_endpoint->connection || stream_endpoint->connection->avdtp_cid != avdtp_cid) return 0;
|
||||||
return (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING);
|
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);
|
avdtp_request_can_send_now_initiator(stream_endpoint->connection, stream_endpoint->l2cap_media_cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int a2dp_max_media_payload_size(uint8_t int_seid){
|
int a2dp_max_media_payload_size(uint8_t local_seid){
|
||||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, &a2dp_source_context);
|
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
|
||||||
if (!stream_endpoint) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
if (stream_endpoint->l2cap_media_cid == 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 0;
|
||||||
}
|
}
|
||||||
return l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid) - AVDTP_MEDIA_PAYLOAD_HEADER_SIZE;
|
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;
|
*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){
|
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(int_seid, &a2dp_source_context);
|
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
|
||||||
if (!stream_endpoint) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream_endpoint->l2cap_media_cid == 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 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,47 +74,48 @@ uint8_t a2dp_source_create_stream_endpoint(avdtp_media_type_t media_type, avdtp_
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Open stream
|
* @brief Open stream
|
||||||
|
* @param bd_addr
|
||||||
|
* @param local_seid
|
||||||
* @param avdtp_cid
|
* @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
|
* @brief Start stream
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param seid
|
* @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
|
* @brief Start stream
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param seid
|
* @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
|
* @brief Close stream
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
* @param seid
|
* @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.
|
* @brief Disconnect from device with cid.
|
||||||
* @param avdtp_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)
|
// 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);
|
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 */
|
/* API_END */
|
||||||
|
|
||||||
|
@ -61,11 +61,28 @@ typedef struct {
|
|||||||
} avdtp_sdp_query_context_t;
|
} avdtp_sdp_query_context_t;
|
||||||
|
|
||||||
static avdtp_sdp_query_context_t sdp_query_context;
|
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 (*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);
|
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;
|
sdp_query_context.connection = NULL;
|
||||||
avdtp_connection_t * connection = avdtp_connection_for_bd_addr(remote, avdtp_context);
|
avdtp_connection_t * connection = avdtp_connection_for_bd_addr(remote, avdtp_context);
|
||||||
if (!connection){
|
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){
|
if (connection->state != AVDTP_SIGNALING_CONNECTION_IDLE){
|
||||||
log_error("avdtp_connect: sink in wrong state,");
|
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;
|
connection->state = AVDTP_SIGNALING_W4_SDP_QUERY_COMPLETE;
|
||||||
sdp_query_context.connection = connection;
|
sdp_query_context.connection = connection;
|
||||||
sdp_query_context.query_role = query_role;
|
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_query_context.packet_handler = avdtp_context->packet_handler;
|
||||||
|
|
||||||
sdp_client_query_uuid16(&avdtp_handle_sdp_client_query_result, remote, BLUETOOTH_PROTOCOL_AVDTP);
|
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){
|
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->connection == connection){
|
||||||
if (stream_endpoint->state >= AVDTP_STREAM_ENDPOINT_OPENED && stream_endpoint->state != AVDTP_STREAM_ENDPOINT_W4_L2CAP_FOR_MEDIA_DISCONNECTED){
|
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;
|
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);
|
l2cap_disconnect(stream_endpoint->l2cap_media_cid, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -197,7 +221,7 @@ void avdtp_handle_can_send_now(avdtp_connection_t * connection, uint16_t l2cap_c
|
|||||||
}
|
}
|
||||||
connection->disconnect = 0;
|
connection->disconnect = 0;
|
||||||
connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED;
|
connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED;
|
||||||
l2cap_disconnect(connection->l2cap_signaling_cid, 0);
|
l2cap_disconnect(connection->tl2cap_signaling_cid, 0);
|
||||||
return;
|
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 * 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();
|
avdtp_stream_endpoint_t * stream_endpoint = btstack_memory_avdtp_stream_endpoint_get();
|
||||||
memset(stream_endpoint, 0, sizeof(avdtp_stream_endpoint_t));
|
memset(stream_endpoint, 0, sizeof(avdtp_stream_endpoint_t));
|
||||||
context->stream_endpoints_id_counter++;
|
stream_endpoint->sep.seid = avdtp_get_next_local_seid(context);
|
||||||
stream_endpoint->sep.seid = context->stream_endpoints_id_counter;
|
|
||||||
stream_endpoint->sep.media_type = media_type;
|
stream_endpoint->sep.media_type = media_type;
|
||||||
stream_endpoint->sep.type = sep_type;
|
stream_endpoint->sep.type = sep_type;
|
||||||
btstack_linked_list_add(&context->stream_endpoints, (btstack_linked_item_t *) stream_endpoint);
|
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){
|
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;
|
uint16_t local_cid;
|
||||||
|
uint8_t status;
|
||||||
switch (packet_type){
|
switch (packet_type){
|
||||||
case L2CAP_DATA_PACKET:{
|
case L2CAP_DATA_PACKET:{
|
||||||
int offset = avdtp_read_signaling_header(&connection->signaling_packet, packet, size);
|
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){
|
switch (event){
|
||||||
case L2CAP_EVENT_CHANNEL_OPENED:
|
case L2CAP_EVENT_CHANNEL_OPENED:
|
||||||
if (stream_endpoint->l2cap_media_cid == 0){
|
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->state = AVDTP_STREAM_ENDPOINT_OPENED;
|
||||||
stream_endpoint->connection = connection;
|
stream_endpoint->connection = connection;
|
||||||
stream_endpoint->l2cap_media_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
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);
|
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;
|
||||||
}
|
}
|
||||||
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:
|
case BLUETOOTH_SERVICE_CLASS_AUDIO_SOURCE:
|
||||||
if (sdp_query_context.query_role != AVDTP_SOURCE) {
|
if (sdp_query_context.query_role != AVDTP_SOURCE) {
|
||||||
sdp_query_context.connection->state = AVDTP_SIGNALING_CONNECTION_IDLE;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
// log_info("SDP Attribute 0x%04x: AVDTP SOURCE protocol UUID: 0x%04x", sdp_event_query_attribute_byte_get_attribute_id(packet), uuid);
|
// 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:
|
case BLUETOOTH_SERVICE_CLASS_AUDIO_SINK:
|
||||||
if (sdp_query_context.query_role != AVDTP_SINK) {
|
if (sdp_query_context.query_role != AVDTP_SINK) {
|
||||||
sdp_query_context.connection->state = AVDTP_SIGNALING_CONNECTION_IDLE;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
// log_info("SDP Attribute 0x%04x: AVDTP SINK protocol UUID: 0x%04x", sdp_event_query_attribute_byte_get_attribute_id(packet), uuid);
|
// 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) {
|
if (!avdtp_l2cap_psm) {
|
||||||
sdp_query_context.connection->state = AVDTP_SIGNALING_CONNECTION_IDLE;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
sdp_query_context.connection->state = AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED;
|
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));
|
// log_info("avdtp_packet_handler packet type %02x, event %02x ", packet_type, hci_event_packet_get_type(packet));
|
||||||
switch (packet_type) {
|
switch (packet_type) {
|
||||||
case L2CAP_DATA_PACKET:
|
case L2CAP_DATA_PACKET:
|
||||||
connection = avdtp_connection_for_l2cap_signaling_cid(channel, context);
|
connection = avdtp_connection_for_tl2cap_signaling_cid(channel, context);
|
||||||
if (connection){
|
if (connection){
|
||||||
handle_l2cap_data_packet_for_signaling_connection(connection, packet, size, context);
|
handle_l2cap_data_packet_for_signaling_connection(connection, packet, size, context);
|
||||||
break;
|
break;
|
||||||
@ -443,7 +478,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
|||||||
break;
|
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);
|
stream_endpoint_state_machine(stream_endpoint->connection, stream_endpoint, L2CAP_DATA_PACKET, 0, packet, size, context);
|
||||||
break;
|
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);
|
l2cap_event_channel_opened_get_address(packet, event_addr);
|
||||||
local_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
local_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||||
if (l2cap_event_channel_opened_get_status(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",
|
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));
|
bd_addr_to_str(event_addr), l2cap_event_channel_opened_get_status(packet));
|
||||||
break;
|
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);
|
connection = avdtp_connection_for_bd_addr(event_addr, context);
|
||||||
if (!connection) break;
|
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;
|
if (connection->state != AVDTP_SIGNALING_CONNECTION_W4_L2CAP_CONNECTED) break;
|
||||||
connection->l2cap_signaling_cid = local_cid;
|
connection->tl2cap_signaling_cid = local_cid;
|
||||||
connection->con_handle = con_handle;
|
|
||||||
connection->query_seid = 0;
|
connection->query_seid = 0;
|
||||||
connection->state = AVDTP_SIGNALING_CONNECTION_OPENED;
|
connection->state = AVDTP_SIGNALING_CONNECTION_OPENED;
|
||||||
log_info(" -> AVDTP_SIGNALING_CONNECTION_OPENED, connection %p", connection);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,7 +577,7 @@ void avdtp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
|||||||
case L2CAP_EVENT_CHANNEL_CLOSED:
|
case L2CAP_EVENT_CHANNEL_CLOSED:
|
||||||
// data: event (8), len(8), channel (16)
|
// data: event (8), len(8), channel (16)
|
||||||
local_cid = l2cap_event_channel_closed_get_local_cid(packet);
|
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);
|
log_info(" -> L2CAP_EVENT_CHANNEL_CLOSED signaling cid 0x%0x", local_cid);
|
||||||
|
|
||||||
stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(local_cid, context);
|
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;
|
break;
|
||||||
|
|
||||||
case L2CAP_EVENT_CAN_SEND_NOW:
|
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) {
|
if (!connection) {
|
||||||
stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(channel, context);
|
stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(channel, context);
|
||||||
if (!stream_endpoint->connection) break;
|
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){
|
uint8_t avdtp_disconnect(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) return;
|
if (!connection) return BTSTACK_MEMORY_ALLOC_FAILED;
|
||||||
if (connection->state == AVDTP_SIGNALING_CONNECTION_IDLE) return;
|
if (connection->state == AVDTP_SIGNALING_CONNECTION_IDLE) return AVDTP_CONNECTION_IN_WRONG_STATE;
|
||||||
if (connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED) return;
|
if (connection->state == AVDTP_SIGNALING_CONNECTION_W4_L2CAP_DISCONNECTED) return AVDTP_CONNECTION_IN_WRONG_STATE;
|
||||||
|
|
||||||
connection->disconnect = 1;
|
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){
|
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_l2cap_signaling_cid(avdtp_cid, context);
|
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||||
if (!connection){
|
if (!connection){
|
||||||
log_error("avdtp_media_connect: no connection for signaling cid 0x%02x found", avdtp_cid);
|
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){
|
if (avdtp_find_remote_sep(connection, acp_seid) == 0xFF){
|
||||||
log_error("avdtp_media_connect: no remote sep for seid %d found", acp_seid);
|
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) {
|
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) {
|
||||||
log_error("avdtp_media_connect: wrong connection state %d", connection->state);
|
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);
|
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
||||||
if (!stream_endpoint) {
|
if (!stream_endpoint) {
|
||||||
log_error("avdtp_media_connect: no stream_endpoint with seid %d found", int_seid);
|
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->state < AVDTP_STREAM_ENDPOINT_CONFIGURED) return AVDTP_STREAM_ENDPOINT_IN_WRONG_STATE;
|
||||||
if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return;
|
if (stream_endpoint->remote_sep_index == AVDTP_INVALID_SEP_INDEX) return AVDTP_SEID_DOES_NOT_EXIST;
|
||||||
|
|
||||||
connection->initiator_transaction_label++;
|
connection->initiator_transaction_label++;
|
||||||
connection->acp_seid = acp_seid;
|
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->initiator_config_state = AVDTP_INITIATOR_W2_OPEN_STREAM;
|
||||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_W2_REQUEST_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){
|
uint8_t avdtp_start_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context){
|
||||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, 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;
|
|
||||||
if (!connection){
|
if (!connection){
|
||||||
log_error("avdtp_start_stream: no connection for seid %d found",stream_endpoint->sep.seid);
|
log_error("avdtp_start_stream: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||||
return;
|
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;
|
stream_endpoint->start_stream = 1;
|
||||||
connection->int_seid = int_seid;
|
connection->local_seid = local_seid;
|
||||||
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_stop_stream(uint8_t int_seid, avdtp_context_t * context){
|
uint8_t avdtp_stop_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context){
|
||||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, 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;
|
|
||||||
if (!connection){
|
if (!connection){
|
||||||
log_error("avdtp_stop_stream: no connection for seid %d found",stream_endpoint->sep.seid);
|
log_error("avdtp_stop_stream: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||||
return;
|
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;
|
stream_endpoint->stop_stream = 1;
|
||||||
connection->int_seid = int_seid;
|
connection->local_seid = local_seid;
|
||||||
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_abort_stream(uint8_t int_seid, avdtp_context_t * context){
|
uint8_t avdtp_abort_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context){
|
||||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, 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;
|
|
||||||
|
|
||||||
if (!connection){
|
if (!connection){
|
||||||
log_error("avdtp_abort_stream: no connection for seid %d found",stream_endpoint->sep.seid);
|
log_error("avdtp_abort_stream: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||||
return;
|
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;
|
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){
|
uint8_t avdtp_suspend_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context){
|
||||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_with_seid(int_seid, context);
|
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, 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;
|
|
||||||
if (!connection){
|
if (!connection){
|
||||||
log_error("avdtp_abort_stream: no connection for seid %d found",stream_endpoint->sep.seid);
|
log_error("avdtp_suspend_stream: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||||
return;
|
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;
|
stream_endpoint->suspend_stream = 1;
|
||||||
connection->int_seid = int_seid;
|
connection->local_seid = local_seid;
|
||||||
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_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * context){
|
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){
|
if (!connection){
|
||||||
log_error("avdtp_discover_stream_endpoints: no connection for signaling cid 0x%02x found", avdtp_cid);
|
log_error("avdtp_discover_stream_endpoints: no connection for signaling cid 0x%02x found", avdtp_cid);
|
||||||
return;
|
return;
|
||||||
@ -718,7 +787,7 @@ void avdtp_discover_stream_endpoints(uint16_t avdtp_cid, avdtp_context_t * conte
|
|||||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE:
|
case AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE:
|
||||||
connection->initiator_transaction_label++;
|
connection->initiator_transaction_label++;
|
||||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_DISCOVER_SEPS;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
log_error("avdtp_discover_stream_endpoints: wrong state");
|
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){
|
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){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) 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_transaction_label++;
|
||||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES;
|
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES;
|
||||||
connection->acp_seid = acp_seid;
|
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){
|
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){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) 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_transaction_label++;
|
||||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES;
|
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES;
|
||||||
connection->acp_seid = acp_seid;
|
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){
|
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){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) 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_transaction_label++;
|
||||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CONFIGURATION;
|
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CONFIGURATION;
|
||||||
connection->acp_seid = acp_seid;
|
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){
|
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_l2cap_signaling_cid(avdtp_cid, context);
|
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||||
if (!connection){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||||
if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) 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) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection->initiator_transaction_label++;
|
connection->initiator_transaction_label++;
|
||||||
connection->acp_seid = acp_seid;
|
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_bitmap = configured_services_bitmap;
|
||||||
stream_endpoint->remote_capabilities = configuration;
|
stream_endpoint->remote_capabilities = configuration;
|
||||||
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_SET_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){
|
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_l2cap_signaling_cid(avdtp_cid, context);
|
avdtp_connection_t * connection = avdtp_connection_for_avdtp_cid(avdtp_cid, context);
|
||||||
if (!connection){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
//TODO: if opened only app capabilities, enable reconfigure for not opened
|
//TODO: if opened only app capabilities, enable reconfigure for not opened
|
||||||
if (connection->state < AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
if (connection->state < AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||||
if (connection->initiator_connection_state != AVDTP_SIGNALING_CONNECTION_INITIATOR_IDLE) 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) {
|
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;
|
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->initiator_transaction_label++;
|
||||||
connection->acp_seid = acp_seid;
|
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_bitmap = configured_services_bitmap;
|
||||||
stream_endpoint->remote_capabilities = configuration;
|
stream_endpoint->remote_capabilities = configuration;
|
||||||
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID;
|
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){
|
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){
|
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 0;
|
||||||
}
|
}
|
||||||
return connection->remote_seps_num;
|
return connection->remote_seps_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
avdtp_sep_t * avdtp_remote_sep(uint16_t avdtp_cid, uint8_t index, avdtp_context_t * context){
|
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){
|
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 NULL;
|
||||||
}
|
}
|
||||||
return &connection->remote_seps[index];
|
return &connection->remote_seps[index];
|
||||||
|
@ -376,11 +376,10 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
btstack_linked_item_t item;
|
btstack_linked_item_t item;
|
||||||
|
|
||||||
bd_addr_t remote_addr;
|
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_service_mode_t service_mode;
|
||||||
|
|
||||||
avdtp_connection_state_t state;
|
avdtp_connection_state_t state;
|
||||||
@ -396,7 +395,7 @@ typedef struct {
|
|||||||
uint8_t initiator_transaction_label;
|
uint8_t initiator_transaction_label;
|
||||||
uint8_t acceptor_transaction_label;
|
uint8_t acceptor_transaction_label;
|
||||||
uint8_t query_seid;
|
uint8_t query_seid;
|
||||||
uint8_t int_seid;
|
uint8_t local_seid;
|
||||||
uint8_t acp_seid;
|
uint8_t acp_seid;
|
||||||
|
|
||||||
uint8_t wait_to_send_acceptor;
|
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_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);
|
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);
|
uint8_t avdtp_connect(bd_addr_t remote, avdtp_sep_type_t query_role, avdtp_context_t * context, uint16_t * avdtp_cid);
|
||||||
void avdtp_disconnect(uint16_t avdtp_cid, avdtp_context_t * context);
|
uint8_t 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);
|
uint8_t avdtp_open_stream(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid, avdtp_context_t * context);
|
||||||
void avdtp_start_stream(uint8_t int_seid, avdtp_context_t * context);
|
uint8_t avdtp_start_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context);
|
||||||
void avdtp_stop_stream (uint8_t int_seid, avdtp_context_t * context);
|
uint8_t avdtp_stop_stream (uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context);
|
||||||
void avdtp_abort_stream(uint8_t int_seid, avdtp_context_t * context);
|
uint8_t avdtp_abort_stream(uint16_t avdtp_cid, uint8_t local_seid, avdtp_context_t * context);
|
||||||
void avdtp_suspend_stream(uint8_t int_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_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_capabilities(uint16_t avdtp_cid, uint8_t remote_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_all_capabilities(uint16_t avdtp_cid, uint8_t remote_seid, avdtp_context_t * context);
|
||||||
void avdtp_get_configuration(uint16_t avdtp_cid, uint8_t acp_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 int_seid, uint8_t acp_seid, uint16_t configured_services_bitmap, avdtp_capabilities_t configuration, 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 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 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);
|
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);
|
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->error_code = BAD_LENGTH;
|
||||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
|
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE;
|
||||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
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;
|
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;
|
if (connection->state != AVDTP_SIGNALING_CONNECTION_OPENED) return;
|
||||||
log_info(" ACP: AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS");
|
log_info(" ACP: AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS");
|
||||||
connection->acceptor_connection_state = 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;
|
return;
|
||||||
case AVDTP_SI_GET_CAPABILITIES:
|
case AVDTP_SI_GET_CAPABILITIES:
|
||||||
case AVDTP_SI_GET_ALL_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->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||||
}
|
}
|
||||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
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->reject_service_category = connection->query_seid;
|
||||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
// deal with first susspended seid
|
// 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->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE;
|
||||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
||||||
connection->num_suspended_seids = 0;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
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->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_GENERAL_REJECT_WITH_ERROR_CODE;
|
||||||
connection->reject_signal_identifier = connection->signaling_packet.signal_identifier;
|
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);
|
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;
|
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)){
|
if (get_bit16(sep.configured_service_categories, AVDTP_MEDIA_CODEC)){
|
||||||
switch (sep.configuration.media_codec.media_codec_type){
|
switch (sep.configuration.media_codec.media_codec_type){
|
||||||
case AVDTP_CODEC_SBC:
|
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;
|
break;
|
||||||
default:
|
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;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case AVDTP_SI_RECONFIGURE:{
|
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)){
|
if (get_bit16(sep.configured_service_categories, AVDTP_MEDIA_CODEC)){
|
||||||
switch (sep.capabilities.media_codec.media_codec_type){
|
switch (sep.capabilities.media_codec.media_codec_type){
|
||||||
case AVDTP_CODEC_SBC:
|
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;
|
break;
|
||||||
default:
|
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;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ void avdtp_acceptor_stream_config_subsm(avdtp_connection_t * connection, uint8_t
|
|||||||
if (!request_to_send){
|
if (!request_to_send){
|
||||||
log_info(" ACP: NOT IMPLEMENTED");
|
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){
|
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:
|
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_ANSWER_DISCOVER_SEPS:
|
||||||
connection->state = AVDTP_SIGNALING_CONNECTION_OPENED;
|
connection->state = AVDTP_SIGNALING_CONNECTION_OPENED;
|
||||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
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;
|
break;
|
||||||
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE:
|
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_WITH_ERROR_CODE:
|
||||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
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;
|
break;
|
||||||
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE:
|
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_REJECT_CATEGORY_WITH_ERROR_CODE:
|
||||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
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;
|
break;
|
||||||
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_GENERAL_REJECT_WITH_ERROR_CODE:
|
case AVDTP_SIGNALING_CONNECTION_ACCEPTOR_W2_GENERAL_REJECT_WITH_ERROR_CODE:
|
||||||
connection->acceptor_connection_state = AVDTP_SIGNALING_CONNECTION_ACCEPTOR_IDLE;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
sent = 0;
|
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;
|
uint8_t reject_service_category = connection->reject_service_category;
|
||||||
avdtp_signal_identifier_t reject_signal_identifier = connection->reject_signal_identifier;
|
avdtp_signal_identifier_t reject_signal_identifier = connection->reject_signal_identifier;
|
||||||
uint8_t error_code = connection->error_code;
|
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;
|
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;
|
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");
|
log_info(" ACP: NOT IMPLEMENTED");
|
||||||
sent = 0;
|
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
|
// check fragmentation
|
||||||
if (connection->signaling_packet.packet_type != AVDTP_SINGLE_PACKET && connection->signaling_packet.packet_type != AVDTP_END_PACKET){
|
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 {
|
} else {
|
||||||
stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(connection->acp_seid, context);
|
stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(connection->acp_seid, context);
|
||||||
if (!stream_endpoint){
|
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;
|
if (!stream_endpoint) return;
|
||||||
sep.seid = connection->acp_seid;
|
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){
|
if (avdtp_find_remote_sep(connection, sep.seid) == 0xFF){
|
||||||
connection->remote_seps[connection->remote_seps_num++] = sep;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AVDTP_SI_GET_CAPABILITIES:
|
case AVDTP_SI_GET_CAPABILITIES:
|
||||||
case AVDTP_SI_GET_ALL_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);
|
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)){
|
if (get_bit16(sep.registered_service_categories, AVDTP_MEDIA_CODEC)){
|
||||||
switch (sep.capabilities.media_codec.media_codec_type){
|
switch (sep.capabilities.media_codec.media_codec_type){
|
||||||
case AVDTP_CODEC_SBC:
|
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;
|
break;
|
||||||
default:
|
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;
|
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)){
|
if (get_bit16(sep.configured_service_categories, AVDTP_MEDIA_CODEC)){
|
||||||
switch (sep.configuration.media_codec.media_codec_type){
|
switch (sep.configuration.media_codec.media_codec_type){
|
||||||
case AVDTP_CODEC_SBC:
|
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;
|
break;
|
||||||
default:
|
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;
|
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);
|
log_info(" AVDTP_RESPONSE_ACCEPT_MSG, signal %d not implemented", connection->signaling_packet.signal_identifier);
|
||||||
break;
|
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++;
|
connection->initiator_transaction_label++;
|
||||||
break;
|
break;
|
||||||
case AVDTP_RESPONSE_REJECT_MSG:
|
case AVDTP_RESPONSE_REJECT_MSG:
|
||||||
log_info(" AVDTP_RESPONSE_REJECT_MSG signal %d", connection->signaling_packet.signal_identifier);
|
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;
|
return;
|
||||||
case AVDTP_GENERAL_REJECT_MSG:
|
case AVDTP_GENERAL_REJECT_MSG:
|
||||||
log_info(" AVDTP_GENERAL_REJECT_MSG signal %d", connection->signaling_packet.signal_identifier);
|
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;
|
return;
|
||||||
default:
|
default:
|
||||||
break;
|
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:
|
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_DISCOVER_SEPS:
|
||||||
log_info(" INT: 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;
|
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;
|
break;
|
||||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES:
|
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CAPABILITIES:
|
||||||
log_info(" INT: 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;
|
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;
|
break;
|
||||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES:
|
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_ALL_CAPABILITIES:
|
||||||
log_info(" INT: 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;
|
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;
|
break;
|
||||||
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CONFIGURATION:
|
case AVDTP_SIGNALING_CONNECTION_INITIATOR_W2_GET_CONFIGURATION:
|
||||||
log_info(" INT: AVDTP_INITIATOR_W4_GET_CONFIGURATION");
|
log_info(" INT: AVDTP_INITIATOR_W4_GET_CONFIGURATION");
|
||||||
connection->initiator_connection_state = AVDTP_SIGNALING_CONNECTION_INITIATOR_W4_ANSWER;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
sent = 0;
|
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);
|
stream_endpoint = avdtp_stream_endpoint_associated_with_acp_seid(connection->acp_seid, context);
|
||||||
if (!stream_endpoint){
|
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;
|
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){
|
if (stream_endpoint->start_stream){
|
||||||
stream_endpoint->start_stream = 0;
|
stream_endpoint->start_stream = 0;
|
||||||
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_OPENED){
|
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;
|
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;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -300,9 +300,9 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
|||||||
if (stream_endpoint->stop_stream){
|
if (stream_endpoint->stop_stream){
|
||||||
stream_endpoint->stop_stream = 0;
|
stream_endpoint->stop_stream = 0;
|
||||||
if (stream_endpoint->state >= AVDTP_STREAM_ENDPOINT_OPENED){
|
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;
|
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;
|
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_CLOSING:
|
||||||
case AVDTP_STREAM_ENDPOINT_OPENED:
|
case AVDTP_STREAM_ENDPOINT_OPENED:
|
||||||
case AVDTP_STREAM_ENDPOINT_STREAMING:
|
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;
|
connection->acp_seid = connection->remote_seps[stream_endpoint->remote_sep_index].seid;
|
||||||
stream_endpoint->state = AVDTP_STREAM_ENDPOINT_ABORTING;
|
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;
|
return;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -328,7 +328,7 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
|||||||
stream_endpoint->suspend_stream = 0;
|
stream_endpoint->suspend_stream = 0;
|
||||||
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING){
|
if (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING){
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -346,10 +346,10 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
|||||||
switch (stream_endpoint_state){
|
switch (stream_endpoint_state){
|
||||||
case AVDTP_INITIATOR_W2_SET_CONFIGURATION:
|
case AVDTP_INITIATOR_W2_SET_CONFIGURATION:
|
||||||
case AVDTP_INITIATOR_W2_RECONFIGURE_STREAM_WITH_SEID:{
|
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);
|
// 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.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;
|
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);
|
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();
|
l2cap_reserve_packet_buffer();
|
||||||
uint8_t * out_buffer = l2cap_get_outgoing_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){
|
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;
|
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_FRAGMENTATED_COMMAND;
|
||||||
log_info(" INT: fragmented");
|
log_info(" INT: fragmented");
|
||||||
}
|
}
|
||||||
l2cap_send_prepared(connection->l2cap_signaling_cid, pos);
|
l2cap_send_prepared(connection->tl2cap_signaling_cid, pos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AVDTP_INITIATOR_FRAGMENTATED_COMMAND:{
|
case AVDTP_INITIATOR_FRAGMENTATED_COMMAND:{
|
||||||
l2cap_reserve_packet_buffer();
|
l2cap_reserve_packet_buffer();
|
||||||
uint8_t * out_buffer = l2cap_get_outgoing_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){
|
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;
|
stream_endpoint->initiator_config_state = AVDTP_INITIATOR_FRAGMENTATED_COMMAND;
|
||||||
log_info(" INT: fragmented");
|
log_info(" INT: fragmented");
|
||||||
}
|
}
|
||||||
l2cap_send_prepared(connection->l2cap_signaling_cid, pos);
|
l2cap_send_prepared(connection->tl2cap_signaling_cid, pos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AVDTP_INITIATOR_W2_OPEN_STREAM:
|
case AVDTP_INITIATOR_W2_OPEN_STREAM:
|
||||||
switch (stream_endpoint->state){
|
switch (stream_endpoint->state){
|
||||||
case AVDTP_STREAM_ENDPOINT_W2_REQUEST_OPEN_STREAM:
|
case AVDTP_STREAM_ENDPOINT_W2_REQUEST_OPEN_STREAM:
|
||||||
log_info(" INT: 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;
|
break;
|
||||||
default:
|
default:
|
||||||
sent = 0;
|
sent = 0;
|
||||||
@ -397,6 +397,6 @@ void avdtp_initiator_stream_config_subsm_run(avdtp_connection_t * connection, av
|
|||||||
|
|
||||||
// check fragmentation
|
// check fragmentation
|
||||||
if (connection->signaling_packet.packet_type != AVDTP_SINGLE_PACKET && connection->signaling_packet.packet_type != AVDTP_END_PACKET){
|
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;
|
avdtp_sink_context->avdtp_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_connect(bd_addr_t remote){
|
uint8_t avdtp_sink_connect(bd_addr_t remote, uint16_t * avdtp_cid){
|
||||||
avdtp_connect(remote, AVDTP_SOURCE, avdtp_sink_context);
|
return avdtp_connect(remote, AVDTP_SOURCE, avdtp_sink_context, avdtp_cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_disconnect(uint16_t avdtp_cid){
|
uint8_t avdtp_sink_disconnect(uint16_t avdtp_cid){
|
||||||
avdtp_disconnect(avdtp_cid, avdtp_sink_context);
|
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){
|
uint8_t avdtp_sink_open_stream(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
|
||||||
avdtp_open_stream(avdtp_cid, int_seid, acp_seid, avdtp_sink_context);
|
return avdtp_open_stream(avdtp_cid, local_seid, remote_seid, avdtp_sink_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_start_stream(uint8_t int_seid){
|
uint8_t avdtp_sink_start_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_start_stream(int_seid, avdtp_sink_context);
|
return avdtp_start_stream(avdtp_cid, local_seid, avdtp_sink_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_stop_stream(uint8_t int_seid){
|
uint8_t avdtp_sink_stop_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_stop_stream(int_seid, avdtp_sink_context);
|
return avdtp_stop_stream(avdtp_cid, local_seid, avdtp_sink_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_abort_stream(uint8_t int_seid){
|
uint8_t avdtp_sink_abort_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_abort_stream(int_seid, avdtp_sink_context);
|
return avdtp_abort_stream(avdtp_cid, local_seid, avdtp_sink_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_suspend(uint8_t int_seid){
|
uint8_t avdtp_sink_suspend(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_suspend_stream(int_seid, avdtp_sink_context);
|
return avdtp_suspend_stream(avdtp_cid, local_seid, avdtp_sink_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_discover_stream_endpoints(uint16_t avdtp_cid){
|
void avdtp_sink_discover_stream_endpoints(uint16_t avdtp_cid){
|
||||||
avdtp_discover_stream_endpoints(avdtp_cid, avdtp_sink_context);
|
avdtp_discover_stream_endpoints(avdtp_cid, avdtp_sink_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_get_capabilities(uint16_t avdtp_cid, uint8_t acp_seid){
|
void avdtp_sink_get_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||||
avdtp_get_capabilities(avdtp_cid, acp_seid, avdtp_sink_context);
|
avdtp_get_capabilities(avdtp_cid, remote_seid, avdtp_sink_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_get_all_capabilities(uint16_t avdtp_cid, uint8_t acp_seid){
|
void avdtp_sink_get_all_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||||
avdtp_get_all_capabilities(avdtp_cid, acp_seid, avdtp_sink_context);
|
avdtp_get_all_capabilities(avdtp_cid, remote_seid, avdtp_sink_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_sink_get_configuration(uint16_t avdtp_cid, uint8_t acp_seid){
|
void avdtp_sink_get_configuration(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||||
avdtp_get_configuration(avdtp_cid, acp_seid, avdtp_sink_context);
|
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){
|
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, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_sink_context);
|
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){
|
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, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_sink_context);
|
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?)
|
* @brief Connect to device with a bluetooth address. (and perform configuration?)
|
||||||
* @param bd_addr
|
* @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));
|
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.
|
* @brief Disconnect from device with connection handle.
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
*/
|
*/
|
||||||
void avdtp_sink_disconnect(uint16_t avdtp_cid);
|
uint8_t avdtp_sink_disconnect(uint16_t avdtp_cid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Discover stream endpoints
|
* @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 avdtp_cid
|
||||||
* @param seid
|
* @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
|
* @brief Start stream
|
||||||
* @param local_seid
|
* @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
|
* @brief Abort stream
|
||||||
* @param local_seid
|
* @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
|
* @brief Start stream
|
||||||
* @param local_seid
|
* @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
|
* @brief Suspend stream
|
||||||
* @param local_seid
|
* @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 */
|
/* API_END */
|
||||||
|
|
||||||
|
@ -105,56 +105,56 @@ void avdtp_source_register_packet_handler(btstack_packet_handler_t callback){
|
|||||||
avdtp_source_context->avdtp_callback = callback;
|
avdtp_source_context->avdtp_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_connect(bd_addr_t remote){
|
uint8_t avdtp_source_connect(bd_addr_t remote, uint16_t * avdtp_cid){
|
||||||
avdtp_connect(remote, AVDTP_SINK, avdtp_source_context);
|
return avdtp_connect(remote, AVDTP_SINK, avdtp_source_context, avdtp_cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_disconnect(uint16_t con_handle){
|
uint8_t avdtp_source_disconnect(uint16_t avdtp_cid){
|
||||||
avdtp_disconnect(con_handle, avdtp_source_context);
|
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){
|
uint8_t avdtp_source_open_stream(uint16_t avdtp_cid, uint8_t local_seid, uint8_t remote_seid){
|
||||||
avdtp_open_stream(con_handle, int_seid, acp_seid, avdtp_source_context);
|
return avdtp_open_stream(avdtp_cid, local_seid, remote_seid, avdtp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_start_stream(uint8_t int_seid){
|
uint8_t avdtp_source_start_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_start_stream(int_seid, avdtp_source_context);
|
return avdtp_start_stream(avdtp_cid, local_seid, avdtp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_stop_stream(uint8_t int_seid){
|
uint8_t avdtp_source_stop_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_stop_stream(int_seid, avdtp_source_context);
|
return avdtp_stop_stream(avdtp_cid, local_seid, avdtp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_abort_stream(uint8_t int_seid){
|
uint8_t avdtp_source_abort_stream(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_abort_stream(int_seid, avdtp_source_context);
|
return avdtp_abort_stream(avdtp_cid, local_seid, avdtp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_suspend(uint8_t int_seid){
|
uint8_t avdtp_source_suspend(uint16_t avdtp_cid, uint8_t local_seid){
|
||||||
avdtp_suspend_stream(int_seid, avdtp_source_context);
|
return avdtp_suspend_stream(avdtp_cid, local_seid, avdtp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_discover_stream_endpoints(uint16_t con_handle){
|
void avdtp_source_discover_stream_endpoints(uint16_t avdtp_cid){
|
||||||
avdtp_discover_stream_endpoints(con_handle, avdtp_source_context);
|
avdtp_discover_stream_endpoints(avdtp_cid, avdtp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_get_capabilities(uint16_t con_handle, uint8_t acp_seid){
|
void avdtp_source_get_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||||
avdtp_get_capabilities(con_handle, acp_seid, avdtp_source_context);
|
avdtp_get_capabilities(avdtp_cid, remote_seid, avdtp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_get_all_capabilities(uint16_t con_handle, uint8_t acp_seid){
|
void avdtp_source_get_all_capabilities(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||||
avdtp_get_all_capabilities(con_handle, acp_seid, avdtp_source_context);
|
avdtp_get_all_capabilities(avdtp_cid, remote_seid, avdtp_source_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void avdtp_source_get_configuration(uint16_t con_handle, uint8_t acp_seid){
|
void avdtp_source_get_configuration(uint16_t avdtp_cid, uint8_t remote_seid){
|
||||||
avdtp_get_configuration(con_handle, acp_seid, avdtp_source_context);
|
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){
|
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(con_handle, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_source_context);
|
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){
|
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(con_handle, int_seid, acp_seid, configured_services_bitmap, configuration, avdtp_source_context);
|
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){
|
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?)
|
* @brief Connect to device with a bluetooth address. (and perform configuration?)
|
||||||
* @param bd_addr
|
* @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.
|
* @brief Disconnect from device with connection handle.
|
||||||
* @param avdtp_cid
|
* @param avdtp_cid
|
||||||
*/
|
*/
|
||||||
void avdtp_source_disconnect(uint16_t avdtp_cid);
|
uint8_t avdtp_source_disconnect(uint16_t avdtp_cid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Discover stream endpoints
|
* @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 avdtp_cid
|
||||||
* @param seid
|
* @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
|
* @brief Start stream
|
||||||
* @param local_seid
|
* @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
|
* @brief Abort stream
|
||||||
* @param local_seid
|
* @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
|
* @brief Start stream
|
||||||
* @param local_seid
|
* @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
|
* @brief Suspend stream
|
||||||
* @param local_seid
|
* @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);
|
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;
|
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_t it;
|
||||||
btstack_linked_list_iterator_init(&it, &context->connections);
|
btstack_linked_list_iterator_init(&it, &context->connections);
|
||||||
while (btstack_linked_list_iterator_has_next(&it)){
|
while (btstack_linked_list_iterator_has_next(&it)){
|
||||||
avdtp_connection_t * connection = (avdtp_connection_t *)btstack_linked_list_iterator_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 connection;
|
||||||
}
|
}
|
||||||
return NULL;
|
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));
|
(*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;
|
if (!callback) return;
|
||||||
uint8_t event[8];
|
uint8_t event[8];
|
||||||
int pos = 0;
|
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;
|
event[pos++] = AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, avdtp_cid);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = int_seid;
|
event[pos++] = local_seid;
|
||||||
event[pos++] = acp_seid;
|
event[pos++] = remote_seid;
|
||||||
event[pos++] = status;
|
event[pos++] = status;
|
||||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
(*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));
|
(*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;
|
if (!callback) return;
|
||||||
uint8_t event[8];
|
uint8_t event[7];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
event[pos++] = HCI_EVENT_AVDTP_META;
|
event[pos++] = HCI_EVENT_AVDTP_META;
|
||||||
event[pos++] = sizeof(event) - 2;
|
event[pos++] = sizeof(event) - 2;
|
||||||
event[pos++] = AVDTP_SUBEVENT_SIGNALING_ACCEPT;
|
event[pos++] = AVDTP_SUBEVENT_SIGNALING_ACCEPT;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, avdtp_cid);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = int_seid;
|
event[pos++] = local_seid;
|
||||||
event[pos++] = identifier;
|
event[pos++] = identifier;
|
||||||
event[pos++] = status;
|
|
||||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
(*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;
|
if (!callback) return;
|
||||||
uint8_t event[7];
|
uint8_t event[7];
|
||||||
int pos = 0;
|
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;
|
event[pos++] = AVDTP_SUBEVENT_SIGNALING_REJECT;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, avdtp_cid);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = int_seid;
|
event[pos++] = local_seid;
|
||||||
event[pos++] = identifier;
|
event[pos++] = identifier;
|
||||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
(*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;
|
if (!callback) return;
|
||||||
uint8_t event[7];
|
uint8_t event[7];
|
||||||
int pos = 0;
|
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;
|
event[pos++] = AVDTP_SUBEVENT_SIGNALING_GENERAL_REJECT;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, avdtp_cid);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = int_seid;
|
event[pos++] = local_seid;
|
||||||
event[pos++] = identifier;
|
event[pos++] = identifier;
|
||||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
(*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;
|
if (!callback) return;
|
||||||
uint8_t event[15];
|
uint8_t event[15];
|
||||||
int pos = 0;
|
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;
|
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CAPABILITY;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, avdtp_cid);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = int_seid;
|
event[pos++] = local_seid;
|
||||||
event[pos++] = acp_seid;
|
event[pos++] = remote_seid;
|
||||||
event[pos++] = media_codec.media_type;
|
event[pos++] = media_codec.media_type;
|
||||||
event[pos++] = media_codec.media_codec_information[0] >> 4;
|
event[pos++] = media_codec.media_codec_information[0] >> 4;
|
||||||
event[pos++] = media_codec.media_codec_information[0] & 0x0F;
|
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));
|
(*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;
|
if (!callback) return;
|
||||||
uint8_t event[111];
|
uint8_t event[111];
|
||||||
int pos = 0;
|
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;
|
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CAPABILITY;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, avdtp_cid);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = int_seid;
|
event[pos++] = local_seid;
|
||||||
event[pos++] = acp_seid;
|
event[pos++] = remote_seid;
|
||||||
event[pos++] = media_codec.media_type;
|
event[pos++] = media_codec.media_type;
|
||||||
little_endian_store_16(event, pos, media_codec.media_codec_type);
|
little_endian_store_16(event, pos, media_codec.media_codec_type);
|
||||||
pos += 2;
|
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));
|
(*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;
|
if (!callback) return;
|
||||||
uint8_t event[16+2];
|
uint8_t event[16+2];
|
||||||
int pos = 0;
|
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;
|
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_SBC_CONFIGURATION;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, avdtp_cid);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = int_seid;
|
event[pos++] = local_seid;
|
||||||
event[pos++] = acp_seid;
|
event[pos++] = remote_seid;
|
||||||
event[pos++] = reconfigure;
|
event[pos++] = reconfigure;
|
||||||
|
|
||||||
uint8_t num_channels = 0;
|
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));
|
(*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;
|
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;
|
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];
|
uint8_t event[112];
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
event[pos++] = HCI_EVENT_AVDTP_META;
|
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;
|
event[pos++] = AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION;
|
||||||
little_endian_store_16(event, pos, avdtp_cid);
|
little_endian_store_16(event, pos, avdtp_cid);
|
||||||
pos += 2;
|
pos += 2;
|
||||||
event[pos++] = int_seid;
|
event[pos++] = local_seid;
|
||||||
event[pos++] = acp_seid;
|
event[pos++] = remote_seid;
|
||||||
event[pos++] = reconfigure;
|
event[pos++] = reconfigure;
|
||||||
|
|
||||||
event[pos++] = media_codec.media_type;
|
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));
|
(*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;
|
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;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -791,3 +801,15 @@ uint8_t avdtp_find_remote_sep(avdtp_connection_t * connection, uint8_t remote_se
|
|||||||
return AVDTP_INVALID_SEP_INDEX;
|
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
|
#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_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_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_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);
|
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_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_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_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_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_signaling_emit_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, avdtp_signal_identifier_t identifier);
|
||||||
void avdtp_streaming_emit_can_send_media_packet_now(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint16_t sequence_number);
|
void avdtp_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);
|
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);
|
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
|
#if defined __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user