diff --git a/vbox3/vboxgetty/tclscript.c b/vbox3/vboxgetty/tclscript.c index 3f975c81..9f50bedc 100644 --- a/vbox3/vboxgetty/tclscript.c +++ b/vbox3/vboxgetty/tclscript.c @@ -1,9 +1,16 @@ /* -** $Id: tclscript.c,v 1.5 1998/08/28 13:06:15 michael Exp $ +** $Id: tclscript.c,v 1.6 1998/08/29 15:35:09 michael Exp $ ** ** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: tclscript.c,v $ +** Revision 1.6 1998/08/29 15:35:09 michael +** - Removed audio setup - it will crash my machine. Kernel mailing list says +** there are many bugs in the sound ioctl's :-( But audio will work correct +** without the settings. +** - Added voice play function. Played messages are *not* recorded or piped to +** the audio device. +** ** Revision 1.5 1998/08/28 13:06:15 michael ** - Removed audio full duplex mode. Sorry, my soundcard doesn't support ** this :-) @@ -126,7 +133,7 @@ int scr_execute(char *name, struct vboxuser *user) if (user) { - printstring(temppathname, "%s/%s/scripts/%s", user->home, user->name, name); + printstring(temppathname, "%s/tcl/%s", user->home, name); if (access(temppathname, F_OK|R_OK) == 0) canrun = 1; } @@ -314,7 +321,7 @@ int vbox_voice(VBOX_TCLFUNC) int rc; int i; - if (objc == 3) + if (objc >= 3) { cmd = Tcl_GetStringFromObj(objv[1], NULL); arg = Tcl_GetStringFromObj(objv[2], NULL); @@ -356,6 +363,36 @@ int vbox_voice(VBOX_TCLFUNC) /* Nachricht(en) abspielen und dabei auch eingeh- */ /* ende Daten vom Modem bearbeiten. */ + rc = 0; + i = 2; + + while (i < objc) + { + arg = Tcl_GetStringFromObj(objv[i], NULL); + + if ((rc = voice_play(arg)) != 0) break; + + i++; + } + + switch (rc) + { + case 0: + Tcl_SetResult(intp, "OK", NULL); + break; + + case 1: + Tcl_SetResult(intp, "TOUCHTONE", NULL); + break; + + case 2: + Tcl_SetResult(intp, "SUSPEND", NULL); + break; + + default: + Tcl_SetResult(intp, "HANGUP", NULL); + break; + } } break; diff --git a/vbox3/vboxgetty/voice.c b/vbox3/vboxgetty/voice.c index 2cc0a871..027d20f0 100644 --- a/vbox3/vboxgetty/voice.c +++ b/vbox3/vboxgetty/voice.c @@ -1,9 +1,16 @@ /* -** $Id: voice.c,v 1.5 1998/08/28 13:06:18 michael Exp $ +** $Id: voice.c,v 1.6 1998/08/29 15:35:10 michael Exp $ ** ** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: voice.c,v $ +** Revision 1.6 1998/08/29 15:35:10 michael +** - Removed audio setup - it will crash my machine. Kernel mailing list says +** there are many bugs in the sound ioctl's :-( But audio will work correct +** without the settings. +** - Added voice play function. Played messages are *not* recorded or piped to +** the audio device. +** ** Revision 1.5 1998/08/28 13:06:18 michael ** - Removed audio full duplex mode. Sorry, my soundcard doesn't support ** this :-) @@ -91,7 +98,10 @@ static void voice_create_vboxcall(void); static void voice_remove_vboxcall(void); /************************************************************************* - ** + ** voice_init(): Beantwortet den Anruf und startet das Tcl-Skript. ** + ************************************************************************* + ** => vboxuser Zeiger auf die vboxuser-Struktur ** + ** => vboxcall Zeiger auf die vboxcall-Struktur ** *************************************************************************/ int voice_init(struct vboxuser *vboxuser, struct vboxcall *vboxcall) @@ -144,10 +154,10 @@ int voice_init(struct vboxuser *vboxuser, struct vboxcall *vboxcall) voicevbox = 0; + log_line(LOG_D, "Answering call...\n"); + if (scr_init_variables(vars) == 0) { - log_line(LOG_D, "Answering call...\n"); - if (modem_command(&vboxmodem, "ATA", "VCON") > 0) { log_line(LOG_D, "Setting voice compression to \"ulaw\"...\n"); @@ -271,7 +281,7 @@ int voice_wait(int timeout) if (modem_byte_o > 0) { - log_line(LOG_D, "Voice: incoming %03d; outgoing %03d...\n", modem_byte_i, modem_byte_o); + log_line(LOG_D, "Wait: incoming %03d; outgoing %03d...\n", modem_byte_i, modem_byte_o); if (voicedesc != -1) write(voicedesc, modem_line_o, modem_byte_o); if (audiodesc != -1) write(audiodesc, modem_line_o, modem_byte_o); @@ -332,6 +342,197 @@ int voice_wait(int timeout) return(result); } + + + + +/************************************************************************* + ** + *************************************************************************/ + +int voice_play(char *name) +{ + unsigned char modem_line_i[1]; + unsigned char modem_line_o[VBOXVOICE_BUFSIZE + 1]; + int total_byte_i; + int total_byte_o; + int modem_byte_i; + int modem_byte_o; + int result; + int gotdle; + int desc; + char *stop; + int i; + + if ((!name) || (!*name)) + { + log(LOG_W, "No message to play selected (ignored).\n"); + + return(0); + } + + if ((stop = rindex(name, '/'))) name = ++stop; + + log(LOG_D, "Playing \"%s\"...\n", name); + + + printstring(temppathname, "%s/msg/%s", voicevboxuser->home, name); + + errno = 0; + desc = open(temppathname, O_RDONLY); + + if (desc == -1) + { + printstring(temppathname, "%s/msg/%s", PKGDATADIR, name); + + errno = 0; + desc = open(temppathname, O_RDONLY); + } + + if (desc == -1) + { + log(LOG_W, "Can't open \"%s\" (%s).\n", name, strerror(errno)); + + return(0); + } + + + voicestat = VBOXVOICE_STAT_OK; + gotdle = 0; + total_byte_i = 0; + total_byte_o = 0; + + while (voicestat == VBOXVOICE_STAT_OK) + { + modem_byte_i = 0; + modem_byte_o = 0; + result = 0; + + modem_set_timeout(5); + + while ((modem_byte_o < VBOXVOICE_BUFSIZE) && (voicestat == VBOXVOICE_STAT_OK)) + { + if ((i = read(desc, modem_line_i, 1)) != 1) + { + if (i != 0) log(LOG_W, "Can't read \"%s\" [%d] (%s).\n", name, i, strerror(errno)); + + voicestat |= VBOXVOICE_STAT_DONE; + } + else vboxmodem_raw_write(&vboxmodem, modem_line_i, 1); + + if ((result = vboxmodem_raw_read(&vboxmodem, modem_line_i, 1)) == 1) + { + modem_byte_i++; + + if (gotdle) + { + switch (*modem_line_i) + { + case ETX: + voicestat |= VBOXVOICE_STAT_HANGUP; + break; + + default: + break; + } + + gotdle = 0; + } + else + { + if (*modem_line_i == DLE) + { + modem_line_o[modem_byte_o++] = DLE; + + gotdle = 1; + } + + modem_line_o[modem_byte_o++] = *modem_line_i; + } + } + else break; + } + + modem_set_timeout(0); + + total_byte_o += modem_byte_o; + total_byte_i += modem_byte_i; + + if (modem_byte_o > 0) + { + if ((total_byte_o > 1024) || (voicestat != VBOXVOICE_STAT_OK)) + { + log_line(LOG_D, "Play: incoming %04d; outgoing %04d...\n", total_byte_i, total_byte_o); + + total_byte_i = 0; + total_byte_o = 0; + } + + if (voicedesc != -1) write(voicedesc, modem_line_o, modem_byte_o); + if (audiodesc != -1) write(audiodesc, modem_line_o, modem_byte_o); + } + + if ((stop = ctrl_exists(voicevboxuser->home, "suspend", savettydname))) + { + log(LOG_D, "Control \"vboxctrl-suspend-%s\" detected: %s.\n", savettydname, stop); + + voicestat |= VBOXVOICE_STAT_SUSPEND; + } + + if ((stop = ctrl_exists(voicevboxuser->home, "audio", savettydname))) + { + log(LOG_D, "Control \"vboxctrl-audio-%s\" detected: %s.\n", savettydname, stop); + + if (strcasecmp(stop, "HEAR") == 0) voice_hear(1); + if (strcasecmp(stop, "STOP") == 0) voice_hear(0); + } + + if ((result != 1) || (modem_get_timeout())) + { + if (!modem_get_timeout()) + { + log_line(LOG_W, "Can't read voice data (%s).\n", strerror(errno)); + + voicestat |= VBOXVOICE_STAT_TIMEOUT; + } + else voicestat |= VBOXVOICE_STAT_TIMEOUT; + } + } + + modem_set_timeout(0); + + if (desc != -1) close(desc); + + result = 0; + + if (voicestat & VBOXVOICE_STAT_TOUCHTONE) + { + log_line(LOG_D, "Full touchtone sequence found!\n"); + + result = 1; + } + + if (voicestat & VBOXVOICE_STAT_SUSPEND) result = 2; + + if ((voicestat & VBOXVOICE_STAT_HANGUP) || (vboxmodem.nocarrier)) + { + log_line(LOG_D, "Remote caller quit the call!\n"); + + voice_save(0); + voice_hear(0); + + modem_command(&vboxmodem, "", "NO CARRIER"); + + result = -1; + } + + return(result); +} + + + + + /*************************************************************************/ /** voice_save(): Schaltet das mitspeichern der eingehenden Audiodaten **/ /** ein oder aus. **/ @@ -434,7 +635,7 @@ int voice_hear(int mode) return(voice_hear(-1)); } - +/* i = ((VBOXVOICE_NUMFRAGS * VBOXVOICE_FRAGFACT) << 16) | VBOXVOICE_BUFEXP; if (ioctl(audiodesc, SNDCTL_DSP_SETFRAGMENT, &i) == -1) @@ -453,7 +654,7 @@ int voice_hear(int mode) return(voice_hear(-1)); } - i = 0; /* Mono */ + i = 0; if (ioctl(audiodesc, SNDCTL_DSP_STEREO, &i) == -1) { @@ -462,7 +663,7 @@ int voice_hear(int mode) return(voice_hear(-1)); } - i = 8000; /* Sampling rate */ + i = 8000; if (ioctl(audiodesc, SNDCTL_DSP_SPEED, &i) == -1) { @@ -470,6 +671,7 @@ int voice_hear(int mode) return(voice_hear(-1)); } +*/ } return(0); diff --git a/vbox3/vboxgetty/voice.h b/vbox3/vboxgetty/voice.h index 656b3c0d..f528fb2b 100644 --- a/vbox3/vboxgetty/voice.h +++ b/vbox3/vboxgetty/voice.h @@ -1,5 +1,5 @@ /* -** $Id: voice.h,v 1.3 1998/08/28 13:06:19 michael Exp $ +** $Id: voice.h,v 1.4 1998/08/29 15:35:12 michael Exp $ ** ** Copyright 1996-1998 Michael 'Ghandi' Herold */ @@ -30,13 +30,16 @@ #define VBOXVOICE_BUFEXP 5 #define VBOXVOICE_NUMFRAGS 4 #define VBOXVOICE_FRAGFACT 5 -#define VBOXVOICE_BUFSIZE ((1 << VBOXVOICE_BUFEXP) * VBOXVOICE_FRAGFACT) +#define VBOXVOICE_BUFSIZE 32 + + /* ((1 << VBOXVOICE_BUFEXP) * VBOXVOICE_FRAGFACT)*/ #define VBOXVOICE_STAT_OK 0 #define VBOXVOICE_STAT_TIMEOUT 1 #define VBOXVOICE_STAT_HANGUP 2 #define VBOXVOICE_STAT_TOUCHTONE 4 #define VBOXVOICE_STAT_SUSPEND 8 +#define VBOXVOICE_STAT_DONE 16 #define ETX (0x03) #define NL (0x0A) @@ -65,5 +68,6 @@ extern int voice_init(struct vboxuser *, struct vboxcall *); extern int voice_save(int); extern int voice_hear(int); extern int voice_wait(int); +extern int voice_play(char *); #endif /* _VBOX_VOICE_H */