summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-12-16 17:09:57 -0300
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2008-12-16 17:19:56 -0300
commitb2b736c38f02704d225680fd0541936e36a73e82 (patch)
tree2d49757bfabd5bc63b87d56b11ebaeed308eda7b /audio
parent1c01d240ba6ac475dba2fb39dbb208343fb78eed (diff)
Fix gstreamer plugin to reflect the ipc changes.
Diffstat (limited to 'audio')
-rw-r--r--audio/gstavdtpsink.c162
1 files changed, 96 insertions, 66 deletions
diff --git a/audio/gstavdtpsink.c b/audio/gstavdtpsink.c
index b1378a93..bf35407c 100644
--- a/audio/gstavdtpsink.c
+++ b/audio/gstavdtpsink.c
@@ -62,7 +62,7 @@ GST_DEBUG_CATEGORY_STATIC(avdtp_sink_debug);
struct bluetooth_data {
- struct bt_getcapabilities_rsp caps; /* Bluetooth device caps */
+ struct bt_get_capabilities_rsp *caps; /* Bluetooth device caps */
guint link_mtu;
gchar buffer[BUFFER_SIZE]; /* Codec transfer buffer */
@@ -113,7 +113,7 @@ static GIOError gst_avdtp_sink_audioservice_send(GstAvdtpSink *self,
static GIOError gst_avdtp_sink_audioservice_expect(
GstAvdtpSink *self,
bt_audio_msg_header_t *outmsg,
- int expected_type);
+ guint8 expected_name);
static void gst_avdtp_sink_base_init(gpointer g_class)
@@ -243,16 +243,38 @@ static gint gst_avdtp_sink_bluetooth_recvmsg_fd(GstAvdtpSink *sink)
return 0;
}
+static codec_capabilities_t *gst_avdtp_find_caps(GstAvdtpSink *sink,
+ uint8_t codec_type)
+{
+ struct bt_get_capabilities_rsp *rsp = sink->data->caps;
+ codec_capabilities_t *codec = (void *) rsp->data;
+ int bytes_left = rsp->h.length - sizeof(*rsp);
+
+ while (bytes_left > 0) {
+ if (codec->type == codec_type)
+ break;
+
+ bytes_left -= codec->length;
+ codec = (void *) codec + codec->length;
+ }
+
+ if (bytes_left <= 0)
+ return NULL;
+
+ return codec;
+}
+
static gboolean gst_avdtp_sink_init_sbc_pkt_conf(GstAvdtpSink *sink,
GstCaps *caps,
sbc_capabilities_t *pkt)
{
- sbc_capabilities_t *cfg = &sink->data->caps.sbc_capabilities;
+ sbc_capabilities_t *cfg;
const GValue *value = NULL;
const char *pref, *name;
gint rate, subbands, blocks;
GstStructure *structure = gst_caps_get_structure(caps, 0);
+ cfg = (void *) gst_avdtp_find_caps(sink, BT_A2DP_CODEC_SBC);
name = gst_structure_get_name(structure);
if (!(IS_SBC(name))) {
@@ -595,6 +617,9 @@ static GstStructure *gst_avdtp_sink_parse_mpeg_caps(
gboolean valid_layer = FALSE;
gboolean mono, stereo;
+ if (!mpeg)
+ return NULL;
+
GST_LOG_OBJECT(self, "parsing mpeg caps");
structure = gst_structure_empty_new("audio/mpeg");
@@ -709,14 +734,17 @@ static GstStructure *gst_avdtp_sink_parse_mpeg_caps(
static gboolean gst_avdtp_sink_update_caps(GstAvdtpSink *self)
{
- sbc_capabilities_t *sbc = &self->data->caps.sbc_capabilities;
- mpeg_capabilities_t *mpeg = &self->data->caps.mpeg_capabilities;
+ sbc_capabilities_t *sbc;
+ mpeg_capabilities_t *mpeg;
GstStructure *sbc_structure;
GstStructure *mpeg_structure;
gchar *tmp;
GST_LOG_OBJECT(self, "updating device caps");
+ sbc = (void *) gst_avdtp_find_caps(self, BT_A2DP_CODEC_SBC);
+ mpeg = (void *) gst_avdtp_find_caps(self, BT_A2DP_CODEC_MPEG12);
+
sbc_structure = gst_avdtp_sink_parse_sbc_caps(self, sbc);
mpeg_structure = gst_avdtp_sink_parse_mpeg_caps(self, mpeg);
@@ -735,14 +763,17 @@ static gboolean gst_avdtp_sink_update_caps(GstAvdtpSink *self)
static gboolean gst_avdtp_sink_get_capabilities(GstAvdtpSink *self)
{
- gchar *buf[BT_AUDIO_IPC_PACKET_SIZE];
- struct bt_getcapabilities_req *req = (void *) buf;
- struct bt_getcapabilities_rsp *rsp = (void *) buf;
+ gchar *buf[BT_SUGGESTED_BUFFER_SIZE];
+ struct bt_get_capabilities_req *req = (void *) buf;
+ struct bt_get_capabilities_rsp *rsp = (void *) buf;
GIOError io_error;
- memset(req, 0, BT_AUDIO_IPC_PACKET_SIZE);
+ memset(req, 0, BT_SUGGESTED_BUFFER_SIZE);
+
+ req->h.type = BT_REQUEST;
+ req->h.name = BT_GET_CAPABILITIES;
+ req->h.length = sizeof(*req);
- req->h.msg_type = BT_GETCAPABILITIES_REQ;
if (self->device == NULL)
return FALSE;
strncpy(req->device, self->device, 18);
@@ -756,20 +787,14 @@ static gboolean gst_avdtp_sink_get_capabilities(GstAvdtpSink *self)
}
io_error = gst_avdtp_sink_audioservice_expect(self,
- &rsp->rsp_h.msg_h, BT_GETCAPABILITIES_RSP);
+ &rsp->h, BT_GET_CAPABILITIES);
if (io_error != G_IO_ERROR_NONE) {
GST_ERROR_OBJECT(self, "Error while getting device caps");
return FALSE;
}
- if (rsp->rsp_h.posix_errno != 0) {
- GST_ERROR_OBJECT(self, "BT_GETCAPABILITIES failed : %s(%d)",
- strerror(rsp->rsp_h.posix_errno),
- rsp->rsp_h.posix_errno);
- return FALSE;
- }
-
- memcpy(&self->data->caps, rsp, sizeof(*rsp));
+ self->data->caps = g_malloc0(rsp->h.length);
+ memcpy(self->data->caps, rsp, rsp->h.length);
if (!gst_avdtp_sink_update_caps(self)) {
GST_WARNING_OBJECT(self, "failed to update capabilities");
return FALSE;
@@ -888,16 +913,16 @@ failed:
static gboolean gst_avdtp_sink_stream_start(GstAvdtpSink *self)
{
- gchar buf[BT_AUDIO_IPC_PACKET_SIZE];
- struct bt_streamstart_req *req = (void *) buf;
- struct bt_streamstart_rsp *rsp = (void *) buf;
- struct bt_streamfd_ind *ind = (void*) buf;
+ gchar buf[BT_SUGGESTED_BUFFER_SIZE];
+ struct bt_start_stream_req *req = (void *) buf;
+ struct bt_start_stream_rsp *rsp = (void *) buf;
+ struct bt_new_stream_ind *ind = (void*) buf;
GIOError io_error;
- GST_DEBUG_OBJECT(self, "stream start");
-
memset (req, 0, sizeof(buf));
- req->h.msg_type = BT_STREAMSTART_REQ;
+ req->h.type = BT_REQUEST;
+ req->h.name = BT_START_STREAM;
+ req->h.length = sizeof(*req);
io_error = gst_avdtp_sink_audioservice_send(self, &req->h);
if (io_error != G_IO_ERROR_NONE) {
@@ -906,27 +931,16 @@ static gboolean gst_avdtp_sink_stream_start(GstAvdtpSink *self)
return FALSE;
}
- GST_DEBUG_OBJECT(self, "stream start packet sent");
-
io_error = gst_avdtp_sink_audioservice_expect(self,
- &rsp->rsp_h.msg_h, BT_STREAMSTART_RSP);
+ &rsp->h, BT_START_STREAM);
if (io_error != G_IO_ERROR_NONE) {
GST_ERROR_OBJECT(self, "Error while stream "
"start confirmation");
return FALSE;
}
- if (rsp->rsp_h.posix_errno != 0) {
- GST_ERROR_OBJECT(self, "BT_STREAMSTART_RSP failed : %s(%d)",
- strerror(rsp->rsp_h.posix_errno),
- rsp->rsp_h.posix_errno);
- return FALSE;
- }
-
- GST_DEBUG_OBJECT(self, "stream started");
-
io_error = gst_avdtp_sink_audioservice_expect(self, &ind->h,
- BT_STREAMFD_IND);
+ BT_NEW_STREAM);
if (io_error != G_IO_ERROR_NONE) {
GST_ERROR_OBJECT(self, "Error while receiving "
"stream filedescriptor");
@@ -1019,9 +1033,9 @@ static gboolean gst_avdtp_sink_init_mp3_pkt_conf(
static gboolean gst_avdtp_sink_configure(GstAvdtpSink *self,
GstCaps *caps)
{
- gchar buf[BT_AUDIO_IPC_PACKET_SIZE];
- struct bt_setconfiguration_req *req = (void *) buf;
- struct bt_setconfiguration_rsp *rsp = (void *) buf;
+ gchar buf[BT_SUGGESTED_BUFFER_SIZE];
+ struct bt_set_configuration_req *req = (void *) buf;
+ struct bt_set_configuration_rsp *rsp = (void *) buf;
gboolean ret;
GIOError io_error;
gchar *temp;
@@ -1032,17 +1046,20 @@ static gboolean gst_avdtp_sink_configure(GstAvdtpSink *self,
g_free(temp);
memset (req, 0, sizeof(buf));
- req->h.msg_type = BT_SETCONFIGURATION_REQ;
+ req->h.type = BT_REQUEST;
+ req->h.name = BT_SET_CONFIGURATION;
+ req->h.length = sizeof(*req);
+
req->access_mode = BT_CAPABILITIES_ACCESS_MODE_WRITE;
strncpy(req->device, self->device, 18);
structure = gst_caps_get_structure(caps, 0);
if (gst_structure_has_name(structure, "audio/x-sbc"))
ret = gst_avdtp_sink_init_sbc_pkt_conf(self, caps,
- &req->sbc_capabilities);
+ (void *) &req->codec);
else if (gst_structure_has_name(structure, "audio/mpeg"))
ret = gst_avdtp_sink_init_mp3_pkt_conf(self, caps,
- &req->mpeg_capabilities);
+ (void *) &req->codec);
else
ret = FALSE;
@@ -1059,26 +1076,15 @@ static gboolean gst_avdtp_sink_configure(GstAvdtpSink *self,
return FALSE;
}
- GST_DEBUG_OBJECT(self, "configuration packet sent");
-
io_error = gst_avdtp_sink_audioservice_expect(self,
- &rsp->rsp_h.msg_h, BT_SETCONFIGURATION_RSP);
+ &rsp->h, BT_SET_CONFIGURATION);
if (io_error != G_IO_ERROR_NONE) {
GST_ERROR_OBJECT(self, "Error while receiving device "
"confirmation");
return FALSE;
}
- if (rsp->rsp_h.posix_errno != 0) {
- GST_ERROR_OBJECT(self, "BT_SETCONFIGURATION_RSP failed : "
- "%s(%d)",
- strerror(rsp->rsp_h.posix_errno),
- rsp->rsp_h.posix_errno);
- return FALSE;
- }
-
self->data->link_mtu = rsp->link_mtu;
- GST_DEBUG_OBJECT(self, "configuration set");
return TRUE;
}
@@ -1219,13 +1225,19 @@ static GIOError gst_avdtp_sink_audioservice_send(
{
GIOError error;
gsize written;
+ const char *type, *name;
error = g_io_channel_write(self->server, (const gchar*) msg,
- BT_AUDIO_IPC_PACKET_SIZE, &written);
+ BT_SUGGESTED_BUFFER_SIZE, &written);
if (error != G_IO_ERROR_NONE)
GST_ERROR_OBJECT(self, "Error sending data to audio service:"
" %s(%d)", strerror(errno), errno);
+ type = bt_audio_strtype(msg->type);
+ name = bt_audio_strname(msg->name);
+
+ GST_DEBUG_OBJECT(self, "sent: %s -> %s", type, name);
+
return error;
}
@@ -1235,30 +1247,50 @@ static GIOError gst_avdtp_sink_audioservice_recv(
{
GIOError status;
gsize bytes_read;
- const char *type;
+ const char *type, *name;
status = g_io_channel_read(self->server, (gchar*) inmsg,
- BT_AUDIO_IPC_PACKET_SIZE, &bytes_read);
+ BT_SUGGESTED_BUFFER_SIZE, &bytes_read);
if (status != G_IO_ERROR_NONE) {
GST_ERROR_OBJECT(self, "Error receiving data from "
"audio service");
return status;
}
- type = bt_audio_strmsg(inmsg->msg_type);
+ type = bt_audio_strtype(inmsg->type);
if (!type) {
status = G_IO_ERROR_INVAL;
GST_ERROR_OBJECT(self, "Bogus message type %d "
"received from audio service",
- inmsg->msg_type);
+ inmsg->type);
}
+ name = bt_audio_strname(inmsg->name);
+ if (!name) {
+ status = G_IO_ERROR_INVAL;
+ GST_ERROR_OBJECT(self, "Bogus message name %d "
+ "received from audio service",
+ inmsg->name);
+ }
+
+ if (inmsg->type == BT_ERROR) {
+ bt_audio_error_t *err = (void *) inmsg;
+ status = G_IO_ERROR_INVAL;
+ GST_ERROR_OBJECT(self, "%s failed : "
+ "%s(%d)",
+ name,
+ strerror(err->posix_errno),
+ err->posix_errno);
+ }
+
+ GST_DEBUG_OBJECT(self, "received: %s <- %s", type, name);
+
return status;
}
static GIOError gst_avdtp_sink_audioservice_expect(
GstAvdtpSink *self, bt_audio_msg_header_t *outmsg,
- int expected_type)
+ guint8 expected_name)
{
GIOError status;
@@ -1266,7 +1298,7 @@ static GIOError gst_avdtp_sink_audioservice_expect(
if (status != G_IO_ERROR_NONE)
return status;
- if (outmsg->msg_type != expected_type)
+ if (outmsg->name != expected_name)
status = G_IO_ERROR_INVAL;
return status;
@@ -1357,5 +1389,3 @@ void gst_avdtp_sink_set_channel_mode(GstAvdtpSink *self,
GST_WARNING_OBJECT(self, "Received invalid channel "
"mode: %s", mode);
}
-
-