📄 serial.c
字号:
/* * taken from * * -------------------------------------------------------------------- * * SMS Client, send messages to mobile phones and pagers * * * * modem.c * * * * Copyright (C) 1997,1998,1999 Angelo Masci * * * * You can contact the author at this e-mail address: * * * * angelo@styx.demon.co.uk * * -------------------------------------------------------------------- * */#include <stdio.h>#include <termios.h>#include <stdlib.h>#include <time.h>#include <fcntl.h>#include <unistd.h>#include <signal.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#if defined(SOLARIS)#include <sys/mkdev.h>#endif#include "serial.h"static struct termios t, t_orig;static long MDM_dtr_init_sleep;int toggle_DTR(int modem, long sleep_period){struct termios t, ot; if (tcgetattr(modem, &t) == -1) { fprintf(stderr, "MODEM: Failed tcgetattr()\n"); close(modem); return -1; } if (tcgetattr(modem, &ot) == -1) { fprintf(stderr, "MODEM: Failed tcgetattr()\n"); close(modem); return -1; } if ((cfsetospeed(&t, B0) == -1) || /* B0 causes */ (cfsetispeed(&t, B0) == -1)) /* DTR to be lowered */ { fprintf(stderr, "MODEM: Failed cfsetspeed() - B0 HANGUP\n"); return -1; } if (tcsetattr(modem,TCSANOW, &t) == -1) { fprintf(stderr, "MODEM: Failed tcsetattr() - B0 HANGUP\n"); return -1; } usleep(sleep_period); /* Allow things to */ /* Settle down DTR may */ /* need to be left */ /* lowered for a period */ /* of time */ /* There appears to be a problem here. */ /* When the modem hangs up after toggling DTR */ /* I can't seem to get tcsetattr() working! */ /* Any ideas what's going on? */ if (tcsetattr(modem,TCSANOW, &ot) == -1) { fprintf(stderr, "MODEM: Failed tcsetattr() - setting speed\n"); return -1; } return 0;}void fcntl_clear(int fd, int flags){ int val; if ((val = fcntl(fd, F_GETFL, 0)) < 0) { fprintf(stderr, "MODEM: fcntl F_GETFL\n"); exit(-1); } val &= ~flags; if (fcntl(fd, F_SETFL, val) < 0) { fprintf(stderr, "MODEM: fcntl F_SETFL\n"); exit(-1); }}int MDM_init(const char *modem_file, char data, char parity, char stop, char flow, long baud){ int modem, t_baud; modem = open(modem_file, O_RDWR|O_NONBLOCK); if (modem == -1) { fprintf(stderr, "MODEM: Failed to open %s\n", modem_file); return -1; } /* ---------------------------- */ /* Toggle DTR to reset modem */ /* ---------------------------- */ if (toggle_DTR(modem, MDM_dtr_init_sleep)) { fprintf(stderr, "MODEM: Failed to toggle DTR\n"); close(modem); return -1; } /* ---------------------------- */ /* Get terminal line state */ /* ---------------------------- */ if (tcgetattr(modem, &t) == -1) { fprintf(stderr, "MODEM: Failed tcgetattr()\n"); close(modem); return -1; } /* ---------------------------- */ /* Save original line state */ /* ---------------------------- */ if (tcgetattr(modem, &t_orig) == -1) { fprintf(stderr, "MODEM: Failed tcgetattr()\n"); close(modem); return -1; } /* ---------------------------- */ /* Set up terminal attributes */ /* for the device */ /* ---------------------------- */ t.c_cflag = 0; t.c_oflag = 0; /* Turn off all output processing */ t.c_iflag = 0; t.c_lflag = 0; /* Everything off in local flags, */ /* disables: */ /* canonical mode */ /* signal generation */ /* echo */ t.c_cc[VMIN] = 1; /* 1 Character buffer */ t.c_cc[VTIME] = 0; /* Block indefinitely */ t.c_cflag |= CREAD | /* Enable receiver */ HUPCL; /* Lower modem lines on last close */ /* 1 stop bit (since CSTOPB off) */ /* ---------------------------- */ /* Set data bits 5 through 8 */ /* ---------------------------- */ t.c_cflag &= ~(CSIZE); /* Mask data size */ switch (data) { case 5: t.c_cflag |= CS5; /* Set 5 bits */ break; case 6: t.c_cflag |= CS6; /* Set 6 bits */ break; case 7: t.c_cflag |= CS7; /* Set 7 bits */ break; case 8: t.c_cflag |= CS8; /* Set 8 bits */ break; default: fprintf(stderr, "MODEM: Number of bits must be either 5,6,7 or 8. was %c\n",data); close(modem); return -1; } /* ---------------------------- */ /* Set parity Even, Odd or None */ /* ---------------------------- */ switch (parity) { case 'E': t.c_cflag |= PARENB; /* Enable parity */ break; case 'O': t.c_cflag |= PARENB; /* Enable parity */ t.c_cflag |= PARODD; /* set parity to odd */ break; case 'N': break; /* No parity DEFAULT */ default: fprintf(stderr, "MODEM: Parity must be either E,O or N\n"); close(modem); return -1; } /* ---------------------------- */ /* Set stop bits 1 or 2 */ /* ---------------------------- */ switch (stop) { case 2: t.c_cflag |= CSTOPB; /* 2 Stop bits */ break; case 1: /* 1 Stop bits DEFAULT */ break; default: fprintf(stderr, "MODEM: Stop bits must be either 1 or 2\n"); close(modem); return -1; } /* ---------------------------- */ /* Set flow control */ /* Hardware or Software */ /* ---------------------------- */ switch (flow) { case 'H': t.c_cflag |= CRTSCTS; /* Hardware Flow */ /* control */ break; case 'S': t.c_iflag |= IXON | /* Xon/Xoff Flow */ IXOFF | /* control */ IXANY; break; default:#if !defined(LINUX) fprintf(stderr, "MODEM: Flow control must be S for this platform\n");#else fprintf(stderr, "MODEM: Flow control must be either H or S for this platform\n");#endif close(modem); return -1; } /* ---------------------------- */ /* Set baud rate */ /* Convert from numeric to */ /* defines set in termios */ /* ---------------------------- */ if (baud >= 38400) { t_baud = B38400; } else if (baud >= 19200) { t_baud = B19200; } else if (baud >= 9600) { t_baud = B9600; } else if (baud >= 4800) { t_baud = B4800; } else if (baud >= 2400) { t_baud = B2400; } else if (baud >= 1200) { t_baud = B1200; } else { t_baud = B300; } if (cfsetispeed(&t, t_baud) == -1) /* Set Input Baud rate */ { fprintf(stderr, "MODEM: Failed Trying to set Input baud to %ld\n", baud); close(modem); return -1; } if (cfsetospeed(&t, t_baud) == -1) /* Set output Baud rate */ { fprintf(stderr, "MODEM: Failed Trying to set Output baud to %ld\n", baud); close(modem); return -1; } /* ---------------------------- */ /* Apply changes to modem */ /* device */ /* ---------------------------- */ if (tcflush(modem, TCIOFLUSH) == -1) { fprintf(stderr, "MODEM: Failed tcflush()\n"); close(modem); return -1; } if (tcsetattr(modem,TCSANOW, &t) == -1) { fprintf(stderr, "MODEM: Failed tcsetattr()\n"); close(modem); return -1; } /* ---------------------------- */ /* Reset mode to blocking */ /* ---------------------------- */ fcntl_clear(modem, O_NONBLOCK); if (toggle_DTR(modem, MDM_dtr_init_sleep)) { fprintf(stderr, "MODEM: Failed to toggle DTR\n"); close(modem); return -1; } return modem;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -