[pulseaudio-discuss] [PATCH] bluetooth: Remove module-bluetooth-proximity

jprvita at gmail.com jprvita at gmail.com
Fri Aug 16 05:30:41 PDT 2013


From: João Paulo Rechi Vita <jprvita at openbossa.org>

module-bluetooth-proximity has not worked for quite a while, since it
uses pre-BlueZ4 APIs. Nobody complained since then, which is a good
indication that it doesn't have much users. Even the original commit
message refers to it more as a toy than as something of great use: "add
new fun module that automatically mutes your audio devices when you
leave with your bluetooth phone, and unmutes when you come back"

Removing it we completely remove the dependency on libbluetooth.
---
 LICENSE                                            |  20 +-
 po/POTFILES.in                                     |   2 -
 src/.gitignore                                     |   1 -
 src/Makefile.am                                    |  20 -
 src/modules/bluetooth/module-bluetooth-proximity.c | 480 ---------------------
 src/modules/bluetooth/proximity-helper.c           | 202 ---------
 6 files changed, 10 insertions(+), 715 deletions(-)
 delete mode 100644 src/modules/bluetooth/module-bluetooth-proximity.c
 delete mode 100644 src/modules/bluetooth/proximity-helper.c

diff --git a/LICENSE b/LICENSE
index 30833e5..226c4ce 100644
--- a/LICENSE
+++ b/LICENSE
@@ -2,16 +2,16 @@ All PulseAudio source files are licensed under the GNU Lesser General Public
 License. (see file LGPL for details)
 
 However, the server side has optional GPL dependencies.  These include the
-libsamplerate and gdbm (core libraries), LIRC (lirc module), FFTW (equalizer
-module) and bluez (bluetooth proximity helper program) libraries, although
-others may also be included in the future.  If PulseAudio is compiled with these
-optional components, this effectively downgrades the license of the server part
-to GPL (see the file GPL for details), exercising section 3 of the LGPL.  In
-such circumstances, you should treat the client library (libpulse) of PulseAudio
-as being LGPL licensed and the server part (libpulsecore) as being GPL licensed.
-Since the PulseAudio daemon, tests, various utilities/helpers and the modules
-link to libpulsecore and/or the afore mentioned optional GPL dependencies they
-are of course also GPL licensed also in this scenario.
+libsamplerate and gdbm (core libraries), LIRC (lirc module) and FFTW (equalizer
+module), although others may also be included in the future.  If PulseAudio is
+compiled with these optional components, this effectively downgrades the
+license of the server part to GPL (see the file GPL for details), exercising
+section 3 of the LGPL.  In such circumstances, you should treat the client
+library (libpulse) of PulseAudio as being LGPL licensed and the server part
+(libpulsecore) as being GPL licensed.  Since the PulseAudio daemon, tests,
+various utilities/helpers and the modules link to libpulsecore and/or the afore
+mentioned optional GPL dependencies they are of course also GPL licensed also
+in this scenario.
 
 In addition to this, if D-Bus support is enabled, the PulseAudio client library
 (libpulse) MAY need to be licensed under the GPL, depending on the license
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ec87b18..725c38d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -17,7 +17,6 @@ src/modules/module-solaris.c
 src/modules/module-default-device-restore.c
 src/modules/x11/module-x11-xsmp.c
 src/modules/module-remap-sink.c
-src/modules/bluetooth/module-bluetooth-proximity.c
 src/modules/module-detect.c
 src/modules/module-always-sink.c
 src/modules/module-lirc.c
@@ -38,7 +37,6 @@ src/modules/module-esound-compat-spawnfd.c
 src/modules/module-esound-compat-spawnpid.c
 #src/modules/module-waveout.c
 src/modules/module-combine.c
-src/modules/bluetooth/proximity-helper.c
 src/modules/x11/module-x11-publish.c
 src/modules/rtp/module-rtp-recv.c
 src/modules/rtp/sdp.c
diff --git a/src/.gitignore b/src/.gitignore
index 7fe8494..80f6f2c 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -7,7 +7,6 @@ TAGS
 .libs
 /Makefile
 /Makefile.in
-proximity-helper
 client.conf
 daemon.conf
 default.pa
diff --git a/src/Makefile.am b/src/Makefile.am
index ff37877..d9e0d4a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1320,14 +1320,10 @@ endif
 
 if HAVE_BLUEZ
 modlibexec_LTLIBRARIES += \
