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

📄 btmodem.c

📁 Affix - Bluetooth Protocol Stack for Linux has been developed at Nokia Research Center in Helsinki
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Affix - Bluetooth Protocol Stack for Linux   Copyright (C) 2001 Nokia Corporation   Authors:   		Christian Plog <plog@informatik.uni-bonn.de>	emulation part:		Imre Deak <imre.deak@nokia.com>   		Dmitry Kasatkin <dmitry.kasatkin@nokia.com>   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: btmodem.c,v 1.4 2003/03/14 10:47:40 kds Exp $   Modem multiplexer/emulator   Fixes:   		Dmitry Kasatkin		:*/		#include <syslog.h>#include <sys/types.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <termios.h>#include <errno.h>#include <time.h>#include <string.h>#include <ctype.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <affix/btcore.h>/* The size of the read buffer: */#define BUFFER_SIZE 1024/* Global variables, are used in subroutines: */char *mddev;		/* name of the serial device for the modem*/char *bty;		/* name of the serial device emulation on the bluetoothconnection */char *mdbuf;		/* buffer for data read from the modem but not yet delivered to the bluetooth device */char *btbuf;		/* buffer for data read from the bluetooth device but not yet delivered to the modem */int   btfd;		/* the file handle of the bluetooth serial device */int   mdfd;		/* the file handle of the serial device for the modem */int   verbose;		/* does the user want comments? */int   logging;		/* does the user want logs? */char *logfile;		/* the name of the logfile */FILE *logfp;		/* file handle for the logfile */char *logtext;		/* used for construction of the strings to log */int   silent;		/* whether to be silent on stdout or not */long  btrxcount;	/* bytes received over bluetooth */long  bttxcount;	/* bytes send over bluetooth */long  mdrxcount;	/* bytes received over the modem line */long  mdtxcount;	/* bytes send over the modem line */int   crtscts;		/* use RTS/CTS instead of XON/XOFF */int val;#define TIMEOUT 30000 // reads from device, one character at a time with a fixed timeoutint read_line_nonblk(int fd, char *buf, int max_size){        int     i;        fd_set  fset_rd;        struct  timeval tv;        int     res;         if (max_size < 1)                return -1;        for (i = 0; i < max_size - 1; i++) {                FD_ZERO(&fset_rd);                FD_SET(fd, &fset_rd);                tv.tv_sec = 0;                tv.tv_usec = TIMEOUT * 1000;                if (select(fd + 1, &fset_rd, NULL, NULL, &tv) <= 0)                        return i;                if ((res = read(fd, &buf[i], 1)) <= 0)                        return -1;                buf[i + 1] = '\0';		if (buf[i] == '\n' || buf[i] == '\r')                        return i + 1;        }        return -1;}void nsleep(int sec, int nsec){	struct timespec req;	req.tv_sec = sec;	req.tv_nsec = nsec;	/* 1msec */	nanosleep(&req, NULL);}int write_to_modem(int fd, char *buf, int size){	int i;	for (i = 0; i < size; i++) {		if (write(fd, buf++, 1) != 1)			return -1;		nsleep(0, 500000);	}	return 0;}#define CARRIER_STR "\r\nCARRIER\r\n"#define CONNECT_STR "\r\nCONNECT 9600\r\n"#define OK_STR "\r\nOK\r\n"int emulate(void){	static char 	buf[512];	struct termios	term;	openlog(NULL/*"btmodem"*/, 0, LOG_USER);	if (tcgetattr(1, &term) != 0) {		syslog(LOG_ERR, "tcgetattr failed.\n");		goto failed;	}	cfmakeraw(&term);	term.c_cflag |= CRTSCTS;	if (tcsetattr(1, TCSANOW, &term) != 0) {		syslog(LOG_ERR, "tcsetattr failed.\n");		goto failed;	}	for (;;) {		int i;		int res = read_line_nonblk(0, buf, sizeof(buf));		if (res <= 0) {			syslog(LOG_ERR, "input failed.\n");			goto failed;		}		syslog(LOG_DEBUG, "Got %s\n", buf);		for (i = 0; i < (int)strlen(buf); i++)			buf[i] = toupper(buf[i]);		if (strncmp(buf, "AT", 2) == 0) {			if (strncmp(buf, "ATD", 3) == 0 || strstr(buf, "DT") || strstr(buf, "DP")) {				nsleep(1, 0);				syslog(LOG_DEBUG, "Send %s %s", CARRIER_STR, CONNECT_STR);				if (write_to_modem(1, CARRIER_STR, sizeof(CARRIER_STR) - 1) != 0 ||				    write_to_modem(1, CONNECT_STR, sizeof(CONNECT_STR) - 1) != 0) {					syslog(LOG_ERR, "write to modem failed.\n");					goto failed;				}#if 0				syslog(LOG_DEBUG, "Set CD\n");				val = TIOCM_CD;				if (ioctl(1, TIOCMBIS, &val) != 0) {					syslog(LOG_ERR, "failed to set CD. errno=%d\n", errno);					goto failed;				}#endif				break;			} else {				syslog(LOG_DEBUG, "Send OK\\r");				if (write_to_modem(1, OK_STR, sizeof(OK_STR) - 1) != 0) {					syslog(LOG_ERR, "write to modem failed.\n");					goto failed;				}			}		} else if (strncmp(buf, "CLIENT", 6) == 0) {			syslog(LOG_DEBUG, "Send CLIENTSERVER\n");			write(1, "CLIENTSERVER", 12);			break;		} else {			syslog(LOG_DEBUG, "Send ERROR\n");			write(1, "\r\nERROR\r\n", 9);		}	}	closelog();	return 0;failed:	closelog();	return -1;}/* Writes the string to the log facilities - always expects complete lines! */void logit(char *logtext){	if (silent != 1) {		printf(logtext);		printf("\n");		fflush(stdout);	}	if (logging) {		fprintf(logfp, "btmodem [%d]: ", getpid());		fprintf(logfp, logtext);		fprintf(logfp, "\n");		fflush(logfp);	}}/* Frees all used ressources: */void free_ressources(void){	if (verbose)		logit("Freeing buffer for modem data");	if (mdbuf)		free(mdbuf);	if (verbose)		logit("Freeing buffer for bluetooth data");	if (btbuf)		free(btbuf);	if (verbose)		logit("Closeing modem device");	if (mdfd)		close(mdfd);	if (verbose)		logit("Closing bluetooth serial device");	if (btfd)		close(btfd);	if (verbose)		logit("Freeing buffer for devicename of modem");	if (mddev)		free(mddev);	if (verbose)		logit("Freeing buffer for devicename of bluetooth serial device");	if (bty)		free(bty);	if (verbose)		logit("Freeing buffer for name of log file");	if (logfile)		free(logfile);	if (logtext)		free(logtext);	if (verbose)		logit("Closing log file");	if (logfp)		fclose(logfp);	fflush(stdout);}/* Handles breaks: */void handle_interruption(int sig){	if (sig == 2)		printf("\nInterrupted\n");	else		printf("\nAborted!\n");	fflush(stdout);	free_ressources();	exit(0);}/* Shows all the parameters: */void usage(void){	printf("Syntax: btmodem [-e] [-b bluetooth] [-h] [-l [logfile]] [-m modem] [-q] [-v [-v]] [-x [count]]\n");	printf("        -e              Modem emulation (use stdin/stdout). -m is not used\n");	printf("        -b client       The device name of the client serial connection,\n");	printf("                        usually over a bluetooth connection.\n");	printf("                        Default: /dev/bty0\n");	printf("        -h              Use hardware flow control (RTS/CTS) instead of the\n");	printf("                        default XON/XOFF\n");	printf("        -l [logfile]    Log in a file. The default name for the logfile is\n");	printf("                        /var/log/btmodem\n");	printf("        -m modem        The device name of the serial port on which the modem\n");	printf("                        is connected. The defualt is: /dev/ttyS0\n");	printf("        -q              Quiet mode - do not show any messages on stdout.\n");	printf("                        This has no influence on the information written in\n");	printf("                        the logfile\n");	printf("        -v              Verbose mode: Show a lot of information as output on\n");	printf("                        stdout and in the logfile if logging is activated\n");	printf("                        REMARK: usually only important status messages are\n");	printf("                                shown.\n");	printf("                        WARNING: if both -q and -v are set, -q takes\n");	printf("                                 precedence!\n");	printf("        -v -v           Higher verbosity: Show Even more information,\n");	printf("                        including all data transmitted in verbatim form\n");	printf("        -x [count]      Show the data as hexdump (always, regardless of\n");	printf("                        verbosity. If the quiet mode is set, don't show the\n");	printf("                        hexdump on the screen). The hexdump is written to the\n");	printf("                        logfile. If -v -v and -x is set, the data will be\n");	printf("                        shown twice, once verbatim and once as hexdump. count\n");	printf("                        is the number of bytes shown in each line.\n");	printf("                        Default: 16\n");}/* Setup for the serial ports: */void modem_setup(int desc){	struct termios settings;	int result;	result = tcgetattr(desc, &settings);	if (result < 0) {		perror ("error in tcgetattr");		return;	}	cfmakeraw(&settings);	if (result < 0) {		perror ("error in cfmakeraw");		return;	}	settings.c_cflag &= ~(PARENB | CSIZE | CSTOPB);	settings.c_cflag |= (CS8);	if (crtscts) {		settings.c_cflag |= (CRTSCTS);		settings.c_iflag &= ~(IXON | IXOFF);		logit("Using hardware flow control");	} else {		settings.c_cflag &= ~(CRTSCTS);		settings.c_iflag |= (IXON | IXOFF);		logit("Using software flow control");	}	settings.c_lflag &= ~(ECHO | ICANON);	cfsetspeed(&settings, B115200);	result = tcsetattr (desc, TCSANOW, &settings);	if (result < 0) {		perror ("error in tcgetattr");		return;	}}/* Makes an hexdump out of buffer and prints it with loggit   *//* each line will contain linewidth bytes with two signs each */void print_hexdump(unsigned char *buffer, int bufsize, int linewidth, int modemin){	char *helpbuffer;	int   i, pos;	if (!linewidth)		return;	helpbuffer = (char *)malloc(linewidth * 3 + 1);	memset(helpbuffer, 0, linewidth * 3 + 1);	pos = 0;	if (modemin)		helpbuffer[0] = '>';	else		helpbuffer[0] = '<';	for (i = 0; i < bufsize; i++) {		pos++;		snprintf(helpbuffer + strlen(helpbuffer), linewidth * 3 + 1 - strlen(helpbuffer), "%.2X ", buffer[i]);		/* If line is long enough, then print the line and start a new one: */		if (pos == linewidth) {			pos = 0;			logit(helpbuffer);			memset(helpbuffer, 0, linewidth * 3 + 1);			if (modemin)				helpbuffer[0] = '>';			else				helpbuffer[0] = '<';		}	}	/* If at least one sign is in the buffer, then print it: */	if (pos > 0)		logit(helpbuffer);	free(helpbuffer);}int main(int argc, char **argv){	int    param;                   /* Command line option to parse */	int    endprog;                 /* whether to abort the main loop */	int    mddata;               /* count of bytes read and buffered from the modem */	int    btdata;           /* count of bytes read and buffered from the bluetooth device */	int    mdrxsize;           /* count of bytes now read from the modem */	int    btrxsize;       /* count of bytes now read from the bluetooth device */	int    mdtxsize;          /* count of bytes writen to the modem */	int    bttxsize;      /* count of bytes writen to the bluetooth device */	int    mdsig;     /* the new signal stats on the modem lines */	int    oldmdsig;		/* the old signal stats on the modem lines */	int    btsig; /* the new signal stats on the bluetooth lines */	int    oldbtsig;		/* the old signal stats on the bluetooth lines */	int    setmdsig;         /* which signals to set on the modem lines */	int    setbtsig;     /* which signals to set on the bluetooth lines */	int    unsetmdsig;       /* which signals to unset on the modem lines */	int    unsetbtsig;   /* which signals to unset on the bluetooth lines */	int    maxhandle;               /* the maximum file handle (neccessary for select) */	int    hexdumplinewidth;        /* number of chars in each line of an hexdump */	fd_set readfds;	fd_set writefds;	struct timeval tv;	int	emu = 0;	openlog(NULL/*argv[0]*/, 0, LOG_DAEMON);	BTINFO("%s %s started.", argv[0], affix_version);

⌨️ 快捷键说明

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