summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0001-Added-a-connection-proxy-plugin.patch1010
-rw-r--r--meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0001-build-and-link-with-a-shared-library.patch867
-rw-r--r--meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0002-log-add-calling-function-name.patch26
-rw-r--r--meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0002-proxy-plugin-close-transport-when-null-device-is-set.patch46
-rw-r--r--meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0003-increased-the-number-of-connexions-to-16.patch25
-rw-r--r--meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend13
6 files changed, 924 insertions, 1063 deletions
diff --git a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0001-Added-a-connection-proxy-plugin.patch b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0001-Added-a-connection-proxy-plugin.patch
deleted file mode 100644
index fd0f4ea8..00000000
--- a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0001-Added-a-connection-proxy-plugin.patch
+++ /dev/null
@@ -1,1010 +0,0 @@
-From e730ec274c16d5ba390cb1cd29a8ada16204dd44 Mon Sep 17 00:00:00 2001
-From: Thierry Bultel <thierry.bultel@iot.bzh>
-Date: Wed, 29 Aug 2018 17:02:52 +0200
-Subject: [PATCH] Added a connection proxy plugin
-
-Introduces a new ioplug plugin for alsa.
-This plugin always keeps the opened PCM in a consitent state
-for the sound application, despite of bluealsa server or
-or device disconnection.
-For now, only playback is supported, and only one PCM per application
-is allowed.
-The sound application is in charge of telling the plugin what device
-to use; the bluealsa_proxy_set_remote_device can be opened through
-snd_dlopen. Please see the provided README.md for more details.
-
-Signed-off-by: Stephane Desneux <stephane.desneux@iot.bzh>
----
- src/asound/20-bluealsa_proxy.conf | 41 ++
- src/asound/Makefile.am | 19 +-
- src/asound/README.md | 61 +++
- src/asound/bluealsa-pcm-proxy.c | 811 ++++++++++++++++++++++++++++++++++++++
- 4 files changed, 931 insertions(+), 1 deletion(-)
- create mode 100644 src/asound/20-bluealsa_proxy.conf
- create mode 100644 src/asound/README.md
- create mode 100644 src/asound/bluealsa-pcm-proxy.c
-
-diff --git a/src/asound/20-bluealsa_proxy.conf b/src/asound/20-bluealsa_proxy.conf
-new file mode 100644
-index 0000000..dec1cd8
---- /dev/null
-+++ b/src/asound/20-bluealsa_proxy.conf
-@@ -0,0 +1,41 @@
-+# BlueALSA integration setup
-+
-+defaults.bluealsa.interface "hci0"
-+defaults.bluealsa.profile "a2dp"
-+defaults.bluealsa.delay 20000
-+defaults.bluealsa.battery "yes"
-+
-+ctl.bluealsa {
-+ @args [ HCI BAT ]
-+ @args.HCI {
-+ type string
-+ default {
-+ @func refer
-+ name defaults.bluealsa.interface
-+ }
-+ }
-+ @args.BAT {
-+ type string
-+ default {
-+ @func refer
-+ name defaults.bluealsa.battery
-+ }
-+ }
-+ type bluealsa
-+ interface $HCI
-+ battery $BAT
-+}
-+
-+pcm.bluealsa_proxy {
-+ type plug
-+ slave.pcm {
-+ type bluealsa_proxy
-+ }
-+ hint {
-+ show {
-+ @func refer
-+ name defaults.namehint.extended
-+ }
-+ description "Bluetooth Audio Hub Proxy"
-+ }
-+}
-diff --git a/src/asound/Makefile.am b/src/asound/Makefile.am
-index 75a2dc3..d3b2dfd 100644
---- a/src/asound/Makefile.am
-+++ b/src/asound/Makefile.am
-@@ -5,22 +5,34 @@ EXTRA_DIST = 20-bluealsa.conf
-
- asound_module_ctl_LTLIBRARIES = libasound_module_ctl_bluealsa.la
- asound_module_pcm_LTLIBRARIES = libasound_module_pcm_bluealsa.la
--asound_module_data_DATA = 20-bluealsa.conf
-+asound_module_pcm_proxy_LTLIBRARIES = libasound_module_pcm_bluealsa_proxy.la
-+
-+asound_module_data_DATA = 20-bluealsa.conf 20-bluealsa_proxy.conf
-
- libasound_module_ctl_bluealsa_la_SOURCES = \
- ../shared/ctl-client.c \
- ../shared/log.c \
- bluealsa-ctl.c
-+
- libasound_module_pcm_bluealsa_la_SOURCES = \
- ../shared/ctl-client.c \
- ../shared/log.c \
- ../shared/rt.c \
- bluealsa-pcm.c
-
-+libasound_module_pcm_bluealsa_proxy_la_SOURCES = \
-+ ../shared/ctl-client.c \
-+ ../shared/log.c \
-+ ../shared/rt.c \
-+ bluealsa-pcm-proxy.c
-+
-+
- asound_module_ctldir = @ALSA_PLUGIN_DIR@
- asound_module_pcmdir = @ALSA_PLUGIN_DIR@
-+asound_module_pcm_proxydir = @ALSA_PLUGIN_DIR@
- asound_module_datadir = @ALSA_DATA_DIR@/alsa.conf.d
-
-+
- AM_CFLAGS = \
- -I$(top_srcdir)/src \
- @ALSA_CFLAGS@ \
-@@ -34,3 +46,8 @@ libasound_module_ctl_bluealsa_la_LIBADD = \
- libasound_module_pcm_bluealsa_la_LIBADD = \
- @ALSA_LIBS@ \
- @BLUEZ_LIBS@
-+libasound_module_pcm_bluealsa_proxy_la_LIBADD = \
-+ @ALSA_LIBS@ \
-+ @BLUEZ_LIBS@
-+
-+
-\ No newline at end of file
-diff --git a/src/asound/README.md b/src/asound/README.md
-new file mode 100644
-index 0000000..8ab52a8
---- /dev/null
-+++ b/src/asound/README.md
-@@ -0,0 +1,61 @@
-+# ioplug proxy
-+
-+The ioplug proxy maintains a consitent state of the opened PCM.
-+
-+The application can call snd_pcm_open giving "bluealsa_proxy" as a card name.
-+Only one PCM of this type can be opened by the application, and for now the
-+hci interface is assumed to be hci0.
-+
-+To change to another one, just modify this line in 20-blualsa_proxu.conf
-+defaults.bluealsa.interface "hci0"
-+
-+One the PCM is opened, which always succeeds regardless of the fact that there is
-+a bluetooth device connected or not, the application can set it dynamically using
-+the bluealsa_proxy_set_remote_device function, like in this example code:
-+
-+```
-+#define ALSA_BLUEZ_PROXY_LIB "/usr/lib/alsa-lib/libasound_module_pcm_bluealsa_proxy.so"
-+#define ALSA_BLUEZ_PROXY_SETDEVICE "bluealsa_proxy_set_remote_device"
-+
-+typedef int (*bluealsa_set_remote_device_ptr) (const char * interface, const char * device, const char * profile);
-+
-+static bluealsa_set_remote_device_ptr bluealsa_proxy_set_remote_device = NULL;
-+
-+void alsa_bluez_init() {
-+ static bool initialized = false;
-+ if (initialized)
-+ goto failed;
-+
-+ char errbuf[256];
-+ void * dl = snd_dlopen(ALSA_BLUEZ_PROXY_LIB, RTLD_NOW, errbuf, 256);
-+ if (!dl) {
-+ printf("Failed to open bluealsa proxy plugin\n");
-+ goto failed;
-+ }
-+
-+ void * func = snd_dlsym(dl, ALSA_BLUEZ_PROXY_SETDEVICE, SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION));
-+ if (!func) {
-+ printf("Unable to find %s symbol\n", ALSA_BLUEZ_PROXY_SETDEVICE);
-+ goto failed;
-+ }
-+
-+ bluealsa_proxy_set_remote_device = func;
-+ initialized = true;
-+
-+failed:
-+ return;
-+}
-+
-+int alsa_bluez_set_device(const char * interface, const char * device, const char * profile) {
-+ if (!bluealsa_proxy_set_remote_device)
-+ return -1;
-+
-+ return bluealsa_proxy_set_remote_device(interface,device,profile);
-+}
-+
-+...
-+alsa_bluez_set_device("hci0","XX.XX.XX.XX.XX", "a2dp");
-+...
-+
-+```
-+
-diff --git a/src/asound/bluealsa-pcm-proxy.c b/src/asound/bluealsa-pcm-proxy.c
-new file mode 100644
-index 0000000..4abab2b
---- /dev/null
-+++ b/src/asound/bluealsa-pcm-proxy.c
-@@ -0,0 +1,811 @@
-+/*
-+ * bluealsa-proxy-pcm.c
-+ * Copyright (c) 2018 Thierry Bultel
-+ *
-+ * This file is a part of bluez-alsa.
-+ *
-+ * This project is licensed under the terms of the MIT license.
-+ *
-+ */
-+
-+#define _GNU_SOURCE
-+#include <errno.h>
-+#include <poll.h>
-+#include <pthread.h>
-+#include <signal.h>
-+#include <stdbool.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <sys/eventfd.h>
-+#include <sys/ioctl.h>
-+
-+#include <alsa/asoundlib.h>
-+#include <alsa/pcm_external.h>
-+
-+#include "shared/ctl-client.h"
-+#include "shared/ctl-proto.h"
-+#include "shared/log.h"
-+#include "shared/rt.h"
-+
-+#undef debug
-+#define debug printf
-+
-+#define INTERFACE_STR_MAXLEN 256
-+#define BDADDR_STR_LEN 18
-+#define PROFILE_STR_MAXLEN 16
-+
-+struct bluealsa_pcm {
-+ snd_pcm_ioplug_t io;
-+
-+ /* bluealsa socket */
-+ int fd;
-+
-+ /* event file descriptor */
-+ int event_fd;
-+
-+ /* requested transport */
-+ struct msg_transport * transport;
-+ size_t pcm_buffer_size;
-+
-+ int pcm_fd;
-+
-+ /* virtual hardware - ring buffer */
-+ snd_pcm_uframes_t io_ptr;
-+ pthread_t io_thread;
-+ bool io_started;
-+
-+ /* communication and encoding/decoding delay */
-+ snd_pcm_sframes_t delay;
-+ /* user provided extra delay component */
-+ snd_pcm_sframes_t delay_ex;
-+
-+ /* ALSA operates on frames, we on bytes */
-+ size_t frame_size;
-+
-+ /* In order to see whether the PCM has reached under-run (or over-run), we
-+ * have to know the exact position of the hardware and software pointers.
-+ * To do so, we could use the HW pointer provided by the IO plug structure.
-+ * This pointer is updated by the snd_pcm_hwsync() function, which is not
-+ * thread-safe (total disaster is guaranteed). Since we can not call this
-+ * function, we are going to use our own HW pointer, which can be updated
-+ * safely in our IO thread. */
-+ snd_pcm_uframes_t io_hw_boundary;
-+ snd_pcm_uframes_t io_hw_ptr;
-+
-+ char interface[INTERFACE_STR_MAXLEN];
-+ bdaddr_t addr;
-+ char profile[PROFILE_STR_MAXLEN];
-+ enum pcm_type type;
-+ enum pcm_stream stream;
-+
-+};
-+
-+typedef struct bluealsa_pcm bluealsa_pcm_t;
-+
-+static bluealsa_pcm_t * the_pcm = NULL;
-+
-+static int close_bluez_connection();
-+static int open_bluez_connection();
-+
-+
-+/**
-+ * Helper function for closing PCM transport. */
-+static int close_transport(struct bluealsa_pcm *pcm) {
-+
-+ debug("%s ...\n", __func__);
-+ if (pcm->transport == NULL)
-+ return 0;
-+
-+ int rv = bluealsa_close_transport(pcm->fd, pcm->transport);
-+ int err = errno;
-+
-+ close(pcm->pcm_fd);
-+ pcm->pcm_fd = -1;
-+ errno = err;
-+ return rv;
-+}
-+
-+/**
-+ * IO thread, which facilitates ring buffer. */
-+static void *io_thread(void *arg) {
-+ snd_pcm_ioplug_t *io = (snd_pcm_ioplug_t *)arg;
-+
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ sigset_t sigset;
-+ sigemptyset(&sigset);
-+
-+ /* Block signal, which will be used for pause/resume actions. */
-+ sigaddset(&sigset, SIGIO);
-+ /* Block SIGPIPE, so we could receive EPIPE while writing to the pipe
-+ * whose reading end has been closed. This will allow clean playback
-+ * termination. */
-+ sigaddset(&sigset, SIGPIPE);
-+
-+ if ((errno = pthread_sigmask(SIG_BLOCK, &sigset, NULL)) != 0) {
-+ SNDERR("Thread signal mask error: %s", strerror(errno));
-+ goto final;
-+ }
-+
-+wait_pcm_fd:
-+
-+ debug("PLUGIN io-thread: wait for pcm_fd\n");
-+
-+ /* In the capture mode, the PCM FIFO is opened in the non-blocking mode.
-+ * So right now, we have to synchronize write and read sides, otherwise
-+ * reading might return 0, which will be incorrectly recognized as FIFO
-+ * close signal, but in fact it means, that it was not opened yet. */
-+ if (io->stream == SND_PCM_STREAM_CAPTURE) {
-+
-+ /* Is the data fd ready ? */
-+ if (pcm->pcm_fd == -1) {
-+ usleep(100*1000); // TODO This should be replaced by a semaphore
-+ goto wait_pcm_fd;
-+ }
-+
-+ /* check both fd status */
-+
-+ struct pollfd pfds[2] = {
-+ { pcm->pcm_fd, POLLIN, 0 },
-+ { pcm->fd, POLLIN|POLLPRI, 0 }};
-+
-+ int ret = poll(pfds, 2, -1);
-+ if (ret == -1) {
-+ SNDERR("PCM FIFO poll error: %s", strerror(errno));
-+ goto final;
-+ }
-+
-+ short int evt0 = pfds[0].revents;
-+ short int evt1 = pfds[1].revents;
-+
-+ if (evt1 & POLLHUP) {
-+ debug("Server closed the connection\n");
-+ close_bluez_connection();
-+ open_bluez_connection();
-+ usleep(100*1000); /* avoid spinning too fast /*/
-+ goto wait_pcm_fd;
-+ }
-+
-+ if (evt0 & POLLHUP) {
-+ debug("Remote device disconnected\n");
-+ close_bluez_connection();
-+ open_bluez_connection();
-+ usleep(100*1000);
-+ goto wait_pcm_fd;
-+ }
-+ }
-+
-+ const snd_pcm_channel_area_t *areas = snd_pcm_ioplug_mmap_areas(io);
-+
-+ struct asrsync asrs;
-+ asrsync_init(asrs, io->rate);
-+
-+ for (;;) {
-+
-+ int tmp;
-+ switch (io->state) {
-+ case SND_PCM_STATE_RUNNING:
-+ case SND_PCM_STATE_DRAINING:
-+ break;
-+ case SND_PCM_STATE_DISCONNECTED:
-+ debug("PLUGIN: DISCONNECTED\n");
-+ goto final;
-+ default:
-+ sigwait(&sigset, &tmp);
-+ asrsync_init(asrs, io->rate);
-+ }
-+
-+ snd_pcm_uframes_t io_ptr = pcm->io_ptr;
-+ snd_pcm_uframes_t io_buffer_size = io->buffer_size;
-+ snd_pcm_uframes_t io_hw_ptr = pcm->io_hw_ptr;
-+ snd_pcm_uframes_t io_hw_boundary = pcm->io_hw_boundary;
-+ snd_pcm_uframes_t frames = io->period_size;
-+ char *buffer = areas->addr + (areas->first + areas->step * io_ptr) / 8;
-+ char *head = buffer;
-+ ssize_t ret = 0;
-+ size_t len;
-+
-+ /* If the leftover in the buffer is less than a whole period sizes,
-+ * adjust the number of frames which should be transfered. It has
-+ * turned out, that the buffer might contain fractional number of
-+ * periods - it could be an ALSA bug, though, it has to be handled. */
-+ if (io_buffer_size - io_ptr < frames)
-+ frames = io_buffer_size - io_ptr;
-+
-+ /* IO operation size in bytes */
-+ len = frames * pcm->frame_size;
-+ io_ptr += frames;
-+
-+ if (io_ptr >= io_buffer_size)
-+ io_ptr -= io_buffer_size;
-+
-+ io_hw_ptr += frames;
-+ if (io_hw_ptr >= io_hw_boundary)
-+ io_hw_ptr -= io_hw_boundary;
-+
-+ if (io->stream == SND_PCM_STREAM_CAPTURE) {
-+
-+ /* Read the whole period "atomically". This will assure, that frames
-+ * are not fragmented, so the pointer can be correctly updated. */
-+ while (len != 0 && (ret = read(pcm->pcm_fd, head, len)) != 0) {
-+ if (ret == -1) {
-+ if (errno == EINTR)
-+ continue;
-+
-+ SNDERR("PCM FIFO read error: %s", strerror(errno));
-+ goto final;
-+ }
-+ head += ret;
-+ len -= ret;
-+ }
-+
-+ /* something went wrong. this can be a server,
-+ * or device disconnection, or a device change request
-+ * from the client application */
-+
-+ if (ret == 0)
-+ goto wait_pcm_fd;
-+
-+ }
-+ else {
-+
-+ /* check for under-run and act accordingly */
-+ if (io_hw_ptr > io->appl_ptr) {
-+ io->state = SND_PCM_STATE_XRUN;
-+ io_ptr = -1;
-+ goto sync;
-+ }
-+
-+ /* Perform atomic write - see the explanation above. */
-+ do {
-+ if ((ret = write(pcm->pcm_fd, head, len)) == -1) {
-+ if (errno == EINTR)
-+ continue;
-+ SNDERR("PCM FIFO write error: %s", strerror(errno));
-+ goto final;
-+ }
-+ head += ret;
-+ len -= ret;
-+ }
-+ while (len != 0);
-+
-+ /* synchronize playback time */
-+ asrsync_sync(&asrs, frames);
-+ }
-+
-+sync:
-+ pcm->io_ptr = io_ptr;
-+ pcm->io_hw_ptr = io_hw_ptr;
-+
-+ eventfd_write(pcm->event_fd, 1);
-+ }
-+
-+final:
-+
-+ debug("PLUGIN: io_thread exiting\n");
-+
-+ close_transport(pcm);
-+ eventfd_write(pcm->event_fd, 0xDEAD0000);
-+
-+ return NULL;
-+}
-+
-+static int bluealsa_proxy_start(snd_pcm_ioplug_t *io) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ debug("%s ...\n", __func__);
-+
-+ /* If the IO thread is already started, skip thread creation. Otherwise,
-+ * we might end up with a bunch of IO threads reading or writing to the
-+ * same FIFO simultaneously. Instead, just send resume signal. */
-+ if (pcm->io_started) {
-+ io->state = SND_PCM_STATE_RUNNING;
-+ pthread_kill(pcm->io_thread, SIGIO);
-+ return 0;
-+ }
-+
-+ /* initialize delay calculation */
-+ pcm->delay = 0;
-+
-+ if (pcm->transport && bluealsa_pause_transport(pcm->fd, pcm->transport, false) == -1) {
-+ debug("Couldn't start PCM: %s\n", strerror(errno));
-+ return -errno;
-+ }
-+
-+ /* State has to be updated before the IO thread is created - if the state
-+ * does not indicate "running", the IO thread will be suspended until the
-+ * "resume" signal is delivered. This requirement is only (?) theoretical,
-+ * anyhow forewarned is forearmed. */
-+ snd_pcm_state_t prev_state = io->state;
-+ io->state = SND_PCM_STATE_RUNNING;
-+
-+ pcm->io_started = true;
-+
-+ return 0;
-+}
-+
-+static int bluealsa_proxy_stop(snd_pcm_ioplug_t *io) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ debug("Stopping");
-+ if (pcm->io_started) {
-+ pcm->io_started = false;
-+ pthread_cancel(pcm->io_thread);
-+ pthread_join(pcm->io_thread, NULL);
-+ }
-+ return 0;
-+}
-+
-+static snd_pcm_sframes_t bluealsa_proxy_pointer(snd_pcm_ioplug_t *io) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+ if (pcm->pcm_fd == -1)
-+ return -ENODEV;
-+
-+ return pcm->io_ptr;
-+}
-+
-+static int bluealsa_proxy_close(snd_pcm_ioplug_t *io) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ debug("Closing plugin\n");
-+ close(pcm->fd);
-+ close(pcm->event_fd);
-+ free(pcm);
-+
-+ the_pcm = NULL;
-+
-+ return 0;
-+}
-+
-+static int bluealsa_proxy_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+ (void)params;
-+
-+ pcm->frame_size = (snd_pcm_format_physical_width(io->format) * io->channels) / 8;
-+
-+ /* Indicate that our PCM is ready for writing, even though is is not 100%
-+ * true - IO thread is not running yet. Some weird implementations might
-+ * require PCM to be writable before the snd_pcm_start() call. */
-+ if (io->stream == SND_PCM_STREAM_PLAYBACK)
-+ eventfd_write(pcm->event_fd, 1);
-+
-+ if (pcm->io.stream == SND_PCM_STREAM_PLAYBACK) {
-+ /* By default, the size of the pipe buffer is set to a too large value for
-+ * our purpose. On modern Linux system it is 65536 bytes. Large buffer in
-+ * the playback mode might contribute to an unnecessary audio delay. Since
-+ * it is possible to modify the size of this buffer we will set is to some
-+ * low value, but big enough to prevent audio tearing. Note, that the size
-+ * will be rounded up to the page size (typically 4096 bytes). */
-+ pcm->pcm_buffer_size = fcntl(pcm->pcm_fd, F_SETPIPE_SZ, 2048);
-+ debug("FIFO buffer size: %zd", pcm->pcm_buffer_size);
-+ }
-+
-+ debug("Selected HW buffer: %zd periods x %zd bytes %c= %zd bytes\n",
-+ io->buffer_size / io->period_size, pcm->frame_size * io->period_size,
-+ io->period_size * (io->buffer_size / io->period_size) == io->buffer_size ? '=' : '<',
-+ io->buffer_size * pcm->frame_size);
-+
-+ return 0;
-+}
-+
-+static int bluealsa_proxy_hw_free(snd_pcm_ioplug_t *io) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+ debug("Freeing HW");
-+
-+ if (close_transport(pcm) == -1)
-+ return -errno;
-+ return 0;
-+}
-+
-+static int bluealsa_proxy_sw_params(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+ snd_pcm_sw_params_get_boundary(params, &pcm->io_hw_boundary);
-+ return 0;
-+}
-+
-+static int bluealsa_proxy_prepare(snd_pcm_ioplug_t *io) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ /* initialize ring buffer */
-+ pcm->io_hw_ptr = 0;
-+ pcm->io_ptr = 0;
-+
-+ return 0;
-+}
-+
-+static int bluealsa_proxy_drain(snd_pcm_ioplug_t *io) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ if (bluealsa_drain_transport(pcm->fd, pcm->transport) == -1)
-+ return -errno;
-+ return 0;
-+}
-+
-+static int bluealsa_proxy_pause(snd_pcm_ioplug_t *io, int enable) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ if (bluealsa_pause_transport(pcm->fd, pcm->transport, enable) == -1)
-+ return -errno;
-+
-+ if (enable == 0) {
-+ io->state = SND_PCM_STATE_RUNNING;
-+ pthread_kill(pcm->io_thread, SIGIO);
-+ }
-+
-+ /* Even though PCM transport is paused, our IO thread is still running. If
-+ * the implementer relies on the PCM file descriptor readiness, we have to
-+ * bump our internal event trigger. Otherwise, client might stuck forever
-+ * in the poll/select system call. */
-+ eventfd_write(pcm->event_fd, 1);
-+
-+ return 0;
-+}
-+
-+static void bluealsa_proxy_dump(snd_pcm_ioplug_t *io, snd_output_t *out) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+ char addr[18];
-+
-+ if (pcm->transport == NULL) {
-+ snd_output_printf(out, "Bluetooth Proxy: no transport yet\n");
-+ return;
-+ }
-+
-+ ba2str(&pcm->transport->addr, addr);
-+ snd_output_printf(out, "Bluetooth Proxy device: %s\n", addr);
-+ snd_output_printf(out, "Bluetooth Proxy profile: %d\n", pcm->transport->type);
-+ snd_output_printf(out, "Bluetooth Proxy codec: %d\n", pcm->transport->codec);
-+
-+}
-+
-+static int bluealsa_proxy_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ if (pcm->pcm_fd == -1)
-+ return -ENODEV;
-+
-+ /* Exact calculation of the PCM delay is very hard, if not impossible. For
-+ * the sake of simplicity we will make few assumptions and approximations.
-+ * In general, the delay is proportional to the number of bytes queued in
-+ * the FIFO buffer, the time required to encode data, Bluetooth transfer
-+ * latency and the time required by the device to decode and play audio. */
-+
-+ static int counter = 0;
-+ snd_pcm_sframes_t delay = 0;
-+ unsigned int size;
-+
-+ /* bytes queued in the PCM ring buffer */
-+ delay += io->appl_ptr - io->hw_ptr;
-+
-+ /* bytes queued in the FIFO buffer */
-+ if (ioctl(pcm->pcm_fd, FIONREAD, &size) != -1)
-+ delay += size / pcm->frame_size;
-+
-+ /* On the server side, the delay stat will not be available until the PCM
-+ * data transfer is started. Do not make an unnecessary call then. */
-+ if ((io->state == SND_PCM_STATE_RUNNING || io->state == SND_PCM_STATE_DRAINING)) {
-+
-+ /* data transfer (communication) and encoding/decoding */
-+ if (io->stream == SND_PCM_STREAM_PLAYBACK &&
-+ (pcm->delay == 0 || ++counter % (io->rate / 10) == 0)) {
-+
-+ unsigned int tmp;
-+ if ((tmp = bluealsa_get_transport_delay(pcm->fd, pcm->transport)) != -1) {
-+ pcm->delay = (io->rate / 100) * tmp / 100;
-+ debug("BlueALSA delay: %.1f ms (%ld frames)", (float)tmp / 10, pcm->delay);
-+ }
-+
-+ }
-+
-+ }
-+
-+ *delayp = delay + pcm->delay + pcm->delay_ex;
-+ return 0;
-+}
-+
-+static int bluealsa_proxy_poll_descriptors_count(snd_pcm_ioplug_t *io) {
-+ (void)io;
-+ return 1;
-+}
-+
-+static int bluealsa_proxy_poll_descriptors(snd_pcm_ioplug_t *io, struct pollfd *pfd,
-+ unsigned int space) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ if (space != 1)
-+ return -EINVAL;
-+
-+ pfd[0].fd = pcm->event_fd;
-+ pfd[0].events = POLLIN;
-+
-+ return 1;
-+}
-+
-+static int bluealsa_proxy_poll_revents(snd_pcm_ioplug_t *io, struct pollfd *pfd,
-+ unsigned int nfds, unsigned short *revents) {
-+ struct bluealsa_pcm *pcm = io->private_data;
-+
-+ if (nfds != 1) {
-+ return -EINVAL;
-+ }
-+
-+ if (pcm->pcm_fd == -1) {
-+ return -ENODEV;
-+ }
-+
-+ if (pfd[0].revents & POLLIN) {
-+
-+ eventfd_t event;
-+ eventfd_read(pcm->event_fd, &event);
-+
-+ if (event & 0xDEAD0000) {
-+ goto fail;
-+ }
-+
-+ /* If the event was triggered prematurely, wait for another one.
-+ * This causes a deadlock if */
-+ if (!snd_pcm_avail_update(io->pcm)) {
-+ return *revents = 0;
-+ }
-+
-+ /* ALSA expects that the event will match stream direction, e.g.
-+ * playback will not start if the event is for reading. */
-+ *revents = io->stream == SND_PCM_STREAM_CAPTURE ? POLLIN : POLLOUT;
-+
-+ }
-+ else
-+ *revents = 0;
-+
-+ return 0;
-+
-+fail:
-+ *revents = POLLERR | POLLHUP;
-+ return -ENODEV;
-+}
-+
-+static const snd_pcm_ioplug_callback_t bluealsa_proxy_callback = {
-+ .start = bluealsa_proxy_start,
-+ .stop = bluealsa_proxy_stop,
-+ .pointer = bluealsa_proxy_pointer,
-+ .close = bluealsa_proxy_close,
-+ .hw_params = bluealsa_proxy_hw_params,
-+ .hw_free = bluealsa_proxy_hw_free,
-+ .sw_params = bluealsa_proxy_sw_params,
-+ .prepare = bluealsa_proxy_prepare,
-+ .drain = bluealsa_proxy_drain,
-+ .pause = bluealsa_proxy_pause,
-+ .dump = bluealsa_proxy_dump,
-+ .delay = bluealsa_proxy_delay,
-+ .poll_descriptors_count = bluealsa_proxy_poll_descriptors_count,
-+ .poll_descriptors = bluealsa_proxy_poll_descriptors,
-+ .poll_revents = bluealsa_proxy_poll_revents,
-+};
-+
-+static enum pcm_type bluealsa_proxy_parse_profile(const char *profile) {
-+
-+ if (profile == NULL)
-+ return PCM_TYPE_NULL;
-+
-+ if (strcasecmp(profile, "a2dp") == 0)
-+ return PCM_TYPE_A2DP;
-+ else if (strcasecmp(profile, "sco") == 0)
-+ return PCM_TYPE_SCO;
-+
-+ return PCM_TYPE_NULL;
-+}
-+
-+/* This must be called when a transport is available */
-+
-+static int bluealsa_proxy_set_hw_constraint(struct bluealsa_pcm *pcm) {
-+ snd_pcm_ioplug_t *io = &pcm->io;
-+
-+ static const snd_pcm_access_t accesses[] = {
-+ SND_PCM_ACCESS_MMAP_INTERLEAVED,
-+ SND_PCM_ACCESS_RW_INTERLEAVED,
-+ };
-+ static const unsigned int formats[] = {
-+ SND_PCM_FORMAT_S16_LE,
-+ };
-+
-+ int err;
-+
-+ debug("Setting constraints\n");
-+
-+ if ((err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS,
-+ sizeof(accesses) / sizeof(*accesses), accesses)) < 0)
-+ return err;
-+
-+ if ((err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT,
-+ sizeof(formats) / sizeof(*formats), formats)) < 0)
-+ return err;
-+
-+ if ((err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS,
-+ 2, 1024)) < 0)
-+ return err;
-+
-+ /* In order to prevent audio tearing and minimize CPU utilization, we're
-+ * going to setup buffer size constraints. These limits are derived from
-+ * the transport sampling rate and the number of channels, so the buffer
-+ * "time" size will be constant. The minimal period size and buffer size
-+ * are respectively 10 ms and 200 ms. Upper limits are not constraint. */
-+ unsigned int min_p = pcm->transport->sampling * 10 / 1000 * pcm->transport->channels * 2;
-+ unsigned int min_b = pcm->transport->sampling * 200 / 1000 * pcm->transport->channels * 2;
-+
-+ if ((err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES,
-+ min_p, 1024 * 16)) < 0)
-+ return err;
-+
-+ if ((err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_BUFFER_BYTES,
-+ min_b, 1024 * 1024 * 16)) < 0)
-+ return err;
-+
-+ if ((err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_CHANNELS,
-+ pcm->transport->channels, pcm->transport->channels)) < 0)
-+ return err;
-+
-+ if ((err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE,
-+ pcm->transport->sampling, pcm->transport->sampling)) < 0)
-+ return err;
-+
-+ return 0;
-+}
-+
-+
-+SND_PCM_PLUGIN_DEFINE_FUNC(bluealsa_proxy) {
-+ (void)root;
-+
-+ struct bluealsa_pcm *pcm;
-+ long delay = 0;
-+ int ret;
-+
-+ if ((pcm = calloc(1, sizeof(*pcm))) == NULL)
-+ return -ENOMEM;
-+
-+ pcm->fd = -1;
-+ pcm->event_fd = -1;
-+ pcm->pcm_fd = -1;
-+ pcm->delay_ex = delay;
-+
-+ if ((pcm->event_fd = eventfd(0, EFD_CLOEXEC)) == -1) {
-+ ret = -errno;
-+ goto fail;
-+ }
-+
-+ pcm->io.version = SND_PCM_IOPLUG_VERSION;
-+ pcm->io.name = "BlueALSA";
-+ pcm->io.flags = SND_PCM_IOPLUG_FLAG_LISTED;
-+ pcm->io.mmap_rw = 1;
-+ pcm->io.callback = &bluealsa_proxy_callback;
-+ pcm->io.private_data = pcm;
-+ pcm->transport = NULL;
-+
-+ enum pcm_stream _stream = stream == SND_PCM_STREAM_PLAYBACK ?
-+ PCM_STREAM_PLAYBACK : PCM_STREAM_CAPTURE;
-+
-+ pcm->stream = stream;
-+
-+ if ((ret = snd_pcm_ioplug_create(&pcm->io, name, stream, mode)) < 0)
-+ goto fail;
-+
-+ *pcmp = pcm->io.pcm;
-+
-+ // Remember PCM
-+ the_pcm = pcm;
-+
-+ if ((errno = pthread_create(&pcm->io_thread, NULL, io_thread, &pcm->io)) != 0) {
-+ debug("Couldn't create IO thread: %s", strerror(errno));
-+ pcm->io_started = false;
-+
-+ ret = -errno;
-+ goto fail;
-+ }
-+
-+ pthread_setname_np(pcm->io_thread, "pcm-io");
-+ return 0;
-+
-+fail:
-+ if (pcm->fd != -1)
-+ close(pcm->fd);
-+ if (pcm->event_fd != -1)
-+ close(pcm->event_fd);
-+ free(pcm);
-+ return ret;
-+}
-+
-+SND_PCM_PLUGIN_SYMBOL(bluealsa_proxy);
-+
-+static int open_bluez_connection() {
-+ int ret = 0;
-+ bluealsa_pcm_t * pcm = the_pcm;
-+
-+ char addr[256];
-+ ba2str(&pcm->addr, addr);
-+
-+ debug("%s interface %s addr %s type %d\n", __func__, pcm->interface, addr, pcm->type);
-+
-+ if ((pcm->fd = bluealsa_open(pcm->interface)) == -1) {
-+ SNDERR("BlueALSA connection failed: %s", strerror(errno));
-+ ret = -errno;
-+ goto fail;
-+ }
-+
-+ if ((pcm->transport = bluealsa_get_transport(pcm->fd, pcm->addr, pcm->type, pcm->stream)) == NULL) {
-+ SNDERR("Couldn't get BlueALSA transport: %s", strerror(errno));
-+ ret = -errno;
-+ goto fail;
-+ }
-+
-+ if ((ret = bluealsa_proxy_set_hw_constraint(pcm)) < 0) {
-+ snd_pcm_ioplug_delete(&pcm->io);
-+ goto fail;
-+ }
-+
-+ pcm->transport->stream = pcm->stream;
-+
-+ if ((pcm->pcm_fd = bluealsa_open_transport(pcm->fd, pcm->transport)) == -1) {
-+ debug("Couldn't open PCM FIFO: %s", strerror(errno));
-+ return -errno;
-+ }
-+
-+ debug("PLUGIN: starting transport\n");
-+
-+ if (bluealsa_pause_transport(pcm->fd, pcm->transport, false) == -1) {
-+ debug("Couldn't start PCM: %s", strerror(errno));
-+ return -errno;
-+ }
-+
-+ debug("PLUGIN: connection ready !\n");
-+
-+ return 0;
-+
-+fail:
-+ return ret;
-+}
-+
-+static int close_bluez_connection() {
-+ int ret = 0;
-+ bluealsa_pcm_t * pcm = the_pcm;
-+ close_transport(pcm);
-+ close(pcm->fd);
-+ return ret;
-+}
-+
-+/* This is an exported function, to be loaded by clients via dlsym */
-+
-+int bluealsa_proxy_set_remote_device(const char * interface, const char * device, const char * profile) {
-+ int ret = -1;
-+
-+ debug("PLUGIN: %s: interface %s device %s profile %s\n", __func__, interface, device, profile);
-+
-+ if (the_pcm == NULL) {
-+ SNDERR("No current opened connection to bluezalsa server\n");
-+ goto failed;
-+ }
-+
-+ enum pcm_type type;
-+
-+ if (device == NULL || str2ba(device, &the_pcm->addr) != 0) {
-+ SNDERR("Invalid BT device address: %s", device);
-+ ret = -EINVAL;
-+ goto failed;
-+ }
-+
-+ if ((type = bluealsa_proxy_parse_profile(profile)) == PCM_TYPE_NULL) {
-+ SNDERR("Invalid BT profile [a2dp, sco]: %s", profile);
-+ ret = -EINVAL;
-+ goto failed;
-+ }
-+
-+ strncpy(the_pcm->profile, profile, PROFILE_STR_MAXLEN);
-+ strncpy(the_pcm->interface, interface, INTERFACE_STR_MAXLEN);
-+
-+ the_pcm->type = type;
-+
-+ close_bluez_connection();
-+ ret = open_bluez_connection();
-+
-+failed:
-+ return ret;
-+}
-+
-+SND_DLSYM_BUILD_VERSION(bluealsa_proxy_set_remote_device, SND_PCM_DLSYM_VERSION);
---
-2.1.4
-
diff --git a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0001-build-and-link-with-a-shared-library.patch b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0001-build-and-link-with-a-shared-library.patch
new file mode 100644
index 00000000..3d2c4f60
--- /dev/null
+++ b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0001-build-and-link-with-a-shared-library.patch
@@ -0,0 +1,867 @@
+From 032917320d339e44a3981c347887b220e98e369e Mon Sep 17 00:00:00 2001
+From: Thierry Bultel <thierry.bultel@iot.bzh>
+Date: Mon, 3 Dec 2018 14:29:07 +0100
+Subject: [PATCH 1/3] build and link with a shared library
+
+Signed-off-by: Thierry Bultel <thierry.bultel@iot.bzh>
+---
+ configure.ac | 4 +-
+ includes/bluealsa/bluealsa.h | 21 ++++++
+ {src/shared => includes/bluealsa}/ctl-client.h | 2 +-
+ {src/shared => includes/bluealsa}/ctl-proto.h | 0
+ {src/shared => includes/bluealsa}/defs.h | 0
+ {src/shared => includes/bluealsa}/ffb.h | 0
+ {src/shared => includes/bluealsa}/log.h | 0
+ {src/shared => includes/bluealsa}/rt.h | 0
+ src/Makefile.am | 11 ++-
+ src/asound/Makefile.am | 15 ++--
+ src/asound/bluealsa-ctl.c | 6 +-
+ src/asound/bluealsa-pcm.c | 10 +--
+ src/at.c | 4 +-
+ src/bluealsa.h | 2 +-
+ src/bluealsalib/Makefile.am | 50 ++++++++++++++
+ src/bluealsalib/bluealsa.pc.in | 12 ++++
+ src/bluez-a2dp.c | 2 +-
+ src/bluez.c | 2 +-
+ src/ctl.c | 4 +-
+ src/ctl.h | 2 +-
+ src/io.c | 8 +--
+ src/main.c | 4 +-
+ src/ofono.c | 2 +-
+ src/rfcomm.c | 4 +-
+ src/shared/ctl-client.c | 4 +-
+ src/shared/ffb.c | 2 +-
+ src/shared/log.c | 4 +-
+ src/shared/rt.c | 2 +-
+ src/transport.c | 2 +-
+ src/utils.c | 2 +-
+ test/Makefile.am | 10 ++-
+ test/server-mock.c | 3 -
+ test/test-at.c | 1 -
+ test/test-bluealsalib.c | 96 ++++++++++++++++++++++++++
+ test/test-io.c | 3 -
+ test/test-pcm.c | 4 +-
+ test/test-utils.c | 8 +--
+ utils/Makefile.am | 11 ++-
+ utils/aplay.c | 8 +--
+ utils/rfcomm.c | 4 +-
+ 40 files changed, 254 insertions(+), 75 deletions(-)
+ create mode 100644 includes/bluealsa/bluealsa.h
+ rename {src/shared => includes/bluealsa}/ctl-client.h (98%)
+ rename {src/shared => includes/bluealsa}/ctl-proto.h (100%)
+ rename {src/shared => includes/bluealsa}/defs.h (100%)
+ rename {src/shared => includes/bluealsa}/ffb.h (100%)
+ rename {src/shared => includes/bluealsa}/log.h (100%)
+ rename {src/shared => includes/bluealsa}/rt.h (100%)
+ create mode 100644 src/bluealsalib/Makefile.am
+ create mode 100644 src/bluealsalib/bluealsa.pc.in
+ create mode 100644 test/test-bluealsalib.c
+
+diff --git a/configure.ac b/configure.ac
+index 734fb59..fc52531 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -158,8 +158,10 @@ AC_CONFIG_FILES([
+ Makefile
+ src/Makefile
+ src/asound/Makefile
++ src/bluealsalib/Makefile
+ utils/Makefile
+- test/Makefile])
++ test/Makefile
++ src/bluealsalib/bluealsa.pc])
+ AC_OUTPUT
+
+ # warn user that alsa-lib thread-safety makes troubles
+diff --git a/includes/bluealsa/bluealsa.h b/includes/bluealsa/bluealsa.h
+new file mode 100644
+index 0000000..062856a
+--- /dev/null
++++ b/includes/bluealsa/bluealsa.h
+@@ -0,0 +1,21 @@
++/*
++ * BlueALSA - bluealsa.h
++ * Copyright (c) 2018 Thierry Bultel
++ *
++ * This file is a part of bluez-alsa.
++ *
++ * This project is licensed under the terms of the MIT license.
++ *
++ */
++
++#ifndef BLUEALSA_H
++#define BLUEALSA_H
++
++#include <bluealsa/ctl-client.h>
++#include <bluealsa/defs.h>
++
++typedef int (*transport_update_cb) (struct ba_msg_transport *transports);
++
++extern int bluelsa_register_transport_update_cb(const char * interfance, transport_update_cb cb);
++
++#endif
+diff --git a/src/shared/ctl-client.h b/includes/bluealsa/ctl-client.h
+similarity index 98%
+rename from src/shared/ctl-client.h
+rename to includes/bluealsa/ctl-client.h
+index 18f724d..36b537c 100644
+--- a/src/shared/ctl-client.h
++++ b/includes/bluealsa/ctl-client.h
+@@ -12,7 +12,7 @@
+ #define BLUEALSA_SHARED_CTLCLIENT_H_
+
+ #include <stdbool.h>
+-#include "shared/ctl-proto.h"
++#include <bluealsa/ctl-proto.h>
+
+ int bluealsa_open(const char *interface);
+
+diff --git a/src/shared/ctl-proto.h b/includes/bluealsa/ctl-proto.h
+similarity index 100%
+rename from src/shared/ctl-proto.h
+rename to includes/bluealsa/ctl-proto.h
+diff --git a/src/shared/defs.h b/includes/bluealsa/defs.h
+similarity index 100%
+rename from src/shared/defs.h
+rename to includes/bluealsa/defs.h
+diff --git a/src/shared/ffb.h b/includes/bluealsa/ffb.h
+similarity index 100%
+rename from src/shared/ffb.h
+rename to includes/bluealsa/ffb.h
+diff --git a/src/shared/log.h b/includes/bluealsa/log.h
+similarity index 100%
+rename from src/shared/log.h
+rename to includes/bluealsa/log.h
+diff --git a/src/shared/rt.h b/includes/bluealsa/rt.h
+similarity index 100%
+rename from src/shared/rt.h
+rename to includes/bluealsa/rt.h
+diff --git a/src/Makefile.am b/src/Makefile.am
+index fb1241d..5626ae5 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -2,12 +2,9 @@
+ # Copyright (c) 2016-2018 Arkadiusz Bokowy
+
+ bin_PROGRAMS = bluealsa
+-SUBDIRS = asound
++SUBDIRS = bluealsalib asound
+
+ bluealsa_SOURCES = \
+- shared/ffb.c \
+- shared/log.c \
+- shared/rt.c \
+ at.c \
+ bluealsa.c \
+ bluez.c \
+@@ -34,7 +31,8 @@ AM_CFLAGS = \
+ @APTX_CFLAGS@ \
+ @LDAC_CFLAGS@ \
+ @LDAC_ABR_CFLAGS@ \
+- @SBC_CFLAGS@
++ @SBC_CFLAGS@ \
++ -I$(top_srcdir)/includes
+
+ LDADD = \
+ @BLUEZ_LIBS@ \
+@@ -44,4 +42,5 @@ LDADD = \
+ @APTX_LIBS@ \
+ @LDAC_LIBS@ \
+ @LDAC_ABR_LIBS@ \
+- @SBC_LIBS@
++ @SBC_LIBS@ \
++ bluealsalib/libbluealsa.la
+diff --git a/src/asound/Makefile.am b/src/asound/Makefile.am
+index 923d884..24618f1 100644
+--- a/src/asound/Makefile.am
++++ b/src/asound/Makefile.am
+@@ -5,32 +5,35 @@ EXTRA_DIST = 20-bluealsa.conf
+
+ asound_module_ctl_LTLIBRARIES = libasound_module_ctl_bluealsa.la
+ asound_module_pcm_LTLIBRARIES = libasound_module_pcm_bluealsa.la
++
+ asound_module_conf_DATA = 20-bluealsa.conf
+
+ libasound_module_ctl_bluealsa_la_SOURCES = \
+- ../shared/ctl-client.c \
+- ../shared/log.c \
+ bluealsa-ctl.c
++
+ libasound_module_pcm_bluealsa_la_SOURCES = \
+- ../shared/ctl-client.c \
+- ../shared/log.c \
+- ../shared/rt.c \
+ bluealsa-pcm.c
+
+ asound_module_ctldir = @ALSA_PLUGIN_DIR@
+ asound_module_pcmdir = @ALSA_PLUGIN_DIR@
++
+ asound_module_confdir = @ALSA_CONF_DIR@
+
+ AM_CFLAGS = \
+ -I$(top_srcdir)/src \
++ -I$(top_srcdir)/includes \
+ @ALSA_CFLAGS@ \
+ @BLUEZ_CFLAGS@ \
+ @GLIB2_CFLAGS@
+
+-AM_LDFLAGS = -module -avoid-version
++AM_LDFLAGS = \
++ -module \
++ -avoid-version \
++ ../bluealsalib/libbluealsa.la
+
+ libasound_module_ctl_bluealsa_la_LIBADD = \
+ @ALSA_LIBS@
++
+ libasound_module_pcm_bluealsa_la_LIBADD = \
+ @ALSA_LIBS@ \
+ @BLUEZ_LIBS@
+diff --git a/src/asound/bluealsa-ctl.c b/src/asound/bluealsa-ctl.c
+index 76cbe6a..3c931ca 100644
+--- a/src/asound/bluealsa-ctl.c
++++ b/src/asound/bluealsa-ctl.c
+@@ -19,9 +19,9 @@
+ #include <alsa/asoundlib.h>
+ #include <alsa/control_external.h>
+
+-#include "shared/ctl-client.h"
+-#include "shared/ctl-proto.h"
+-#include "shared/log.h"
++#include <bluealsa/ctl-client.h>
++#include <bluealsa/ctl-proto.h>
++#include <bluealsa/log.h>
+
+
+ enum ctl_elem_type {
+diff --git a/src/asound/bluealsa-pcm.c b/src/asound/bluealsa-pcm.c
+index 46788f5..2136964 100644
+--- a/src/asound/bluealsa-pcm.c
++++ b/src/asound/bluealsa-pcm.c
+@@ -23,11 +23,11 @@
+ #include <alsa/asoundlib.h>
+ #include <alsa/pcm_external.h>
+
+-#include "shared/ctl-client.h"
+-#include "shared/ctl-proto.h"
+-#include "shared/defs.h"
+-#include "shared/log.h"
+-#include "shared/rt.h"
++#include <bluealsa/ctl-client.h>
++#include <bluealsa/ctl-proto.h>
++#include <bluealsa/defs.h>
++#include <bluealsa/log.h>
++#include <bluealsa/rt.h>
+
+
+ struct bluealsa_pcm {
+diff --git a/src/at.c b/src/at.c
+index e3d1703..bda2255 100644
+--- a/src/at.c
++++ b/src/at.c
+@@ -16,8 +16,8 @@
+ #include <stdio.h>
+ #include <string.h>
+
+-#include "shared/defs.h"
+-#include "shared/log.h"
++#include <bluealsa/defs.h>
++#include <bluealsa/log.h>
+
+
+ /**
+diff --git a/src/bluealsa.h b/src/bluealsa.h
+index 3249439..b73241e 100644
+--- a/src/bluealsa.h
++++ b/src/bluealsa.h
+@@ -28,7 +28,7 @@
+ #include "bluez.h"
+ #include "bluez-a2dp.h"
+ #include "transport.h"
+-#include "shared/ctl-proto.h"
++#include <bluealsa/ctl-proto.h>
+
+ /* Maximal number of clients connected to the controller. */
+ #define BLUEALSA_MAX_CLIENTS 7
+diff --git a/src/bluealsalib/Makefile.am b/src/bluealsalib/Makefile.am
+new file mode 100644
+index 0000000..11d9e00
+--- /dev/null
++++ b/src/bluealsalib/Makefile.am
+@@ -0,0 +1,50 @@
++# BlueALSA - Makefile.am
++# Copyright (c) 2018 Thiery Bultel (thierry.bultel@iot.bzh)
++
++bluealsalib_LTLIBRARIES = libbluealsa.la
++
++libbluealsa_la_SOURCES = \
++ ../shared/ctl-client.c \
++ ../shared/ffb.c \
++ ../shared/log.c \
++ ../shared/rt.c
++
++EXTRA_DIST=bluealsa.pc.in
++
++pkgconfigdir = $(libdir)/pkgconfig
++pkgconfig_DATA = bluealsa.pc
++
++AM_CFLAGS = \
++ -I$(top_srcdir)/src \
++ -I$(top_srcdir)/includes \
++ @ALSA_CFLAGS@ \
++ @BLUEZ_CFLAGS@ \
++ @GLIB2_CFLAGS@
++
++libbluealsa_la_LIBADD = \
++ @ALSA_LIBS@ \
++ @BLUEZ_LIBS@
++
++libbluealsa_la_LDFLAGS = \
++ $(AM_LDFLAGS) \
++ -version-info 1:0:0
++
++bluealsalibdir = $(libdir)
++
++# install path for published headers
++bluealsalibincludedir=$(includedir)/bluealsa
++
++bluealsalib_headers_dir=../../includes/bluealsa
++
++bluealsalib_headers = \
++ $(bluealsalib_headers_dir)/bluealsa.h \
++ $(bluealsalib_headers_dir)/ctl-client.h \
++ $(bluealsalib_headers_dir)/ctl-proto.h \
++ $(bluealsalib_headers_dir)/defs.h \
++ $(bluealsalib_headers_dir)/ffb.h \
++ $(bluealsalib_headers_dir)/log.h \
++ $(bluealsalib_headers_dir)/rt.h
++
++libbluealsa_la_SOURCES += $(bluealsalib_headers)
++
++bluealsalibinclude_HEADERS = $(bluealsalib_headers)
+diff --git a/src/bluealsalib/bluealsa.pc.in b/src/bluealsalib/bluealsa.pc.in
+new file mode 100644
+index 0000000..93c3c4a
+--- /dev/null
++++ b/src/bluealsalib/bluealsa.pc.in
+@@ -0,0 +1,12 @@
++prefix=@prefix@
++exec_prefix=@exec_prefix@
++libdir=@libdir@
++includedir=@includedir@
++
++Name: alsa
++Description: Bluez-Alsa - Library
++Version: @VERSION@
++Requires:
++Libs: -L${libdir} -lbluealsa
++#Libs.private: @ALSA_DEPLIBS@
++Cflags: -I${includedir}/bluealsa
+diff --git a/src/bluez-a2dp.c b/src/bluez-a2dp.c
+index 5f81e6e..4c7b07b 100644
+--- a/src/bluez-a2dp.c
++++ b/src/bluez-a2dp.c
+@@ -13,7 +13,7 @@
+ #endif
+
+ #include "bluez-a2dp.h"
+-#include "shared/defs.h"
++#include <bluealsa/defs.h>
+
+ static const a2dp_sbc_t a2dp_sbc = {
+ .frequency =
+diff --git a/src/bluez.c b/src/bluez.c
+index 35f1b36..1478d6f 100644
+--- a/src/bluez.c
++++ b/src/bluez.c
+@@ -24,7 +24,7 @@
+ #include "ctl.h"
+ #include "transport.h"
+ #include "utils.h"
+-#include "shared/log.h"
++#include <bluealsa/log.h>
+
+
+ /**
+diff --git a/src/ctl.c b/src/ctl.c
+index b35afc7..82666b9 100644
+--- a/src/ctl.c
++++ b/src/ctl.c
+@@ -31,8 +31,8 @@
+ #include "hfp.h"
+ #include "transport.h"
+ #include "utils.h"
+-#include "shared/defs.h"
+-#include "shared/log.h"
++#include <bluealsa/defs.h>
++#include <bluealsa/log.h>
+
+
+ /**
+diff --git a/src/ctl.h b/src/ctl.h
+index 5fd92ed..7f185a4 100644
+--- a/src/ctl.h
++++ b/src/ctl.h
+@@ -11,7 +11,7 @@
+ #ifndef BLUEALSA_CTL_H_
+ #define BLUEALSA_CTL_H_
+
+-#include "shared/ctl-proto.h"
++#include <bluealsa/ctl-proto.h>
+
+ int bluealsa_ctl_thread_init(void);
+ void bluealsa_ctl_free(void);
+diff --git a/src/io.c b/src/io.c
+index 5b098c4..e567bdb 100644
+--- a/src/io.c
++++ b/src/io.c
+@@ -44,10 +44,10 @@
+ #include "bluealsa.h"
+ #include "transport.h"
+ #include "utils.h"
+-#include "shared/defs.h"
+-#include "shared/ffb.h"
+-#include "shared/log.h"
+-#include "shared/rt.h"
++#include <bluealsa/defs.h>
++#include <bluealsa/ffb.h>
++#include <bluealsa/log.h>
++#include <bluealsa/rt.h>
+
+
+ /**
+diff --git a/src/main.c b/src/main.c
+index 35e6702..9cef402 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -37,8 +37,8 @@
+ #endif
+ #include "transport.h"
+ #include "utils.h"
+-#include "shared/defs.h"
+-#include "shared/log.h"
++#include <bluealsa/defs.h>
++#include <bluealsa/log.h>
+
+
+ static char *get_a2dp_codecs(
+diff --git a/src/ofono.c b/src/ofono.c
+index 4331e03..63c8685 100644
+--- a/src/ofono.c
++++ b/src/ofono.c
+@@ -26,7 +26,7 @@
+ #include "ctl.h"
+ #include "ofono-iface.h"
+ #include "transport.h"
+-#include "shared/log.h"
++#include <bluealsa/log.h>
+
+ #define OFONO_FAKE_DEV_ID 0xffff
+
+diff --git a/src/rfcomm.c b/src/rfcomm.c
+index f2a904a..b1edf84 100644
+--- a/src/rfcomm.c
++++ b/src/rfcomm.c
+@@ -17,11 +17,11 @@
+ #include <string.h>
+ #include <unistd.h>
+
++#include <bluealsa/defs.h>
+ #include "bluealsa.h"
+ #include "ctl.h"
+ #include "utils.h"
+-#include "shared/defs.h"
+-#include "shared/log.h"
++#include <bluealsa/log.h>
+
+
+ /**
+diff --git a/src/shared/ctl-client.c b/src/shared/ctl-client.c
+index 121689d..01ceecb 100644
+--- a/src/shared/ctl-client.c
++++ b/src/shared/ctl-client.c
+@@ -8,7 +8,7 @@
+ *
+ */
+
+-#include "shared/ctl-client.h"
++#include <bluealsa/ctl-client.h>
+
+ #include <errno.h>
+ #include <fcntl.h>
+@@ -19,7 +19,7 @@
+ #include <sys/types.h>
+ #include <sys/un.h>
+
+-#include "shared/log.h"
++#include <bluealsa/log.h>
+
+
+ /**
+diff --git a/src/shared/ffb.c b/src/shared/ffb.c
+index b31d7d1..ab50f4a 100644
+--- a/src/shared/ffb.c
++++ b/src/shared/ffb.c
+@@ -8,7 +8,7 @@
+ *
+ */
+
+-#include "shared/ffb.h"
++#include "../../includes/bluealsa/ffb.h"
+
+
+ /**
+diff --git a/src/shared/log.c b/src/shared/log.c
+index 65f0fea..884540c 100644
+--- a/src/shared/log.c
++++ b/src/shared/log.c
+@@ -8,7 +8,7 @@
+ *
+ */
+
+-#include "shared/log.h"
++#include <bluealsa/log.h>
+
+ #include <pthread.h>
+ #include <stdarg.h>
+@@ -17,7 +17,7 @@
+ #include <string.h>
+ #include <syslog.h>
+
+-#include "shared/rt.h"
++#include <bluealsa/rt.h>
+
+
+ /* internal logging identifier */
+diff --git a/src/shared/rt.c b/src/shared/rt.c
+index edcbebc..40bd721 100644
+--- a/src/shared/rt.c
++++ b/src/shared/rt.c
+@@ -8,7 +8,7 @@
+ *
+ */
+
+-#include "shared/rt.h"
++#include <bluealsa/rt.h>
+
+ #include <stdlib.h>
+
+diff --git a/src/transport.c b/src/transport.c
+index aca8038..823316b 100644
+--- a/src/transport.c
++++ b/src/transport.c
+@@ -34,7 +34,7 @@
+ #include "io.h"
+ #include "rfcomm.h"
+ #include "utils.h"
+-#include "shared/log.h"
++#include <bluealsa/log.h>
+
+
+ static const char *transport_type_to_string(enum ba_transport_type type) {
+diff --git a/src/utils.c b/src/utils.c
+index 70d069e..27459d2 100644
+--- a/src/utils.c
++++ b/src/utils.c
+@@ -24,7 +24,7 @@
+
+ #include "a2dp-codecs.h"
+ #include "bluez.h"
+-#include "shared/log.h"
++#include <bluealsa/log.h>
+
+
+ /**
+diff --git a/test/Makefile.am b/test/Makefile.am
+index 27a646a..3d67809 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -4,7 +4,8 @@
+ TESTS = \
+ test-at \
+ test-io \
+- test-utils
++ test-utils \
++ test-bluealsalib
+
+ if ENABLE_TEST_PCM
+ TESTS += test-pcm
+@@ -15,10 +16,12 @@ check_PROGRAMS = \
+ test-at \
+ test-io \
+ test-pcm \
+- test-utils
++ test-utils \
++ test-bluealsalib
+
+ AM_CFLAGS = \
+ -I$(top_srcdir)/src \
++ -I$(top_srcdir)/includes \
+ @AAC_CFLAGS@ \
+ @ALSA_CFLAGS@ \
+ @APTX_CFLAGS@ \
+@@ -40,4 +43,5 @@ LDADD = \
+ @GLIB2_LIBS@ \
+ @LDAC_ABR_LIBS@ \
+ @LDAC_LIBS@ \
+- @SBC_LIBS@
++ @SBC_LIBS@ \
++ ../src/bluealsalib/libbluealsa.la
+diff --git a/test/server-mock.c b/test/server-mock.c
+index a27b59d..418e3a0 100644
+--- a/test/server-mock.c
++++ b/test/server-mock.c
+@@ -33,9 +33,6 @@
+ #include "../src/rfcomm.c"
+ #include "../src/transport.c"
+ #include "../src/utils.c"
+-#include "../src/shared/ffb.c"
+-#include "../src/shared/log.c"
+-#include "../src/shared/rt.c"
+
+ static const a2dp_sbc_t cconfig = {
+ .frequency = SBC_SAMPLING_FREQ_44100,
+diff --git a/test/test-at.c b/test/test-at.c
+index 177cceb..8d5e2f3 100644
+--- a/test/test-at.c
++++ b/test/test-at.c
+@@ -11,7 +11,6 @@
+ #include <check.h>
+
+ #include "../src/at.c"
+-#include "../src/shared/log.c"
+
+ START_TEST(test_at_build) {
+
+diff --git a/test/test-bluealsalib.c b/test/test-bluealsalib.c
+new file mode 100644
+index 0000000..d5fa3ff
+--- /dev/null
++++ b/test/test-bluealsalib.c
+@@ -0,0 +1,96 @@
++/*
++ * test-bluealsalib.c
++ * Copyright (c) 2018 Thierry Bultel
++ *
++ * This file is a part of bluez-alsa.
++ *
++ * This project is licensed under the terms of the MIT license.
++ *
++ */
++
++// TODO monitor all available interfaces
++const char * ba_interface = "hci0";
++
++#include <bluealsa/bluealsa.h>
++#include <bluealsa/log.h>
++#include <pthread.h>
++#include <errno.h>
++#include <poll.h>
++
++
++static void * monitor_thread_entry(void* arg) {
++ debug("...");
++
++ int ba_fd, ba_event_fd;
++ enum ba_event transport_mask = BA_EVENT_TRANSPORT_ADDED | BA_EVENT_TRANSPORT_CHANGED|BA_EVENT_TRANSPORT_REMOVED;
++
++ if ((ba_fd = bluealsa_open(ba_interface)) == -1) {
++ error("BlueALSA connection failed: %s", strerror(errno));
++ goto fail;
++ }
++
++ if ((ba_event_fd = bluealsa_open(ba_interface)) == -1) {
++ error("BlueALSA connection failed: %s", strerror(errno));
++ goto fail;
++ }
++
++ if (bluealsa_subscribe(ba_event_fd, transport_mask) == -1) {
++ error("BlueALSA subscription failed: %s", strerror(errno));
++ goto fail;
++ }
++
++goto init;
++
++ while (true) {
++
++ struct ba_msg_event event;
++ struct ba_msg_transport *transports;
++ ssize_t ret;
++ size_t i;
++
++ struct pollfd pfds[] = {{ ba_event_fd, POLLIN, 0 }};
++ if (poll(pfds, ARRAYSIZE(pfds), -1) == -1 && errno == EINTR)
++ continue;
++
++ while ((ret = recv(ba_event_fd, &event, sizeof(event), MSG_DONTWAIT)) == -1 && errno == EINTR)
++ continue;
++ if (ret != sizeof(event)) {
++ error("Couldn't read event: %s", strerror(ret == -1 ? errno : EBADMSG));
++ goto fail;
++ }
++
++init:
++ debug("Fetching available transports");
++ if ((ret = bluealsa_get_transports(ba_fd, &transports)) == -1) {
++ error("Couldn't get transports: %s", strerror(errno));
++ goto fail;
++ }
++
++ debug("Got %d transports", ret);
++
++ for (int ix=0; ix<ret; ix++) {
++ char addr[18];
++ struct ba_msg_transport * transport = &transports[ix];
++ ba2str(&transport->addr, addr);
++ info("Transport %d: type %d, dev %s", ix, transport->type, addr);
++ }
++
++ }
++
++fail:
++ info("exit");
++ return NULL;
++}
++
++int main(int argc, char * argv[]) {
++ printf("%s... !\n", argv[0]);
++
++ pthread_t monitor;
++ if (pthread_create(&monitor, NULL, monitor_thread_entry, NULL) == -1) {
++ debug("failed to create the monitor thread");
++ goto fail;
++ }
++ pthread_join(monitor, NULL);
++fail:
++ return 0;
++}
+diff --git a/test/test-io.c b/test/test-io.c
+index d913d2f..8ebb1d8 100644
+--- a/test/test-io.c
++++ b/test/test-io.c
+@@ -21,9 +21,6 @@
+ #include "../src/rfcomm.c"
+ #include "../src/transport.c"
+ #include "../src/utils.c"
+-#include "../src/shared/ffb.c"
+-#include "../src/shared/log.c"
+-#include "../src/shared/rt.c"
+
+ static const a2dp_sbc_t config_sbc_44100_stereo = {
+ .frequency = SBC_SAMPLING_FREQ_44100,
+diff --git a/test/test-pcm.c b/test/test-pcm.c
+index 1a4d02d..43e30e1 100644
+--- a/test/test-pcm.c
++++ b/test/test-pcm.c
+@@ -18,10 +18,10 @@
+ #include <check.h>
+ #include <alsa/asoundlib.h>
+
++#include <bluealsa/log.h>
++
+ #include "inc/server.inc"
+ #include "inc/sine.inc"
+-#include "../src/shared/ffb.c"
+-#include "../src/shared/log.c"
+
+ #define buffer_test_frames 1024
+ #define dumprv(fn) fprintf(stderr, #fn " = %d\n", (int)fn)
+diff --git a/test/test-utils.c b/test/test-utils.c
+index 767ca4e..98b5b42 100644
+--- a/test/test-utils.c
++++ b/test/test-utils.c
+@@ -10,11 +10,11 @@
+
+ #include <check.h>
+
++#include <bluealsa/defs.h>
++#include <bluealsa/ffb.h>
++#include <bluealsa/rt.h>
++
+ #include "../src/utils.c"
+-#include "../src/shared/defs.h"
+-#include "../src/shared/ffb.c"
+-#include "../src/shared/log.c"
+-#include "../src/shared/rt.c"
+
+ START_TEST(test_dbus_profile_object_path) {
+
+diff --git a/utils/Makefile.am b/utils/Makefile.am
+index 256689a..a6d132c 100644
+--- a/utils/Makefile.am
++++ b/utils/Makefile.am
+@@ -6,32 +6,31 @@ bin_PROGRAMS =
+ if ENABLE_APLAY
+ bin_PROGRAMS += bluealsa-aplay
+ bluealsa_aplay_SOURCES = \
+- ../src/shared/ctl-client.c \
+- ../src/shared/ffb.c \
+- ../src/shared/log.c \
+ aplay.c
+ bluealsa_aplay_CFLAGS = \
+ -I$(top_srcdir)/src \
++ -I$(top_srcdir)/includes \
+ @ALSA_CFLAGS@ \
+ @BLUEZ_CFLAGS@ \
+ @GIO2_CFLAGS@
+ bluealsa_aplay_LDADD = \
+ @ALSA_LIBS@ \
+ @BLUEZ_LIBS@ \
+- @GIO2_LIBS@
++ @GIO2_LIBS@ \
++ ../src/bluealsalib/libbluealsa.la
+ endif
+
+ if ENABLE_RFCOMM
+ bin_PROGRAMS += bluealsa-rfcomm
+ bluealsa_rfcomm_SOURCES = \
+- ../src/shared/ctl-client.c \
+- ../src/shared/log.c \
+ rfcomm.c
+ bluealsa_rfcomm_CFLAGS = \
+ -I$(top_srcdir)/src \
++ -I$(top_srcdir)/includes \
+ @BLUEZ_CFLAGS@
+ bluealsa_rfcomm_LDADD = \
+ @BLUEZ_LIBS@ \
++ ../src/bluealsalib/libbluealsa.la \
+ -lreadline
+ endif
+
+diff --git a/utils/aplay.c b/utils/aplay.c
+index 7b71860..5211e7f 100644
+--- a/utils/aplay.c
++++ b/utils/aplay.c
+@@ -25,10 +25,10 @@
+ #include <alsa/asoundlib.h>
+ #include <gio/gio.h>
+
+-#include "shared/ctl-client.h"
+-#include "shared/defs.h"
+-#include "shared/ffb.h"
+-#include "shared/log.h"
++#include <bluealsa/ctl-client.h>
++#include <bluealsa/defs.h>
++#include <bluealsa/ffb.h>
++#include <bluealsa/log.h>
+
+ struct pcm_worker {
+ struct ba_msg_transport transport;
+diff --git a/utils/rfcomm.c b/utils/rfcomm.c
+index 6794fc4..f5f045c 100644
+--- a/utils/rfcomm.c
++++ b/utils/rfcomm.c
+@@ -24,8 +24,8 @@
+ #include <readline/readline.h>
+ #include <readline/history.h>
+
+-#include "shared/ctl-client.h"
+-#include "shared/log.h"
++#include <bluealsa/ctl-client.h>
++#include <bluealsa/log.h>
+
+ static char *strtrim(char *str) {
+ while (isspace(*str))
+--
+2.16.4
+
diff --git a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0002-log-add-calling-function-name.patch b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0002-log-add-calling-function-name.patch
new file mode 100644
index 00000000..756081a9
--- /dev/null
+++ b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0002-log-add-calling-function-name.patch
@@ -0,0 +1,26 @@
+From 9f8cca2a4c2efb9d9069e26f2e953cee586d6127 Mon Sep 17 00:00:00 2001
+From: Thierry Bultel <thierry.bultel@iot.bzh>
+Date: Mon, 3 Dec 2018 14:31:31 +0100
+Subject: [PATCH 2/3] log: add calling function name
+
+Signed-off-by: Thierry Bultel <thierry.bultel@iot.bzh>
+---
+ includes/bluealsa/log.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/includes/bluealsa/log.h b/includes/bluealsa/log.h
+index 39663fb..6d4cec3 100644
+--- a/includes/bluealsa/log.h
++++ b/includes/bluealsa/log.h
+@@ -31,7 +31,7 @@ void info(const char *format, ...) __attribute__ ((format(printf, 1, 2)));
+
+ #if DEBUG
+ void _debug(const char *format, ...) __attribute__ ((format(printf, 1, 2)));
+-# define debug(M, ARGS ...) _debug("%s:%d: " M, __FILE__, __LINE__, ## ARGS)
++# define debug(M, ARGS ...) _debug("%s:%d:%s: " M, __FILE__, __LINE__,__func__, ## ARGS)
+ #else
+ # define debug(M, ARGS ...) do {} while (0)
+ #endif
+--
+2.16.4
+
diff --git a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0002-proxy-plugin-close-transport-when-null-device-is-set.patch b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0002-proxy-plugin-close-transport-when-null-device-is-set.patch
deleted file mode 100644
index d21555ea..00000000
--- a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0002-proxy-plugin-close-transport-when-null-device-is-set.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 39f578d2c44fef9fd2e105eb7594a2d249152e63 Mon Sep 17 00:00:00 2001
-From: Thierry Bultel <thierry.bultel@iot.bzh>
-Date: Mon, 10 Sep 2018 14:56:14 +0200
-Subject: [PATCH] proxy plugin: close transport when null device is set
-
-Simply closes the transport when bluealsa_proxy_set_remote_device
-specifies a null device.
-Also removed spurious log.
-
-Signed-off-by: Thierry Bultel <thierry.bultel@iot.bzh>
----
- src/asound/bluealsa-pcm-proxy.c | 11 +++++++++--
- 1 file changed, 9 insertions(+), 2 deletions(-)
-
-diff --git a/src/asound/bluealsa-pcm-proxy.c b/src/asound/bluealsa-pcm-proxy.c
-index 4abab2b..7c59cd1 100644
---- a/src/asound/bluealsa-pcm-proxy.c
-+++ b/src/asound/bluealsa-pcm-proxy.c
-@@ -130,7 +130,7 @@ static void *io_thread(void *arg) {
-
- wait_pcm_fd:
-
-- debug("PLUGIN io-thread: wait for pcm_fd\n");
-+ //debug("PLUGIN io-thread: wait for pcm_fd\n");
-
- /* In the capture mode, the PCM FIFO is opened in the non-blocking mode.
- * So right now, we have to synchronize write and read sides, otherwise
-@@ -784,7 +784,14 @@ int bluealsa_proxy_set_remote_device(const char * interface, const char * device
-
- enum pcm_type type;
-
-- if (device == NULL || str2ba(device, &the_pcm->addr) != 0) {
-+ /* When the hardware address is NULL, just close the connection */
-+ if (device == NULL ) {
-+ close_bluez_connection();
-+ ret = 0;
-+ goto failed;
-+ }
-+
-+ if ( str2ba(device, &the_pcm->addr) != 0) {
- SNDERR("Invalid BT device address: %s", device);
- ret = -EINVAL;
- goto failed;
---
-2.16.4
-
diff --git a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0003-increased-the-number-of-connexions-to-16.patch b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0003-increased-the-number-of-connexions-to-16.patch
new file mode 100644
index 00000000..0448fabb
--- /dev/null
+++ b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0003-increased-the-number-of-connexions-to-16.patch
@@ -0,0 +1,25 @@
+From c13a5d8a00b6a1f1293cf7c4bc493f559b7d2591 Mon Sep 17 00:00:00 2001
+From: Thierry Bultel <thierry.bultel@iot.bzh>
+Date: Mon, 10 Dec 2018 16:06:23 +0100
+Subject: [PATCH 3/3] increased the number of connexions to 16
+
+---
+ src/bluealsa.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/bluealsa.h b/src/bluealsa.h
+index b73241e..12f3c0a 100644
+--- a/src/bluealsa.h
++++ b/src/bluealsa.h
+@@ -31,7 +31,7 @@
+ #include <bluealsa/ctl-proto.h>
+
+ /* Maximal number of clients connected to the controller. */
+-#define BLUEALSA_MAX_CLIENTS 7
++#define BLUEALSA_MAX_CLIENTS 16
+
+ /* Indexes of special file descriptors in the poll array. */
+ #define CTL_IDX_SRV 0
+--
+2.16.4
+
diff --git a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend
index ecb73b34..43e4632f 100644
--- a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend
+++ b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend
@@ -1,12 +1,11 @@
-# THIS IS A TEMPORARY WORKAROUND TO IMPLEMENT PERSISTENT PCMS FOR SOFTMIXER
+# This brings some mandatory patches for the softmixer. This is not an actual hack,
+# because all the 3 patches below have been discussed with the maintainer of bluez-alsa,
+# and will be mainlined in the future
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
-SRC_URI += "file://0001-Added-a-connection-proxy-plugin.patch"
-SRC_URI += "file://0002-proxy-plugin-close-transport-when-null-device-is-set.patch"
+SRC_URI += "file://0001-build-and-link-with-a-shared-library.patch"
+SRC_URI += "file://0002-log-add-calling-function-name.patch"
+SRC_URI += "file://0003-increased-the-number-of-connexions-to-16.patch"
-FILES_${PN} += "\
- ${libdir}/alsa-lib/libasound_module_pcm_bluealsa_proxy.so\
- ${datadir}/alsa/alsa.conf.d/20-bluealsa_proxy.conf\
-"