📄 modemsim.c
字号:
/* modemsim, modem simulator for voice * Copyright (C) 2004 Simone Freddio & Andrea Emanuelli * * 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 */#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <linux/soundcard.h>#include "common.h"#include "util.h"#define FIFO_NAME_W "ttySim"#define FIFO_NAME_R "ttySimWr"#define DSP_NAME "/dev/dsp"static int modem_fd_r = 0;static int modem_fd_w = 0;static int dsp_fd = 0;int app_init(void);void app_close(void);char getcharacter(void);int app_init(void){ char module[] = "create_pipe";/* FILE *fl;*/ int rate = 8000; int stereo = false; int fmt = AFMT_U8; /* * Default playback/record format: * 8 khz, 8 bit/sample, mono * */ remove(FIFO_NAME_W); if (mknod(FIFO_NAME_W, S_IFIFO | 0666, 0)) { TRC(TRC_ERR, module, "mknod write fd"); perror("mknod"); return false; } if ((modem_fd_w = open(FIFO_NAME_W, O_WRONLY)) == -1) { TRC(TRC_ERR, module, "open write fd"); perror("open"); return false; } remove(FIFO_NAME_R); if (mknod(FIFO_NAME_R, S_IFIFO | 0666, 0)) { TRC(TRC_ERR, module, "mknod read fd"); perror("mknod"); return false; } if ((modem_fd_r = open(FIFO_NAME_R, O_RDONLY)) == -1) { TRC(TRC_ERR, module, "open read fd"); perror("open"); return false; } /*--------------------*/ dsp_fd = open(DSP_NAME, O_RDWR); if (dsp_fd == -1) { TRC(TRC_ERR, module, "fopen error (dsp)"); perror("open"); return false; } if (ioctl(dsp_fd, SNDCTL_DSP_RESET, NULL) != 0) { TRC(TRC_ERR, module, "ioctl SNDCTL_DSP_RESET"); perror("ioctl"); return false; } if (ioctl(dsp_fd, SNDCTL_DSP_SYNC, NULL) != 0) { TRC(TRC_ERR, module, "ioctl SNDCTL_DSP_RESET"); perror("ioctl"); return false; } if (ioctl(dsp_fd, SNDCTL_DSP_STEREO, &stereo) != 0) { TRC(TRC_ERR, module, "ioctl SNDCTL_DSP_STEREO"); perror("ioctl"); return false; } if (ioctl(dsp_fd, SNDCTL_DSP_SETFMT, &fmt) != 0) { TRC(TRC_ERR, module, "ioctl SNDCTL_DSP_SETFMT"); perror("ioctl"); return false; } if (ioctl(dsp_fd, SNDCTL_DSP_SPEED, &rate) != 0) { TRC(TRC_ERR, module, "ioctl SNDCTL_DSP_SPEED"); perror("ioctl"); return false; } return true;}void app_close(void){ close(modem_fd_w); close(modem_fd_r); remove(FIFO_NAME_R); remove(FIFO_NAME_W);}char getcharacter(void){ char ch; fd_set set; struct timeval tv; int retsel; int fd = fileno(stdin); tv.tv_sec = 0; tv.tv_usec = 10000; FD_ZERO(&set); FD_SET(fd, &set); fflush(stdin); retsel = select(fd + 1, &set, NULL, NULL, &tv); if (retsel == 0) { return 0; } read(fd, &ch, 1); printf("Key: %d, %c\n", ch, ch); return ch;}int main(void){ char module[] = "modemsim"; char cmd[500]; int ext = false, nr, nw; char trc[500]; char response[500]; int playing = 0, recording = 0; char ch; int queue; printf("-----------------------------------------------------------------\n"); printf("Elenco tasti:\n"); printf("\t[0-9,a-z]\t\tInvia il tono corrispondente al programma\n"); printf("\t!\t\t\tInvia il segnale di RING al programma\n"); printf("\tQ\t\t\tEsce dal simulatore.\n"); printf("-----------------------------------------------------------------\n"); TRC(TRC_INFO, module, "Waiting messages..."); if (!app_init()) { exit(1); } while (!ext) { if (playing == 0 && recording == 0) usleep(100000); ch = getcharacter(); if (ch >= '0' && ch <= '9') { TRC(TRC_INFO, module, "sending shielded DTMF"); sprintf(response, "\x10%c", ch); write(modem_fd_w, response, 2); } if (ch >= 'a' && ch <= 'z') { TRC(TRC_INFO, module, "sending shielded TONE"); sprintf(response, "\x10%c", ch); write(modem_fd_w, response, 2); } if (ch == '!') { TRC(TRC_INFO, module, "sending RING"); write(modem_fd_w, "RING\n", 5); } if (ch == 'Q') ext = true; ioctl(modem_fd_r, FIONREAD, &queue); if (queue > 0) { memset(cmd, 0, sizeof(cmd)); nr = read(modem_fd_r, cmd, sizeof(cmd) - 1); switch (nr) { case -1: perror("Read"); TRC(TRC_ERR, module, "read error"); ext = true; break; case 0: if (recording == 2) { fsync(dsp_fd); nr = read(dsp_fd, response, sizeof(response)); nw = write(modem_fd_w, response, nr); sprintf(trc, "Wrote %d bytes to ttySim (readed %d)", nw, nr); TRC(TRC_INFO, module, trc); if (nr == -1) perror("read"); } break; /* TRC(TRC_INFO, module, "connection reset by peer"); ext = true; break;*/ default: if (strstr(cmd, "AT")) { remove_special_chars(cmd); sprintf(trc, "Command (%3d), '%s'", nr, cmd); TRC(TRC_INFO, module, trc); } /* Default response */ strcpy(response, "OK\n\r"); /* Custom responses */ if (strstr(cmd, "ATE0")) strcpy(response, "ATE0OK\n\r"); if (strstr(cmd, "VTX")) { /* play */ strcpy(response, "CONNECT\n\r"); playing = 1; TRC(TRC_INFO, module, "playing..."); } if (strstr(cmd, "VRX")) { /* record */ strcpy(response, "CONNECT\n\r"); recording = 1; TRC(TRC_INFO, module, "recording..."); } /* Playing feature */ if (playing == 2) { nr = write(dsp_fd, cmd, sizeof(cmd)); fsync(dsp_fd); /* sprintf(trc, "Wrote %d bytes to dsp %d", nr, dsp_fd); TRC(TRC_INFO, module, trc);*/ if (nr == -1) perror("write"); if (memory_search(cmd, nr, "\x10\x03", 2) != -1) { playing = 0; TRC(TRC_INFO, module, "stop"); } } /* Recording feature */ if (recording == 2) { strcpy(response, "OK\n\r"); recording = 0; nw = write(modem_fd_w, response, 4); TRC(TRC_INFO, module, "stop recording"); } if (playing < 2 && recording < 2) { nr = write(modem_fd_w, response, strlen(response)); if (strstr(cmd, "AT")) { remove_special_chars(response); sprintf(trc, "Response (%3d), '%s'", nr, response); TRC(TRC_INFO, module, trc); } } if (playing == 1) playing = 2; if (recording == 1) recording = 2; break; } }/* if (strstr(cmd, "ATH")) ext = true;*/ } app_close(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -