bluez: Fix gstreamer plugin to reflect the ipc changes.
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>
Tue, 16 Dec 2008 20:09:57 +0000 (17:09 -0300)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Wed, 9 Jan 2013 14:30:11 +0000 (14:30 +0000)
sys/bluez/gstavdtpsink.c

index 26a32f7..decbf3f 100644 (file)
@@ -63,7 +63,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 */
@@ -110,7 +110,7 @@ static GstStaticPadTemplate avdtp_sink_factory =
 static GIOError gst_avdtp_sink_audioservice_send (GstAvdtpSink * self,
     const bt_audio_msg_header_t * msg);
 static GIOError gst_avdtp_sink_audioservice_expect (GstAvdtpSink * self,
-    bt_audio_msg_header_t * outmsg, int expected_type);
+    bt_audio_msg_header_t * outmsg, guint8 expected_name);
 
 
 static void
@@ -245,16 +245,38 @@ 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))) {
@@ -589,6 +611,9 @@ gst_avdtp_sink_parse_mpeg_caps (GstAvdtpSink * self, mpeg_capabilities_t * mpeg)
   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");
@@ -702,14 +727,17 @@ gst_avdtp_sink_parse_mpeg_caps (GstAvdtpSink * self, mpeg_capabilities_t * mpeg)
 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);
 
@@ -729,14 +757,17 @@ 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);
@@ -750,19 +781,14 @@ 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;
@@ -882,16 +908,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) {
@@ -899,25 +925,14 @@ 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);
+  io_error = gst_avdtp_sink_audioservice_expect (self, &ind->h, BT_NEW_STREAM);
   if (io_error != G_IO_ERROR_NONE) {
     GST_ERROR_OBJECT (self, "Error while receiving " "stream filedescriptor");
     return FALSE;
@@ -1008,9 +1023,9 @@ gst_avdtp_sink_init_mp3_pkt_conf (GstAvdtpSink * self, GstCaps * caps,
 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;
@@ -1021,16 +1036,18 @@ gst_avdtp_sink_configure (GstAvdtpSink * self, GstCaps * caps)
   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);
+    ret = gst_avdtp_sink_init_sbc_pkt_conf (self, caps, (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);
+    ret = gst_avdtp_sink_init_mp3_pkt_conf (self, caps, (void *) &req->codec);
   else
     ret = FALSE;
 
@@ -1046,23 +1063,14 @@ gst_avdtp_sink_configure (GstAvdtpSink * self, GstCaps * caps)
     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;
 }
@@ -1196,13 +1204,19 @@ gst_avdtp_sink_audioservice_send (GstAvdtpSink * self,
 {
   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;
 }
 
@@ -1212,28 +1226,44 @@ gst_avdtp_sink_audioservice_recv (GstAvdtpSink * self,
 {
   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);
+        "received from audio service", 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)
+    bt_audio_msg_header_t * outmsg, guint8 expected_name)
 {
   GIOError status;
 
@@ -1241,7 +1271,7 @@ gst_avdtp_sink_audioservice_expect (GstAvdtpSink * self,
   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;