-		module-bluetooth-proximity.la \
 		module-bluetooth-policy.la \
 		libbluez4-util.la \
 		module-bluez4-discover.la \
 		module-bluez4-device.la
-
-pulselibexec_PROGRAMS += \
-		proximity-helper
 endif
 
 if HAVE_OPENSSL
@@ -1414,7 +1410,6 @@ SYMDEF_FILES = \
 		module-hal-detect-symdef.h \
 		module-udev-detect-symdef.h \
 		module-systemd-login-symdef.h \
-		module-bluetooth-proximity-symdef.h \
 		module-bluetooth-policy-symdef.h \
 		module-bluez4-discover-symdef.h \
 		module-bluez4-device-symdef.h \
@@ -2005,17 +2000,6 @@ gconf_helper_LDADD = $(AM_LDADD) libpulsecore- at PA_MAJORMINOR@.la libpulsecommon-
 gconf_helper_CFLAGS = $(AM_CFLAGS) $(GCONF_CFLAGS)
 gconf_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
-# Bluetooth proximity
-module_bluetooth_proximity_la_SOURCES = modules/bluetooth/module-bluetooth-proximity.c
-module_bluetooth_proximity_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_bluetooth_proximity_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS)
-module_bluetooth_proximity_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -DPA_BT_PROXIMITY_HELPER=\"$(pulselibexecdir)/proximity-helper\"
-
-proximity_helper_SOURCES = modules/bluetooth/proximity-helper.c
-proximity_helper_LDADD = $(AM_LDADD) $(BLUEZ_LIBS)
-proximity_helper_CFLAGS = $(AM_CFLAGS) $(BLUEZ_CFLAGS)
-proximity_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-
 # Bluetooth BlueZ 4 sink / source
 module_bluez4_discover_la_SOURCES = modules/bluetooth/module-bluez4-discover.c
 module_bluez4_discover_la_LDFLAGS = $(MODULE_LDFLAGS)
@@ -2070,10 +2054,6 @@ else
 SYMLINK_PROGRAM=ln -sf
 endif
 install-exec-hook:
-if HAVE_BLUEZ
-	-chown root $(DESTDIR)$(pulselibexecdir)/proximity-helper
-	-chmod u+s $(DESTDIR)$(pulselibexecdir)/proximity-helper
-endif
 	$(SYMLINK_PROGRAM) pacat$(EXEEXT) $(DESTDIR)$(bindir)/parec$(EXEEXT)
 	$(SYMLINK_PROGRAM) pacat$(EXEEXT) $(DESTDIR)$(bindir)/pamon$(EXEEXT)
 	$(SYMLINK_PROGRAM) pacat$(EXEEXT) $(DESTDIR)$(bindir)/paplay$(EXEEXT)
