diff options
| -rw-r--r-- | AUTHORS | 6 | ||||
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | configure.in | 4 | ||||
| -rw-r--r-- | rfcomm/Makefile.am | 13 | ||||
| -rw-r--r-- | rfcomm/kword.c | 60 | ||||
| -rw-r--r-- | rfcomm/kword.h | 48 | ||||
| -rw-r--r-- | rfcomm/lexer.l | 107 | ||||
| -rw-r--r-- | rfcomm/main.c | 433 | ||||
| -rw-r--r-- | rfcomm/parser.y | 164 | ||||
| -rw-r--r-- | rfcomm/rfcomm.8 | 36 | ||||
| -rw-r--r-- | rfcomm/rfcomm.conf | 19 | 
11 files changed, 889 insertions, 3 deletions
@@ -26,3 +26,9 @@ Martin Leopold <martin@leopold.dk>  Stephen Crane <steve.crane@rococosoft.com>  	Support for human readable class of device display. + +Wolfgang Heidrich <wolfgang.heidrich@esk.fhg.de> +	Support for displaying link quality (hcitool). + +Fabrizio Gennari <fabrizio.gennari@philips.com> +	Support for link supervision timeout (hcitool). diff --git a/Makefile.am b/Makefile.am index 6c007cbd..a9fe27a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,4 +2,4 @@  #  $Id$  # -SUBDIRS := hcid tools scripts pcmcia +SUBDIRS := hcid tools rfcomm scripts pcmcia diff --git a/configure.in b/configure.in index fef17598..af2f6ee1 100644 --- a/configure.in +++ b/configure.in @@ -9,7 +9,7 @@ dnl Guess host type.  AC_CANONICAL_SYSTEM  AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(bluez-utils, 2.0) +AM_INIT_AUTOMAKE(bluez-utils, 2.1)  AC_SUBST(DISTRO)  AC_SUBST(PCMCIA) @@ -84,4 +84,4 @@ AC_ARG_ENABLE(pcmcia,             AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=)      fi ]) -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am new file mode 100644 index 00000000..6b7a9eee --- /dev/null +++ b/rfcomm/Makefile.am @@ -0,0 +1,13 @@ +#   +#  $Id$ +# + +sbin_PROGRAMS  = rfcomm + +rfcomm_SOURCES = main.c parser.h parser.y lexer.l kword.h kword.c + +man_MANS       = rfcomm.8 + +YFLAGS = -d + +CLEANFILES = lexer.c parser.c parser.h diff --git a/rfcomm/kword.c b/rfcomm/kword.c new file mode 100644 index 00000000..c83dcc4b --- /dev/null +++ b/rfcomm/kword.c @@ -0,0 +1,60 @@ +/* + * + *  RFCOMM configuration file + * + *  Copyright (C) 2001-2002  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include <stdio.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/rfcomm.h> + +#include "kword.h" +#include "parser.h" + +int lineno; + +struct keyword_t rfcomm_keyword[] = { +	{ "bind",	K_BIND		}, +	{ "device",	K_DEVICE	}, +	{ "channel",	K_CHANNEL	}, +	{ "comment",	K_COMMENT	}, + +	{ "yes",	K_YES		}, +	{ "no",		K_NO		}, +	{ "enable",	K_YES		}, +	{ "disable",	K_NO		}, + +	{ NULL , 0 } +}; + +int rfcomm_find_keyword(struct keyword_t *keyword, char *string) +{ +	while (keyword->string) { +		if (!strcmp(string, keyword->string)) +			return keyword->type; +		keyword++; +	} + +	return -1; +} + +struct rfcomm_opts rfcomm_opts[RFCOMM_MAX_DEV]; diff --git a/rfcomm/kword.h b/rfcomm/kword.h new file mode 100644 index 00000000..cdee0c8c --- /dev/null +++ b/rfcomm/kword.h @@ -0,0 +1,48 @@ +/* + * + *  RFCOMM configuration file + * + *  Copyright (C) 2001-2002  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +extern int lineno; + + +struct keyword_t { +	char *string; +	int type; +}; + +extern struct keyword_t rfcomm_keyword[];  + +int rfcomm_find_keyword(struct keyword_t *keyword, char *string); + + +#define MAXCOMMENTLEN  100 + +struct rfcomm_opts { +	int bind; +	bdaddr_t bdaddr; +	int channel; +	char comment[MAXCOMMENTLEN + 1]; +}; + +extern struct rfcomm_opts rfcomm_opts[RFCOMM_MAX_DEV]; + +int rfcomm_read_config(char *filename); diff --git a/rfcomm/lexer.l b/rfcomm/lexer.l new file mode 100644 index 00000000..c044391f --- /dev/null +++ b/rfcomm/lexer.l @@ -0,0 +1,107 @@ +%{ +/* + * + *  RFCOMM configuration file + * + *  Copyright (C) 2001-2002  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include <stdio.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/rfcomm.h> + +#include "kword.h" +#include "parser.h" + + +#define ECHO {;} +#define YY_DECL int yylex(void) + +int yyerror(char *str); + +%} + +space		[ \t] +linebreak	\n +comment		\#.*\n +keyword		[A-Za-z0-9\_\-]+ + +number		[0-9]+ +string		\".*\" +bdaddr		[A-Za-z0-9]{2}:[A-Za-z0-9]{2}:[A-Za-z0-9]{2}:[A-Za-z0-9]{2}:[A-Za-z0-9]{2}:[A-Za-z0-9]{2} + +%% + +{space}		{ +			/* Skip spaces and tabs */ +			; +		} + +{comment}	{ +			/* Skip comments */ +			lineno++;  +		} + +{number}	{ +			yylval.number = atoi(yytext); +			return NUMBER; +		} + +{string}	{ +			yylval.string = yytext; +			return STRING; +		} + +{bdaddr}	{ +			bdaddr_t *ba = malloc(sizeof(bdaddr_t)); +			str2ba(yytext, ba); +			yylval.bdaddr = ba; +			return BDADDR; +		} + +{keyword}	{ +			int keyword = rfcomm_find_keyword(rfcomm_keyword, yytext); +			if (keyword != -1) +				return keyword; + +			if (strncmp(yytext, "rfcomm", 6) == 0) { +				yylval.number = atoi(yytext + 6); +				return RFCOMM; +			} + +			yylval.string = yytext; +			return WORD; +		} + +{linebreak}	{ +			lineno++; +		} + +.		{ +			return *yytext; +		} + +%% + +int yywrap(void)  +{ +	return 1; +} diff --git a/rfcomm/main.c b/rfcomm/main.c new file mode 100644 index 00000000..2f793faa --- /dev/null +++ b/rfcomm/main.c @@ -0,0 +1,433 @@ +/* + * + *  RFCOMM configuration utility + * + *  Copyright (C) 2002  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <malloc.h> +#include <string.h> +#include <getopt.h> +#include <signal.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/poll.h> +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h> +#include <bluetooth/rfcomm.h> + +#include "kword.h" + +static char *rfcomm_config_file = NULL; + +extern int optind, opterr, optopt; +extern char *optarg; + +static char *rfcomm_state[] = { +	"unknown", +	"connected", +        "open", +        "bound", +        "listening", +        "connecting", +        "connecting", +        "config", +        "disconnecting", +        "closed" +}; + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ +	return; +} + +static void sig_term(int sig) +{ +	__io_canceled = 1; +} + +static char *rfcomm_flagstostr(uint32_t flags) +{ +	static char str[100]; +	str[0] = 0; + +	strcat(str, "["); + +	if (flags & (1 << RFCOMM_REUSE_DLC)) +		strcat(str, "reuse-dlc "); + +	if (flags & (1 << RFCOMM_RELEASE_ONHUP)) +		strcat(str, "release-on-hup "); + +	if (flags & (1 << RFCOMM_TTY_ATTACHED)) +		strcat(str, "tty-attached"); +	 +	strcat(str, "]"); +	return str; +} + +static void print_dev_info(struct rfcomm_dev_info *di) +{ +	char src[18], dst[18], addr[100]; + +	ba2str(&di->src, src); ba2str(&di->dst, dst); + +	if (bacmp(&di->src, BDADDR_ANY) == 0) +		sprintf(addr, "%s", dst); +	else +		sprintf(addr, "%s -> %s", src, dst); + +	printf("rfcomm%d: %s channel %d %s %s\n", +		di->id, addr, di->channel, +		rfcomm_state[di->state],  +		di->flags ? rfcomm_flagstostr(di->flags) : ""); +} + +static void print_dev_list(int ctl, int flags) +{ +	struct rfcomm_dev_list_req *dl; +	struct rfcomm_dev_info *di; +	int i; + +	dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); +	if (!dl) { +		perror("Can't allocate memory"); +		exit(1); +	} + +	dl->dev_num = RFCOMM_MAX_DEV; +	di = dl->dev_info; + +	if (ioctl(ctl, RFCOMMGETDEVLIST, (void *) dl) < 0) { +		perror("Can't get device list"); +		exit(1); +	} + +	for (i = 0; i < dl->dev_num; i++) +		print_dev_info(di + i); +} + +static int create_dev(int ctl, int dev, int flags, bdaddr_t *bdaddr, int argc, char **argv) +{ +	struct rfcomm_dev_req req; +	int err; + +	memset(&req, 0, sizeof(req)); +	req.dev_id = dev; +	req.flags = flags; +	bacpy(&req.src, bdaddr); + +	if (argc < 2) { +		if ((err = rfcomm_read_config(rfcomm_config_file)) < 0) { +			perror("Can't open RFCOMM config file"); +			return err; +		} + +		bacpy(&req.dst, &rfcomm_opts[dev].bdaddr); +		req.channel = rfcomm_opts[dev].channel; + +		if (bacmp(&req.dst, BDADDR_ANY) == 0) { +			fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev); +			return -EFAULT; +		} +		 +	} else { +		str2ba(argv[1], &req.dst); + +		if (argc > 2) +			req.channel = atoi(argv[2]); +		else +			req.channel = 1; +	} + +	if ((err = ioctl(ctl, RFCOMMCREATEDEV, &req)) < 0 ) +		perror("Can't create device"); + +	return err; +} + +static int create_all(int ctl) +{ +	struct rfcomm_dev_req req; +	int i, err; + +	if ((err = rfcomm_read_config(rfcomm_config_file)) < 0) { +		perror("Can't open RFCOMM config file"); +		return err; +	} + +	for (i = 0; i < RFCOMM_MAX_DEV; i++) { +		memset(&req, 0, sizeof(req)); +		req.dev_id = i; +		req.flags = 0; +		bacpy(&req.src, BDADDR_ANY); +		bacpy(&req.dst, &rfcomm_opts[i].bdaddr); +		req.channel = rfcomm_opts[i].channel; + +		if (bacmp(&req.dst, BDADDR_ANY) != 0) +			ioctl(ctl, RFCOMMCREATEDEV, &req); +	} + +	return 0; +} + +static int release_dev(int ctl, int dev, int flags) +{ +	struct rfcomm_dev_req req; +	int err; + +	memset(&req, 0, sizeof(req)); +	req.dev_id = dev; + +	if ((err = ioctl(ctl, RFCOMMRELEASEDEV, &req)) < 0 ) +		perror("Can't release device"); + +	return err; +} + +static int release_all(int ctl) +{ +	struct rfcomm_dev_list_req *dl; +	struct rfcomm_dev_info *di; +	int i; + +	dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); +	if (!dl) { +		perror("Can't allocate memory"); +		exit(1); +	} + +	dl->dev_num = RFCOMM_MAX_DEV; +	di = dl->dev_info; + +	if (ioctl(ctl, RFCOMMGETDEVLIST, (void *) dl) < 0) { +		perror("Can't get device list"); +		exit(1); +	} + +	for (i = 0; i < dl->dev_num; i++) +		release_dev(ctl, (di + i)->id, 0); + +	return 0; +} + +static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ +	struct sigaction sa; +	struct pollfd p; +	char devname[MAXPATHLEN]; +	int fd; + +	if (create_dev(ctl, dev, 0, bdaddr, argc, argv) < 0) +		return; + +	snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); +	if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { +		perror("Can't open RFCOMM device"); +		goto release; +	} + +	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); + +	p.fd = fd; +	p.events = POLLHUP; + +	while (!__io_canceled) { +		p.revents = 0; +		poll(&p, 1, 100); +	} + +	close(fd); + +release: +	release_dev(ctl, dev, 0); +} + +static void cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ +	if (strcmp(argv[0], "all") == 0) +		create_all(ctl); +	else +		create_dev(ctl, dev, 0, bdaddr, argc, argv); +} + +static void cmd_release(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ +	if (strcmp(argv[0], "all") == 0) +		release_all(ctl); +	else +		release_dev(ctl, dev, 0); +} + +static void cmd_show(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ +	if (strcmp(argv[0], "all") == 0) +		print_dev_list(ctl, 0); +	else { +		struct rfcomm_dev_info di = { id: atoi(argv[0]) }; +		if (ioctl(ctl, RFCOMMGETDEVINFO, &di) < 0) { +			perror("Get info failed"); +			exit(1); +		} + +		print_dev_info(&di); +	} +} + +struct { +	char *cmd; +	char *alt; +	void (*func)(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv); +	char *opt; +	char *doc; +} command[] = { +	{ "bind",    "create", cmd_create,  "<dev> <bdaddr> [channel]", "Bind device"    }, +	{ "release", "unbind", cmd_release, "<dev>",                    "Release device" }, +	{ "connect", "conn",   cmd_connect, "<dev> <bdaddr> [channel]", "Connect device" }, +	{ "show",    "info",   cmd_show,    0,                          "Show device"    }, +	{ NULL, NULL, NULL, 0, 0 } +}; + +static void usage(void) +{ +	int i; + +	printf("RFCOMM configuration utility ver %s\n", VERSION); + +	printf("Usage:\n" +		"\trfcomm [options] <command> <dev>\n" +		"\n"); + +	printf("Options:\n" +		"\t-i [hciX|bdaddr]   Local HCI device or BD Address\n" +		"\t-h, --help         Display help\n" +		"\t-a                 Show all devices (default)\n" +		"\n"); + +	printf("Commands:\n"); +        for (i = 0; command[i].cmd; i++) +		printf("\t%-8s %-24s\t%s\n", +			command[i].cmd, +			command[i].opt ? command[i].opt : " ", +			command[i].doc); +	printf("\n"); +} + + +static struct option main_options[] = { +	{ "help",	0, 0, 'h' }, +	{ "device",	1, 0, 'i' }, +	{ "config",	1, 0, 'f' }, +	{ 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[])  +{ + +	bdaddr_t bdaddr; +	int i, opt, ctl, dev_id, show_all = 0; + +	bacpy(&bdaddr, BDADDR_ANY); + +	while ((opt = getopt_long(argc, argv, "+i:f:ah", main_options, NULL)) != -1) { +		switch(opt) { +		case 'i': +			if (strncmp(optarg, "hci", 3) == 0) +				hci_devba(atoi(optarg + 3), &bdaddr); +			else +				str2ba(optarg, &bdaddr); +			break; +			 +		case 'f': +			rfcomm_config_file = strdup(optarg); +			break; + +		case 'a': +			show_all = 1; +			break; + +		case 'h': +			usage(); +			exit(0); + +		default: +			exit(0); +		} +	} + +	argc -= optind; +	argv += optind; +	optind = 0; + +	if (argc < 2) +		show_all = 1; + +	if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM)) < 0 ) { +		perror("Can't open RFCOMM control socket"); +		exit(1); +	} + +	if (show_all) { +		print_dev_list(ctl, 0); +		close(ctl); +		exit(0); +	} + +	if (strncmp(argv[1], "rfcomm", 6) == 0) +		dev_id = atoi(argv[1] + 6); +	else +		dev_id = atoi(argv[1]); + +	for (i = 0; command[i].cmd; i++) { +		if (strncmp(command[i].cmd, argv[0], 4) && strncmp(command[i].alt, argv[0], 4)) +			continue; +		argc--; +		argv++; +		command[i].func(ctl, dev_id, &bdaddr, argc, argv); +		close(ctl); +		exit(0); +	} + +	usage(); + +	close(ctl); + +	return 0; +} diff --git a/rfcomm/parser.y b/rfcomm/parser.y new file mode 100644 index 00000000..9f05f044 --- /dev/null +++ b/rfcomm/parser.y @@ -0,0 +1,164 @@ +%{ +/* + * + *  RFCOMM configuration file + * + *  Copyright (C) 2001-2002  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/param.h> +#include <sys/socket.h> + +#include <bluetooth/bluetooth.h> +#include <bluetooth/rfcomm.h> + +#include "kword.h" + +int yyparse(void); +int yylex(void); +int yyerror(char *s);  + +struct rfcomm_opts *opts; + +%} + +%union { +	int number; +	char *string; +	bdaddr_t *bdaddr; +} + +%token K_BIND K_DEVICE K_CHANNEL K_COMMENT +%token K_YES K_NO + +%token <number> NUMBER RFCOMM +%token <string> STRING WORD +%token <bdaddr> BDADDR + +%type <number> bool + +%% + +config		: statement | config statement +		; + +statement	: section '{' rfcomm_options '}' +		| rfcomm  '{' rfcomm_options '}' +		| WORD +			{ +			} +		| error +			{ +				yyclearin; +				yyerrok; +			} +		; + +section		: WORD +			{ +				opts = NULL; +			} + +rfcomm		: RFCOMM +			{ +				if (($1 >= 0) && ($1 < RFCOMM_MAX_DEV)) +					opts = &rfcomm_opts[$1]; +				else +					opts = NULL; +			} +		; + +rfcomm_options	: rfcomm_option ';' +		| error ';' +		| rfcomm_options rfcomm_option ';' +		; + +rfcomm_option	: K_BIND bool +			{ +				if (opts) +					opts->bind = $2; +			} +		| K_DEVICE BDADDR +			{ +				if (opts) +					bacpy(&opts->bdaddr, $2); +			} +		| K_CHANNEL NUMBER +			{ +				if (opts) +					opts->channel = $2; +			} +		| K_COMMENT STRING +			{ +				if (opts) +					snprintf(opts->comment, MAXCOMMENTLEN, "%s", $2); +			} +		| WORD +			{ +				// Unknown option +			} +		; + +bool		: K_YES	{ $$ = 1; } +		| K_NO	{ $$ = 0; } +		; + +%% + +int yyerror(char *s)  +{ +	fprintf(stderr, "%s line %d\n", s, lineno); +	return 0; +} + +int rfcomm_read_config(char *filename) +{ +	extern FILE *yyin; +	char file[MAXPATHLEN + 1]; +	int i; + +	for (i = 0; i < RFCOMM_MAX_DEV; i++) { +		rfcomm_opts[i].bind = 0; +		bacpy(&rfcomm_opts[i].bdaddr, BDADDR_ANY); +		rfcomm_opts[i].channel = 1; +	} + +	if (filename) { +		snprintf(file, MAXPATHLEN,  "%s", filename); +	} else { +		snprintf(file, MAXPATHLEN, "%s/.bluetooth/rfcomm.conf", getenv("HOME")); + +		if ((getuid() == 0) || (access(file, R_OK) < 0)) +			snprintf(file, MAXPATHLEN, "/etc/bluetooth/rfcomm.conf"); +	} + +	if (!(yyin = fopen(file, "r"))) +		return -1; + +	lineno = 1; +	yyparse(); + +	fclose(yyin); +   +	return 0;      +} diff --git a/rfcomm/rfcomm.8 b/rfcomm/rfcomm.8 new file mode 100644 index 00000000..d60af804 --- /dev/null +++ b/rfcomm/rfcomm.8 @@ -0,0 +1,36 @@ +.\" +.\"	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., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH RFCOMM 8 "APRIL 28, 2002" "" "" + +.SH NAME +rfcomm \- RFCOMM configuration utility +.SH SYNOPSIS +.BR "rfcomm +[-i +.I hciX | bdaddr +] < +.I command +> < +.I dev +> +.SH DESCRIPTION +.B rfcomm +is used to set up, maintain, and inspect the RFCOMM configuration +of the Bluetooth subsystem in the Linux kernel. +.SH AUTHOR +Written by Marcel Holtmann <marcel@holtmann.org>. +.br diff --git a/rfcomm/rfcomm.conf b/rfcomm/rfcomm.conf new file mode 100644 index 00000000..c1b10cd5 --- /dev/null +++ b/rfcomm/rfcomm.conf @@ -0,0 +1,19 @@ +# +# RFCOMM configuration file. +# +# $Id$ +# + +rfcomm0 { +	# Automatically bind the device at startup +	bind no; + +	# Bluetooth address of the device +	device 11:22:33:44:55:66; + +	# RFCOMM channel for the connection +	channel	1; + +	# Description of the connection +	comment "Example Bluetooth device"; +}  | 
