diff options
-rw-r--r-- | Makefile.tools | 39 | ||||
-rw-r--r-- | acinclude.m4 | 18 | ||||
-rwxr-xr-x | bootstrap-configure | 3 | ||||
-rw-r--r-- | compat/bnep.c | 339 | ||||
-rw-r--r-- | compat/dun.c | 334 | ||||
-rw-r--r-- | compat/dund.1 | 72 | ||||
-rw-r--r-- | compat/dund.c | 645 | ||||
-rw-r--r-- | compat/dund.h | 40 | ||||
-rw-r--r-- | compat/fakehid.c | 669 | ||||
-rw-r--r-- | compat/fakehid.txt | 134 | ||||
-rw-r--r-- | compat/hidd.1 | 41 | ||||
-rw-r--r-- | compat/hidd.c | 848 | ||||
-rw-r--r-- | compat/hidd.h | 30 | ||||
-rw-r--r-- | compat/lib.h | 86 | ||||
-rw-r--r-- | compat/msdun.c | 153 | ||||
-rw-r--r-- | compat/pand.1 | 77 | ||||
-rw-r--r-- | compat/pand.c | 811 | ||||
-rw-r--r-- | compat/pand.h | 36 | ||||
-rw-r--r-- | compat/sdp.c | 706 | ||||
-rw-r--r-- | compat/sdp.h | 39 |
20 files changed, 0 insertions, 5120 deletions
diff --git a/Makefile.tools b/Makefile.tools index c770d5733..1626a4bed 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -223,42 +223,3 @@ EXTRA_DIST += test/sap-client test/hsplay test/hsmicro \ test/service-record.dtd test/service-did.xml \ test/service-spp.xml test/service-opp.xml test/service-ftp.xml \ test/simple-player test/test-nap - -if HIDD -bin_PROGRAMS += compat/hidd - -compat_hidd_SOURCES = compat/hidd.c compat/hidd.h src/uinput.h \ - compat/sdp.h compat/sdp.c compat/fakehid.c \ - src/textfile.h src/textfile.c -compat_hidd_LDADD = -lm lib/libbluetooth-private.la - -dist_man_MANS += compat/hidd.1 -else -EXTRA_DIST += compat/hidd.1 -endif - -if PAND -bin_PROGRAMS += compat/pand - -compat_pand_SOURCES = compat/pand.c compat/pand.h \ - compat/bnep.c compat/sdp.h compat/sdp.c \ - src/textfile.h src/textfile.c -compat_pand_LDADD = lib/libbluetooth-private.la - -dist_man_MANS += compat/pand.1 -else -EXTRA_DIST += compat/pand.1 -endif - -if DUND -bin_PROGRAMS += compat/dund - -compat_dund_SOURCES = compat/dund.c compat/dund.h compat/lib.h \ - compat/sdp.h compat/sdp.c compat/dun.c compat/msdun.c \ - src/textfile.h src/textfile.c -compat_dund_LDADD = lib/libbluetooth-private.la - -dist_man_MANS += compat/dund.1 -else -EXTRA_DIST += compat/dund.1 -endif diff --git a/acinclude.m4 b/acinclude.m4 index ab0ebba1c..b78c0770d 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -179,9 +179,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [ health_enable=no pnat_enable=no tools_enable=yes - hidd_enable=no - pand_enable=no - dund_enable=no cups_enable=no test_enable=no bccmd_enable=no @@ -273,18 +270,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [ dfutool_enable=${enableval} ]) - AC_ARG_ENABLE(hidd, AC_HELP_STRING([--enable-hidd], [install HID daemon]), [ - hidd_enable=${enableval} - ]) - - AC_ARG_ENABLE(pand, AC_HELP_STRING([--enable-pand], [install PAN daemon]), [ - pand_enable=${enableval} - ]) - - AC_ARG_ENABLE(dund, AC_HELP_STRING([--enable-dund], [install DUN daemon]), [ - dund_enable=${enableval} - ]) - AC_ARG_ENABLE(cups, AC_HELP_STRING([--enable-cups], [install CUPS backend support]), [ cups_enable=${enableval} ]) @@ -369,9 +354,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AM_CONDITIONAL(HAL, test "${hal_enable}" = "yes") AM_CONDITIONAL(READLINE, test "${readline_found}" = "yes") AM_CONDITIONAL(PNATPLUGIN, test "${pnat_enable}" = "yes") - AM_CONDITIONAL(HIDD, test "${hidd_enable}" = "yes") - AM_CONDITIONAL(PAND, test "${pand_enable}" = "yes") - AM_CONDITIONAL(DUND, test "${dund_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") AM_CONDITIONAL(TEST, test "${test_enable}" = "yes" && test "${check_found}" = "yes") AM_CONDITIONAL(TOOLS, test "${tools_enable}" = "yes") diff --git a/bootstrap-configure b/bootstrap-configure index f00d1d45d..ff63c58e3 100755 --- a/bootstrap-configure +++ b/bootstrap-configure @@ -21,9 +21,6 @@ fi --enable-bccmd \ --enable-dfutool \ --enable-hid2hci \ - --enable-hidd \ - --enable-pand \ - --enable-dund \ --enable-test \ --enable-cups \ --enable-dbusoob \ diff --git a/compat/bnep.c b/compat/bnep.c deleted file mode 100644 index 281350baf..000000000 --- a/compat/bnep.c +++ /dev/null @@ -1,339 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2010 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 - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/socket.h> -#include <sys/ioctl.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/bnep.h> - -#include <netinet/in.h> - -#include "pand.h" - -static int ctl; - -/* Compatibility with old ioctls */ -#define OLD_BNEPCONADD 1 -#define OLD_BNEPCONDEL 2 -#define OLD_BNEPGETCONLIST 3 -#define OLD_BNEPGETCONINFO 4 - -static unsigned long bnepconnadd; -static unsigned long bnepconndel; -static unsigned long bnepgetconnlist; -static unsigned long bnepgetconninfo; - -static struct { - char *str; - uint16_t uuid; -} __svc[] = { - { "PANU", BNEP_SVC_PANU }, - { "NAP", BNEP_SVC_NAP }, - { "GN", BNEP_SVC_GN }, - { NULL } -}; - -int bnep_str2svc(char *svc, uint16_t *uuid) -{ - int i; - for (i = 0; __svc[i].str; i++) - if (!strcasecmp(svc, __svc[i].str)) { - *uuid = __svc[i].uuid; - return 0; - } - return -1; -} - -char *bnep_svc2str(uint16_t uuid) -{ - int i; - for (i = 0; __svc[i].str; i++) - if (__svc[i].uuid == uuid) - return __svc[i].str; - return NULL; -} - -int bnep_init(void) -{ - ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); - if (ctl < 0) { - perror("Failed to open control socket"); - return 1; - } - - /* Temporary ioctl compatibility hack */ - { - struct bnep_connlist_req req; - struct bnep_conninfo ci[1]; - - req.cnum = 1; - req.ci = ci; - - if (!ioctl(ctl, BNEPGETCONNLIST, &req)) { - /* New ioctls */ - bnepconnadd = BNEPCONNADD; - bnepconndel = BNEPCONNDEL; - bnepgetconnlist = BNEPGETCONNLIST; - bnepgetconninfo = BNEPGETCONNINFO; - } else { - /* Old ioctls */ - bnepconnadd = OLD_BNEPCONADD; - bnepconndel = OLD_BNEPCONDEL; - bnepgetconnlist = OLD_BNEPGETCONLIST; - bnepgetconninfo = OLD_BNEPGETCONINFO; - } - } - - return 0; -} - -int bnep_cleanup(void) -{ - close(ctl); - return 0; -} - -int bnep_show_connections(void) -{ - struct bnep_connlist_req req; - struct bnep_conninfo ci[48]; - unsigned int i; - - req.cnum = 48; - req.ci = ci; - if (ioctl(ctl, bnepgetconnlist, &req)) { - perror("Failed to get connection list"); - return -1; - } - - for (i = 0; i < req.cnum; i++) { - char addr[18]; - ba2str((bdaddr_t *) ci[i].dst, addr); - printf("%s %s %s\n", ci[i].device, - addr, bnep_svc2str(ci[i].role)); - } - return 0; -} - -int bnep_kill_connection(uint8_t *dst) -{ - struct bnep_conndel_req req; - - memcpy(req.dst, dst, ETH_ALEN); - req.flags = 0; - if (ioctl(ctl, bnepconndel, &req)) { - perror("Failed to kill connection"); - return -1; - } - return 0; -} - -int bnep_kill_all_connections(void) -{ - struct bnep_connlist_req req; - struct bnep_conninfo ci[48]; - unsigned int i; - - req.cnum = 48; - req.ci = ci; - if (ioctl(ctl, bnepgetconnlist, &req)) { - perror("Failed to get connection list"); - return -1; - } - - for (i = 0; i < req.cnum; i++) { - struct bnep_conndel_req req; - memcpy(req.dst, ci[i].dst, ETH_ALEN); - req.flags = 0; - ioctl(ctl, bnepconndel, &req); - } - return 0; -} - -static int bnep_connadd(int sk, uint16_t role, char *dev) -{ - struct bnep_connadd_req req; - - strncpy(req.device, dev, 16); - req.device[15] = '\0'; - req.sock = sk; - req.role = role; - if (ioctl(ctl, bnepconnadd, &req)) - return -1; - strncpy(dev, req.device, 16); - return 0; -} - -struct __service_16 { - uint16_t dst; - uint16_t src; -} __attribute__ ((packed)); - -struct __service_32 { - uint16_t unused1; - uint16_t dst; - uint16_t unused2; - uint16_t src; -} __attribute__ ((packed)); - -struct __service_128 { - uint16_t unused1; - uint16_t dst; - uint16_t unused2[8]; - uint16_t src; - uint16_t unused3[7]; -} __attribute__ ((packed)); - -int bnep_accept_connection(int sk, uint16_t role, char *dev) -{ - struct bnep_setup_conn_req *req; - struct bnep_control_rsp *rsp; - unsigned char pkt[BNEP_MTU]; - ssize_t r; - - r = recv(sk, pkt, BNEP_MTU, 0); - if (r <= 0) - return -1; - - errno = EPROTO; - - if ((size_t) r < sizeof(*req)) - return -1; - - req = (void *) pkt; - - /* Highest known Control command ID - * is BNEP_FILTER_MULT_ADDR_RSP = 0x06 */ - if (req->type == BNEP_CONTROL && - req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) { - uint8_t pkt[3]; - - pkt[0] = BNEP_CONTROL; - pkt[1] = BNEP_CMD_NOT_UNDERSTOOD; - pkt[2] = req->ctrl; - - send(sk, pkt, sizeof(pkt), 0); - - return -1; - } - - if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) - return -1; - - /* FIXME: Check role UUIDs */ - - rsp = (void *) pkt; - rsp->type = BNEP_CONTROL; - rsp->ctrl = BNEP_SETUP_CONN_RSP; - rsp->resp = htons(BNEP_SUCCESS); - if (send(sk, rsp, sizeof(*rsp), 0) < 0) - return -1; - - return bnep_connadd(sk, role, dev); -} - -/* Create BNEP connection - * sk - Connect L2CAP socket - * role - Local role - * service - Remote service - * dev - Network device (contains actual dev name on return) - */ -int bnep_create_connection(int sk, uint16_t role, uint16_t svc, char *dev) -{ - struct bnep_setup_conn_req *req; - struct bnep_control_rsp *rsp; - struct __service_16 *s; - struct timeval timeo; - unsigned char pkt[BNEP_MTU]; - ssize_t r; - - /* Send request */ - req = (void *) pkt; - req->type = BNEP_CONTROL; - req->ctrl = BNEP_SETUP_CONN_REQ; - req->uuid_size = 2; /* 16bit UUID */ - - s = (void *) req->service; - s->dst = htons(svc); - s->src = htons(role); - - memset(&timeo, 0, sizeof(timeo)); - timeo.tv_sec = 30; - - setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo)); - - if (send(sk, pkt, sizeof(*req) + sizeof(*s), 0) < 0) - return -1; - -receive: - /* Get response */ - r = recv(sk, pkt, BNEP_MTU, 0); - if (r <= 0) - return -1; - - memset(&timeo, 0, sizeof(timeo)); - timeo.tv_sec = 0; - - setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo)); - - errno = EPROTO; - - if ((size_t) r < sizeof(*rsp)) - return -1; - - rsp = (void *) pkt; - if (rsp->type != BNEP_CONTROL) - return -1; - - if (rsp->ctrl != BNEP_SETUP_CONN_RSP) - goto receive; - - r = ntohs(rsp->resp); - - switch (r) { - case BNEP_SUCCESS: - break; - - case BNEP_CONN_INVALID_DST: - case BNEP_CONN_INVALID_SRC: - case BNEP_CONN_INVALID_SVC: - errno = EPROTO; - return -1; - - case BNEP_CONN_NOT_ALLOWED: - errno = EACCES; - return -1; - } - - return bnep_connadd(sk, role, dev); -} diff --git a/compat/dun.c b/compat/dun.c deleted file mode 100644 index 3f3a0d417..000000000 --- a/compat/dun.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2010 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 - -#include <stdio.h> -#include <errno.h> -#include <ctype.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <syslog.h> -#include <dirent.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <sys/param.h> -#include <sys/ioctl.h> -#include <sys/socket.h> - -#include <netinet/in.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/rfcomm.h> - -#include "dund.h" -#include "lib.h" - -#define PROC_BASE "/proc" - -static int for_each_port(int (*func)(struct rfcomm_dev_info *, unsigned long), unsigned long arg) -{ - struct rfcomm_dev_list_req *dl; - struct rfcomm_dev_info *di; - long r = 0; - int sk, i; - - sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM); - if (sk < 0 ) { - perror("Can't open RFCOMM control socket"); - exit(1); - } - - dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); - if (!dl) { - perror("Can't allocate request memory"); - close(sk); - exit(1); - } - - dl->dev_num = RFCOMM_MAX_DEV; - di = dl->dev_info; - - if (ioctl(sk, RFCOMMGETDEVLIST, (void *) dl) < 0) { - perror("Can't get device list"); - exit(1); - } - - for (i = 0; i < dl->dev_num; i++) { - r = func(di + i, arg); - if (r) break; - } - - close(sk); - free(dl); - return r; -} - -static int uses_rfcomm(char *path, char *dev) -{ - struct dirent *de; - DIR *dir; - - dir = opendir(path); - if (!dir) - return 0; - - if (chdir(path) < 0) - return 0; - - while ((de = readdir(dir)) != NULL) { - char link[PATH_MAX + 1]; - int len = readlink(de->d_name, link, PATH_MAX); - if (len > 0) { - link[len] = 0; - if (strstr(link, dev)) { - closedir(dir); - return 1; - } - } - } - - closedir(dir); - - return 0; -} - -static int find_pppd(int id, pid_t *pid) -{ - struct dirent *de; - char path[PATH_MAX + 1]; - char dev[10]; - int empty = 1; - DIR *dir; - - dir = opendir(PROC_BASE); - if (!dir) { - perror(PROC_BASE); - return -1; - } - - sprintf(dev, "rfcomm%d", id); - - *pid = 0; - while ((de = readdir(dir)) != NULL) { - empty = 0; - if (isdigit(de->d_name[0])) { - sprintf(path, "%s/%s/fd", PROC_BASE, de->d_name); - if (uses_rfcomm(path, dev)) { - *pid = atoi(de->d_name); - break; - } - } - } - closedir(dir); - - if (empty) - fprintf(stderr, "%s is empty (not mounted ?)\n", PROC_BASE); - - return *pid != 0; -} - -static int dun_exec(char *tty, char *prog, char **args) -{ - int pid = fork(); - int fd; - - switch (pid) { - case -1: - return -1; - - case 0: - break; - - default: - return pid; - } - - setsid(); - - /* Close all FDs */ - for (fd = 3; fd < 20; fd++) - close(fd); - - execvp(prog, args); - - syslog(LOG_ERR, "Error while executing %s", prog); - - exit(1); -} - -static int dun_create_tty(int sk, char *tty, int size) -{ - struct sockaddr_rc sa; - struct stat st; - socklen_t alen; - int id, try = 30; - - struct rfcomm_dev_req req = { - .flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP), - .dev_id = -1 - }; - - alen = sizeof(sa); - if (getpeername(sk, (struct sockaddr *) &sa, &alen) < 0) - return -1; - bacpy(&req.dst, &sa.rc_bdaddr); - - alen = sizeof(sa); - if (getsockname(sk, (struct sockaddr *) &sa, &alen) < 0) - return -1; - bacpy(&req.src, &sa.rc_bdaddr); - req.channel = sa.rc_channel; - - id = ioctl(sk, RFCOMMCREATEDEV, &req); - if (id < 0) - return id; - - snprintf(tty, size, "/dev/rfcomm%d", id); - while (stat(tty, &st) < 0) { - snprintf(tty, size, "/dev/bluetooth/rfcomm/%d", id); - if (stat(tty, &st) < 0) { - snprintf(tty, size, "/dev/rfcomm%d", id); - if (try--) { - usleep(100 * 1000); - continue; - } - - memset(&req, 0, sizeof(req)); - req.dev_id = id; - ioctl(sk, RFCOMMRELEASEDEV, &req); - - return -1; - } - } - - return id; -} - -int dun_init(void) -{ - return 0; -} - -int dun_cleanup(void) -{ - return 0; -} - -static int show_conn(struct rfcomm_dev_info *di, unsigned long arg) -{ - pid_t pid; - - if (di->state == BT_CONNECTED && - (di->flags & (1<<RFCOMM_REUSE_DLC)) && - (di->flags & (1<<RFCOMM_TTY_ATTACHED)) && - (di->flags & (1<<RFCOMM_RELEASE_ONHUP))) { - - if (find_pppd(di->id, &pid)) { - char dst[18]; - ba2str(&di->dst, dst); - - printf("rfcomm%d: %s channel %d pppd pid %d\n", - di->id, dst, di->channel, pid); - } - } - return 0; -} - -static int kill_conn(struct rfcomm_dev_info *di, unsigned long arg) -{ - bdaddr_t *dst = (bdaddr_t *) arg; - pid_t pid; - - if (di->state == BT_CONNECTED && - (di->flags & (1<<RFCOMM_REUSE_DLC)) && - (di->flags & (1<<RFCOMM_TTY_ATTACHED)) && - (di->flags & (1<<RFCOMM_RELEASE_ONHUP))) { - - if (dst && bacmp(&di->dst, dst)) - return 0; - - if (find_pppd(di->id, &pid)) { - if (kill(pid, SIGINT) < 0) - perror("Kill"); - - if (!dst) - return 0; - return 1; - } - } - return 0; -} - -int dun_show_connections(void) -{ - for_each_port(show_conn, 0); - return 0; -} - -int dun_kill_connection(uint8_t *dst) -{ - for_each_port(kill_conn, (unsigned long) dst); - return 0; -} - -int dun_kill_all_connections(void) -{ - for_each_port(kill_conn, 0); - return 0; -} - -int dun_open_connection(int sk, char *pppd, char **args, int wait) -{ - char tty[100]; - int pid; - - if (dun_create_tty(sk, tty, sizeof(tty) - 1) < 0) { - syslog(LOG_ERR, "RFCOMM TTY creation failed. %s(%d)", strerror(errno), errno); - return -1; - } - - args[0] = "pppd"; - args[1] = tty; - args[2] = "nodetach"; - - pid = dun_exec(tty, pppd, args); - if (pid < 0) { - syslog(LOG_ERR, "Exec failed. %s(%d)", strerror(errno), errno); - return -1; - } - - if (wait) { - int status; - waitpid(pid, &status, 0); - /* FIXME: Check for waitpid errors */ - } - - return 0; -} diff --git a/compat/dund.1 b/compat/dund.1 deleted file mode 100644 index 09fb7f755..000000000 --- a/compat/dund.1 +++ /dev/null @@ -1,72 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. -.TH BlueZ "1" "February 2003" "DUN daemon" "User Commands" -.SH NAME -dund \- BlueZ Bluetooth dial-up networking daemon -.SH DESCRIPTION -DUN daemon -.SH SYNOPSIS -dund <options> [pppd options] -.SH OPTIONS -.TP -\fB\-\-show\fR \fB\-\-list\fR \fB\-l\fR -Show active DUN connections -.TP -\fB\-\-listen\fR \fB\-s\fR -Listen for DUN connections -.TP -\fB\-\-dialup\fR \fB\-u\fR -Listen for dialup/telephone connections -.TP -\fB\-\-connect\fR \fB\-c\fR <bdaddr> -Create DUN connection -.TP -\fB\-\-mrouter\fR \fB\-m\fR <bdaddr> -Create mRouter connection -.TP -\fB\-\-search\fR \fB\-Q[duration]\fR -Search and connect -.TP -\fB\-\-kill\fR \fB\-k\fR <bdaddr> -Kill DUN connection -.TP -\fB\-\-killall\fR \fB\-K\fR -Kill all DUN connections -.TP -\fB\-\-channel\fR \fB\-C\fR <channel> -RFCOMM channel -.TP -\fB\-\-device\fR \fB\-i\fR <bdaddr> -Source bdaddr -.TP -\fB\-\-nosdp\fR \fB\-D\fR -Disable SDP -.TP -\fB\-\-auth\fR \fB\-A\fR -Enable authentification -.TP -\fB\-\-encrypt\fR \fB\-E\fR -Enable encryption -.TP -\fB\-\-secure\fR \fB\-S\fR -Secure connection -.TP -\fB\-\-master\fR \fB\-M\fR -Become the master of a piconet -.TP -\fB\-\-nodetach\fR \fB\-n\fR -Do not become a daemon -.TP -\fB\-\-persist\fR \fB\-p[interval]\fR -Persist mode -.TP -\fB\-\-pppd\fR \fB\-d\fR <pppd> -Location of the PPP daemon (pppd) -.TP -\fB\-\-msdun\fR \fB\-X\fR [timeo] -Enable Microsoft dialup networking support -.TP -\fB\-\-activesync\fR \fB\-a\fR -Enable Microsoft ActiveSync networking -.TP -\fB\-\-cache\fR \fB\-C\fR [valid] -Enable address cache diff --git a/compat/dund.c b/compat/dund.c deleted file mode 100644 index af1b53607..000000000 --- a/compat/dund.c +++ /dev/null @@ -1,645 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2010 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 - -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <signal.h> -#include <getopt.h> - -#include <sys/socket.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/hci.h> -#include <bluetooth/hci_lib.h> -#include <bluetooth/rfcomm.h> -#include <bluetooth/hidp.h> - -#include "sdp.h" -#include "dund.h" -#include "lib.h" - -volatile sig_atomic_t __io_canceled; - -/* MS dialup networking support (i.e. CLIENT / CLIENTSERVER thing) */ -static int msdun = 0; - -static char *pppd = "/usr/sbin/pppd"; -static char *pppd_opts[DUN_MAX_PPP_OPTS] = - { - /* First 3 are reserved */ - "", "", "", - "noauth", - "noipdefault", - NULL - }; - -static int detach = 1; -static int persist; -static int use_sdp = 1; -static int auth; -static int encrypt; -static int secure; -static int master; -static int type = LANACCESS; -static int search_duration = 10; -static uint use_cache; - -static int channel; - -static struct { - uint valid; - char dst[40]; - bdaddr_t bdaddr; - int channel; -} cache; - -static bdaddr_t src_addr = *BDADDR_ANY; -static int src_dev = -1; - -volatile int terminate; - -enum { - NONE, - SHOW, - LISTEN, - CONNECT, - KILL -} modes; - -static int create_connection(char *dst, bdaddr_t *bdaddr, int mrouter); - -static int do_listen(void) -{ - struct sockaddr_rc sa; - int sk, lm; - - if (type == MROUTER) { - if (!cache.valid) - return -1; - - if (create_connection(cache.dst, &cache.bdaddr, type) < 0) { - syslog(LOG_ERR, "Cannot connect to mRouter device. %s(%d)", - strerror(errno), errno); - return -1; - } - } - - if (!channel) - channel = DUN_DEFAULT_CHANNEL; - - if (use_sdp) - dun_sdp_register(&src_addr, channel, type); - - if (type == MROUTER) - syslog(LOG_INFO, "Waiting for mRouter callback on channel %d", channel); - - /* Create RFCOMM socket */ - sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); - if (sk < 0) { - syslog(LOG_ERR, "Cannot create RFCOMM socket. %s(%d)", - strerror(errno), errno); - return -1; - } - - sa.rc_family = AF_BLUETOOTH; - sa.rc_channel = channel; - sa.rc_bdaddr = src_addr; - - if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) { - syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno); - return -1; - } - - /* Set link mode */ - lm = 0; - if (master) - lm |= RFCOMM_LM_MASTER; - if (auth) - lm |= RFCOMM_LM_AUTH; - if (encrypt) - lm |= RFCOMM_LM_ENCRYPT; - if (secure) - lm |= RFCOMM_LM_SECURE; - - if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) { - syslog(LOG_ERR, "Failed to set link mode. %s(%d)", strerror(errno), errno); - return -1; - } - - listen(sk, 10); - - while (!terminate) { - socklen_t alen = sizeof(sa); - int nsk; - char ba[40]; - char ch[10]; - - nsk = accept(sk, (struct sockaddr *) &sa, &alen); - if (nsk < 0) { - syslog(LOG_ERR, "Accept failed. %s(%d)", strerror(errno), errno); - continue; - } - - switch (fork()) { - case 0: - break; - case -1: - syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno); - default: - close(nsk); - if (type == MROUTER) { - close(sk); - terminate = 1; - } - continue; - } - - close(sk); - - if (msdun && ms_dun(nsk, 1, msdun) < 0) { - syslog(LOG_ERR, "MSDUN failed. %s(%d)", strerror(errno), errno); - exit(0); - } - - ba2str(&sa.rc_bdaddr, ba); - snprintf(ch, sizeof(ch), "%d", channel); - - /* Setup environment */ - setenv("DUN_BDADDR", ba, 1); - setenv("DUN_CHANNEL", ch, 1); - - if (!dun_open_connection(nsk, pppd, pppd_opts, 0)) - syslog(LOG_INFO, "New connection from %s", ba); - - close(nsk); - exit(0); - } - - if (use_sdp) - dun_sdp_unregister(); - return 0; -} - -/* Connect and initiate RFCOMM session - * Returns: - * -1 - critical error (exit persist mode) - * 1 - non critical error - * 0 - success - */ -static int create_connection(char *dst, bdaddr_t *bdaddr, int mrouter) -{ - struct sockaddr_rc sa; - int sk, err = 0, ch; - - if (use_cache && cache.valid && cache.channel) { - /* Use cached channel */ - ch = cache.channel; - - } else if (!channel) { - syslog(LOG_INFO, "Searching for %s on %s", mrouter ? "SP" : "LAP", dst); - - if (dun_sdp_search(&src_addr, bdaddr, &ch, mrouter) <= 0) - return 0; - } else - ch = channel; - - syslog(LOG_INFO, "Connecting to %s channel %d", dst, ch); - - sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); - if (sk < 0) { - syslog(LOG_ERR, "Cannot create RFCOMM socket. %s(%d)", - strerror(errno), errno); - return -1; - } - - sa.rc_family = AF_BLUETOOTH; - sa.rc_channel = 0; - sa.rc_bdaddr = src_addr; - - if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) - syslog(LOG_ERR, "Bind failed. %s(%d)", - strerror(errno), errno); - - sa.rc_channel = ch; - sa.rc_bdaddr = *bdaddr; - - if (!connect(sk, (struct sockaddr *) &sa, sizeof(sa)) ) { - if (mrouter) { - sleep(1); - close(sk); - return 0; - } - - syslog(LOG_INFO, "Connection established"); - - if (msdun && ms_dun(sk, 0, msdun) < 0) { - syslog(LOG_ERR, "MSDUN failed. %s(%d)", strerror(errno), errno); - err = 1; - goto out; - } - - if (!dun_open_connection(sk, pppd, pppd_opts, (persist > 0))) - err = 0; - else - err = 1; - } else { - syslog(LOG_ERR, "Connect to %s failed. %s(%d)", - dst, strerror(errno), errno); - err = 1; - } - -out: - if (use_cache) { - if (!err) { - /* Succesesful connection, validate cache */ - strcpy(cache.dst, dst); - bacpy(&cache.bdaddr, bdaddr); - cache.channel = ch; - cache.valid = use_cache; - } else { - cache.channel = 0; - cache.valid--; - } - } - - close(sk); - return err; -} - -/* Search and connect - * Returns: - * -1 - critical error (exit persist mode) - * 1 - non critical error - * 0 - success - */ -static int do_connect(void) -{ - inquiry_info *ii; - int reconnect = 0; - int i, n, r = 0; - - do { - if (reconnect) - sleep(persist); - reconnect = 1; - - if (cache.valid) { - /* Use cached bdaddr */ - r = create_connection(cache.dst, &cache.bdaddr, 0); - if (r < 0) { - terminate = 1; - break; - } - continue; - } - - syslog(LOG_INFO, "Inquiring"); - - /* FIXME: Should we use non general LAP here ? */ - - ii = NULL; - n = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0); - if (n < 0) { - syslog(LOG_ERR, "Inquiry failed. %s(%d)", strerror(errno), errno); - continue; - } - - for (i = 0; i < n; i++) { - char dst[40]; - ba2str(&ii[i].bdaddr, dst); - - r = create_connection(dst, &ii[i].bdaddr, 0); - if (r < 0) { - terminate = 1; - break; - } - } - bt_free(ii); - } while (!terminate && persist); - - return r; -} - -static void do_show(void) -{ - dun_show_connections(); -} - -static void do_kill(char *dst) -{ - if (dst) { - bdaddr_t ba; - str2ba(dst, &ba); - dun_kill_connection((void *) &ba); - } else - dun_kill_all_connections(); -} - -static void sig_hup(int sig) -{ - return; -} - -static void sig_term(int sig) -{ - io_cancel(); - terminate = 1; -} - -static struct option main_lopts[] = { - { "help", 0, 0, 'h' }, - { "listen", 0, 0, 's' }, - { "connect", 1, 0, 'c' }, - { "search", 2, 0, 'Q' }, - { "kill", 1, 0, 'k' }, - { "killall", 0, 0, 'K' }, - { "channel", 1, 0, 'P' }, - { "device", 1, 0, 'i' }, - { "nosdp", 0, 0, 'D' }, - { "list", 0, 0, 'l' }, - { "show", 0, 0, 'l' }, - { "nodetach", 0, 0, 'n' }, - { "persist", 2, 0, 'p' }, - { "auth", 0, 0, 'A' }, - { "encrypt", 0, 0, 'E' }, - { "secure", 0, 0, 'S' }, - { "master", 0, 0, 'M' }, - { "cache", 0, 0, 'C' }, - { "pppd", 1, 0, 'd' }, - { "msdun", 2, 0, 'X' }, - { "activesync", 0, 0, 'a' }, - { "mrouter", 1, 0, 'm' }, - { "dialup", 0, 0, 'u' }, - { 0, 0, 0, 0 } -}; - -static const char *main_sopts = "hsc:k:Kr:i:lnp::DQ::AESMP:C::P:Xam:u"; - -static const char *main_help = - "Bluetooth LAP (LAN Access over PPP) daemon version %s\n" - "Usage:\n" - "\tdund <options> [pppd options]\n" - "Options:\n" - "\t--show --list -l Show active LAP connections\n" - "\t--listen -s Listen for LAP connections\n" - "\t--dialup -u Pretend to be a dialup/telephone\n" - "\t--connect -c <bdaddr> Create LAP connection\n" - "\t--mrouter -m <bdaddr> Create mRouter connection\n" - "\t--search -Q[duration] Search and connect\n" - "\t--kill -k <bdaddr> Kill LAP connection\n" - "\t--killall -K Kill all LAP connections\n" - "\t--channel -P <channel> RFCOMM channel\n" - "\t--device -i <bdaddr> Source bdaddr\n" - "\t--nosdp -D Disable SDP\n" - "\t--auth -A Enable authentication\n" - "\t--encrypt -E Enable encryption\n" - "\t--secure -S Secure connection\n" - "\t--master -M Become the master of a piconet\n" - "\t--nodetach -n Do not become a daemon\n" - "\t--persist -p[interval] Persist mode\n" - "\t--pppd -d <pppd> Location of the PPP daemon (pppd)\n" - "\t--msdun -X[timeo] Enable Microsoft dialup networking support\n" - "\t--activesync -a Enable Microsoft ActiveSync networking\n" - "\t--cache -C[valid] Enable address cache\n"; - -int main(int argc, char *argv[]) -{ - char *dst = NULL, *src = NULL; - struct sigaction sa; - int mode = NONE; - int opt; - - while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) { - switch(opt) { - case 'l': - mode = SHOW; - detach = 0; - break; - - case 's': - mode = LISTEN; - type = LANACCESS; - break; - - case 'c': - mode = CONNECT; - dst = strdup(optarg); - break; - - case 'Q': - mode = CONNECT; - dst = NULL; - if (optarg) - search_duration = atoi(optarg); - break; - - case 'k': - mode = KILL; - detach = 0; - dst = strdup(optarg); - break; - - case 'K': - mode = KILL; - detach = 0; - dst = NULL; - break; - - case 'P': - channel = atoi(optarg); - break; - - case 'i': - src = strdup(optarg); - break; - - case 'D': - use_sdp = 0; - break; - - case 'A': - auth = 1; - break; - - case 'E': - encrypt = 1; - break; - - case 'S': - secure = 1; - break; - - case 'M': - master = 1; - break; - - case 'n': - detach = 0; - break; - - case 'p': - if (optarg) - persist = atoi(optarg); - else - persist = 5; - break; - - case 'C': - if (optarg) - use_cache = atoi(optarg); - else - use_cache = 2; - break; - - case 'd': - pppd = strdup(optarg); - break; - - case 'X': - if (optarg) - msdun = atoi(optarg); - else - msdun = 10; - break; - - case 'a': - msdun = 10; - type = ACTIVESYNC; - break; - - case 'm': - mode = LISTEN; - dst = strdup(optarg); - type = MROUTER; - break; - - case 'u': - mode = LISTEN; - type = DIALUP; - break; - - case 'h': - default: - printf(main_help, VERSION); - exit(0); - } - } - - argc -= optind; - argv += optind; - - /* The rest is pppd options */ - if (argc > 0) { - for (opt = 3; argc && opt < DUN_MAX_PPP_OPTS - 1; - argc--, opt++) - pppd_opts[opt] = *argv++; - pppd_opts[opt] = NULL; - } - - io_init(); - - if (dun_init()) { - free(dst); - return -1; - } - - /* Check non daemon modes first */ - switch (mode) { - case SHOW: - do_show(); - free(dst); - return 0; - - case KILL: - do_kill(dst); - free(dst); - return 0; - - case NONE: - printf(main_help, VERSION); - free(dst); - return 0; - } - - /* Initialize signals */ - 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); - - if (detach && daemon(0, 0)) { - perror("Can't start daemon"); - exit(1); - } - - openlog("dund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "Bluetooth DUN daemon version %s", VERSION); - - if (src) { - src_dev = hci_devid(src); - if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) { - syslog(LOG_ERR, "Invalid source. %s(%d)", strerror(errno), errno); - free(dst); - return -1; - } - } - - if (dst) { - strncpy(cache.dst, dst, sizeof(cache.dst) - 1); - str2ba(dst, &cache.bdaddr); - - /* Disable cache invalidation */ - use_cache = cache.valid = ~0; - } - - switch (mode) { - case CONNECT: - do_connect(); - break; - - case LISTEN: - do_listen(); - break; - } - - free(dst); - return 0; -} diff --git a/compat/dund.h b/compat/dund.h deleted file mode 100644 index e3a4ef6a3..000000000 --- a/compat/dund.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2010 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 - * - */ - -#define DUN_CONFIG_DIR "/etc/bluetooth/dun" - -#define DUN_DEFAULT_CHANNEL 1 - -#define DUN_MAX_PPP_OPTS 40 - -int dun_init(void); -int dun_cleanup(void); - -int dun_show_connections(void); -int dun_kill_connection(uint8_t *dst); -int dun_kill_all_connections(void); - -int dun_open_connection(int sk, char *pppd, char **pppd_opts, int wait); - -int ms_dun(int fd, int server, int timeo); diff --git a/compat/fakehid.c b/compat/fakehid.c deleted file mode 100644 index 66161b3f7..000000000 --- a/compat/fakehid.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2003-2010 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 - -#define _GNU_SOURCE -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <signal.h> -#include <sys/poll.h> -#include <sys/ioctl.h> -#include <sys/socket.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/rfcomm.h> -#include <bluetooth/hidp.h> - -#include "hidd.h" -#include "uinput.h" - -#include <math.h> - -#ifdef NEED_PPOLL -#include "ppoll.h" -#endif - -static volatile sig_atomic_t __io_canceled = 0; - -static void sig_hup(int sig) -{ -} - -static void sig_term(int sig) -{ - __io_canceled = 1; -} - -static int send_event(int fd, uint16_t type, uint16_t code, int32_t value) -{ - struct uinput_event event; - - if (fd <= fileno(stderr)) - return -EINVAL; - - memset(&event, 0, sizeof(event)); - event.type = type; - event.code = code; - event.value = value; - - return write(fd, &event, sizeof(event)); -} - -static int uinput_create(char *name, int keyboard, int mouse) -{ - struct uinput_dev dev; - int fd, aux; - - fd = open("/dev/uinput", O_RDWR); - if (fd < 0) { - fd = open("/dev/input/uinput", O_RDWR); - if (fd < 0) { - fd = open("/dev/misc/uinput", O_RDWR); - if (fd < 0) { - fprintf(stderr, "Can't open input device: %s (%d)\n", - strerror(errno), errno); - return -1; - } - } - } - - memset(&dev, 0, sizeof(dev)); - - if (name) - strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE - 1); - - dev.id.bustype = BUS_BLUETOOTH; - dev.id.vendor = 0x0000; - dev.id.product = 0x0000; - dev.id.version = 0x0000; - - if (write(fd, &dev, sizeof(dev)) < 0) { - fprintf(stderr, "Can't write device information: %s (%d)\n", - strerror(errno), errno); - close(fd); - return -1; - } - - if (mouse) { - ioctl(fd, UI_SET_EVBIT, EV_REL); - - for (aux = REL_X; aux <= REL_MISC; aux++) - ioctl(fd, UI_SET_RELBIT, aux); - } - - if (keyboard) { - ioctl(fd, UI_SET_EVBIT, EV_KEY); - ioctl(fd, UI_SET_EVBIT, EV_LED); - ioctl(fd, UI_SET_EVBIT, EV_REP); - - for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++) - ioctl(fd, UI_SET_KEYBIT, aux); - /* - *for (aux = LED_NUML; aux <= LED_MISC; aux++) - * ioctl(fd, UI_SET_LEDBIT, aux); - */ - } - - if (mouse) { - ioctl(fd, UI_SET_EVBIT, EV_KEY); - - for (aux = BTN_LEFT; aux <= BTN_BACK; aux++) - ioctl(fd, UI_SET_KEYBIT, aux); - } - - ioctl(fd, UI_DEV_CREATE); - - return fd; -} - -static int rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - struct sockaddr_rc addr; - int sk; - - sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); - if (sk < 0) { - fprintf(stderr, "Can't create socket: %s (%d)\n", - strerror(errno), errno); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.rc_family = AF_BLUETOOTH; - bacpy(&addr.rc_bdaddr, src); - - if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - fprintf(stderr, "Can't bind socket: %s (%d)\n", - strerror(errno), errno); - close(sk); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.rc_family = AF_BLUETOOTH; - bacpy(&addr.rc_bdaddr, dst); - addr.rc_channel = channel; - - if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - fprintf(stderr, "Can't connect: %s (%d)\n", - strerror(errno), errno); - close(sk); - return -1; - } - - return sk; -} - -static void func(int fd) -{ -} - -static void back(int fd) -{ -} - -static void next(int fd) -{ -} - -static void button(int fd, unsigned int button, int is_press) -{ - switch (button) { - case 1: - send_event(fd, EV_KEY, BTN_LEFT, is_press); - break; - case 3: - send_event(fd, EV_KEY, BTN_RIGHT, is_press); - break; - } - - send_event(fd, EV_SYN, SYN_REPORT, 0); -} - -static void move(int fd, unsigned int direction) -{ - double angle; - int32_t x, y; - - angle = (direction * 22.5) * 3.1415926 / 180; - x = (int) (sin(angle) * 8); - y = (int) (cos(angle) * -8); - - send_event(fd, EV_REL, REL_X, x); - send_event(fd, EV_REL, REL_Y, y); - - send_event(fd, EV_SYN, SYN_REPORT, 0); -} - -static inline void epox_decode(int fd, unsigned char event) -{ - switch (event) { - case 48: - func(fd); break; - case 55: - back(fd); break; - case 56: - next(fd); break; - case 53: - button(fd, 1, 1); break; - case 121: - button(fd, 1, 0); break; - case 113: - break; - case 54: - button(fd, 3, 1); break; - case 120: - button(fd, 3, 0); break; - case 112: - break; - case 51: - move(fd, 0); break; - case 97: - move(fd, 1); break; - case 65: - move(fd, 2); break; - case 98: - move(fd, 3); break; - case 50: - move(fd, 4); break; - case 99: - move(fd, 5); break; - case 67: - move(fd, 6); break; - case 101: - move(fd, 7); break; - case 52: - move(fd, 8); break; - case 100: - move(fd, 9); break; - case 66: - move(fd, 10); break; - case 102: - move(fd, 11); break; - case 49: - move(fd, 12); break; - case 103: - move(fd, 13); break; - case 57: - move(fd, 14); break; - case 104: - move(fd, 15); break; - case 69: - break; - default: - printf("Unknown event code %d\n", event); - break; - } -} - -int epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - unsigned char buf[16]; - struct sigaction sa; - struct pollfd p; - sigset_t sigs; - char addr[18]; - int i, fd, sk, len; - - sk = rfcomm_connect(src, dst, channel); - if (sk < 0) - return -1; - - fd = uinput_create("Bluetooth Presenter", 0, 1); - if (fd < 0) { - close(sk); - return -1; - } - - ba2str(dst, addr); - - printf("Connected to %s on channel %d\n", addr, channel); - printf("Press CTRL-C for hangup\n"); - - 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); - - sigfillset(&sigs); - sigdelset(&sigs, SIGCHLD); - sigdelset(&sigs, SIGPIPE); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - p.fd = sk; - p.events = POLLIN | POLLERR | POLLHUP; - - while (!__io_canceled) { - p.revents = 0; - if (ppoll(&p, 1, NULL, &sigs) < 1) - continue; - - len = read(sk, buf, sizeof(buf)); - if (len < 0) - break; - - for (i = 0; i < len; i++) - epox_decode(fd, buf[i]); - } - - printf("Disconnected\n"); - - ioctl(fd, UI_DEV_DESTROY); - - close(fd); - close(sk); - - return 0; -} - -int headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - printf("Not implemented\n"); - return -1; -} - -/* The strange meta key close to Ctrl has been assigned to Esc, - Fn key to CtrlR and the left space to Alt*/ - -static unsigned char jthree_keycodes[63] = { - KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, - KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, - KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, - KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, - KEY_LEFTALT, KEY_TAB, KEY_CAPSLOCK, KEY_ESC, - KEY_7, KEY_8, KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, - KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, - KEY_H, KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, - KEY_N, KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH, KEY_UP, - KEY_SPACE, KEY_COMPOSE, KEY_LEFT, KEY_DOWN, KEY_RIGHT, - KEY_LEFTCTRL, KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_DELETE, KEY_RIGHTCTRL, KEY_RIGHTALT, -}; - -static inline void jthree_decode(int fd, unsigned char event) -{ - if (event > 63) - send_event(fd, EV_KEY, jthree_keycodes[event & 0x3f], 0); - else - send_event(fd, EV_KEY, jthree_keycodes[event - 1], 1); -} - -int jthree_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - unsigned char buf[16]; - struct sigaction sa; - struct pollfd p; - sigset_t sigs; - char addr[18]; - int i, fd, sk, len; - - sk = rfcomm_connect(src, dst, channel); - if (sk < 0) - return -1; - - fd = uinput_create("J-Three Keyboard", 1, 0); - if (fd < 0) { - close(sk); - return -1; - } - - ba2str(dst, addr); - - printf("Connected to %s on channel %d\n", addr, channel); - printf("Press CTRL-C for hangup\n"); - - 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); - - sigfillset(&sigs); - sigdelset(&sigs, SIGCHLD); - sigdelset(&sigs, SIGPIPE); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - p.fd = sk; - p.events = POLLIN | POLLERR | POLLHUP; - - while (!__io_canceled) { - p.revents = 0; - if (ppoll(&p, 1, NULL, &sigs) < 1) - continue; - - len = read(sk, buf, sizeof(buf)); - if (len < 0) - break; - - for (i = 0; i < len; i++) - jthree_decode(fd, buf[i]); - } - - printf("Disconnected\n"); - - ioctl(fd, UI_DEV_DESTROY); - - close(fd); - close(sk); - - return 0; -} - -static const int celluon_xlate_num[10] = { - KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 -}; - -static const int celluon_xlate_char[26] = { - KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, - KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, - KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z -}; - -static int celluon_xlate(int c) -{ - if (c >= '0' && c <= '9') - return celluon_xlate_num[c - '0']; - - if (c >= 'A' && c <= 'Z') - return celluon_xlate_char[c - 'A']; - - switch (c) { - case 0x08: - return KEY_BACKSPACE; - case 0x09: - return KEY_TAB; - case 0x0d: - return KEY_ENTER; - case 0x11: - return KEY_LEFTCTRL; - case 0x14: - return KEY_CAPSLOCK; - case 0x20: - return KEY_SPACE; - case 0x25: - return KEY_LEFT; - case 0x26: - return KEY_UP; - case 0x27: - return KEY_RIGHT; - case 0x28: - return KEY_DOWN; - case 0x2e: - return KEY_DELETE; - case 0x5b: - return KEY_MENU; - case 0xa1: - return KEY_RIGHTSHIFT; - case 0xa0: - return KEY_LEFTSHIFT; - case 0xba: - return KEY_SEMICOLON; - case 0xbd: - return KEY_MINUS; - case 0xbc: - return KEY_COMMA; - case 0xbb: - return KEY_EQUAL; - case 0xbe: - return KEY_DOT; - case 0xbf: - return KEY_SLASH; - case 0xc0: - return KEY_GRAVE; - case 0xdb: - return KEY_LEFTBRACE; - case 0xdc: - return KEY_BACKSLASH; - case 0xdd: - return KEY_RIGHTBRACE; - case 0xde: - return KEY_APOSTROPHE; - case 0xff03: - return KEY_HOMEPAGE; - case 0xff04: - return KEY_TIME; - case 0xff06: - return KEY_OPEN; - case 0xff07: - return KEY_LIST; - case 0xff08: - return KEY_MAIL; - case 0xff30: - return KEY_CALC; - case 0xff1a: /* Map FN to ALT */ - return KEY_LEFTALT; - case 0xff2f: - return KEY_INFO; - default: - printf("Unknown key %x\n", c); - return c; - } -} - -struct celluon_state { - int len; /* Expected length of current packet */ - int count; /* Number of bytes received */ - int action; - int key; -}; - -static void celluon_decode(int fd, struct celluon_state *s, uint8_t c) -{ - if (s->count < 2 && c != 0xa5) { - /* Lost Sync */ - s->count = 0; - return; - } - - switch (s->count) { - case 0: - /* New packet - Reset state */ - s->len = 30; - s->key = 0; - break; - case 1: - break; - case 6: - s->action = c; - break; - case 28: - s->key = c; - if (c == 0xff) - s->len = 31; - break; - case 29: - case 30: - if (s->count == s->len - 1) { - /* TODO: Verify checksum */ - if (s->action < 2) { - send_event(fd, EV_KEY, celluon_xlate(s->key), - s->action); - } - s->count = -1; - } else { - s->key = (s->key << 8) | c; - } - break; - } - - s->count++; - - return; -} - -int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) -{ - unsigned char buf[16]; - struct sigaction sa; - struct pollfd p; - sigset_t sigs; - char addr[18]; - int i, fd, sk, len; - struct celluon_state s; - - sk = rfcomm_connect(src, dst, channel); - if (sk < 0) - return -1; - - fd = uinput_create("Celluon Keyboard", 1, 0); - if (fd < 0) { - close(sk); - return -1; - } - - ba2str(dst, addr); - - printf("Connected to %s on channel %d\n", addr, channel); - printf("Press CTRL-C for hangup\n"); - - 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); - - sigfillset(&sigs); - sigdelset(&sigs, SIGCHLD); - sigdelset(&sigs, SIGPIPE); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - p.fd = sk; - p.events = POLLIN | POLLERR | POLLHUP; - - memset(&s, 0, sizeof(s)); - - while (!__io_canceled) { - p.revents = 0; - if (ppoll(&p, 1, NULL, &sigs) < 1) - continue; - - len = read(sk, buf, sizeof(buf)); - if (len < 0) - break; - - for (i = 0; i < len; i++) - celluon_decode(fd, &s, buf[i]); - } - - printf("Disconnected\n"); - - ioctl(fd, UI_DEV_DESTROY); - - close(fd); - close(sk); - - return 0; -} diff --git a/compat/fakehid.txt b/compat/fakehid.txt deleted file mode 100644 index 000d0ee2f..000000000 --- a/compat/fakehid.txt +++ /dev/null @@ -1,134 +0,0 @@ -EPox Presenter -============== - -# hcitool inq -Inquiring ... - 00:04:61:aa:bb:cc clock offset: 0x1ded class: 0x004000 - -# hcitool info 00:04:61:aa:bb:cc -Requesting information ... - BD Address: 00:04:61:aa:bb:cc - OUI Company: EPOX Computer Co., Ltd. (00-04-61) - Device Name: EPox BT-PM01B aabbcc - LMP Version: 1.1 (0x1) LMP Subversion: 0xf78 - Manufacturer: Cambridge Silicon Radio (10) - Features: 0xff 0xff 0x0f 0x00 0x00 0x00 0x00 0x00 - <3-slot packets> <5-slot packets> <encryption> <slot offset> - <timing accuracy> <role switch> <hold mode> <sniff mode> - <park state> <RSSI> <channel quality> <SCO link> <HV2 packets> - <HV3 packets> <u-law log> <A-law log> <CVSD> <paging scheme> - <power control> <transparent SCO> - -# sdptool records --raw 00:04:61:aa:bb:cc -Sequence - Attribute 0x0000 - ServiceRecordHandle - UINT32 0x00010000 - Attribute 0x0001 - ServiceClassIDList - Sequence - UUID16 0x1101 - SerialPort - Attribute 0x0004 - ProtocolDescriptorList - Sequence - Sequence - UUID16 0x0100 - L2CAP - Sequence - UUID16 0x0003 - RFCOMM - UINT8 0x01 - Attribute 0x0100 - String Cable Replacement - - -J-Three Keyboard -================ - -# hcitool inq -Inquiring ... - 00:0A:3A:aa:bb:cc clock offset: 0x3039 class: 0x001f00 - -# hcitool info 00:0A:3A:aa:bb:cc -Password: -Requesting information ... - BD Address: 00:0A:3A:aa:bb:cc - OUI Company: J-THREE INTERNATIONAL Holding Co., Ltd. (00-0A-3A) - Device Name: KEYBOARD - LMP Version: 1.1 (0x1) LMP Subversion: 0x2c2 - Manufacturer: Cambridge Silicon Radio (10) - Features: 0xbc 0x06 0x07 0x00 0x00 0x00 0x00 0x00 - <encryption> <slot offset> <timing accuracy> <role switch> - <sniff mode> <RSSI> <channel quality> <CVSD> <paging scheme> - <power control> - -# sdptool records --raw 00:0A:3A:aa:bb:cc -Sequence - Attribute 0x0000 - ServiceRecordHandle - UINT32 0x00010000 - Attribute 0x0001 - ServiceClassIDList - Sequence - UUID16 0x1101 - SerialPort - Attribute 0x0004 - ProtocolDescriptorList - Sequence - Sequence - UUID16 0x0100 - L2CAP - Sequence - UUID16 0x0003 - RFCOMM - UINT8 0x01 - Attribute 0x0006 - LanguageBaseAttributeIDList - Sequence - UINT16 0x656e - UINT16 0x006a - UINT16 0x0100 - Attribute 0x0100 - String SPP slave - - -Celluon Laserkey Keyboard -========================= - -# hcitool inq -Inquiring ... - 00:0B:24:aa:bb:cc clock offset: 0x3ab6 class: 0x400210 - -# hcitool info 00:0B:24:aa:bb:cc -Requesting information ... - BD Address: 00:0B:24:aa:bb:cc - OUI Company: AirLogic (00-0B-24) - Device Name: CL800BT - LMP Version: 1.1 (0x1) LMP Subversion: 0x291 - Manufacturer: Cambridge Silicon Radio (10) - Features: 0xff 0xff 0x0f 0x00 0x00 0x00 0x00 0x00 - <3-slot packets> <5-slot packets> <encryption> <slot offset> - <timing accuracy> <role switch> <hold mode> <sniff mode> - <park state> <RSSI> <channel quality> <SCO link> <HV2 packets> - <HV3 packets> <u-law log> <A-law log> <CVSD> <paging scheme> - <power control> <transparent SCO> - -# sdptool records --raw 00:0B:24:aa:bb:cc -Sequence - Attribute 0x0000 - ServiceRecordHandle - UINT32 0x00010000 - Attribute 0x0001 - ServiceClassIDList - Sequence - UUID16 0x1101 - SerialPort - Attribute 0x0004 - ProtocolDescriptorList - Sequence - Sequence - UUID16 0x0100 - L2CAP - Sequence - UUID16 0x0003 - RFCOMM - UINT8 0x01 - Attribute 0x0100 - String Serial Port - -Packet format is as follows (all fields little-endian): - 0 uint16 magic # 0x5a5a - 2 uint32 unknown # ??? - 6 uint8 action # 0 = keyup, 1 = keydown, 2 = repeat - # 3, 4, 5, 6 = ??? (Mouse mode) - 7 uint8 unknown[9] # ??? - 16 uint8 action2 # ??? same as action - 17 uint16 x # Horizontal coordinate - 19 uint16 y # Vertical coordinate - 21 uint16 time # Some sort of timestamp - 23 uint8 unknown[5] # ??? - 28 uint8 key[] # single byte keycode or 0xff byte - # follwed by special keycode byte. - Each packet followed by a checksum byte. diff --git a/compat/hidd.1 b/compat/hidd.1 deleted file mode 100644 index b186ac247..000000000 --- a/compat/hidd.1 +++ /dev/null @@ -1,41 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33. -.TH HIDD "1" "May 2004" "hidd - Bluetooth HID daemon" "User Commands" -.SH NAME -hidd \- Bluetooth HID daemon -.SH DESCRIPTION -hidd - Bluetooth HID daemon -.SS "Usage:" -.IP -hidd [options] [commands] -.SH OPTIONS -.TP -\fB\-i\fR <hciX|bdaddr> -Local HCI device or BD Address -.TP -\fB\-t\fR <timeout> -Set idle timeout (in minutes) -.TP -\fB\-n\fR, \fB\-\-nodaemon\fR -Don't fork daemon to background -.TP -\fB\-h\fR, \fB\-\-help\fR -Display help -.SS "Commands:" -.TP -\fB\-\-server\fR -Start HID server -.TP -\fB\-\-search\fR -Search for HID devices -.TP -\fB\-\-connect\fR <bdaddr> -Connect remote HID device -.TP -\fB\-\-kill\fR <bdaddr> -Terminate HID connection -.TP -\fB\-\-killall\fR -Terminate all connections -.TP -\fB\-\-show\fR -List current HID connections diff --git a/compat/hidd.c b/compat/hidd.c deleted file mode 100644 index f8a0dfd5a..000000000 --- a/compat/hidd.c +++ /dev/null @@ -1,848 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2003-2010 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 - -#define _GNU_SOURCE -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <signal.h> -#include <getopt.h> -#include <sys/poll.h> -#include <sys/ioctl.h> -#include <sys/socket.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/hci.h> -#include <bluetooth/hci_lib.h> -#include <bluetooth/l2cap.h> -#include <bluetooth/sdp.h> -#include <bluetooth/hidp.h> - -#include "sdp.h" -#include "hidd.h" - -#ifdef NEED_PPOLL -#include "ppoll.h" -#endif - -enum { - NONE, - SHOW, - SERVER, - SEARCH, - CONNECT, - KILL -}; - -static volatile sig_atomic_t __io_canceled = 0; - -static void sig_hup(int sig) -{ -} - -static void sig_term(int sig) -{ - __io_canceled = 1; -} - -static int l2cap_connect(bdaddr_t *src, bdaddr_t *dst, unsigned short psm) -{ - struct sockaddr_l2 addr; - struct l2cap_options opts; - int sk; - - if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) - return -1; - - memset(&addr, 0, sizeof(addr)); - addr.l2_family = AF_BLUETOOTH; - bacpy(&addr.l2_bdaddr, src); - - if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(sk); - return -1; - } - - memset(&opts, 0, sizeof(opts)); - opts.imtu = HIDP_DEFAULT_MTU; - opts.omtu = HIDP_DEFAULT_MTU; - opts.flush_to = 0xffff; - - setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)); - - memset(&addr, 0, sizeof(addr)); - addr.l2_family = AF_BLUETOOTH; - bacpy(&addr.l2_bdaddr, dst); - addr.l2_psm = htobs(psm); - - if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(sk); - return -1; - } - - return sk; -} - -static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int lm, int backlog) -{ - struct sockaddr_l2 addr; - struct l2cap_options opts; - int sk; - - if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) - return -1; - - memset(&addr, 0, sizeof(addr)); - addr.l2_family = AF_BLUETOOTH; - bacpy(&addr.l2_bdaddr, bdaddr); - addr.l2_psm = htobs(psm); - - if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(sk); - return -1; - } - - setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)); - - memset(&opts, 0, sizeof(opts)); - opts.imtu = HIDP_DEFAULT_MTU; - opts.omtu = HIDP_DEFAULT_MTU; - opts.flush_to = 0xffff; - - setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)); - - if (listen(sk, backlog) < 0) { - close(sk); - return -1; - } - - return sk; -} - -static int l2cap_accept(int sk, bdaddr_t *bdaddr) -{ - struct sockaddr_l2 addr; - socklen_t addrlen; - int nsk; - - memset(&addr, 0, sizeof(addr)); - addrlen = sizeof(addr); - - if ((nsk = accept(sk, (struct sockaddr *) &addr, &addrlen)) < 0) - return -1; - - if (bdaddr) - bacpy(bdaddr, &addr.l2_bdaddr); - - return nsk; -} - -static int request_authentication(bdaddr_t *src, bdaddr_t *dst) -{ - struct hci_conn_info_req *cr; - char addr[18]; - int err, dd, dev_id; - - ba2str(src, addr); - dev_id = hci_devid(addr); - if (dev_id < 0) - return dev_id; - - dd = hci_open_dev(dev_id); - if (dd < 0) - return dd; - - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return -ENOMEM; - - bacpy(&cr->bdaddr, dst); - cr->type = ACL_LINK; - err = ioctl(dd, HCIGETCONNINFO, (unsigned long) cr); - if (err < 0) { - free(cr); - hci_close_dev(dd); - return err; - } - - err = hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000); - - free(cr); - hci_close_dev(dd); - - return err; -} - -static int request_encryption(bdaddr_t *src, bdaddr_t *dst) -{ - struct hci_conn_info_req *cr; - char addr[18]; - int err, dd, dev_id; - - ba2str(src, addr); - dev_id = hci_devid(addr); - if (dev_id < 0) - return dev_id; - - dd = hci_open_dev(dev_id); - if (dd < 0) - return dd; - - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return -ENOMEM; - - bacpy(&cr->bdaddr, dst); - cr->type = ACL_LINK; - err = ioctl(dd, HCIGETCONNINFO, (unsigned long) cr); - if (err < 0) { - free(cr); - hci_close_dev(dd); - return err; - } - - err = hci_encrypt_link(dd, htobs(cr->conn_info->handle), 1, 25000); - - free(cr); - hci_close_dev(dd); - - return err; -} - -static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int nocheck, int bootonly, int encrypt, int timeout) -{ - struct hidp_connadd_req req; - struct sockaddr_l2 addr; - socklen_t addrlen; - bdaddr_t src, dst; - char bda[18]; - int err; - - memset(&addr, 0, sizeof(addr)); - addrlen = sizeof(addr); - - if (getsockname(csk, (struct sockaddr *) &addr, &addrlen) < 0) - return -1; - - bacpy(&src, &addr.l2_bdaddr); - - memset(&addr, 0, sizeof(addr)); - addrlen = sizeof(addr); - - if (getpeername(csk, (struct sockaddr *) &addr, &addrlen) < 0) - return -1; - - bacpy(&dst, &addr.l2_bdaddr); - - memset(&req, 0, sizeof(req)); - req.ctrl_sock = csk; - req.intr_sock = isk; - req.flags = 0; - req.idle_to = timeout * 60; - - err = get_stored_device_info(&src, &dst, &req); - if (!err) - goto create; - - if (!nocheck) { - ba2str(&dst, bda); - syslog(LOG_ERR, "Rejected connection from unknown device %s", bda); - /* Return no error to avoid run_server() complaining too */ - return 0; - } - - if (!nosdp) { - err = get_sdp_device_info(&src, &dst, &req); - if (err < 0) - goto error; - } else { - struct l2cap_conninfo conn; - socklen_t size; - uint8_t class[3]; - - memset(&conn, 0, sizeof(conn)); - size = sizeof(conn); - if (getsockopt(csk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &size) < 0) - memset(class, 0, 3); - else - memcpy(class, conn.dev_class, 3); - - if (class[1] == 0x25 && (class[2] == 0x00 || class[2] == 0x01)) - req.subclass = class[0]; - else - req.subclass = 0xc0; - } - -create: - if (subclass != 0x00) - req.subclass = subclass; - - ba2str(&dst, bda); - syslog(LOG_INFO, "New HID device %s (%s)", bda, req.name); - - if (encrypt && (req.subclass & 0x40)) { - err = request_authentication(&src, &dst); - if (err < 0) { - syslog(LOG_ERR, "Authentication for %s failed", bda); - goto error; - } - - err = request_encryption(&src, &dst); - if (err < 0) - syslog(LOG_ERR, "Encryption for %s failed", bda); - } - - if (bootonly) { - req.rd_size = 0; - req.flags |= (1 << HIDP_BOOT_PROTOCOL_MODE); - } - - err = ioctl(ctl, HIDPCONNADD, &req); - -error: - free(req.rd_data); - - return err; -} - -static void run_server(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int nocheck, int bootonly, int encrypt, int timeout) -{ - struct pollfd p[2]; - sigset_t sigs; - short events; - int err, ncsk, nisk; - - sigfillset(&sigs); - sigdelset(&sigs, SIGCHLD); - sigdelset(&sigs, SIGPIPE); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - p[0].fd = csk; - p[0].events = POLLIN | POLLERR | POLLHUP; - - p[1].fd = isk; - p[1].events = POLLIN | POLLERR | POLLHUP; - - while (!__io_canceled) { - p[0].revents = 0; - p[1].revents = 0; - - if (ppoll(p, 2, NULL, &sigs) < 1) - continue; - - events = p[0].revents | p[1].revents; - - if (events & POLLIN) { - ncsk = l2cap_accept(csk, NULL); - nisk = l2cap_accept(isk, NULL); - - err = create_device(ctl, ncsk, nisk, subclass, nosdp, nocheck, bootonly, encrypt, timeout); - if (err < 0) - syslog(LOG_ERR, "HID create error %d (%s)", - errno, strerror(errno)); - - close(nisk); - sleep(1); - close(ncsk); - } - } -} - -static char *hidp_state[] = { - "unknown", - "connected", - "open", - "bound", - "listening", - "connecting", - "connecting", - "config", - "disconnecting", - "closed" -}; - -static char *hidp_flagstostr(uint32_t flags) -{ - static char str[100]; - str[0] = 0; - - strcat(str, "["); - - if (flags & (1 << HIDP_BOOT_PROTOCOL_MODE)) - strcat(str, "boot-protocol"); - - strcat(str, "]"); - - return str; -} - -static void do_show(int ctl) -{ - struct hidp_connlist_req req; - struct hidp_conninfo ci[16]; - char addr[18]; - unsigned int i; - - req.cnum = 16; - req.ci = ci; - - if (ioctl(ctl, HIDPGETCONNLIST, &req) < 0) { - perror("Can't get connection list"); - close(ctl); - exit(1); - } - - for (i = 0; i < req.cnum; i++) { - ba2str(&ci[i].bdaddr, addr); - printf("%s %s [%04x:%04x] %s %s\n", addr, ci[i].name, - ci[i].vendor, ci[i].product, hidp_state[ci[i].state], - ci[i].flags ? hidp_flagstostr(ci[i].flags) : ""); - } -} - -static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int fakehid, int bootonly, int encrypt, int timeout) -{ - struct hidp_connadd_req req; - uint16_t uuid = HID_SVCLASS_ID; - uint8_t channel = 0; - char name[256]; - int csk, isk, err; - - memset(&req, 0, sizeof(req)); - name[0] = '\0'; - - err = get_sdp_device_info(src, dst, &req); - if (err < 0 && fakehid) - err = get_alternate_device_info(src, dst, - &uuid, &channel, name, sizeof(name) - 1); - - if (err < 0) { - perror("Can't get device information"); - close(ctl); - exit(1); - } - - switch (uuid) { - case HID_SVCLASS_ID: - goto connect; - - case SERIAL_PORT_SVCLASS_ID: - if (subclass == 0x40 || !strcmp(name, "Cable Replacement")) { - if (epox_presenter(src, dst, channel) < 0) { - close(ctl); - exit(1); - } - break; - } - if (subclass == 0x1f || !strcmp(name, "SPP slave")) { - if (jthree_keyboard(src, dst, channel) < 0) { - close(ctl); - exit(1); - } - break; - } - if (subclass == 0x02 || !strcmp(name, "Serial Port")) { - if (celluon_keyboard(src, dst, channel) < 0) { - close(ctl); - exit(1); - } - break; - } - break; - - case HEADSET_SVCLASS_ID: - case HANDSFREE_SVCLASS_ID: - if (headset_presenter(src, dst, channel) < 0) { - close(ctl); - exit(1); - } - break; - } - - return; - -connect: - csk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_CTRL); - if (csk < 0) { - perror("Can't create HID control channel"); - close(ctl); - exit(1); - } - - isk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_INTR); - if (isk < 0) { - perror("Can't create HID interrupt channel"); - close(csk); - close(ctl); - exit(1); - } - - err = create_device(ctl, csk, isk, subclass, 1, 1, bootonly, encrypt, timeout); - if (err < 0) { - fprintf(stderr, "HID create error %d (%s)\n", - errno, strerror(errno)); - close(isk); - sleep(1); - close(csk); - close(ctl); - exit(1); - } -} - -static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int fakehid, int bootonly, int encrypt, int timeout) -{ - inquiry_info *info = NULL; - bdaddr_t src, dst; - int i, dev_id, num_rsp, length, flags; - char addr[18]; - uint8_t class[3]; - - ba2str(bdaddr, addr); - dev_id = hci_devid(addr); - if (dev_id < 0) { - dev_id = hci_get_route(NULL); - hci_devba(dev_id, &src); - } else - bacpy(&src, bdaddr); - - length = 8; /* ~10 seconds */ - num_rsp = 0; - flags = IREQ_CACHE_FLUSH; - - printf("Searching ...\n"); - - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); - - for (i = 0; i < num_rsp; i++) { - memcpy(class, (info+i)->dev_class, 3); - if (class[1] == 0x25 && (class[2] == 0x00 || class[2] == 0x01)) { - bacpy(&dst, &(info+i)->bdaddr); - ba2str(&dst, addr); - - printf("\tConnecting to device %s\n", addr); - do_connect(ctl, &src, &dst, subclass, fakehid, bootonly, encrypt, timeout); - } - } - - if (!fakehid) - goto done; - - for (i = 0; i < num_rsp; i++) { - memcpy(class, (info+i)->dev_class, 3); - if ((class[0] == 0x00 && class[2] == 0x00 && - (class[1] == 0x40 || class[1] == 0x1f)) || - (class[0] == 0x10 && class[1] == 0x02 && class[2] == 0x40)) { - bacpy(&dst, &(info+i)->bdaddr); - ba2str(&dst, addr); - - printf("\tConnecting to device %s\n", addr); - do_connect(ctl, &src, &dst, subclass, 1, bootonly, 0, timeout); - } - } - -done: - bt_free(info); - - if (!num_rsp) { - fprintf(stderr, "\tNo devices in range or visible\n"); - close(ctl); - exit(1); - } -} - -static void do_kill(int ctl, bdaddr_t *bdaddr, uint32_t flags) -{ - struct hidp_conndel_req req; - struct hidp_connlist_req cl; - struct hidp_conninfo ci[16]; - unsigned int i; - - if (!bacmp(bdaddr, BDADDR_ALL)) { - cl.cnum = 16; - cl.ci = ci; - - if (ioctl(ctl, HIDPGETCONNLIST, &cl) < 0) { - perror("Can't get connection list"); - close(ctl); - exit(1); - } - - for (i = 0; i < cl.cnum; i++) { - bacpy(&req.bdaddr, &ci[i].bdaddr); - req.flags = flags; - - if (ioctl(ctl, HIDPCONNDEL, &req) < 0) { - perror("Can't release connection"); - close(ctl); - exit(1); - } - } - - } else { - bacpy(&req.bdaddr, bdaddr); - req.flags = flags; - - if (ioctl(ctl, HIDPCONNDEL, &req) < 0) { - perror("Can't release connection"); - close(ctl); - exit(1); - } - } -} - -static void usage(void) -{ - printf("hidd - Bluetooth HID daemon version %s\n\n", VERSION); - - printf("Usage:\n" - "\thidd [options] [commands]\n" - "\n"); - - printf("Options:\n" - "\t-i <hciX|bdaddr> Local HCI device or BD Address\n" - "\t-t <timeout> Set idle timeout (in minutes)\n" - "\t-b <subclass> Overwrite the boot mode subclass\n" - "\t-n, --nodaemon Don't fork daemon to background\n" - "\t-h, --help Display help\n" - "\n"); - - printf("Commands:\n" - "\t--server Start HID server\n" - "\t--search Search for HID devices\n" - "\t--connect <bdaddr> Connect remote HID device\n" - "\t--unplug <bdaddr> Unplug the HID connection\n" - "\t--kill <bdaddr> Terminate HID connection\n" - "\t--killall Terminate all connections\n" - "\t--show List current HID connections\n" - "\n"); -} - -static struct option main_options[] = { - { "help", 0, 0, 'h' }, - { "nodaemon", 0, 0, 'n' }, - { "subclass", 1, 0, 'b' }, - { "timeout", 1, 0, 't' }, - { "device", 1, 0, 'i' }, - { "master", 0, 0, 'M' }, - { "encrypt", 0, 0, 'E' }, - { "nosdp", 0, 0, 'D' }, - { "nocheck", 0, 0, 'Z' }, - { "bootonly", 0, 0, 'B' }, - { "hidonly", 0, 0, 'H' }, - { "show", 0, 0, 'l' }, - { "list", 0, 0, 'l' }, - { "server", 0, 0, 'd' }, - { "listen", 0, 0, 'd' }, - { "search", 0, 0, 's' }, - { "create", 1, 0, 'c' }, - { "connect", 1, 0, 'c' }, - { "disconnect", 1, 0, 'k' }, - { "terminate", 1, 0, 'k' }, - { "release", 1, 0, 'k' }, - { "kill", 1, 0, 'k' }, - { "killall", 0, 0, 'K' }, - { "unplug", 1, 0, 'u' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char *argv[]) -{ - struct sigaction sa; - bdaddr_t bdaddr, dev; - uint32_t flags = 0; - uint8_t subclass = 0x00; - char addr[18]; - int log_option = LOG_NDELAY | LOG_PID; - int opt, ctl, csk, isk; - int mode = SHOW, detach = 1, nosdp = 0, nocheck = 0, bootonly = 0; - int fakehid = 1, encrypt = 0, timeout = 30, lm = 0; - - bacpy(&bdaddr, BDADDR_ANY); - - while ((opt = getopt_long(argc, argv, "+i:nt:b:MEDZBHldsc:k:Ku:h", main_options, NULL)) != -1) { - switch(opt) { - case 'i': - if (!strncasecmp(optarg, "hci", 3)) - hci_devba(atoi(optarg + 3), &bdaddr); - else - str2ba(optarg, &bdaddr); - break; - case 'n': - detach = 0; - break; - case 't': - timeout = atoi(optarg); - break; - case 'b': - if (!strncasecmp(optarg, "0x", 2)) - subclass = (uint8_t) strtol(optarg, NULL, 16); - else - subclass = atoi(optarg); - break; - case 'M': - lm |= L2CAP_LM_MASTER; - break; - case 'E': - encrypt = 1; - break; - case 'D': - nosdp = 1; - break; - case 'Z': - nocheck = 1; - break; - case 'B': - bootonly = 1; - break; - case 'H': - fakehid = 0; - break; - case 'l': - mode = SHOW; - break; - case 'd': - mode = SERVER; - break; - case 's': - mode = SEARCH; - break; - case 'c': - str2ba(optarg, &dev); - mode = CONNECT; - break; - case 'k': - str2ba(optarg, &dev); - mode = KILL; - break; - case 'K': - bacpy(&dev, BDADDR_ALL); - mode = KILL; - break; - case 'u': - str2ba(optarg, &dev); - flags = (1 << HIDP_VIRTUAL_CABLE_UNPLUG); - mode = KILL; - break; - case 'h': - usage(); - exit(0); - default: - exit(0); - } - } - - ba2str(&bdaddr, addr); - - ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP); - if (ctl < 0) { - perror("Can't open HIDP control socket"); - exit(1); - } - - switch (mode) { - case SERVER: - csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, lm, 10); - if (csk < 0) { - perror("Can't listen on HID control channel"); - close(ctl); - exit(1); - } - - isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, lm, 10); - if (isk < 0) { - perror("Can't listen on HID interrupt channel"); - close(ctl); - close(csk); - exit(1); - } - break; - - case SEARCH: - do_search(ctl, &bdaddr, subclass, fakehid, bootonly, encrypt, timeout); - close(ctl); - exit(0); - - case CONNECT: - do_connect(ctl, &bdaddr, &dev, subclass, fakehid, bootonly, encrypt, timeout); - close(ctl); - exit(0); - - case KILL: - do_kill(ctl, &dev, flags); - close(ctl); - exit(0); - - default: - do_show(ctl); - close(ctl); - exit(0); - } - - if (detach) { - if (daemon(0, 0)) { - perror("Can't start daemon"); - exit(1); - } - } else - log_option |= LOG_PERROR; - - openlog("hidd", log_option, LOG_DAEMON); - - if (bacmp(&bdaddr, BDADDR_ANY)) - syslog(LOG_INFO, "Bluetooth HID daemon (%s)", addr); - else - syslog(LOG_INFO, "Bluetooth HID daemon"); - - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_NOCLDSTOP; - - sa.sa_handler = sig_term; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sa.sa_handler = sig_hup; - sigaction(SIGHUP, &sa, NULL); - - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - - run_server(ctl, csk, isk, subclass, nosdp, nocheck, bootonly, encrypt, timeout); - - syslog(LOG_INFO, "Exit"); - - close(csk); - close(isk); - close(ctl); - - return 0; -} diff --git a/compat/hidd.h b/compat/hidd.h deleted file mode 100644 index 053696762..000000000 --- a/compat/hidd.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2003-2010 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 - * - */ - -#define L2CAP_PSM_HIDP_CTRL 0x11 -#define L2CAP_PSM_HIDP_INTR 0x13 - -int epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel); -int headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel); -int jthree_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel); -int celluon_keyboard(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel); diff --git a/compat/lib.h b/compat/lib.h deleted file mode 100644 index 3b3aeb51a..000000000 --- a/compat/lib.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2010 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 - * - */ - -#include <sys/types.h> -#include <errno.h> -#include <signal.h> - -#ifndef min -#define min(a,b) ( (a)<(b) ? (a):(b) ) -#endif - -/* IO cancelation */ -extern volatile sig_atomic_t __io_canceled; - -static inline void io_init(void) -{ - __io_canceled = 0; -} - -static inline void io_cancel(void) -{ - __io_canceled = 1; -} - -/* Read exactly len bytes (Signal safe)*/ -static inline int read_n(int fd, char *buf, int len) -{ - register int t = 0, w; - - while (!__io_canceled && len > 0) { - if ((w = read(fd, buf, len)) < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - if (!w) - return 0; - len -= w; - buf += w; - t += w; - } - - return t; -} - -/* Write exactly len bytes (Signal safe)*/ -static inline int write_n(int fd, char *buf, int len) -{ - register int t = 0, w; - - while (!__io_canceled && len > 0) { - if ((w = write(fd, buf, len)) < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - if (!w) - return 0; - len -= w; - buf += w; - t += w; - } - - return t; -} diff --git a/compat/msdun.c b/compat/msdun.c deleted file mode 100644 index ae88c0ce8..000000000 --- a/compat/msdun.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2010 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 - -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdint.h> -#include <stdlib.h> -#include <syslog.h> -#include <setjmp.h> -#include <string.h> - -#include "lib.h" -#include "dund.h" - -#define MS_PPP 2 -#define MS_SUCCESS 1 -#define MS_FAILED -1 -#define MS_TIMEOUT -2 - -static sigjmp_buf jmp; -static int retry; -static int timeout; - -static void sig_alarm(int sig) -{ - siglongjmp(jmp, MS_TIMEOUT); -} - -static int w4_str(int fd, char *str) -{ - char buf[40]; - unsigned len = 0; - int r; - - while (1) { - r = read(fd, buf + len, sizeof(buf) - len - 1); - if (r < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - break; - } - if (!r) - break; - - len += r; - - if (len < strlen(str)) - continue; - buf[len] = 0; - - if (strstr(buf, str)) - return MS_SUCCESS; - - /* Detect PPP */ - if (strchr(buf, '~')) - return MS_PPP; - } - return MS_FAILED; -} - -static int ms_server(int fd) -{ - switch (w4_str(fd, "CLIENT")) { - case MS_SUCCESS: - write_n(fd, "CLIENTSERVER", 12); - case MS_PPP: - return MS_SUCCESS; - default: - return MS_FAILED; - } -} - -static int ms_client(int fd) -{ - write_n(fd, "CLIENT", 6); - return w4_str(fd, "CLIENTSERVER"); -} - -int ms_dun(int fd, int server, int timeo) -{ - sig_t osig; - - retry = 4; - timeout = timeo; - - if (!server) - timeout /= retry; - - osig = signal(SIGALRM, sig_alarm); - - while (1) { - int r = sigsetjmp(jmp, 1); - if (r) { - if (r == MS_TIMEOUT && !server && --retry) - continue; - - alarm(0); - signal(SIGALRM, osig); - - switch (r) { - case MS_SUCCESS: - case MS_PPP: - errno = 0; - return 0; - - case MS_FAILED: - errno = EPROTO; - break; - - case MS_TIMEOUT: - errno = ETIMEDOUT; - break; - } - return -1; - } - - alarm(timeout); - - if (server) - r = ms_server(fd); - else - r = ms_client(fd); - - siglongjmp(jmp, r); - } -} diff --git a/compat/pand.1 b/compat/pand.1 deleted file mode 100644 index 4603b8bf5..000000000 --- a/compat/pand.1 +++ /dev/null @@ -1,77 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. -.TH BlueZ "1" "February 2003" "PAN daemon" "User Commands" -.SH NAME -pand \- BlueZ Bluetooth PAN daemon -.SH DESCRIPTION -The pand PAN daemon allows your computer to connect to ethernet -networks using Bluetooth. -.SH SYNPOSIS -pand <options> -.SH OPTIONS -.TP -\fB\-\-show\fR \fB\-\-list\fR \fB\-l\fR -Show active PAN connections -.TP -\fB\-\-listen\fR \fB\-s\fR -Listen for PAN connections -.TP -\fB\-\-connect\fR \fB\-c\fR <bdaddr> -Create PAN connection -.TP -\fB\-\-search\fR \fB\-Q[duration]\fR -Search and connect -.TP -\fB\-\-kill\fR \fB\-k\fR <bdaddr> -Kill PAN connection -.TP -\fB\-\-killall\fR \fB\-K\fR -Kill all PAN connections -.TP -\fB\-\-role\fR \fB\-r\fR <role> -Local PAN role (PANU, NAP, GN) -.TP -\fB\-\-service\fR \fB\-d\fR <role> -Remote PAN service (PANU, NAP, GN) -.TP -\fB\-\-ethernet\fR \fB\-e\fR <name> -Network interface name -.TP -\fB\-\-device\fR \fB\-i\fR <bdaddr> -Source bdaddr -.TP -\fB\-\-nosdp\fR \fB\-D\fR -Disable SDP -.TP -\fB\-\-encrypt\fR \fB\-E\fR -Enable encryption -.TP -\fB\-\-secure\fR \fB\-S\fR -Secure connection -.TP -\fB\-\-master\fR \fB\-M\fR -Become the master of a piconet -.TP -\fB\-\-nodetach\fR \fB\-n\fR -Do not become a daemon -.TP -\fB\-\-persist\fR \fB\-p[interval]\fR -Persist mode -.TP -\fB\-\-cache\fR \fB\-C[valid]\fR -Cache addresses -.TP -\fB\-\-pidfile\fR \fB\-P <pidfile>\fR -Create PID file -.TP -\fB\-\-devup\fR \fB\-u <script>\fR -Script to run when interface comes up -.TP -\fB\-\-devdown\fR \fB\-o <script>\fR -Script to run when interface comes down -.TP -\fB\-\-autozap\fR \fB\-z\fR -Disconnect automatically on exit - -.SH SCRIPTS -The devup/devdown script will be called with bluetooth device as first argument -and bluetooth destination address as second argument. diff --git a/compat/pand.c b/compat/pand.c deleted file mode 100644 index b82650ed7..000000000 --- a/compat/pand.c +++ /dev/null @@ -1,811 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2010 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 - -#define _GNU_SOURCE -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <signal.h> -#include <getopt.h> -#include <sys/poll.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/socket.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/hci.h> -#include <bluetooth/hci_lib.h> -#include <bluetooth/l2cap.h> -#include <bluetooth/bnep.h> -#include <bluetooth/hidp.h> - -#include "sdp.h" -#include "pand.h" - -#ifdef NEED_PPOLL -#include "ppoll.h" -#endif - -static uint16_t role = BNEP_SVC_PANU; /* Local role (ie service) */ -static uint16_t service = BNEP_SVC_NAP; /* Remote service */ - -static int detach = 1; -static int persist; -static int use_sdp = 1; -static int use_cache; -static int link_mode = 0; -static int cleanup; -static int search_duration = 10; - -static struct { - int valid; - char dst[40]; - bdaddr_t bdaddr; -} cache; - -static char netdev[16] = "bnep%d"; -static char *pidfile = NULL; -static char *devupcmd = NULL; -static char *devdowncmd = NULL; - -static bdaddr_t src_addr = *BDADDR_ANY; -static int src_dev = -1; - -static volatile int terminate; - -static void do_kill(char *dst); - -enum { - NONE, - SHOW, - LISTEN, - CONNECT, - KILL -} modes; - -struct script_arg { - char dev[20]; - char dst[20]; - int sk; - int nsk; -}; - -static void run_script(char *script, char *dev, char *dst, int sk, int nsk) -{ - char *argv[4]; - struct sigaction sa; - - if (!script) - return; - - if (access(script, R_OK | X_OK)) - return; - - if (fork()) - return; - - if (sk >= 0) - close(sk); - - if (nsk >= 0) - close(nsk); - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - - argv[0] = script; - argv[1] = dev; - argv[2] = dst; - argv[3] = NULL; - - execv(script, argv); - - exit(1); -} - -/* Wait for disconnect or error condition on the socket */ -static int w4_hup(int sk, struct script_arg *down_cmd) -{ - struct pollfd pf; - sigset_t sigs; - int n; - - sigfillset(&sigs); - sigdelset(&sigs, SIGCHLD); - sigdelset(&sigs, SIGPIPE); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - while (!terminate) { - pf.fd = sk; - pf.events = POLLERR | POLLHUP; - - n = ppoll(&pf, 1, NULL, &sigs); - - if (n < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - - syslog(LOG_ERR, "Poll failed. %s(%d)", - strerror(errno), errno); - - return 1; - } - - if (n) { - int err = 0; - socklen_t olen = sizeof(err); - - getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &olen); - - syslog(LOG_INFO, "%s disconnected%s%s", netdev, - err ? " : " : "", err ? strerror(err) : ""); - - if (down_cmd) - run_script(devdowncmd, - down_cmd->dev, down_cmd->dst, - down_cmd->sk, down_cmd->nsk); - - close(sk); - - return 0; - } - } - - return 0; -} - -static int do_listen(void) -{ - struct l2cap_options l2o; - struct sockaddr_l2 l2a; - socklen_t olen; - int sk, lm; - - if (use_sdp) - bnep_sdp_register(&src_addr, role); - - /* Create L2CAP socket and bind it to PSM BNEP */ - sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (sk < 0) { - syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", - strerror(errno), errno); - return -1; - } - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &src_addr); - l2a.l2_psm = htobs(BNEP_PSM); - - if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { - syslog(LOG_ERR, "Bind failed. %s(%d)", - strerror(errno), errno); - return -1; - } - - /* Setup L2CAP options according to BNEP spec */ - memset(&l2o, 0, sizeof(l2o)); - olen = sizeof(l2o); - if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { - syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)", - strerror(errno), errno); - return -1; - } - - l2o.imtu = l2o.omtu = BNEP_MTU; - if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) { - syslog(LOG_ERR, "Failed to set L2CAP options. %s(%d)", - strerror(errno), errno); - return -1; - } - - /* Set link mode */ - lm = link_mode; - if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { - syslog(LOG_ERR, "Failed to set link mode. %s(%d)", - strerror(errno), errno); - return -1; - } - - listen(sk, 10); - - while (!terminate) { - socklen_t alen = sizeof(l2a); - char devname[16]; - int nsk; - - nsk = accept(sk, (struct sockaddr *) &l2a, &alen); - if (nsk < 0) { - syslog(LOG_ERR, "Accept failed. %s(%d)", - strerror(errno), errno); - continue; - } - - switch (fork()) { - case 0: - break; - case -1: - syslog(LOG_ERR, "Fork failed. %s(%d)", - strerror(errno), errno); - default: - close(nsk); - continue; - } - - strncpy(devname, netdev, 16); - devname[15] = '\0'; - - if (!bnep_accept_connection(nsk, role, devname)) { - char str[40]; - struct script_arg down_cmd; - - ba2str(&l2a.l2_bdaddr, str); - - syslog(LOG_INFO, "New connection from %s at %s", - str, devname); - - run_script(devupcmd, devname, str, sk, nsk); - - memset(&down_cmd, 0, sizeof(struct script_arg)); - strncpy(down_cmd.dev, devname, strlen(devname) + 1); - strncpy(down_cmd.dst, str, strlen(str) + 1); - down_cmd.sk = sk; - down_cmd.nsk = nsk; - w4_hup(nsk, &down_cmd); - } else { - syslog(LOG_ERR, "Connection failed. %s(%d)", - strerror(errno), errno); - } - - close(nsk); - exit(0); - } - - if (use_sdp) - bnep_sdp_unregister(); - - return 0; -} - -/* Connect and initiate BNEP session - * Returns: - * -1 - critical error (exit persist mode) - * 1 - non critical error - * 0 - success - */ -static int create_connection(char *dst, bdaddr_t *bdaddr) -{ - struct l2cap_options l2o; - struct sockaddr_l2 l2a; - socklen_t olen; - int sk, r = 0; - struct script_arg down_cmd; - - syslog(LOG_INFO, "Connecting to %s", dst); - - sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (sk < 0) { - syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", - strerror(errno), errno); - return -1; - } - - /* Setup L2CAP options according to BNEP spec */ - memset(&l2o, 0, sizeof(l2o)); - olen = sizeof(l2o); - getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); - l2o.imtu = l2o.omtu = BNEP_MTU; - setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &src_addr); - - if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) - syslog(LOG_ERR, "Bind failed. %s(%d)", - strerror(errno), errno); - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, bdaddr); - l2a.l2_psm = htobs(BNEP_PSM); - - if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) && - !bnep_create_connection(sk, role, service, netdev)) { - - syslog(LOG_INFO, "%s connected", netdev); - - run_script(devupcmd, netdev, dst, sk, -1); - - if (persist || devdowncmd) { - memset(&down_cmd, 0, sizeof(struct script_arg)); - strncpy(down_cmd.dev, netdev, strlen(netdev) + 1); - strncpy(down_cmd.dst, dst, strlen(dst) + 1); - down_cmd.sk = sk; - down_cmd.nsk = -1; - w4_hup(sk, &down_cmd); - - if (terminate && cleanup) { - syslog(LOG_INFO, "Disconnecting from %s.", dst); - do_kill(dst); - } - } - - r = 0; - } else { - syslog(LOG_ERR, "Connect to %s failed. %s(%d)", - dst, strerror(errno), errno); - r = 1; - } - - close(sk); - - if (use_cache) { - if (!r) { - /* Succesesful connection, validate cache */ - strcpy(cache.dst, dst); - bacpy(&cache.bdaddr, bdaddr); - cache.valid = use_cache; - } else - cache.valid--; - } - - return r; -} - -/* Search and connect - * Returns: - * -1 - critical error (exit persist mode) - * 1 - non critical error - * 0 - success - */ -static int do_connect(void) -{ - inquiry_info *ii; - int reconnect = 0; - int i, n, r = 0; - - do { - if (reconnect) - sleep(persist); - reconnect = 1; - - if (cache.valid > 0) { - /* Use cached bdaddr */ - r = create_connection(cache.dst, &cache.bdaddr); - if (r < 0) { - terminate = 1; - break; - } - continue; - } - - syslog(LOG_INFO, "Inquiring"); - - /* FIXME: Should we use non general LAP here ? */ - - ii = NULL; - n = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0); - if (n < 0) { - syslog(LOG_ERR, "Inquiry failed. %s(%d)", - strerror(errno), errno); - continue; - } - - for (i = 0; i < n; i++) { - char dst[40]; - ba2str(&ii[i].bdaddr, dst); - - if (use_sdp) { - syslog(LOG_INFO, "Searching for %s on %s", - bnep_svc2str(service), dst); - - if (bnep_sdp_search(&src_addr, &ii[i].bdaddr, service) <= 0) - continue; - } - - r = create_connection(dst, &ii[i].bdaddr); - if (r < 0) { - terminate = 1; - break; - } - } - bt_free(ii); - } while (!terminate && persist); - - return r; -} - -static void do_show(void) -{ - bnep_show_connections(); -} - -static void do_kill(char *dst) -{ - if (dst) { - bdaddr_t *ba = strtoba(dst); - bnep_kill_connection((void *) ba); - free(ba); - } else { - bnep_kill_all_connections(); - } -} - -static void sig_hup(int sig) -{ - return; -} - -static void sig_term(int sig) -{ - terminate = 1; -} - -static int write_pidfile(void) -{ - int fd; - FILE *f; - pid_t pid; - - do { - fd = open(pidfile, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, 0644); - if (fd == -1) { - /* Try to open the file for read. */ - fd = open(pidfile, O_RDONLY); - if (fd < 0) { - syslog(LOG_ERR, "Could not read old pidfile: %s(%d)", - strerror(errno), errno); - return -1; - } - - /* We're already running; send a SIGHUP (we presume that they - * are calling ifup for a reason, so they probably want to - * rescan) and then exit cleanly and let things go on in the - * background. Muck with the filename so that we don't go - * deleting the pid file for the already-running instance. - */ - f = fdopen(fd, "r"); - if (!f) { - syslog(LOG_ERR, "Could not fdopen old pidfile: %s(%d)", - strerror(errno), errno); - close(fd); - return -1; - } - - pid = 0; - if (fscanf(f, "%d", &pid) != 1) - pid = 0; - fclose(f); - - if (pid) { - /* Try to kill it. */ - if (kill(pid, SIGHUP) == -1) { - /* No such pid; remove the bogus pid file. */ - syslog(LOG_INFO, "Removing stale pidfile"); - unlink(pidfile); - fd = -1; - } else { - /* Got it. Don't mess with the pid file on - * our way out. */ - syslog(LOG_INFO, "Signalling existing process %d and exiting\n", pid); - pidfile = NULL; - return -1; - } - } - } - } while(fd == -1); - - f = fdopen(fd, "w"); - if (!f) { - syslog(LOG_ERR, "Could not fdopen new pidfile: %s(%d)", - strerror(errno), errno); - close(fd); - unlink(pidfile); - return -1; - } - - fprintf(f, "%d\n", getpid()); - fclose(f); - - return 0; -} - -static struct option main_lopts[] = { - { "help", 0, 0, 'h' }, - { "listen", 0, 0, 's' }, - { "connect", 1, 0, 'c' }, - { "search", 2, 0, 'Q' }, - { "kill", 1, 0, 'k' }, - { "killall", 0, 0, 'K' }, - { "role", 1, 0, 'r' }, - { "service", 1, 0, 'd' }, - { "ethernet", 1, 0, 'e' }, - { "device", 1, 0, 'i' }, - { "nosdp", 0, 0, 'D' }, - { "list", 0, 0, 'l' }, - { "show", 0, 0, 'l' }, - { "nodetach", 0, 0, 'n' }, - { "persist", 2, 0, 'p' }, - { "auth", 0, 0, 'A' }, - { "encrypt", 0, 0, 'E' }, - { "secure", 0, 0, 'S' }, - { "master", 0, 0, 'M' }, - { "cache", 0, 0, 'C' }, - { "pidfile", 1, 0, 'P' }, - { "devup", 1, 0, 'u' }, - { "devdown", 1, 0, 'o' }, - { "autozap", 0, 0, 'z' }, - { 0, 0, 0, 0 } -}; - -static const char *main_sopts = "hsc:k:Kr:d:e:i:lnp::DQ::AESMC::P:u:o:z"; - -static const char *main_help = - "Bluetooth PAN daemon version %s\n" - "Usage:\n" - "\tpand <options>\n" - "Options:\n" - "\t--show --list -l Show active PAN connections\n" - "\t--listen -s Listen for PAN connections\n" - "\t--connect -c <bdaddr> Create PAN connection\n" - "\t--autozap -z Disconnect automatically on exit\n" - "\t--search -Q[duration] Search and connect\n" - "\t--kill -k <bdaddr> Kill PAN connection\n" - "\t--killall -K Kill all PAN connections\n" - "\t--role -r <role> Local PAN role (PANU, NAP, GN)\n" - "\t--service -d <role> Remote PAN service (PANU, NAP, GN)\n" - "\t--ethernet -e <name> Network interface name\n" - "\t--device -i <bdaddr> Source bdaddr\n" - "\t--nosdp -D Disable SDP\n" - "\t--auth -A Enable authentication\n" - "\t--encrypt -E Enable encryption\n" - "\t--secure -S Secure connection\n" - "\t--master -M Become the master of a piconet\n" - "\t--nodetach -n Do not become a daemon\n" - "\t--persist -p[interval] Persist mode\n" - "\t--cache -C[valid] Cache addresses\n" - "\t--pidfile -P <pidfile> Create PID file\n" - "\t--devup -u <script> Script to run when interface comes up\n" - "\t--devdown -o <script> Script to run when interface comes down\n"; - -int main(int argc, char *argv[]) -{ - char *dst = NULL, *src = NULL; - struct sigaction sa; - int mode = NONE; - int opt; - - while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) { - switch(opt) { - case 'l': - mode = SHOW; - detach = 0; - break; - - case 's': - mode = LISTEN; - break; - - case 'c': - mode = CONNECT; - dst = strdup(optarg); - break; - - case 'Q': - mode = CONNECT; - if (optarg) - search_duration = atoi(optarg); - break; - - case 'k': - mode = KILL; - detach = 0; - dst = strdup(optarg); - break; - - case 'K': - mode = KILL; - detach = 0; - break; - - case 'i': - src = strdup(optarg); - break; - - case 'r': - bnep_str2svc(optarg, &role); - break; - - case 'd': - bnep_str2svc(optarg, &service); - break; - - case 'D': - use_sdp = 0; - break; - - case 'A': - link_mode |= L2CAP_LM_AUTH; - break; - - case 'E': - link_mode |= L2CAP_LM_ENCRYPT; - break; - - case 'S': - link_mode |= L2CAP_LM_SECURE; - break; - - case 'M': - link_mode |= L2CAP_LM_MASTER; - break; - - case 'e': - strncpy(netdev, optarg, 16); - netdev[15] = '\0'; - break; - - case 'n': - detach = 0; - break; - - case 'p': - if (optarg) - persist = atoi(optarg); - else - persist = 5; - break; - - case 'C': - if (optarg) - use_cache = atoi(optarg); - else - use_cache = 2; - break; - - case 'P': - pidfile = strdup(optarg); - break; - - case 'u': - devupcmd = strdup(optarg); - break; - - case 'o': - devdowncmd = strdup(optarg); - break; - - case 'z': - cleanup = 1; - break; - - case 'h': - default: - printf(main_help, VERSION); - exit(0); - } - } - - argc -= optind; - argv += optind; - optind = 0; - - if (bnep_init()) { - free(dst); - return -1; - } - - /* Check non daemon modes first */ - switch (mode) { - case SHOW: - do_show(); - free(dst); - return 0; - - case KILL: - do_kill(dst); - free(dst); - return 0; - - case NONE: - printf(main_help, VERSION); - free(dst); - return 0; - } - - /* Initialize signals */ - 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_hup; - sigaction(SIGHUP, &sa, NULL); - - sa.sa_handler = sig_term; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - - if (detach && daemon(0, 0)) { - perror("Can't start daemon"); - exit(1); - } - - openlog("pand", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "Bluetooth PAN daemon version %s", VERSION); - - if (src) { - src_dev = hci_devid(src); - if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) { - syslog(LOG_ERR, "Invalid source. %s(%d)", - strerror(errno), errno); - free(dst); - return -1; - } - } - - if (pidfile && write_pidfile()) { - free(dst); - return -1; - } - - if (dst) { - /* Disable cache invalidation */ - use_cache = 0; - - strncpy(cache.dst, dst, sizeof(cache.dst) - 1); - str2ba(dst, &cache.bdaddr); - cache.valid = 1; - free(dst); - } - - switch (mode) { - case CONNECT: - do_connect(); - break; - - case LISTEN: - do_listen(); - break; - } - - if (pidfile) - unlink(pidfile); - - return 0; -} diff --git a/compat/pand.h b/compat/pand.h deleted file mode 100644 index 08b5bdc86..000000000 --- a/compat/pand.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> - * Copyright (C) 2002-2010 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 - * - */ - -int bnep_init(void); -int bnep_cleanup(void); - -int bnep_str2svc(char *svc, uint16_t *uuid); -char *bnep_svc2str(uint16_t uuid); - -int bnep_show_connections(void); -int bnep_kill_connection(uint8_t *dst); -int bnep_kill_all_connections(void); - -int bnep_accept_connection(int sk, uint16_t role, char *dev); -int bnep_create_connection(int sk, uint16_t role, uint16_t svc, char *dev); diff --git a/compat/sdp.c b/compat/sdp.c deleted file mode 100644 index 9ad83334e..000000000 --- a/compat/sdp.c +++ /dev/null @@ -1,706 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2003-2010 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 - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <limits.h> -#include <sys/stat.h> -#include <sys/socket.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/l2cap.h> -#include <bluetooth/sdp.h> -#include <bluetooth/sdp_lib.h> -#include <bluetooth/hidp.h> -#include <bluetooth/bnep.h> - -#include "textfile.h" -#include "sdp.h" - -static sdp_record_t *record = NULL; -static sdp_session_t *session = NULL; - -static void epox_endian_quirk(unsigned char *data, int size) -{ - /* USAGE_PAGE (Keyboard) 05 07 - * USAGE_MINIMUM (0) 19 00 - * USAGE_MAXIMUM (65280) 2A 00 FF <= must be FF 00 - * LOGICAL_MINIMUM (0) 15 00 - * LOGICAL_MAXIMUM (65280) 26 00 FF <= must be FF 00 - */ - unsigned char pattern[] = { 0x05, 0x07, 0x19, 0x00, 0x2a, 0x00, 0xff, - 0x15, 0x00, 0x26, 0x00, 0xff }; - unsigned int i; - - if (!data) - return; - - for (i = 0; i < size - sizeof(pattern); i++) { - if (!memcmp(data + i, pattern, sizeof(pattern))) { - data[i + 5] = 0xff; - data[i + 6] = 0x00; - data[i + 10] = 0xff; - data[i + 11] = 0x00; - } - } -} - -static int store_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req) -{ - char filename[PATH_MAX + 1], addr[18], *str, *desc; - int i, err, size; - - ba2str(src, addr); - create_name(filename, PATH_MAX, STORAGEDIR, addr, "hidd"); - - size = 15 + 3 + 3 + 5 + (req->rd_size * 2) + 1 + 9 + strlen(req->name) + 2; - str = malloc(size); - if (!str) - return -ENOMEM; - - desc = malloc((req->rd_size * 2) + 1); - if (!desc) { - free(str); - return -ENOMEM; - } - - memset(desc, 0, (req->rd_size * 2) + 1); - for (i = 0; i < req->rd_size; i++) - sprintf(desc + (i * 2), "%2.2X", req->rd_data[i]); - - snprintf(str, size - 1, "%04X:%04X:%04X %02X %02X %04X %s %08X %s", - req->vendor, req->product, req->version, - req->subclass, req->country, req->parser, desc, - req->flags, req->name); - - free(desc); - - create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - - ba2str(dst, addr); - err = textfile_put(filename, addr, str); - - free(str); - - return err; -} - -int get_stored_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req) -{ - char filename[PATH_MAX + 1], addr[18], tmp[3], *str, *desc; - unsigned int vendor, product, version, subclass, country, parser, pos; - int i; - - desc = malloc(4096); - if (!desc) - return -ENOMEM; - - memset(desc, 0, 4096); - - ba2str(src, addr); - create_name(filename, PATH_MAX, STORAGEDIR, addr, "hidd"); - - ba2str(dst, addr); - str = textfile_get(filename, addr); - if (!str) { - free(desc); - return -EIO; - } - - sscanf(str, "%04X:%04X:%04X %02X %02X %04X %4095s %08X %n", - &vendor, &product, &version, &subclass, &country, - &parser, desc, &req->flags, &pos); - - - req->vendor = vendor; - req->product = product; - req->version = version; - req->subclass = subclass; - req->country = country; - req->parser = parser; - - snprintf(req->name, 128, "%s", str + pos); - - free(str); - req->rd_size = strlen(desc) / 2; - req->rd_data = malloc(req->rd_size); - if (!req->rd_data) { - free(desc); - return -ENOMEM; - } - - memset(tmp, 0, sizeof(tmp)); - for (i = 0; i < req->rd_size; i++) { - memcpy(tmp, desc + (i * 2), 2); - req->rd_data[i] = (uint8_t) strtol(tmp, NULL, 16); - } - - free(desc); - - return 0; -} - -int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req) -{ - struct sockaddr_l2 addr; - socklen_t addrlen; - bdaddr_t bdaddr; - uint32_t range = 0x0000ffff; - sdp_session_t *s; - sdp_list_t *search, *attrid, *pnp_rsp, *hid_rsp; - sdp_record_t *rec; - sdp_data_t *pdlist, *pdlist2; - uuid_t svclass; - int err; - - s = sdp_connect(src, dst, SDP_RETRY_IF_BUSY | SDP_WAIT_ON_CLOSE); - if (!s) - return -1; - - sdp_uuid16_create(&svclass, PNP_INFO_SVCLASS_ID); - search = sdp_list_append(NULL, &svclass); - attrid = sdp_list_append(NULL, &range); - - err = sdp_service_search_attr_req(s, search, - SDP_ATTR_REQ_RANGE, attrid, &pnp_rsp); - - sdp_list_free(search, NULL); - sdp_list_free(attrid, NULL); - - sdp_uuid16_create(&svclass, HID_SVCLASS_ID); - search = sdp_list_append(NULL, &svclass); - attrid = sdp_list_append(NULL, &range); - - err = sdp_service_search_attr_req(s, search, - SDP_ATTR_REQ_RANGE, attrid, &hid_rsp); - - sdp_list_free(search, NULL); - sdp_list_free(attrid, NULL); - - memset(&addr, 0, sizeof(addr)); - addrlen = sizeof(addr); - - if (getsockname(s->sock, (struct sockaddr *) &addr, &addrlen) < 0) - bacpy(&bdaddr, src); - else - bacpy(&bdaddr, &addr.l2_bdaddr); - - sdp_close(s); - - if (err || !hid_rsp) - return -1; - - if (pnp_rsp) { - rec = (sdp_record_t *) pnp_rsp->data; - - pdlist = sdp_data_get(rec, 0x0201); - req->vendor = pdlist ? pdlist->val.uint16 : 0x0000; - - pdlist = sdp_data_get(rec, 0x0202); - req->product = pdlist ? pdlist->val.uint16 : 0x0000; - - pdlist = sdp_data_get(rec, 0x0203); - req->version = pdlist ? pdlist->val.uint16 : 0x0000; - - sdp_record_free(rec); - } - - rec = (sdp_record_t *) hid_rsp->data; - - pdlist2 = sdp_data_get(rec, 0x0100); - if (pdlist2) - strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1); - else { - pdlist = sdp_data_get(rec, 0x0101); - pdlist2 = sdp_data_get(rec, 0x0102); - if (pdlist) { - if (pdlist2) { - if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) { - strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1); - strcat(req->name, " "); - } - strncat(req->name, pdlist->val.str, - sizeof(req->name) - strlen(req->name)); - } else - strncpy(req->name, pdlist->val.str, sizeof(req->name) - 1); - } - } - - pdlist = sdp_data_get(rec, 0x0201); - req->parser = pdlist ? pdlist->val.uint16 : 0x0100; - - pdlist = sdp_data_get(rec, 0x0202); - req->subclass = pdlist ? pdlist->val.uint8 : 0; - - pdlist = sdp_data_get(rec, 0x0203); - req->country = pdlist ? pdlist->val.uint8 : 0; - - pdlist = sdp_data_get(rec, 0x0206); - if (pdlist) { - pdlist = pdlist->val.dataseq; - pdlist = pdlist->val.dataseq; - pdlist = pdlist->next; - - req->rd_data = malloc(pdlist->unitSize); - if (req->rd_data) { - memcpy(req->rd_data, (unsigned char *) pdlist->val.str, pdlist->unitSize); - req->rd_size = pdlist->unitSize; - epox_endian_quirk(req->rd_data, req->rd_size); - } - } - - sdp_record_free(rec); - - if (bacmp(&bdaddr, BDADDR_ANY)) - store_device_info(&bdaddr, dst, req); - - return 0; -} - -int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t *uuid, uint8_t *channel, char *name, size_t len) -{ - uint16_t attr1 = SDP_ATTR_PROTO_DESC_LIST; - uint16_t attr2 = SDP_ATTR_SVCNAME_PRIMARY; - sdp_session_t *s; - sdp_list_t *search, *attrid, *rsp; - uuid_t svclass; - int err; - - s = sdp_connect(src, dst, SDP_RETRY_IF_BUSY | SDP_WAIT_ON_CLOSE); - if (!s) - return -1; - - sdp_uuid16_create(&svclass, HEADSET_SVCLASS_ID); - search = sdp_list_append(NULL, &svclass); - attrid = sdp_list_append(NULL, &attr1); - attrid = sdp_list_append(attrid, &attr2); - - err = sdp_service_search_attr_req(s, search, - SDP_ATTR_REQ_INDIVIDUAL, attrid, &rsp); - - sdp_list_free(search, NULL); - sdp_list_free(attrid, NULL); - - if (err <= 0) { - sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID); - search = sdp_list_append(NULL, &svclass); - attrid = sdp_list_append(NULL, &attr1); - attrid = sdp_list_append(attrid, &attr2); - - err = sdp_service_search_attr_req(s, search, - SDP_ATTR_REQ_INDIVIDUAL, attrid, &rsp); - - sdp_list_free(search, NULL); - sdp_list_free(attrid, NULL); - - if (err < 0) { - sdp_close(s); - return err; - } - - if (uuid) - *uuid = SERIAL_PORT_SVCLASS_ID; - } else { - if (uuid) - *uuid = HEADSET_SVCLASS_ID; - } - - sdp_close(s); - - for (; rsp; rsp = rsp->next) { - sdp_record_t *rec = (sdp_record_t *) rsp->data; - sdp_list_t *protos; - - sdp_get_service_name(rec, name, len); - - if (!sdp_get_access_protos(rec, &protos)) { - uint8_t ch = sdp_get_proto_port(protos, RFCOMM_UUID); - if (ch > 0) { - if (channel) - *channel = ch; - return 0; - } - } - - sdp_record_free(rec); - } - - return -EIO; -} - -void bnep_sdp_unregister(void) -{ - if (record && sdp_record_unregister(session, record)) - syslog(LOG_ERR, "Service record unregistration failed."); - - sdp_close(session); -} - -int bnep_sdp_register(bdaddr_t *device, uint16_t role) -{ - sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; - uuid_t root_uuid, pan, l2cap, bnep; - sdp_profile_desc_t profile[1]; - sdp_list_t *proto[2]; - sdp_data_t *v, *p; - uint16_t psm = 15, version = 0x0100; - uint16_t security_desc = 0; - uint16_t net_access_type = 0xfffe; - uint32_t max_net_access_rate = 0; - char *name = "BlueZ PAN"; - char *desc = "BlueZ PAN Service"; - int status; - - session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); - if (!session) { - syslog(LOG_ERR, "Failed to connect to the local SDP server. %s(%d)", - strerror(errno), errno); - return -1; - } - - record = sdp_record_alloc(); - if (!record) { - syslog(LOG_ERR, "Failed to allocate service record %s(%d)", - strerror(errno), errno); - sdp_close(session); - return -1; - } - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - sdp_list_free(root, 0); - - sdp_uuid16_create(&l2cap, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap); - p = sdp_data_alloc(SDP_UINT16, &psm); - proto[0] = sdp_list_append(proto[0], p); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&bnep, BNEP_UUID); - proto[1] = sdp_list_append(NULL, &bnep); - v = sdp_data_alloc(SDP_UINT16, &version); - proto[1] = sdp_list_append(proto[1], v); - - /* Supported protocols */ - { - uint16_t ptype[4] = { - 0x0800, /* IPv4 */ - 0x0806, /* ARP */ - }; - sdp_data_t *head, *pseq; - int p; - - for (p = 0, head = NULL; p < 2; p++) { - sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]); - if (head) - sdp_seq_append(head, data); - else - head = data; - } - pseq = sdp_data_alloc(SDP_SEQ16, head); - proto[1] = sdp_list_append(proto[1], pseq); - } - - apseq = sdp_list_append(apseq, proto[1]); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - - sdp_add_lang_attr(record); - - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(aproto, NULL); - sdp_data_free(p); - sdp_data_free(v); - sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security_desc); - - switch (role) { - case BNEP_SVC_NAP: - sdp_uuid16_create(&pan, NAP_SVCLASS_ID); - svclass = sdp_list_append(NULL, &pan); - sdp_set_service_classes(record, svclass); - - sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - - sdp_set_info_attr(record, "Network Access Point", name, desc); - - sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE, SDP_UINT16, &net_access_type); - sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE, SDP_UINT32, &max_net_access_rate); - break; - - case BNEP_SVC_GN: - sdp_uuid16_create(&pan, GN_SVCLASS_ID); - svclass = sdp_list_append(NULL, &pan); - sdp_set_service_classes(record, svclass); - - sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - - sdp_set_info_attr(record, "Group Network Service", name, desc); - break; - - case BNEP_SVC_PANU: - sdp_uuid16_create(&pan, PANU_SVCLASS_ID); - svclass = sdp_list_append(NULL, &pan); - sdp_set_service_classes(record, svclass); - sdp_list_free(svclass, 0); - - sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - sdp_list_free(pfseq, 0); - - sdp_set_info_attr(record, "PAN User", name, desc); - break; - } - - status = sdp_device_record_register(session, device, record, 0); - if (status) { - syslog(LOG_ERR, "SDP registration failed."); - sdp_record_free(record); record = NULL; - sdp_close(session); - return -1; - } - - return 0; -} - -/* Search for PAN service. - * Returns 1 if service is found and 0 otherwise. */ -int bnep_sdp_search(bdaddr_t *src, bdaddr_t *dst, uint16_t service) -{ - sdp_list_t *srch, *rsp = NULL; - sdp_session_t *s; - uuid_t svclass; - int err; - - switch (service) { - case BNEP_SVC_PANU: - sdp_uuid16_create(&svclass, PANU_SVCLASS_ID); - break; - case BNEP_SVC_NAP: - sdp_uuid16_create(&svclass, NAP_SVCLASS_ID); - break; - case BNEP_SVC_GN: - sdp_uuid16_create(&svclass, GN_SVCLASS_ID); - break; - } - - srch = sdp_list_append(NULL, &svclass); - - s = sdp_connect(src, dst, 0); - if (!s) { - syslog(LOG_ERR, "Failed to connect to the SDP server. %s(%d)", - strerror(errno), errno); - return 0; - } - - err = sdp_service_search_req(s, srch, 1, &rsp); - sdp_close(s); - - /* Assume that search is successeful - * if at least one record is found */ - if (!err && sdp_list_len(rsp)) - return 1; - - return 0; -} - -static unsigned char async_uuid[] = { 0x03, 0x50, 0x27, 0x8F, 0x3D, 0xCA, 0x4E, 0x62, - 0x83, 0x1D, 0xA4, 0x11, 0x65, 0xFF, 0x90, 0x6C }; - -void dun_sdp_unregister(void) -{ - if (record && sdp_record_unregister(session, record)) - syslog(LOG_ERR, "Service record unregistration failed."); - sdp_close(session); -} - -int dun_sdp_register(bdaddr_t *device, uint8_t channel, int type) -{ - sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; - uuid_t root_uuid, l2cap, rfcomm, dun; - sdp_profile_desc_t profile[1]; - sdp_list_t *proto[2]; - int status; - - session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); - if (!session) { - syslog(LOG_ERR, "Failed to connect to the local SDP server. %s(%d)", - strerror(errno), errno); - return -1; - } - - record = sdp_record_alloc(); - if (!record) { - syslog(LOG_ERR, "Failed to alloc service record"); - return -1; - } - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - sdp_uuid16_create(&l2cap, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&rfcomm, RFCOMM_UUID); - proto[1] = sdp_list_append(NULL, &rfcomm); - proto[1] = sdp_list_append(proto[1], sdp_data_alloc(SDP_UINT8, &channel)); - apseq = sdp_list_append(apseq, proto[1]); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - - switch (type) { - case MROUTER: - sdp_uuid16_create(&dun, SERIAL_PORT_SVCLASS_ID); - break; - case ACTIVESYNC: - sdp_uuid128_create(&dun, (void *) async_uuid); - break; - case DIALUP: - sdp_uuid16_create(&dun, DIALUP_NET_SVCLASS_ID); - break; - default: - sdp_uuid16_create(&dun, LAN_ACCESS_SVCLASS_ID); - break; - } - - svclass = sdp_list_append(NULL, &dun); - sdp_set_service_classes(record, svclass); - - switch (type) { - case LANACCESS: - sdp_uuid16_create(&profile[0].uuid, LAN_ACCESS_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - break; - case DIALUP: - sdp_uuid16_create(&profile[0].uuid, DIALUP_NET_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - break; - } - - switch (type) { - case MROUTER: - sdp_set_info_attr(record, "mRouter", NULL, NULL); - break; - case ACTIVESYNC: - sdp_set_info_attr(record, "ActiveSync", NULL, NULL); - break; - case DIALUP: - sdp_set_info_attr(record, "Dialup Networking", NULL, NULL); - break; - default: - sdp_set_info_attr(record, "LAN Access Point", NULL, NULL); - break; - } - - status = sdp_device_record_register(session, device, record, 0); - if (status) { - syslog(LOG_ERR, "SDP registration failed."); - sdp_record_free(record); - record = NULL; - return -1; - } - return 0; -} - -int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int type) -{ - sdp_session_t *s; - sdp_list_t *srch, *attrs, *rsp; - uuid_t svclass; - uint16_t attr; - int err; - - s = sdp_connect(src, dst, 0); - if (!s) { - syslog(LOG_ERR, "Failed to connect to the SDP server. %s(%d)", - strerror(errno), errno); - return -1; - } - - switch (type) { - case MROUTER: - sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID); - break; - case ACTIVESYNC: - sdp_uuid128_create(&svclass, (void *) async_uuid); - break; - case DIALUP: - sdp_uuid16_create(&svclass, DIALUP_NET_SVCLASS_ID); - break; - default: - sdp_uuid16_create(&svclass, LAN_ACCESS_SVCLASS_ID); - break; - } - - srch = sdp_list_append(NULL, &svclass); - - attr = SDP_ATTR_PROTO_DESC_LIST; - attrs = sdp_list_append(NULL, &attr); - - err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); - - sdp_close(s); - - if (err) - return 0; - - for(; rsp; rsp = rsp->next) { - sdp_record_t *rec = (sdp_record_t *) rsp->data; - sdp_list_t *protos; - - if (!sdp_get_access_protos(rec, &protos)) { - int ch = sdp_get_proto_port(protos, RFCOMM_UUID); - if (ch > 0) { - *channel = ch; - return 1; - } - } - } - - return 0; -} diff --git a/compat/sdp.h b/compat/sdp.h deleted file mode 100644 index 6ca975ff5..000000000 --- a/compat/sdp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2003-2010 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 - * - */ - -#define LANACCESS 0 -#define MROUTER 1 -#define ACTIVESYNC 2 -#define DIALUP 3 - -int get_stored_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req); -int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req); -int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t *uuid, uint8_t *channel, char *name, size_t len); - -int bnep_sdp_search(bdaddr_t *src, bdaddr_t *dst, uint16_t service); -int bnep_sdp_register(bdaddr_t *device, uint16_t role); -void bnep_sdp_unregister(void); - -int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int type); -int dun_sdp_register(bdaddr_t *device, uint8_t channel, int type); -void dun_sdp_unregister(void); |