diff --git a/src/modules/bluetooth/module-bluetooth-proximity.c b/src/modules/bluetooth/module-bluetooth-proximity.c
deleted file mode 100644
index c4e6ca6..0000000
--- a/src/modules/bluetooth/module-bluetooth-proximity.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/***
-  This file is part of PulseAudio.
-
-  Copyright 2005-2006 Lennart Poettering
-
-  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 <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <pulse/xmalloc.h>
-#include <pulsecore/module.h>
-#include <pulsecore/log.h>
-#include <pulsecore/namereg.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/modargs.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/start-child.h>
-#include <pulsecore/dbus-shared.h>
-
-#include "module-bluetooth-proximity-symdef.h"
-
-PA_MODULE_AUTHOR("Lennart Poettering");
-PA_MODULE_DESCRIPTION("Bluetooth Proximity Volume Control");
-PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_LOAD_ONCE(true);
-PA_MODULE_USAGE(
-        "sink=<sink name> "
-        "hci=<hci device> "
-);
-
-#define DEFAULT_HCI "hci0"
-
-static const char* const valid_modargs[] = {
-    "sink",
-    "hci",
-    NULL,
-};
-
-struct bonding {
-    struct userdata *userdata;
-    char address[18];
-
-    pid_t pid;
-    int fd;
-
-    pa_io_event *io_event;
-
-    enum {
-        UNKNOWN,
-        FOUND,
-        NOT_FOUND
-    } state;
-};
-
-struct userdata {
-    pa_module *module;
-    pa_dbus_connection *dbus_connection;
-
-    char *sink_name;
-    char *hci, *hci_path;
-
-    pa_hashmap *bondings;
-
-    unsigned n_found;
-    unsigned n_unknown;
-
-    bool muted:1;
-    bool filter_added:1;
-};
-
-static void update_volume(struct userdata *u) {
-    pa_assert(u);
-
-    if (u->muted && u->n_found > 0) {
-        pa_sink *s;
-
-        u->muted = false;
-
-        if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK))) {
-            pa_log_warn("Sink device '%s' not available for unmuting.", pa_strnull(u->sink_name));
-            return;
-        }
-
-        pa_log_info("Found %u BT devices, unmuting.", u->n_found);
-        pa_sink_set_mute(s, false, false);
-
-    } else if (!u->muted && (u->n_found+u->n_unknown) <= 0) {
-        pa_sink *s;
-
-        u->muted = true;
-
-        if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK))) {
-            pa_log_warn("Sink device '%s' not available for muting.", pa_strnull(u->sink_name));
-            return;
-        }
-
-        pa_log_info("No BT devices found, muting.");
-        pa_sink_set_mute(s, true, false);
-
-    } else
-        pa_log_info("%u devices now active, %u with unknown state.", u->n_found, u->n_unknown);
-}
-
-static void bonding_free(struct bonding *b) {
-    pa_assert(b);
-
-    if (b->state == FOUND)
-        pa_assert_se(b->userdata->n_found-- >= 1);
-
-    if (b->state == UNKNOWN)
-        pa_assert_se(b->userdata->n_unknown-- >= 1);
-
-    if (b->pid != (pid_t) -1) {
-        kill(b->pid, SIGTERM);
-        waitpid(b->pid, NULL, 0);
-    }
-
-    if (b->fd >= 0)
-        pa_close(b->fd);
-
-    if (b->io_event)
-        b->userdata->module->core->mainloop->io_free(b->io_event);
-
-    pa_xfree(b);
-}
-
-static void io_event_cb(
-        pa_mainloop_api*a,
-        pa_io_event* e,
-        int fd,
-        pa_io_event_flags_t events,
-        void *userdata) {
-
-    struct bonding *b = userdata;
-    char x;
-    ssize_t r;
-
-    pa_assert(b);
-
-    if ((r = read(fd, &x, 1)) <= 0) {
-        pa_log_warn("Child watching '%s' died abnormally: %s", b->address, r == 0 ? "EOF" : pa_cstrerror(errno));
-
-        pa_assert_se(pa_hashmap_remove(b->userdata->bondings, b->address) == b);
-        bonding_free(b);
-        return;
-    }
-
-    pa_assert_se(r == 1);
-
-    if (b->state == UNKNOWN)
-        pa_assert_se(b->userdata->n_unknown-- >= 1);
-
-    if (x == '+') {
-        pa_assert(b->state == UNKNOWN || b->state == NOT_FOUND);
-
-        b->state = FOUND;
-        b->userdata->n_found++;
-
-        pa_log_info("Device '%s' is alive.", b->address);
-
-    } else {
-        pa_assert(x == '-');
-        pa_assert(b->state == UNKNOWN || b->state == FOUND);
-
-        if (b->state == FOUND)
-            b->userdata->n_found--;
-
-        b->state = NOT_FOUND;
-
-        pa_log_info("Device '%s' is dead.", b->address);
-    }
-
-    update_volume(b->userdata);
-}
-
-static struct bonding* bonding_new(struct userdata *u, const char *a) {
-    struct bonding *b = NULL;
-    DBusMessage *m = NULL, *r = NULL;
-    DBusError e;
-    const char *class;
-
-    pa_assert(u);
-    pa_assert(a);
-
-    pa_return_val_if_fail(strlen(a) == 17, NULL);
-    pa_return_val_if_fail(!pa_hashmap_get(u->bondings, a), NULL);
-
-    dbus_error_init(&e);
-
-    pa_assert_se(m = dbus_message_new_method_call("org.bluez", u->hci_path, "org.bluez.Adapter", "GetRemoteMajorClass"));
-    pa_assert_se(dbus_message_append_args(m, DBUS_TYPE_STRING, &a, DBUS_TYPE_INVALID));
-    r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(u->dbus_connection), m, -1, &e);
-
-    if (!r) {
-        pa_log("org.bluez.Adapter.GetRemoteMajorClass(%s) failed: %s", a, e.message);
-        goto fail;
-    }
-
-    if (!(dbus_message_get_args(r, &e, DBUS_TYPE_STRING, &class, DBUS_TYPE_INVALID))) {
-        pa_log("Malformed org.bluez.Adapter.GetRemoteMajorClass signal: %s", e.message);
-        goto fail;
-    }
-
-    if (!pa_streq(class, "phone")) {
-        pa_log_info("Found device '%s' of class '%s', ignoring.", a, class);
-        goto fail;
-    }
-
-    b = pa_xnew(struct bonding, 1);
-    b->userdata = u;
-    pa_strlcpy(b->address, a, sizeof(b->address));
-    b->pid = (pid_t) -1;
-    b->fd = -1;
-    b->io_event = NULL;
-    b->state = UNKNOWN;
-    u->n_unknown ++;
-
-    pa_log_info("Watching device '%s' of class '%s'.", b->address, class);
-
-    if ((b->fd = pa_start_child_for_read(PA_BT_PROXIMITY_HELPER, a, &b->pid)) < 0) {
-        pa_log("Failed to start helper tool.");
-        goto fail;
-    }
-
-    b->io_event = u->module->core->mainloop->io_new(
-            u->module->core->mainloop,
-            b->fd,
-            PA_IO_EVENT_INPUT,
-            io_event_cb,
-            b);
-
-    dbus_message_unref(m);
-    dbus_message_unref(r);
-
-    pa_hashmap_put(u->bondings, b->address, b);
-
-    return b;
-
-fail:
-    if (m)
-        dbus_message_unref(m);
-    if (r)
-        dbus_message_unref(r);
-
-    if (b)
-        bonding_free(b);
-
-    dbus_error_free(&e);
-    return NULL;
-}
-
-static void bonding_remove(struct userdata *u, const char *a) {
-    struct bonding *b;
-    pa_assert(u);
-
-    pa_return_if_fail((b = pa_hashmap_remove(u->bondings, a)));
-
-    pa_log_info("No longer watching device '%s'", b->address);
-    bonding_free(b);
-}
-
-static DBusHandlerResult filter_func(DBusConnection *connection, DBusMessage *m, void *userdata) {
-    struct userdata *u = userdata;
-    DBusError e;
-
-    dbus_error_init(&e);
-
-    if (dbus_message_is_signal(m, "org.bluez.Adapter", "BondingCreated")) {
-        const char *a;
-
-        if (!(dbus_message_get_args(m, &e, DBUS_TYPE_STRING, &a, DBUS_TYPE_INVALID))) {
-            pa_log("Malformed org.bluez.Adapter.BondingCreated signal: %s", e.message);
-            goto finish;
-        }
-
-        bonding_new(u, a);
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
-    } else if (dbus_message_is_signal(m, "org.bluez.Adapter", "BondingRemoved")) {
-
-        const char *a;
-
-        if (!(dbus_message_get_args(m, &e, DBUS_TYPE_STRING, &a, DBUS_TYPE_INVALID))) {
-            pa_log("Malformed org.bluez.Adapter.BondingRemoved signal: %s", e.message);
-            goto finish;
-        }
-
-        bonding_remove(u, a);
-
-        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-    }
-
-finish:
-
-    dbus_error_free(&e);
-
-    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-static int update_matches(struct userdata *u, bool add) {
-    char *filter1, *filter2;
-    DBusError e;
-    int r = -1;
-
-    pa_assert(u);
-    dbus_error_init(&e);
-
-    filter1 = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='BondingCreated',path='%s'", u->hci_path);
-    filter2 = pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='BondingRemoved',path='%s'", u->hci_path);
-
-    if (add) {
-        dbus_bus_add_match(pa_dbus_connection_get(u->dbus_connection), filter1, &e);
-
-        if (dbus_error_is_set(&e)) {
-            pa_log("dbus_bus_add_match(%s) failed: %s", filter1, e.message);
-            goto finish;
-        }
-    } else
-        dbus_bus_remove_match(pa_dbus_connection_get(u->dbus_connection), filter1, NULL);
-
-    if (add) {
-        dbus_bus_add_match(pa_dbus_connection_get(u->dbus_connection), filter2, &e);
-
-        if (dbus_error_is_set(&e)) {
-            pa_log("dbus_bus_add_match(%s) failed: %s", filter2, e.message);
-            dbus_bus_remove_match(pa_dbus_connection_get(u->dbus_connection), filter1, NULL);
-            goto finish;
-        }
-    } else
-        dbus_bus_remove_match(pa_dbus_connection_get(u->dbus_connection), filter2, NULL);
-
-    if (add) {
-        pa_assert_se(dbus_connection_add_filter(pa_dbus_connection_get(u->dbus_connection), filter_func, u, NULL));
-        u->filter_added = true;
-    } else if (u->filter_added)
-        dbus_connection_remove_filter(pa_dbus_connection_get(u->dbus_connection), filter_func, u);
-
-    r = 0;
-
-finish:
-    pa_xfree(filter1);
-    pa_xfree(filter2);
-    dbus_error_free(&e);
-
-    return r;
-}
-
-int pa__init(pa_module*m) {
-    pa_modargs *ma = NULL;
-    struct userdata *u;
-    DBusError e;
-    DBusMessage *msg = NULL, *r = NULL;
-    DBusMessageIter iter, sub;
-
-    pa_assert(m);
-    dbus_error_init(&e);
-
-    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
-        pa_log("Failed to parse module arguments");
-        goto fail;
-    }
-
-    m->userdata = u = pa_xnew0(struct userdata, 1);
-    u->module = m;
-    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
-    u->hci = pa_xstrdup(pa_modargs_get_value(ma, "hci", DEFAULT_HCI));
-    u->hci_path = pa_sprintf_malloc("/org/bluez/%s", u->hci);
-    u->bondings = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
-
-    if (!(u->dbus_connection = pa_dbus_bus_get(m->core, DBUS_BUS_SYSTEM, &e))) {
-        pa_log("Failed to get D-Bus connection: %s", e.message);
-        goto fail;
-    }
-
-    if (update_matches(u, true) < 0)
-        goto fail;
-
-    pa_assert_se(msg = dbus_message_new_method_call("org.bluez", u->hci_path, "org.bluez.Adapter", "ListBondings"));
-
-    if (!(r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(u->dbus_connection), msg, -1, &e))) {
-        pa_log("org.bluez.Adapter.ListBondings failed: %s", e.message);
-        goto fail;
-    }
-
-    dbus_message_iter_init(r, &iter);
-
-    if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
-        pa_log("Malformed reply to org.bluez.Adapter.ListBondings.");
-        goto fail;
-    }
-
-    dbus_message_iter_recurse(&iter, &sub);
-
-    while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
-        const char *a = NULL;
-
-        dbus_message_iter_get_basic(&sub, &a);
-        bonding_new(u, a);
-
-        dbus_message_iter_next(&sub);
-    }
-
-    dbus_message_unref(r);
-    dbus_message_unref(msg);
-
-    pa_modargs_free(ma);
-
-    if (pa_hashmap_size(u->bondings) == 0)
-        pa_log_warn("Warning: no phone device bonded.");
-
-    update_volume(u);
-
-    return 0;
-
-fail:
-
-    if (ma)
-        pa_modargs_free(ma);
-
-    pa__done(m);
-
-    dbus_error_free(&e);
-
-    if (msg)
-        dbus_message_unref(msg);
-
-    if (r)
-        dbus_message_unref(r);
-
-    return -1;
-}
-
-void pa__done(pa_module*m) {
-    struct userdata *u;
-    pa_assert(m);
-
-    if (!(u = m->userdata))
-        return;
-
-    if (u->bondings)
-        pa_hashmap_free(u->bondings, (pa_free_cb_t) bonding_free);
-
-    if (u->dbus_connection) {
-        update_matches(u, false);
-        pa_dbus_connection_unref(u->dbus_connection);
-    }
-
-    pa_xfree(u->sink_name);
-    pa_xfree(u->hci_path);
-    pa_xfree(u->hci);
-    pa_xfree(u);
-}
diff --git a/src/modules/bluetooth/proximity-helper.c b/src/modules/bluetooth/proximity-helper.c
deleted file mode 100644
index 3767f01..0000000
--- a/src/modules/bluetooth/proximity-helper.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Small SUID helper that allows us to ping a BT device. Borrows
- * heavily from bluez-utils' l2ping, which is licensed as GPL2+
- * and comes with a copyright like this:
- *
- *  Copyright (C) 2000-2001  Qualcomm Incorporated
- *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk at qualcomm.com>
- *  Copyright (C) 2002-2007  Marcel Holtmann <marcel at holtmann.org>
- *
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program 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 General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#undef NDEBUG
-
-#include <assert.h>
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/select.h>
-
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-#include <bluetooth/l2cap.h>
-
-#define PING_STRING "PulseAudio"
-#define IDENT 200
-#define TIMEOUT 4
-#define INTERVAL 2
-
-static void update_status(int found) {
-    static int status = -1;
-
-    if (!found && status != 0)
-        printf("-");
-    if (found && status <= 0)
-        printf("+");
-
-    fflush(stdout);
-    status = !!found;
-}
-
-int main(int argc, char *argv[]) {
-    struct sockaddr_l2 addr;
-    union {
-        l2cap_cmd_hdr hdr;
-        uint8_t buf[L2CAP_CMD_HDR_SIZE + sizeof(PING_STRING)];
-    }  packet;
-    int fd = -1;
-    uint8_t id = IDENT;
-    int connected = 0;
-
-    assert(argc == 2);
-
-    for (;;) {
-        fd_set fds;
-        struct timeval end;
-        ssize_t r;
-
-        if (!connected) {
-
-            if (fd >= 0)
-                close(fd);
-
-            if ((fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) {
-                fprintf(stderr, "socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP) failed: %s", strerror(errno));
-                goto finish;
-            }
-
-            memset(&addr, 0, sizeof(addr));
-            addr.l2_family = AF_BLUETOOTH;
-            bacpy(&addr.l2_bdaddr, BDADDR_ANY);
-
-            if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-                fprintf(stderr, "bind() failed: %s", strerror(errno));
-                goto finish;
-            }
-
-            memset(&addr, 0, sizeof(addr));
-            addr.l2_family = AF_BLUETOOTH;
-            str2ba(argv[1], &addr.l2_bdaddr);
-
-            if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-
-                if (errno == EHOSTDOWN || errno == ECONNRESET || errno == ETIMEDOUT) {
-                    update_status(0);
-                    sleep(INTERVAL);
-                    continue;
-                }
-
-                fprintf(stderr, "connect() failed: %s", strerror(errno));
-                goto finish;
-            }
-
-            connected = 1;
-        }
-
-        assert(connected);
-
-        memset(&packet, 0, sizeof(packet));
-        strcpy((char*) packet.buf + L2CAP_CMD_HDR_SIZE, PING_STRING);
-        packet.hdr.ident = id;
-        packet.hdr.len = htobs(sizeof(PING_STRING));
-        packet.hdr.code = L2CAP_ECHO_REQ;
-
-        if ((r = send(fd, &packet, sizeof(packet), 0)) < 0) {
-
-            if (errno == EHOSTDOWN || errno == ECONNRESET || errno == ETIMEDOUT) {
-                update_status(0);
-                connected = 0;
-                sleep(INTERVAL);
-                continue;
-            }
-
-            fprintf(stderr, "send() failed: %s", strerror(errno));
-            goto finish;
-        }
-
-        assert(r == sizeof(packet));
-
-        gettimeofday(&end, NULL);
-        end.tv_sec += TIMEOUT;
-
-        for (;;) {
-            struct timeval now, delta;
-
-            gettimeofday(&now, NULL);
-
-            if (timercmp(&end, &now, <=)) {
-                update_status(0);
-                connected = 0;
-                sleep(INTERVAL);
-                break;
-            }
-
-            timersub(&end, &now, &delta);
-
-            FD_ZERO(&fds);
-            FD_SET(fd, &fds);
-
-            if (select(fd+1, &fds, NULL, NULL, &delta) < 0) {
-                fprintf(stderr, "select() failed: %s", strerror(errno));
-                goto finish;
-            }
-
-            if ((r = recv(fd, &packet, sizeof(packet), 0)) <= 0) {
-
-                if (errno == EHOSTDOWN || errno == ECONNRESET || errno == ETIMEDOUT) {
-                    update_status(0);
-                    connected = 0;
-                    sleep(INTERVAL);
-                    break;
-                }
-
-                fprintf(stderr, "send() failed: %s", r == 0 ? "EOF" : strerror(errno));
-                goto finish;
-            }
-
-            assert(r >= L2CAP_CMD_HDR_SIZE);
-
-            if (packet.hdr.ident != id)
-                continue;
-
-            if (packet.hdr.code == L2CAP_ECHO_RSP || packet.hdr.code == L2CAP_COMMAND_REJ) {
-
-                if (++id >= 0xFF)
-                    id = IDENT;
-
-                update_status(1);
-                sleep(INTERVAL);
-                break;
-            }
-        }
-    }
-
-finish:
-
-    if (fd >= 0)
-        close(fd);
-
-    return 1;
-}
-- 
1.7.11.7



More information about the pulseaudio-discuss mailing list