📄 modememul.c
字号:
/* * modememul.c -- Simple modem emulator which handles dialup over BT * * Copyright (C) 2000, 2001 Axis Communications AB * * Author: Mattias Agren <mattias.agren@axis.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. * * Exceptionally, Axis Communications AB grants discretionary and * conditional permissions for additional use of the text contained * in the company's release of the AXIS OpenBT Stack under the * provisions set forth hereunder. * * Provided that, if you use the AXIS OpenBT Stack with other files, * that do not implement functionality as specified in the Bluetooth * System specification, to produce an executable, this does not by * itself cause the resulting executable to be covered by the GNU * General Public License. Your use of that executable is in no way * restricted on account of using the AXIS OpenBT Stack code with it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the provisions of the GNU * General Public License. * * $Id: modememul.c,v 1.15 2001/10/16 16:56:25 pkj Exp $ * */#include <sys/time.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/wait.h>#include <fcntl.h>#include <time.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <termios.h>#include <stdlib.h>#include <string.h>#include <syslog.h>#include <errno.h>#include <stdarg.h>#include <signal.h>#include "btd.h"#include "bt_misc.h"#include "bt_if.h"#define D(x) //x#define PPPDCMD "pppd"/* Modem emulator stuff */#define RESTART 0#define START_PPP 1#define PPP_FLAGSEQUENCE 0x7e#define PPP_CONTROL_ESCAPE 0x7d#define PPP_CONF_REQ 0x1#define PPP_TERM_REQ 0x5#define PROT_LCP 0xc021int modem_emulator(int bt_fd);int parse_modem_data(int bt_fd, char *data, int len);/* add sig handler which traps SIGHUP */voidsighandler(int sig){ D(syslog(LOG_INFO, "Got signal %d", sig)); if ((sig == SIGQUIT) || (sig == SIGTERM || (sig == SIGHUP))) { D(syslog(LOG_INFO, "Modem emulator exiting")); exit(0); }}voidinit_sighandler(void){ struct sigaction act; D(syslog(LOG_INFO, "Initiating signal handler")); act.sa_handler = sighandler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGHUP, &act, 0); sigaction(SIGQUIT, &act, 0); sigaction(SIGTERM, &act, 0);}intmain(int argc, char **argv){ int btfd; char *speedstr; int done = 0; int line = -1; setsid(); /* become session leader (to catch SIGHUPS) */ init_sighandler(); speedstr = argv[2]; if (sscanf(argv[1], "/dev/ttyBT%d", &line) != 1) { fprintf(stderr, "Invalid arguments to modememulator\n"); exit(1); } while (done != START_PPP) { syslog(LOG_INFO, "Starting modem emulator on %s", argv[1]); if (!bt_isconnected(-1, line)) { D(syslog(LOG_INFO, "No BT connection, stopping modememulator")); exit(0); } if ((btfd = open(argv[1], O_RDWR, 0)) < 0) { perror("open"); exit(1); } /* not necessary for BT devices... */ fd_setup(btfd, speedstr, USE_NO_FLOW); done = modem_emulator(btfd); close(btfd); D(syslog(LOG_INFO, "Closing %s", argv[1])); } /* replace first arg with pppd instead of modem emulator rest of arguments are the same */ argv[0] = PPPDCMD; execvp(PPPDCMD, argv /*pppd_options*/); fprintf(stderr, "%s: no such file or directory\n", PPPDCMD); exit(1);}int modem_emulator(int bt_fd){ char *connect = "CONNECT\r\n"; char *client_server = "CLIENTSERVER\r\n"; char *ok = "OK\r\n"; char data[128]; int done = 0, i; fd_set rfd; D(syslog(LOG_INFO, "Modem emulator starting")); while (!done) { FD_ZERO(&rfd); FD_SET(bt_fd, &rfd); select(FD_SETSIZE, &rfd, NULL, NULL, NULL); if (FD_ISSET(bt_fd, &rfd)) { int len = read(bt_fd, &data, 128); data[len] = 0; D(syslog(LOG_INFO, "Modem emulator got %d bytes", len)); if (len <= 0) return RESTART; /* Check if data is a ppp frame, if so start pppd right away */ for (i = 0; i < len; i++) { if ((data[i] == PPP_FLAGSEQUENCE)) { if ((len - i) >= 7) { unsigned short prot; unsigned short type; /* check for escaped chars */ if (data[i+2] == PPP_CONTROL_ESCAPE) { D(syslog(LOG_INFO, "Found ctrl esc")); prot = ((data[i+4]<<8) | (data[i+5])); } else { prot = ((data[i+3]<<8) | (data[i+4])); } D(syslog(LOG_INFO, "prot : %x", prot)); D(print_data("ppp packet : ", data, len)); if (prot == PROT_LCP) { type = (data[i+7]^0x20); if (type == PPP_TERM_REQ) { syslog(LOG_INFO, "Found PPP Terminate, restart modem emulator"); return RESTART; } else if (type == PPP_CONF_REQ) { syslog(LOG_INFO, "Found PPP Connect, start pppd"); return START_PPP; } else { syslog(LOG_INFO, "Unknown PPP LCP type [%d]", type); return START_PPP; /* start pppd anyway */ } } else { syslog(LOG_INFO, "Unknown PPP prot type [%d]", prot); return RESTART; } } } } /* AT commands */ if (!strncasecmp(data, "ATD", 3)) /* windows standard modem */ { D(syslog(LOG_INFO, "Got ATD")); D(syslog(LOG_INFO, "Write: %s", connect)); write(bt_fd, connect, strlen(connect)); syslog(LOG_INFO, "Modem connected!"); return START_PPP; } else if (!strncasecmp(data, "CLIENT", 6)) /* windows null modem */ { D(syslog(LOG_INFO, "Got CLIENT")); write(bt_fd, client_server, strlen(client_server)); syslog(LOG_INFO, "Nullmodem connected!"); return START_PPP; } else { syslog(LOG_INFO, "Modem emulator replies OK"); write(bt_fd, ok, strlen(ok)); } } } return done;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -