/* simplex repeater controller */ #include #include #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #else #include /* GNU/Linux */ #endif #define BASE_ADDRESS 0x3BC /* 0x3BC or 0x378 or 0x278 */ #define BREC "/usr/bin/brec" /* path to audio recording program */ #define BPLAY "/usr/bin/bplay" /* path to audio playing program */ #define TONES "/usr/local/bin/tones" /* path to tones binary */ #define HZ "8000" /* makes good MP3's */ #define BITS "16" /* "" */ #define SEC "20" /* seconds of audio to record */ #define DELAY 2 /* seconds to delay */ static char *logs = "/usr/local/simplex_repeater"; /* directory to hold audio */ unsigned char Nib1, Nib2; char *optarg, buf[64]; char *sec = SEC; char *brec = BREC; char *bplay = BPLAY; char *tones = TONES; char *bits = BITS; char *hz = HZ; int a, Delete, status, fd; pid_t pid; extern int errno; struct tm *l; time_t t; int check (void); int initial (void); int Key (unsigned char); void usage (char *); void onalarm (int); int main (int argc, char **argv) { if (geteuid () && getuid ()) { fprintf (stderr, "\n\n%s must be run as root to access hardware ports.\n", argv[0]); fprintf (stderr, "Leaving...\n\n"); exit (1); } while ((a = getopt (argc, argv, "dl:")) != EOF) { switch (a) { case 'd': /* Delete recorded audio */ Delete = 1; break; case 'l': /* Directory to log to */ logs = optarg; break; default: usage (argv[0]); break; } } initial (); for (;;) { check (); if (Nib2 == 0) { t = time (NULL); l = localtime (&t); #ifdef DEBUG printf ("Nib1 = 0x%x - Fake 20 second recording...\n", Nib1); sleep (20); printf ("Nib1 = 0x%x - Fake 20 second playing...\n", Nib1); sleep (20); printf ("Beep Beep\a\a\n"); #else if (chdir (logs) != 0) { perror ("chdir"); exit (errno); } snprintf (buf, sizeof (buf), "%.2d.%.2d.%.4d-%.2d:%.2d:%.2d.wav", (1 + l->tm_mon), (l->tm_mday), (1900 + l->tm_year), (l->tm_hour), (l->tm_min), (l->tm_sec)); /* record it */ if ((pid = fork ()) < 0) perror ("fork"); else if (pid == 0) { if (execl (brec, brec, "-t", sec, "-s", hz, "-b", bits, "-w", buf, (char *) 0) < 0) perror ("execl"); } signal (SIGALRM, onalarm); alarm ((atoi (SEC) + 5)); if (wait (&status) == -1 || (status & 0177) != 0) fprintf (stderr, "%s killed.\n", brec); /* Key on and play it */ sleep (DELAY); Key (1); if ((pid = fork ()) < 0) perror ("fork"); else if (pid == 0) { if (execl (bplay, bplay, buf, (char *) 0) < 0) perror ("execl"); } signal (SIGALRM, onalarm); alarm ((atoi (SEC) + 5)); if (wait (&status) == -1 || (status & 0177) != 0) fprintf (stderr, "%s killed.\n", bplay); /* repeater beep */ sleep (1); if ((pid = fork ()) < 0) perror ("fork"); else if (pid == 0) { if (execl (tones, tones, "100", "200", "300", (char *) 0) < 0) perror ("execl"); } signal (SIGALRM, onalarm); alarm (2); if (wait (&status) == -1 || (status & 0177) != 0) fprintf (stderr, "%s killed.\n", tones); /* Key off and delete it */ Key (0); if (Delete == 1) { if (unlink (buf) != 0) { perror ("unlink"); exit (errno); } } #endif } /* Loop forever, lots of cpu time */ } } int check (void) { Nib2 = (inb (BASE_ADDRESS + 1) & 0x40); /* Isolate Pin 10 - 01000000 */ #ifdef DEBUG printf ("Nib2 = 0x%x\n", Nib2); #endif return (0); } int initial (void) { fprintf (stderr, "Running...\n\n"); #ifdef __FreeBSD__ if (open ("/dev/io", O_RDWR) < 0) #else if (ioperm (BASE_ADDRESS, 3, 1) < 0) #endif { fprintf (stderr, "\nERROR: Can't open port 0x%x\n", BASE_ADDRESS); perror ("port"); exit (errno); } Nib1 = (inb (BASE_ADDRESS + 1) & 0x40); /* Isolate Pin 10 - 01000000 */ #ifdef DEBUG printf ("Nib1 = 0x%x\n", Nib1); #endif return (0); } int Key (unsigned char val) { #ifdef __FreeBSD__ if (fd = open ("/dev/io", O_RDWR) < 0) #else if (ioperm (BASE_ADDRESS, 3, 1) < 0) #endif { fprintf (stderr, "ERROR: Can't open port 0x%x\n", BASE_ADDRESS); perror ("port"); exit (errno); } #ifdef __FreeBSD__ outb (BASE_ADDRESS, val); close (fd); #else outb (val, BASE_ADDRESS); #endif return (0); } void usage (char *pname) { fprintf (stderr, "%s ", pname); fprintf (stderr, "[-d] [-l ]\n\n\t-d Delete recorded audio\n\t"); fprintf (stderr, "-l directory to record audio to\n\n"); exit (1); } void onalarm (int val) { kill (pid, SIGHUP); kill (pid + 1, SIGHUP); }