[pulseaudio-commits] 6 commits - configure.ac src/modules src/pulse src/pulsecore src/tests
Arun Raghavan
arun at kemper.freedesktop.org
Thu Oct 30 22:20:13 PDT 2014
configure.ac | 6
src/modules/bluetooth/backend-native.c | 501 +++++++++++++++++++++++++++
src/modules/bluetooth/bluez5-util.c | 2
src/modules/bluetooth/bluez5-util.h | 11
src/modules/bluetooth/module-bluez5-device.c | 172 ++++++++-
src/modules/module-tunnel.c | 4
src/pulse/context.c | 4
src/pulsecore/creds.h | 10
src/pulsecore/iochannel.c | 32 -
src/pulsecore/iochannel.h | 2
src/pulsecore/pdispatch.c | 18
src/pulsecore/pdispatch.h | 2
src/pulsecore/protocol-native.c | 4
src/pulsecore/pstream-util.c | 20 -
src/pulsecore/pstream.c | 62 +--
src/pulsecore/pstream.h | 4
src/tests/srbchannel-test.c | 2
17 files changed, 754 insertions(+), 102 deletions(-)
New commits:
commit 5dfa83385c457766954d40d8998eda028ed7d57b
Author: Arun Raghavan <arun at accosted.net>
Date: Fri Oct 31 10:15:02 2014 +0530
bluetooth: Fix some native backend command sending
We weren't writing out one character from the "OK" response, and the
"AT" part of the "+VGS" and "+VGM" commands was missing. Also, the spec
says that the command is terminated by only a CR and not an LF (probably
doesn't hurt, but let's adhere to the spec for now).
diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
index aa2b756..a9dc64c 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -248,7 +248,7 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i
pa_log_debug("RFCOMM >> OK");
- len = write(fd, "\r\nOK\r\n", 5);
+ len = write(fd, "\r\nOK\r\n", 6);
/* we ignore any errors, it's not critical and real errors should
* be caught with the HANGUP and ERROR events handled above */
@@ -285,8 +285,8 @@ static void set_speaker_gain(pa_bluetooth_transport *t, uint16_t gain) {
t->speaker_gain = gain;
- len = sprintf(buf, "+VGS=%d\r\n", gain);
- pa_log_debug("RFCOMM >> +VGS=%d", gain);
+ len = sprintf(buf, "AT+VGS=%d\r", gain);
+ pa_log_debug("RFCOMM >> AT+VGS=%d", gain);
written = write(trfc->rfcomm_fd, buf, len);
@@ -304,8 +304,8 @@ static void set_microphone_gain(pa_bluetooth_transport *t, uint16_t gain) {
t->microphone_gain = gain;
- len = sprintf(buf, "+VGM=%d\r\n", gain);
- pa_log_debug("RFCOMM >> +VGM=%d", gain);
+ len = sprintf(buf, "AT+VGM=%d\r", gain);
+ pa_log_debug("RFCOMM >> AT+VGM=%d", gain);
written = write (trfc->rfcomm_fd, buf, len);
commit 34a5c754a90e46168c8a540ee13d9289dfb31247
Author: Wim Taymans <wim.taymans at gmail.com>
Date: Fri Oct 24 09:56:52 2014 +0200
backend-native: implement volume control
Parse the gain changed AT commands from the headset and fire 2 new
hooks as a result. The device will connect to those hooks and change the
source/sink volumes.
When the source/sink volume changes, set the gain on the microphone or
speaker respectively. Make sure we do nothing if the transport can not
handle the gain changes.
diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
index db9bce9..aa2b756 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -114,6 +114,7 @@ static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_
src_addr = d->adapter->address;
dst_addr = d->address;
+ /* don't use ba2str to avoid -lbluetooth */
for (i = 5; i >= 0; i--, src_addr += 3)
src.b[i] = strtol(src_addr, NULL, 16);
for (i = 5; i >= 0; i--, dst_addr += 3)
@@ -230,13 +231,25 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i
if (events & PA_IO_EVENT_INPUT) {
char buf[512];
ssize_t len;
+ int gain;
len = read(fd, buf, 511);
buf[len] = 0;
pa_log_debug("RFCOMM << %s", buf);
+ if (sscanf(buf, "AT+VGS=%d", &gain) == 1) {
+ t->speaker_gain = gain;
+ pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED), t);
+
+ } else if (sscanf(buf, "AT+VGM=%d", &gain) == 1) {
+ t->microphone_gain = gain;
+ pa_hook_fire(pa_bluetooth_discovery_hook(t->device->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED), t);
+ }
+
pa_log_debug("RFCOMM >> OK");
- len = write (fd, "\r\nOK\r\n", 5);
+
+ len = write(fd, "\r\nOK\r\n", 5);
+
/* we ignore any errors, it's not critical and real errors should
* be caught with the HANGUP and ERROR events handled above */
if (len < 0)
@@ -262,6 +275,44 @@ static void transport_destroy(pa_bluetooth_transport *t) {
pa_xfree(trfc);
}
+static void set_speaker_gain(pa_bluetooth_transport *t, uint16_t gain) {
+ struct transport_rfcomm *trfc = t->userdata;
+ char buf[512];
+ ssize_t len, written;
+
+ if (t->speaker_gain == gain)
+ return;
+
+ t->speaker_gain = gain;
+
+ len = sprintf(buf, "+VGS=%d\r\n", gain);
+ pa_log_debug("RFCOMM >> +VGS=%d", gain);
+
+ written = write(trfc->rfcomm_fd, buf, len);
+
+ if (written != len)
+ pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
+}
+
+static void set_microphone_gain(pa_bluetooth_transport *t, uint16_t gain) {
+ struct transport_rfcomm *trfc = t->userdata;
+ char buf[512];
+ ssize_t len, written;
+
+ if (t->microphone_gain == gain)
+ return;
+
+ t->microphone_gain = gain;
+
+ len = sprintf(buf, "+VGM=%d\r\n", gain);
+ pa_log_debug("RFCOMM >> +VGM=%d", gain);
+
+ written = write (trfc->rfcomm_fd, buf, len);
+
+ if (written != len)
+ pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
+}
+
static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m, void *userdata) {
pa_bluetooth_backend *b = userdata;
pa_bluetooth_device *d;
@@ -308,6 +359,8 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m,
t->acquire = bluez5_sco_acquire_cb;
t->release = bluez5_sco_release_cb;
t->destroy = transport_destroy;
+ t->set_speaker_gain = set_speaker_gain;
+ t->set_microphone_gain = set_microphone_gain;
trfc = pa_xnew0(struct transport_rfcomm, 1);
trfc->rfcomm_fd = fd;
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
index 1a8a364..3ef0ac8 100644
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -40,6 +40,8 @@ typedef struct pa_bluetooth_backend pa_bluetooth_backend;
typedef enum pa_bluetooth_hook {
PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED, /* Call data: pa_bluetooth_device */
PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED, /* Call data: pa_bluetooth_transport */
+ PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */
+ PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED, /* Call data: pa_bluetooth_transport */
PA_BLUETOOTH_HOOK_MAX
} pa_bluetooth_hook_t;
@@ -61,6 +63,8 @@ typedef enum pa_bluetooth_transport_state {
typedef int (*pa_bluetooth_transport_acquire_cb)(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu);
typedef void (*pa_bluetooth_transport_release_cb)(pa_bluetooth_transport *t);
typedef void (*pa_bluetooth_transport_destroy_cb)(pa_bluetooth_transport *t);
+typedef void (*pa_bluetooth_transport_set_speaker_gain_cb)(pa_bluetooth_transport *t, uint16_t gain);
+typedef void (*pa_bluetooth_transport_set_microphone_gain_cb)(pa_bluetooth_transport *t, uint16_t gain);
struct pa_bluetooth_transport {
pa_bluetooth_device *device;
@@ -73,11 +77,16 @@ struct pa_bluetooth_transport {
uint8_t *config;
size_t config_size;
+ uint16_t microphone_gain;
+ uint16_t speaker_gain;
+
pa_bluetooth_transport_state_t state;
pa_bluetooth_transport_acquire_cb acquire;
pa_bluetooth_transport_release_cb release;
pa_bluetooth_transport_destroy_cb destroy;
+ pa_bluetooth_transport_set_speaker_gain_cb set_speaker_gain;
+ pa_bluetooth_transport_set_microphone_gain_cb set_microphone_gain;
void *userdata;
};
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index 15731d1..d077161 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -66,6 +66,7 @@ PA_MODULE_USAGE("path=<device object path>");
#define BITPOOL_DEC_LIMIT 32
#define BITPOOL_DEC_STEP 5
+#define HSP_MAX_GAIN 15
static const char* const valid_modargs[] = {
"path",
@@ -103,6 +104,8 @@ struct userdata {
pa_hook_slot *device_connection_changed_slot;
pa_hook_slot *transport_state_changed_slot;
+ pa_hook_slot *transport_speaker_gain_changed_slot;
+ pa_hook_slot *transport_microphone_gain_changed_slot;
pa_bluetooth_discovery *discovery;
pa_bluetooth_device *device;
@@ -903,6 +906,40 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
}
/* Run from main thread */
+static void source_set_volume_cb(pa_source *s) {
+ uint16_t gain;
+ pa_volume_t volume;
+ struct userdata *u;
+
+ pa_assert(s);
+ pa_assert(s->core);
+
+ u = s->userdata;
+
+ pa_assert(u);
+ pa_assert(u->source == s);
+ pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
+
+ if (u->transport->set_microphone_gain == NULL)
+ return;
+
+ gain = (pa_cvolume_max(&s->real_volume) * HSP_MAX_GAIN) / PA_VOLUME_NORM;
+
+ if (gain > HSP_MAX_GAIN)
+ gain = HSP_MAX_GAIN;
+
+ volume = (pa_volume_t) (gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
+
+ /* increment volume by one to correct rounding errors */
+ if (volume < PA_VOLUME_NORM)
+ volume++;
+
+ pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume);
+
+ u->transport->set_microphone_gain(u->transport, gain);
+}
+
+/* Run from main thread */
static int add_source(struct userdata *u) {
pa_source_new_data data;
@@ -944,6 +981,10 @@ static int add_source(struct userdata *u) {
u->source->userdata = u;
u->source->parent.process_msg = source_process_msg;
+ if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT) {
+ pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
+ u->source->n_volume_steps = 16;
+ }
return 0;
}
@@ -1022,6 +1063,40 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
}
/* Run from main thread */
+static void sink_set_volume_cb(pa_sink *s) {
+ uint16_t gain;
+ pa_volume_t volume;
+ struct userdata *u;
+
+ pa_assert(s);
+ pa_assert(s->core);
+
+ u = s->userdata;
+
+ pa_assert(u);
+ pa_assert(u->sink == s);
+ pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
+
+ if (u->transport->set_speaker_gain == NULL)
+ return;
+
+ gain = (pa_cvolume_max(&s->real_volume) * HSP_MAX_GAIN) / PA_VOLUME_NORM;
+
+ if (gain > HSP_MAX_GAIN)
+ gain = HSP_MAX_GAIN;
+
+ volume = (pa_volume_t) (gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
+
+ /* increment volume by one to correct rounding errors */
+ if (volume < PA_VOLUME_NORM)
+ volume++;
+
+ pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume);
+
+ u->transport->set_speaker_gain(u->transport, gain);
+}
+
+/* Run from main thread */
static int add_sink(struct userdata *u) {
pa_sink_new_data data;
@@ -1064,6 +1139,10 @@ static int add_sink(struct userdata *u) {
u->sink->userdata = u;
u->sink->parent.process_msg = sink_process_msg;
+ if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT) {
+ pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
+ u->sink->n_volume_steps = 16;
+ }
return 0;
}
@@ -1975,6 +2054,54 @@ static pa_hook_result_t transport_state_changed_cb(pa_bluetooth_discovery *y, pa
return PA_HOOK_OK;
}
+static pa_hook_result_t transport_speaker_gain_changed_cb(pa_bluetooth_discovery *y, pa_bluetooth_transport *t, struct userdata *u) {
+ pa_volume_t volume;
+ pa_cvolume v;
+ uint16_t gain;
+
+ pa_assert(t);
+ pa_assert(u);
+
+ if (t != u->transport)
+ return PA_HOOK_OK;
+
+ gain = t->speaker_gain;
+ volume = (pa_volume_t) (gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
+
+ /* increment volume by one to correct rounding errors */
+ if (volume < PA_VOLUME_NORM)
+ volume++;
+
+ pa_cvolume_set(&v, u->sample_spec.channels, volume);
+ pa_sink_volume_changed(u->sink, &v);
+
+ return PA_HOOK_OK;
+}
+
+static pa_hook_result_t transport_microphone_gain_changed_cb(pa_bluetooth_discovery *y, pa_bluetooth_transport *t, struct userdata *u) {
+ pa_volume_t volume;
+ pa_cvolume v;
+ uint16_t gain;
+
+ pa_assert(t);
+ pa_assert(u);
+
+ if (t != u->transport)
+ return PA_HOOK_OK;
+
+ gain = t->microphone_gain;
+ volume = (pa_volume_t) (gain * PA_VOLUME_NORM / HSP_MAX_GAIN);
+
+ /* increment volume by one to correct rounding errors */
+ if (volume < PA_VOLUME_NORM)
+ volume++;
+
+ pa_cvolume_set(&v, u->sample_spec.channels, volume);
+ pa_source_volume_changed(u->source, &v);
+
+ return PA_HOOK_OK;
+}
+
/* Run from main thread context */
static int device_process_msg(pa_msgobject *obj, int code, void *data, int64_t offset, pa_memchunk *chunk) {
struct bluetooth_msg *m = BLUETOOTH_MSG(obj);
@@ -2039,6 +2166,13 @@ int pa__init(pa_module* m) {
pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED),
PA_HOOK_NORMAL, (pa_hook_cb_t) transport_state_changed_cb, u);
+ u->transport_speaker_gain_changed_slot =
+ pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_SPEAKER_GAIN_CHANGED), PA_HOOK_NORMAL, (pa_hook_cb_t) transport_speaker_gain_changed_cb, u);
+
+ u->transport_microphone_gain_changed_slot =
+ pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_TRANSPORT_MICROPHONE_GAIN_CHANGED), PA_HOOK_NORMAL, (pa_hook_cb_t) transport_microphone_gain_changed_cb, u);
+
+
if (add_card(u) < 0)
goto fail;
@@ -2091,6 +2225,12 @@ void pa__done(pa_module *m) {
if (u->transport_state_changed_slot)
pa_hook_slot_free(u->transport_state_changed_slot);
+ if (u->transport_speaker_gain_changed_slot)
+ pa_hook_slot_free(u->transport_speaker_gain_changed_slot);
+
+ if (u->transport_microphone_gain_changed_slot)
+ pa_hook_slot_free(u->transport_microphone_gain_changed_slot);
+
if (u->sbc_info.buffer)
pa_xfree(u->sbc_info.buffer);
commit 7d4a497b3db6e3c58fb5fe64131c8f81cade85b7
Author: Wim Taymans <wim.taymans at gmail.com>
Date: Fri Oct 24 09:56:51 2014 +0200
backend-native: add a new native headset backend
Add a simple native headset backend that implements support for the
blutooth HSP profile.
This allows pulseaudio to output audio to a Headset using the HSP profile.
Make the native backend the default.
diff --git a/configure.ac b/configure.ac
index f807699..f165eb4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1036,14 +1036,14 @@ AM_CONDITIONAL([HAVE_BLUEZ], [test "x$HAVE_BLUEZ" = x1])
## Bluetooth Headset profiles backend ##
AC_ARG_WITH(bluetooth_headset_backend,
- AS_HELP_STRING([--with-bluetooth-headset-backend=<ofono|null>],[Backend for Bluetooth headset profiles (ofono)]))
+ AS_HELP_STRING([--with-bluetooth-headset-backend=<ofono|native|null>],[Backend for Bluetooth headset profiles (native)]))
if test -z "$with_bluetooth_headset_backend" ; then
- BLUETOOTH_HEADSET_BACKEND=ofono
+ BLUETOOTH_HEADSET_BACKEND=native
else
BLUETOOTH_HEADSET_BACKEND=$with_bluetooth_headset_backend
fi
-AS_IF([test "x$BLUETOOTH_HEADSET_BACKEND" != "xofono" && test "x$BLUETOOTH_HEADSET_BACKEND" != "xnull"],
+AS_IF([test "x$BLUETOOTH_HEADSET_BACKEND" != "xofono" && test "x$BLUETOOTH_HEADSET_BACKEND" != "xnull" && test "x$BLUETOOTH_HEADSET_BACKEND" != "xnative"],
[AC_MSG_ERROR([*** Invalid Bluetooth Headset backend])])
AC_SUBST(BLUETOOTH_HEADSET_BACKEND)
diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
new file mode 100644
index 0000000..db9bce9
--- /dev/null
+++ b/src/modules/bluetooth/backend-native.c
@@ -0,0 +1,448 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2014 Wim Taymans <wim.taymans at gmail.com>
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/shared.h>
+#include <pulsecore/core-error.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/dbus-shared.h>
+#include <pulsecore/log.h>
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sco.h>
+
+#include "bluez5-util.h"
+
+struct pa_bluetooth_backend {
+ pa_core *core;
+ pa_dbus_connection *connection;
+ pa_bluetooth_discovery *discovery;
+
+ PA_LLIST_HEAD(pa_dbus_pending, pending);
+};
+
+struct transport_rfcomm {
+ int rfcomm_fd;
+ pa_io_event *rfcomm_io;
+ pa_mainloop_api *mainloop;
+};
+
+#define BLUEZ_SERVICE "org.bluez"
+#define BLUEZ_MEDIA_TRANSPORT_INTERFACE BLUEZ_SERVICE ".MediaTransport1"
+
+#define BLUEZ_ERROR_NOT_SUPPORTED "org.bluez.Error.NotSupported"
+
+#define BLUEZ_PROFILE_MANAGER_INTERFACE BLUEZ_SERVICE ".ProfileManager1"
+#define BLUEZ_PROFILE_INTERFACE BLUEZ_SERVICE ".Profile1"
+
+#define HSP_AG_PROFILE "/Profile/HSPAGProfile"
+
+#define PROFILE_INTROSPECT_XML \
+ DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
+ "<node>" \
+ " <interface name=\"" BLUEZ_PROFILE_INTERFACE "\">" \
+ " <method name=\"Release\">" \
+ " </method>" \
+ " <method name=\"RequestDisconnection\">" \
+ " <arg name=\"device\" direction=\"in\" type=\"o\"/>" \
+ " </method>" \
+ " <method name=\"NewConnection\">" \
+ " <arg name=\"device\" direction=\"in\" type=\"o\"/>" \
+ " <arg name=\"fd\" direction=\"in\" type=\"h\"/>" \
+ " <arg name=\"opts\" direction=\"in\" type=\"a{sv}\"/>" \
+ " </method>" \
+ " </interface>" \
+ " <interface name=\"org.freedesktop.DBus.Introspectable\">" \
+ " <method name=\"Introspect\">" \
+ " <arg name=\"data\" type=\"s\" direction=\"out\"/>" \
+ " </method>" \
+ " </interface>" \
+ "</node>"
+
+static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_backend *backend, DBusMessage *m,
+ DBusPendingCallNotifyFunction func, void *call_data) {
+
+ pa_dbus_pending *p;
+ DBusPendingCall *call;
+
+ pa_assert(backend);
+ pa_assert(m);
+
+ pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(backend->connection), m, &call, -1));
+
+ p = pa_dbus_pending_new(pa_dbus_connection_get(backend->connection), m, call, backend, call_data);
+ PA_LLIST_PREPEND(pa_dbus_pending, backend->pending, p);
+ dbus_pending_call_set_notify(call, func, p, NULL);
+
+ return p;
+}
+
+static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) {
+ pa_bluetooth_device *d = t->device;
+ struct sockaddr_sco addr;
+ int err, i;
+ int sock;
+ bdaddr_t src;
+ bdaddr_t dst;
+ const char *src_addr, *dst_addr;
+
+ src_addr = d->adapter->address;
+ dst_addr = d->address;
+
+ for (i = 5; i >= 0; i--, src_addr += 3)
+ src.b[i] = strtol(src_addr, NULL, 16);
+ for (i = 5; i >= 0; i--, dst_addr += 3)
+ dst.b[i] = strtol(dst_addr, NULL, 16);
+
+ sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
+ if (sock < 0) {
+ pa_log_error("socket(SEQPACKET, SCO) %s", pa_cstrerror(errno));
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sco_family = AF_BLUETOOTH;
+ bacpy(&addr.sco_bdaddr, &src);
+
+ if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ pa_log_error("bind(): %s", pa_cstrerror(errno));
+ goto fail_close;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sco_family = AF_BLUETOOTH;
+ bacpy(&addr.sco_bdaddr, &dst);
+
+ pa_log_info ("doing connect\n");
+ err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
+ if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) {
+ pa_log_error("connect(): %s", pa_cstrerror(errno));
+ goto fail_close;
+ }
+
+ /* The "48" below is hardcoded until we get meaningful MTU values exposed
+ * by the kernel */
+
+ if (imtu)
+ *imtu = 48;
+
+ if (omtu)
+ *omtu = 48;
+
+ return sock;
+
+fail_close:
+ close(sock);
+ return -1;
+}
+
+static void bluez5_sco_release_cb(pa_bluetooth_transport *t) {
+ pa_log_info("Transport %s released", t->path);
+ /* device will close the SCO socket for us */
+}
+
+static void register_profile_reply(DBusPendingCall *pending, void *userdata) {
+ DBusMessage *r;
+ pa_dbus_pending *p;
+ pa_bluetooth_backend *b;
+ char *profile;
+
+ pa_assert(pending);
+ pa_assert_se(p = userdata);
+ pa_assert_se(b = p->context_data);
+ pa_assert_se(profile = p->call_data);
+ pa_assert_se(r = dbus_pending_call_steal_reply(pending));
+
+ if (dbus_message_is_error(r, BLUEZ_ERROR_NOT_SUPPORTED)) {
+ pa_log_info("Couldn't register profile %s because it is disabled in BlueZ", profile);
+ goto finish;
+ }
+
+ if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
+ pa_log_error(BLUEZ_PROFILE_MANAGER_INTERFACE ".RegisterProfile() failed: %s: %s", dbus_message_get_error_name(r),
+ pa_dbus_get_error_message(r));
+ goto finish;
+ }
+
+finish:
+ dbus_message_unref(r);
+
+ PA_LLIST_REMOVE(pa_dbus_pending, b->pending, p);
+ pa_dbus_pending_free(p);
+
+ pa_xfree(profile);
+}
+
+static void register_profile(pa_bluetooth_backend *b, const char *profile, const char *uuid) {
+ DBusMessage *m;
+ DBusMessageIter i, d;
+
+ pa_log_debug("Registering Profile %s", profile);
+
+ pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, "/org/bluez", BLUEZ_PROFILE_MANAGER_INTERFACE, "RegisterProfile"));
+
+ dbus_message_iter_init_append(m, &i);
+ dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &profile);
+ dbus_message_iter_append_basic(&i, DBUS_TYPE_STRING, &uuid);
+ dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &d);
+ dbus_message_iter_close_container(&i, &d);
+
+ send_and_add_to_pending(b, m, register_profile_reply, pa_xstrdup(profile));
+}
+
+static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
+ pa_bluetooth_transport *t = userdata;
+
+ pa_assert(io);
+ pa_assert(t);
+
+ if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) {
+ pa_log_info("Lost RFCOMM connection.");
+ goto fail;
+ }
+
+ if (events & PA_IO_EVENT_INPUT) {
+ char buf[512];
+ ssize_t len;
+
+ len = read(fd, buf, 511);
+ buf[len] = 0;
+ pa_log_debug("RFCOMM << %s", buf);
+
+ pa_log_debug("RFCOMM >> OK");
+ len = write (fd, "\r\nOK\r\n", 5);
+ /* we ignore any errors, it's not critical and real errors should
+ * be caught with the HANGUP and ERROR events handled above */
+ if (len < 0)
+ pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
+ }
+
+ return;
+
+fail:
+ pa_bluetooth_transport_unlink(t);
+ pa_bluetooth_transport_free(t);
+ return;
+}
+
+static void transport_destroy(pa_bluetooth_transport *t) {
+ struct transport_rfcomm *trfc = t->userdata;
+
+ trfc->mainloop->io_free(trfc->rfcomm_io);
+
+ shutdown(trfc->rfcomm_fd, SHUT_RDWR);
+ close (trfc->rfcomm_fd);
+
+ pa_xfree(trfc);
+}
+
+static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m, void *userdata) {
+ pa_bluetooth_backend *b = userdata;
+ pa_bluetooth_device *d;
+ pa_bluetooth_transport *t;
+ pa_bluetooth_profile_t p;
+ DBusMessage *r;
+ int fd;
+ const char *sender, *path, *handler;
+ DBusMessageIter arg_i;
+ char *pathfd;
+ struct transport_rfcomm *trfc;
+
+ if (!dbus_message_iter_init(m, &arg_i) || !pa_streq(dbus_message_get_signature(m), "oha{sv}")) {
+ pa_log_error("Invalid signature found in NewConnection");
+ goto fail;
+ }
+
+ handler = dbus_message_get_path(m);
+ pa_assert (pa_streq(handler, HSP_AG_PROFILE));
+
+ pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_OBJECT_PATH);
+ dbus_message_iter_get_basic(&arg_i, &path);
+
+ d = pa_bluetooth_discovery_get_device_by_path(b->discovery, path);
+ if (d == NULL) {
+ pa_log_error("Device doesnt exist for %s", path);
+ goto fail;
+ }
+
+ pa_assert_se(dbus_message_iter_next(&arg_i));
+
+ pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_UNIX_FD);
+ dbus_message_iter_get_basic(&arg_i, &fd);
+
+ pa_log_debug("dbus: NewConnection path=%s, fd=%d", path, fd);
+
+ sender = dbus_message_get_sender(m);
+
+ p = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
+ pathfd = pa_sprintf_malloc ("%s/fd%d", path, fd);
+ d->transports[p] = t = pa_bluetooth_transport_new(d, sender, pathfd, p, NULL, 0);
+ pa_xfree(pathfd);
+
+ t->acquire = bluez5_sco_acquire_cb;
+ t->release = bluez5_sco_release_cb;
+ t->destroy = transport_destroy;
+
+ trfc = pa_xnew0(struct transport_rfcomm, 1);
+ trfc->rfcomm_fd = fd;
+ trfc->mainloop = b->core->mainloop;
+ trfc->rfcomm_io = trfc->mainloop->io_new(b->core->mainloop, fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP,
+ rfcomm_io_callback, t);
+ t->userdata = trfc;
+
+ pa_bluetooth_transport_put(t);
+
+ pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
+
+ pa_assert_se(r = dbus_message_new_method_return(m));
+
+ return r;
+
+fail:
+ pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to handle new connection"));
+ return r;
+}
+
+static DBusMessage *profile_request_disconnection(DBusConnection *conn, DBusMessage *m, void *userdata) {
+ DBusMessage *r;
+
+ pa_assert_se(r = dbus_message_new_method_return(m));
+
+ return r;
+}
+
+static DBusHandlerResult profile_handler(DBusConnection *c, DBusMessage *m, void *userdata) {
+ pa_bluetooth_backend *b = userdata;
+ DBusMessage *r = NULL;
+ const char *path, *interface, *member;
+
+ pa_assert(b);
+
+ path = dbus_message_get_path(m);
+ interface = dbus_message_get_interface(m);
+ member = dbus_message_get_member(m);
+
+ pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
+
+ if (!pa_streq(path, HSP_AG_PROFILE))
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+ const char *xml = PROFILE_INTROSPECT_XML;
+
+ pa_assert_se(r = dbus_message_new_method_return(m));
+ pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID));
+
+ } else if (dbus_message_is_method_call(m, BLUEZ_PROFILE_INTERFACE, "Release")) {
+ } else if (dbus_message_is_method_call(m, BLUEZ_PROFILE_INTERFACE, "RequestDisconnection")) {
+ r = profile_request_disconnection(c, m, userdata);
+ } else if (dbus_message_is_method_call(m, BLUEZ_PROFILE_INTERFACE, "NewConnection"))
+ r = profile_new_connection(c, m, userdata);
+ else
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (r) {
+ pa_assert_se(dbus_connection_send(pa_dbus_connection_get(b->connection), r, NULL));
+ dbus_message_unref(r);
+ }
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void profile_init(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile) {
+ static const DBusObjectPathVTable vtable_profile = {
+ .message_function = profile_handler,
+ };
+ const char *object_name;
+ const char *uuid;
+
+ pa_assert(b);
+
+ switch (profile) {
+ case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ object_name = HSP_AG_PROFILE;
+ uuid = PA_BLUETOOTH_UUID_HSP_AG;
+ break;
+ default:
+ pa_assert_not_reached();
+ break;
+ }
+
+ pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(b->connection), object_name, &vtable_profile, b));
+ register_profile(b, object_name, uuid);
+}
+
+static void profile_done(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile) {
+ pa_assert(b);
+
+ switch (profile) {
+ case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_AG_PROFILE);
+ break;
+ default:
+ pa_assert_not_reached();
+ break;
+ }
+}
+
+pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discovery *y) {
+ pa_bluetooth_backend *backend;
+ DBusError err;
+
+ pa_log_debug("Bluetooth Headset Backend API support using the NULL backend");
+
+ backend = pa_xnew0(pa_bluetooth_backend, 1);
+ backend->core = c;
+
+ dbus_error_init(&err);
+ if (!(backend->connection = pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &err))) {
+ pa_log("Failed to get D-Bus connection: %s", err.message);
+ dbus_error_free(&err);
+ pa_xfree(backend);
+ return NULL;
+ }
+
+ backend->discovery = y;
+
+ profile_init(backend, PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
+
+ return backend;
+}
+
+void pa_bluetooth_backend_free(pa_bluetooth_backend *backend) {
+ pa_assert(backend);
+
+ pa_dbus_free_pending_list(&backend->pending);
+
+ profile_done(backend, PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
+
+ pa_dbus_connection_unref(backend->connection);
+
+ pa_xfree(backend);
+}
commit d7199bafea7be9ca26ee9a551e245de0f4bc9e29
Author: Wim Taymans <wim.taymans at gmail.com>
Date: Fri Oct 24 09:56:50 2014 +0200
bluez5-util: add destroy function
Add a destroy function to the transport that is called before freeing
the transport. Useful for cleaning up extra userdata.
diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
index 1ee2f33..9431aed 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -205,6 +205,8 @@ void pa_bluetooth_transport_unlink(pa_bluetooth_transport *t) {
void pa_bluetooth_transport_free(pa_bluetooth_transport *t) {
pa_assert(t);
+ if (t->destroy)
+ t->destroy(t);
pa_bluetooth_transport_unlink(t);
pa_xfree(t->owner);
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
index 8db4a17..1a8a364 100644
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -60,6 +60,7 @@ typedef enum pa_bluetooth_transport_state {
typedef int (*pa_bluetooth_transport_acquire_cb)(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu);
typedef void (*pa_bluetooth_transport_release_cb)(pa_bluetooth_transport *t);
+typedef void (*pa_bluetooth_transport_destroy_cb)(pa_bluetooth_transport *t);
struct pa_bluetooth_transport {
pa_bluetooth_device *device;
@@ -76,6 +77,7 @@ struct pa_bluetooth_transport {
pa_bluetooth_transport_acquire_cb acquire;
pa_bluetooth_transport_release_cb release;
+ pa_bluetooth_transport_destroy_cb destroy;
void *userdata;
};
commit 2251085ddacd780163ed2d84194aff3a0d5153f7
Author: Wim Taymans <wim.taymans at gmail.com>
Date: Fri Oct 24 09:56:49 2014 +0200
bluez5-device: use get_profile_direction
Use the get_profile_direction() helper function to decide when to add a
source and a sink instead of enumerating profiles.
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index 48e498b..15731d1 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -1210,6 +1210,19 @@ static int setup_transport(struct userdata *u) {
}
/* Run from main thread */
+static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
+ static const pa_direction_t profile_direction[] = {
+ [PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
+ [PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_OFF] = 0
+ };
+
+ return profile_direction[p];
+}
+
+/* Run from main thread */
static int init_profile(struct userdata *u) {
int r = 0;
pa_assert(u);
@@ -1220,13 +1233,11 @@ static int init_profile(struct userdata *u) {
pa_assert(u->transport);
- if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
- u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (get_profile_direction (u->profile) & PA_DIRECTION_OUTPUT)
if (add_sink(u) < 0)
r = -1;
- if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
- u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (get_profile_direction (u->profile) & PA_DIRECTION_INPUT)
if (add_source(u) < 0)
r = -1;
@@ -1546,19 +1557,6 @@ static char *cleanup_name(const char *name) {
}
/* Run from main thread */
-static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
- static const pa_direction_t profile_direction[] = {
- [PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
- [PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
- [PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
- [PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
- [PA_BLUETOOTH_PROFILE_OFF] = 0
- };
-
- return profile_direction[p];
-}
-
-/* Run from main thread */
static pa_available_t get_port_availability(struct userdata *u, pa_direction_t direction) {
pa_available_t result = PA_AVAILABLE_NO;
unsigned i;
commit 8718496d1497ea32ef83a46a30625cac096d9f95
Author: Arun Raghavan <arun at accosted.net>
Date: Wed Aug 6 07:48:19 2014 +0530
creds: Rename pa_ancil to pa_cmsg_ancil_data
Makes the purpose of the structure clearear.
diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index 69547eb..cfbcd1a 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -1780,14 +1780,14 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) {
}
/* Called from main context */
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_ancil *ancil, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data, void *userdata) {
struct userdata *u = userdata;
pa_assert(p);
pa_assert(packet);
pa_assert(u);
- if (pa_pdispatch_run(u->pdispatch, packet, ancil, u) < 0) {
+ if (pa_pdispatch_run(u->pdispatch, packet, ancil_data, u) < 0) {
pa_log("Invalid packet");
pa_module_unload_request(u->module, true);
return;
diff --git a/src/pulse/context.c b/src/pulse/context.c
index ec9f3ac..d5da9b8 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -328,7 +328,7 @@ static void pstream_die_callback(pa_pstream *p, void *userdata) {
pa_context_fail(c, PA_ERR_CONNECTIONTERMINATED);
}
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_ancil *ancil, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data, void *userdata) {
pa_context *c = userdata;
pa_assert(p);
@@ -337,7 +337,7 @@ static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_a
pa_context_ref(c);
- if (pa_pdispatch_run(c->pdispatch, packet, ancil, c) < 0)
+ if (pa_pdispatch_run(c->pdispatch, packet, ancil_data, c) < 0)
pa_context_fail(c, PA_ERR_PROTOCOL);
pa_context_unref(c);
diff --git a/src/pulsecore/creds.h b/src/pulsecore/creds.h
index 06806bc..43f6166 100644
--- a/src/pulsecore/creds.h
+++ b/src/pulsecore/creds.h
@@ -31,10 +31,10 @@
#include <pulsecore/socket.h>
#include <stdbool.h>
-#define MAX_ANCIL_FDS 2
+#define MAX_ANCIL_DATA_FDS 2
typedef struct pa_creds pa_creds;
-typedef struct pa_ancil pa_ancil;
+typedef struct pa_cmsg_ancil_data pa_cmsg_ancil_data;
#if defined(SCM_CREDENTIALS)
@@ -46,12 +46,12 @@ struct pa_creds {
};
/* Struct for handling ancillary data, i e, extra data that can be sent together with a message
- over unix pipes. Supports sending and receiving credentials and file descriptors. */
-struct pa_ancil {
+ * over unix pipes. Supports sending and receiving credentials and file descriptors. */
+struct pa_cmsg_ancil_data {
pa_creds creds;
bool creds_valid;
int nfd;
- int fds[MAX_ANCIL_FDS];
+ int fds[MAX_ANCIL_DATA_FDS];
};
#else
diff --git a/src/pulsecore/iochannel.c b/src/pulsecore/iochannel.c
index 6b1fc7a..ae9b42c 100644
--- a/src/pulsecore/iochannel.c
+++ b/src/pulsecore/iochannel.c
@@ -355,7 +355,7 @@ ssize_t pa_iochannel_write_with_fds(pa_iochannel*io, const void*data, size_t l,
struct iovec iov;
union {
struct cmsghdr hdr;
- uint8_t data[CMSG_SPACE(sizeof(int) * MAX_ANCIL_FDS)];
+ uint8_t data[CMSG_SPACE(sizeof(int) * MAX_ANCIL_DATA_FDS)];
} cmsg;
pa_assert(io);
@@ -364,7 +364,7 @@ ssize_t pa_iochannel_write_with_fds(pa_iochannel*io, const void*data, size_t l,
pa_assert(io->ofd >= 0);
pa_assert(fds);
pa_assert(nfd > 0);
- pa_assert(nfd <= MAX_ANCIL_FDS);
+ pa_assert(nfd <= MAX_ANCIL_DATA_FDS);
pa_zero(iov);
iov.iov_base = (void*) data;
@@ -391,24 +391,24 @@ ssize_t pa_iochannel_write_with_fds(pa_iochannel*io, const void*data, size_t l,
return r;
}
-ssize_t pa_iochannel_read_with_ancil(pa_iochannel*io, void*data, size_t l, pa_ancil *ancil) {
+ssize_t pa_iochannel_read_with_ancil_data(pa_iochannel*io, void*data, size_t l, pa_cmsg_ancil_data *ancil_data) {
ssize_t r;
struct msghdr mh;
struct iovec iov;
union {
struct cmsghdr hdr;
- uint8_t data[CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int) * MAX_ANCIL_FDS)];
+ uint8_t data[CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int) * MAX_ANCIL_DATA_FDS)];
} cmsg;
pa_assert(io);
pa_assert(data);
pa_assert(l);
pa_assert(io->ifd >= 0);
- pa_assert(ancil);
+ pa_assert(ancil_data);
if (io->ifd_type > 0) {
- ancil->creds_valid = false;
- ancil->nfd = 0;
+ ancil_data->creds_valid = false;
+ ancil_data->nfd = 0;
return pa_iochannel_read(io, data, l);
}
@@ -426,8 +426,8 @@ ssize_t pa_iochannel_read_with_ancil(pa_iochannel*io, void*data, size_t l, pa_an
if ((r = recvmsg(io->ifd, &mh, 0)) >= 0) {
struct cmsghdr *cmh;
- ancil->creds_valid = false;
- ancil->nfd = 0;
+ ancil_data->creds_valid = false;
+ ancil_data->nfd = 0;
for (cmh = CMSG_FIRSTHDR(&mh); cmh; cmh = CMSG_NXTHDR(&mh, cmh)) {
@@ -439,21 +439,21 @@ ssize_t pa_iochannel_read_with_ancil(pa_iochannel*io, void*data, size_t l, pa_an
pa_assert(cmh->cmsg_len == CMSG_LEN(sizeof(struct ucred)));
memcpy(&u, CMSG_DATA(cmh), sizeof(struct ucred));
- ancil->creds.gid = u.gid;
- ancil->creds.uid = u.uid;
- ancil->creds_valid = true;
+ ancil_data->creds.gid = u.gid;
+ ancil_data->creds.uid = u.uid;
+ ancil_data->creds_valid = true;
}
else if (cmh->cmsg_type == SCM_RIGHTS) {
int nfd = (cmh->cmsg_len - CMSG_LEN(0)) / sizeof(int);
- if (nfd > MAX_ANCIL_FDS) {
+ if (nfd > MAX_ANCIL_DATA_FDS) {
int i;
pa_log("Trying to receive too many file descriptors!");
for (i = 0; i < nfd; i++)
pa_close(((int*) CMSG_DATA(cmh))[i]);
continue;
}
- memcpy(ancil->fds, CMSG_DATA(cmh), nfd * sizeof(int));
- ancil->nfd = nfd;
+ memcpy(ancil_data->fds, CMSG_DATA(cmh), nfd * sizeof(int));
+ ancil_data->nfd = nfd;
}
}
@@ -463,7 +463,7 @@ ssize_t pa_iochannel_read_with_ancil(pa_iochannel*io, void*data, size_t l, pa_an
if (r == -1 && errno == ENOTSOCK) {
io->ifd_type = 1;
- return pa_iochannel_read_with_ancil(io, data, l, ancil);
+ return pa_iochannel_read_with_ancil_data(io, data, l, ancil_data);
}
return r;
diff --git a/src/pulsecore/iochannel.h b/src/pulsecore/iochannel.h
index 390f798..959ee88 100644
--- a/src/pulsecore/iochannel.h
+++ b/src/pulsecore/iochannel.h
@@ -59,7 +59,7 @@ int pa_iochannel_creds_enable(pa_iochannel *io);
ssize_t pa_iochannel_write_with_fds(pa_iochannel*io, const void*data, size_t l, int nfd, const int *fds);
ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l, const pa_creds *ucred);
-ssize_t pa_iochannel_read_with_ancil(pa_iochannel*io, void*data, size_t l, pa_ancil *ancil);
+ssize_t pa_iochannel_read_with_ancil_data(pa_iochannel*io, void*data, size_t l, pa_cmsg_ancil_data *ancil_data);
#endif
bool pa_iochannel_is_readable(pa_iochannel*io);
diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c
index fdb27c9..53284ee 100644
--- a/src/pulsecore/pdispatch.c
+++ b/src/pulsecore/pdispatch.c
@@ -221,7 +221,7 @@ struct pa_pdispatch {
PA_LLIST_HEAD(struct reply_info, replies);
pa_pdispatch_drain_cb_t drain_callback;
void *drain_userdata;
- const pa_ancil *ancil;
+ const pa_cmsg_ancil_data *ancil_data;
bool use_rtclock;
};
@@ -291,7 +291,7 @@ static void run_action(pa_pdispatch *pd, struct reply_info *r, uint32_t command,
pa_pdispatch_unref(pd);
}
-int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_ancil *ancil, void *userdata) {
+int pa_pdispatch_run(pa_pdispatch *pd, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data, void *userdata) {
uint32_t tag, command;
pa_tagstruct *ts = NULL;
int ret = -1;
@@ -325,7 +325,7 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_ancil *ancil,
}
#endif
- pd->ancil = ancil;
+ pd->ancil_data = ancil_data;
if (command == PA_COMMAND_ERROR || command == PA_COMMAND_REPLY) {
struct reply_info *r;
@@ -349,7 +349,7 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const pa_ancil *ancil,
ret = 0;
finish:
- pd->ancil = NULL;
+ pd->ancil_data = NULL;
if (ts)
pa_tagstruct_free(ts);
@@ -444,8 +444,8 @@ const pa_creds * pa_pdispatch_creds(pa_pdispatch *pd) {
pa_assert(pd);
pa_assert(PA_REFCNT_VALUE(pd) >= 1);
- if (pd->ancil && pd->ancil->creds_valid)
- return &pd->ancil->creds;
+ if (pd->ancil_data && pd->ancil_data->creds_valid)
+ return &pd->ancil_data->creds;
return NULL;
}
@@ -454,9 +454,9 @@ const int * pa_pdispatch_fds(pa_pdispatch *pd, int *nfd) {
pa_assert(PA_REFCNT_VALUE(pd) >= 1);
pa_assert(nfd);
- if (pd->ancil) {
- *nfd = pd->ancil->nfd;
- return pd->ancil->fds;
+ if (pd->ancil_data) {
+ *nfd = pd->ancil_data->nfd;
+ return pd->ancil_data->fds;
}
*nfd = 0;
diff --git a/src/pulsecore/pdispatch.h b/src/pulsecore/pdispatch.h
index 038f90d..df2e2fd 100644
--- a/src/pulsecore/pdispatch.h
+++ b/src/pulsecore/pdispatch.h
@@ -41,7 +41,7 @@ pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *m, bool use_rtclock, const pa_pd
void pa_pdispatch_unref(pa_pdispatch *pd);
pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd);
-int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, const pa_ancil *ancil, void *userdata);
+int pa_pdispatch_run(pa_pdispatch *pd, pa_packet *p, const pa_cmsg_ancil_data *ancil_data, void *userdata);
void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t callback, void *userdata, pa_free_cb_t free_cb);
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 2ef1854..c0cd0e0 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -4888,14 +4888,14 @@ static void command_set_port_latency_offset(pa_pdispatch *pd, uint32_t command,
/*** pstream callbacks ***/
-static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_ancil *ancil, void *userdata) {
+static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_assert(p);
pa_assert(packet);
pa_native_connection_assert_ref(c);
- if (pa_pdispatch_run(c->pdispatch, packet, ancil, c) < 0) {
+ if (pa_pdispatch_run(c->pdispatch, packet, ancil_data, c) < 0) {
pa_log("invalid packet.");
native_connection_unlink(c);
}
diff --git a/src/pulsecore/pstream-util.c b/src/pulsecore/pstream-util.c
index 0403ab7..9ccd5a4 100644
--- a/src/pulsecore/pstream-util.c
+++ b/src/pulsecore/pstream-util.c
@@ -28,7 +28,7 @@
#include "pstream-util.h"
-static void pa_pstream_send_tagstruct_with_ancil(pa_pstream *p, pa_tagstruct *t, const pa_ancil *ancil) {
+static void pa_pstream_send_tagstruct_with_ancil_data(pa_pstream *p, pa_tagstruct *t, const pa_cmsg_ancil_data *ancil_data) {
size_t length;
uint8_t *data;
pa_packet *packet;
@@ -38,7 +38,7 @@ static void pa_pstream_send_tagstruct_with_ancil(pa_pstream *p, pa_tagstruct *t,
pa_assert_se(data = pa_tagstruct_free_data(t, &length));
pa_assert_se(packet = pa_packet_new_dynamic(data, length));
- pa_pstream_send_packet(p, packet, ancil);
+ pa_pstream_send_packet(p, packet, ancil_data);
pa_packet_unref(packet);
}
@@ -46,35 +46,35 @@ static void pa_pstream_send_tagstruct_with_ancil(pa_pstream *p, pa_tagstruct *t,
void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const pa_creds *creds) {
if (creds) {
- pa_ancil a;
+ pa_cmsg_ancil_data a;
a.nfd = 0;
a.creds_valid = true;
a.creds = *creds;
- pa_pstream_send_tagstruct_with_ancil(p, t, &a);
+ pa_pstream_send_tagstruct_with_ancil_data(p, t, &a);
}
else
- pa_pstream_send_tagstruct_with_ancil(p, t, NULL);
+ pa_pstream_send_tagstruct_with_ancil_data(p, t, NULL);
}
void pa_pstream_send_tagstruct_with_fds(pa_pstream *p, pa_tagstruct *t, int nfd, const int *fds) {
if (nfd > 0) {
- pa_ancil a;
+ pa_cmsg_ancil_data a;
a.nfd = nfd;
a.creds_valid = false;
- pa_assert(nfd <= MAX_ANCIL_FDS);
+ pa_assert(nfd <= MAX_ANCIL_DATA_FDS);
memcpy(a.fds, fds, sizeof(int) * nfd);
- pa_pstream_send_tagstruct_with_ancil(p, t, &a);
+ pa_pstream_send_tagstruct_with_ancil_data(p, t, &a);
}
else
- pa_pstream_send_tagstruct_with_ancil(p, t, NULL);
+ pa_pstream_send_tagstruct_with_ancil_data(p, t, NULL);
}
#else
void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, const pa_creds *creds) {
- pa_pstream_send_tagstruct_with_ancil(p, t, NULL);
+ pa_pstream_send_tagstruct_with_ancil_data(p, t, NULL);
}
void pa_pstream_send_tagstruct_with_fds(pa_pstream *p, pa_tagstruct *t, int nfd, const int *fds) {
diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c
index ceda728..c32b44c 100644
--- a/src/pulsecore/pstream.c
+++ b/src/pulsecore/pstream.c
@@ -95,8 +95,8 @@ struct item_info {
/* packet info */
pa_packet *packet;
#ifdef HAVE_CREDS
- bool with_ancil;
- pa_ancil ancil;
+ bool with_ancil_data;
+ pa_cmsg_ancil_data ancil_data;
#endif
/* memblock info */
@@ -170,8 +170,8 @@ struct pa_pstream {
pa_mempool *mempool;
#ifdef HAVE_CREDS
- pa_ancil read_ancil, write_ancil;
- bool send_ancil_now;
+ pa_cmsg_ancil_data read_ancil_data, write_ancil_data;
+ bool send_ancil_data_now;
#endif
};
@@ -324,7 +324,7 @@ static void pstream_free(pa_pstream *p) {
pa_xfree(p);
}
-void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_ancil *ancil) {
+void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data) {
struct item_info *i;
pa_assert(p);
@@ -341,12 +341,12 @@ void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_ancil *anc
i->packet = pa_packet_ref(packet);
#ifdef HAVE_CREDS
- if ((i->with_ancil = !!ancil)) {
- i->ancil = *ancil;
- if (ancil->creds_valid)
- pa_assert(ancil->nfd == 0);
+ if ((i->with_ancil_data = !!ancil_data)) {
+ i->ancil_data = *ancil_data;
+ if (ancil_data->creds_valid)
+ pa_assert(ancil_data->nfd == 0);
else
- pa_assert(ancil->nfd > 0);
+ pa_assert(ancil_data->nfd > 0);
}
#endif
@@ -389,7 +389,7 @@ void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa
i->offset = offset;
i->seek_mode = seek_mode;
#ifdef HAVE_CREDS
- i->with_ancil = false;
+ i->with_ancil_data = false;
#endif
pa_queue_push(p->send_queue, i);
@@ -416,7 +416,7 @@ void pa_pstream_send_release(pa_pstream *p, uint32_t block_id) {
item->type = PA_PSTREAM_ITEM_SHMRELEASE;
item->block_id = block_id;
#ifdef HAVE_CREDS
- item->with_ancil = false;
+ item->with_ancil_data = false;
#endif
pa_queue_push(p->send_queue, item);
@@ -453,7 +453,7 @@ void pa_pstream_send_revoke(pa_pstream *p, uint32_t block_id) {
item->type = PA_PSTREAM_ITEM_SHMREVOKE;
item->block_id = block_id;
#ifdef HAVE_CREDS
- item->with_ancil = false;
+ item->with_ancil_data = false;
#endif
pa_queue_push(p->send_queue, item);
@@ -577,8 +577,8 @@ static void prepare_next_write_item(pa_pstream *p) {
}
#ifdef HAVE_CREDS
- if ((p->send_ancil_now = p->write.current->with_ancil))
- p->write_ancil = p->write.current->ancil;
+ if ((p->send_ancil_data_now = p->write.current->with_ancil_data))
+ p->write_ancil_data = p->write.current->ancil_data;
#endif
}
@@ -637,16 +637,16 @@ static int do_write(pa_pstream *p) {
pa_assert(l > 0);
#ifdef HAVE_CREDS
- if (p->send_ancil_now) {
- if (p->write_ancil.creds_valid) {
- pa_assert(p->write_ancil.nfd == 0);
- if ((r = pa_iochannel_write_with_creds(p->io, d, l, &p->write_ancil.creds)) < 0)
+ if (p->send_ancil_data_now) {
+ if (p->write_ancil_data.creds_valid) {
+ pa_assert(p->write_ancil_data.nfd == 0);
+ if ((r = pa_iochannel_write_with_creds(p->io, d, l, &p->write_ancil_data.creds)) < 0)
goto fail;
}
else
- if ((r = pa_iochannel_write_with_fds(p->io, d, l, p->write_ancil.nfd, p->write_ancil.fds)) < 0)
+ if ((r = pa_iochannel_write_with_fds(p->io, d, l, p->write_ancil_data.nfd, p->write_ancil_data.fds)) < 0)
goto fail;
- p->send_ancil_now = false;
+ p->send_ancil_data_now = false;
} else
#endif
if (p->srb)
@@ -719,19 +719,19 @@ static int do_read(pa_pstream *p, struct pstream_read *re) {
else
#ifdef HAVE_CREDS
{
- pa_ancil b;
+ pa_cmsg_ancil_data b;
- if ((r = pa_iochannel_read_with_ancil(p->io, d, l, &b)) <= 0)
+ if ((r = pa_iochannel_read_with_ancil_data(p->io, d, l, &b)) <= 0)
goto fail;
if (b.creds_valid) {
- p->read_ancil.creds_valid = true;
- p->read_ancil.creds = b.creds;
+ p->read_ancil_data.creds_valid = true;
+ p->read_ancil_data.creds = b.creds;
}
if (b.nfd > 0) {
- pa_assert(b.nfd <= MAX_ANCIL_FDS);
- p->read_ancil.nfd = b.nfd;
- memcpy(p->read_ancil.fds, b.fds, sizeof(int) * b.nfd);
+ pa_assert(b.nfd <= MAX_ANCIL_DATA_FDS);
+ p->read_ancil_data.nfd = b.nfd;
+ memcpy(p->read_ancil_data.fds, b.fds, sizeof(int) * b.nfd);
}
}
#else
@@ -880,7 +880,7 @@ static int do_read(pa_pstream *p, struct pstream_read *re) {
if (p->receive_packet_callback)
#ifdef HAVE_CREDS
- p->receive_packet_callback(p, re->packet, &p->read_ancil, p->receive_packet_callback_userdata);
+ p->receive_packet_callback(p, re->packet, &p->read_ancil_data, p->receive_packet_callback_userdata);
#else
p->receive_packet_callback(p, re->packet, NULL, p->receive_packet_callback_userdata);
#endif
@@ -942,8 +942,8 @@ frame_done:
re->data = NULL;
#ifdef HAVE_CREDS
- p->read_ancil.creds_valid = false;
- p->read_ancil.nfd = 0;
+ p->read_ancil_data.creds_valid = false;
+ p->read_ancil_data.nfd = 0;
#endif
return 0;
diff --git a/src/pulsecore/pstream.h b/src/pulsecore/pstream.h
index 8e4056c..cbea237 100644
--- a/src/pulsecore/pstream.h
+++ b/src/pulsecore/pstream.h
@@ -38,7 +38,7 @@
typedef struct pa_pstream pa_pstream;
-typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const pa_ancil *ancil, void *userdata);
+typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data, void *userdata);
typedef void (*pa_pstream_memblock_cb_t)(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata);
typedef void (*pa_pstream_notify_cb_t)(pa_pstream *p, void *userdata);
typedef void (*pa_pstream_block_id_cb_t)(pa_pstream *p, uint32_t block_id, void *userdata);
@@ -50,7 +50,7 @@ void pa_pstream_unref(pa_pstream*p);
void pa_pstream_unlink(pa_pstream *p);
-void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_ancil *ancil);
+void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data);
void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk);
void pa_pstream_send_release(pa_pstream *p, uint32_t block_id);
void pa_pstream_send_revoke(pa_pstream *p, uint32_t block_id);
diff --git a/src/tests/srbchannel-test.c b/src/tests/srbchannel-test.c
index bf7b0f0..ce5930b 100644
--- a/src/tests/srbchannel-test.c
+++ b/src/tests/srbchannel-test.c
@@ -36,7 +36,7 @@ static unsigned packets_received;
static unsigned packets_checksum;
static size_t packets_length;
-static void packet_received(pa_pstream *p, pa_packet *packet, const pa_ancil *ancil, void *userdata) {
+static void packet_received(pa_pstream *p, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data, void *userdata) {
unsigned i;
fail_unless(packets_length == packet->length);
packets_received++;
More information about the pulseaudio-commits
mailing list