From b23d595aeb7b89ffec2a8794c7a130db89b7808b Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 30 Aug 1998 17:32:05 +0000 Subject: [PATCH] - Total new audio setup - now it works correct and don't crash the machine. - Example answercall.tcl added. - Reduced in-/outgoing data logging. Now only around all 8000 bytes a line ist logged. - Added control file check to play and record function. --- vbox3/vboxgetty/Makefile.am | 11 +- vbox3/vboxgetty/audio.c | 164 +++++++ vbox3/vboxgetty/audio.h | 15 + vbox3/vboxgetty/examples/scripts/Makefile.am | 12 +- .../vboxgetty/examples/scripts/answercall.tcl | 71 +++ vbox3/vboxgetty/tclscript.c | 16 +- vbox3/vboxgetty/voice.c | 442 +++++++++--------- vbox3/vboxgetty/voice.h | 18 +- 8 files changed, 498 insertions(+), 251 deletions(-) create mode 100644 vbox3/vboxgetty/audio.c create mode 100644 vbox3/vboxgetty/audio.h create mode 100644 vbox3/vboxgetty/examples/scripts/answercall.tcl diff --git a/vbox3/vboxgetty/Makefile.am b/vbox3/vboxgetty/Makefile.am index 64f41e44..23b1696f 100644 --- a/vbox3/vboxgetty/Makefile.am +++ b/vbox3/vboxgetty/Makefile.am @@ -1,5 +1,5 @@ ## -## $Id: Makefile.am,v 1.3 1998/07/06 09:05:17 michael Exp $ +## $Id: Makefile.am,v 1.4 1998/08/30 17:32:05 michael Exp $ ## ## system admin executables to install #################################### @@ -38,7 +38,8 @@ vboxgetty_SOURCES = log.c log.h \ vboxgetty.c vboxgetty.h \ voice.c voice.h \ control.c control.h \ - lock.c lock.h + lock.c lock.h \ + audio.c audio.h ## other directories to process ########################################### @@ -48,3 +49,9 @@ SUBDIRS = examples CLEANFILES = *~ MAINTAINERCLEANFILES = Makefile.in + +## Local install routines ################################################ + +install-exec-local: + $(mkinstalldirs) $(sbindir) + $(INSTALL) -s -m 700 vboxgetty $(sbindir)/ diff --git a/vbox3/vboxgetty/audio.c b/vbox3/vboxgetty/audio.c new file mode 100644 index 00000000..db46836b --- /dev/null +++ b/vbox3/vboxgetty/audio.c @@ -0,0 +1,164 @@ +/* +** $Id: audio.c,v 1.1 1998/08/30 17:32:05 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +** +** $Log: audio.c,v $ +** Revision 1.1 1998/08/30 17:32:05 michael +** - Total new audio setup - now it works correct and don't crash the +** machine. +** - Example answercall.tcl added. +** - Reduced in-/outgoing data logging. Now only around all 8000 bytes a +** line ist logged. +** - Added control file check to play and record function. +** +*/ + +#include +#include + +#include +#include +#include +#include + +#include "audio.h" +#include "log.h" +#include "voice.h" + +/************************************************************************* + ** audio_open_dev(): Öffnet das Audiodevice und stellt es ein. ** + ************************************************************************* + ** => name Name des Devices. ** + *************************************************************************/ + +int audio_open_dev(char *name) +{ + int desc; + int mask; + + errno = 0; + + if ((desc = open(name, O_WRONLY)) == -1) + { + log(LOG_W, "Can't open \"%s\" (%s).\n", name, strerror(errno)); + + return(audio_close_dev(desc)); + } + + /* Fragmentgröße und Anzahl der Fragmente einstellen. Die */ + /* höheren 16 Bit sind die Anzahl der Fragmente, die nied- */ + /* eren die Fragmentgröße. Hier 5 Fragmente und 32 Byte */ + /* Fragmentgröße (Bit 4). Es darf nur *ein* Bit für die */ + /* Größe verwendet werden, sonst schmiert der Rechner eis- */ + /* kalt ab! */ + + mask = 0x00050004; + + if (ioctl(desc, SNDCTL_DSP_SETFRAGMENT, &mask) == -1) + { + log(LOG_W, "Error: SNDCTL_DSP_SETFRAGMENT (%s).\n", strerror(errno)); + + return(audio_close_dev(desc)); + } + + /* OSS ab 3.6 gibt muLaw nur zurück, wenn die Audiohardware */ + /* das Format unterstützt. Ansonsten wird muLaw durch eine */ + /* Lookup-Table emuliert. Es wird hier nur geprüft ob U8 */ + /* unterstützt wird. Wenn ja wird muLaw eingestellt, aber */ + /* keine weitere Überprüfung mehr gemacht! */ + + if (ioctl(desc, SNDCTL_DSP_GETFMTS, &mask) == -1) + { + log(LOG_W, "Error: SNDCTL_DSP_GETFMTS (%s).\n", strerror(errno)); + + return(audio_close_dev(desc)); + } + + if (!(mask & AFMT_U8)) + { + log(LOG_E, "Audio device doesn't support U8 (disabled).\n"); + + return(audio_close_dev(desc)); + } + + mask = AFMT_MU_LAW; + + if (ioctl(desc, SNDCTL_DSP_SETFMT, &mask) == -1) + { + log(LOG_W, "Error: SNDCTL_DSP_SETFMT (%s).\n", strerror(errno)); + + return(audio_close_dev(desc)); + } + + if (!(mask & AFMT_MU_LAW)) + { + log(LOG_D, "Audio device doesn't support hardware muLaw.\n"); + } + + /* Stereo-Modus des Devices einstellen. 0 ist Mono und 1 */ + /* ist Stereo. Da nur in Mono aufgezeichnet wird, wird */ + /* auch nur Mono eingestellt. */ + + mask = 0; + + if (ioctl(desc, SNDCTL_DSP_STEREO, &mask) == -1) + { + log(LOG_W, "Error: SNDCTL_DSP_STEREO (%s).\n", strerror(errno)); + + return(audio_close_dev(desc)); + } + + /* Sampling Rate des Devices einstellen. i4l liefert die */ + /* Daten in 8kHz, also werden sie auch damit wiedergege- */ + /* ben. */ + + mask = 8000; + + if (ioctl(desc, SNDCTL_DSP_SPEED, &mask) == -1) + { + log(LOG_W, "Error: SNDCTL_DSP_SPEED (%s).\n", strerror(errno)); + + return(audio_close_dev(desc)); + } + + if (mask != 8000) + { + log(LOG_E, "Audio device doesn't support 8kHz sampling rate (disabled).\n"); + + return(audio_close_dev(desc)); + } + + /* Nach allen Einstellungen zur Sicherheit nochmal die */ + /* Größe der Fragmente überprüfen. Sie muß mit der Größe */ + /* des Modembuffers übereinstimmen (32 Byte). */ + + if (ioctl(desc, SNDCTL_DSP_GETBLKSIZE, &mask) == -1) + { + log(LOG_W, "Error: SNDCTL_DSP_GETBLKSIZE (%s).\n", strerror(errno)); + + return(audio_close_dev(desc)); + } + + if (mask != VBOXVOICE_BUFSIZE) + { + log(LOG_E, "Audio fragment size is not %d (audio disabled).\n", VBOXVOICE_BUFSIZE); + + return(audio_close_dev(desc)); + } + + return(desc); +} + +/************************************************************************* + ** audio_close_dev(): Schließt das Audiodevice. ** + ************************************************************************* + ** => desc File Descriptor des Devices. ** + *************************************************************************/ + +int audio_close_dev(int desc) +{ + if (desc != -1) close(desc); + + return(-1); +} diff --git a/vbox3/vboxgetty/audio.h b/vbox3/vboxgetty/audio.h new file mode 100644 index 00000000..52f27a4c --- /dev/null +++ b/vbox3/vboxgetty/audio.h @@ -0,0 +1,15 @@ +/* +** $Id: audio.h,v 1.1 1998/08/30 17:32:06 michael Exp $ +** +** Copyright 1996-1998 Michael 'Ghandi' Herold +*/ + +#ifndef _VBOX_AUDIO_H +#define _VBOX_AUDIO_H 1 + +/** Prototypes ***********************************************************/ + +extern int audio_open_dev(char *); +extern int audio_close_dev(int); + +#endif /* _VBOX_AUDIO_H */ diff --git a/vbox3/vboxgetty/examples/scripts/Makefile.am b/vbox3/vboxgetty/examples/scripts/Makefile.am index 211cbf77..d6ce2b28 100644 --- a/vbox3/vboxgetty/examples/scripts/Makefile.am +++ b/vbox3/vboxgetty/examples/scripts/Makefile.am @@ -1,15 +1,19 @@ ## -## $Id: Makefile.am,v 1.4 1998/07/06 09:05:55 michael Exp $ +## $Id: Makefile.am,v 1.5 1998/08/30 17:32:15 michael Exp $ ## ## The tcl scripts to install ############################################ -pkgdata_DATA = initmodem.tcl - -EXTRA_DIST = $(pkgdata_DATA) +EXTRA_DIST = initmodem.tcl answercall.tcl ## Clean & Maintenance ################################################### CLEANFILES = *~ MAINTAINERCLEANFILES = Makefile.in +## Local install routines ################################################ + +install-data-local: + $(mkinstalldirs) $(pkgdatadir)/tcl + $(INSTALL) -m 644 initmodem.tcl $(pkgdatadir)/tcl/ + $(INSTALL) -m 644 answercall.tcl $(pkgdatadir)/tcl/ diff --git a/vbox3/vboxgetty/examples/scripts/answercall.tcl b/vbox3/vboxgetty/examples/scripts/answercall.tcl new file mode 100644 index 00000000..b7555cb5 --- /dev/null +++ b/vbox3/vboxgetty/examples/scripts/answercall.tcl @@ -0,0 +1,71 @@ +# $Id: answercall.tcl,v 1.1 1998/08/30 17:32:16 michael Exp $ + +#----------------------------------------------------------------------# +# This script is called after the call is answered. Here you can do # +# message playing, message recording and all other things you want. # +# # +# The following global variables can be used in this script: # +# # +# vbxv_savetime - The time in unix format the script was started # +# vbxv_callerid - The remote's caller ID # +# vbxv_callername - The remote's caller name # +# vbxv_localphone - The local called phone number # +# vbxv_username - The local user # +# vbxv_userhome - The local user's spool directory # +# vbxv_usedscript - The name of this script :-) # +# vbxv_saveulaw - The name of the voice data record file # +# vbxv_savevbox - The name of the voice data description file # +#----------------------------------------------------------------------# +# The script runs under user permissions! # +#----------------------------------------------------------------------# + + # This script is simple and don't use the touchtone feature! If # + # you want touchtone support, create a new answer script in the # + # users spool directory and add the touchtone functions! # + +#vbox_breaklist c + + # Start voice recording and stop audio playback. If you want a # + # permanent audio playback, you can start it here. If not, use # + # vbox to create the temporary vboxctrl-audio control! # + +vbox_voice r start +vbox_voice a stop + + # Now the standard and the beep message are played. The script # + # will be stopped if the remote caller hangup or if the call # + # should be suspended. # + +set result [vbox_voice p standard.ulaw beep.ulaw] + +if {("$result" != "HANGUP") && ("$result" != "SUSPEND")} { + + # Now the message will be recorded. The script will stop if the # + # remote caller hangup or if the call should be suspended. # + + set result [vbox_voice w $vbxv_savetime] +} + + # If the call should be suspended we play a small message to # + # inform the remote caller. # + +if { "$result" == "SUSPEND" } { + vbox_voice p suspend.ulaw +} + +vbox_voice r stop +vbox_voice a stop + + # Uncomment the next lines below and the message will mailed # + # to the same user vboxgetty running for. # + # # + # Note! I use mutt to send the message via attachment. If you # + # don't run mutt, use a similar tool or call a script and # + # create the attachment manualy! # + +#if {([file isfile "$vbxv_saveulaw"]) && ([file isfile "$vbxv_savevbox"])} { +# +# vbox_log D "Mailing recorded message to \"$vbxv_username\"..." +# +# exec mutt -s "New vbox message ($vbxv_callername)" -a "$vbxv_saveulaw" $vbxv_username <$vbxv_savevbox +#} diff --git a/vbox3/vboxgetty/tclscript.c b/vbox3/vboxgetty/tclscript.c index 9f50bedc..d4273e46 100644 --- a/vbox3/vboxgetty/tclscript.c +++ b/vbox3/vboxgetty/tclscript.c @@ -1,9 +1,17 @@ /* -** $Id: tclscript.c,v 1.6 1998/08/29 15:35:09 michael Exp $ +** $Id: tclscript.c,v 1.7 1998/08/30 17:32:07 michael Exp $ ** ** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: tclscript.c,v $ +** Revision 1.7 1998/08/30 17:32:07 michael +** - Total new audio setup - now it works correct and don't crash the +** machine. +** - Example answercall.tcl added. +** - Reduced in-/outgoing data logging. Now only around all 8000 bytes a +** line ist logged. +** - Added control file check to play and record function. +** ** 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 @@ -140,7 +148,7 @@ int scr_execute(char *name, struct vboxuser *user) if (!canrun) { - printstring(temppathname, "%s/%s", PKGDATADIR, name); + printstring(temppathname, "%s/tcl/%s", PKGDATADIR, name); if (access(temppathname, F_OK|R_OK) == 0) canrun = 1; } @@ -425,8 +433,8 @@ int vbox_voice(VBOX_TCLFUNC) /* Eingehende Audiodaten zum mithören an ein */ /* anderes Device schicken. */ - if (strcasecmp(arg, "stop") == 0) rc = voice_hear(0); - if (strcasecmp(arg, "hear") == 0) rc = voice_hear(1); + if (strcasecmp(arg, "stop") == 0) rc = voice_hear(0); + if (strcasecmp(arg, "start") == 0) rc = voice_hear(1); switch (rc) { diff --git a/vbox3/vboxgetty/voice.c b/vbox3/vboxgetty/voice.c index 027d20f0..b7bcf157 100644 --- a/vbox3/vboxgetty/voice.c +++ b/vbox3/vboxgetty/voice.c @@ -1,9 +1,17 @@ /* -** $Id: voice.c,v 1.6 1998/08/29 15:35:10 michael Exp $ +** $Id: voice.c,v 1.7 1998/08/30 17:32:08 michael Exp $ ** ** Copyright 1996-1998 Michael 'Ghandi' Herold ** ** $Log: voice.c,v $ +** Revision 1.7 1998/08/30 17:32:08 michael +** - Total new audio setup - now it works correct and don't crash the +** machine. +** - Example answercall.tcl added. +** - Reduced in-/outgoing data logging. Now only around all 8000 bytes a +** line ist logged. +** - Added control file check to play and record function. +** ** 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 @@ -62,7 +70,6 @@ #include #include -#include #include #include #include @@ -76,6 +83,7 @@ #include "vboxgetty.h" #include "tclscript.h" #include "control.h" +#include "audio.h" /** Variables ************************************************************/ @@ -96,6 +104,7 @@ static char voicename_call[PATH_MAX + 1]; static void voice_stop_vtxrtx(void); static void voice_create_vboxcall(void); static void voice_remove_vboxcall(void); +static void voice_mkdir(char *); /************************************************************************* ** voice_init(): Beantwortet den Anruf und startet das Tcl-Skript. ** @@ -106,6 +115,7 @@ static void voice_remove_vboxcall(void); int voice_init(struct vboxuser *vboxuser, struct vboxcall *vboxcall) { + char connect[12]; char msgsavetime[32]; char voicestoppl[2]; char voicestoprc[2]; @@ -141,8 +151,8 @@ int voice_init(struct vboxuser *vboxuser, struct vboxcall *vboxcall) currenttime = time(NULL); - printstring(voicename_ulaw, "%s/incoming/%11.11lu-%8.8lu.ulaw", vboxuser->home, (unsigned long)currenttime, (unsigned long)getpid()); - printstring(voicename_vbox, "%s/incoming/%11.11lu-%8.8lu.vbox", vboxuser->home, (unsigned long)currenttime, (unsigned long)getpid()); + printstring(voicename_ulaw, "%s/new/%11.11lu-%8.8lu.ulaw", vboxuser->home, (unsigned long)currenttime, (unsigned long)getpid()); + printstring(voicename_vbox, "%s/new/%11.11lu-%8.8lu.vbox", vboxuser->home, (unsigned long)currenttime, (unsigned long)getpid()); /* Den Namen der Call Datei erzeugen, in dem später Daten zum */ /* aktuellen Anruf gesichert werden. */ @@ -154,7 +164,12 @@ int voice_init(struct vboxuser *vboxuser, struct vboxcall *vboxcall) voicevbox = 0; - log_line(LOG_D, "Answering call...\n"); + voice_mkdir(NULL ); + voice_mkdir("new"); + voice_mkdir("msg"); + voice_mkdir("tcl"); + + log_line(LOG_A, "Answering call...\n"); if (scr_init_variables(vars) == 0) { @@ -173,6 +188,16 @@ int voice_init(struct vboxuser *vboxuser, struct vboxcall *vboxcall) voice_create_vboxcall(); + /* Bevor das Skript gestartet wird, werden die */ + /* ersten 11 Byte vom Modem eingelesen. Damit */ + /* wird ein Fehler in i4l umgangen, der die */ + /* Connectmessage bei Full Duplex 2x in den Mo- */ + /* dembuffer schreibt. */ + + modem_set_timeout(2); + vboxmodem_raw_read(&vboxmodem, connect, 11); + modem_set_timeout(0); + rc = scr_execute(vboxcall->script, vboxuser); voice_hear(0); @@ -209,26 +234,28 @@ int voice_init(struct vboxuser *vboxuser, struct vboxcall *vboxcall) return(-1); } -/*************************************************************************/ -/** voice_wait(): Liest eine angegebene Zeit lang Audiodaten vom Modem. **/ -/*************************************************************************/ -/** => timeout Timeout in Sekunden **/ -/*************************************************************************/ -/** <= 0 wenn der Timeout eingetreten ist. **/ -/** 1 wenn eine gültige Touchtonesequenz gefunden wurde. **/ -/** 2 wenn der Anruf suspended werden soll. **/ -/** -1 bei einem Fehler oder Remote hangup **/ -/*************************************************************************/ +/************************************************************************* + ** voice_wait(): Liest eine angegebene Zeit lang Audiodaten vom Modem. ** + ************************************************************************* + ** => timeout Timeout in Sekunden ** + ************************************************************************* + ** <= 0 wenn der Timeout eingetreten ist. ** + ** 1 wenn eine gültige Touchtonesequenz gefunden wurde. ** + ** 2 wenn der Anruf suspended werden soll. ** + ** -1 bei einem Fehler oder Remote hangup ** + *************************************************************************/ int voice_wait(int timeout) { - char modem_line_i[1]; - char modem_line_o[VBOXVOICE_BUFSIZE + 1]; - int modem_byte_i; - int modem_byte_o; - int result; - int gotdle; - char *stop; + 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; + char *stop; voicestat = VBOXVOICE_STAT_OK; gotdle = 0; @@ -279,27 +306,39 @@ int voice_wait(int timeout) else break; } + total_byte_o += modem_byte_o; + total_byte_i += modem_byte_i; + if (modem_byte_o > 0) { - 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); - } - if ((stop = ctrl_exists(voicevboxuser->home, "suspend", savettydname))) - { - log(LOG_D, "Control \"vboxctrl-suspend-%s\" detected: %s.\n", savettydname, stop); + /* Einmal in der Sekunde die Logmessage ausgeben und die */ + /* Controls checken. */ - voicestat |= VBOXVOICE_STAT_SUSPEND; - } + if ((total_byte_o >= VBOXVOICE_SAMPLERATE) || (voicestat != VBOXVOICE_STAT_OK)) + { + log_line(LOG_D, "Wait: incoming %04d; outgoing %04d...\n", total_byte_i, total_byte_o); - if ((stop = ctrl_exists(voicevboxuser->home, "audio", savettydname))) - { - log(LOG_D, "Control \"vboxctrl-audio-%s\" detected: %s.\n", savettydname, stop); + total_byte_i = 0; + total_byte_o = 0; - if (strcasecmp(stop, "HEAR") == 0) voice_hear(1); - if (strcasecmp(stop, "STOP") == 0) voice_hear(0); + 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, "stop") == 0) voice_hear(0); + if (strcasecmp(stop, "start") == 0) voice_hear(1); + } + } } if ((result != 1) || (modem_get_timeout())) @@ -329,7 +368,7 @@ int voice_wait(int timeout) if ((voicestat & VBOXVOICE_STAT_HANGUP) || (vboxmodem.nocarrier)) { - log_line(LOG_D, "Remote caller quit the call!\n"); + log_line(LOG_D, "*** Remote hangup ***\n"); voice_save(0); voice_hear(0); @@ -342,12 +381,16 @@ int voice_wait(int timeout) return(result); } - - - - /************************************************************************* - ** + ** voice_play(): Spielt eine Nachricht ab und liest dabei Voicedaten ** + ** vom Modem. ** + ************************************************************************* + ** name Name der Nachricht die gespielt werden soll. ** + ************************************************************************* + ** <= 0 wenn der Timeout eingetreten ist. ** + ** 1 wenn eine gültige Touchtonesequenz gefunden wurde. ** + ** 2 wenn der Anruf suspended werden soll. ** + ** -1 bei einem Fehler oder Remote hangup ** *************************************************************************/ int voice_play(char *name) @@ -375,7 +418,6 @@ int voice_play(char *name) log(LOG_D, "Playing \"%s\"...\n", name); - printstring(temppathname, "%s/msg/%s", voicevboxuser->home, name); errno = 0; @@ -396,7 +438,6 @@ int voice_play(char *name) return(0); } - voicestat = VBOXVOICE_STAT_OK; gotdle = 0; total_byte_i = 0; @@ -460,31 +501,34 @@ int voice_play(char *name) if (modem_byte_o > 0) { - if ((total_byte_o > 1024) || (voicestat != VBOXVOICE_STAT_OK)) + if (voicedesc != -1) write(voicedesc, modem_line_o, modem_byte_o); + if (audiodesc != -1) write(audiodesc, modem_line_o, modem_byte_o); + + /* Einmal in der Sekunde die Logmessage ausgeben und die */ + /* Controls checken. */ + + if ((total_byte_o >= VBOXVOICE_SAMPLERATE) || (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 ((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, "stop") == 0) voice_hear(0); + if (strcasecmp(stop, "start") == 0) voice_hear(1); + } } - - 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())) @@ -516,7 +560,7 @@ int voice_play(char *name) if ((voicestat & VBOXVOICE_STAT_HANGUP) || (vboxmodem.nocarrier)) { - log_line(LOG_D, "Remote caller quit the call!\n"); + log_line(LOG_D, "*** Remote hangup ***\n"); voice_save(0); voice_hear(0); @@ -529,29 +573,34 @@ int voice_play(char *name) return(result); } - - - - -/*************************************************************************/ -/** voice_save(): Schaltet das mitspeichern der eingehenden Audiodaten **/ -/** ein oder aus. **/ -/*************************************************************************/ -/** => save 1 wenn die Daten gespeichert werden sollen oder 0 **/ -/** wenn nicht. **/ -/** **/ -/** <= 0 wenn die Aktion ausgeführt werden konnte oder -1 **/ -/** einem Fehler. **/ -/*************************************************************************/ +/************************************************************************* + ** voice_save(): Schaltet das mitspeichern der eingehenden Voicedaten ** + ** ein oder aus. ** + ************************************************************************* + ** => save > 0 um das mitspeichern einzuschalten; alle anderen ** + ** Werte schaltes es aus. ** + *************************************************************************/ int voice_save(int save) { - struct vboxsave vboxsave; - int desc; + FILE *vbox; - if (save) + if (save > 0) { - log_line(LOG_D, "Starting audio recording...\n"); + if (voicedesc == -1) + { + log(LOG_D, "Starting voice recording...\n"); + log(LOG_D, "Opening \"%s\"...\n", voicename_ulaw); + + errno = 0; + + if ((voicedesc = open(voicename_ulaw, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) == -1) + { + log(LOG_E, "Can't open/append \"%s\" (%s).\n", voicename_ulaw, strerror(errno)); + + return(-1); + } + } if (!voicevbox) { @@ -559,53 +608,37 @@ int voice_save(int save) /* jetzt erzeugt. Die Datei enthält die Informationen */ /* wer wann wie die Nachricht gesprochen hat. */ - log_line(LOG_D, "Opening \"%s\"...\n", voicename_vbox); + log(LOG_D, "Creating \"%s\"...\n", voicename_vbox); - if ((desc = open(voicename_vbox, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != -1) + errno = 0; + + if ((vbox = fopen(voicename_vbox, "w"))) { - vboxsave.time = time(NULL); + fprintf(vbox, "Name: %s\n" , voicevboxcall->name ); + fprintf(vbox, "ID : %s\n" , voicevboxuser->incomingid); + fprintf(vbox, "Time: %ld\n", time(NULL) ); - xstrncpy(vboxsave.name , voicevboxcall->name , VBOXSAVE_NAME); - xstrncpy(vboxsave.id , voicevboxuser->incomingid, VBOXSAVE_ID ); + fclose(vbox); - if (write(desc, &vboxsave, sizeof(vboxsave)) == sizeof(vboxsave)) - { - voicevbox = 1; - } - - close(desc); + voicevbox = 1; } - else log_line(LOG_E, "Can't create \"%s\".\n", voicename_vbox); + else log(LOG_E, "Can't create \"%s\" (%s).\n", voicename_vbox, strerror(errno)); } - - if (voicedesc == -1) - { - log_line(LOG_D, "Opening \"%s\"...\n", voicename_ulaw); - - voicedesc = open(voicename_ulaw, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - } - - if (voicedesc != -1) return(0); - - log_line(LOG_E, "Can't open/append \"%s\".\n", voicename_ulaw); } else { - log_line(LOG_D, "Stopping audio recording...\n"); - if (voicedesc != -1) { - log_line(LOG_D, "Closing \"%s\"...\n", voicename_ulaw); + log(LOG_D, "Stopping voice recording...\n"); + log(LOG_D, "Closing \"%s\"...\n", voicename_ulaw); close(voicedesc); } voicedesc = -1; - - return(0); } - return(-1); + return(0); } /************************************************************************* @@ -627,74 +660,29 @@ int voice_hear(int mode) { if (audiodesc == -1) { - log(LOG_D, "Starting \"/dev/audio\" mode...\n"); + log(LOG_D, "Starting audio playback...\n"); - if ((audiodesc = open("/dev/audio", O_WRONLY)) == -1) - { - log(LOG_E, "Can't open \"/dev/audio\" (%s).\n", strerror(errno)); - - return(voice_hear(-1)); - } -/* - i = ((VBOXVOICE_NUMFRAGS * VBOXVOICE_FRAGFACT) << 16) | VBOXVOICE_BUFEXP; - - if (ioctl(audiodesc, SNDCTL_DSP_SETFRAGMENT, &i) == -1) - { - log(LOG_E, "Error: SNDCTL_DSP_SETFRAGMENT (%s).\n", strerror(errno)); - - return(voice_hear(-1)); - } - - i = AFMT_MU_LAW; - - if (ioctl(audiodesc, SNDCTL_DSP_SETFMT, &i) == -1) - { - log(LOG_E, "Error: SNDCTL_DSP_SETFMT (%s).\n", strerror(errno)); - - return(voice_hear(-1)); - } - - i = 0; - - if (ioctl(audiodesc, SNDCTL_DSP_STEREO, &i) == -1) - { - log(LOG_E, "Error: SNDCTL_DSP_STEREO (%s).\n", strerror(errno)); - - return(voice_hear(-1)); - } - - i = 8000; - - if (ioctl(audiodesc, SNDCTL_DSP_SPEED, &i) == -1) - { - log(LOG_E, "Error: SNDCTL_DSP_SPEED (%s).\n", strerror(errno)); - - return(voice_hear(-1)); - } -*/ + if ((audiodesc = audio_open_dev("/dev/audio")) == -1) return(-1); } - - return(0); } else { if (audiodesc != -1) { - log(LOG_D, "Stopping \"/dev/audio\" mode...\n"); + log(LOG_D, "Stopping audio playback...\n"); - close(audiodesc); + audio_close_dev(audiodesc); } audiodesc = -1; } - return(mode); + return(0); } - - - - +/************************************************************************* + ** FIXME + *************************************************************************/ static void voice_stop_vtxrtx(void) { @@ -703,83 +691,70 @@ static void voice_stop_vtxrtx(void) if (!vboxmodem.nocarrier) { + /* DLE/DC4 an den Modememluator schicken um den Record-Modus */ + /* zu stoppen. Der Emulator sollte mit DLE/ETX antworten. */ + log_line(LOG_D, "Sending \"\" to stop record mode...\n"); + printstring(line, "%c%c", DLE, DC4); + vboxmodem_raw_write(&vboxmodem, line, 2); + have = 0; + modem_set_timeout(modemsetup.commandtimeout); - - /* DLE/DC4 an den Modememluator schicken um den Record-Modus */ - /* zu stoppen. Der Emulator sollte mit DLE/ETX antworten. */ - - log_line(LOG_D, "Sending \"\" to stop record mode...\n"); - - printstring(line, "%c%c", DLE, DC4); - - vboxmodem_raw_write(&vboxmodem, line, 2); - - have = 0; - - modem_set_timeout(modemsetup.commandtimeout); - - while (vboxmodem_raw_read(&vboxmodem, line, 1) == 1) - { - log_char(LOG_D, *line); - - if (*line != DLE) + while (vboxmodem_raw_read(&vboxmodem, line, 1) == 1) { - if ((*line == ETX) && (have)) + log_char(LOG_D, *line); + + if (*line != DLE) { - have++; + if ((*line == ETX) && (have)) + { + have++; - break; + break; + } + else have = 0; } - else have = 0; + else have = 1; } - else have = 1; - } - modem_set_timeout(0); + modem_set_timeout(0); - if (have == 2) log_line(LOG_D, "Found !\n"); + if (have == 2) log_line(LOG_D, "Found !\n"); + log_line(LOG_D, "Sending \"\" to stop playback mode...\n"); + printstring(line, "%c%c", DLE, ETX); + vboxmodem_raw_write(&vboxmodem, line, 2); - log_line(LOG_D, "Sending \"\" to stop playback mode...\n"); + have = 0; - printstring(line, "%c%c", DLE, ETX); + modem_set_timeout(modemsetup.commandtimeout); - vboxmodem_raw_write(&vboxmodem, line, 2); - - have = 0; - - modem_set_timeout(modemsetup.commandtimeout); - - while (vboxmodem_raw_read(&vboxmodem, line, 1) == 1) - { - log_char(LOG_D, *line); - - if (*line != DLE) + while (vboxmodem_raw_read(&vboxmodem, line, 1) == 1) { - if ((*line == DC4) && (have)) + log_char(LOG_D, *line); + + if (*line != DLE) { - have++; + if ((*line == DC4) && (have)) + { + have++; - break; + break; + } + else have = 0; } - else have = 0; + else have = 1; } - else have = 1; - } - - modem_set_timeout(0); - - if (have == 2) log_line(LOG_D, "Found !\n"); - + modem_set_timeout(0); + if (have == 2) log_line(LOG_D, "Found !\n"); } } @@ -791,30 +766,19 @@ static void voice_stop_vtxrtx(void) static void voice_create_vboxcall(void) { FILE *call; - char done; log(LOG_D, "Creating \"%s\"...\n", voicename_call); - done = 0; - if ((call = fopen(voicename_call, "w"))) { - if (chmod(voicename_call, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) == 0) - { - /* CallerID, Name, tty-Device und die aktuelle PID in der */ - /* Datei speichern. */ + /* CallerID, Name, tty-Device und die aktuelle PID in der */ + /* Datei speichern. */ - fprintf(call, "%s:%s:%s:ld\n", voicevboxuser->incomingid, voicevboxuser->name, savettydname, getpid()); - - done = 1; - } - else log(LOG_E, "Can't chmod \"%s\".\n", voicename_call, strerror(errno)); + fprintf(call, "%s:%s:%s:ld\n", voicevboxuser->incomingid, voicevboxuser->name, savettydname, getpid()); fclose(call); } else log(LOG_E, "Can't create \"%s\" (%s)!\n", voicename_call, strerror(errno)); - - if (!done) voice_remove_vboxcall(); } /************************************************************************* @@ -831,10 +795,26 @@ static void voice_remove_vboxcall(void) } } +/************************************************************************* + ** voice_mkdir(): Erzeugt die Verzeichnisse im Userspool. ** + *************************************************************************/ +static void voice_mkdir(char *name) +{ + if (name) + printstring(temppathname, "%s/%s", voicevboxuser->home, name); + else + printstring(temppathname, "%s", voicevboxuser->home); + log(LOG_D, "Creating directory \"%s\"...\n", temppathname); + errno = 0; - - - + if (mkdir(temppathname, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH) == -1) + { + if (errno != EEXIST) + { + log(LOG_E, "Can't create \"%s\" (%s).\n", temppathname, strerror(errno)); + } + } +} diff --git a/vbox3/vboxgetty/voice.h b/vbox3/vboxgetty/voice.h index f528fb2b..2f37cd10 100644 --- a/vbox3/vboxgetty/voice.h +++ b/vbox3/vboxgetty/voice.h @@ -1,5 +1,5 @@ /* -** $Id: voice.h,v 1.4 1998/08/29 15:35:12 michael Exp $ +** $Id: voice.h,v 1.5 1998/08/30 17:32:10 michael Exp $ ** ** Copyright 1996-1998 Michael 'Ghandi' Herold */ @@ -27,12 +27,8 @@ /** Defines **************************************************************/ -#define VBOXVOICE_BUFEXP 5 -#define VBOXVOICE_NUMFRAGS 4 -#define VBOXVOICE_FRAGFACT 5 -#define VBOXVOICE_BUFSIZE 32 - - /* ((1 << VBOXVOICE_BUFEXP) * VBOXVOICE_FRAGFACT)*/ +#define VBOXVOICE_BUFSIZE 32 +#define VBOXVOICE_SAMPLERATE 8000 #define VBOXVOICE_STAT_OK 0 #define VBOXVOICE_STAT_TIMEOUT 1 @@ -51,15 +47,17 @@ #define CAN (0x18) #define VBOXSAVE_NAME 64 -#define VBOXSAVE_ID 64 +#define VBOXSAVE_CAID 64 +#define VBOXSAVE_VBOX 6 /** Structures ***********************************************************/ struct vboxsave { - time_t time; + char vbox[VBOXSAVE_VBOX + 1]; char name[VBOXSAVE_NAME + 1]; - char id[VBOXSAVE_ID + 1]; + char caid[VBOXSAVE_CAID + 1]; + time_t time; }; /** Prototypes ***********************************************************/