diff options
-rw-r--r-- | LICENSE | 20 | ||||
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/Makefile.am | 20 | ||||
-rw-r--r-- | src/modules/bluetooth/module-bluetooth-proximity.c | 480 | ||||
-rw-r--r-- | src/modules/bluetooth/proximity-helper.c | 202 |
6 files changed, 10 insertions, 714 deletions
@@ -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; -} |