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