2833 lines
151 KiB
XML
2833 lines
151 KiB
XML
<?xml version="1.0"?>
|
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
|
|
[
|
|
<!ENTITY cs "<application>CapiSuite</application>">
|
|
]>
|
|
<book lang="en">
|
|
<title>CapiSuite 0.5.cvs</title>
|
|
<subtitle><ulink url="http://www.capisuite.de"/></subtitle>
|
|
|
|
|
|
<bookinfo>
|
|
<author>
|
|
<firstname>Gernot</firstname><surname>Hillier</surname>
|
|
<affiliation><address><email>gernot@hillier.de</email></address></affiliation>
|
|
</author>
|
|
</bookinfo>
|
|
|
|
|
|
<preface id="intro"><title>Introduction</title>
|
|
|
|
<sect1><title>Welcome to &cs;</title>
|
|
|
|
<para>Welcome to &cs;, a Python-scriptable ISDN telecommunication suite.</para>
|
|
|
|
<para>
|
|
This manual should help you to be able to use &cs; as quick as possible.
|
|
As I hate reading long documentation just as much as you do, let's jump
|
|
right in.
|
|
</para>
|
|
|
|
<refentry id="capisuite">
|
|
<refmeta>
|
|
<refentrytitle>capisuite</refentrytitle>
|
|
<manvolnum>8</manvolnum>
|
|
</refmeta>
|
|
<refnamediv>
|
|
<refname>capisuite</refname>
|
|
<refpurpose>Python-scriptable ISDN telecommunication suite</refpurpose>
|
|
</refnamediv>
|
|
<refsect1 id="welcome"><title>Description</title>
|
|
<para>&cs; is a Python-scriptable ISDN telecommunication suite.
|
|
It uses the new CAPI interface for accessing
|
|
your ISDN-hardware - so you'll need a card for which a CAPI compatible
|
|
driver is available. Currently these are all cards manufactured by AVM
|
|
and some Eicon cards.
|
|
</para>
|
|
|
|
<para condition="man">This man page only gives a short introduction, for
|
|
the real documentation please see the HTML or PDF manual distributed
|
|
with CapiSuite.</para>
|
|
|
|
<para>&cs; tries to give the user the ability to code his own ISDN applications
|
|
without having to fiddle around with all the dirty programming details like callback
|
|
functions, data buffers, protocol settings and so on.</para>
|
|
|
|
<para>I took a scripting language which is (in my opinion) very easy to understand,
|
|
to use and to learn - especially for beginners: Python. I extended it with some
|
|
functions providing the basic ISDN "building blocks" for the users application.
|
|
Behind these functions the heart of &cs; implements all the dirty details
|
|
a user isn't interested in. My goal was to make script-coding as
|
|
simple as possible but to also give you the flexibility to realize what you
|
|
want.</para>
|
|
|
|
<para>To give you an impression, coding a simple answering machine is as easy as:
|
|
|
|
<informalexample>
|
|
<programlisting>def callIncoming (call, service, call_from, call_to):
|
|
connect_voice (call, 10) # answer call after 10 secs
|
|
audio_send (call, "announcemnt.la") # play announcement
|
|
audio_send (call, "beep.la") # play beep
|
|
audio_receive (call, "call.la", 10) # record call</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<para>Of course some details are missing like creating a unique filename or storing
|
|
the additional information (called and calling party numbers, time, ...) - but I assume
|
|
you got my idea.</para>
|
|
|
|
<para>And - don't be afraid - if you just want to have a normal answering machine or send and
|
|
receive some fax documents, you can use the default scripts distributed with &cs;.
|
|
They give you already some nice features - e.g. the answering machine is multi-user
|
|
ready, supports automatic fax detection and remote inquiry functions. You'll only
|
|
need to tell &cs; some details like your own number, record an own announcement
|
|
and that's it.</para>
|
|
|
|
<para>So &cs; is already equipped for your daily telecommunication needs - but if you don't
|
|
like to do the things the way I do - just change it or completely do it on your
|
|
own. And if you write nice scripts or have changes to my default scripts, I would
|
|
love to get and perhaps make them available for all users if you don't mind.</para>
|
|
</refsect1>
|
|
<refsect1 condition="man"><title>See Also</title>
|
|
<para><simplelist type="inline">
|
|
<member><xref linkend="capisuite.conf"/></member>
|
|
<member><xref linkend="fax.conf"/></member>
|
|
<member><xref linkend="answering_machine.conf"/></member>
|
|
<member><xref linkend="capisuitefax"/></member>
|
|
</simplelist></para>
|
|
</refsect1>
|
|
</refentry>
|
|
</sect1>
|
|
<sect1 id="manual"><title>Structure of the manual</title>
|
|
<para>This manual is split into three big parts.</para>
|
|
|
|
<para>The first part (<xref linkend="gettingstarted"/>) explains how to install &cs;, what
|
|
you can do with the default scripts you have after installing it and how
|
|
to configure them. No line of code will be presented here. If you just want
|
|
to use the default scripts that should be all the reading you need.</para>
|
|
|
|
<para>The second part (<xref linkend="userguide"/>) will tell you how to write your own scripts. It will
|
|
give you a very, very small introduction into Python and a complete reference
|
|
of the commands &cs; adds to it. Last, an overview over the default
|
|
scripts is given which will tell you how they work so you can easily take them
|
|
as starting points and/or examples for your own application.</para>
|
|
|
|
<para>The last part is intended for programmers who want to help in developing the &cs; core.
|
|
It provides an overview of the system and a detailled description for each single class, method
|
|
and attribute. As it's autocreated from the sources of &cs;, it's not included in this document.
|
|
You'll find it locally in <ulink url="../reference/index.html"/> or online at
|
|
<ulink url="http://www.capisuite.de/capisuite/reference/index.html"/>.</para>
|
|
|
|
<para>There are also some additional parts containing "what I also wanted to mention":</para>
|
|
|
|
<para>As &cs; started as a diploma thesis, I want to thank all who helped me so far in <xref linkend="acknowledgements"/></para>
|
|
|
|
<para>When you want to code your own scripts or want to help in developing the &cs; core,
|
|
you'll soon stumble upon some special ISDN and CAPI error codes, which are explained in
|
|
<xref linkend="capicodes"/>.
|
|
</para>
|
|
|
|
<para>If you need further information or support, please have a look at the &cs; home page on
|
|
<ulink url="http://www.capisuite.de"/>. You'll find links to a bug tracker, up-to-date documentation,
|
|
downloads and other ressources there. If you have questions, need support or want to tell us your
|
|
ideas concerning &cs; or your opinion, you're more than welcome on the &cs; mailing lists. Please don't
|
|
write me personal mails with such questions as this won't help other users and I can't answer the same
|
|
question ten times a day, sorry. For informations on how to subscribe to the lists and where to find the
|
|
archives, please also refer to the home page.</para>
|
|
|
|
<para>Hope I managed to whet your appetite - so let's now really start over to get you ready to
|
|
use it.</para>
|
|
</sect1>
|
|
</preface>
|
|
|
|
<chapter id="gettingstarted"><title>Getting Started</title>
|
|
<sect1 id="install"><title>Requirements and installation of &cs;</title>
|
|
|
|
<sect2 id="requirements"><title>Requirements</title>
|
|
<sect3 id="require_hard"><title>Hardware and drivers</title>
|
|
<para>As &cs; uses the CAPI (Common ISDN Application Programming Interface)
|
|
for accessing your ISDN-hardware, you'll need a card for which a CAPI compatible
|
|
driver is available.</para>
|
|
|
|
<para>Currently these are all cards manufactured by AVM and some Eicon cards.
|
|
If you have one of the passive cards of AVM, you'll have to download and
|
|
install their CAPI drivers.</para>
|
|
|
|
<para>With the upcoming Linux 2.6 and the new mISDN project included therein,
|
|
also most cards which are supported by the HiSax driver today will soon have
|
|
a CAPI-compliant driver. Unfortunately, mISDN also won't include a fax protocol
|
|
implementation and therefore passive cards still won't be able to fax in &cs;
|
|
(or in any other program under Linux); fax support for passive cards is only
|
|
available in the binary drivers from AVM currently.</para>
|
|
|
|
<para>There's no way to get &cs; to work with the old ISDN4Linux interface
|
|
and drivers. Presumable there also never will be one because of the mISDN project
|
|
which will replace HiSax/ISDN4Linux soon.</para>
|
|
|
|
<para>There are some distributions (e.g. current versions of SuSE) which
|
|
include the Capi4Linux drivers from AVM already - you'll only have to
|
|
activate them (use YaST2 in SuSE Linux). If you own an active card of AVM
|
|
(e.g. the B1, C2 or C4), then you'll have everything you need already installed.
|
|
SuSE also provides a small frontend to configure &cs; in YaST.</para>
|
|
|
|
<para>&cs; has mainly been tested on AVM ISDN cards, esp. the Fritz!PCI, the Fritz!USB and
|
|
the B1 on the i386 platform but there should be no problem with other
|
|
CAPI-compatible drivers for other cards or on other platforms. Nevertheless,
|
|
some features aren't mandatory for all CAPI-compatible cards, so perhaps
|
|
you may not be able to fax or to switch from voice to fax mode with all
|
|
cards.</para>
|
|
</sect3>
|
|
<sect3 id="require_soft"><title>Software</title>
|
|
<para>&cs; depends on some packages which must be installed before &cs; can be used.</para>
|
|
|
|
<para>I will list them here with a short information why these packages are needed and where to
|
|
find further information on how to install them. It may be always a good idea to check the
|
|
installation tool of your favourite distribution first and see if they're included with it before
|
|
trying to download and install them from the net. Don't be afraid, because there are so many -
|
|
most of them are included in nearly every distribution and perhaps are already installed on your system.</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>Python >= 2.2</term>
|
|
<listitem><para>&cs; uses an embedded Python interpreter to interpret the given scripts -
|
|
so you'll need an installed and working version of Python. This should be included
|
|
in mostly every up-to-date Linux distribution. For further infos on Python, a nice
|
|
tutorial and much more, please go to <ulink url="http://www.python.org"/></para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>sox >= 12.17.3</term>
|
|
<listitem><para>This is the swiss-knife for converting audio formats. It's not required
|
|
by the &cs; core, but will be very helpful if you want to hear or record the
|
|
voice files used for calls on your machine. It's also required if you want to
|
|
use the default scripts of &cs;. I'll bet this is included in your distribution
|
|
and most likely already installed on your system. Just try to start <command>sox</command>
|
|
to get sure. As Helmut Gruber pointed out, you need at least version 12.17.3, as this
|
|
version started to handle inverse A-Law files. You'll find more details on
|
|
<ulink url="http://sox.sourceforge.net"/>
|
|
</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>sfftobmp</term>
|
|
<listitem><para>&cs; will save fax files in the CAPI specific format Structured Fax File (SFF).
|
|
sfftobmp is a small but useful converter to convert this files to more
|
|
common formats like JPEG, TIFF or BMP. Get it on <ulink url="http://sfftools.sourceforge.net/sfftobmp.html"/>.
|
|
It's again not needed by the &cs; core, but by the default scripts.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>sffview</term>
|
|
<listitem><para>This tool is a simple but useful SFF viewer. It's not needed by any
|
|
&cs; component, but very useful if you just want to see a fax file without
|
|
the need to convert it first. You can get it from <ulink url="http://sfftools.sourceforge.net/sffview.html"/>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>tiff2ps</term>
|
|
<listitem><para>A small utility to convert TIFF files to the Postscript format. It's needed by
|
|
the default script to convert faxes to PDF files (SFF->TIFF->PS->PDF :-} ).
|
|
It's often included in a package called <literal>tiff</literal> or
|
|
<literal>tifftools</literal>. Details on <ulink url="http://www.libtiff.org"/>
|
|
</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>ps2pdf</term>
|
|
<listitem><para>Again a small utility for the SFF->PDF chain - this time for the
|
|
conversion of Adobe PostScript to Adobe PDF. It's part of Ghostscript, so
|
|
you most likely have it already. (<ulink url="http://www.gnu.org/software/ghostscript/ghostscript.html"/>)
|
|
</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>current Ghostscript with cfax patch</term>
|
|
<listitem><para>Current Ghostscript versions will include a device to create the above mentioned
|
|
SFF files. If you have an older version, you'll need the patch from
|
|
<ulink url="http://sfftools.sourceforge.net/ghostscript.html"/>. To see if your GhostScript
|
|
version already has this patch, please call <command>gs --help</command> and see if you can
|
|
find the device <literal>cfax</literal> in the long list of supported devices.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>jpeg2ps</term>
|
|
<listitem><para>The <command>jpeg2ps</command> command is used to convert color fax files to the
|
|
PostScript format for mail delivery. It's not so important, unless you want to be able to receive
|
|
color faxes. Unfortunately, there's currently no way to disable the reception of color faxes with
|
|
AVM cards due to a bug in the AVM CAPI driver. So if someone sends you a color fax (which seems to
|
|
be a very rare case), you'll need this package - unless you'll get a mail stating this error.
|
|
If your distribution doesn't have this packages, you can download it from
|
|
<ulink url="http://www.pdflib.com/products/more/jpeg2ps.html"/>.</para>
|
|
<para>As the color fax protocol uses concatenated JPEG files for transferring multiple pages, you
|
|
should also download and apply my multipleJPEG patch from
|
|
<ulink url="http://www.hillier.de/linux/jpeg2ps-multi.php3"/></para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>glibc locales</term>
|
|
<listitem><para>If you want to use an AVM card (which most of you will do ;-) ) to send or receive
|
|
faxes, you'll need installed glibc locales because &cs; needs to convert your fax
|
|
headline to the historic CP437 encoding which AVM drivers expect. The glibc locales are
|
|
a part of the default C library glibc which you definitely already have installed, but some
|
|
distributors make the locales installable separately. SuSE e.g. puts them in a package
|
|
called glibc-locale which you probably have to install. To see if you already have them,
|
|
look for a file called "IBM437.so" in your library paths (in SuSE it's located in
|
|
/usr/lib/gconv). If you don't find it, look for sub-packages of glibc which could include
|
|
them.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect3>
|
|
</sect2>
|
|
<sect2 id="install_install"><title>Installation</title>
|
|
<para>First of all, I would suggest to check if your CAPI-driver is setup correctly.
|
|
To do this, simply run <command>capiinfo</command> on a root shell.</para>
|
|
|
|
<para>If you get many lines of output, your CAPI driver works. If you just get
|
|
an error message, you'll have to install CAPI-compatible drivers. Refer
|
|
to the documentation of your ISDN card vendor, your Linux distribution
|
|
and/or some ISDN mailing lists for this, please.</para>
|
|
|
|
<para>The rest of the installation depends on wether you use binary or source
|
|
packages for installing &cs;. If you don't want to change the
|
|
&cs; sources, I would recommend you to use the binary packages
|
|
when available for your distribution and platform.</para>
|
|
|
|
<para>You can download both binary packages and sources from the download section on
|
|
<ulink url="http://www.capisuite.de"/>. If you built up your own packages
|
|
for other distributions, please send me them and I'll copy them there...</para>
|
|
|
|
<sect3 id="install_bin"><title>Installation from binary packages</title>
|
|
|
|
<para>If you can get binary packages for your distribution and platform,
|
|
I would advise to use them. I'm building RPM packages for SuSE Linux
|
|
regularly, as this is the distribution I use (and BTW the company which
|
|
paid and supported me to write &cs; as diploma thesis ;-) ). There are also
|
|
packages for other distributions available prepared by other users - please
|
|
see the download section for links to them.</para>
|
|
|
|
<para>If you managed to install &cs; on a system not mentioned below,
|
|
please tell me and I'll include the instructions here. If you have created
|
|
binary packages for other distributions, I'll be also happy to point
|
|
to your download section or make them available on my page.</para>
|
|
|
|
<para>Now everything should be setup ready to run. So please read on in
|
|
<xref linkend="csglobal"/>.</para>
|
|
|
|
<sect4 id="install_bin_rpm"><title>Installation from RPM packages (SuSE, RedHat)</title>
|
|
<para>To install the &cs; RPM packages you can either use your favorite setup tool -
|
|
either provided by your distributor or the community - or you can do manually
|
|
(as root):</para>
|
|
|
|
<screen>rpm -Uvh capisuite-version.rpm</screen>
|
|
</sect4>
|
|
|
|
<sect4 id="install_bin_debian"><title>Installation from Debian packages</title>
|
|
|
|
<para>To install the Debian (woody) packages built by Achim Bohnet, please add
|
|
the following lines to your <filename>/etc/apt/sources.list</filename>:</para>
|
|
|
|
<screen>deb http://www.mpe.mpg.de/~ach/debian ./
|
|
deb-src http://www.mpe.mpg.de/~ach/debian ./</screen>
|
|
|
|
<para>Now, issue the following commands:</para>
|
|
|
|
<screen>apt-get update # add package list from repository
|
|
apt-get install capisuite # install and resolve dependencies</screen>
|
|
|
|
<para>When a new package is available, <command>apt-get update</command> grabs the new
|
|
package listing and</para>
|
|
|
|
<screen>apt-get -u (dist-)upgrade</screen>
|
|
|
|
<para>updates all out-of-date packages (and new additional package dependencies in the dist-upgrade version).</para>
|
|
|
|
<para>Similar procedures are valid for the menu/gui pkg installers <command>dselect</command>,
|
|
<command>aptitude</command>, <command>kpackage</command>, ...</para>
|
|
|
|
<para>For further details, please have a look at the Debian documentation, for example the APT HowTo on
|
|
<ulink url="http://www.debian.org/doc/manuals/apt-howto/index.en.html"/> (english) or
|
|
<ulink url="http://www.de.debian.org/doc/user-manuals#apt-howto"/> (german).</para>
|
|
</sect4>
|
|
</sect3>
|
|
|
|
<sect3 id="install_source"><title>Installation from the source packages</title>
|
|
<para>If there are no binary packages you can use or if you like to do
|
|
everything on your own, you can get the sources from the download section.</para>
|
|
|
|
<para>Download the newest source tarball (capisuite-X.Y.tar.gz) from the
|
|
&cs; homepage and copy it to some location. Go there and issue the following
|
|
commands:</para>
|
|
|
|
<screen
|
|
>./configure
|
|
make
|
|
su # get root now
|
|
make install</screen>
|
|
|
|
<para>This will install &cs; completely in the <filename>/usr/local</filename>-tree. If you
|
|
want it to stay in other directories, please see the commandline-help
|
|
printed by
|
|
|
|
<screen
|
|
>./configure --help</screen>
|
|
|
|
for options to customize the installation directories.</para>
|
|
</sect3>
|
|
<sect3 id="install_CVS"><title>Installation from CVS</title>
|
|
<para>If you want to live on the bleeding edge and always test the newest features,
|
|
you may also checkout the current sources of &cs; from the CVS
|
|
repository.</para>
|
|
|
|
<para><emphasis>This is not recommended unless you want to test the newest features or
|
|
want to help in developing &cs;! The sources in CVS may not work, burn your computer
|
|
or may not even compile. Do this on your own risk!</emphasis></para>
|
|
|
|
<para>You'll need installed and working versions of the usual development tools like
|
|
autoconf, autoheader, automake, GNU make, gcc/g++ and also the components described
|
|
above (esp. development packages of Python).</para>
|
|
|
|
<para>If you want to build the documentation out of the sources, you'll also need
|
|
Doxygen.</para>
|
|
|
|
<para>For instructions on where to find the CVS repository and how to checkout
|
|
the sources, please refer to the download section on the &cs; homepage
|
|
on <ulink url="http://www.capisuite.de"/>.</para>
|
|
|
|
<para>After you checked out the sources to some directory, please do
|
|
<screen>make -f Makefile.cvs</screen>
|
|
</para>
|
|
|
|
<para>Now, you can continue with the normal installation process as described in
|
|
<xref linkend="install_source"/>.</para>
|
|
|
|
|
|
</sect3>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="csglobal"><title>How &cs; works, how it is configured and started</title>
|
|
<para>First, let's start with a short introduction what &cs; actually
|
|
is and how it works. After that, the configuration and startup of &cs;
|
|
will be explained in short.</para>
|
|
|
|
<sect2 id="howwork"><title>How does &cs; work?</title>
|
|
<para>&cs; is a daemon (program which runs in the background) whos
|
|
main task is to sit around and wait until a call is incoming.
|
|
If this happens it will start a special Python script - the
|
|
<emphasis>incoming script</emphasis> - and do what this script tells it, for example
|
|
record a voice call to implement an answering machine.</para>
|
|
|
|
<para>To also be able to issue outgoing calls, another script is called
|
|
at regular intervals - the <emphasis>idle script</emphasis>. It can check any resource
|
|
to get instructions for placing a call - one can for example imagine
|
|
to check a special mail account or watch a special directory where
|
|
tasks are placed by the user.</para>
|
|
|
|
<para>So all user-visible actions and the behaviour of &cs; are defined
|
|
in these two scripts.</para>
|
|
|
|
<para>You'll need to do two things now:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para>provide scripts by either</para>
|
|
<itemizedlist>
|
|
<listitem><para>using and configuring the default scripts distributed with &cs; or</para></listitem>
|
|
<listitem><para>writing your own scripts (perhaps by using the default ones as templates)</para></listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
<listitem><para>configure &cs; itself and tell it where to find the two scripts</para></listitem>
|
|
</itemizedlist>
|
|
|
|
<para>This page concentrates on the general configuration of &cs; - that consists mainly of
|
|
options telling it which scripts to use and where and how to log its activities. After
|
|
that, some details about starting &cs; are described.</para>
|
|
|
|
<para>The next pages will then introduce the standard scripts you already installed along with
|
|
&cs; and tell you how to use the answering maching and fax functions provided
|
|
by them.</para>
|
|
|
|
<para>The details on how to write your own scripts are covered in another part of the
|
|
documentation (<xref linkend="userguide"/>).</para>
|
|
</sect2>
|
|
<sect2 id="configcs"><title>Configuration of &cs;</title>
|
|
<para>&cs; uses a general configuration file for the core functions. This file should
|
|
be located in <filename>/etc/capisuite/capisuite.conf</filename> or <filename>/usr/local/etc/capisuite/capisuite.conf</filename>
|
|
depending on how you installed &cs;. It's described in detail in <xref linkend="capisuite.conf"/>.
|
|
Most options are set to reasonable defaults already for using the standard scripts -
|
|
so if you want you can also skip this section.</para>
|
|
|
|
<refentry id="capisuite.conf">
|
|
<refmeta>
|
|
<refentrytitle>capisuite.conf</refentrytitle>
|
|
<manvolnum>5</manvolnum>
|
|
</refmeta>
|
|
<refnamediv>
|
|
<refname>capisuite.conf</refname>
|
|
<refpurpose>configuration of the &cs; daemon</refpurpose>
|
|
</refnamediv>
|
|
<refsect1><title>Description</title>
|
|
|
|
<para>The options for the &cs; daemon are configured here. They will be
|
|
presented in brief here - for further details please
|
|
refer to the comments in the configuration file itself.</para>
|
|
</refsect1>
|
|
<refsect1><title>Options</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>incoming_script="/path/to/incoming.py"</option></term>
|
|
<listitem><para>This option tells &cs; which script should be executed at incoming
|
|
calls. Only change this if you want to use your own script.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>idle_script="/path/to/idle.py"</option></term>
|
|
<listitem><para>This option reflects the path and name of the idle script.
|
|
This script is called in regular intervalls to check if any outgoing
|
|
call should be done. As above, the default should be ok if you don't
|
|
use your own script.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>idle_script_interval="30"</option></term>
|
|
<listitem><para>Here you can define how often the idle script should be executed. The
|
|
number given is the interval between subsequent invocations in seconds.
|
|
Lesser numbers give you quicker response to queued jobs but also a higher
|
|
system load. The default should be ok in most cases.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>log_file="/path/to/capisuite.log"</option></term>
|
|
<listitem><para>This file will be used for all "normal" messages printed by
|
|
&cs; telling you what it does. Error messages are written to a
|
|
special log (see below).</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>log_level="1"</option></term>
|
|
<listitem><para>You can define how detailled the log output of &cs; will be.
|
|
The default will give you some informational messages for each
|
|
incoming and outgoing call and should be enough for normal use. I would
|
|
recommend to only increase it if you encounter some problems.
|
|
Logs of higher level are mainly intended for developers, so just use
|
|
them if you want to report a problem or have some know-how of the CAPI
|
|
interface and the internals of &cs;.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>log_error="/path/to/capisuite.error"</option></term>
|
|
<listitem><para>All errors which &cs; detects internally and in your scripts
|
|
will end up here. They are written to an extra file so that they don't
|
|
get lost in the normal log. Please check this log regularly for any
|
|
messages - especially when you encounter problems. Please report all
|
|
messages you don't understand and which aren't caused by your
|
|
own script-modifications to the &cs; team.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>DDI_length="0"</option></term>
|
|
<listitem><para>When your ISDN card is connected to an ISDN interface in PtP mode,
|
|
i.e. if you use DDI which, in understandable words mean you have only one
|
|
ISDN phone number and can define your own extensions as you like, you have
|
|
to set the length of your extension numbers here. In Germany, PtP mode is
|
|
called "Anlagenanschluss". Let's say you use 1234-000 till 1234-999, then your
|
|
DDI_length would be 3. If you set this to 0, DDI/PtP is disabled.</para>
|
|
|
|
<para>If you're not sure what all this should mean, then chances
|
|
are high you don't use DDI and can leave this option as it is.</para></listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>DDI_base_length="0"</option></term>
|
|
<listitem><para>This option is only used when DDI_length is not 0. This is the length
|
|
of your base number - in the example above it would be 4.</para></listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>DDI_stop_numbers=""</option></term>
|
|
<listitem><para>If you usually use extension numbers of a specified length, but also
|
|
want to use some shorter ones (e.g. the "-0" extension for you switchboard), then
|
|
you can list these shorter extensions here, separated by commas.</para></listitem>
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1 condition="man"><title>See Also</title>
|
|
<para><simplelist type="inline">
|
|
<member><xref linkend="capisuite"/></member>
|
|
<member><xref linkend="fax.conf"/></member>
|
|
<member><xref linkend="answering_machine.conf"/></member>
|
|
<member><xref linkend="capisuitefax"/></member>
|
|
</simplelist></para>
|
|
</refsect1>
|
|
</refentry>
|
|
</sect2>
|
|
<sect2 id="startcs"><title>Startup of CapiSuite</title>
|
|
<para>As &cs; is a daemon, it is normally activated during the system
|
|
startup process. Just add a call to
|
|
|
|
<screen><command>/path/to/capisuite -d</command></screen>
|
|
|
|
in your startup scripts. In LSB conforming Linux distributions, you'll
|
|
find the startup scripts in <filename>/etc/init.d</filename>. For detailled documentation
|
|
how to add a service there please refer to the documentation of your
|
|
distribution. There's an example startup script written for SuSE Linux included
|
|
in the source distribution (see <filename>rc.capisuite</filename>) which should (hopefully)
|
|
work with other LSB compliant distributions, too. If you need to modify it, I'll
|
|
welcome your feedback and happily add instructions for other distributions here.</para>
|
|
|
|
<para>If you use the right RPM packages of &cs;, the necessary scripts
|
|
should already be included. For activating them, please use your
|
|
distributors config tool. If you use the RPM distributed with SuSE Linux
|
|
and want to stay with the default scripts, everything should work "out of the box".
|
|
As soon as you have configured the default scripts, simply run
|
|
<command>rccapisuite restart</command>.</para>
|
|
|
|
<para>For debug purposes, you can also start &cs; manually at any time
|
|
by just calling
|
|
|
|
<screen><command>/path/to/capisuite</command></screen></para>
|
|
|
|
<para>There are also some other commandline options available:</para>
|
|
|
|
<variablelist>
|
|
<title>commandline options of &cs;</title>
|
|
<varlistentry>
|
|
<term><option>--help, -h</option></term>
|
|
<listitem><para>show a short summary of commandline options</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>--config=file, -c file</option></term>
|
|
<listitem><para>use a custom configuration file instead
|
|
of <filename>/etc/capisuite/capisuite.conf</filename> or
|
|
<filename>/usr/local/etc/capisuite/capisuite.conf</filename>.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>--daemon, -d</option></term>
|
|
<listitem><para>run as daemon (used in your startup script, see above)</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>&cs; can run as any user you want theoretically. It only needs read/write permissions to <filename>/dev/capi20</filename>.
|
|
If you use the default scripts, however, &cs; <emphasis>must</emphasis> run as <literal>root</literal>.</para>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="scripts"><title>Features and configuration of the default scripts</title>
|
|
<para>As already written above, &cs; comes with default scripts
|
|
giving you the most used communication functions of an answering machine
|
|
and a fax device.</para>
|
|
|
|
<para>This section should help you to use them for your daily needs.</para>
|
|
|
|
<sect2 id="script_features"><title>Script features</title>
|
|
<para>The scripts distributed with &cs; give you the following main
|
|
functions:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>multi-user answering machine</para>
|
|
<itemizedlist>
|
|
<listitem><para>different users using different numbers and different announcements are supported</para></listitem>
|
|
<listitem><para>incoming calls are saved and sent to the user by email</para></listitem>
|
|
<listitem><para>the delay until a call is accepted and the maximum record length are freely adjustable</para></listitem>
|
|
<listitem><para>silence is detected and the call terminated after an adjustable silence period</para></listitem>
|
|
<listitem><para>incoming fax calls are automatically detected and received</para></listitem>
|
|
<listitem><para>comfortable, menu-controlled remote inquiry functions are supported telling you
|
|
the date/time when the call was received and the called and calling numbers.</para></listitem>
|
|
<listitem><para>record your own announcement via the remote inquiry menu</para></listitem>
|
|
<listitem><para>nearly each setting is configurable globally but can be overwritten for each user</para></listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
<listitem>
|
|
<para>fax machine</para>
|
|
<itemizedlist>
|
|
<listitem><para>different users using different numbers are supported</para></listitem>
|
|
<listitem><para>incoming faxes are stored and sent to the user by email</para></listitem>
|
|
<listitem><para>command line tool for faxing PostScript documents included</para></listitem>
|
|
<listitem><para>number of tries and delays for sending faxes freely configurable</para></listitem>
|
|
<listitem><para>currently supports only one ISDN controller for outgoing faxes</para></listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>As my native language is german, all waves distributed with &cs; are in german only. If someone wants to
|
|
provide waves in english (or any other language), please contact me. Thx!</para>
|
|
</sect2>
|
|
|
|
<sect2 id="howscriptswork"><title>How the scripts work</title>
|
|
<para>Here follows a rough overview of how the scripts work in general. I will only explain
|
|
the behaviour which is important for the user here. If you want to understand the internals,
|
|
please refer to <xref linkend="default_script_overview"/>.</para>
|
|
|
|
<para>When an incoming call is received, several lists for the different users are
|
|
searched for the called number. The different users can define their own numbers in
|
|
the configuration (see below). So the scripts decide by looking on the called number
|
|
to which user the call destinates. If they find the number in the voice- or fax-number
|
|
list of any user, they'll answer the call with this service and give the caller the possibility to
|
|
leave his message or send his fax.</para>
|
|
|
|
<para>The received document is then saved to a local directory in some native format
|
|
and also converted to a well-known format and mailed to the user along with some
|
|
details of the call. Voice calls are sent as a WAV attachment, while fax calls
|
|
are sent as PDF documents attached to the mail.</para>
|
|
|
|
<para>So you'll normally get your incoming calls as a mail to a specified address -
|
|
but they're also saved in the local filesystem to be on the safe side.
|
|
It's your task to delete old files you don't need any more. For further instructions,
|
|
please see <xref linkend="deleteoldfiles"/>.</para>
|
|
|
|
<para>There's also the possibility to do a remote inquiry on the answering machine.
|
|
The caller is presented a menu where he can choose to record
|
|
his announcement or to hear the saved voice calls. He will be told how many calls
|
|
are available, from whom and when they were received and so on. He'll also be
|
|
able to delete recorded calls he doesn't need any more.</para>
|
|
|
|
<para>Another script will check special queue directories for fax send jobs
|
|
regularly. To put jobs in this directory, the commandline tool <command>capisuitefax</command> is
|
|
provided. See <xref linkend="usingscripts"/> for further details on this.</para>
|
|
</sect2>
|
|
|
|
<sect2 id="script_config"><title>Script configuration</title>
|
|
<para>There are some important options which the scripts need to know before you can use them -
|
|
things like the users' numbers and some details of how to handle the calls.</para>
|
|
|
|
<para>These options are read from two configuration files. All options for the two
|
|
files are described in short below. For all details, please see the comments
|
|
in the sample configuration files installed with &cs;.</para>
|
|
|
|
<refentry id="fax.conf">
|
|
<refmeta>
|
|
<refentrytitle>fax.conf</refentrytitle>
|
|
<manvolnum>5</manvolnum>
|
|
</refmeta>
|
|
<refnamediv>
|
|
<refname>fax.conf</refname>
|
|
<refpurpose>configuration of the &cs; fax services</refpurpose>
|
|
</refnamediv>
|
|
<refsect1><title>Description</title>
|
|
<para>This file holds all available config options for the fax
|
|
services provided by the default scripts distributed with &cs;.
|
|
It is read from <filename>/etc/capisuite/fax.conf</filename> or
|
|
<filename>/usr/local/etc/capisuite/fax.conf</filename> (depending on the installation).</para>
|
|
|
|
<para>It is divided into one or more sections. A section begins with the section
|
|
name in square brackets like <literal>[section]</literal> while the options are <literal>key="value"</literal> lines.</para>
|
|
|
|
<para>A special section called <literal>[GLOBAL]</literal> and one section
|
|
for each user called <literal>[<username>]</literal> are required.
|
|
<emphasis>The <literal><username></literal> must be a valid system user</emphasis>.</para>
|
|
|
|
<para>The <literal>[GLOBAL]</literal>-section defines some global options like
|
|
pathnames and default settings for options that can be overridden in the user-sections.
|
|
The user-sections hold all the options which belong to a particular user.</para>
|
|
</refsect1>
|
|
<refsect1><title>The [GLOBAL] section</title>
|
|
<variablelist>
|
|
<varlistentry id="fax_spool_dir">
|
|
<term><option>spool_dir="/path/to/spooldir/"</option></term>
|
|
<listitem><para>This directory is used to archive sent (or failed) jobs. It must exist and
|
|
the user &cs; runs as must have write permission to its subdirectories.
|
|
Two subdirectories are used:</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><filename>spooldir/done/</filename></term>
|
|
<listitem><para>Jobs finished successfully are moved to this directory.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><filename>spooldir/failed/</filename></term>
|
|
<listitem><para>Job which have failed finally end up here.</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>This option is mandatory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_user_dir">
|
|
<term><option>fax_user_dir="/path/to/userdir/"</option></term>
|
|
<listitem><para>This directory is used to store fax jobs and received documents
|
|
to. It must exist and
|
|
the user &cs; runs as must have write permission to it. It will contain
|
|
one subdirectory for each configured user (named like his userid). The
|
|
following subdirectories are used below the user-specific dir:</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><filename>user_dir/username/received/</filename></term>
|
|
<listitem><para>Received faxes are saved here.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><filename>user_dir/username/sendq/</filename></term>
|
|
<listitem><para>Fax files to be sent are queued here by <command>capisuitefax</command>.</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>This option is mandatory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_send_tries">
|
|
<term><option>send_tries="10"</option></term>
|
|
<listitem>
|
|
<para>When a fax can't be sent to the destination for any reason, it's tried for several times.
|
|
This setting limits the number of tries. If all tries failed, the job will be moved to the failed dir
|
|
(see <option>fax_spool_dir</option>) and the user will get a mail.
|
|
</para>
|
|
<para>This option is optional. If not given, it defaults to 10 tries.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_send_delays">
|
|
<term><option>send_delays="60,60,60,300,300,3600,3600,18000,36000"</option></term>
|
|
<listitem><para>When a fax can't be sent to the destination for any reason, it's tried again.
|
|
This setting specifies the delays in seconds between subsequent tries. The different values are
|
|
separated with commas and <emphasis>no blanks</emphasis>. The list should have send_tries-1
|
|
(see <option>fax_send_tries</option>) values - if not, surplus entries are ignored and missing
|
|
entries are filled up with the last value. The default should just be ok giving you increasing
|
|
delays for up to 10 tries.</para>
|
|
<para>This option is optional. If not given, it defaults to the list shown above.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_send_controller">
|
|
<term><option>send_controller="1"</option></term>
|
|
<listitem><para>If you have more than one ISDN controller installed (some active cards for more than
|
|
one basic rate interface like the AVM C2 or C4 are also represented as multiple controllers for
|
|
CAPI applications like &cs;), you can decide which controller (and therefore which basic rate
|
|
interface) should be used for sending your faxes. All controllers are numbered starting with 1.
|
|
If you're not sure which controller has which number, increase the log level to at least 2
|
|
in &cs; (see <xref linkend="configcs"/>), restart it and have a look in the log file where all
|
|
controllers will be listed then. Unfortunately, &cs; isn't able to use more than one controller
|
|
for sending faxes at the moment, so no list is allowed here. If you have only one controller,
|
|
just leave it at <literal>1</literal></para>
|
|
<para>This option is optional. If not given, it defaults controller 1.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_outgoing_MSN">
|
|
<term><option>outgoing_MSN="<your MSN>"</option></term>
|
|
<listitem><para>This number is used as our own number for outgoing calls. If it's not given,
|
|
the first number of fax_numbers is used (see user sections). If
|
|
this one is also empty, the user can't send faxes. Please
|
|
replace with one valid MSN of your ISDN interface or leave empty. This value can be
|
|
overwritten in the user sections individually.</para>
|
|
<para>This option is optional. If not given, it defaults to empty.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_outgoing_timeout">
|
|
<term><option>outgoing_timeout="60"</option></term>
|
|
<listitem><para>Default setting which defines how many seconds we will wait for a successful connection after
|
|
dialing the number. This value can be overwritten in the user sections individually.</para>
|
|
<para>This option is optional. If not given, it defaults to 60 seconds.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_dial_prefix">
|
|
<term><option>dial_prefix=""</option></term>
|
|
<listitem>
|
|
<para>If anything is entered here, it will be used as a prefix which is added to any
|
|
number given to <command>capisuitefax</command> as prefix. This is e.g. very helpful if your
|
|
ISDN adapter is connected to a PBX which needs "0" for external calls. It's also possible to
|
|
disable its usage later for a certain fax document, so setting this will certainly not prevent
|
|
you from placing internal calls without prefix.
|
|
</para>
|
|
<para>This option is optional. If not given, it defaults to an empty prefix.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_stationID">
|
|
<term><option>fax_stationID="<your faxID>"</option></term>
|
|
<listitem><para>Default fax station ID to use when sending a fax document. The station ID is
|
|
usually the number of your fax station in international format, so an example would be
|
|
"+49 89 123456" for a number in Munich, Germany. Station IDs may only consist of the "+"-sign,
|
|
spaces and the digits 0-9. The maximal length is 20. This value can be overwritten in the user
|
|
sections individually.</para>
|
|
<para>This option is mandatory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_headline">
|
|
<term><option>fax_headline="<your faxheadline>"</option></term>
|
|
<listitem><para>Default fax headline to use when sending a fax document. Where and if this
|
|
headline will be presented depends on the implementation of your CAPI driver. The headline
|
|
should have a reasonable length to fit on the top of a page, but there's no definite limit
|
|
given.</para>
|
|
<para>This option is optional. If not given, it defaults to an empty headline.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_email_from">
|
|
<term><option>fax_email_from="<mailaddress>"</option></term>
|
|
<listitem><para>You can set a default originator ("From"-address) for the e-mails &cs; sends
|
|
here.</para>
|
|
<para>This option is optional. If you set this to an empty string, the destinator is used as
|
|
originator (i.e. if "gernot" receives a fax, the mail comes from "gernot" to "gernot").</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1><title>The user sections</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>outgoing_MSN</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>outgoing_timeout</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>fax_stationID</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>fax_headline</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>fax_email_from</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_numbers">
|
|
<term><option>fax_numbers="<number1>,<number2>,..."</option></term>
|
|
<listitem><para>A list containing the numbers on which this user wants to receive incoming fax calls.
|
|
These numbers are used to differ between users - so the same number must not appear in more
|
|
than one user section! The numbers are separated with commas and <emphasis>no blanks</emphasis>
|
|
are allowed. The first number of the list also serves as our own number for
|
|
sending a fax if outgoing_MSN is not set (see <option>outgoing_MSN</option>).</para>
|
|
<para>If you want to use the same number for receiving fax and voice calls, please
|
|
<emphasis>do not</emphasis> enter it here. Use the voice_numbers option instead
|
|
(see <xref linkend="answering_machine.conf"/>) - the answering machine has a built in fax detection
|
|
and can also receive faxes.</para>
|
|
<para>When this list is set to <literal>*</literal>,
|
|
<emphasis>all</emphasis> incoming calls will be accepted for this user (use with care!).
|
|
This is only useful for a setup with only one user which wants to receive any call as fax.
|
|
</para>
|
|
<para>If for any reason <emphasis>no destination</emphasis> number is signalled for special
|
|
MSNs (austrian telecom seems to do this for the main MSN, where it is called "Global Call"),
|
|
you can use the special sign <literal>-</literal> which means "no destination number available".</para>
|
|
<para>This option is optional. If not given, the user can't receive fax documents.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_email">
|
|
<term><option>fax_email=""</option></term>
|
|
<listitem><para>If given, this string indicates email-addresses where the received faxes will
|
|
be sent to. More addresses are separated by commas. If it is empty, they will be sent
|
|
to the user account on the system &cs; is running on. The address is also used to send
|
|
status reports for sent fax jobs to. If you don't want emails to be sent at all, use the
|
|
action option (see option <option>fax_action</option>) below.</para>
|
|
<para>This option is optional. If not given, the mail is sent to the system account.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="fax_action">
|
|
<term><option>fax_action="MailAndSave"</option></term>
|
|
<listitem><para>Here you can define what action will be taken when a call is received.
|
|
Currently, two possible actions are supported:
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>MailAndSave</option></term>
|
|
<listitem><para>The received call will be mailed to the given address (see
|
|
<option>fax_email</option> above) and saved to the <option>fax_user_dir</option> (see global options)
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>SaveOnly</option></term>
|
|
<listitem><para>The call will be only saved to the fax_user_dir (see global options)</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
<para>This option is mandatory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1 condition="man"><title>See Also</title>
|
|
<para><simplelist type="inline">
|
|
<member><xref linkend="capisuite"/></member>
|
|
<member><xref linkend="capisuite.conf"/></member>
|
|
<member><xref linkend="answering_machine.conf"/></member>
|
|
<member><xref linkend="capisuitefax"/></member>
|
|
</simplelist></para>
|
|
</refsect1>
|
|
</refentry>
|
|
|
|
<refentry id="answering_machine.conf">
|
|
<refmeta>
|
|
<refentrytitle>answering_machine.conf</refentrytitle>
|
|
<manvolnum>5</manvolnum>
|
|
</refmeta>
|
|
<refnamediv>
|
|
<refname>answering_machine.conf</refname>
|
|
<refpurpose>configuration of &cs; answering machine</refpurpose>
|
|
</refnamediv>
|
|
<refsect1><title>Description</title>
|
|
<para>This file holds all available config options for the answering
|
|
machine provided by the default scripts distributed with &cs;. It is read
|
|
from <filename>/etc/capisuite/answering_machine.conf</filename>
|
|
or <filename>/usr/local/etc/capisuite/answering_machine.conf</filename> (depending on the installation).</para>
|
|
|
|
<para>It is divided into one or more sections. A section begins with the section
|
|
name in square brackets like <literal>[section]</literal> while the options are <literal>key="value"</literal> lines.</para>
|
|
|
|
<para>A special section called <literal>[GLOBAL]</literal> and one section
|
|
for each user called <literal>[<username>]</literal> are required.
|
|
<emphasis>The <literal><username></literal> must be a valid system user</emphasis>.</para>
|
|
|
|
<para>The <literal>[GLOBAL]</literal>-section defines some global options like
|
|
pathnames and default settings for options that can be overridden in the user-sections.
|
|
The user-sections hold all the options which belong to a particular user.</para>
|
|
</refsect1>
|
|
<refsect1><title>The [GLOBAL] section</title>
|
|
<variablelist>
|
|
<varlistentry id="voice_audio_dir">
|
|
<term><option>audio_dir="/path/to/audiodir/"</option></term>
|
|
<listitem><para>The answering machine script uses several wave files, for example
|
|
a global announcement if the user hasn't set his own and some spoken word fragments
|
|
for the remote inquiry and the menu presented there. These audio files are searched
|
|
in this directory. If user_audio_files is enabled (see <option>user_audio_files</option>), each user can also
|
|
provide his own audio snippets in his user_dir (see <option>voice_user_dir</option>).</para>
|
|
<para>This option is mandatory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_user_dir">
|
|
<term><option>voice_user_dir="/path/to/userdir/"</option></term>
|
|
<listitem><para>This directory is used to save user specific data to. It must exist and
|
|
the user &cs; runs as must have write permission to it. It will contain
|
|
one subdirectory for each configured user (named like his userid). The
|
|
following subdirectories are used below the user-specific dir:</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><filename>user_dir/username/</filename></term>
|
|
<listitem><para>Here the user may provide his own audio_files
|
|
(see also option <option>user_audio_files</option> below).
|
|
The user defined announcement is also saved here.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><filename>user_dir/username/received/</filename></term>
|
|
<listitem><para>Received voice calls are saved here.</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
<para>This option is mandatory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_user_audio_files">
|
|
<term><option>user_audio_files="0"</option></term>
|
|
<listitem>
|
|
<para>If set to <literal>1</literal>, each user may provide his own audio files
|
|
in his user directory (see <option>voice_user_dir</option>). If set to <literal>0</literal>,
|
|
only the audio_dir (see <option>voice_audio_dir</option>) will be searched.
|
|
</para>
|
|
<para>This option is optional. If not set, it defaults to not reading own user audio files (0).</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_delay">
|
|
<term><option>voice_delay="15"</option></term>
|
|
<listitem><para>Sets the default value for the delay for accepting an incoming
|
|
call in (in seconds). A value of <literal>10</literal> means that the answering
|
|
machine accepts incoming calls 10 seconds after the incoming connection request.
|
|
This value can be overwritten in the user sections individually.</para>
|
|
<para>This option is mandatory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_announcement">
|
|
<term><option>announcement="announcement.la"</option></term>
|
|
<listitem><para>Sets the default name to use for user announcements.
|
|
The announcements are searched in <filename>user_dir/username/announcement</filename>
|
|
then. If not found, a global announcement containing the called MSN will be played.
|
|
This value can be overwritten in the user sections individually.</para>
|
|
<para>This option is optional. If not set, it defaults to "announcement.la".</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_record_length">
|
|
<term><option>record_length="60"</option></term>
|
|
<listitem><para>Default setting for the maximum record length in seconds. This value can
|
|
be overwritten in the user sections individually.</para>
|
|
<para>This option is optional. If not set, it defaults to 60 seconds.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_record_silence_timeout">
|
|
<term><option>record_silence_timeout="5"</option></term>
|
|
<listitem><para>Default setting for the record silence timeout in seconds. When set to a value
|
|
greater than 0, the recording will be aborted if silence is detected for the given
|
|
amount of seconds. Set this to 0 to disable it. This value can
|
|
be overwritten in the user sections individually.</para>
|
|
<para>This option is optional. If not set, it defaults to 5 seconds.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_email_from">
|
|
<term><option>voice_email_from="<mailaddress>"</option></term>
|
|
<listitem><para>You can set a default originator ("From"-address) for the e-mails &cs; sends
|
|
here.</para>
|
|
<para>This option is optional. If you set this to an empty string, the destinator is used
|
|
as originator (i.e. if "gernot" receives a voice call, the mail comes from "gernot" to
|
|
"gernot").</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist></refsect1>
|
|
<refsect1><title>The user sections</title>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>voice_delay</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>announcement</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>record_length</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>record_silence_timeout</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>voice_email_from</option></term>
|
|
<listitem><para>User specific value for the corresponding global option</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_numbers">
|
|
<term><option>voice_numbers="<number1>,<number2>,..."</option></term>
|
|
<listitem><para>A list containing the numbers on which this user wants to receive incoming voice calls.
|
|
These numbers are used to differ between users - so the same number must not appear in more
|
|
than one user section! The numbers are separated with commas and <emphasis>no blanks</emphasis>
|
|
are allowed. The answering machine script does also automatic fax detection, so a fax can
|
|
be sent to this number. When this list is set to <literal>*</literal>,
|
|
<emphasis>all</emphasis> incoming calls will be accepted for this user (use with care!).
|
|
This is only useful for a setup with only one user which wants to receive any call.</para>
|
|
|
|
<para>If for any reason <emphasis>no destination</emphasis> number is signalled for special MSNs
|
|
(austrian telecom seems to do this for the main MSN, where it is called "Global Call"), you can
|
|
use the special sign <literal>-</literal> which means "no destination number available".</para>
|
|
|
|
<para>This option is optional. If not set, the user won't receive voice calls.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_email">
|
|
<term><option>voice_email=""</option></term>
|
|
<listitem><para>If given, this string indicates email-addresses where the received faxes and
|
|
voice calls will be sent to. If it is empty, they will be sent to the user account on the
|
|
system &cs; is running on. More addresses are separated by commas. If you don't want emails
|
|
to be sent at all, use the action option (see <option>voice_action</option>).</para>
|
|
<para>This option is optional. If not set, the calls are mailed to the system account.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_pin">
|
|
<term><option>pin="<your PIN>"</option></term>
|
|
<listitem><para>The answering machine also supports a remote inquiry function.
|
|
This function is used by entering a PIN (Personal Identification Number)
|
|
while the announcement is played. This PIN can be setup here.
|
|
If you don't want to use the remote inquiry function, just use an empty
|
|
PIN setting. The PIN doesn't have a maximal length - but perhaps you should
|
|
not use 200 digits or you perhaps won't be able to remember them (I won't at least). ;-)</para>
|
|
<para>This option is optional. If not set, remote inquiry is disabled.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry id="voice_action">
|
|
<term><option>voice_action="MailAndSave"</option></term>
|
|
<listitem><para>Here you can define what action will be taken when a call is received.
|
|
Currently, three possible actions are supported:
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>MailAndSave</option></term>
|
|
<listitem><para>The received call will be mailed to the given address (see
|
|
<option>voice_email</option> above) and saved to the <filename>voice_user_dir</filename>
|
|
(see global options)
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>SaveOnly</option></term>
|
|
<listitem><para>The call will be only saved to the <filename>voice_user_dir</filename>
|
|
(see global options)</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>None</option></term>
|
|
<listitem><para>Only the announcement will be played - no recording is done.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</para>
|
|
<para>This option is mandatory.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1 condition="man"><title>See Also</title>
|
|
<para><simplelist type="inline">
|
|
<member><xref linkend="capisuite"/></member>
|
|
<member><xref linkend="capisuite.conf"/></member>
|
|
<member><xref linkend="fax.conf"/></member>
|
|
<member><xref linkend="capisuitefax"/></member>
|
|
</simplelist></para>
|
|
</refsect1>
|
|
</refentry>
|
|
</sect2>
|
|
<sect2 id="deleteoldfiles"><title>Deleting old files</title>
|
|
|
|
<para>As written above, all incoming and outgoing calls will be saved on
|
|
the local file system to assure nothing gets lost. There's no cleaning
|
|
up done by &cs;, so these files will stay forever on your system
|
|
if you don't clean them up from time to time.</para>
|
|
|
|
<para>As it's not very convenient to do this manually, I would advise to
|
|
automate this process. <application>cron</application> is predestinated for
|
|
such a task. On most modern GNU/Linux distributions, you can simply place
|
|
scripts in <filename>/etc/cron.daily</filename> and they will be called
|
|
automatically once a day.</para>
|
|
|
|
<para>An example for a bash script you can use is included in the &cs; distribution.
|
|
Just copy <filename>capisuite.cron</filename> to <filename>/etc/cron.daily/capisuite</filename>
|
|
and assure it has correct permissions (owner root, executable bit set).</para>
|
|
|
|
<para>Now edit the file <filename>cronjob.conf</filename> and copy it to
|
|
your &cs; configuration directory (usually <filename>/etc/capisuite</filename>
|
|
or <filename>/usr/local/etc/capisuite</filename>). It tells the cron job how
|
|
long the files should be stored in the different dirs.</para>
|
|
|
|
<para>The following options are available:</para>
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>MAX_DAYS_RCVD="<value>"</option></term>
|
|
<listitem><para>Files stored in the user receive directories
|
|
which weren't accessed in the last <option><value></option>
|
|
days are deleted. Set to <option>0</option> to disable this
|
|
automatic deletion.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>MAX_DAYS_DONE="<value>"</option></term>
|
|
<listitem><para>Files stored in the global done directory
|
|
which weren't accessed in the last <option><value></option>
|
|
days are deleted. Set to <option>0</option> to disable this
|
|
automatic deletion.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>MAX_DAYS_FAILED="<value>"</option></term>
|
|
<listitem><para>Files stored in the global failed directory
|
|
which weren't accessed in the last <option><value></option>
|
|
days are deleted. Set to <option>0</option> to disable this
|
|
automatic deletion.</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="usingscripts"><title>Using &cs; together with the default scripts</title>
|
|
<sect2 id="usingscripts_receive"><title>Receiving calls</title>
|
|
<para>Now this is a nice, short section. Once you have configured
|
|
&cs;, the scripts and started &cs; successfully, there's nothing
|
|
more you have to do. You'll get your mails as described in
|
|
<xref linkend="howscriptswork"/> and that's it. You only have
|
|
to setup your mail program to receive local mails. Enjoy! :-)</para>
|
|
</sect2>
|
|
<sect2 id="usingscripts_remoteinquiry"><title>Doing a remote inquiry</title>
|
|
<para>To do a remote inquiry, please enter your PIN (see <xref linkend="answering_machine.conf"/>)
|
|
while the announcement of the answering machine is played. After some seconds
|
|
you will get a "voice menu" telling you how to record your own announcement
|
|
for your answering machine or how to playback the received calls.</para>
|
|
</sect2>
|
|
<sect2 id="usingscripts_send"><title>Sending fax jobs</title>
|
|
<para>The default scripts for &cs; also include a commandline
|
|
tool for sending faxes called <command>capisuitefax</command>. It's
|
|
described in the next section.</para>
|
|
|
|
<refentry id="capisuitefax">
|
|
<refmeta>
|
|
<refentrytitle>capisuitefax</refentrytitle>
|
|
<manvolnum>1</manvolnum>
|
|
</refmeta>
|
|
<refnamediv>
|
|
<refname>capisuitefax</refname>
|
|
<refpurpose>sending faxes with the &cs; default scripts</refpurpose>
|
|
</refnamediv>
|
|
<refsynopsisdiv>
|
|
<cmdsynopsis>
|
|
<command>capisuitefax</command>
|
|
<arg>-q</arg>
|
|
<arg>-n</arg>
|
|
<arg>-u <replaceable>user</replaceable></arg>
|
|
<arg>-A <replaceable>adr</replaceable></arg>
|
|
<arg>-S <replaceable>subj</replaceable></arg>
|
|
<arg choice="plain">-d <replaceable>number</replaceable></arg>
|
|
<arg choice="plain" rep="repeat">file</arg>
|
|
</cmdsynopsis>
|
|
<cmdsynopsis>
|
|
<command>capisuitefax</command>
|
|
<arg>-q</arg>
|
|
<arg choice="plain">-a <replaceable>id</replaceable></arg>
|
|
</cmdsynopsis>
|
|
<cmdsynopsis>
|
|
<command>capisuitefax</command>
|
|
<arg choice="plain">-h</arg>
|
|
</cmdsynopsis>
|
|
<cmdsynopsis>
|
|
<command>capisuitefax</command>
|
|
<arg choice="plain">-l</arg>
|
|
</cmdsynopsis>
|
|
</refsynopsisdiv>
|
|
|
|
<refsect1><title>Description</title>
|
|
|
|
<para>The default scripts for &cs; come with the tool <command>capisuitefax</command>
|
|
for sending faxes.</para>
|
|
|
|
<para>It will be called with some parameters
|
|
telling it which file to send (it currently only supports PostScript files)
|
|
and to which number. It will then enqueue the job converted to the
|
|
right format into the send queue
|
|
from which it's collected by another &cs; script and sent to the
|
|
destination. If the sending was completed successfully or failed finally
|
|
after trying for some time, the according user will get an email
|
|
telling him/her what has happened.</para>
|
|
|
|
</refsect1>
|
|
|
|
<refsect1><title>Options</title>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>-a id</option></term>
|
|
<listitem><para>Abort the job with the given id. To get a job id, use the <option>-l</option>
|
|
option.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>-A adr</option></term>
|
|
<listitem><para>The addressee of the fax. This option is (currently) only
|
|
for informational purposes and will be quoted in the sent status mail.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>-d number</option></term>
|
|
<listitem><para>The number which should be called (destination of the fax)</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>-h</option></term>
|
|
<listitem><para>Show a short commandline help</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>-l</option></term>
|
|
<listitem><para>Shows the jobs which are currently in the send queue.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>-n</option></term>
|
|
<listitem><para>Don't use the configured dial prefix for this job. Useful for internal jobs.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>-q</option></term>
|
|
<listitem><para>Be quiet, don't output informational messages</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>-S subj</option></term>
|
|
<listitem><para>A subject for the fax. This option is (currently) only
|
|
for informational purposes and will be quoted in the sent status mail.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>-u user</option></term>
|
|
<listitem><para>
|
|
Send fax as another user. Only allowed if <command>capisuitefax</command>
|
|
is called as user <literal>root</literal>. This is mainly helpful for realizing
|
|
extensions to e.g. do network faxing.
|
|
</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><option>file...</option></term>
|
|
<listitem><para>One or more PostScript files to send to this destination. More than
|
|
one PostScript file will produce several separate fax jobs.</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</refsect1>
|
|
<refsect1 condition="man"><title>See Also</title>
|
|
<para><simplelist type="inline">
|
|
<member><xref linkend="capisuite"/></member>
|
|
<member><xref linkend="capisuite.conf"/></member>
|
|
<member><xref linkend="fax.conf"/></member>
|
|
<member><xref linkend="answering_machine.conf"/></member>
|
|
</simplelist></para>
|
|
</refsect1>
|
|
</refentry>
|
|
</sect2>
|
|
</sect1>
|
|
</chapter>
|
|
|
|
|
|
<chapter id="userguide"><title>Users Guide</title>
|
|
|
|
<para>In the last chapter you've seen how to use the default scripts distributed with &cs;.
|
|
But the main goal in developing &cs; was not to provide a perfect ready-to-use
|
|
application. I intended to develop a tool where you can write your <emphasis>own</emphasis>
|
|
applications very easyly. I'll show you how to do this in the next sections.</para>
|
|
|
|
|
|
<sect1 id="ug_python"><title>Introduction to Python</title>
|
|
|
|
<para>As I thought about the scripting language I wanted to integrate into &cs;,
|
|
my first idea was to develop an own, simple one. But as more as I looked into it, the
|
|
more I found that a general purpose language will be much
|
|
more helpful than re-inventing every wheel that I would need. So I looked for some
|
|
easy to integrate (and to learn) language. The one I liked most was Python - and it
|
|
also had a nice documentation about embedding, so I chose it and I'm still happy about
|
|
that decision. :-)</para>
|
|
|
|
<para>So the first thing you'll have to do is to learn Python. Don't be afraid -
|
|
it was developed as a beginners language and Guido (Guido van Rossum, the inventor of Python)
|
|
has done very well in my opinion.</para>
|
|
|
|
<para>In the next few sections, I'll give you a short introduction to the features of Python
|
|
you most probably will need for &cs;. As this shouldn't be a manual about Python or a tutorial
|
|
in computer programming, I assume you're already familiar with the basic concepts of todays
|
|
wide-spread procedural and object-oriented languages.</para>
|
|
|
|
<para>If not, I would advise you to get and read a book for learning Python - there are many
|
|
available in different languages. The Python home page on <ulink url="http://www.python.org"/>
|
|
has also nice and comprehensive manuals and tutorials available for free.</para>
|
|
|
|
<sect2 id="python_basics"><title>Python Basics</title>
|
|
|
|
<para>Python supports most features you know from other common languages. Here's the
|
|
syntax of the basic operations shown in a Python session. A Python session is another
|
|
fine feature of its interpreter: just start it by typing <command>python</command>
|
|
in a shell and you'll get a prompt:</para>
|
|
|
|
<screen
|
|
>gernot@linux:~> python
|
|
Python 2.2.1 (#1, Sep 10 2002, 17:49:17)
|
|
[GCC 3.2] on linux2
|
|
Type "help", "copyright", "credits" or "license" for more
|
|
information.
|
|
>>></screen>
|
|
|
|
<para>As you can see, the Python prompt is <literal>>>></literal>.
|
|
If you enter commands that span multiple lines, Python shows a second
|
|
prompt: <literal>...</literal></para>
|
|
|
|
<screen>>>> if (1==2):
|
|
... print "Now THAT's interesting!"
|
|
...</screen>
|
|
|
|
<para>Ok, now let's go on:</para>
|
|
|
|
<screen>>>> # comments start with # at the begin of a line
|
|
>>> # now the usual first steps
|
|
>>> print "hello world"
|
|
hello world
|
|
>>> # variables
|
|
>>> a=5 # no separate declarations necessary
|
|
>>> b=a*2
|
|
>>> print b
|
|
10
|
|
>>> b='hello'
|
|
>>> print b,'world'
|
|
hello world
|
|
>>> # python is very powerful in handling sequences
|
|
>>> a=(1,2,3) # defines a tuple (not changeable!)
|
|
>>> print a
|
|
(1, 2, 3)
|
|
>>> a[1]=2 # this must fail
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
TypeError: object doesn't support item assignment
|
|
>>> a=[1,2,3] # defines a list (changeable)
|
|
>>> a[1]=7
|
|
>>> print a
|
|
[1, 7, 3]
|
|
>>> # control structures
|
|
>>> if (b=='hello'):
|
|
... print "b is hello"
|
|
... else:
|
|
... print "????"
|
|
...
|
|
b is hello
|
|
>>> # the for statement can iterate over sequences
|
|
>>> for i in a:
|
|
... print i
|
|
...
|
|
1
|
|
7
|
|
3
|
|
>>> # replace positions 1 to 3 (without 3) with 0
|
|
>>> a[1:3]=[0]
|
|
>>> a
|
|
[1, 0]
|
|
>>> # a[-i] is the i-the element counted from the back
|
|
>>> a[-1]=7; a[-2]=8
|
|
>>> a
|
|
[8, 7]</screen>
|
|
|
|
</sect2>
|
|
<sect2 id="py_blocks"><title>Blocks, Functions and Exceptions</title>
|
|
<para>Blocks are grouped only by identation. No <literal>begin</literal>,
|
|
<literal>end</literal>, braces (<literal>{</literal>, <literal>}</literal>)
|
|
or the like are needed. This sounds very uncomfortable at the first sight, but it's
|
|
really nice - you must always structure your code exactly how you
|
|
<emphasis>mean</emphasis> it:</para>
|
|
|
|
<screen>>>> for i in [1,2,3]:
|
|
... print 2*i
|
|
...
|
|
2
|
|
4
|
|
6
|
|
>>> i=0
|
|
>>> while (i!=3):
|
|
... print i
|
|
... i+=1
|
|
...
|
|
0
|
|
1
|
|
2</screen>
|
|
|
|
<para>Now let's see how to define functions and how to work with
|
|
exceptions:</para>
|
|
|
|
<screen>>>> def double_it(a):
|
|
... return (2*a)
|
|
...
|
|
>>> print double_it(9)
|
|
18
|
|
>>> print double_it("hello")
|
|
hellohello
|
|
>>>
|
|
>>> # let's trigger a exception
|
|
>>> a=1/0
|
|
Traceback (most recent call last):
|
|
File "<stdin>", line 1, in ?
|
|
ZeroDivisionError: integer division or modulo by zero
|
|
>>>
|
|
>>> # now let's catch it
|
|
>>> try:
|
|
... a=1/0
|
|
... except ZeroDivisionError,e:
|
|
... print "You divided by zero, message was:",e
|
|
...
|
|
You divided by zero, message was: integer division or modulo by zero</screen>
|
|
</sect2>
|
|
<sect2 id="py_modules"><title>Working with modules</title>
|
|
<para>Modules are a way to group functions together. They must be
|
|
imported before you can use them and they give you a new object
|
|
containing all functions. Let's play around with some of them:
|
|
</para>
|
|
|
|
<screen>>>> import time
|
|
>>> # what is in time?
|
|
>>> dir(time)
|
|
['__doc__', '__file__', '__name__', 'accept2dyear', ...]
|
|
>>> # So - what do all these functions do? Python can tell...
|
|
>>> print time.__doc__
|
|
This module provides various functions to manipulate time values.
|
|
|
|
[...]
|
|
|
|
Variables:
|
|
|
|
[...]
|
|
|
|
Functions:
|
|
|
|
time() -- return current time in seconds since the Epoch as a float
|
|
ctime() -- convert time in seconds to string
|
|
[...]
|
|
|
|
>>> # Could you please explain ctime in more detail?
|
|
>>> print time.ctime.__doc__
|
|
ctime(seconds) -> string
|
|
|
|
Convert a time in seconds since the Epoch to a string in local time.
|
|
This is equivalent to asctime(localtime(seconds)). When the time tuple
|
|
is not present, current time as returned by localtime() is used.
|
|
|
|
>>> time.time()
|
|
1044380131.186987
|
|
>>> time.ctime()
|
|
'Tue Feb 4 18:35:36 2003'
|
|
>>> import os
|
|
>>> os.getuid()
|
|
500
|
|
>>> import pwd
|
|
>>> pwd.getpwuid(500)
|
|
('hans', 'x', 500, 100, 'Hans Meier', '/home/hans', '/bin/bash')</screen>
|
|
|
|
<para>Ok, now I hope you got a small idea of Python. Have fun with
|
|
it. I had... :-)</para>
|
|
|
|
<para>If you have further questions, I would <emphasis>really</emphasis> advise you
|
|
to continue with a good book or the documentation on
|
|
<ulink url="http://www.python.org"/>. Please don't ask general Python
|
|
questions on the &cs; lists...</para>
|
|
|
|
</sect2>
|
|
</sect1>
|
|
<sect1 id="ug_writing_scripts"><title>A first look on the incoming and idle scripts</title>
|
|
<para>In <xref linkend="howwork"/> I already told you that there are two kinds
|
|
of scripts used in &cs;. Now let's have a closer look on them.</para>
|
|
|
|
<sect2 id="ug_scripts_incoming"><title>The incoming script</title>
|
|
<para>Every time a call is received by &cs;, it will call the incoming script -
|
|
to be precise it will call a function named <literal>callIncoming</literal> in
|
|
a python script located somewhere on your disk. This "somewhere" was defined in
|
|
<xref linkend="configcs"/>, remember?</para>
|
|
|
|
<para>So the given script must always define a function with the following signature:</para>
|
|
|
|
<programlisting>def callIncoming(call,service,call_from,call_to):
|
|
# function body
|
|
...</programlisting>
|
|
|
|
<para>The parameters given by &cs; are:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>call</term>
|
|
<listitem><para>reference to the incoming call. This will be used
|
|
later in all &cs;-functions you call to tell the system which call
|
|
you mean. You'll only pass this parameter on to other functions - the
|
|
script can't do anything other with it (it's
|
|
<emphasis>opaque</emphasis>).</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>service (integer)</term>
|
|
<listitem><para>Service of the incoming call as signalled by the ISDN,
|
|
set to one of the following values:
|
|
<itemizedlist>
|
|
<listitem><para><literal>SERVICE_VOICE</literal>: voice call</para></listitem>
|
|
<listitem><para><literal>SERVICE_FAXG3</literal>: analog fax call</para></listitem>
|
|
<listitem><para><literal>SERVICE_OTHER</literal>: other service not listed above</para></listitem>
|
|
</itemizedlist>
|
|
</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>call_from (string)</term>
|
|
<listitem><para>the number of the calling party (source of the call) as Python string</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term>call_to (string)</term>
|
|
<listitem><para>the number of the called party (destination of the call) as Python string</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>The first task of the function should be to decide if it wants to accept or reject
|
|
the call. If it accepts it, it will normally do something with it (receive a fax, record
|
|
a voice call, play nice announcements, ...) and then disconnect. After it has done
|
|
all necessary work, it should finish immidiately. In a later chapter, I'll present
|
|
you some examples which should make things clearer.</para>
|
|
|
|
<para>Naturally, you can break down your application in more functions and perhaps more
|
|
scripts, which will be called and/or imported recursively - but the starting point is always
|
|
the <emphasis>incoming script</emphasis> containing <literal>callIncoming</literal>.
|
|
If Python and &cs; are correctly installed, you should also be able to import and use
|
|
any Python module.</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 id="ug_scripts_idle"><title>The idle script</title>
|
|
<para>As the incoming script will only be started when a call comes in, we need
|
|
another mechanism to initiate an outgoing call. As &cs; can't know when you plan
|
|
to do so, it will just call a function named <literal>idle</literal> in the
|
|
so called "idle script" in regular intervals. For configuring the intervals and where
|
|
this script is located, please refer to <xref linkend="configcs"/>.</para>
|
|
|
|
<para>The called function must have the following signature:</para>
|
|
|
|
<programlisting>def idle(capi):
|
|
# function body
|
|
...</programlisting>
|
|
|
|
<para>The only parameter given by &cs; is:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>capi</term>
|
|
<listitem><para>This is a reference to an internal class of &cs;
|
|
which handles the communication with the CAPI interface. You'll
|
|
have to pass on this parameter to some &cs; functions. Nothing
|
|
else useful you can do with it in your script. This
|
|
parameter has internal reasons and will possibly (hopefully)
|
|
go away some day in the future. Just pass it on when told
|
|
to do so for now.</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>Now you can do what you want in this function. Most likely, you'll check
|
|
for a job in an email account, look for a file to send in a special directory
|
|
or so and place a call to send the job to the right destination.</para>
|
|
|
|
<para>Theoretically, you could also accomplish every other periodical task on your
|
|
system in the idle script - but perhaps we should leave such general things to
|
|
applications which were designed for this like <application>cron</application>. ;-)</para>
|
|
|
|
<para>As above, <literal>idle</literal> can call other functions or scripts if
|
|
you like to and all Python modules are available for import.</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="fileformats"><title>Used file formats</title>
|
|
<para>Before we'll continue with writing scripts, please let me tell you some words
|
|
about the file formats the &cs; core uses.</para>
|
|
|
|
<para>&cs; always reads and saves files in the native format as they are be expected and given
|
|
by the CAPI ISDN drivers. This preserves it from having to convert everything from and to other
|
|
formats thus reducing unnecessary overhead.</para>
|
|
|
|
<para>As these formats aren't that well-known and you will need special tools to convert or
|
|
view/play them, I'll give you a short overview of how you can do this.</para>
|
|
|
|
<para>Most likely, your scripts will convert the special ISDN file formats to well-known
|
|
ones for sending them to you via e-mail for example. Nevertheless, I'd advice you to store
|
|
the received and sent files in the native &cs; formats somewhere. This will protect you from
|
|
losing data in the case the conversion fails and will help you in debugging problems which may
|
|
arise with your scripts.</para>
|
|
|
|
<para>All tools which I refer to here are described in <xref linkend="require_soft"/>. See
|
|
there for informations how to get them.</para>
|
|
|
|
<sect2 id="voice_fileformat"><title>Format of voice files (inversed A-Law, 8kHz, mono)</title>
|
|
<para>ISDN transmits voice data as waves with a sample-rate of 8kHz in mono. To
|
|
save bandwith, a compression called A-Law is used (at least in Europe, other countries
|
|
like the USA use u-Law which is quite similar to A-Law). For any reason
|
|
beyond my understanding, they use a bit-reversed form of A-Law called
|
|
"inversed A-Law".</para>
|
|
|
|
<sect3 id="creating_alaw"><title>Creating A-Law files</title>
|
|
|
|
<para>There are two possible ways to create A-Law files.</para>
|
|
|
|
<para>The first one is to call your computer with your phone (either use the default answering
|
|
machine script and configure it as described in <xref linkend="answering_machine.conf"/>
|
|
or write a simple script yourself). Now, record whatever you want and take the created
|
|
output file (when you use the default scripts please take the file from the
|
|
user_dir, not the attachment of the mail as this is already converted) and use it.</para>
|
|
|
|
<para>You eventually want to trim the recorded file and remove unwanted
|
|
noise and silence at the beginning and the end. This can easily be done
|
|
by <command>sox</command> and <command>play</command> (both come together
|
|
with the <command>sox</command> package).</para>
|
|
|
|
<para><command>sox</command> is used to convert a file while <command>play</command>
|
|
is used to just play it. Both support the same effects including the trim option.
|
|
Both also detect what type of file you are using by looking at the suffix of
|
|
your file name. So all your inversed A-Law files should be named like
|
|
<filename>something.la</filename> (<filename>.la</filename> is the inversed
|
|
form of <filename>.al</filename> which stands for A-Law).</para>
|
|
|
|
<para>So let's first try to find the optimal values for the trim effect by calling
|
|
<command>play:</command></para>
|
|
|
|
<screen><command>play myfile.la trim <start-offset> <duration></command></screen>
|
|
|
|
<para>Now play around with start-offset and duration (both given in seconds) until
|
|
you know the right values. If you found them, you can use <command>sox</command>
|
|
to actually produce the needed file:</para>
|
|
|
|
<screen><command>sox myfile.la outfile.la trim <start-offset> <duration></command></screen>
|
|
|
|
<para>You'll now get a file named <filename>outfile.la</filename> which should
|
|
contain what you want.</para>
|
|
|
|
<para>The second way to create an inversed A-Law file is to record a normal WAV-file
|
|
with your favourite sound-tools and convert it to the destination format using
|
|
<command>sox</command>. You'll get the best results when your WAV file already
|
|
is in 8kHz, mono, 16 bit format. <command>sox</command> is able to convert
|
|
other waves if necessary but this usually will result in worse quality. You should
|
|
also normalize your sound file to about 50% of the maximum amplitude.</para>
|
|
|
|
<para>You can convert WAV to inversed A-Law by calling (thx to Carsten Heesch for the tip):</para>
|
|
|
|
<screen><command>sox myfile.wav -r 8000 -c 1 -b outfile.la resample -ql</command></screen>
|
|
|
|
<para>If you used vbox in the past and want to convert your old message files, you can
|
|
use the following command:</para>
|
|
|
|
<screen><command>vboxtoau < infile.msg | sox -tau - outfile.la</command></screen>
|
|
|
|
</sect3>
|
|
<sect3 id="playing_alaw"><title>Playing A-Law files</title>
|
|
<para>Again, there are two possibilities. The <command>play</command> command
|
|
of <command>sox</command> is able to just play the inversed A-Law format without
|
|
any conversion. Just call <command>play</command> with the filename as parameter:</para>
|
|
|
|
<screen><command>play myfile.la</command></screen>
|
|
|
|
<para>But you can also use sox to convert the A-Law files to the more common
|
|
WAV format by just invoking:</para>
|
|
|
|
<screen><command>sox myfile.la -w outfile.wav</command></screen>
|
|
|
|
<para>The created <filename>outfile.wav</filename> can be played
|
|
by nearly any audio player without problems.</para>
|
|
</sect3>
|
|
</sect2>
|
|
<sect2 id="fax_fileformat"><title>Format of fax files (Structured Fax Files)</title>
|
|
<para>CAPI-compliant drivers will expect and provide fax files in a so called
|
|
Structured Fax File (SFF). As this seems to be a CAPI-specific format, there
|
|
are not much tools out there for GNU/Linux which are capable of handling it.
|
|
Finally I found some small tools written by Peter Schäfer, which we can
|
|
use here.</para>
|
|
|
|
<para>&cs; is also able to receive color fax files which will be stored in
|
|
a special file format I called CFF.</para>
|
|
|
|
<sect3 id="create_sff"><title>Creating a SFF</title>
|
|
<para>In current Ghostscript releases, a patch from Peter has been
|
|
included to produce SF files. To see if your Ghostscript already
|
|
supports it, enter <command>gs --help</command> and look for
|
|
the so-called <command>cfax</command>-device in the long device list
|
|
presented to you. If it's not listed, you have to take a newer Ghostscript
|
|
or recompile it, sorry. I don't know any other way to produce SFF currently.</para>
|
|
|
|
<para>You need a PostScript file (as produced by nearly every Linux program
|
|
when you choose "print to file") first. Now you can call GhostScript to
|
|
convert it to a SFF:</para>
|
|
|
|
<screen><command>gs -dNOPAUSE -dBATCH -sDEVICE=cfax -sOutputFile=outfile.sff file.ps</command></screen>
|
|
|
|
<para>If you're not sure if it worked you can use <command>sffview</command>
|
|
as described below.</para>
|
|
</sect3>
|
|
<sect3 id="view_sff"><title>Viewing / converting from SFF</title>
|
|
<para>To simply view a received SFF, you can use the <command>sffview</command>
|
|
program. It's a simple but useful tool for viewing SF files without the need
|
|
to convert them. Just start it and you will get a GUI where you can open the
|
|
desired file.</para>
|
|
|
|
<para>If you want to convert a fax file to a more common format, I recommend
|
|
using <command>sfftobmp</command>. It supports quite some output formats
|
|
like JPEG, TIFF, PBM or BMP. I prefer multipage TIFF files as this is the only
|
|
format being able to store several pages in one file. To convert
|
|
SFF to multipage TIFF, call:</para>
|
|
|
|
<screen><command>sfftobmp -tif myfile.sff outfile.tiff</command></screen>
|
|
|
|
<para>This will give you a TIFF file which you can convert now to nearly
|
|
any other useful format with the TIFF tools, for example <command>tiff2ps</command>.
|
|
</para>
|
|
</sect3>
|
|
<sect3 id="cff"><title>Color faxes - the CFF format</title>
|
|
<para>There exists an enhancement to the fax standard which allows to transfer
|
|
documents in color. It's not very widely used, but as some people wanted it for &cs;,
|
|
I added support for receiving these faxes with &cs;.</para>
|
|
|
|
<para>The CFF format (I don't know if this is an official name for the format) basically
|
|
consists of concatenated JPEG images. Most programs who can handle JPEG files
|
|
should be able to open it and display at least the first page. Together with my patch
|
|
described in <xref linkend="require_soft"/>, the jpeg2ps tool can convert it to
|
|
the PostScript format so you can open it with any usual viewer.</para>
|
|
|
|
<para>Currently, I don't know a nice way to create this format manually. Therefore,
|
|
&cs; currently only supports the reception of these files. If someone knows
|
|
such a tool or is willing to implement one, please contact me!</para>
|
|
</sect3>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="incoming_tutorial"><title>Tutorial: writing an incoming script</title>
|
|
<para>In this section, I'll show you how to code your own incoming script step by step.
|
|
We begin with simply accepting every incoming call, playing a beep. The last example
|
|
is a very simple but useful answering machine with fax recognition and receiving.</para>
|
|
|
|
<sect2 id="incoming_tut_basics"><title>Basics and a really dumb answering machine.</title>
|
|
<para>Let's start with a very simple case: accept all incoming calls, beep and record
|
|
something so we have an audio file to play with later. First of all, create a new directory
|
|
somewhere which must be writable to <literal>root</literal>. We also need some test audio
|
|
file for sending. Let's take the beep which is distributed with &cs;.</para>
|
|
|
|
<screen>mkdir capisuite-examples
|
|
chmod 777 capisuite-examples # make it world-writeable
|
|
cd capisuite-examples
|
|
cp /usr/local/share/capisuite/beep.la .</screen>
|
|
|
|
<para>Perhaps you must change the path in the last line to reflect your installation.</para>
|
|
|
|
<para>Now copy and paste the example shown here to a file called <filename>example.py</filename>
|
|
in this directory. Don't forget to change the <literal>my_path</literal>-setting.</para>
|
|
|
|
<example><title>example.py</title>
|
|
<programlisting>import capisuite<co id="incoming_ex1_1"/>
|
|
|
|
my_path="/path/to/the/just/created/capisuite-examples/"<co id="incoming_ex1_2"/>
|
|
|
|
def callIncoming(call,service,call_from,call_to):<co id="incoming_ex1_3"/>
|
|
capisuite.connect_voice(call,10)<co id="incoming_ex1_4"/>
|
|
capisuite.audio_send(call,my_path+"beep.la")<co id="incoming_ex1_5"/>
|
|
capisuite.audio_receive(call,my_path+"recorded.la",20,3)<co id="incoming_ex1_6"/>
|
|
capisuite.disconnect(call)<co id="incoming_ex1_7"/></programlisting></example>
|
|
|
|
<para>Let's walk through the script line by line:</para>
|
|
|
|
<calloutlist>
|
|
<callout arearefs="incoming_ex1_1">
|
|
<para>Import the capisuite module which holds all &cs; specific functions.
|
|
All &cs; objects (functions, constants) in this module can be referenced by
|
|
<literal>capisuite.objectname</literal> now. You could also do a
|
|
"<literal>from capisuite import *</literal>", which will insert all objects in the
|
|
current namespace - but this isn't recommended as they may collide with other
|
|
global objects.</para>
|
|
|
|
<note><para>The imported module <literal>capisuite</literal> isn't available
|
|
as extra module, so you can't do this in an interactive Python session.
|
|
It's included in the &cs; binary and only available in scripts interpreted
|
|
by &cs;.</para></note>
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_2">
|
|
<para>Please change this to the real path you use for running these examples.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_3">
|
|
<para>Define the necessary function as explained in
|
|
<xref linkend="ug_scripts_incoming"/></para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_4">
|
|
<para>That's the first &cs; function we use: it accepts the pending call. The
|
|
first parameter tells &cs; which call you mean. This parameter is necessary
|
|
for nearly all &cs; functions. Ok, we only have one call now - but please
|
|
think about an incoming script which also wants to place an outgoing call at
|
|
the same time (for example to transfer a call). In this case &cs; wouldn't know
|
|
which call you mean - so you must pass the reference you got to all connection
|
|
related functions.</para>
|
|
|
|
<para>You can also tell &cs; to wait for an arbitrary time before accepting a
|
|
call - that's what the second parameter is used for. So this script will wait
|
|
10 seconds before connecting with the caller. Don't think this parameter is
|
|
useless and you could call a Python function (like <literal>time.sleep()</literal>)
|
|
to wait instead. This won't work for any delay longer than 4 (or 8, depending
|
|
on your ISDN setup) seconds as the call will timeout if an ISDN device doesn't
|
|
"pre-accept" it by telling your network provider that it's ringing. &cs; will
|
|
do so if necessary - so please just use this parameter.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_5">
|
|
<para>This call should be fairly self-explainig. Send the audio file stored in
|
|
<filename>beep.la</filename>.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_6">
|
|
<para>Record an audio file for maximal 20 seconds - stopping earlier if more than
|
|
3 seconds of silence are recognized.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_7">
|
|
<para>Last, but not least - disconnect. Hang up. Finish. It's over.</para>
|
|
</callout>
|
|
</calloutlist>
|
|
|
|
<para>&cs; configuration must be changed to use the just created script.
|
|
Do this by editing your <filename>capisuite.conf</filename> and replacing the
|
|
<literal>incoming_script</literal> value by the path to the file you just
|
|
created (see <xref linkend="configcs"/>) and restart &cs;.</para>
|
|
|
|
<para>Now test it: call any number which ends up at your ISDN card - if you have
|
|
connected it to your ISDN interface, than any number (MSN) will do - if it's connected
|
|
to a PBX, then you must call a number which was configured for the card in your PBX.</para>
|
|
|
|
<para>You should hear a beep and then you can speak something into this primitive answering
|
|
machine. Please don't hangup before the script does as this case isn't handled yet. Just
|
|
wait 3 seconds after saying something - it should disconnect after this period of silence.</para>
|
|
|
|
<para>If it doesn't work, you perhaps made an error when copying the script. In this case,
|
|
please have a look at the &cs; log and error log, which you'll find in
|
|
<filename>/var/log/capisuite</filename> or <filename>/usr/local/var/log/capisuite</filename>
|
|
if you haven't changed the path.</para>
|
|
|
|
<para>A good trick to check for syntax errors is also to run your script through
|
|
the normal Python interpreter. Do this by calling <command>python /path/to/your/example.py</command>.
|
|
Naturally, it will complain about the <literal>import capisuite</literal> as this is no standard
|
|
Python module. But before it does this, it will check the syntax of your script - so if you get
|
|
any <emphasis>other</emphasis> error, please fix it and try again. If you only get
|
|
|
|
<screen>Traceback (most recent call last):
|
|
File "../scripts/incoming.py", line 16, in ?
|
|
import capisuite,cs_helpers
|
|
ImportError: No module named capisuite</screen>
|
|
|
|
then your script has a correct syntax.</para>
|
|
|
|
<para>I hope you got your script working by now - if not, don't hesitate to ask on the
|
|
&cs; mailing lists <emphasis>if</emphasis> you have read a Python tutorial before.</para>
|
|
|
|
<para>In the next section we want to use an announcement, so please record some words
|
|
with this simple script and move the created file <filename>recorded.la</filename> to
|
|
<filename>announce.la</filename>.</para>
|
|
</sect2>
|
|
<sect2 id="incoming_tut_improving"><title>Improving it to a useful (?) state</title>
|
|
<para>Well, it's really not nice that the caller mustn't hangup - and it's even worse
|
|
that we do accept all incoming calls - perhaps by taking away your mothers important
|
|
calls?</para>
|
|
|
|
<para>Let's quickly improve this.</para>
|
|
|
|
<example><title>example.py, improved</title>
|
|
<programlisting>import capisuite
|
|
|
|
my_path="/path/to/the/just/created/capisuite-examples/"
|
|
|
|
def callIncoming(call,service,call_from,call_to):
|
|
try:<co id="incoming_ex2_1"/>
|
|
if (call_to=="123"):<co id="incoming_ex2_2"/>
|
|
capisuite.connect_voice(call,10)
|
|
capisuite.audio_send(call,my_path+"announce.la")<co id="incoming_ex2_2a"/>
|
|
capisuite.audio_send(call,my_path+"beep.la")
|
|
capisuite.audio_receive(call,my_path+"recorded.la",20,3)
|
|
capisuite.disconnect(call)
|
|
else:
|
|
capisuite.reject(call,1)<co id="incoming_ex2_3"/>
|
|
capisuite.disconnect(call)<co id="incoming_ex2_3a"/>
|
|
except capisuite.CallGoneError:
|
|
capisuite.disconnect(call)<co id="incoming_ex2_4"/></programlisting></example>
|
|
|
|
<calloutlist>
|
|
<callout arearefs="incoming_ex2_1">
|
|
<para>If the other party hangs up unexpectedly, &cs; will raise an
|
|
exception named <literal>CallGoneError</literal>. Therefore, you should
|
|
always put your code in a <literal>try</literal> statement and catch
|
|
the raised exception at the end of your script (or perhaps
|
|
earlier if needed). This exception can be raised by any call to a &cs;
|
|
command which expects a connection like audio_send(). Since &cs; 0.5, it's
|
|
not raised at once on normal disconnects; for example if the caller hangs up
|
|
<emphasis>during</emphasis> audio_receive() the function will just finish.
|
|
An exception will not be raised until you call the <emphasis>next</emphasis>
|
|
command which expects a connection. The reason for this change was to only
|
|
raise an exception on real errors and to make it possible to handle disconnects
|
|
in the normal flow of your scripts. On most scripts, this change shouldn't
|
|
have an effect.
|
|
</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex2_2">
|
|
<para>Have a look at the called number (please replace <literal>123</literal>
|
|
with the number &cs; should accept)...</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex2_2a">
|
|
<para>Play the announcement we recorded in the last section. If you don't
|
|
like it, simply record a new one and move the <filename>recorded.la</filename>
|
|
again to <filename>announce.la</filename>.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex2_3">
|
|
<para>Ignore the call.
|
|
The second parameter tells the exact reason for the reject - you can
|
|
ignore a call (any other ISDN device or phone will still be ringing for
|
|
that number) by using <literal>1</literal>, actively disconnect by
|
|
using <literal>2</literal> or any error condition which is
|
|
available in the ISDN specification (see <xref linkend="capicodes_isdn"/>
|
|
for available codes).</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex2_3a">
|
|
<para>You always have to call <literal>disconnect</literal> at the end of your script,
|
|
as this will wait for the end of the call, while <literal>reject</literal> only initiates
|
|
the call reject. Otherwise you'll get a warning in the error log.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex2_4">
|
|
<para>This is the exception handler for <literal>CallGoneError</literal> - the
|
|
exception &cs; raises when the call is disconnected by the other party
|
|
unexpectedly. You should also call <literal>disconnect</literal> here to
|
|
wait until the call is completely disconnected.</para>
|
|
</callout>
|
|
</calloutlist>
|
|
|
|
<para>Save this to <filename>example.py</filename> again and test it.
|
|
It's not necessary to restart &cs; as all scripts will be read at
|
|
each time they're executed. Now you're allowed to hang up, too ;-).
|
|
</para>
|
|
|
|
|
|
</sect2>
|
|
<sect2 id="incoming_tut_unique_names"><title>Using sensible file names</title>
|
|
<para>We always used the same name to save the recorded message to which clearly isn't
|
|
reasonable. We should really choose a new name for every new call. This isn't as simple as
|
|
it may sound - you must assure that the used algorithm will also work for multiple calls
|
|
arriving at the same time. Fortunately, the helpful programmer of &cs; had the same problem
|
|
and so we can use the code he (hmmm... I?) has written.</para>
|
|
|
|
<para>The Python module <filename>cs_helpers.py</filename> contains some useful functions
|
|
which are needed by the default scripts provided with &cs; but may be also helpful
|
|
for the use in your own scripts. It contains the function <literal>uniqueName</literal>
|
|
which does exactly what we need here. The syntax is:</para>
|
|
|
|
<screen>filename=cs_helpers.uniqueName(directory,prefix,sufix)</screen>
|
|
|
|
<para>The function will find a new unique filename in the given <literal>directory</literal>.
|
|
The created filename will be "<filename>prefix-XXX.suffix</filename>" where <literal>XXX</literal>
|
|
is the next free number started at 0. The next free number is remembered in a file
|
|
<filename>prefix-nextnr</filename> and the created name is returned.</para>
|
|
|
|
<para>We can simply add this call to our script:</para>
|
|
|
|
<example><title>using unique filenames</title>
|
|
<programlisting>import capisuite<emphasis>,cs_helpers</emphasis>
|
|
|
|
my_path="/path/to/the/just/created/capisuite-examples/"
|
|
|
|
def callIncoming(call,service,call_from,call_to):
|
|
try:
|
|
if (call_to=="123"):
|
|
<emphasis>filename=cs_helpers.uniqueName(my_path,"voice","la")</emphasis>
|
|
capisuite.connect_voice(call,10)
|
|
capisuite.audio_send(call,my_path+"announce.la")
|
|
capisuite.audio_send(call,my_path+"beep.la")
|
|
capisuite.audio_receive(call,<emphasis>filename</emphasis>,20,3)
|
|
capisuite.disconnect(call)
|
|
else:
|
|
capisuite.reject(call,1)
|
|
except capisuite.CallGoneError:
|
|
capisuite.disconnect(call)</programlisting></example>
|
|
<para>If you're interested in other functions which <literal>cs_helpers.py</literal>
|
|
defines, just have a look at the reference at <xref linkend="default_helpers"/>.</para>
|
|
</sect2>
|
|
<sect2 id="incoming_tut_fax_recognition"><title>Automatic fax recognition and receiving</title>
|
|
|
|
<para>As last step, I want to show you how fax recognition and receiving works and
|
|
how to switch from voice to fax mode.</para>
|
|
|
|
<para>Here's the last and most complicated example of this section. It'll introduce
|
|
four new &cs; functions and shows how to split up the functionality in another
|
|
function which is used by <literal>callIncoming</literal>. There are much changes
|
|
which are described below - but most of them should be nearly self-explanatory.
|
|
So I don't think this last step is too big. And you don't want to read 10 more steps
|
|
here, do you? ;-)</para>
|
|
|
|
<example><title>Adding fax functions</title>
|
|
<programlisting>import capisuite,cs_helpers,os<co id="incoming_ex4_0"/>
|
|
|
|
my_path="/path/to/the/just/created/capisuite-examples/"
|
|
|
|
def callIncoming(call,service,call_from,call_to):
|
|
try:
|
|
if (call_to=="123"):
|
|
filename=cs_helpers.uniqueName(my_path,"voice","la")
|
|
capisuite.connect_voice(call,10)
|
|
capisuite.enable_DTMF(call)<co id="incoming_ex4_1"/>
|
|
capisuite.audio_send(call,my_path+"announce.la",1)<co id="incoming_ex4_2"/>
|
|
capisuite.audio_send(call,my_path+"beep.la",1)
|
|
capisuite.audio_receive(call,filename,20,3,1)
|
|
dtmf=capisuite.read_DTMF(call,0)<co id="incoming_ex4_3"/>
|
|
if (dtmf=="X"):<co id="incoming_ex4_4"/>
|
|
if (os.access(filename,os.R_OK)):<co id="incoming_ex4_5"/>
|
|
os.unlink(filename)
|
|
faxIncoming(call)<co id="incoming_ex4_6"/>
|
|
capisuite.disconnect(call)
|
|
else:
|
|
capisuite.reject(call,1)
|
|
except capisuite.CallGoneError:
|
|
capisuite.disconnect(call)
|
|
|
|
def faxIncoming(call):
|
|
capisuite.switch_to_faxG3(call,"+49 123 45678","Test headline")<co id="incoming_ex4_7"/>
|
|
filename=cs_helpers.uniqueName(my_path,"fax","sff")
|
|
capisuite.fax_receive(call,filename)<co id="incoming_ex4_8"/></programlisting></example>
|
|
|
|
<calloutlist>
|
|
<callout arearefs="incoming_ex4_0">
|
|
<para>In this example, we need a normal Python module for the first time.
|
|
The <literal>os</literal> module holds functions for all kinds of operation
|
|
system services and is needed for deleting a file here.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex4_1">
|
|
<para>DTMF is the abbreviation for Dual Tone Multi Frequency. These
|
|
are the tones which are generated when you press the digits on your
|
|
phone and are usually used for dialling. They're also sent by modern
|
|
fax machines before the transmission starts. Therefore, the same
|
|
functions can be used for recognizing pressed digits and fax machines.
|
|
</para>
|
|
|
|
<para>Before any DTMF is recognized by &cs;, the according function must
|
|
be enabled by <literal>enable_DTMF</literal>.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex4_2">
|
|
<para>All audio send and receive functions support abortion when a DTMF
|
|
tone is recognized. This is enabled by passing "<literal>1</literal>"
|
|
as last parameter. It will also prevent the function from starting
|
|
if a DTMF char was recognized <emphasis>before</emphasis> but not yet
|
|
read by the script.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex4_3">
|
|
<para>&cs; stores all received DTMF signals in a buffer from where they
|
|
can be read at any time. Reading is done by <literal>read_DTMF</literal>
|
|
which also clears the buffer. It will return all received characters in
|
|
a string, so if the caller presses "3","5","*", you'll get "35*".</para>
|
|
|
|
<para>The <literal>0</literal> tells &cs; not to wait for DTMF signals -
|
|
if none are available, it will simply return an empty string.
|
|
It's also possible to specify that it should wait for a certain amount of
|
|
time or until a certain number of signals have been received.</para>
|
|
|
|
<note><para>Please note that it's not necessary to check for received DTMF
|
|
after each audio send or receive function. Simply enable the DTMF abortion
|
|
in all commands in a block and check for received tones after the whole block.
|
|
</para></note>
|
|
</callout>
|
|
<callout arearefs="incoming_ex4_4">
|
|
<para>Fax machines send a special tone which is represented as
|
|
"<literal>X</literal>" by the CAPI. So if you receive the string
|
|
"X", a fax machine is calling and we should start our fax handling routines.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex4_5">
|
|
<para>Possibly, the announcement was so short that the recording has started
|
|
already before the fax is recognized. We won't save a file containing
|
|
only the fax beep and so we test if it was created (<function>os.access</function>
|
|
checks for the existence of a file) and delete it if needed by calling
|
|
<literal>os.unlink</literal>.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex4_6">
|
|
<para>Fax handling was realized in a separate function which is called here.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex4_7">
|
|
<para>So far, this connection is in voice mode (which was set by using
|
|
<literal>connect_voice</literal>). If we want to receive a fax now, the
|
|
mode must be changed to fax. This is done by <literal>switch_to_faxG3</literal>.
|
|
As the fax protocol needs some additional parameters, they must be given
|
|
here. The first string is the so called <emphasis>fax station ID</emphasis>
|
|
which is sent to the calling fax and shown in it's protocol, while the
|
|
second one is a <emphasis>fax headline</emphasis>. This headline is mainly
|
|
used for sending faxes. To be honest, I personally don't know if it has any
|
|
sense to specify this if you only want to receive a fax. But it surely won't
|
|
harm ;-). If someone knows this for sure, please tell me.</para>
|
|
|
|
<note><para>If you want to use an own number solely for fax purposes, you
|
|
should <emphasis>not</emphasis> use <literal>switch_to_faxG3</literal>.
|
|
Use <literal>connect_faxG3</literal> instead.</para></note>
|
|
</callout>
|
|
<callout arearefs="incoming_ex4_8">
|
|
<para>After the connection has been set to fax mode succesfully, we can
|
|
receive the fax document finally. The used function
|
|
<literal>fax_receive</literal> gets a new name which is again created by
|
|
calling <literal>cs_helpers.uniqueName</literal> as above.</para>
|
|
</callout>
|
|
</calloutlist>
|
|
|
|
<para>Congrats. You've finished my small tutorial. Now it's up to you - you can
|
|
play with the created script and try to make it more complete. Many of the
|
|
commands used above also return useful informations which we didn't use here.
|
|
There's still much to do - sending received calls to a user via e-mail, log
|
|
connections, ... If you want to complete this script,
|
|
<xref linkend="command_reference"/> will be helpful. You can also read on here
|
|
to have a short look on the idle scripts, followed by a quick overview of the
|
|
structure of the default scripts shipped with &cs;.</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="idle_examples"><title>Example for an idle script</title>
|
|
|
|
<para>After we've seen how to handle incoming calls, a very short introduction to
|
|
initiate outgoing calls by using the idle script will follow.</para>
|
|
|
|
<para>As written before, the idle script will be called by &cs; in regular intervals
|
|
allowing you to look for stored jobs somewhere and sending them to the destinations.</para>
|
|
|
|
<para>The example shown here will look for a file <filename>job-XXXX.sff</filename> in
|
|
the example directory we created in the last section. This file will be faxed to the
|
|
destination indicated by <literal>XXXX</literal>. If you have no valid destination
|
|
where you can send test faxes to, how about using &cs; as source and destination at
|
|
the same time? In this case, replace <literal>XXXX</literal> by the number your
|
|
incoming script handles. This won't work if your ISDN card can't handle two fax
|
|
transfers in parallel (some old AVM B1 cards have this limitation, for example).</para>
|
|
|
|
<para>We now need one or more fax files in the SFF format for our tests, so please
|
|
create some with a name like the one shown above. If you don't know how to do this,
|
|
please refer to <xref linkend="create_sff"/>.</para>
|
|
|
|
<para>If I want to develop a &cs; script but am not really sure how to do it, I often
|
|
start by coding a normal script which I can test without &cs;. So let's create a script
|
|
which searches the files and extracts the destination numbers first. If this works,
|
|
we can continue by adding the &cs; specific calls later.</para>
|
|
|
|
<example><title>idle_example.py</title>
|
|
<programlisting>import os,re<co id="idle_ex1_1"/>
|
|
|
|
my_path="/path/to/your/capisuite-examples/"
|
|
|
|
files=os.listdir(my_path)<co id="idle_ex1_2"/>
|
|
files=filter (lambda s: re.match("job-.*\.sff",s),files)<co id="idle_ex1_3"/>
|
|
|
|
for job in files:<co id="idle_ex1_4"/>
|
|
destination=job[4:-3]<co id="idle_ex1_5"/> # Hmmm.. Is this right?
|
|
print "found",job,"to destination",destination</programlisting>
|
|
</example>
|
|
|
|
<calloutlist>
|
|
<callout arearefs="idle_ex1_1">
|
|
<para>We know the <literal>os</literal> module already.
|
|
<literal>re</literal> provides functions for searching for regular
|
|
expressions. If you don't know what regular expressions are, please
|
|
read for example the Python documentation for the
|
|
<literal>re</literal>-module or some other documentation about them.
|
|
It's too complicated to explain it here.</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex1_2">
|
|
<para><literal>os.listdir</literal> returns the files in a given
|
|
directory as list.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_3">
|
|
<para>This line is a little bit more tricky. It filters out all filenames
|
|
which doesn't follow the rule <emphasis>starting with "job-", then any
|
|
number of chars, ending with ".sff"</emphasis> from the list. This is
|
|
done by the <literal>filter</literal> function. The function expects the name
|
|
of a function which checks the rule as first parameter and the list to filter
|
|
(<literal>files</literal>) as second one.</para>
|
|
|
|
<para>We could now define a new function and use its name here, but the
|
|
<literal>lambda</literal> keyword allows a much more elegant solution: it
|
|
defines a "nameless function" with the parameter <literal>s</literal>. The
|
|
function body follows directly behind and consists of a call to
|
|
<literal>re.match</literal> which checks if the given string
|
|
<literal>s</literal> matches the expression.
|
|
</para>
|
|
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_4">
|
|
<para>Iterate over all found filenames.</para>
|
|
</callout>
|
|
<callout arearefs="incoming_ex1_5">
|
|
<para>The destination is extracted from the given filename by using string
|
|
indexes.</para>
|
|
</callout>
|
|
</calloutlist>
|
|
|
|
<para>Now, save the script as <filename>idle_example.py</filename> in our example dir and run
|
|
it by calling <command>python idle_example.py</command>.</para>
|
|
|
|
<para>If you have provided SFF files with the right names they should be shown line by line
|
|
now. But... Obviously something doesn't work right here. The destination includes the
|
|
"<literal>.</literal>". Indeed, I've made a mistake when indexing the string. It should be
|
|
<literal>destination=job[4:-4]</literal> instead of <literal>[4:-3]</literal>. So let's change
|
|
that and test again. It should work now. That's the reason why I prefer to code such scripts
|
|
outside of &cs; first. Debugging is much faster this way...</para>
|
|
|
|
<para>As we know now that the basic parts work, we can add the real communication functions.</para>
|
|
|
|
<para>Please save this example to <filename>idle_example.py</filename> in your example directory, again.</para>
|
|
|
|
<example><title>idle_example.py, version for &cs;</title>
|
|
<programlisting>import os,re<emphasis>,capisuite</emphasis>
|
|
|
|
my_path="/path/to/your/capisuite-examples/"
|
|
my_number="678"<co id="idle_ex2_1"/>
|
|
my_stationID="+49 123 45678"
|
|
my_headline="example headline"
|
|
|
|
def idle(capi):<co id="idle_ex2_4"/>
|
|
files=os.listdir(my_path)
|
|
files=filter (lambda s: re.match("job-.*\.sff",s),files)
|
|
|
|
for job in files:
|
|
destination=job[4:-4]
|
|
capisuite.log("sending "+job+" to destination "+destination,1)<co id="idle_ex2_5"/>
|
|
try:
|
|
(call,result)=capisuite.call_faxG3(capi,1,my_number,destination,
|
|
60,my_stationID,my_headline)<co id="idle_ex2_6"/>
|
|
if (result!=0):<co id="idle_ex2_7"/>
|
|
capisuite.log("job "+job+" failed at call setup with reason "
|
|
+str(hex(result)),1)
|
|
os.rename(my_path+job,my_path+"failed-"+job)<co id="idle_ex2_9"/>
|
|
return<co id="idle_ex2_10"/>
|
|
capisuite.fax_send(call,my_path+job)<co id="idle_ex2_11"/>
|
|
(result,resultB3)=capisuite.disconnect(call)<co id="idle_ex2_12"/>
|
|
except capisuite.CallGoneError:
|
|
(result,resultB3)=capisuite.disconnect(call)
|
|
|
|
if (result in (0,0x3400,0x3480,0x3490,0x349f) and resultB3==0):<co id="idle_ex2_13"/>
|
|
capisuite.log("job "+job+" was successful",1)
|
|
os.rename(my_path+job,my_path+"done-"+job)
|
|
return
|
|
else:
|
|
capisuite.log("job "+job+" failed during send with reasons "
|
|
+str(hex(result))+","+str(hex(resultB3)),1)
|
|
os.rename(my_path+job,my_path+"failed-"+job)</programlisting>
|
|
</example>
|
|
|
|
<calloutlist>
|
|
<callout arearefs="idle_ex2_1">
|
|
<para>Some parameters for sending the fax are set here. <literal>my_number</literal> is your own number
|
|
which is used for sending the fax. <literal>my_stationID</literal> is the fax station ID, which will
|
|
be transmitted to the other fax machine and shown on the sent fax page. Only digits and "+" are allowed.
|
|
You can also define a short text which will show up in the fax headline in <literal>fax_headline</literal>.
|
|
</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_4">
|
|
<para>As explained in <xref linkend="ug_scripts_idle"/>, you have to define a function called
|
|
<literal>idle</literal> which will be executed in regular intervals by &cs; then. So all code
|
|
has been moved to this function.</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_5">
|
|
<para>We can't print messages to stdout as the script will run in the context of a daemon. So &cs;
|
|
provides functions for creating entries in the &cs; log file. <function>log</function> expects at
|
|
least two parameters: the message and a log level. This level corresponds to the log level setting
|
|
in the global &cs; configuration (see <xref linkend="configcs"/>). If the level of the message is
|
|
<emphasis>less or equal</emphasis> the level set in the configuration, it is printed to the logs.
|
|
So you can insert messages for debug purposes which aren't printed to the logs in normal operation
|
|
by using levels higher than 1.</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_6">
|
|
<para>This function initiates an outgoing call using the fax service. The parameters are:</para>
|
|
<itemizedlist>
|
|
<listitem><para>reference to the Capi object you got from &cs; (parameter to <function>idle</function>).</para></listitem>
|
|
<listitem><para>the (number of the) controller to use for outgoing calls. The first controller has always number "1".</para></listitem>
|
|
<listitem><para>own number to use for the outgoing call</para></listitem>
|
|
<listitem><para>destination number to call</para></listitem>
|
|
<listitem><para>maximum time to wait for a successful connection in seconds</para></listitem>
|
|
<listitem><para>the fax station ID</para></listitem>
|
|
<listitem><para>fax headline</para></listitem>
|
|
</itemizedlist>
|
|
<para>The function returns a tuple containing a reference to the created call and an error value.</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_7">
|
|
<para>This block checks if the connection was successful. For a detailled description of possible error values,
|
|
please see the <xref linkend="command_reference"/>. 0 means "everything was ok, call is established".</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_9">
|
|
<para>If the call wasn't successful, rename the fax file to prevent the script from sending the same file
|
|
over and over.</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_10">
|
|
<para>Don't forget to exit the <function>idle</function> function if the call couldn't be established!</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_11">
|
|
<para>Another very simple &cs; command: send the given file as fax document.</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_12">
|
|
<para>We previously ignored the reasons <emphasis>why</emphasis> a call was disconnected. Now we have to
|
|
analyze them because we need to know if the file was transferred succesful. Therefore,
|
|
<function>disconnect</function> returns a tuple containing of the physical and logical error value. Every
|
|
ISDN connection contains one physical and (at least) one logical connection. One could imagine the physical
|
|
connection as "the wire" connecting us to our destination, while the logical connection refers to
|
|
the fax protocol which uses this "wire". You have to look on both values to see if everything was ok.</para>
|
|
</callout>
|
|
<callout arearefs="idle_ex2_13">
|
|
<para>Allowed values for the physical disconnection are 0,0x3400,0x3480, 0x3490 and 0x349f. These all mean "no error
|
|
occured, call was disconnected normally". The logical value may only be 0 if everything went ok. For further
|
|
information on error values, please refer to <xref linkend="command_reference"/>.</para>
|
|
</callout>
|
|
</calloutlist>
|
|
|
|
<para>After you've saved the file and changed the default values to your own configuration, please alter the value of
|
|
<literal>idle_script</literal> in the &cs; configuration to point to this script as described in <xref linkend="configcs"/>.
|
|
</para>
|
|
|
|
<para>Restart &cs; and watch the logs. Some minutes later, the <filename>job-XXX.sff</filename> files should've been sent
|
|
and renamed to either <filename>done-job-XXX.sff</filename> or <filename>failed-job-XXX.sff</filename>. If the job failed,
|
|
please consult the error log and the error values explained in
|
|
<xref linkend="command_reference"/> and <xref linkend="capicodes"/>.</para>
|
|
|
|
<para>Hopefully, this tutorial helped you in understanding how to code your own scripts. Please continue with changing the
|
|
examples or the files distributed with &cs; (read <xref linkend="default_script_overview"/> before). You will find a
|
|
complete reference of the available commands in <xref linkend="command_reference"/>.</para>
|
|
|
|
<para>If you have any trouble in getting your scripts up and running, please use the &cs; mailing lists. And don't forget to have
|
|
fun. ;-)</para>
|
|
</sect1>
|
|
|
|
<sect1 id="default_script_overview"><title>Structural overview of the default scripts</title>
|
|
<sect2 id="default_incoming"><title>incoming.py</title>
|
|
<para>The incoming script handles all incoming connections. It reads two configuration files containing all necessary
|
|
data which were described in detail in <xref linkend="script_config"/>. The overall structure will be described here
|
|
giving you an overview of how it is implemented.</para>
|
|
|
|
<para>First (after importing some necessary modules), it defines the necessary function <function>callIncoming</function>
|
|
which will call all other functions if needed.</para>
|
|
|
|
<sect3 id="default_incoming_1"><title>function <function>callIncoming</function></title>
|
|
<para>This function starts with a call to <function>cs_helpers.readConfig</function>
|
|
to read the configuration. It then iterates through all sections representing the configured users (except
|
|
<literal>GLOBAL</literal>) to see if the called number belongs to any user. If a match is found, the user and
|
|
the defined service are saved to <literal>curr_user</literal> and <literal>curr_service</literal>.</para>
|
|
|
|
<para>If no match was found (<literal>curr_user</literal> is empty), the call is
|
|
rejected and the function returns. Otherwise the call is accepted and - depending
|
|
on the service used - <function>faxIncoming</function> or
|
|
<function>voiceIncoming</function> is called.</para>
|
|
|
|
<para>The function also defines an exeception handler for <literal>capisuite.CallGoneError</literal>.</para>
|
|
</sect3>
|
|
<sect3 id="default_incoming_2"><title>function <function>faxIncoming</function></title>
|
|
<para>First of all, the directory to use for incoming fax data is determined and created
|
|
if not existing yet, the existence of the given user is checked and a log entry is written.</para>
|
|
|
|
<para>It then switches to fax mode if necessary, creates a uniqe filename, calls
|
|
<function>capisuite.fax_receive</function>, disconnects and logs the disconnection reasons.
|
|
Then it checks if a fax has been really received succesfully (i.e. if the file exists). If yes, it creates a description file for it,
|
|
<command>chown</command>'s the file to the right user and sends the file as mail.</para>
|
|
</sect3>
|
|
<sect3 id="default_incoming_3"><title>function <function>voiceIncoming</function></title>
|
|
<para><function>voiceIncoming</function> has much more features to accomplish like fax recognition
|
|
and switching to fax mode, starting a remote inquiry etc.</para>
|
|
|
|
<para>It starts by determining the directory to use and creating a unique filename. Also, the PIN for remote inquiry
|
|
is saved to a private variable. There are two possibilites now: the user has already an own announcement - in this case
|
|
it's played now. Otherwise, a predefined announcement containing of a general announcement and the number which was called
|
|
is played. If recording a message wasn't disabled (by setting <literal>voice_action</literal> to <literal>None</literal>),
|
|
it starts now after a beep.</para>
|
|
|
|
<para>All <function>audio_send</function> and <literal>audio_receive</literal> calls used so far had DTMF abortion enabled
|
|
and so the script "falls through" all these calls after a DTMF signal was recognized. After them,
|
|
<function>read_DTMF</function> is used to see if any such signal have been found. "<literal>X</literal>" represents the fax
|
|
tone and triggers a switch to fax protocols and a call to <function>faxIncoming</function>. Any other received signals
|
|
are interpreted to be a part of the PIN for remote inquiry and so a loop which waits 3 seconds after each tone for the next
|
|
one is entered. If a valid PIN is entered, it starts the <function>remoteInquiry</function>. After three wrong attempts,
|
|
it will disconnect.</para>
|
|
|
|
<para>After disconnecting and logging, a description file is written (if the recorded file exists), both files will be
|
|
<command>chown</command>'ed to the right user and the recorded message will be mailed to him/her.</para>
|
|
</sect3>
|
|
<sect3 id="default_incoming_4"><title>function <function>remoteInquiry</function></title>
|
|
<para>The <function>remoteInquiry</function> starts by creating a lock file and acquiring an
|
|
exclusive lock on it to prevent two parallel remote inquiries for the same user. If the lock
|
|
can't be acquired, an error message is played and the function returns. If locking has succeeded,
|
|
a list of the recorded voice calls is compiled by listing the user directory, filtering and
|
|
sorting it. Now, a file called <filename>last_inquiry</filename> is read when it exists.
|
|
It contains the number of the last heard message. With this information, the old messages can
|
|
be filtered out to a separate list and thus the caller can listen to messages he doesn't know
|
|
already first.</para>
|
|
|
|
<para>The number of new messages is said, followed by a small menu where the caller can choose
|
|
to either record an announcment or hear the recorded messages. If he chooses announcement
|
|
recording, the function <function>newAnnouncement</function> is called, otherwise
|
|
<function>remoteInquiry</function> will continue.</para>
|
|
|
|
<para>Now, a loop will first iterate over the new and then the all old messages. It starts by
|
|
telling the caller how much messages have been found. Then all messages will be played, repeating
|
|
the following steps for each one:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para>read the description file of the current message</para></listitem>
|
|
<listitem><para>play an information block containing the current message number, source, destination, date and time of the
|
|
call.</para>
|
|
</listitem>
|
|
<listitem><para>play the message</para></listitem>
|
|
<listitem><para>provide a menu where the caller can go on to the next or last message, repeat the current message or delete
|
|
it</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>At the end, the caller will be informed that no more messages are available and the connection will be finished, followed
|
|
by releasing the lock file and deleting it.</para>
|
|
</sect3>
|
|
<sect3 id="default_incoming_5"><title>function <function>newAnnouncement</function></title>
|
|
<para><function>newAnnouncement</function> presents some instructions to the caller first. Then, the new announcement will be
|
|
recorded to a temporary file. To give the user the ability to check it, it will be played, followed by a menu allowing him/her to
|
|
save it or to repeat the recording. If the user has chosen to save it, it will be moved from the temporary file to
|
|
<filename>announcement.la</filename> in the users voice directory and <command>chown</command>'ed to him/her. The call will be
|
|
finished with an approval to the caller that it has been saved succesfully.</para>
|
|
</sect3>
|
|
</sect2>
|
|
<sect2 id="default_idle"><title>idle.py</title>
|
|
<para>The idle script is responsible for collecting jobs from the send queues (where they're stored by <command>capisuitefax</command>)
|
|
and sending them to the given destinations. It reads its configuration from the files presented in <xref linkend="script_config"/>, too.
|
|
</para>
|
|
|
|
<sect3 id="default_idle_1"><title>function <function>idle</function></title>
|
|
<para>After reading the configuration by calling <function>cs_helpers.readConfig</function> and testing for the existence
|
|
of the archive directories needed, the userlist is compiled from the list of available sections.</para>
|
|
|
|
<para>For each user who has a valid fax setup (otherwise this user will be skipped), the send queue will be looked at. If the
|
|
necessary queue directories don't exist, they'll be created. After that, a list called <literal>files</literal> with the names of
|
|
all files in the send queue is created and filtered to only contain fax jobs.</para>
|
|
|
|
<para>For each found job, a security check is done to see if it was created by the right user. If this check was successful, a
|
|
lock file is created and a lock on it is acquired. This prevents the <command>capisuitefax</command> command to abort a job while
|
|
it is in transfer. After that, the existence of the file is checked (perhaps the job has been cancelled before we could acquire
|
|
the lock?).</para>
|
|
|
|
<para>Now, the description file for this job is read and the starttime is checked. If it's not reached, the script will go on with
|
|
the next job. Otherwise, some parameters are taken from the configuration and a log message is created. The file is transferred by
|
|
calling <function>sendfax</function>. The results are stored and logged. If the job was successful, it is moved to the done dir and
|
|
an approval is mailed to the user. If it wasn't succesful, the delay interval will be determined from the configuration and the new
|
|
starttime is calculated by increasing the old starttime by this interval. A counter for the used tries is increased and the description
|
|
file is rewritten with the new values. If the number of tries exceeds a given maximum, the job is moved to the failed dir and the
|
|
error is reported to the user by mail.</para>
|
|
|
|
<para>Finally, the lock file will be unlocked and deleted.</para>
|
|
</sect3>
|
|
<sect3 id="default_idle_2"><title>function <function>sendfax</function></title>
|
|
<para>This function handles the send process. After determining the MSN to use from either the <literal>outgoing_MSN</literal>
|
|
setting or from the <literal>fax_numbers</literal> list, a call to the destination is initiated. If it fails, the function returns;
|
|
otherwise the file will be sent and the connection finished.</para>
|
|
</sect3>
|
|
<sect3 id="default_idle_3"><title>function <function>movejob</function></title>
|
|
<para>This is a small helper function used for moving a job and its accompanying description file to another directory.</para>
|
|
</sect3>
|
|
|
|
</sect2>
|
|
<sect2 id="default_capisuitefax"><title>capisuitefax</title>
|
|
<para><command>capisuitefax</command> allows to enqueue fax jobs, list the current queue and abort jobs. It's not used directly by the
|
|
&cs; system - it's a frontend for the users send queue directory. It has several commandline options - for an explanation
|
|
of its usage, please refer to <xref linkend="usingscripts_send"/>.</para>
|
|
|
|
<para>There are three helper functions defined first. <emphasis><function>usage</function></emphasis> prints out a small help if
|
|
"<option>--help</option>" or "<option>-h</option>" was given as parameter or if a parameter isn't understood. <emphasis><function
|
|
>showlist</function></emphasis> gets a listing from the users send queue directory and prints it nicely formatted as table. <emphasis>
|
|
<function>abortjob</function></emphasis> removes a job from the queue. It does this safely by using a lock file to not interfere with
|
|
the sending process.</para>
|
|
|
|
<para>The main code of this script checks the given commandline options first. It sets several variables to the given values.
|
|
After some checks of the validity of the options, the rights of the user to send faxes and the existence of the necessary
|
|
directories, it will fulfill the requested task. Either, <function>listqueue</function> will be called to show a listing of
|
|
active jobs, <function>abortjob</function> to abort a job or the given files are processed and put to the queue.</para>
|
|
|
|
<para>To process a job, the existence of it and its format will be checked. Currently, only PostScript is allowed. The &cs; core
|
|
itself only supports the SF format. Therefore, the files are converted from PostScript to it by calling
|
|
<command>ghostscript</command>. Finally, the description file for this job is created containing the given parameters like the
|
|
destination number.</para>
|
|
</sect2>
|
|
<sect2 id="default_helpers"><title>cs_helpers.py</title>
|
|
<para>The <filename>cs_helpers.py</filename> script contains many small helper functions used in the other scripts. These are:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><function>readConfig</function></term>
|
|
<listitem><para>Reads either the configuration files described in <xref linkend="script_config"/> or an arbitrary
|
|
config file like the description files accompanying each received file or job to send.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><function>escape</function></term>
|
|
<listitem><para>"Escapes" a file name - this means puts it into quotation marks to be able to
|
|
call external tools with it as parameter savely and correctly even if the name contains
|
|
special characters or whitespaces.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><function>getOption</function></term>
|
|
<listitem><para>Get an option from the given user section and fall back to the global section if it's not found.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><function>getAudio</function></term>
|
|
<listitem><para>Get an audio file from the users directory or fall back to the global &cs; directory.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><function>uniqueName</function></term>
|
|
<listitem><para>Construct a new file name in a given directory by using a given prefix & suffix and adding a counter. See
|
|
also <xref linkend="incoming_tut_unique_names"/>.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><function>sendMIMEMail</function></term>
|
|
<listitem><para>Send an e-mail with attachment to a given user. Supports also automatic format conversion SFF -> PDF and
|
|
inversed A-Law -> WAV.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><function>sendSimpleMail</function></term>
|
|
<listitem><para>Send a normal e-mail without attachment to a given user.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><function>writeDescription</function></term>
|
|
<listitem><para>Create a description file which can be read by <function>readConfig</function> later.</para></listitem>
|
|
</varlistentry>
|
|
<varlistentry>
|
|
<term><function>sayNumber</function></term>
|
|
<listitem><para>Supports saying a number using various wave fragments. Works only for german output currently.</para></listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>For a detailled description of each function and its usage, please have a look at the script file itself. There are
|
|
comments describing each function in detail.</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 id="command_reference"><title>&cs; command reference</title>
|
|
<para>&cs; provides an internal Python module called <literal>capisuite</literal> which can be imported as usual by <literal>import capisuite</literal>.
|
|
Internal means, it's compiled in the &cs; binary and will only be found if &cs; interpretes the script.</para>
|
|
|
|
<para>A complete reference of all functions of this module is auto-generated from the &cs; sources and so you'll find it in the reference
|
|
manual available locally on <ulink url="../reference/group__python.html"/> or online on
|
|
<ulink url="http://www.capisuite.de/capisuite/reference/group__python.html"/>.</para>
|
|
|
|
<para>As it doesn't make sense to duplicate the information here, please refer to it.</para>
|
|
|
|
<note><para>These functions are implemented in C internally and so the reference document shows the C function header instead
|
|
of the header how it would be defined in Python. So please ignore the function header shown there and only have a look at the
|
|
description and the parameters given under <emphasis>args</emphasis>. If this is too confusing, please tell me and perhaps I'll
|
|
find a better way to auto-create this document someday then...</para></note>
|
|
</sect1>
|
|
|
|
</chapter>
|
|
<appendix id="acknowledgements"><title>Acknowledgements</title>
|
|
<para>&cs; started as diploma thesis in winter semester 2002/03. I want to thank the following people for helping me with it:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para>Karsten Keil from SuSE Linux AG (my tutor for the thesis) for his invaluable support and patience when answering me
|
|
many ISDN questions, doing tests and for his suggestions concerning the architecture of &cs;</para></listitem>
|
|
|
|
<listitem><para>Prof. Dr. Wolfgang Jürgensen from the UAS Landshut (my tutor from the UAS) for his help in ISDN
|
|
questions during the thesis and for teaching me the ISDN basics in his lecture before</para></listitem>
|
|
|
|
<listitem><para>Prof. Dr. Peter Scholz from the UAS Landshut (second tutor from the UAS) for his support and his suggestions</para></listitem>
|
|
|
|
<listitem><para>my girl friend Claudia and her sister Bethina for proof-reading my thesis</para></listitem>
|
|
|
|
<listitem><para>Peter Reinhart from SuSE for proof-reading my thesis</para></listitem>
|
|
|
|
<listitem><para>many colleagues from SuSE for helping me with technical problems, esp. Andreas Jaeger, Andreas Schwab, Thorsten Kukuk and Andi Kleen</para></listitem>
|
|
|
|
<listitem><para>Achim Bohnet for being the first one from the community trying to compile the CVS version and making me quite some suggestions
|
|
how to improve it</para></listitem>
|
|
|
|
<listitem><para>Achim Bohnet and Herbert Hübner for providing binary RPMs for
|
|
RedHat and Debian</para></listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Since I published &cs;, many other people tested it, reported errors and sent me bug
|
|
fixes or new code to include. I won't mention them all here, but I'm including all names in the
|
|
ChangeLog and NEWS files distributed with &cs;. A general THANK YOU to all of my users and
|
|
especially those named there!</para>
|
|
</appendix>
|
|
|
|
<appendix id="capicodes"><title>CAPI 2.0 Error Codes</title>
|
|
<para>The CAPI interface used here has its own coding of standard ISDN
|
|
error codes. Most of the errors described in <xref linkend="capicodes_general"/>
|
|
are only important for developers of the &cs; core. As user, you only need
|
|
to know the codes shown in <xref linkend="capicodes_connection"/>
|
|
as they'll be used in the &cs; Python functions like <function>capisuite.disconnect</function>.</para>
|
|
|
|
<para>You'll find a list of all the codes and a short description below. A detailled description of
|
|
the CAPI codes can be found in the CAPI specification available at
|
|
<ulink url="http://www.capi.org"/>.</para>
|
|
|
|
<para>All numbers are given <emphasis>hexadecimal</emphasis>!</para>
|
|
|
|
<section id="capicodes_connection"><title>CAPI errors describing connection problems</title>
|
|
|
|
<para>All errors described here indicate some problem with the connection. These errors
|
|
are also important for script writers as they're returned by some &cs; Python functions.
|
|
See <xref linkend="command_reference"/> for further details.</para>
|
|
|
|
<section id="capicodes_protocol"><title>Protocol errors</title>
|
|
<para>Protocol errors indicate some problem during data transfer. Only messages for
|
|
the transparent (voice) and fax protocols spoken by &cs; are shown here.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para><literal>0</literal> - Normal call clearing, no error</para></listitem>
|
|
<listitem><para><literal>3301</literal> - Protocol error layer 1 (broken line or B-channel removed by signalling protocol)</para></listitem>
|
|
<listitem><para><literal>3302</literal> - Protocol error layer 2</para></listitem>
|
|
<listitem><para><literal>3303</literal> - Protocol error layer 3</para></listitem>
|
|
<listitem><para><literal>3304</literal> - Another application got that call</para></listitem>
|
|
<listitem><para><literal>3311</literal> - T.30 (fax) error: Connection not successful (remote station is not a G3 fax device)</para></listitem>
|
|
<listitem><para><literal>3312</literal> - T.30 (fax) error: Connection not successful (training error)</para></listitem>
|
|
<listitem><para><literal>3313</literal> - T.30 (fax) error: Disconnect before transfer (remote station doesn't support transfer mode, e.g. wrong resolution)</para></listitem>
|
|
<listitem><para><literal>3314</literal> - T.30 (fax) error: Disconnect during transfer (remote abort)</para></listitem>
|
|
<listitem><para><literal>3315</literal> - T.30 (fax) error: Disconnect during transfer (remote procedure error)</para></listitem>
|
|
<listitem><para><literal>3316</literal> - T.30 (fax) error: Disconnect during transfer (local transmit data underflow)</para></listitem>
|
|
<listitem><para><literal>3317</literal> - T.30 (fax) error: Disconnect during transfer (local receive data overflow)</para></listitem>
|
|
<listitem><para><literal>3318</literal> - T.30 (fax) error: Disconnect during transfer (local abort)</para></listitem>
|
|
<listitem><para><literal>3319</literal> - T.30 (fax) error: Illegal parameter coding (e.g. defective SFF file)</para></listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
<section id="capicodes_isdn"><title>ISDN error codes</title>
|
|
|
|
<para>These codes are ISDN error codes which are described by the
|
|
ETS 300 102-01 standard in more detail. It's currently available for private use at
|
|
<ulink url="http://www.etsi.org"/> without fee. For details how the ISDN codes
|
|
are mapped to the CAPI numbers see the CAPI specification, parameter "Info".</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para><literal>3400</literal> - Normal termination, no reason available</para></listitem>
|
|
<listitem><para><literal>3480</literal> - Normal termination</para></listitem>
|
|
<listitem><para><literal>3481</literal> - Unallocated (unassigned) number</para></listitem>
|
|
<listitem><para><literal>3482</literal> - No route to specified transit network</para></listitem>
|
|
<listitem><para><literal>3483</literal> - No route to destination</para></listitem>
|
|
<listitem><para><literal>3486</literal> - Channel unacceptable</para></listitem>
|
|
<listitem><para><literal>3487</literal> - Call awarded and being delivered in an established channel</para></listitem>
|
|
<listitem><para><literal>3490</literal> - Normal call clearing</para></listitem>
|
|
<listitem><para><literal>3491</literal> - User busy</para></listitem>
|
|
<listitem><para><literal>3492</literal> - No user responding</para></listitem>
|
|
<listitem><para><literal>3493</literal> - No answer from user (user alerted)</para></listitem>
|
|
<listitem><para><literal>3495</literal> - Call rejected</para></listitem>
|
|
<listitem><para><literal>3496</literal> - Number changed</para></listitem>
|
|
<listitem><para><literal>349A</literal> - Non-selected user clearing</para></listitem>
|
|
<listitem><para><literal>349B</literal> - Destination out of order</para></listitem>
|
|
<listitem><para><literal>349C</literal> - Invalid number format</para></listitem>
|
|
<listitem><para><literal>349D</literal> - Facility rejected</para></listitem>
|
|
<listitem><para><literal>349E</literal> - Response to STATUS ENQUIRY</para></listitem>
|
|
<listitem><para><literal>349F</literal> - Normal, unspecified</para></listitem>
|
|
<listitem><para><literal>34A2</literal> - No circuit / channel available</para></listitem>
|
|
<listitem><para><literal>34A6</literal> - Network out of order</para></listitem>
|
|
<listitem><para><literal>34A9</literal> - Temporary failure</para></listitem>
|
|
<listitem><para><literal>34AA</literal> - Switching equipment congestion</para></listitem>
|
|
<listitem><para><literal>34AB</literal> - Access information discarded</para></listitem>
|
|
<listitem><para><literal>34AC</literal> - Requested circuit / channel not available</para></listitem>
|
|
<listitem><para><literal>34AF</literal> - Resources unavailable, unspecified</para></listitem>
|
|
<listitem><para><literal>34B1</literal> - Quality of service unavailable</para></listitem>
|
|
<listitem><para><literal>34B2</literal> - Requested facility not subscribed</para></listitem>
|
|
<listitem><para><literal>34B9</literal> - Bearer capability not authorized</para></listitem>
|
|
<listitem><para><literal>34BA</literal> - Bearer capability not presently available</para></listitem>
|
|
<listitem><para><literal>34BF</literal> - Service or option not available, unspecified</para></listitem>
|
|
<listitem><para><literal>34C1</literal> - Bearer capability not implemented</para></listitem>
|
|
<listitem><para><literal>34C2</literal> - Channel type not implemented</para></listitem>
|
|
<listitem><para><literal>34C5</literal> - Requested facility not implemented</para></listitem>
|
|
<listitem><para><literal>34C6</literal> - Only restricted digital information bearer capability is available</para></listitem>
|
|
<listitem><para><literal>34CF</literal> - Service or option not implemented, unspecified</para></listitem>
|
|
<listitem><para><literal>34D1</literal> - Invalid call reference value</para></listitem>
|
|
<listitem><para><literal>34D2</literal> - Identified channel does not exist</para></listitem>
|
|
<listitem><para><literal>34D3</literal> - A suspended call exists, but this call identity does not</para></listitem>
|
|
<listitem><para><literal>34D4</literal> - Call identity in use</para></listitem>
|
|
<listitem><para><literal>34D5</literal> - No call suspended</para></listitem>
|
|
<listitem><para><literal>34D6</literal> - Call having the requested call identity has been cleared</para></listitem>
|
|
<listitem><para><literal>34D8</literal> - Incompatible destination</para></listitem>
|
|
<listitem><para><literal>34DB</literal> - Invalid transit network selection</para></listitem>
|
|
<listitem><para><literal>34DF</literal> - Invalid message, unspecified</para></listitem>
|
|
<listitem><para><literal>34E0</literal> - Mandatory information element is missing</para></listitem>
|
|
<listitem><para><literal>34E1</literal> - Message type non-existent or not implemented</para></listitem>
|
|
<listitem><para><literal>34E2</literal> - Message not compatible with call state or message type non-existent or not implemented</para></listitem>
|
|
<listitem><para><literal>34E3</literal> - Information element non-existent or not implemented</para></listitem>
|
|
<listitem><para><literal>34E4</literal> - Invalid information element contents</para></listitem>
|
|
<listitem><para><literal>34E5</literal> - Message not compatible with call state</para></listitem>
|
|
<listitem><para><literal>34E6</literal> - Recovery on timer expiry</para></listitem>
|
|
<listitem><para><literal>34EF</literal> - Protocol error, unspecified</para></listitem>
|
|
<listitem><para><literal>34FF</literal> - Interworking, unspecified</para></listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="capicodes_general"><title>Internal CAPI errors</title>
|
|
<para>These errors are mainly of interest for developers of the &cs; core. If you're a user, you normally
|
|
won't need them.</para>
|
|
|
|
<section id="capicodes_info"><title>Informative values (no error)</title>
|
|
<para>These values are only warnings and may appear in the extensive &cs; log in messages from the CAPI.</para>
|
|
<itemizedlist>
|
|
<listitem><para><literal>0000</literal> - No error, request accepted</para></listitem>
|
|
<listitem><para><literal>0001</literal> - NCPI not supported by current protocol, NCPI ignored</para></listitem>
|
|
<listitem><para><literal>0002</literal> - Flags not supported by current protocol, flags ignored</para></listitem>
|
|
<listitem><para><literal>0003</literal> - Alert already sent by another application</para></listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
<section id="capicodes_register"><title>Errors concerning CAPI_REGISTER</title>
|
|
<para>These errors may appear when the application starts and mostly indicate problems with your driver installation.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para><literal>1001</literal> - Too many applications.</para></listitem>
|
|
<listitem><para><literal>1002</literal> - Logical Block size too small; must be at least 128 bytes.</para></listitem>
|
|
<listitem><para><literal>1003</literal> - Buffer exceeds 64 kbytes.</para></listitem>
|
|
<listitem><para><literal>1004</literal> - Message buffer size too small, must be at least 1024 bytes.</para></listitem>
|
|
<listitem><para><literal>1005</literal> - Max. number of logical connections not supported.</para></listitem>
|
|
<listitem><para><literal>1006</literal> - reserved (unknown error).</para></listitem>
|
|
<listitem><para><literal>1007</literal> - The message could not be accepted because of an internal busy condition.</para></listitem>
|
|
<listitem><para><literal>1008</literal> - OS Resource error (out of memory?).</para></listitem>
|
|
<listitem><para><literal>1009</literal> - CAPI not installed.</para></listitem>
|
|
<listitem><para><literal>100A</literal> - Controller does not support external equipment.</para></listitem>
|
|
<listitem><para><literal>100B</literal> - Controller does only support external equipment.</para></listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
<section id="capicodes_messages"><title>Message exchange errors</title>
|
|
<para>These errors are really internal: they're raised if the application calls
|
|
CAPI in a wrong way. If they occur, it's usually a bug which you should tell
|
|
the &cs; developers.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para><literal>1101</literal> - Illegal application number.</para></listitem>
|
|
<listitem><para><literal>1102</literal> - Illegal command or subcommand, or message length less than 12 octets.</para></listitem>
|
|
<listitem><para><literal>1103</literal> - The message could not be accepted because of a queue full condition.</para></listitem>
|
|
<listitem><para><literal>1104</literal> - Queue is empty.</para></listitem>
|
|
<listitem><para><literal>1105</literal> - Queue overflow: a message was lost!!</para></listitem>
|
|
<listitem><para><literal>1106</literal> - Unknown notification parameter.</para></listitem>
|
|
<listitem><para><literal>1107</literal> - The message could not be accepted because on an internal busy condition.</para></listitem>
|
|
<listitem><para><literal>1108</literal> - OS resource error (out of memory?).</para></listitem>
|
|
<listitem><para><literal>1109</literal> - CAPI not installed.</para></listitem>
|
|
<listitem><para><literal>110A</literal> - Controller does not support external equipment.</para></listitem>
|
|
<listitem><para><literal>110B</literal> - Controller does only support external equipment.</para></listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
<section id="capicodes_resource"><title>Resource/Coding Errors</title>
|
|
<para>The errors described here are issued when the application tries to use a ressource which isn't available.
|
|
These are mostly also bugs in the application. Please tell us.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para><literal>2001</literal> - Message not supported in current state</para></listitem>
|
|
<listitem><para><literal>2002</literal> - Illegal Controller / PLCI / NCCI</para></listitem>
|
|
<listitem><para><literal>2003</literal> - Out of PLCI</para></listitem>
|
|
<listitem><para><literal>2004</literal> - Out of NCCI</para></listitem>
|
|
<listitem><para><literal>2005</literal> - Out of LISTEN</para></listitem>
|
|
<listitem><para><literal>2007</literal> - llegal message parameter coding</para></listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
<section id="capicodes_service"><title>Errors concerning requested services</title>
|
|
<para>The errors described here are issued when the application tries to request a service in a wrong way.
|
|
Again, these are mostly bugs you should tell us.</para>
|
|
|
|
<itemizedlist>
|
|
<listitem><para><literal>3001</literal> - B1 protocol not supported</para></listitem>
|
|
<listitem><para><literal>3002</literal> - B2 protocol not supported</para></listitem>
|
|
<listitem><para><literal>3003</literal> - B3 protocol not supported</para></listitem>
|
|
<listitem><para><literal>3004</literal> - B1 protocol parameter not supported</para></listitem>
|
|
<listitem><para><literal>3005</literal> - B2 protocol parameter not supported</para></listitem>
|
|
<listitem><para><literal>3006</literal> - B3 protocol parameter not supported</para></listitem>
|
|
<listitem><para><literal>3007</literal> - B protocol combination not supported</para></listitem>
|
|
<listitem><para><literal>3008</literal> - NCPI not supported</para></listitem>
|
|
<listitem><para><literal>3009</literal> - CIP Value unknown</para></listitem>
|
|
<listitem><para><literal>300A</literal> - Flags not supported (reserved bits)</para></listitem>
|
|
<listitem><para><literal>300B</literal> - Facility not supported</para></listitem>
|
|
<listitem><para><literal>300C</literal> - Data length not supported by current protocol</para></listitem>
|
|
<listitem><para><literal>300D</literal> - Reset procedure not supported by current protocol</para></listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
</section>
|
|
</appendix>
|
|
|
|
</book>
|