From 4fdebe9404a020d0bc20776f6571999e76a15440 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 17 Dec 2008 17:19:22 -0300 Subject: Update module-bluetooth-device to the new ipc. --- src/modules/bluetooth/ipc.c | 52 ++++--- src/modules/bluetooth/ipc.h | 190 ++++++++++++------------ src/modules/bluetooth/module-bluetooth-device.c | 147 +++++++++++------- 3 files changed, 217 insertions(+), 172 deletions(-) (limited to 'src') diff --git a/src/modules/bluetooth/ipc.c b/src/modules/bluetooth/ipc.c index 98256998..67785309 100644 --- a/src/modules/bluetooth/ipc.c +++ b/src/modules/bluetooth/ipc.c @@ -22,22 +22,26 @@ #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]; } diff --git a/src/modules/bluetooth/ipc.h b/src/modules/bluetooth/ipc.h index ae85e727..0e985c3a 100644 --- a/src/modules/bluetooth/ipc.h +++ b/src/modules/bluetooth/ipc.h @@ -23,36 +23,36 @@ /* 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 - 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 - BT_STREAMSTOP_RSP--> + BT_STOP_STREAM_RSP--> - on IPC close or appl crash + on IPC close or appl crash */ @@ -71,43 +71,36 @@ extern "C" { #include #include -#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 } diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c index 3460fe9a..5974d485 100644 --- a/src/modules/bluetooth/module-bluetooth-device.c +++ b/src/modules/bluetooth/module-bluetooth-device.c @@ -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; -- cgit