⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btsocket.c

📁 affix是一个Open Source的蓝牙协议栈
💻 C
字号:
/*    Affix - Bluetooth Protocol Stack for Linux   Copyright (C) 2004 Nokia Corporation   Original Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>   Partly based on socket.c	Copyright (C) 1992 by Juergen Nickelsen <nickel@cs.tu-berlin.de>	Please read the file COPYRIGHT for further details.      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.   *//*    $Id: btsocket.c,v 1.16 2004/05/26 10:24:21 kassatki Exp $   btctl - driver control program	Fixes:	Dmitry Kasatkin <dmitry.kasatkin@nokia.com>*/#include <affix/config.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/errno.h>#include <fcntl.h>#include <unistd.h>#include <syslog.h>#include <signal.h>#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <getopt.h>#include <string.h>#include <termios.h>#include <affix/bluetooth.h>#include <affix/btcore.h>#include <affix/utils.h>int		nameset;int		proto = BTPROTO_RFCOMM;BD_ADDR		bda;/* global variables */int forkflag = 0 ;		/* server forks on connection */int loopflag = 0 ;		/* loop server */int serverflag = 0 ;		/* create server socket */int backgflag = 0 ;		/* put yourself in background */char *pipe_program = NULL ;	/* program to execute in two-way pipe */int WaitForever = 0;            /* wait forever for socket on connection refused */int btyflag = 0;void server(struct sockaddr_affix *sa);void client(struct sockaddr_affix *sa);void handle_server_connection(void);/* perror with progname */void perror2(char *s){    fprintf(stderr, "%s: ", progname) ;    perror(s) ;}void usage(void){	printf("Usage: btsocket [--l2cap] [--tty] [ -2hbcfqrvw ] [-i <name>] [ -p command ] bda <port | service>\n");	printf("       btsocket [--l2cap] [--tty] [ -2hbcfqrvw ] [-i <name>] [ -p command ] -s [ -l ] port\n");	printf("\n"		"Notes:\n"		"\t1. *address* argument can be replaced by cache entry number (btclt list)\n"		"\n"		);}void do_exit(void){}int main(int argc, char **argv){	int	c, i, lind, err;	struct sockaddr_affix	saddr;	int port ;			/* port number for socket */	struct option	opts[] = {		{"help", 0, 0, 'h'},		{"l2cap", 0, 0, '2'},		{"tty", 0, 0, 't'},		{"nosdp", 0, 0, 's'},		{"version", 0, 0, 'V'},		{0, 0, 0, 0}	};		if (affix_init(argc, argv, LOG_USER)) {		fprintf(stderr, "Affix initialization failed\n");		return 1;	}	atexit(do_exit);	/* parse options */	while ((c = getopt_long(argc, argv, "2thbcflp:qrsvWw?", opts, &lind)) != -1) {		switch (c) {			case 't':				btyflag = 1;				break;			case '2':				proto = BTPROTO_L2CAP;				break;			case 'h':				usage();				return 0;				break;			case 'f':				forkflag = 1 ;				break ;			case 'c':				crlfflag = 1 ;				break ;			case 'w':				writeonlyflag = 1 ;				break ;			case 'p':				pipe_program = argv[optind - 1] ;				break ;			case 'q':				quitflag = 1 ;				break ;			case 'r':				readonlyflag = 1 ;				break ;			case 's':				serverflag = 1 ;				break ;			case 'v':				verboseflag = 1 ;				break ;			case 'l':				loopflag = 1 ;				break ;			case 'b':				backgflag = 1 ;				break ;			case 'W':				WaitForever = 1 ;			default:				printf("Unknown option: %c\n", optopt);				usage();				exit(15);		}	}	if (__argv[optind] && sscanf(__argv[optind], "bt%d", &i) > 0) {		/* interface name */		sprintf(btdev, "bt%d", i);		optind++;		nameset = 1;	}	if (argc - optind + serverflag != 2) { /* number of args ok? */		usage() ;		exit(15) ;	}	/* check some option combinations */#define senseless(s1, s2) \	fprintf(stderr, "It does not make sense to set %s and %s.\n", (s1), (s2))		if (writeonlyflag && readonlyflag) {			senseless("-r", "-w") ;			exit(15) ;		}	if (loopflag && !serverflag) {		senseless("-l", "not -s") ;		exit(15) ;	}	if (backgflag && !serverflag) {		senseless("-b", "not -s") ;		exit(15) ;	}	if (forkflag && !serverflag) {		senseless("-f", "not -s") ;	}	if (btyflag && proto == BTPROTO_L2CAP) {		senseless("--l2cap", "--tty") ;		exit(15);	}	/* set up signal handling */	//init_signals() ;	saddr.family = PF_AFFIX;	saddr.devnum = hci_devnum(btdev);//HCIDEV_ANY;	saddr.bda = BDADDR_ANY;	/* get port number */	if (!serverflag) {		// get bda		err = btdev_get_bda(&saddr.bda, argv[optind++]);		if (err) {			fprintf(stderr, "Incorrect address given\n");			return 1;		}	} 	/* get port number */	port = sdp_find_port_by_name(&saddr, argv[optind]) ;	if (port < 0) {		fprintf(stderr, "%s: unknown service\n", progname) ;		exit(5) ;	}	saddr.port = port;	/* and go */	if (serverflag) {		if (backgflag) {			affix_background() ;		}		server(&saddr) ;	} else {		client(&saddr) ;	}	       	return 0;}int sock2bty(void){	int	line;	char	dev[32];	line = rfcomm_open_tty(active_socket, RFCOMM_BTY_ANY);	close(active_socket);	if (line < 0) {		perror2("Unable to bind a socket to virtual port device");		exit(errno);	}	sprintf(dev, "/dev/bty%d", line);	active_socket = open(dev, O_RDWR);	if (active_socket < 0) {		fprintf(stderr, "Unable to open port device %s", dev);		exit(errno);	}	return active_socket;}int create_server_socket(struct sockaddr_affix *sa, int queue_length){	int s;	if ((s = socket(PF_AFFIX, SOCK_STREAM, proto)) < 0) {		return -1 ;	}	if (bind(s, (struct sockaddr *)sa, sizeof(*sa)) < 0) {		return -1 ;	}	if (listen(s, queue_length) < 0) {		return -1 ;	}	return s ;}void server(struct sockaddr_affix *sa){	int socket_handle, alen ;	/* allocate server socket */	socket_handle = create_server_socket(sa, 1) ;	if (socket_handle < 0) {		perror2("server socket") ;		exit(1) ;	}	if (verboseflag) {		fprintf(stderr, "listening on port %d\n", sa->port) ;	}	/* server loop */	do {		struct sockaddr_affix sa ;		alen = sizeof(sa) ;		/* accept a connection */		if ((active_socket = accept(socket_handle, (struct sockaddr*) &sa, &alen)) == -1) {			perror2("accept") ;		} else {			if (verboseflag) {				/* if verbose, get name of peer and give message */			}			if (forkflag) {				switch (fork()) {					case 0:						handle_server_connection() ;						exit(0) ;					case -1:						perror2("fork") ;						break ;					default:						close(active_socket) ;						affix_wait_for_children() ;				}			} else {				handle_server_connection() ;			}		}	} while (loopflag) ;}void handle_server_connection(){	/* open pipes to program, if requested */	if (btyflag)		sock2bty();	if (pipe_program) {#if 0		affix_open_pipes(pipe_program);#else		if (affix_dup2std(active_socket) < 0) {			perror2("Unable to duplicate socket descriptor to stdin/stdout");			exit(errno);		}		execl("/bin/sh", "sh", "-c", pipe_program, NULL) ;#endif	}	/* enter IO loop */	affix_do_io() ;	/* connection is closed now */	close(active_socket) ;	if (pipe_program) {		/* remove zombies */		affix_wait_for_children() ;	}}int create_client_socket(struct sockaddr_affix *sa){	int s ;	if ((s = socket(PF_AFFIX, SOCK_STREAM, proto)) < 0) { /* get socket */		return -1 ;	}	if (connect(s, (struct sockaddr*)sa, sizeof(*sa)) < 0) {                  /* connect */		close(s) ;		return -1 ;	}	return s ;}void client(struct sockaddr_affix *sa){	/* get connection */	while (1) {		active_socket = create_client_socket(sa) ;		if (active_socket >= 0 || !WaitForever || errno != ECONNREFUSED)			break;		sleep( 60 );	}	if (active_socket == -1) {		perror2("client socket") ;		exit(errno) ;	} 	if (verboseflag) {		fprintf(stderr, "connected to %s port %d\n", bda2str(&sa->bda), sa->port) ;	}		if (btyflag)		sock2bty();	if (pipe_program) {#if 0		affix_open_pipes(pipe_program);#else		if (affix_dup2std(active_socket) < 0) {			perror2("Unable to duplicate socket descriptor to stdin/stdout");			exit(errno);		}		execl("/bin/sh", "sh", "-c", pipe_program, NULL) ;		exit(errno);#endif	}	/* enter IO loop for stdin/stdout */	affix_do_io() ;	/* connection is closed now */	close(active_socket) ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -