This sample shows the processing of multiple incoming voice calls, streaming of audio data in both directions and call transfer to fixed or detected numbers. In addition, detection and processing of DTMF is shown. The sample includes a command line user interface to configure a few parameters and to show active connections and status messages. The following features are shown:
The sample can be built with the GNU compiler collection Version 2.x
or 3.x.
A makefile is included in the sample code. The POSIX threading library
is required for the Diva Server SDK library. To build the sample,
change into the "voiceext2" directory and build the sample with the
"make" command. The executable file "server" will be created in the
"bin"
directory.
Example:
# cd voiceext2
# make
The sample is started from the command line with optional parameters
as described below. The optional parameters define the different
streamed audio
files (messages) for any incoming call, the location where the logfile
and incoming
audio streams are stored and how many additional information should be
displayed on the screen. To use the sample, change your actual
directory to the folder where the
"server" binary is located and start it.
Syntax: 'server
[options]', the options are:
-v
: Print more detailed info to screen
-fg <FileName>
: Greeting message filename
-ft <FileName>
: Transfer message filename
-fb <FileName>
: Busy message filename
-fm <FileName>
: Misc Error message filename
-fa <FileName>
: No Answer message filename
-fq <FileName> : GoodBye message filename
-fs <FileName>
: Beep message file name
-fp <SavePath>
: Location, where the recorded messages and logfiles are stored
-d
<AwDelay> : Time to wait before connecting the call
-m
<MinDigits> : Minimum number of DTMF digits for transfer
-s <DTMF_TO> :
DTMF No Digit Timeout before transfering call
-o <Operator> : Operator Number
Example:
# cd voiceext2/bin
# ./server -fp /home/user/incoming
-d 1 -fg ../mygreeting.wav -o 123
In this example an incoming voice call is accepted after one second.
The greeting message from file '../mygreeting wav' is streamed to the
caller after the call
was accepted. This message is played continuously up to 3 times, if no
input from the user is detected. The caller is adviced to press the
number to which he
wants to be transfered, the '#' key for transfer to the operator or the
'*' key to get
disconnected.
The operator number is set up to '123' in this example,
so if a caller wants to be connected to the operator, he will be
transfered to this number. If the target number is busy or the called
party does not answer the call, a message (answering machine function)
will be recorded as an incoming audio stream file (wave
format) and
stored in the path '/home/user/incoming'. On disconnect, a logfile
in the same directory as the recorded wavefile is expanded by a new entry
with information about the last call.
| makefile | Build rules for use with the make tool |
| src/main.c | Command line interface, main module |
| src/diva_os.c | Operating system specific module |
| src/CallProcessing.cpp |
Functional SDK related module |
| include/dssdk.h | Diva Server SDK interface description |
| include/diva_os.h | Operating system specific module interface definition |
| include/CallProcessing.h |
Functional module interface
definition |
| bin/*.wav | Wavefiles containing audio messages |
| bin/server | Executable binary. Exists only after a successfull build process |
| readme.html | This documentation |
The sample is separated in a functional (SDK related) module, an
operating
system (in this case Linux) specific module and a user interface
module, in this case a command line interface. This makes it easy to
port this sample to
other platforms or to GUI applications. The Linux specific module
"diva_os.c" uses the
socketpair/poll communication and syncronisation model, so it can be
extended easily to process more input events. This model creates a
socketpair, into which various events can be written to. At the receive
side of the socketpair, the "poll()" function is listening for the
queued-in events and distributes these SDK events to the event
handler in the functional module. In parallel,
the required timer function is realised with the timeout parameter of
the
poll() function. More details of the operating system specific module
are out of scope and not discussed further.
The command line interface or main module parses the command line
and sets up internal and common variables accordingly. It then
initialises the Linux specific module before the initialisation of the
functional module is called. In the main 'while' loop, the execution is
blocked until a SDK event or a timer event happens. These events are
distributed to the according handlers in the functional module.
Additionally, the main module contains functions that print logging
messages onto the screen. A more detailed discussion of these modules
is out
of the scope of this documentation, so the following description
focuses on the
communication-related
SDK part or common code, implemented by the file
"src/CallProcessing.cpp".
The sample uses no global data. Instead, the common data is
allocated from the stack of the 'main()' function and the call related
data structures are allocated from heap during initialisation. The data
types are defined in the according include files (*.h).
The operating system specific include file 'diva_os.h' defines, as
most interesting part, a pointer to the callback routine for the SDK.
This pointer is set up during initialisation of the operating system
specific part and used by the SDK during the initialisation of the
functional part.
The functional part's include file 'CallProcessing.h' defines the
'struct server_t' data
structure, which includes module common data, the operating system
specific data 'struct diva_os_t' and the function related data 'struct
diva_func_t'. Second, it defines
'struct diva_func_t' as the functional specific variables. Most
interesting is the pointer '*pConnections', which is an array of call
related data structures of the type 'SingleConnection' that is allocated
from heap during initialisation of the functional part.
The main module calls the event and timer handler of the functional
part. With the event DivaEventIncomingCall, an internal object of
SingleConnection is assigned to this call and a reference to this
object is assigned as application call handle with the call to
DivaAlert and DivaAnswer. This handle is given as the first parameter
for all following events related to this call. This makes it easier for
the application to assign the event to one of the 'SingleConnection'
objects. The sample application answers the call either directly from
'ProcessIncomingCall' or with a delay from the timer handler. In both
cases, the call is answered by calling DivaAnswer, setting the call type
to DivaCallTypeVoice.
Once the call reaches the connected state, the event
DivaEventCallConnected is signaled and audio streaming starts. Note
that the call passes various states before it reaches the
connected state. These states are signaled via DivaEventCallProgress.
The sample does not need these states, however, for a real voice
processing system this information might be useful.
Once the call is disconnected, the event DivaEventCallDisconnected is
signaled. The application retrieves the disconnect reason and stores
the information of the call. It is very important that the
application releases the call by calling DivaCloseCall.
The application registers for DTMF reporting for each call. The tones
are reported via the event DivaEventDTMFReceived. The second parameter
contains the detected DTMF tone. The detected tone is processed
depending on the current internal state and the detected tone. Another
event that triggers certain actions depending on the internal state is
the event DivaEventVoiceFileDone. Several actions start with the
streaming of an audio file. Once the file is streamed the real action,
e.g. the call transfer, is started.
The sample application streams a voice message once the connection
is established. This is done by calling DivaSendVoiceFile. The SDK
confirms that streaming is completed by the event
DivaEventVoiceFileDone. The application now switches to recording mode
by calling DivaRecordVoiceFile. The application also uses
DivaSendMultipleVoiceFiles to stream a message that consists of a file
containing the text and another containing the beep.