a2dp source: wrap avdtp calls [a2371]

This commit is contained in:
Milanka Ringwald 2019-11-18 11:37:12 +01:00
parent fcc47f4ac1
commit 33f3f68c3b

View File

@ -52,7 +52,6 @@
#include "l2cap.h"
#define AVDTP_MAX_SEP_NUM 10
#define AVDTP_MEDIA_PAYLOAD_HEADER_SIZE 12
static const char * default_a2dp_source_service_name = "BTstack A2DP Source Service";
static const char * default_a2dp_source_service_provider_name = "BTstack A2DP Source Service Provider";
@ -581,106 +580,14 @@ uint8_t a2dp_source_pause_stream(uint16_t a2dp_cid, uint8_t local_seid){
return avdtp_suspend_stream(a2dp_cid, local_seid, &a2dp_source_context);
}
static void a2dp_source_setup_media_header(uint8_t * media_packet, int size, int *offset, uint8_t marker, uint16_t sequence_number){
if (size < AVDTP_MEDIA_PAYLOAD_HEADER_SIZE){
log_error("small outgoing buffer");
return;
}
uint8_t rtp_version = 2;
uint8_t padding = 0;
uint8_t extension = 0;
uint8_t csrc_count = 0;
uint8_t payload_type = 0x60;
// uint16_t sequence_number = stream_endpoint->sequence_number;
uint32_t timestamp = btstack_run_loop_get_time_ms();
uint32_t ssrc = 0x11223344;
// rtp header (min size 12B)
int pos = 0;
// int mtu = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
media_packet[pos++] = (rtp_version << 6) | (padding << 5) | (extension << 4) | csrc_count;
media_packet[pos++] = (marker << 1) | payload_type;
big_endian_store_16(media_packet, pos, sequence_number);
pos += 2;
big_endian_store_32(media_packet, pos, timestamp);
pos += 4;
big_endian_store_32(media_packet, pos, ssrc); // only used for multicast
pos += 4;
*offset = pos;
}
void a2dp_source_stream_endpoint_request_can_send_now(uint16_t a2dp_cid, uint8_t local_seid){
if (a2dp_source_context.avdtp_cid != a2dp_cid){
log_error("A2DP source: a2dp cid 0x%02x not known, expected 0x%02x", a2dp_cid, a2dp_source_context.avdtp_cid);
return;
}
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
if (!stream_endpoint) {
log_error("A2DP source: no stream_endpoint with seid %d", local_seid);
return;
}
stream_endpoint->send_stream = 1;
avdtp_request_can_send_now_initiator(stream_endpoint->connection, stream_endpoint->l2cap_media_cid);
avdtp_source_stream_endpoint_request_can_send_now(a2dp_cid, local_seid);
}
int a2dp_max_media_payload_size(uint16_t a2dp_cid, uint8_t local_seid){
if (a2dp_source_context.avdtp_cid != a2dp_cid){
log_error("A2DP source: a2dp cid 0x%02x not known, expected 0x%02x", a2dp_cid, a2dp_source_context.avdtp_cid);
return 0;
}
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
if (!stream_endpoint) {
log_error("A2DP source: no stream_endpoint with seid %d", local_seid);
return 0;
}
if (stream_endpoint->l2cap_media_cid == 0){
log_error("A2DP source: no media connection for seid %d", local_seid);
return 0;
}
return l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid) - AVDTP_MEDIA_PAYLOAD_HEADER_SIZE;
}
static void a2dp_source_copy_media_payload(uint8_t * media_packet, int size, int * offset, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames){
if (size < num_bytes_to_copy + 1){
log_error("small outgoing buffer: buffer size %u, but need %u", size, num_bytes_to_copy + 1);
return;
}
int pos = *offset;
media_packet[pos++] = num_frames; // (fragmentation << 7) | (starting_packet << 6) | (last_packet << 5) | num_frames;
memcpy(media_packet + pos, storage, num_bytes_to_copy);
pos += num_bytes_to_copy;
*offset = pos;
return avdtp_max_media_payload_size(a2dp_cid, local_seid);
}
int a2dp_source_stream_send_media_payload(uint16_t a2dp_cid, uint8_t local_seid, uint8_t * storage, int num_bytes_to_copy, uint8_t num_frames, uint8_t marker){
if (a2dp_source_context.avdtp_cid != a2dp_cid){
log_error("A2DP source: a2dp cid 0x%02x not known, expected 0x%02x", a2dp_cid, a2dp_source_context.avdtp_cid);
return 0;
}
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, &a2dp_source_context);
if (!stream_endpoint) {
log_error("A2DP source: no stream_endpoint with seid %d", local_seid);
return 0;
}
if (stream_endpoint->l2cap_media_cid == 0){
log_error("A2DP source: no media connection for seid %d", local_seid);
return 0;
}
int size = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
int offset = 0;
l2cap_reserve_packet_buffer();
uint8_t * media_packet = l2cap_get_outgoing_buffer();
//int size = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
a2dp_source_setup_media_header(media_packet, size, &offset, marker, stream_endpoint->sequence_number);
a2dp_source_copy_media_payload(media_packet, size, &offset, storage, num_bytes_to_copy, num_frames);
stream_endpoint->sequence_number++;
l2cap_send_prepared(stream_endpoint->l2cap_media_cid, offset);
return size;
return avdtp_source_stream_send_media_payload(a2dp_cid, local_seid, storage, num_bytes_to_copy, num_frames, marker);
}