Update module-bluetooth-device to the new ipc.
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>
Wed, 17 Dec 2008 20:19:22 +0000 (17:19 -0300)
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>
Mon, 22 Dec 2008 17:24:07 +0000 (14:24 -0300)
src/modules/bluetooth/ipc.c
src/modules/bluetooth/ipc.h
src/modules/bluetooth/module-bluetooth-device.c

index 9825699..6778530 100644 (file)
 
 #include "ipc.h"
 
-/* This table contains the string representation for messages */
-static const char *strmsg[] = {
-       "BT_GETCAPABILITIES_REQ",
-       "BT_GETCAPABILITIES_RSP",
-       "BT_SETCONFIGURATION_REQ",
-       "BT_SETCONFIGURATION_RSP",
-       "BT_STREAMSTART_REQ",
-       "BT_STREAMSTART_RSP",
-       "BT_STREAMSTOP_REQ",
-       "BT_STREAMSTOP_RSP",
-       "BT_STREAMSUSPEND_IND",
-       "BT_STREAMRESUME_IND",
-       "BT_CONTROL_REQ",
-       "BT_CONTROL_RSP",
-       "BT_CONTROL_IND",
-       "BT_STREAMFD_IND",
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+/* This table contains the string representation for messages types */
+static const char *strtypes[] = {
+       "BT_REQUEST",
+       "BT_RESPONSE",
+       "BT_INDICATION",
+       "BT_ERROR",
+};
+
+/* This table contains the string representation for messages names */
+static const char *strnames[] = {
+       "BT_GET_CAPABILITIES",
+       "BT_SET_CONFIGURATION",
+       "BT_NEW_STREAM",
+       "BT_START_STREAM",
+       "BT_STOP_STREAM",
+       "BT_SUSPEND_STREAM",
+       "BT_RESUME_STREAM",
+       "BT_CONTROL",
 };
 
 int bt_audio_service_open(void)
@@ -88,7 +92,7 @@ int bt_audio_service_get_data_fd(int sk)
        msgh.msg_control = &cmsg_b;
        msgh.msg_controllen = CMSG_LEN(sizeof(int));
 
-       ret = (int) recvmsg(sk, &msgh, 0);
+       ret = recvmsg(sk, &msgh, 0);
        if (ret < 0) {
                err = errno;
                fprintf(stderr, "%s: Unable to receive fd: %s (%d)\n",
@@ -109,10 +113,18 @@ int bt_audio_service_get_data_fd(int sk)
        return -1;
 }
 
-const char *bt_audio_strmsg(int type)
+const char *bt_audio_strtype(uint8_t type)
+{
+       if (type >= ARRAY_SIZE(strtypes))
+               return NULL;
+
+       return strtypes[type];
+}
+
+const char *bt_audio_strname(uint8_t name)
 {
-    if (type < 0 || (size_t) type > (sizeof(strmsg) / sizeof(strmsg[0])))
+       if (name >= ARRAY_SIZE(strnames))
                return NULL;
 
-       return strmsg[type];
+       return strnames[name];
 }
index ae85e72..0e985c3 100644 (file)
 /*
   Message sequence chart of streaming sequence for A2DP transport
 
-  Audio daemon                       User
-                             on snd_pcm_open
-                 <--BT_GETCAPABILITIES_REQ
+  Audio daemon                 User
+                               on snd_pcm_open
+                               <--BT_GET_CAPABILITIES_REQ
 
-  BT_GETCAPABILITIES_RSP-->
+  BT_GET_CAPABILITIES_RSP-->
 
-                        on snd_pcm_hw_params
-                <--BT_SETCONFIGURATION_REQ
+                               on snd_pcm_hw_params
+                               <--BT_SETCONFIGURATION_REQ
 
-  BT_SETCONFIGURATION_RSP-->
+  BT_SET_CONFIGURATION_RSP-->
 
-                       on snd_pcm_prepare
-                <--BT_STREAMSTART_REQ
+                               on snd_pcm_prepare
+                               <--BT_START_STREAM_REQ
 
   <Moves to streaming state>
-  BT_STREAMSTART_RSP-->
+  BT_START_STREAM_RSP-->
 
-  BT_STREAMFD_IND -->
+  BT_NEW_STREAM_IND -->
 
-                          <  streams data >
-                             ..........
+                               <  streams data >
+                               ..........
 
-               on snd_pcm_drop/snd_pcm_drain
+                               on snd_pcm_drop/snd_pcm_drain
 
-                <--BT_STREAMSTOP_REQ
+                               <--BT_STOP_STREAM_REQ
 
   <Moves to open state>
-  BT_STREAMSTOP_RSP-->
+  BT_STOP_STREAM_RSP-->
 
-                       on IPC close or appl crash
+                               on IPC close or appl crash
   <Moves to idle>
 
  */
@@ -71,43 +71,36 @@ extern "C" {
 #include <sys/un.h>
 #include <errno.h>
 
-#define BT_AUDIO_IPC_PACKET_SIZE   128
+#define BT_SUGGESTED_BUFFER_SIZE   128
 #define BT_IPC_SOCKET_NAME "\0/org/bluez/audio"
 
-/* Generic message header definition, except for RSP messages */
+/* Generic message header definition, except for RESPONSE messages */
 typedef struct {
-       uint8_t msg_type;
+       uint8_t type;
+       uint8_t name;
+       uint16_t length;
 } __attribute__ ((packed)) bt_audio_msg_header_t;
 
-/* Generic message header definition, for all RSP messages */
 typedef struct {
-       bt_audio_msg_header_t   msg_h;
-       uint8_t                 posix_errno;
-} __attribute__ ((packed)) bt_audio_rsp_msg_header_t;
-
-/* Messages list */
-#define BT_GETCAPABILITIES_REQ         0
-#define BT_GETCAPABILITIES_RSP         1
-
-#define BT_SETCONFIGURATION_REQ                2
-#define BT_SETCONFIGURATION_RSP                3
-
-#define BT_STREAMSTART_REQ             4
-#define BT_STREAMSTART_RSP             5
-
-#define BT_STREAMSTOP_REQ              6
-#define BT_STREAMSTOP_RSP              7
-
-#define BT_STREAMSUSPEND_IND           8
-#define BT_STREAMRESUME_IND            9
-
-#define BT_CONTROL_REQ                10
-#define BT_CONTROL_RSP                11
-#define BT_CONTROL_IND                12
-
-#define BT_STREAMFD_IND                       13
-
-/* BT_GETCAPABILITIES_REQ */
+       bt_audio_msg_header_t h;
+       uint8_t posix_errno;
+} __attribute__ ((packed)) bt_audio_error_t;
+
+/* Message types */
+#define BT_REQUEST                     0
+#define BT_RESPONSE                    1
+#define BT_INDICATION                  2
+#define BT_ERROR                       3
+
+/* Messages names */
+#define BT_GET_CAPABILITIES            0
+#define BT_SET_CONFIGURATION           1
+#define BT_NEW_STREAM                  2
+#define BT_START_STREAM                        3
+#define BT_STOP_STREAM                 4
+#define BT_SUSPEND_STREAM              5
+#define BT_RESUME_STREAM               6
+#define BT_CONTROL                     7
 
 #define BT_CAPABILITIES_TRANSPORT_A2DP 0
 #define BT_CAPABILITIES_TRANSPORT_SCO  1
@@ -119,19 +112,22 @@ typedef struct {
 
 #define BT_FLAG_AUTOCONNECT    1
 
-struct bt_getcapabilities_req {
+struct bt_get_capabilities_req {
        bt_audio_msg_header_t   h;
        char                    device[18];     /* Address of the remote Device */
        uint8_t                 transport;      /* Requested transport */
        uint8_t                 flags;          /* Requested flags */
 } __attribute__ ((packed));
 
-/* BT_GETCAPABILITIES_RSP */
-
 /**
  * SBC Codec parameters as per A2DP profile 1.0 ยง 4.3
  */
 
+#define BT_A2DP_CODEC_SBC                      0x00
+#define BT_A2DP_CODEC_MPEG12                   0x01
+#define BT_A2DP_CODEC_MPEG24                   0x02
+#define BT_A2DP_CODEC_ATRAC                    0x03
+
 #define BT_SBC_SAMPLING_FREQ_16000             (1 << 3)
 #define BT_SBC_SAMPLING_FREQ_32000             (1 << 2)
 #define BT_SBC_SAMPLING_FREQ_44100             (1 << 1)
@@ -164,7 +160,19 @@ struct bt_getcapabilities_req {
 #define BT_MPEG_LAYER_2                                (1 << 1)
 #define BT_MPEG_LAYER_3                                1
 
+#define BT_HFP_CODEC_PCM                       0x00
+
+#define BT_PCM_FLAG_NREC                       1
+
+typedef struct {
+       uint8_t transport;
+       uint8_t type;
+       uint8_t length;
+       uint8_t data[0];
+} __attribute__ ((packed)) codec_capabilities_t;
+
 typedef struct {
+       codec_capabilities_t capability;
        uint8_t channel_mode;
        uint8_t frequency;
        uint8_t allocation_method;
@@ -175,6 +183,7 @@ typedef struct {
 } __attribute__ ((packed)) sbc_capabilities_t;
 
 typedef struct {
+       codec_capabilities_t capability;
        uint8_t channel_mode;
        uint8_t crc;
        uint8_t layer;
@@ -183,75 +192,65 @@ typedef struct {
        uint16_t bitrate;
 } __attribute__ ((packed)) mpeg_capabilities_t;
 
-struct bt_getcapabilities_rsp {
-       bt_audio_rsp_msg_header_t       rsp_h;
-       uint8_t                         transport;         /* Granted transport */
-       sbc_capabilities_t              sbc_capabilities;  /* A2DP only */
-       mpeg_capabilities_t             mpeg_capabilities; /* A2DP only */
-       uint16_t                        sampling_rate;     /* SCO only */
+typedef struct {
+       codec_capabilities_t capability;
+       uint8_t flags;
+       uint16_t sampling_rate;
+} __attribute__ ((packed)) pcm_capabilities_t;
+
+
+struct bt_get_capabilities_rsp {
+       bt_audio_msg_header_t   h;
+       uint8_t                 data[0];        /* First codec_capabilities_t */
 } __attribute__ ((packed));
 
-/* BT_SETCONFIGURATION_REQ */
-struct bt_setconfiguration_req {
+struct bt_set_configuration_req {
        bt_audio_msg_header_t   h;
-       char                    device[18];             /* Address of the remote Device */
-       uint8_t                 transport;              /* Requested transport */
-       uint8_t                 access_mode;            /* Requested access mode */
-       sbc_capabilities_t      sbc_capabilities;       /* A2DP only - only one of this field
-                                                       and next one must be filled */
-       mpeg_capabilities_t     mpeg_capabilities;      /* A2DP only */
+       char                    device[18];     /* Address of the remote Device */
+       uint8_t                 access_mode;    /* Requested access mode */
+       codec_capabilities_t    codec;          /* Requested codec */
 } __attribute__ ((packed));
 
-/* BT_SETCONFIGURATION_RSP */
-struct bt_setconfiguration_rsp {
-       bt_audio_rsp_msg_header_t       rsp_h;
-       uint8_t                         transport;      /* Granted transport */
-       uint8_t                         access_mode;    /* Granted access mode */
-       uint16_t                        link_mtu;       /* Max length that transport supports */
+struct bt_set_configuration_rsp {
+       bt_audio_msg_header_t   h;
+       uint8_t                 transport;      /* Granted transport */
+       uint8_t                 access_mode;    /* Granted access mode */
+       uint16_t                link_mtu;       /* Max length that transport supports */
 } __attribute__ ((packed));
 
-/* BT_STREAMSTART_REQ */
 #define BT_STREAM_ACCESS_READ          0
 #define BT_STREAM_ACCESS_WRITE         1
 #define BT_STREAM_ACCESS_READWRITE     2
-struct bt_streamstart_req {
+struct bt_start_stream_req {
        bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
 
-/* BT_STREAMSTART_RSP */
-struct bt_streamstart_rsp {
-       bt_audio_rsp_msg_header_t       rsp_h;
+struct bt_start_stream_rsp {
+       bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
 
-/* BT_STREAMFD_IND */
 /* This message is followed by one byte of data containing the stream data fd
    as ancilliary data */
-struct bt_streamfd_ind {
+struct bt_new_stream_ind {
        bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
 
-/* BT_STREAMSTOP_REQ */
-struct bt_streamstop_req {
+struct bt_stop_stream_req {
        bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
 
-/* BT_STREAMSTOP_RSP */
-struct bt_streamstop_rsp {
-       bt_audio_rsp_msg_header_t       rsp_h;
+struct bt_stop_stream_rsp {
+       bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
 
-/* BT_STREAMSUSPEND_IND */
-struct bt_streamsuspend_ind {
+struct bt_suspend_stream_ind {
        bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
 
-/* BT_STREAMRESUME_IND */
-struct bt_streamresume_ind {
+struct bt_resume_stream_ind {
        bt_audio_msg_header_t   h;
 } __attribute__ ((packed));
 
-/* BT_CONTROL_REQ */
-
 #define BT_CONTROL_KEY_POWER                   0x40
 #define BT_CONTROL_KEY_VOL_UP                  0x41
 #define BT_CONTROL_KEY_VOL_DOWN                        0x42
@@ -272,14 +271,12 @@ struct bt_control_req {
        uint8_t                 key;            /* Control Key */
 } __attribute__ ((packed));
 
-/* BT_CONTROL_RSP */
 struct bt_control_rsp {
-       bt_audio_rsp_msg_header_t       rsp_h;
-       uint8_t                         mode;   /* Control Mode */
-       uint8_t                         key;    /* Control Key */
+       bt_audio_msg_header_t   h;
+       uint8_t                 mode;           /* Control Mode */
+       uint8_t                 key;            /* Control Key */
 } __attribute__ ((packed));
 
-/* BT_CONTROL_IND */
 struct bt_control_ind {
        bt_audio_msg_header_t   h;
        uint8_t                 mode;           /* Control Mode */
@@ -299,7 +296,10 @@ BT_STREAMFD_IND message is returned */
 int bt_audio_service_get_data_fd(int sk);
 
 /* Human readable message type string */
-const char *bt_audio_strmsg(int type);
+const char *bt_audio_strtype(uint8_t type);
+
+/* Human readable message name string */
+const char *bt_audio_strname(uint8_t name);
 
 #ifdef __cplusplus
 }
index 3460fe9..5974d48 100644 (file)
@@ -122,8 +122,12 @@ static const char* const valid_modargs[] = {
 
 static int bt_audioservice_send(int sk, const bt_audio_msg_header_t *msg) {
     int e;
-    pa_log_debug("sending %s", bt_audio_strmsg(msg->msg_type));
-    if (send(sk, msg, BT_AUDIO_IPC_PACKET_SIZE, 0) > 0)
+    const char *type, *name;
+
+    type = bt_audio_strtype(msg->type);
+    name = bt_audio_strname(msg->name);
+    pa_log_debug("sending: %s -> %s", type, name);
+    if (send(sk, msg, BT_SUGGESTED_BUFFER_SIZE, 0) > 0)
         e = 0;
     else {
         e = -errno;
@@ -132,20 +136,22 @@ static int bt_audioservice_send(int sk, const bt_audio_msg_header_t *msg) {
     return e;
 }
 
-static int bt_audioservice_recv(int sk, bt_audio_msg_header_t *inmsg) {
+static int bt_audioservice_recv(int sk, bt_audio_msg_header_t *inmsg, uint16_t expected_length) {
     int e;
-    const char *type;
+    const char *type, *name;
 
     pa_log_debug("trying to receive msg from audio service...");
-    if (recv(sk, inmsg, BT_AUDIO_IPC_PACKET_SIZE, 0) > 0) {
-        type = bt_audio_strmsg(inmsg->msg_type);
-        if (type) {
-            pa_log_debug("Received %s", type);
+    if (recv(sk, inmsg, expected_length ? : BT_SUGGESTED_BUFFER_SIZE, 0) > 0) {
+        type = bt_audio_strtype(inmsg->type);
+        name = bt_audio_strname(inmsg->name);
+        if (type && name) {
+            pa_log_debug("Received: %s <- %s", type, name);
             e = 0;
         }
         else {
             e = -EINVAL;
-            pa_log_error("Bogus message type %d received from audio service", inmsg->msg_type);
+            pa_log_error("Bogus message type %d name %d received from audio service",
+                        inmsg->type, inmsg->name);
         }
     }
     else {
@@ -156,29 +162,66 @@ static int bt_audioservice_recv(int sk, bt_audio_msg_header_t *inmsg) {
     return e;
 }
 
-static int bt_audioservice_expect(int sk, bt_audio_msg_header_t *rsp_hdr, int expected_type) {
-    int e = bt_audioservice_recv(sk, rsp_hdr);
-    if (e == 0) {
-        if (rsp_hdr->msg_type != expected_type) {
+static int bt_audioservice_expect(int sk, bt_audio_msg_header_t *rsp, uint8_t expected_name, uint16_t expected_length) {
+    int e = bt_audioservice_recv(sk, rsp, expected_length);
+
+    if (e < 0) {
+        if (rsp->name != expected_name) {
             e = -EINVAL;
-            pa_log_error("Bogus message %s received while %s was expected", bt_audio_strmsg(rsp_hdr->msg_type),
-                    bt_audio_strmsg(expected_type));
+            pa_log_error("Bogus message %s received while %s was expected",
+                    bt_audio_strname(rsp->name),
+                    bt_audio_strname(expected_name));
         }
     }
+
+    if (rsp->type == BT_ERROR) {
+        bt_audio_error_t *error = (void *) rsp;
+        pa_log_error("%s failed : %s(%d)", bt_audio_strname(rsp->name), pa_cstrerror(error->posix_errno), error->posix_errno);
+        return -error->posix_errno;
+    }
+
     return e;
 }
 
+static int bt_parsecaps(struct userdata *u, struct bt_get_capabilities_rsp *rsp) {
+    uint16_t bytes_left = rsp->h.length - sizeof(*rsp);
+    codec_capabilities_t *codec = (void *) rsp->data;
+
+    u->transport = codec->transport;
+
+    if (codec->transport != BT_CAPABILITIES_TRANSPORT_A2DP)
+        return 0;
+
+    while (bytes_left > 0) {
+        if (codec->type == BT_A2DP_CODEC_SBC)
+            break;
+
+        bytes_left -= codec->length;
+        codec = (void *) (codec + codec->length);
+    }
+
+    if (bytes_left <= 0 || codec->length != sizeof(u->a2dp.sbc_capabilities))
+        return -EINVAL;
+
+    memcpy(&u->a2dp.sbc_capabilities, codec, codec->length);
+
+    return 0;
+}
+
 static int bt_getcaps(struct userdata *u) {
     int e;
     union {
-        bt_audio_rsp_msg_header_t rsp_hdr;
-        struct bt_getcapabilities_req getcaps_req;
-        struct bt_getcapabilities_rsp getcaps_rsp;
-        uint8_t buf[BT_AUDIO_IPC_PACKET_SIZE];
+        bt_audio_msg_header_t rsp;
+        struct bt_get_capabilities_req getcaps_req;
+        struct bt_get_capabilities_rsp getcaps_rsp;
+        uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
     } msg;
 
-    memset(msg.buf, 0, BT_AUDIO_IPC_PACKET_SIZE);
-    msg.getcaps_req.h.msg_type = BT_GETCAPABILITIES_REQ;
+    memset(msg.buf, 0, BT_SUGGESTED_BUFFER_SIZE);
+    msg.getcaps_req.h.type = BT_REQUEST;
+    msg.getcaps_req.h.name = BT_GET_CAPABILITIES;
+    msg.getcaps_req.h.length = sizeof(msg.getcaps_req);
+
     strncpy(msg.getcaps_req.device, u->addr, 18);
     if (strcasecmp(u->profile, "a2dp") == 0)
         msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_A2DP;
@@ -196,20 +239,13 @@ static int bt_getcaps(struct userdata *u) {
         return e;
     }
 
-    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp_hdr.msg_h, BT_GETCAPABILITIES_RSP);
+    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp, BT_GET_CAPABILITIES, 0);
     if (e < 0) {
         pa_log_error("Failed to expect for GETCAPABILITIES_RSP");
         return e;
     }
-    if (msg.rsp_hdr.posix_errno != 0) {
-        pa_log_error("BT_GETCAPABILITIES failed : %s (%d)", pa_cstrerror(msg.rsp_hdr.posix_errno), msg.rsp_hdr.posix_errno);
-        return -msg.rsp_hdr.posix_errno;
-    }
-
-    if ((u->transport = msg.getcaps_rsp.transport) == BT_CAPABILITIES_TRANSPORT_A2DP)
-        u->a2dp.sbc_capabilities = msg.getcaps_rsp.sbc_capabilities;
 
-    return 0;
+    return bt_parsecaps(u, &msg.getcaps_rsp);
 }
 
 static uint8_t default_bitpool(uint8_t freq, uint8_t mode) {
@@ -393,10 +429,10 @@ static void bt_a2dp_setup(struct bt_a2dp *a2dp) {
 static int bt_setconf(struct userdata *u) {
     int e;
     union {
-        bt_audio_rsp_msg_header_t rsp_hdr;
-        struct bt_setconfiguration_req setconf_req;
-        struct bt_setconfiguration_rsp setconf_rsp;
-        uint8_t buf[BT_AUDIO_IPC_PACKET_SIZE];
+        bt_audio_msg_header_t rsp;
+        struct bt_set_configuration_req setconf_req;
+        struct bt_set_configuration_rsp setconf_rsp;
+        uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
     } msg;
 
     if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
@@ -410,12 +446,16 @@ static int bt_setconf(struct userdata *u) {
     else
         u->ss.format = PA_SAMPLE_U8;
 
-    memset(msg.buf, 0, BT_AUDIO_IPC_PACKET_SIZE);
-    msg.setconf_req.h.msg_type = BT_SETCONFIGURATION_REQ;
+    memset(msg.buf, 0, BT_SUGGESTED_BUFFER_SIZE);
+    msg.setconf_req.h.type = BT_REQUEST;
+    msg.setconf_req.h.name = BT_SET_CONFIGURATION;
+    msg.setconf_req.h.length = sizeof(msg.setconf_req);
+
     strncpy(msg.setconf_req.device, u->addr, 18);
-    msg.setconf_req.transport = u->transport;
+    msg.setconf_req.codec.transport = u->transport;
     if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP)
-        msg.setconf_req.sbc_capabilities = u->a2dp.sbc_capabilities;
+        memcpy(&msg.setconf_req.codec, &u->a2dp.sbc_capabilities,
+                sizeof(u->a2dp.sbc_capabilities));
     msg.setconf_req.access_mode = BT_CAPABILITIES_ACCESS_MODE_WRITE;
 
     e = bt_audioservice_send(u->audioservice_fd, &msg.setconf_req.h);
@@ -424,17 +464,12 @@ static int bt_setconf(struct userdata *u) {
         return e;
     }
 
-    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp_hdr.msg_h, BT_SETCONFIGURATION_RSP);
+    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp, BT_SET_CONFIGURATION, sizeof(msg.setconf_rsp));
     if (e < 0) {
         pa_log_error("Failed to expect BT_SETCONFIGURATION_RSP");
         return e;
     }
 
-    if (msg.rsp_hdr.posix_errno != 0) {
-        pa_log_error("BT_SETCONFIGURATION failed : %s(%d)", pa_cstrerror(msg.rsp_hdr.posix_errno), msg.rsp_hdr.posix_errno);
-        return -msg.rsp_hdr.posix_errno;
-    }
-
     u->transport = msg.setconf_rsp.transport;
     u->strtransport = (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP ? pa_xstrdup("A2DP") : pa_xstrdup("SCO"));
     u->link_mtu = msg.setconf_rsp.link_mtu;
@@ -456,14 +491,17 @@ static int bt_getstreamfd(struct userdata *u) {
     int e;
 //    uint32_t period_count = io->buffer_size / io->period_size;
     union {
-        bt_audio_rsp_msg_header_t rsp_hdr;
-        struct bt_streamstart_req start_req;
-        struct bt_streamfd_ind streamfd_ind;
-        uint8_t buf[BT_AUDIO_IPC_PACKET_SIZE];
+        bt_audio_msg_header_t rsp;
+        struct bt_start_stream_req start_req;
+        struct bt_start_stream_rsp start_rsp;
+        struct bt_new_stream_ind streamfd_ind;
+        uint8_t buf[BT_SUGGESTED_BUFFER_SIZE];
     } msg;
 
-    memset(msg.buf, 0, BT_AUDIO_IPC_PACKET_SIZE);
-    msg.start_req.h.msg_type = BT_STREAMSTART_REQ;
+    memset(msg.buf, 0, BT_SUGGESTED_BUFFER_SIZE);
+    msg.start_req.h.type = BT_REQUEST;
+    msg.start_req.h.name = BT_START_STREAM;
+    msg.start_req.h.length = sizeof(msg.start_req);
 
     e = bt_audioservice_send(u->audioservice_fd, &msg.start_req.h);
     if (e < 0) {
@@ -471,18 +509,13 @@ static int bt_getstreamfd(struct userdata *u) {
         return e;
     }
 
-    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp_hdr.msg_h, BT_STREAMSTART_RSP);
+    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp, BT_START_STREAM, sizeof(msg.start_rsp));
     if (e < 0) {
         pa_log_error("Failed to expect BT_STREAMSTART_RSP");
         return e;
     }
 
-    if (msg.rsp_hdr.posix_errno != 0) {
-        pa_log_error("BT_START failed : %s(%d)", pa_cstrerror(msg.rsp_hdr.posix_errno), msg.rsp_hdr.posix_errno);
-        return -msg.rsp_hdr.posix_errno;
-    }
-
-    e = bt_audioservice_expect(u->audioservice_fd, &msg.streamfd_ind.h, BT_STREAMFD_IND);
+    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp, BT_NEW_STREAM, sizeof(msg.streamfd_ind));
     if (e < 0) {
         pa_log_error("Failed to expect BT_STREAMFD_IND");
         return e;