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

📄 main.c

📁 Fax and soft modem source code. - Slow modem You can use this code to build a soft modem function
💻 C
字号:
/*********************************************************
**********************************************************
	main.c
**********************************************************
**********************************************************/
/* Modem for MIPS   AJF	  January 1995
   Main program */

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/fcntl.h>

#include <complex.h>
#include <sinegen.h>
#include <myaudio.h>
#include <bitrates.h>

#include "modem.h"

#define TOFN "/dev/ttyd2"

global int numpages;
global uint options, bitrates;
global vmode veemode;

struct vminfo
  { char *s;
    vmode v;
  };

static vminfo vmodes[] =
  { { "-V21o", V21o }, { "-V21a", V21a }, { "-V23o", V23o }, { "-V23a", V23a },
    { "-V32o", V32o }, { "-V34o", V34o },
    { NULL, (vmode) 0 },	/* terminator */
  };

static char *telno;

static void newhandler(), catchsignal(int), sighandler(int);
static bool legaltelno(char*);
static void setoptions(char**);
static uint bitrate(int), legalbps(vmode);
static void checkoptions(), usage(int);
static void seizeline(), sendanswer();

inline bool isdigit(char ch) { return (ch >= '0') && (ch <= '9'); }


global void main(int argc, char **argv)
  { set_new_handler(newhandler);
    catchsignal(SIGINT); catchsignal(SIGTERM);
    catchsignal(SIGUSR1); catchsignal(SIGABRT);
    setoptions(argv);
    checkoptions();
    if ((options & opt_org) && !legaltelno(telno)) giveup("Illegal telephone number");
    if (options & opt_mod)
      { uint b = legalbps(veemode);
	unless (options & opt_bps) bitrates = b;	/* default is the full set */
	if (bitrates & ~b) giveup("illegal mode-bitrate combination");
      }
    if (options & opt_fax)
      { initdoc();
	if (options & opt_org) readdoc();		/* read whole doc before time-critical part */
      }
    openaudio(); atexit(closeaudio);
    seizeline();
    if (options & opt_org) dialnumber(telno);
    if (options & (opt_fax | opt_mod))
      { if (options & opt_org) waitfortone(CONN_TONE);	/* wait for answer (connect) tone */
	if (options & opt_ans) sendanswer();		/* send answer tone */
	int contime = time(NULL);
	infomsg("Connected");
	if (options & opt_v8) startsession();		/* V.8 procedures */
	if (options & opt_fax) becomefax();
	if (options & opt_mod) becomemodem();
	infomsg("Call duration: %d secs", time(NULL) - contime);
      }
    if ((options & opt_fax) && !(options & opt_org)) writedoc();  /* write whole doc after time-critical part */
    exit(0);
  }

static void newhandler()
  { giveup("No room");
  }

static void catchsignal(int sig)
  { signal(sig, (SIG_PF) sighandler);
  }

static void sighandler(int sig)
  { switch (sig)
      { default:
	    giveup("Killed by signal %d.", sig);

	case SIGUSR1:
	    giveup("Remote modem is not responding.");
      }
  }

static bool legaltelno(char *vec)
  { int n = 0;
    char *dstr = "0123456789*#ABCD";
    if (vec[n] == '+' || vec[n] == '=') n++;
    until (vec[n] == '\0' || strchr(dstr, vec[n]) == NULL) n++;
    return (n <= 20 && vec[n] == '\0');
  }

static void setoptions(char **argv)
  { int ap = 0;
    unless (argv[ap] == NULL) ap++;
    options = bitrates = 0;
    until (argv[ap] == NULL)
      { char *s = argv[ap++];
	if (s[0] == '+' || s[0] == '=')
	  { if (options & opt_org) usage(1);
	    telno = s; options |= opt_org;
	  }
	else if (seq(s, "-ans")) options |= opt_ans;
	else if (seq(s, "-fax")) options |= opt_fax;
	else if (seq(s, "-bps"))
	  { while (argv[ap] != NULL && isdigit(argv[ap][0]))
	      { int bps = atoi(argv[ap++]);
		bitrates |= bitrate(bps);
	      }
	    options |= opt_bps;
	  }
	else if (seq(s,"-V8")) options |= opt_v8;
	else
	  { int k = 0;
	    unless (s[k++] == '-') usage(2);
	    if (s[k] == 'V')
	      { if (options & opt_mod) usage(3);
		int m = 0;
		until (vmodes[m].s == NULL || seq(vmodes[m].s, s)) m++;
		if (vmodes[m].s == NULL) usage(4);
		veemode = vmodes[m].v;
		options |= opt_mod;
		if (veemode == V34o) options |= opt_v8;	    /* V.34 requires V.8 */
	      }
	    else
	      { until (s[k] == '\0')
		  { char ch = s[k++];
		    if (ch == 'v') options |= opt_v;
		    else usage(5);
		  }
	      }
	  }
      }
  }

static uint bitrate(int n)
  { /* see bitrates.h */
    unless (n >= 2400 && n <= 28800 && n%2400 == 0) giveup("unknown bit rate %d", n);
    return 1 << (n/2400 - 1);
  }

static uint legalbps(vmode m)
  { switch (m)
      { default:
	    return 0;

	case V32o:
	    return bps_4800 | bps_7200 | bps_9600 | bps_12000 | bps_14400;

	case V34o:
	    return bps_2400 | bps_4800 | bps_7200 | bps_9600 | bps_12000 | bps_14400 |
		   bps_16800 | bps_19200 | bps_21600 | bps_24000 | bps_26400 | bps_28800;
      }
  }

static void checkoptions()
  { unless (options & (opt_org | opt_ans)) usage(6);		/* need either org/ans	 */
    unless (~options & (opt_org | opt_ans)) usage(7);		/* but not both		 */
    unless (~options & (opt_fax | opt_mod)) usage(8);		/* mustn't have both fax and mod */
  }

static void usage(int n)
  { fprintf(stderr, "Modem Vsn. 5.1 from <fisher@minster.york.ac.uk>\n");
    fprintf(stderr, "Usage(%d): modem [-v] [-V8] {-<mode> | -fax} [-bps <bps> ...] [+<telnum> | -ans]\n", n);
    fprintf(stderr, "Modes:");
    for (int i = 0; vmodes[i].s != NULL; i++) fprintf(stderr, " %s", vmodes[i].s);
    putc('\n', stderr);
    exit(2);
  }

static void seizeline()
  { sleep(2); /* wait in case line has only just been dropped */
    int fd = open(TOFN, O_RDWR); /* this asserts DTR */
    if (fd < 0) giveup("Can't open %s", TOFN);
  }

static void sendanswer()			/* send V.25 answer sequence   */
  { sendpause(2.15);				/* silence for 2.15 sec	       */
    sinegen *sgen = new sinegen(2100.0);
    for (int i = 0; i < 7; i++)
      { int ns = (int) (0.45 * SAMPLERATE);	/* 2100 Hz for 450 ms	       */
	for (int j = 0; j < ns; j++)
	  { float val = sgen -> fnext();
	    outsample(val);
	  }
	sgen -> flipphase();			/* flip phase for next segment */
      }
    delete sgen;
    sendpause(0.075);				/* silence for 75 ms	       */
  }

⌨️ 快捷键说明

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