aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/i4b/isdnphone
diff options
context:
space:
mode:
authorHellmuth Michaelis <hm@FreeBSD.org>2000-10-09 14:22:51 +0000
committerHellmuth Michaelis <hm@FreeBSD.org>2000-10-09 14:22:51 +0000
commitba518fe5501ea441126dbdc0b6adfe464b96aa28 (patch)
treec94e061d3dc1b1069b5a0c98c57c0f49eb95d425 /usr.sbin/i4b/isdnphone
parentc199657754e612bbd6230e35af9a70bd4c8226ae (diff)
update to i4b version 0.95.04
Notes
Notes: svn path=/head/; revision=66880
Diffstat (limited to 'usr.sbin/i4b/isdnphone')
-rw-r--r--usr.sbin/i4b/isdnphone/Makefile10
-rw-r--r--usr.sbin/i4b/isdnphone/audio.c159
-rw-r--r--usr.sbin/i4b/isdnphone/defs.h189
-rw-r--r--usr.sbin/i4b/isdnphone/display.c246
-rw-r--r--usr.sbin/i4b/isdnphone/isdn.c191
-rw-r--r--usr.sbin/i4b/isdnphone/isdnphone.874
-rw-r--r--usr.sbin/i4b/isdnphone/main.c451
7 files changed, 1320 insertions, 0 deletions
diff --git a/usr.sbin/i4b/isdnphone/Makefile b/usr.sbin/i4b/isdnphone/Makefile
new file mode 100644
index 000000000000..42d4490983c5
--- /dev/null
+++ b/usr.sbin/i4b/isdnphone/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+PROG = isdnphone
+SRCS = main.c display.c audio.c isdn.c
+MAN8 = isdnphone.8
+
+DPADD = ${LIBCURSES}
+LDADD = -lcurses
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/i4b/isdnphone/audio.c b/usr.sbin/i4b/isdnphone/audio.c
new file mode 100644
index 000000000000..2dc88d6afc2e
--- /dev/null
+++ b/usr.sbin/i4b/isdnphone/audio.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * isdnphone - audio operations
+ * ============================
+ *
+ * $Id: audio.c,v 1.5 1999/12/13 21:25:26 hm Exp $
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:52:39 1999]
+ *
+ *----------------------------------------------------------------------------*/
+
+#include "defs.h"
+
+/*---------------------------------------------------------------------------*
+ *
+ *---------------------------------------------------------------------------*/
+int
+init_audio(char *audiodevice)
+{
+ int ret;
+ int fd;
+ u_long fmt = 0;
+
+ snd_chan_param pa;
+ struct snd_size sz;
+ snd_capabilities soundcaps;
+
+ if((fd = open(audiodevice, O_RDWR)) < 0)
+ {
+ fprintf(stderr, "unable to open %s: %s\n", audiodevice, strerror(errno));
+ return(-1);
+ }
+
+ ret = ioctl(fd, AIOGCAP, &soundcaps);
+
+ if(ret == -1)
+ {
+ fprintf(stderr, "ERROR: ioctl AIOGCAP %s: %s\n", audiodevice, strerror(errno));
+ return(-1);
+ }
+
+ fmt = soundcaps.formats;
+
+ if((fmt & AFMT_FULLDUPLEX) && (!(fmt & AFMT_WEIRD)))
+ {
+#ifdef NOTDEF
+ if(fmt & AFMT_A_LAW)
+ {
+ play_fmt = rec_fmt = AFMT_A_LAW;
+ }
+ else
+#endif
+ if(fmt & AFMT_MU_LAW)
+ {
+ play_fmt = rec_fmt = AFMT_MU_LAW;
+ }
+ else
+ {
+ printf("sorry, A-law or u-law not supported!\n");
+ close(fd);
+ return(-1);
+ }
+ }
+ else
+ {
+ printf("no full-duplex available!\n");
+ close (fd);
+ return(-1);
+ }
+
+ pa.play_format = play_fmt;
+ pa.rec_format = rec_fmt;
+ pa.play_rate = pa.rec_rate = AUDIORATE;
+
+ ret = ioctl(fd, AIOSFMT, &pa);
+
+ if(ret == -1)
+ {
+ fprintf(stderr, "ERROR: ioctl AIOSFMT %s: %s\n", audiodevice, strerror(errno));
+ return(-1);
+ }
+
+ sz.play_size = BCH_MAX_DATALEN;
+ sz.rec_size = BCH_MAX_DATALEN;
+
+ ret = ioctl(fd, AIOSSIZE, &sz);
+
+ if(ret == -1)
+ {
+ fprintf(stderr, "ERROR: ioctl AIOSSIZE %s: %s\n", audiodevice, strerror(errno));
+ return(-1);
+ }
+
+ return(fd);
+}
+
+/*---------------------------------------------------------------------------*
+ * audio device has speech data from microphone
+ *---------------------------------------------------------------------------*/
+void
+audio_hdlr(void)
+{
+ unsigned char buffer[BCH_MAX_DATALEN];
+ int ret;
+
+ ret = read(audiofd, buffer, BCH_MAX_DATALEN);
+
+ if(ret < 0)
+ {
+ fatal("read audio failed: %s", strerror(errno));
+ }
+
+ debug("audio_hdlr: read %d bytes\n", ret);
+
+ if(ret > 0)
+ {
+ telwrite(ret, buffer);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * write audio data to loudspeaker
+ *---------------------------------------------------------------------------*/
+void
+audiowrite(int len, unsigned char *buf)
+{
+ if((write(audiofd, buf, len)) < 0)
+ {
+ fatal("write audio failed: %s", strerror(errno));
+ }
+}
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdnphone/defs.h b/usr.sbin/i4b/isdnphone/defs.h
new file mode 100644
index 000000000000..bbbd5136b988
--- /dev/null
+++ b/usr.sbin/i4b/isdnphone/defs.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * isdnphone - header file
+ * =======================
+ *
+ * $Id: defs.h,v 1.6 1999/12/13 21:25:26 hm Exp $
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:52:46 1999]
+ *
+ *----------------------------------------------------------------------------*/
+
+#include <ncurses.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+
+#include <machine/i4b_ioctl.h>
+#include <machine/i4b_tel_ioctl.h>
+#include <machine/soundcard.h>
+
+/* device file prefixes */
+
+#define I4BTELDEVICE "/dev/i4btel"
+#define I4BTELDDEVICE "/dev/i4bteld"
+#define AUDIODEVICE "/dev/audio"
+
+#define GOOD 0
+#define ERROR (-1)
+#define WARNING (-2)
+
+/* main window dimensions */
+
+#define MW_ROW 5
+#define MW_COL 8
+
+#define MW_WIDTH 60
+#define MW_HEIGHT 8
+
+#define DB_ROW 15
+#define DB_COL 1
+#define DB_WID 79
+#define DB_HGT 9
+
+#define MW_STATEY 2
+#define MW_STATEX 1
+#define MW_STX 10
+
+#define MW_NUMY 4
+#define MW_NUMX 1
+#define MW_NUX 10
+
+#define MW_MSGY 6
+#define MW_MSGX 1
+#define MW_MSX 10
+
+/* fullscreen mode menu window */
+
+#define WMITEMS 4 /* no of items */
+#define WMENU_LEN 18 /* window width */
+#define WMENU_HGT (WMITEMS+4) /* window height */
+#define WMENU_TITLE "Command"
+#define WMENU_POSLN 8 /* window position: lines */
+#define WMENU_POSCO 20 /* window position: columns */
+
+#define CR 0x0d
+#define LF 0x0a
+#define TAB 0x09
+#define CNTRL_D 0x04
+#define CNTRL_L 0x0c
+
+#define ST_IDLE 0
+#define ST_DIALING 1
+#define ST_ACTIVE 2
+#define ST_MAX 2
+
+#define AUDIORATE 8000
+
+#ifdef MAIN
+
+WINDOW *main_w; /* curses main window pointer */
+WINDOW *dbg_w;
+
+int curses_ready = 0; /* flag, curses display is initialized */
+int state = ST_IDLE;
+
+char *states[] = {
+ "IDLE",
+ "DIALING",
+ "ACTIVE"
+};
+
+int dialerfd = -1;
+int audiofd = -1;
+int telfd = -1;
+int curx;
+char numberbuffer[TELNO_MAX];
+
+int play_fmt = AFMT_MU_LAW;
+int rec_fmt = AFMT_MU_LAW;
+
+int opt_unit = 0;
+int opt_d = 0;
+#else
+
+extern WINDOW *main_w;
+extern WINDOW *dbg_w;
+
+extern int curses_ready;
+extern int state;
+
+extern char *states[];
+
+extern int dialerfd;
+extern int audiofd;
+extern int telfd;
+extern int curx;
+extern char numberbuffer[];
+
+extern int play_fmt;
+extern int rec_fmt;
+
+int opt_unit;
+int opt_d;
+
+#endif
+
+extern void audio_hdlr ( void );
+extern void tel_hdlr ( void );
+extern void init_mainw ( void );
+extern int init_audio ( char * );
+extern void do_menu ( void );
+extern int main ( int argc, char **argv );
+extern void do_quit ( int exitval );
+extern void fatal ( char *fmt, ... );
+extern void message ( char *fmt, ... );
+extern void do_dial ( char *number );
+extern void do_hangup ( void );
+
+extern void audiowrite ( int, unsigned char * );
+extern void telwrite ( int, unsigned char * );
+
+extern void newstate ( int newstate );
+
+int init_dial(char *device);
+void dial_hdlr(void);
+int init_tel(char *device);
+
+extern void debug ( char *fmt, ... );
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdnphone/display.c b/usr.sbin/i4b/isdnphone/display.c
new file mode 100644
index 000000000000..1dff9a16f3f9
--- /dev/null
+++ b/usr.sbin/i4b/isdnphone/display.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * isdnphone - some display operations
+ * ===================================
+ *
+ * $Id: display.c,v 1.4 1999/12/13 21:25:26 hm Exp $
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:52:55 1999]
+ *
+ *----------------------------------------------------------------------------*/
+
+#include "defs.h"
+
+/*---------------------------------------------------------------------------*
+ * init curses fullscreen display
+ *---------------------------------------------------------------------------*/
+void
+init_mainw(void)
+{
+ char buffer[512];
+
+ initscr(); /* curses init */
+
+ if((COLS < 80) || (LINES < 24))
+ fatal(0, "ERROR, minimal screensize must be 80x24, is %dx%d, terminating!", COLS, LINES);
+
+
+ if((main_w = newwin(MW_HEIGHT, MW_WIDTH, MW_ROW, MW_COL)) == NULL)
+ fatal("ERROR, curses init main window, terminating!");
+
+ if(opt_d)
+ {
+ if((dbg_w = newwin(DB_HGT, DB_WID, DB_ROW, DB_COL)) == NULL)
+ fatal("ERROR, curses init debug window, terminating!");
+ scrollok(dbg_w, TRUE);
+ }
+
+ raw(); /* raw input */
+ noecho(); /* do not echo input */
+ keypad(stdscr, TRUE); /* use special keys */
+ keypad(main_w, TRUE); /* use special keys */
+
+ box(main_w, 0, 0);
+
+ sprintf(buffer, "isdnphone %d.%d ", VERSION, REL);
+
+ wstandout(main_w);
+ mvwaddstr(main_w, 0, (MW_WIDTH / 2) - (strlen(buffer) / 2), buffer);
+ wstandend(main_w);
+
+ mvwaddstr(main_w, MW_STATEY, MW_STATEX, " state: ");
+ mvwprintw(main_w, MW_STATEY, MW_STX, "%s", states[state]);
+ wmove(main_w, MW_STATEY+1, 1);
+ whline(main_w, 0, MW_WIDTH-2);
+
+ mvwaddstr(main_w, MW_NUMY, MW_NUMX, " number: ");
+ wmove(main_w, MW_NUMY+1, 1);
+ whline(main_w, 0, MW_WIDTH-2);
+
+ mvwaddstr(main_w, MW_MSGY, MW_MSGX, "message: ");
+
+ wrefresh(main_w);
+
+ curses_ready = 1;
+}
+
+/*---------------------------------------------------------------------------*
+ * curses menu for fullscreen command mode
+ *---------------------------------------------------------------------------*/
+void
+do_menu(void)
+{
+ static char *menu[WMITEMS] =
+ {
+ "Hangup",
+#define HANGUP 0
+ "Dial",
+#define DIAL 1
+ "Refresh",
+#define REFRESH 2
+ "Exit",
+#define EXIT 3
+ };
+
+ WINDOW *menu_w;
+ int c;
+ int mpos;
+
+ /* create a new window in the lower screen area */
+
+ if((menu_w = newwin(WMENU_HGT, WMENU_LEN, WMENU_POSLN, WMENU_POSCO )) == NULL)
+ return;
+
+ keypad(menu_w, TRUE); /* use special keys */
+
+ /* draw border around the window */
+
+ box(menu_w, 0, 0);
+
+ /* add a title */
+
+ wstandout(menu_w);
+ mvwaddstr(menu_w, 0, (WMENU_LEN / 2) - (strlen(WMENU_TITLE) / 2), WMENU_TITLE);
+ wstandend(menu_w);
+
+ /* fill the window with the menu options */
+
+ for(mpos=0; mpos <= (WMITEMS-1); mpos++)
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+
+ /* highlight the first menu option */
+
+ mpos = 0;
+ wstandout(menu_w);
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+ wstandend(menu_w);
+
+ /* input loop */
+
+ for(;;)
+ {
+ wrefresh(menu_w);
+
+ c = wgetch(menu_w);
+
+ switch(c)
+ {
+ case TAB:
+ case KEY_DOWN: /* down-move cursor */
+ case ' ':
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+ mpos++;
+ if(mpos >= WMITEMS)
+ mpos = 0;
+ wstandout(menu_w);
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+ wstandend(menu_w);
+ break;
+
+ case KEY_UP: /* up-move cursor */
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+ if(mpos)
+ mpos--;
+ else
+ mpos = WMITEMS-1;
+ wstandout(menu_w);
+ mvwaddstr(menu_w, mpos + 2, 2, menu[mpos]);
+ wstandend(menu_w);
+ break;
+
+ case 'R':
+ case 'r':
+ wrefresh(curscr);
+ goto mexit;
+
+ case 'E':
+ case 'e':
+ case 'Q':
+ case 'q':
+ case 'X':
+ case 'x':
+ do_quit(0);
+ goto mexit;
+ break;
+
+ case 'H':
+ case 'h':
+ do_hangup();
+ goto mexit;
+ break;
+
+ case 'D':
+ case 'd':
+ goto mexit;
+ break;
+
+ case CR:
+ case LF: /* exec highlighted option */
+#ifdef KEY_ENTER
+ case KEY_ENTER:
+#endif
+ switch(mpos)
+ {
+ case DIAL:
+ goto mexit;
+ break;
+ case HANGUP:
+ do_hangup();
+ goto mexit;
+ break;
+ case REFRESH:
+ wrefresh(curscr);
+ break;
+ case EXIT:
+ do_quit(0);
+ break;
+ }
+ goto mexit;
+ break;
+
+ default:
+ goto mexit;
+ break;
+ }
+ }
+
+mexit:
+ /* delete the menu window */
+
+ wclear(menu_w);
+ wrefresh(menu_w);
+ delwin(menu_w);
+
+ /* re-display the original lower window contents */
+
+ touchwin(main_w);
+ wrefresh(main_w);
+}
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdnphone/isdn.c b/usr.sbin/i4b/isdnphone/isdn.c
new file mode 100644
index 000000000000..34719c727269
--- /dev/null
+++ b/usr.sbin/i4b/isdnphone/isdn.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * isdnphone - isdn (i4b) handling
+ * ===============================
+ *
+ * $Id: isdn.c,v 1.4 1999/12/13 21:25:26 hm Exp $
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:53:05 1999]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "defs.h"
+
+/*---------------------------------------------------------------------------*
+ * dialer init
+ *---------------------------------------------------------------------------*/
+int
+init_dial(char *device)
+{
+ int ret;
+
+ if((ret = open(device, O_RDWR)) < 0)
+ {
+ fprintf(stderr, "unable to open %s: %s\n", device, strerror(errno));
+ return(-1);
+ }
+ return(ret);
+}
+
+/*---------------------------------------------------------------------------*
+ * i4bteld data available handler
+ *---------------------------------------------------------------------------*/
+void
+dial_hdlr(void)
+{
+ char result;
+
+ if((read (dialerfd, &result, 1) < 0))
+ {
+ fatal("read failed: %s", strerror(errno));
+ }
+
+ switch(result)
+ {
+ case RSP_CONN:
+ newstate(ST_ACTIVE);
+ message("connected to remote!");
+ break;
+
+ case RSP_BUSY:
+ message("remote is busy!");
+ break;
+
+ case RSP_HUP:
+ newstate(ST_IDLE);
+ message("disconnected from remote!");
+ break;
+
+ case RSP_NOA:
+ message("no answer from remote!");
+ break;
+
+ default:
+ message("unknown response = 0x%2x!", result);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * telephone init
+ *---------------------------------------------------------------------------*/
+int
+init_tel(char *device)
+{
+ int ret;
+ int format;
+
+ if(play_fmt == AFMT_MU_LAW)
+ format = CVT_ALAW2ULAW;
+ else
+ format = CVT_NONE;
+
+ if((ret = open(device, O_RDWR)) < 0)
+ fatal("unable to open %s: %s\n", device, strerror(errno));
+
+ if((ioctl(ret, I4B_TEL_SETAUDIOFMT, &format)) < 0)
+ fatal("ioctl I4B_TEL_SETAUDIOFMT failed: %s", strerror(errno));
+
+ return(ret);
+}
+
+/*---------------------------------------------------------------------------*
+ * dial number
+ *---------------------------------------------------------------------------*/
+void
+do_dial(char *number)
+{
+ char commandbuffer[80];
+ sprintf(commandbuffer, "D%s", number);
+
+ if((write(dialerfd, commandbuffer, strlen(commandbuffer))) < 0)
+ {
+ fatal("write commandbuffer failed: %s", strerror(errno));
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * hangup
+ *---------------------------------------------------------------------------*/
+void
+do_hangup(void)
+{
+ char commandbuffer[80];
+
+ if(state == ST_IDLE)
+ {
+ message("tried hangup while ST_IDLE");
+ return;
+ }
+
+ sprintf(commandbuffer, "H");
+
+ if((write(dialerfd, commandbuffer, strlen(commandbuffer))) < 0)
+ {
+ fatal("write commandbuffer failed: %s", strerror(errno));
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * i4btel speech data available handler
+ *---------------------------------------------------------------------------*/
+void
+tel_hdlr(void)
+{
+ unsigned char buffer[BCH_MAX_DATALEN];
+ int ret;
+
+ ret = read(telfd, buffer, BCH_MAX_DATALEN);
+
+ if(ret < 0)
+ {
+ fatal("read telfd failed: %s", strerror(errno));
+ }
+
+ debug("tel_hdlr: read %d bytes\n", ret);
+
+ if(ret > 0)
+ {
+ audiowrite(ret, buffer);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * write audio data to ISDN
+ *---------------------------------------------------------------------------*/
+void
+telwrite(int len, unsigned char *buf)
+{
+ if((write(telfd, buf, len)) < 0)
+ {
+ fatal("write tel failed: %s", strerror(errno));
+ }
+}
+
+/* EOF */
diff --git a/usr.sbin/i4b/isdnphone/isdnphone.8 b/usr.sbin/i4b/isdnphone/isdnphone.8
new file mode 100644
index 000000000000..62ff227eb8b6
--- /dev/null
+++ b/usr.sbin/i4b/isdnphone/isdnphone.8
@@ -0,0 +1,74 @@
+.\"
+.\" Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id: isdnphone.8,v 1.4 1999/12/13 22:11:55 hm Exp $
+.\"
+.\" $FreeBSD$
+.\"
+.\" last edit-date: [Mon Dec 13 23:05:19 1999]
+.\"
+.\"
+.Dd March 24, 1999
+.Dt ISDNPHONE 8
+.Os
+.Sh NAME
+.Nm isdnphone
+.Nd telephone dialing and more for isdn4bsd
+.Sh SYNOPSIS
+.Nm
+.Op Fl h
+.Op Fl n Ar number
+.Op Fl u Ar unit
+.Sh DESCRIPTION
+.Nm isdnphone
+is part of the isdn4bsd package and is used to handle dialing and hangup
+for the telephone control interfaces /dev/i4bteld<n>.
+.Pp
+Options are provided to dial out or hang up using commandline parameters
+(for use in scripts) or, if none of those options are specified, bring up
+a curses-based fullscreen interface.
+.Pp
+The following options are available:
+.Bl -tag -width Ds
+.It Fl h
+hang up a possibly open telefone connection on the selected interface.
+.It Fl n
+dial the specified number on the selected interface.
+.It Fl u
+Set the unit number to specify the interface used.
+.Pp
+.Sh FILES
+/dev/i4bteld<n>
+.Sh EXAMPLES
+The command:
+.Bd -literal -offset indent
+isdnphone -n 1234
+.Ed
+.Pp
+dials calls the number 1234 to establish a call on /dev/i4btel0
+.Sh AUTHOR
+The
+.Nm
+utility and this manpage were written by
+.An Hellmuth Michaelis Aq hm@kts.org .
diff --git a/usr.sbin/i4b/isdnphone/main.c b/usr.sbin/i4b/isdnphone/main.c
new file mode 100644
index 000000000000..af463570c909
--- /dev/null
+++ b/usr.sbin/i4b/isdnphone/main.c
@@ -0,0 +1,451 @@
+/*
+ * Copyright (c) 1999 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * isdnphone - main module
+ * =======================
+ *
+ * $Id: main.c,v 1.12 1999/12/13 21:25:26 hm Exp $
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Mon Dec 13 21:53:25 1999]
+ *
+ *---------------------------------------------------------------------------*/
+
+#define MAIN
+#include "defs.h"
+
+static void kbd_hdlr(void);
+
+/*---------------------------------------------------------------------------*
+ * usage display and exit
+ *---------------------------------------------------------------------------*/
+static void
+usage(void)
+{
+ fprintf(stderr, "\n");
+ fprintf(stderr, "isdnphone - i4b phone program, version %d.%d.%d, compiled %s %s\n",VERSION, REL, STEP, __DATE__, __TIME__);
+ fprintf(stderr, "usage: isdnphone -d -h -n <number> -u <unit>\n");
+ fprintf(stderr, " -d debug\n");
+ fprintf(stderr, " -h hangup\n");
+ fprintf(stderr, " -n number dial number\n");
+ fprintf(stderr, " -u unit set unit number\n");
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * program entry
+ *---------------------------------------------------------------------------*/
+int
+main(int argc, char **argv)
+{
+ int c;
+ char namebuffer[128];
+ int bschar;
+ int ret;
+ int opt_n = 0;
+ int opt_h = 0;
+ char *number = "";
+
+ numberbuffer[0] = '\0';
+
+ while ((c = getopt(argc, argv, "dhn:u:")) != -1)
+ {
+ switch(c)
+ {
+ case 'd':
+ opt_d = 1;
+ break;
+
+ case 'h':
+ opt_h = 1;
+ break;
+
+ case 'n':
+ number = optarg;
+ opt_n = 1;
+ break;
+
+ case 'u':
+ opt_unit = atoi(optarg);
+ if(opt_unit < 0 || opt_unit > 9)
+ usage();
+ break;
+
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ sprintf(namebuffer,"%s%d", I4BTELDDEVICE, opt_unit);
+
+ if((dialerfd = init_dial(namebuffer)) == -1)
+ exit(1);
+
+ if(opt_n || opt_h)
+ {
+ char commandbuffer[80];
+
+ /* commandline operation goes here */
+
+ if(opt_n)
+ {
+ sprintf(commandbuffer, "D%s", number);
+
+ }
+ else if(opt_h)
+ {
+ sprintf(commandbuffer, "H");
+ }
+
+ if((ret = write(dialerfd, commandbuffer, strlen(commandbuffer))) < 0)
+ {
+ fprintf(stderr, "write commandbuffer failed: %s", strerror(errno));
+ exit(1);
+ }
+
+ close(dialerfd);
+
+ exit(0);
+ }
+
+ if((audiofd = init_audio(AUDIODEVICE)) == -1)
+ exit(1);
+
+ /* fullscreen operation here */
+
+ init_mainw();
+
+ bschar = erasechar();
+ curx = 0;
+
+ wmove(main_w, MW_NUMY, MW_NUX + curx);
+
+ /* go into loop */
+
+ for (;;)
+ {
+ int maxfd = 0;
+ fd_set set;
+ struct timeval timeout;
+
+ FD_ZERO(&set);
+
+ FD_SET(STDIN_FILENO, &set);
+ if(STDIN_FILENO > maxfd)
+ maxfd = STDIN_FILENO;
+
+ FD_SET(dialerfd, &set);
+ if(dialerfd > maxfd)
+ maxfd = dialerfd;
+
+ if(state == ST_ACTIVE)
+ {
+ if(audiofd != -1)
+ {
+ FD_SET(audiofd, &set);
+ if(audiofd > maxfd)
+ maxfd = audiofd;
+ }
+
+ if(telfd != -1)
+ {
+ FD_SET(telfd, &set);
+ if(telfd > maxfd)
+ maxfd = telfd;
+ }
+ }
+
+ timeout.tv_sec = 2;
+ timeout.tv_usec = 0;
+
+ wrefresh(main_w);
+
+ /* if no char is available within timeout, do something */
+
+#ifdef NOTDEF
+ ret = select(maxfd+1, &set, NULL, NULL, &timeout);
+#else
+ ret = select(maxfd+1, &set, NULL, NULL, NULL);
+#endif
+
+ if(ret > 0)
+ {
+ if((telfd != -1) && (FD_ISSET(telfd, &set)))
+ {
+ message("select from ISDN");
+ tel_hdlr();
+ }
+ if((audiofd != -1) && (FD_ISSET(audiofd, &set)))
+ {
+ message("select from audio");
+ audio_hdlr();
+ }
+ if(FD_ISSET(dialerfd, &set))
+ {
+ message("select from tel");
+ dial_hdlr();
+ }
+ if(FD_ISSET(STDIN_FILENO, &set))
+ {
+ message("select from kbd");
+ kbd_hdlr();
+ }
+ }
+ }
+ do_quit(0);
+
+ return(0);
+}
+
+/*---------------------------------------------------------------------------*
+ * keyboard character available handler
+ *---------------------------------------------------------------------------*/
+static void
+kbd_hdlr(void)
+{
+ int kchar;
+
+ kchar = wgetch(main_w); /* get char */
+
+ switch (kchar)
+ {
+ case CR:
+ case LF:
+#ifdef KEY_ENTER
+ case KEY_ENTER:
+#endif
+ if((state == ST_IDLE) &&
+ (numberbuffer[0] != '\0'))
+ {
+ message("dialing .....");
+ do_dial(&numberbuffer[0]);
+ }
+ else
+ {
+ do_menu();
+ }
+ break;
+
+ case CNTRL_D:
+ if(state == ST_IDLE)
+ {
+ do_quit(0);
+ }
+ else
+ {
+ message("cannot exit while not idle!");
+ beep();
+ }
+
+ break;
+
+ case CNTRL_L: /* refresh */
+ touchwin(curscr);
+ wrefresh(curscr);
+ break;
+
+ case KEY_BACKSPACE:
+ case KEY_DC:
+ if (curx == 0)
+ break;
+
+ curx--;
+ mvwaddch(main_w, MW_NUMY, MW_NUX + curx, ' ');
+ numberbuffer[curx] = '\0';
+ wmove(main_w, MW_NUMY, MW_NUX + curx);
+
+ if(curx == 0)
+ message(" ");
+
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if(curx > (TELNO_MAX-1))
+ break;
+
+ mvwaddch(main_w, MW_NUMY, MW_NUX + curx, kchar);
+
+ numberbuffer[curx] = kchar;
+
+ curx++;
+
+ numberbuffer[curx] = '\0';
+
+ message("press ENTER to dial number .....");
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * exit program
+ *---------------------------------------------------------------------------*/
+void
+do_quit(int exitval)
+{
+ close(dialerfd);
+ move(LINES-1, 0);
+ clrtoeol();
+ refresh();
+ endwin();
+ exit(exitval);
+}
+
+/*---------------------------------------------------------------------------*
+ * fatal error exit
+ *---------------------------------------------------------------------------*/
+void
+fatal(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ do_hangup(); /* failsafe */
+
+ if(curses_ready)
+ {
+ close(dialerfd);
+ move(LINES-1, 0);
+ clrtoeol();
+ refresh();
+ endwin();
+ }
+
+ fprintf(stderr, "\nFatal error: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n\n");
+
+ va_end(ap);
+
+ exit(1);
+}
+
+/*---------------------------------------------------------------------------*
+ * message printing
+ *---------------------------------------------------------------------------*/
+void
+message(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ if(curses_ready)
+ {
+ int i;
+ char sbuf[MW_WIDTH];
+
+ wmove(main_w, MW_MSGY, MW_MSX);
+ vsnprintf(sbuf, MW_WIDTH-MW_MSX-1, fmt, ap);
+ waddstr(main_w, sbuf);
+ for(i=strlen(sbuf);i < MW_WIDTH-MW_MSX-2; i++)
+ waddch(main_w, ' ');
+ wmove(main_w, MW_NUMY, MW_NUX + curx);
+ wrefresh(main_w);
+ }
+ else
+ {
+ fprintf(stderr, "ERROR: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ }
+
+ va_end(ap);
+}
+
+/*---------------------------------------------------------------------------*
+ * message printing
+ *---------------------------------------------------------------------------*/
+void
+debug(char *fmt, ...)
+{
+ va_list ap;
+
+ if(opt_d == 0)
+ return;
+
+ va_start(ap, fmt);
+
+ vwprintw(dbg_w, fmt, ap);
+ wrefresh(dbg_w);
+
+ va_end(ap);
+}
+
+/*---------------------------------------------------------------------------*
+ * go to new state
+ *---------------------------------------------------------------------------*/
+void
+newstate(int newstate)
+{
+ int i;
+
+ if(newstate < 0 || newstate > ST_MAX)
+ {
+ message("newstate %d undefined!", newstate);
+ return;
+ }
+
+ state = newstate;
+
+ if(newstate == ST_ACTIVE)
+ {
+ char namebuffer[128];
+
+ sprintf(namebuffer,"%s%d", I4BTELDEVICE, opt_unit);
+ telfd = init_tel(namebuffer);
+ }
+
+ if(newstate == ST_IDLE)
+ {
+ close(telfd);
+ telfd = -1;
+ }
+
+ wmove(main_w, MW_STATEY, MW_STX);
+ waddstr(main_w, states[newstate]);
+
+ for(i=strlen(states[newstate]);i < MW_WIDTH-MW_STX-2; i++)
+ waddch(main_w, ' ');
+
+ wmove(main_w, MW_NUMY, MW_NUX + curx);
+ wrefresh(main_w);
+}
+
+/* EOF */