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

📄 modem.c

📁 功能丰富的串口通讯程序
💻 C
字号:
/*    modem.c -- Modem and device handling routines    Copyright (C) 1996  Nadav Cohen    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.*/#include "config.h"#include <fcntl.h>#include <unistd.h>#include <termios.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <ctype.h>#include <setjmp.h>#include <errno.h>#include <sys/time.h>#include <string.h>/* Global definitions */#define FALSE 0#define TRUE 1#define FAILED -1#define PASSED 0#define OK 0#define ELOCK -1#define EOPEN -2#define ESTAT -3#define ECHAR -4#define EGETA -5#define MSWAIT 50/* Global data */struct termios term, saveterm;int modem;jmp_buf jmpbuf;unsigned char CurrentBuffer[128], CurrentBufferFilled;int BufferCounter, UsedGetChar, BytesRead;int Ansi, Avatar, vt100;/* Line status */int DTR, RTS, DSR, CTS, ST, SR, CAR, RNG;char Emu[20];int Emupos=0;int islocked(char *device){ char s[255], lockbuf[128]; int handle, i; struct stat buf; pid_t pid; /* Create the lockfile full name */ sprintf(s, "%s/LCK..%s", Strings[LockPath], device);  /* Check if it exists, if it does check for stale procceses */ if (stat(s,&buf) == 0){ /* Check if we can open it for read only */ if ((handle = open(s, O_RDONLY)) == -1 ) return EOPEN; i = read(handle, &lockbuf, 127); close(handle); if (i > 0) {  lockbuf[i]=0;  sscanf(lockbuf, "%d", &pid);  /* Check if the proccess exists, if not delete the stale lock file */  if (pid > 0 && kill(pid, 0) < 0 && errno == ESRCH){   unlink(s);  }  else return ELOCK; } }   /* Create the lock file */ if ((handle = open(s, O_CREAT|O_WRONLY|O_EXCL)) == -1) return EOPEN;  /* Chnage the file mode so that we can read/write , our group and everybody else can read it too */ fchmod(handle, S_IWRITE|S_IREAD|S_IRGRP|S_IROTH);  /* Enter our pid */ sprintf(s, "%010d\n",getpid()); write(handle,s,strlen(s)); close(handle); return OK;}int unlock(char *device){ char s[255], temp[255]; /* Create the lockfile full name */ strcpy(temp, rindex(device, '/')+1); sprintf(s, "%s/LCK..%s",Strings[LockPath], temp); if (unlink(s) == -1)  return FAILED; return PASSED;}void dummyalrm(int dummy){ dummy = 0; longjmp(jmpbuf, 1);}int initModem(char *device, int baud){ char s[255]; struct stat status; /* Check if modem is locked *** Remove this line */ strcpy(s, rindex(device, '/')+1); if (islocked(s) < 0) return FAILED;  /* Create the full name of the device */ strcpy(s, device); /* Opening the device */ if (setjmp(jmpbuf) == 0) {  modem = -1;  signal(SIGALRM, dummyalrm);  alarm(2);  if ((modem = open(s, O_RDWR|O_NOCTTY|O_NONBLOCK)) == -1) return EOPEN; } alarm(0); signal(SIGALRM, SIG_IGN);  /*Get device's status */ if (fstat(modem, &status) == -1) {  strcpy(s, rindex(device, '/')+1);  unlock(s);  close(modem);  return ESTAT; }  /* Checking if device is charachter device */ if (!S_ISCHR(status.st_mode)) {  unlock(device);  close(modem);  return ECHAR; }  /* Get device's flags using termios */ if (tcgetattr(modem, &term) == -1) {  unlock(device);  close(modem);  return EGETA; } /* Save the flags */ memcpy(&saveterm, &term, sizeof(struct termios));  /* Enter raw mode */  term.c_iflag &= ~(IGNBRK | IGNCR | INLCR | ICRNL | IUCLC | IXANY |                   IXON | IXOFF | INPCK | ISTRIP); term.c_iflag |= BRKINT | IGNPAR; term.c_oflag &= ~OPOST; term.c_lflag = ~(ICANON | ISIG | ECHO | ECHONL | ECHOE | ECHOK); term.c_cflag |= CS8 | CREAD | HUPCL | CRTSCTS;  /* Set the baud */  switch(baud){ case 300: baud = B300; break; case 600: baud = B600; break; case 2400: baud = B2400; break; case 4800: baud = B4800; break; case 9600: baud = B9600; break; case 19200: baud = B19200; break; case 38400: baud = B38400; break; case 57600: baud = B57600; break; case 115200: baud = B115200; break; case 230400: baud = B230400; break; default: baud = B2400; } cfsetospeed(&term, baud); cfsetispeed(&term, baud);  /* Set the attributes */ tcsetattr(modem, TCSANOW, &term);  return OK;}/* Restore the modem to its previous status */void resetModem(){ tcsetattr(modem, TCSANOW, &saveterm);}void closeModem(){ close(modem);}int sethup(int which){ if (tcgetattr(modem, &term) == -1) return EGETA;  if (which == TRUE) {  term.c_cflag |= HUPCL; } else {  term.c_cflag &= ~HUPCL; } tcsetattr(modem, TCSANOW, &term); return 0;}int setxon(int which){ if (tcgetattr(modem, &term) == -1) return EGETA;  if (which == TRUE) {  term.c_iflag |= IXON;  term.c_cflag &= ~CRTSCTS; } else {  term.c_iflag &= ~(IXON | IXOFF | IXANY);  term.c_cflag |= CRTSCTS; } return 0;}void setparms(int baud, char Parity, char Databit, char Stopbit, char Flow){ int i;  if (tcgetattr(modem, &term) >= 0) {  term.c_cflag &= ~CS7 & ~CS8;  if (Databit == 7) i = CS7;  else i = CS8;  term.c_cflag |= i;  term.c_cflag &= ~(PARENB | PARODD);  if (Parity == 'E')   term.c_cflag |= PARENB;  if (Parity == 'O')   term.c_cflag |= PARODD;  if (Stopbit) term.c_cflag |= CSTOPB;  if (Flow & 1) term.c_cflag |= CRTSCTS;  else term.c_cflag &= ~CRTSCTS;  if (Flow & 2) term.c_iflag |= IXON;  else term.c_iflag &= ~IXON;  switch(baud){  case 300: baud = B300; break;  case 600: baud = B600; break;  case 2400: baud = B2400; break;  case 4800: baud = B4800; break;  case 9600: baud = B9600; break;  case 19200: baud = B19200; break;  case 38400: baud = B38400; break;  case 57600: baud = B57600; break;  case 115200: baud = B115200; break;  case 230400: baud = B230400; break;  default: baud = B2400;  }  cfsetospeed(&term, baud);  cfsetispeed(&term, baud);   tcsetattr(modem, TCSANOW, &term); }}/* A function that checks if there is any input from the modem */int charwaiting(){ fd_set set; timeval timeout;  timeout.tv_sec = 0; timeout.tv_usec = MSWAIT;  FD_ZERO(&set); FD_SET(modem, &set); if (select(modem+1, &set, NULL, NULL, &timeout) > 0) {  if (FD_ISSET(modem, &set)) return TRUE; } return FALSE;} /* This function checks if a write can be done */int canwrite(){ fd_set set; timeval timeout;  timeout.tv_sec = 0; timeout.tv_usec = MSWAIT;  FD_ZERO(&set); FD_SET(modem, &set); if (select(modem+1, NULL, &set, NULL, &timeout) > 0) {  if (FD_ISSET(modem, &set)) return TRUE; } return FALSE;}  /* Get a char from the modem */char mgetchar(){ char ch;  read(modem, &ch, 1); return(ch);}/* Send a char to the modem */void msendchar(char ch){ write(modem, &ch, 1);}/* Get a block from modem upto len bytes long, returns the actual bytes read */int mreadblock(char *buf, int len){ int i;  i = read(modem, buf, len); return i;}/* Write len bytes to modem */void mwriteblock(char *buf, int len){ write(modem, buf, len);}int linestatus(){ int result;  ioctl(modem, TIOCMGET, &result); DTR = result & TIOCM_DTR; RTS = result & TIOCM_RTS; DSR = result & TIOCM_DSR; CTS = result & TIOCM_CTS; ST = result & TIOCM_ST; SR = result & TIOCM_SR; CAR = result & TIOCM_CAR; RNG = result & TIOCM_RNG;  return result;}void hangup(){ struct termios tty, save;  tcgetattr(modem, &tty); tcgetattr(modem, &save); cfsetospeed(&tty, B0); cfsetispeed(&tty, B0); tcsetattr(modem, TCSANOW, &tty); sleep(1); tcsetattr(modem, TCSANOW, &save);}void sbreak(){ tcsendbreak(modem, 0);}unsigned char BufferGetChar(){ UsedGetChar = 1; if (BufferCounter == 128){  CurrentBufferFilled = 0;  BufferCounter = 0;  BytesRead = mreadblock((char *)&CurrentBuffer[CurrentBufferFilled], 1);  if (Integers[GlobalStripHigh]) CurrentBuffer[CurrentBufferFilled] &= 0x7F;  CurrentBufferFilled += BytesRead; } return (CurrentBuffer[BufferCounter++] && 0xFF);}

⌨️ 快捷键说明

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