iInitial commit of rfcommd. - rfcommd - RFCOMM daemon to run filters on clients. Err bitreich.org 70 hgit clone git://bitreich.org/rfcommd/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/rfcommd/ URL:git://bitreich.org/rfcommd/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/rfcommd/ bitreich.org 70 1Log /scm/rfcommd/log.gph bitreich.org 70 1Files /scm/rfcommd/files.gph bitreich.org 70 1Refs /scm/rfcommd/refs.gph bitreich.org 70 1Tags /scm/rfcommd/tag bitreich.org 70 1README /scm/rfcommd/file/README.md.gph bitreich.org 70 1LICENSE /scm/rfcommd/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 70f725160626e24b13cdd304ed86b1184783fc97 /scm/rfcommd/commit/70f725160626e24b13cdd304ed86b1184783fc97.gph bitreich.org 70 hAuthor: Christoph Lohmann <20h@r-36.net> URL:mailto:20h@r-36.net bitreich.org 70 iDate: Fri, 25 Mar 2022 18:10:39 +0100 Err bitreich.org 70 i Err bitreich.org 70 iInitial commit of rfcommd. Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i A Makefile | 53 ++++++++++++++++++++++++++++++ Err bitreich.org 70 i A arg.h | 46 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i A etc/conf.d/rfcommd.gentoo | 6 ++++++ Err bitreich.org 70 i A etc/init.d/rfcommd.gentoo | 29 +++++++++++++++++++++++++++++ Err bitreich.org 70 i A filters/euroklavfilter | 40 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i A filters/spirofilter | 39 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i A rfcommd.c | 595 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i Err bitreich.org 70 i7 files changed, 808 insertions(+), 0 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/rfcommd/file/Makefile.gph bitreich.org 70 i@@ -0,0 +1,53 @@ Err bitreich.org 70 i+# rfcomm-script - a rfcomm service script Err bitreich.org 70 i+# See LICENSE file for copyright and license details. Err bitreich.org 70 i+.POSIX: Err bitreich.org 70 i+ Err bitreich.org 70 i+NAME = rfcommd Err bitreich.org 70 i+VERSION = 0.2 Err bitreich.org 70 i+ Err bitreich.org 70 i+PREFIX = /usr/local Err bitreich.org 70 i+BINDIR = ${PREFIX}/sbin Err bitreich.org 70 i+MANDIR = ${PREFIX}/share/man/man1 Err bitreich.org 70 i+ Err bitreich.org 70 i+RFCOMMD_CFLAGS = -D_GNU_SOURCE -Wall -I. -I/usr/include ${CFLAGS} Err bitreich.org 70 i+RFCOMMD_LDFLAGS = -L/usr/lib -L. -lbluetooth ${LDFLAGS} Err bitreich.org 70 i+ Err bitreich.org 70 i+SRC = rfcommd.c Err bitreich.org 70 i+OBJ = ${SRC:.c=.o} Err bitreich.org 70 i+ Err bitreich.org 70 i+all: ${NAME} Err bitreich.org 70 i+ Err bitreich.org 70 i+.c.o: Err bitreich.org 70 i+ ${CC} ${RFCOMMD_CFLAGS} -c $< Err bitreich.org 70 i+ Err bitreich.org 70 i+${OBJ}: Err bitreich.org 70 i+ Err bitreich.org 70 i+${NAME}: ${OBJ} Err bitreich.org 70 i+ ${CC} -o $@ ${OBJ} ${RFCOMMD_LDFLAGS} Err bitreich.org 70 i+ Err bitreich.org 70 i+clean: Err bitreich.org 70 i+ rm -f ${NAME} ${OBJ} ${NAME}-${VERSION}.tar.gz Err bitreich.org 70 i+ Err bitreich.org 70 i+install: all Err bitreich.org 70 i+ mkdir -p "${DESTDIR}${BINDIR}" Err bitreich.org 70 i+ cp -f ${NAME} "${DESTDIR}${BINDIR}" Err bitreich.org 70 i+ chmod 755 "${DESTDIR}${BINDIR}/${NAME}" Err bitreich.org 70 i+ #mkdir -p "${DESTDIR}${MANDIR}" Err bitreich.org 70 i+ #cp -f ${NAME}.1 "${DESTDIR}${MANDIR}" Err bitreich.org 70 i+ #chmod 644 "${DESTDIR}${MANDIR}/${MANDIR}.1" Err bitreich.org 70 i+ Err bitreich.org 70 i+uninstall: Err bitreich.org 70 i+ rm -f "${DESTDIR}${BINDIR}/${NAME}" Err bitreich.org 70 i+ #rm -f "${DESTDIR}${MANDIR}/${NAME}.1" Err bitreich.org 70 i+ Err bitreich.org 70 i+dist: clean Err bitreich.org 70 i+ mkdir -p ${NAME}-${VERSION} Err bitreich.org 70 i+ cp -R *.c *.h Makefile \ Err bitreich.org 70 i+ ${NAME}-${VERSION} Err bitreich.org 70 i+ tar -cf ${NAME}-${VERSION}.tar ${NAME}-${VERSION} Err bitreich.org 70 i+ gzip ${NAME}-${VERSION}.tar Err bitreich.org 70 i+ mv ${NAME}-${VERSION}.tar.gz ${NAME}-${VERSION}.tgz Err bitreich.org 70 i+ rm -rf "${NAME}-${VERSION}" Err bitreich.org 70 i+ Err bitreich.org 70 i+.PHONY: all clean Err bitreich.org 70 i+ Err bitreich.org 70 1diff --git a/arg.h b/arg.h /scm/rfcommd/file/arg.h.gph bitreich.org 70 i@@ -0,0 +1,46 @@ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * Copy me if you can. Err bitreich.org 70 i+ * by 20h Err bitreich.org 70 i+ */ Err bitreich.org 70 i+ Err bitreich.org 70 i+#ifndef ARG_H__ Err bitreich.org 70 i+#define ARG_H__ Err bitreich.org 70 i+ Err bitreich.org 70 i+/* use main(int argc, char *argv[]) */ Err bitreich.org 70 i+#define ARGBEGIN(ARGV0) for (ARGV0 = *argv, argv++, argc--;\ Err bitreich.org 70 i+ argv[0] && argv[0][0] == '-'\ Err bitreich.org 70 i+ && argv[0][1];\ Err bitreich.org 70 i+ argc--, argv++) {\ Err bitreich.org 70 i+ char argc_;\ Err bitreich.org 70 i+ char **argv_;\ Err bitreich.org 70 i+ int brk_;\ Err bitreich.org 70 i+ if (argv[0][1] == '-' && argv[0][2] == '\0') {\ Err bitreich.org 70 i+ argv++;\ Err bitreich.org 70 i+ argc--;\ Err bitreich.org 70 i+ break;\ Err bitreich.org 70 i+ }\ Err bitreich.org 70 i+ for (brk_ = 0, argv[0]++, argv_ = argv;\ Err bitreich.org 70 i+ argv[0][0] && !brk_;\ Err bitreich.org 70 i+ argv[0]++) {\ Err bitreich.org 70 i+ if (argv_ != argv)\ Err bitreich.org 70 i+ break;\ Err bitreich.org 70 i+ argc_ = argv[0][0];\ Err bitreich.org 70 i+ switch (argc_) Err bitreich.org 70 i+#define ARGEND }\ Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+#define ARGC() argc_ Err bitreich.org 70 i+ Err bitreich.org 70 i+#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ Err bitreich.org 70 i+ ((x), abort(), (char *)0) :\ Err bitreich.org 70 i+ (brk_ = 1, (argv[0][1] != '\0')?\ Err bitreich.org 70 i+ (&argv[0][1]) :\ Err bitreich.org 70 i+ (argc--, argv++, argv[0]))) Err bitreich.org 70 i+ Err bitreich.org 70 i+#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ Err bitreich.org 70 i+ (char *)0 :\ Err bitreich.org 70 i+ (brk_ = 1, (argv[0][1] != '\0')?\ Err bitreich.org 70 i+ (&argv[0][1]) :\ Err bitreich.org 70 i+ (argc--, argv++, argv[0]))) Err bitreich.org 70 i+ Err bitreich.org 70 i+#endif Err bitreich.org 70 1diff --git a/etc/conf.d/rfcommd.gentoo b/etc/conf.d/rfcommd.gentoo /scm/rfcommd/file/etc/conf.d/rfcommd.gentoo.gph bitreich.org 70 i@@ -0,0 +1,6 @@ Err bitreich.org 70 i+# Err bitreich.org 70 i+# Parameters to be passed to rfcommd Err bitreich.org 70 i+# Err bitreich.org 70 i+ Err bitreich.org 70 i+RFCOMMD_ARGS=(-d -f 10:00:E8:27:E3:B3 "sudo -u david /usr/local/bin/spirofilter {}" -f 00:1B:35:14:21:2C "sudo -u david /usr/local/bin/euroklavfilter {}" -f 00:1B:35:17:4B:84 "sudo -u david /usr/local/bin/scpecgfilter {}") Err bitreich.org 70 i+ Err bitreich.org 70 1diff --git a/etc/init.d/rfcommd.gentoo b/etc/init.d/rfcommd.gentoo /scm/rfcommd/file/etc/init.d/rfcommd.gentoo.gph bitreich.org 70 i@@ -0,0 +1,29 @@ Err bitreich.org 70 i+#!/sbin/openrc-run Err bitreich.org 70 i+# Copyright 1999-2016 Gentoo Foundation Err bitreich.org 70 i+# Distributed under the terms of the GNU General Public License v2 Err bitreich.org 70 i+# $Id$ Err bitreich.org 70 i+ Err bitreich.org 70 i+depend() { Err bitreich.org 70 i+ need bluetooth Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+start() { Err bitreich.org 70 i+ ebegin "Starting rfcommd" Err bitreich.org 70 i+ #[ -n "$RFCOMMD_ARGS" ] && RFCOMMD_ARGS="-- $RFCOMMD_ARGS" Err bitreich.org 70 i+ start-stop-daemon -Sbimp /var/run/rfcommd.pid \ Err bitreich.org 70 i+ -1 /var/log/rfcommd-stdout.log \ Err bitreich.org 70 i+ -2 /var/log/rfcommd-stderr.log \ Err bitreich.org 70 i+ -x /usr/sbin/rfcommd -- "${RFCOMMD_ARGS[@]}" Err bitreich.org 70 i+ #start-stop-daemon -Sbimp /var/run/rfcommd.pid \ Err bitreich.org 70 i+ # -1 /tmp/rfcommd-stdout.log \ Err bitreich.org 70 i+ # -2 /tmp/rfcommd-stderr.log \ Err bitreich.org 70 i+ # -x /usr/sbin/rfcommd ${RFCOMMD_ARGS} Err bitreich.org 70 i+ eend $? "Failed to start rfcommd" Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+stop() { Err bitreich.org 70 i+ ebegin "Stopping rfcommd" Err bitreich.org 70 i+ start-stop-daemon -Kip /var/run/rfcommd.pid Err bitreich.org 70 i+ eend $? "Failed to stop rfcommd" Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 1diff --git a/filters/euroklavfilter b/filters/euroklavfilter /scm/rfcommd/file/filters/euroklavfilter.gph bitreich.org 70 i@@ -0,0 +1,40 @@ Err bitreich.org 70 i+#!/bin/sh Err bitreich.org 70 i+ Err bitreich.org 70 i+euroklavdb="/home/david/share/euroklav" Err bitreich.org 70 i+dbpath="${euroklavdb}" Err bitreich.org 70 i+ Err bitreich.org 70 i+if [ $# -gt 0 ]; Err bitreich.org 70 i+then Err bitreich.org 70 i+ infile="$1" Err bitreich.org 70 i+ case "${infile}" in Err bitreich.org 70 i+ /dev/rfcomm*) Err bitreich.org 70 i+ stty -F "${infile}" raw -echo -echoe -echok Err bitreich.org 70 i+ ;; Err bitreich.org 70 i+ esac Err bitreich.org 70 i+else Err bitreich.org 70 i+ infile="/dev/stdin" Err bitreich.org 70 i+fi Err bitreich.org 70 i+ Err bitreich.org 70 i+cd "${dbpath}" Err bitreich.org 70 i+datetime="$(date +%Y-%m-%d-%H-%M-%S)" Err bitreich.org 70 i+outfile="euroklav-${datetime}.txt" Err bitreich.org 70 i+cat "${infile}" \ Err bitreich.org 70 i+| while read -r line; Err bitreich.org 70 i+do Err bitreich.org 70 i+ case "${line}" in Err bitreich.org 70 i+ $'\003'*) Err bitreich.org 70 i+ datetime="$(date +%Y-%m-%d-%H-%M-%S)" Err bitreich.org 70 i+ outfile="euroklav-${datetime}.txt" Err bitreich.org 70 i+ ;; Err bitreich.org 70 i+ *" 4.07 4.08"*) Err bitreich.org 70 i+ printf "%s\n" "${line}" >> ${outfile} Err bitreich.org 70 i+ cat ${outfile} \ Err bitreich.org 70 i+ | tr -d '\002\003' \ Err bitreich.org 70 i+ | tr '\370' ' ' \ Err bitreich.org 70 i+ | tr '\346' ' ' \ Err bitreich.org 70 i+ | lpr Err bitreich.org 70 i+ ;; Err bitreich.org 70 i+ esac Err bitreich.org 70 i+ printf "%s\n" "${line}" >> ${outfile} Err bitreich.org 70 i+done Err bitreich.org 70 i+ Err bitreich.org 70 1diff --git a/filters/spirofilter b/filters/spirofilter /scm/rfcommd/file/filters/spirofilter.gph bitreich.org 70 i@@ -0,0 +1,39 @@ Err bitreich.org 70 i+#!/bin/sh Err bitreich.org 70 i+ Err bitreich.org 70 i+tmpfile="$(mktemp)" Err bitreich.org 70 i+spirometrydb="/home/david/share/spirometry" Err bitreich.org 70 i+ Err bitreich.org 70 i+datetime="$(date +%Y-%m-%d-%H-%M-%S)" Err bitreich.org 70 i+if [ $# -gt 0 ]; Err bitreich.org 70 i+then Err bitreich.org 70 i+ infile="$1" Err bitreich.org 70 i+ case "${infile}" in Err bitreich.org 70 i+ /dev/rfcomm*) Err bitreich.org 70 i+ stty -F "${infile}" raw -echo -echoe -echok Err bitreich.org 70 i+ ;; Err bitreich.org 70 i+ *) Err bitreich.org 70 i+ datetime="$(echo $infile \ Err bitreich.org 70 i+ | cut -d- -f 2- \ Err bitreich.org 70 i+ | cut -d'.' -f 1)" Err bitreich.org 70 i+ ;; Err bitreich.org 70 i+ esac Err bitreich.org 70 i+else Err bitreich.org 70 i+ infile="/dev/stdin" Err bitreich.org 70 i+fi Err bitreich.org 70 i+ Err bitreich.org 70 i+cat "${infile}" > "${tmpfile}" Err bitreich.org 70 i+dbpath="${spirometrydb}" Err bitreich.org 70 i+cd "${dbpath}" Err bitreich.org 70 i+outfile="spirometry-$(cat "${tmpfile}" \ Err bitreich.org 70 i+ | tr -d '\r' \ Err bitreich.org 70 i+ | iconv -f iso8859-1 -t utf-8 \ Err bitreich.org 70 i+ | grep -a "^NAME" \ Err bitreich.org 70 i+ | sed 's,NAME \([^ ]*\)[ ]*\([^ ]*\)[ ]*#ID \([0-9]*\)[ ]*,\1-\2-\3,' \ Err bitreich.org 70 i+ | sed 's, ,_,g; s,/,_,g;')-${datetime}.pcl" Err bitreich.org 70 i+mv "${tmpfile}" "${outfile}" 2>/dev/null Err bitreich.org 70 i+chown david:david "${outfile}" 2>/dev/null Err bitreich.org 70 i+ Err bitreich.org 70 i+cat "${outfile}" \ Err bitreich.org 70 i+ | sed '/Daten von spirolab III Ver/d' \ Err bitreich.org 70 i+ | lpr Err bitreich.org 70 i+ Err bitreich.org 70 1diff --git a/rfcommd.c b/rfcommd.c /scm/rfcommd/file/rfcommd.c.gph bitreich.org 70 i@@ -0,0 +1,595 @@ Err bitreich.org 70 i+/* Err bitreich.org 70 i+ * RFCOMM DAEMON Err bitreich.org 70 i+ * Copied from rfcomm.c in bluez. Err bitreich.org 70 i+ * SDP code from pybluez. Err bitreich.org 70 i+ * Err bitreich.org 70 i+ * Copy me if you can. Err bitreich.org 70 i+ * by 20h Err bitreich.org 70 i+ */ Err bitreich.org 70 i+ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#include "arg.h" Err bitreich.org 70 i+ Err bitreich.org 70 i+volatile sig_atomic_t __io_canceled = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+int dodebug = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+debug(char *fmt, ...) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ va_list fmtargs; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (!dodebug) Err bitreich.org 70 i+ return; Err bitreich.org 70 i+ Err bitreich.org 70 i+ va_start(fmtargs, fmt); Err bitreich.org 70 i+ vfprintf(stderr, fmt, fmtargs); Err bitreich.org 70 i+ va_end(fmtargs); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+sig_hup(int sig) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+sig_term(int sig) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ __io_canceled = 1; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+setup_signals(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct sigaction sa; Err bitreich.org 70 i+ Err bitreich.org 70 i+ memset(&sa, 0, sizeof(sa)); Err bitreich.org 70 i+ sa.sa_flags = SA_NOCLDSTOP; Err bitreich.org 70 i+ sa.sa_handler = SIG_IGN; Err bitreich.org 70 i+ sigaction(SIGCHLD, &sa, NULL); Err bitreich.org 70 i+ sigaction(SIGPIPE, &sa, NULL); Err bitreich.org 70 i+ Err bitreich.org 70 i+ sa.sa_handler = sig_term; Err bitreich.org 70 i+ sigaction(SIGTERM, &sa, NULL); Err bitreich.org 70 i+ sigaction(SIGINT, &sa, NULL); Err bitreich.org 70 i+ Err bitreich.org 70 i+ sa.sa_handler = sig_hup; Err bitreich.org 70 i+ sigaction(SIGHUP, &sa, NULL); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+_adv_available(struct hci_dev_info *di) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ uint32_t *flags = &di->flags; Err bitreich.org 70 i+ int dd; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (hci_test_bit(HCI_RAW, &flags) && !bacmp(&di->bdaddr, BDADDR_ANY)) { Err bitreich.org 70 i+ dd = hci_open_dev(di->dev_id); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (dd < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ hci_read_bd_addr(dd, &di->bdaddr, 1000); Err bitreich.org 70 i+ hci_close_dev(dd); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ return (hci_test_bit(HCI_UP, flags) && Err bitreich.org 70 i+ hci_test_bit(HCI_RUNNING, flags) && Err bitreich.org 70 i+ hci_test_bit(HCI_PSCAN, flags) && Err bitreich.org 70 i+ hci_test_bit(HCI_ISCAN, flags)) != 0 ? 0 : -1; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+_any_adv_available(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct hci_dev_list_req *dl = NULL; Err bitreich.org 70 i+ struct hci_dev_req *dr = NULL; Err bitreich.org 70 i+ struct hci_dev_info di = {0, }; Err bitreich.org 70 i+ int result = -1; Err bitreich.org 70 i+ int ctl = -1; Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + Err bitreich.org 70 i+ sizeof(uint16_t)))) { Err bitreich.org 70 i+ goto CLEAN_UP_RETURN; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ dl->dev_num = HCI_MAX_DEV; Err bitreich.org 70 i+ dr = dl->dev_req; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (ioctl(ctl, HCIGETDEVLIST, (void *)dl) < 0) Err bitreich.org 70 i+ goto CLEAN_UP_RETURN; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (i = 0; i < dl->dev_num; i++) { Err bitreich.org 70 i+ di.dev_id = (dr+i)->dev_id; Err bitreich.org 70 i+ if (ioctl(ctl, HCIGETDEVINFO, (void *)&di) < 0) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (_adv_available(&di) == 0) { Err bitreich.org 70 i+ result = 0; Err bitreich.org 70 i+ goto CLEAN_UP_RETURN; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+CLEAN_UP_RETURN: Err bitreich.org 70 i+ close(ctl); Err bitreich.org 70 i+ free(dl); Err bitreich.org 70 i+ Err bitreich.org 70 i+ return result; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+adv_available(int sock) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ bdaddr_t ba = {{0, }}; Err bitreich.org 70 i+ struct sockaddr addr = {0, }; Err bitreich.org 70 i+ int dev_id = -1; Err bitreich.org 70 i+ socklen_t alen = sizeof(addr); Err bitreich.org 70 i+ struct sockaddr_rc const *addr_rc = (struct sockaddr_rc const *)&addr; Err bitreich.org 70 i+ struct hci_dev_info di; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (getsockname(sock, &addr, &alen) < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ ba = addr_rc->rc_bdaddr; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (bacmp(&ba, BDADDR_ANY) == 0) { Err bitreich.org 70 i+ dev_id = -1; Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ dev_id = hci_get_route(&ba); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (dev_id == -1) { Err bitreich.org 70 i+ return _any_adv_available(); Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ if (hci_devinfo(dev_id, &di)) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ return _adv_available(&di); Err bitreich.org 70 i+ } Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+str2uuid(char *uuidstr, uuid_t *uuid) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ uint32_t uuid_int[4]; Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ char *endptr, buf[9] = { 0 }; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (strlen(uuidstr) == 36) { Err bitreich.org 70 i+ if (uuidstr[8] != '-' && uuidstr[13] != '-' && Err bitreich.org 70 i+ uuidstr[18] != '-' && uuidstr[23] != '-') { Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ strncpy(buf, uuidstr, 8); Err bitreich.org 70 i+ uuid_int[0] = htonl(strtoul(buf, &endptr, 16)); Err bitreich.org 70 i+ if (endptr != buf+8) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ strncpy(buf, uuidstr+9, 4); Err bitreich.org 70 i+ strncpy(buf+4, uuidstr+14, 4); Err bitreich.org 70 i+ uuid_int[1] = htonl(strtoul(buf, &endptr, 16)); Err bitreich.org 70 i+ if (endptr != buf+8) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ strncpy(buf, uuidstr+19, 4); Err bitreich.org 70 i+ strncpy(buf+4, uuidstr+24, 4); Err bitreich.org 70 i+ uuid_int[2] = htonl(strtoul(buf, &endptr, 16)); Err bitreich.org 70 i+ if (endptr != buf+8) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ strncpy(buf, uuidstr+28, 4); Err bitreich.org 70 i+ uuid_int[3] = htonl(strtoul(buf, &endptr, 16)); Err bitreich.org 70 i+ if (endptr != buf+8) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (uuid != NULL) Err bitreich.org 70 i+ sdp_uuid128_create(uuid, uuid_int); Err bitreich.org 70 i+ } else if (strlen(uuidstr) == 8) { Err bitreich.org 70 i+ uuid_int[0] = strtoul(uuidstr, &endptr, 16); Err bitreich.org 70 i+ if (endptr != uuidstr+8) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ if (uuid != NULL) Err bitreich.org 70 i+ sdp_uuid32_create(uuid, uuid_int[0]); Err bitreich.org 70 i+ } else if (strlen(uuidstr) == 4) { Err bitreich.org 70 i+ i = strtol(uuidstr, &endptr, 16); Err bitreich.org 70 i+ if (endptr != uuidstr+4) Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ if (uuid != NULL) Err bitreich.org 70 i+ sdp_uuid16_create(uuid, i); Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+sdp_advertise_service(int sock, char *svcname, Err bitreich.org 70 i+ char *svcid, int svc_class, int profiles, Err bitreich.org 70 i+ char *svcprovider, char *svcdescription) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ char addrbuf[256]; Err bitreich.org 70 i+ int res, err = 0; Err bitreich.org 70 i+ struct sockaddr *sockaddr; Err bitreich.org 70 i+ uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_class_uuid, Err bitreich.org 70 i+ svc_uuid; Err bitreich.org 70 i+ sdp_profile_desc_t *profile_desc; Err bitreich.org 70 i+ sdp_list_t *l2cap_list = NULL, *rfcomm_list = NULL, *root_list = NULL, Err bitreich.org 70 i+ *proto_list = NULL, *profile_list = NULL, Err bitreich.org 70 i+ *svc_class_list = NULL, *access_proto_list = NULL; Err bitreich.org 70 i+ sdp_data_t *channel = 0; Err bitreich.org 70 i+ sdp_record_t record; Err bitreich.org 70 i+ sdp_session_t *session = 0; Err bitreich.org 70 i+ uint8_t rfcomm_channel; Err bitreich.org 70 i+ socklen_t addrlen = sizeof(struct sockaddr_rc); Err bitreich.org 70 i+ Err bitreich.org 70 i+ str2uuid(svcid, &svc_uuid); Err bitreich.org 70 i+ sdp_uuid16_create(&svc_class_uuid, svc_class); Err bitreich.org 70 i+ Err bitreich.org 70 i+ memset(addrbuf, 0, sizeof(addrbuf)); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (adv_available(sock) < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ res = getsockname(sock, (struct sockaddr *)addrbuf, &addrlen); Err bitreich.org 70 i+ if (res < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ sockaddr = (struct sockaddr *)addrbuf; Err bitreich.org 70 i+ Err bitreich.org 70 i+ memset(&record, 0, sizeof(record)); Err bitreich.org 70 i+ memset(&record.handle, 0xff, sizeof(record.handle)); Err bitreich.org 70 i+ Err bitreich.org 70 i+ sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); Err bitreich.org 70 i+ root_list = sdp_list_append(0, &root_uuid); Err bitreich.org 70 i+ sdp_set_browse_groups(&record, root_list); Err bitreich.org 70 i+ sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); Err bitreich.org 70 i+ l2cap_list = sdp_list_append(0, &l2cap_uuid); Err bitreich.org 70 i+ proto_list = sdp_list_append(0, l2cap_list); Err bitreich.org 70 i+ rfcomm_channel = ((struct sockaddr_rc *)sockaddr)->rc_channel; Err bitreich.org 70 i+ sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); Err bitreich.org 70 i+ channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel); Err bitreich.org 70 i+ rfcomm_list = sdp_list_append(0, &rfcomm_uuid); Err bitreich.org 70 i+ sdp_list_append(rfcomm_list, channel); Err bitreich.org 70 i+ sdp_list_append(proto_list, rfcomm_list); Err bitreich.org 70 i+ access_proto_list = sdp_list_append(0, proto_list); Err bitreich.org 70 i+ sdp_set_access_protos(&record, access_proto_list); Err bitreich.org 70 i+ svc_class_list = sdp_list_append(svc_class_list, &svc_class_uuid); Err bitreich.org 70 i+ sdp_set_service_classes(&record, svc_class_list); Err bitreich.org 70 i+ Err bitreich.org 70 i+ profile_desc = (sdp_profile_desc_t *)malloc(sizeof(sdp_profile_desc_t)); Err bitreich.org 70 i+ if (profile_desc == NULL) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ sdp_uuid16_create(&profile_desc->uuid, profiles); Err bitreich.org 70 i+ profile_list = sdp_list_append(profile_list, profile_desc); Err bitreich.org 70 i+ sdp_set_profile_descs(&record, profile_list); Err bitreich.org 70 i+ Err bitreich.org 70 i+ sdp_set_info_attr(&record, svcname, svcprovider, svcdescription); Err bitreich.org 70 i+ sdp_set_service_id(&record, svc_uuid); Err bitreich.org 70 i+ Err bitreich.org 70 i+ session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); Err bitreich.org 70 i+ if (!session) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ err = sdp_record_register(session, &record, 0); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (channel) Err bitreich.org 70 i+ sdp_data_free(channel); Err bitreich.org 70 i+ sdp_list_free(l2cap_list, 0); Err bitreich.org 70 i+ sdp_list_free(rfcomm_list, 0); Err bitreich.org 70 i+ sdp_list_free(root_list, 0); Err bitreich.org 70 i+ sdp_list_free(access_proto_list, 0); Err bitreich.org 70 i+ sdp_list_free(svc_class_list, 0); Err bitreich.org 70 i+ sdp_list_free(profile_list, free); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (err) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+usage(char *argv0) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ fprintf(stderr, "%s [-dhrAESM] [-i hciX|bdaddr] [-L linger] [-c channel] [-f filter cmd] [cmd]\n", Err bitreich.org 70 i+ basename(argv0)); Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+main(int argc, char *argv[]) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int rfcomm_raw_tty = 0, auth = 0, encryption = 0, Err bitreich.org 70 i+ secure = 0, master = 0, linger = 0, sk, nsk, fd, lm , try = 30, Err bitreich.org 70 i+ ctl, rc_channel = 1, filteri, dev; Err bitreich.org 70 i+ char *argv0, *optarg, dst[18], devname[MAXPATHLEN], *replace, Err bitreich.org 70 i+ *cmd, *oldcmd, *defaultcmd = NULL, *runcmd; Err bitreich.org 70 i+ struct sockaddr_rc laddr, raddr; Err bitreich.org 70 i+ struct rfcomm_dev_req req; Err bitreich.org 70 i+ struct termios ti; Err bitreich.org 70 i+ socklen_t alen; Err bitreich.org 70 i+ bdaddr_t bdaddr; Err bitreich.org 70 i+ struct linger l; Err bitreich.org 70 i+ Err bitreich.org 70 i+ char **cmds = NULL; Err bitreich.org 70 i+ char **filteraddrs = NULL; Err bitreich.org 70 i+ bdaddr_t **filterbds = NULL; Err bitreich.org 70 i+ int filtern = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ bacpy(&bdaddr, BDADDR_ANY); Err bitreich.org 70 i+ Err bitreich.org 70 i+ ARGBEGIN(argv0) { Err bitreich.org 70 i+ case 'c': Err bitreich.org 70 i+ rc_channel = atoi(EARGF(usage(argv0))); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'd': Err bitreich.org 70 i+ dodebug = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'i': Err bitreich.org 70 i+ optarg = EARGF(usage(argv0)); Err bitreich.org 70 i+ if (strncmp(optarg, "hci", 3) == 0) { Err bitreich.org 70 i+ hci_devba(atoi(optarg + 3), &bdaddr); Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ str2ba(optarg, &bdaddr); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'f': Err bitreich.org 70 i+ ++filtern; Err bitreich.org 70 i+ filteraddrs = realloc(filteraddrs, Err bitreich.org 70 i+ filtern * sizeof(*filteraddrs)); Err bitreich.org 70 i+ if (filteraddrs == NULL) Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+ Err bitreich.org 70 i+ cmds = realloc(cmds, filtern * sizeof(*cmds)); Err bitreich.org 70 i+ if (cmds == NULL) Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+ Err bitreich.org 70 i+ filterbds = realloc(filterbds, filtern * sizeof(*filterbds)); Err bitreich.org 70 i+ if (filterbds == NULL) Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+ Err bitreich.org 70 i+ filteraddrs[filtern-1] = EARGF(usage(argv0)); Err bitreich.org 70 i+ argv++, argc--; Err bitreich.org 70 i+ if (argc <= 0) Err bitreich.org 70 i+ usage(argv0); Err bitreich.org 70 i+ cmds[filtern-1] = argv[0]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ filterbds[filtern-1] = malloc(sizeof(*filterbds)); Err bitreich.org 70 i+ if (filterbds[filtern-1] == NULL) Err bitreich.org 70 i+ exit(1); Err bitreich.org 70 i+ str2ba(filteraddrs[filtern-1], filterbds[filtern-1]); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'r': Err bitreich.org 70 i+ rfcomm_raw_tty = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'A': Err bitreich.org 70 i+ auth = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'E': Err bitreich.org 70 i+ encryption = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'S': Err bitreich.org 70 i+ secure = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'M': Err bitreich.org 70 i+ master = 1; Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'L': Err bitreich.org 70 i+ linger = atoi(EARGF(usage(argv0))); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ case 'h': Err bitreich.org 70 i+ default: Err bitreich.org 70 i+ usage(argv0); Err bitreich.org 70 i+ } ARGEND; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (argc > 0) Err bitreich.org 70 i+ defaultcmd = argv[0]; Err bitreich.org 70 i+ if (defaultcmd == NULL && filtern < 0) Err bitreich.org 70 i+ usage(argv[0]); Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (filteri = 0; filteri < filtern; filteri++) { Err bitreich.org 70 i+ ba2str(filterbds[filteri], dst); Err bitreich.org 70 i+ debug("filter: %s (%s) -> %s\n", Err bitreich.org 70 i+ filteraddrs[filteri], dst, cmds[filteri]); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ debug("defaultcmd: %s\n", defaultcmd); Err bitreich.org 70 i+ Err bitreich.org 70 i+ setup_signals(); Err bitreich.org 70 i+ Err bitreich.org 70 i+ ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM); Err bitreich.org 70 i+ if (ctl < 0) { Err bitreich.org 70 i+ perror("Can't open RFCOMM control socket"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ laddr.rc_family = AF_BLUETOOTH; Err bitreich.org 70 i+ bacpy(&laddr.rc_bdaddr, &bdaddr); Err bitreich.org 70 i+ laddr.rc_channel = rc_channel; Err bitreich.org 70 i+ Err bitreich.org 70 i+ sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); Err bitreich.org 70 i+ if (sk < 0) { Err bitreich.org 70 i+ perror("Can't create RFCOMM socket"); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ lm = 0; Err bitreich.org 70 i+ if (master) Err bitreich.org 70 i+ lm |= RFCOMM_LM_MASTER; Err bitreich.org 70 i+ if (auth) Err bitreich.org 70 i+ lm |= RFCOMM_LM_AUTH; Err bitreich.org 70 i+ if (encryption) Err bitreich.org 70 i+ lm |= RFCOMM_LM_ENCRYPT; Err bitreich.org 70 i+ if (secure) Err bitreich.org 70 i+ lm |= RFCOMM_LM_SECURE; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) { Err bitreich.org 70 i+ perror("Can't set RFCOMM link mode"); Err bitreich.org 70 i+ close(sk); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { Err bitreich.org 70 i+ perror("Can't bind RFCOMM socket"); Err bitreich.org 70 i+ close(sk); Err bitreich.org 70 i+ return 1; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ debug("Waiting for connection on channel %d\n", laddr.rc_channel); Err bitreich.org 70 i+ Err bitreich.org 70 i+ listen(sk, 10); Err bitreich.org 70 i+ Err bitreich.org 70 i+ sdp_advertise_service(sk, Err bitreich.org 70 i+ "SPP Printer", Err bitreich.org 70 i+ "00001101-0000-1000-8000-00805F9B34FB", Err bitreich.org 70 i+ SERIAL_PORT_SVCLASS_ID, Err bitreich.org 70 i+ SERIAL_PORT_PROFILE_ID, Err bitreich.org 70 i+ "SPP Printer Emulation", Err bitreich.org 70 i+ "rfcommd"); Err bitreich.org 70 i+ Err bitreich.org 70 i+ while (!__io_canceled) { Err bitreich.org 70 i+ alen = sizeof(raddr); Err bitreich.org 70 i+ nsk = accept(sk, (struct sockaddr *)&raddr, &alen); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (fork() != 0) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ Err bitreich.org 70 i+ ba2str(&raddr.rc_bdaddr, dst); Err bitreich.org 70 i+ debug("Accept from %s\n", dst); Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (filteri = 0; filteri < filtern; filteri++) { Err bitreich.org 70 i+ if (!bacmp(filterbds[filteri], &raddr.rc_bdaddr)) { Err bitreich.org 70 i+ runcmd = cmds[filteri]; Err bitreich.org 70 i+ debug("filter found: %s -> %s\n", Err bitreich.org 70 i+ filteraddrs[filteri], Err bitreich.org 70 i+ runcmd); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ if (filteri >= filtern) { Err bitreich.org 70 i+ if (defaultcmd != NULL) { Err bitreich.org 70 i+ debug("running defaultcmd = %s\n", Err bitreich.org 70 i+ defaultcmd); Err bitreich.org 70 i+ runcmd = defaultcmd; Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ close(nsk); Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ alen = sizeof(laddr); Err bitreich.org 70 i+ if (getsockname(nsk, (struct sockaddr *)&laddr, &alen) < 0) { Err bitreich.org 70 i+ perror("Can't get RFCOMM socket name"); Err bitreich.org 70 i+ close(nsk); Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (linger) { Err bitreich.org 70 i+ l.l_onoff = 1; Err bitreich.org 70 i+ l.l_linger = linger; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { Err bitreich.org 70 i+ perror("Can't set linger option"); Err bitreich.org 70 i+ close(nsk); Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ memset(&req, 0, sizeof(req)); Err bitreich.org 70 i+ req.dev_id = -1; Err bitreich.org 70 i+ req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); Err bitreich.org 70 i+ Err bitreich.org 70 i+ bacpy(&req.src, &laddr.rc_bdaddr); Err bitreich.org 70 i+ bacpy(&req.dst, &raddr.rc_bdaddr); Err bitreich.org 70 i+ req.channel = raddr.rc_channel; Err bitreich.org 70 i+ Err bitreich.org 70 i+ dev = ioctl(nsk, RFCOMMCREATEDEV, &req); Err bitreich.org 70 i+ if (dev < 0) { Err bitreich.org 70 i+ perror("Can't create RFCOMM TTY"); Err bitreich.org 70 i+ close(sk); Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); Err bitreich.org 70 i+ while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { Err bitreich.org 70 i+ if (errno == EACCES) { Err bitreich.org 70 i+ perror("Can't open RFCOMM device"); Err bitreich.org 70 i+ goto release; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); Err bitreich.org 70 i+ if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { Err bitreich.org 70 i+ if (try--) { Err bitreich.org 70 i+ snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); Err bitreich.org 70 i+ usleep(100 * 1000); Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ perror("Can't open RFCOMM device"); Err bitreich.org 70 i+ goto release; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (rfcomm_raw_tty) { Err bitreich.org 70 i+ tcflush(fd, TCIOFLUSH); Err bitreich.org 70 i+ Err bitreich.org 70 i+ cfmakeraw(&ti); Err bitreich.org 70 i+ tcsetattr(fd, TCSANOW, &ti); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ ba2str(&req.dst, dst); Err bitreich.org 70 i+ debug("Connection from %s to %s\n", dst, devname); Err bitreich.org 70 i+ Err bitreich.org 70 i+ /* Replace all occurences of '{}' with the rfcomm device path. */ Err bitreich.org 70 i+ asprintf(&oldcmd, "%s", runcmd); Err bitreich.org 70 i+ while ((replace = strstr(oldcmd, "{}"))) { Err bitreich.org 70 i+ replace[0] = '%'; Err bitreich.org 70 i+ replace[1] = 's'; Err bitreich.org 70 i+ asprintf(&cmd, oldcmd, devname); Err bitreich.org 70 i+ free(oldcmd); Err bitreich.org 70 i+ oldcmd = cmd; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ debug("Executing %s\n", cmd); Err bitreich.org 70 i+ Err bitreich.org 70 i+ system(cmd); Err bitreich.org 70 i+ free(cmd); Err bitreich.org 70 i+ Err bitreich.org 70 i+ close(fd); Err bitreich.org 70 i+ close(nsk); Err bitreich.org 70 i+release: Err bitreich.org 70 i+ memset(&req, 0, sizeof(req)); Err bitreich.org 70 i+ req.dev_id = dev; Err bitreich.org 70 i+ req.flags = (1 << RFCOMM_HANGUP_NOW); Err bitreich.org 70 i+ ioctl(ctl, RFCOMMRELEASEDEV, &req); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ close(sk); Err bitreich.org 70 i+ Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 .