summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE20
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am20
-rw-r--r--src/modules/bluetooth/module-bluetooth-proximity.c480
-rw-r--r--src/modules/bluetooth/proximity-helper.c202
6 files changed, 10 insertions, 714 deletions
diff --git a/LICENSE b/LICENSE
index 30833e59e..226c4ce40 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 17ebc1d23..0b8101866 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -15,7 +15,6 @@ src/modules/alsa/module-alsa-card.c
src/modules/alsa/module-alsa-sink.c
src/modules/alsa/module-alsa-source.c
src/modules/bluetooth/module-bluetooth-device.c
-src/modules/bluetooth/module-bluetooth-proximity.c
src/modules/bluetooth/proximity-helper.c
src/modules/echo-cancel/module-echo-cancel.c
src/modules/gconf/gconf-helper.c
diff --git a/src/.gitignore b/src/.gitignore
index 7fe84941d..80f6f2ce5 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 9113d837e..a294b65b8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1322,14 +1322,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
@@ -1418,7 +1414,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 \
@@ -2017,17 +2012,6 @@ gconf_helper_LDADD = $(AM_LDADD) libpulsecore-@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)
@@ -2082,10 +2066,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 1110ceb6a..000000000
--- 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_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) bonding_free);
-
- 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);
-
- 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 3767f01ce..000000000
--- 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@qualcomm.com>
- * Copyright (C) 2002-2007 Marcel Holtmann <marcel@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;
-}