- support reception of color fax documents

git-svn-id: https://svn.ibp.de/svn/capisuite/trunk/capisuite@120 4ebea2bb-67d4-0310-8558-a5799e421b66
This commit is contained in:
gernot 2003-05-25 13:38:30 +00:00
parent 6832b7a392
commit 7c4423720a
7 changed files with 157 additions and 38 deletions

View File

@ -230,13 +230,25 @@
<varlistentry>
<term>aktueller Ghostscript mit cfax-Patch</term>
<listitem><para>Aktuelle Ghostscript-Versionen enthalten ein Device, um die
oben erwähnten SFF-Dateien zu erstellen. Wenn Sie eine ältere Version haben,
brauchen Sie den Patch von
<ulink url="http://sfftools.sourceforge.net/ghostscript.html"/>. Um zu
prüfen, ob Ihre GhostScript-Version diesen Patch bereits hat, rufen Sie bitte
<command>gs --help</command> auf und sehen nach, ob Sie das Device
oben erwähnten SFF-Dateien zu erstellen. Wenn Sie eine ältere Version haben,
brauchen Sie den Patch von
<ulink url="http://sfftools.sourceforge.net/ghostscript.html"/>. Um zu
prüfen, ob Ihre GhostScript-Version diesen Patch bereits hat, rufen Sie bitte
<command> auf und sehen nach, ob Sie das Device
<literal>cfax</literal> in der langen Liste der unterstützten Devices
finden können.</para>
finden können.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>jpeg2ps</term>
<listitem><para>Das <command>jpeg2ps</command>-Kommando wird zur Konvertierung von Farbfaxen in
das PostScript-Format für die Mailzustellung benötigt. Sie brauchen es nicht, wenn Sie keine
Farbfaxe empfangen wollen. Unglücklicherweise gibt es wegen eines Treiberfehlers momentan keine
Möglichkeit, den Empfang von Faxdokumenten bei AVM-ISDN-Karten komplett zu deaktivieren. Wenn Ihnen
also jemand ein Farbfax schicken sollte (was nach meiner Erfahrung nur sehr selten vorkommt), dann
bekommen Sie eine Fehlermeldung per Mail, wenn Sie dieses Programm nicht installiert haben.
Wenn Ihre Linux-Distribution dieses Paket nicht enthält, können Sie es von
<ulink url="http://www.pdflib.com/jpeg2ps/"/> herunterladen.
</listitem>
</varlistentry>
</variablelist>
@ -1660,6 +1672,9 @@ is not present, current time as returned by localtime() is used.
einige kleine Tools gefunden, die Peter Schäfer geschrieben hat und die wir hier verwenden
werden.</para>
<para>CapiSuite kann auch Farbfaxe empfangen, welche in einem speziellen Dateiformat abgelegt
werden, das ich CFF genannt habe.</para>
<sect3 id="create_sff"><title>Erzeugen eines SFF</title>
<para>In aktuellen Ghostscript-Versionen gibt es einen Patch von Peter, um SF-Dateien zu
erstellen. Um zu prüfen, ob Ihr Ghostscript das schon unterstützt,
@ -1697,7 +1712,23 @@ is not present, current time as returned by localtime() is used.
konvertieren können.
</para>
</sect3>
<sect3 id="cff"><title>Farbfaxe - das CFF-Format</title>
<para>Es gibt eine Erweiterung zum Fax-Standard, die die Übertragung von farbigen
Dokumenten erlaubt. Sie wird nur selten benutzt, aber da einige User sie trotzdem
benötigten, habe ich den Empfang solcher Dokumente mittlerweile in CapiSuite realisiert.
</para>
<para>Das CFF-Format (ich weiß nicht sicher, ob das ein offizieller Name für das Format ist)
scheint eine JPEG-Datei mit spezieller Kodierung zu sein. Die meisten Programme, die
JPEG-Dateien unterstützen, sollten CFF-Dateien ebenfalls öffnen können. Eventuell müssen
Sie die Datei von <filename>.cff</filename> in <filename>.jpg</filename> umbenennen, bevor
Sie sie öffnen können.
<para>Leider kenne ich momentan keinen Weg, dieses Format manuell zu erzeugen.
Daher unterstützt CapiSuite bis jetzt nur den Empfang solcher Dokumente. Wenn Sie
mehr darüber wissen sollten oder den JPEG-Standard gut kennen, dann kontaktieren
Sie mich bitte!
</sect3>
</sect2>
</sect1>

View File

@ -20,7 +20,7 @@
<preface id="intro"><title>Introduction</title>
<sect1 id="welcome"><title>Welcome to &cs;</title>
<para>Welcome to &cs;, a Python-scriptable ISDN telecommunication suite.
<para>Welcome to &cs;, 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
@ -214,6 +214,17 @@
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/jpeg2ps/"/>.
</listitem>
</varlistentry>
</variablelist>
</sect3>
</sect2>
@ -1491,6 +1502,9 @@ is not present, current time as returned by localtime() is used.
Finally I found some small tools written by Peter Sch&auml;fer, which we can
use here.</para>
<para>CapiSuite 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
@ -1526,7 +1540,20 @@ is not present, current time as returned by localtime() is used.
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 CapiSuite,
I added support for receiving this faxes with CapiSuite.</para>
<para>The CFF format (I don't know if this is an official name for the format) seems
to be some sort of JPEG file with a special encoding. Most programs who can handle
JPEG files should be able to open it. Perhaps you must rename it from
<filename>.cff</filename> to <filename>.jpg</filename> first, before it will be recognized.</para>
<para>Currently, I don't know a nice way to create this format manually. Therefore,
CapiSuite currently only supports the reception of these files. If someone knows
more about it or knows the JPEG standards well, please contace me!</para>
</sect3>
</sect2>
</sect1>

View File

@ -2,7 +2,7 @@
# -----------------------------------------------------------
# copyright : (C) 2002 by Gernot Hillier
# email : gernot@hillier.de
# version : $Revision: 1.9 $
# version : $Revision: 1.10 $
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -161,7 +161,7 @@ def sendMIMEMail(mail_from,mail_to,mail_subject,mail_type,text,attachment):
basename=attachment[:attachment.rindex('.')+1]
try:
if (mail_type=="sff"):
if (mail_type=="sff"): # normal fax file
# sff -> tif
ret=os.spawnlp(os.P_WAIT,"sfftobmp","sfftobmp","-tif",attachment,basename+"tif")
if (ret or not os.access(basename+"tif",os.F_OK)):
@ -173,7 +173,7 @@ def sendMIMEMail(mail_from,mail_to,mail_subject,mail_type,text,attachment):
command="tiff2ps -a "+escape(basename+"tif")+" | ps2pdf - -"
tiff2pdf=popen2.Popen3(command)
if (tiff2pdf.poll()!=-1):
raise "conv-error","Error while calling tiff2pdf or ps2pdf. Not installed?"
raise "conv-error","Error while calling tiff2ps or ps2pdf. Not installed?"
tiff2pdf.tochild.close() # we don't need the input pipe
# create attachment with pdf stream
filepart = email.MIMEBase.MIMEBase("application","pdf",name=os.path.basename(basename)+"pdf")
@ -185,7 +185,31 @@ def sendMIMEMail(mail_from,mail_to,mail_subject,mail_type,text,attachment):
raise "conv-error","Error "+str(ret)+" occured during tiff2ps or ps2pdf"
os.unlink(basename+"tif")
email.Encoders.encode_base64(filepart)
elif (mail_type=="la"):
elif (mail_type=="cff"): # color fax file
# cff -> ps
ret=os.spawnlp(os.P_WAIT,"jpeg2ps","jpeg2ps",attachment,"-o",basename+"ps")
if (ret or not os.access(basename+"ps",os.F_OK)):
raise "conv-error","Can't convert cff to ps. jpeg2ps not installed?"
# tif -> ps -> pdf
# the first pipe must be handled by the shell so that the output of
# of ps2pdf can be read immediately. Handling this shell in Python
# leads to an overflow of the ps2pdf output pipe...
command="ps2pdf "+escape(basename+"ps")+" -"
ps2pdf=popen2.Popen3(command)
if (ps2pdf.poll()!=-1):
raise "conv-error","Error while calling ps2pdf. Not installed?"
ps2pdf.tochild.close() # we don't need the input pipe
# create attachment with pdf stream
filepart = email.MIMEBase.MIMEBase("application","pdf",name=os.path.basename(basename)+"pdf")
filepart.add_header('Content-Disposition','attachment',filename=os.path.basename(basename)+"pdf")
filepart.set_payload(ps2pdf.fromchild.read())
ps2pdf.fromchild.close()
ret=ps2pdf.wait()
if (ret!=0):
raise "conv-error","Error "+str(ret)+" occured during ps2pdf"
os.unlink(basename+"ps")
email.Encoders.encode_base64(filepart)
elif (mail_type=="la"): # voice file
# la -> wav
# don't use stdout as sox needs a file to be able to seek in it otherwise the header will be incomplete
ret = os.spawnlp(os.P_WAIT,"sox","sox",attachment,basename+"wav")
@ -317,6 +341,9 @@ def sayNumber(call,number,curr_user,config):
capisuite.audio_send(call,getAudio(config,curr_user,i+".la"),1)
# $Log: cs_helpers.pyin,v $
# Revision 1.10 2003/05/25 13:38:30 gernot
# - support reception of color fax documents
#
# Revision 1.9 2003/04/24 21:04:20 gernot
# - replace functions deprecated in Python 2.2.2 (mainly related to the email
# module)

View File

@ -2,7 +2,7 @@
# ----------------------------------------------------
# copyright : (C) 2002 by Gernot Hillier
# email : gernot@hillier.de
# version : $Revision: 1.6 $
# version : $Revision: 1.7 $
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -73,13 +73,6 @@ def callIncoming(call,service,call_from,call_to):
capisuite.connect_voice(call,int(delay))
voiceIncoming(call,call_from,call_to,curr_user,config)
elif (curr_service==capisuite.SERVICE_FAXG3):
stationID=cs_helpers.getOption(config,curr_user,"fax_stationID")
if (stationID==None):
capisuite.error("Warning: fax_stationID not found for user "+curr_user+" -> using empty string")
stationID=""
headline=cs_helpers.getOption(config,curr_user,"fax_headline","") # empty string is no problem here
capisuite.log("call from "+call_from+" to "+call_to+" for "+curr_user+" connecting with fax",1,call)
capisuite.connect_faxG3(call,stationID,headline,0)
faxIncoming(call,call_from,call_to,curr_user,config)
except capisuite.CallGoneError: # catch exceptions from connect_*
(cause,causeB3)=capisuite.disconnect(call)
@ -112,8 +105,19 @@ def faxIncoming(call,call_from,call_to,curr_user,config):
capisuite.error("user "+curr_user+" is not a valid system user. Disconnecting",call)
capisuite.reject(call,0x34A9)
return
filename=cs_helpers.uniqueName(udir+"received/","fax","sff")
try:
stationID=cs_helpers.getOption(config,curr_user,"fax_stationID")
if (stationID==None):
capisuite.error("Warning: fax_stationID not found for user "+curr_user+" -> using empty string")
stationID=""
headline=cs_helpers.getOption(config,curr_user,"fax_headline","") # empty string is no problem here
capisuite.log("call from "+call_from+" to "+call_to+" for "+curr_user+" connecting with fax",1,call)
faxInfo=capisuite.connect_faxG3(call,stationID,headline,0)
if (faxInfo!=None and faxInfo[3]==1):
faxFormat="cff" # color fax
else:
faxFormat="sff" # normal b&w fax
filename=cs_helpers.uniqueName(udir+"received/","fax",faxFormat)
capisuite.fax_receive(call,filename)
(cause,causeB3)=capisuite.disconnect(call)
capisuite.log("connection finished with cause 0x%x,0x%x" % (cause,causeB3),1,call)
@ -140,7 +144,7 @@ def faxIncoming(call,call_from,call_to,curr_user,config):
capisuite.error("Warning: No valid fax_action definition found for user "+curr_user+" -> assuming SaveOnly")
action="saveonly"
if (action=="mailandsave"):
cs_helpers.sendMIMEMail(curr_user, mailaddress, "Fax received from "+call_from+" to "+call_to, "sff",
cs_helpers.sendMIMEMail(curr_user, mailaddress, "Fax received from "+call_from+" to "+call_to, faxFormat,
"You got a fax from "+call_from+" to "+call_to+"\nDate: "+time.ctime()+"\n\n"
+"See attached file.\nThe original file was saved to file://"+filename+"\n\n", filename)
@ -402,6 +406,9 @@ def newAnnouncement(call,userdir,curr_user,config):
# History:
#
# $Log: incoming.py,v $
# Revision 1.7 2003/05/25 13:38:30 gernot
# - support reception of color fax documents
#
# Revision 1.6 2003/04/10 21:29:51 gernot
# - support empty destination number for incoming calls correctly (austrian
# telecom does this (sic))

View File

@ -2,7 +2,7 @@
@brief Contains the Python module and integration routines
@author Gernot Hillier <gernot@hillier.de>
$Revision: 1.3 $
$Revision: 1.4 $
*/
/***************************************************************************
@ -496,8 +496,9 @@ capisuite_reject(PyObject *, PyObject *args)
@param service with which service we should connect
@param faxStationID only used for fax connections
@param faxHeadline only used for fax connections
@return false if exception was rased -> calling function must return NULL then
*/
static PyObject*
bool
capisuite_connect(Connection *conn, int delay, Connection::service_t service, string faxStationID, string faxHeadline)
{
PyThreadState *_save;
@ -514,20 +515,19 @@ capisuite_connect(Connection *conn, int delay, Connection::service_t service, st
catch (CapiMsgError e) {
Py_BLOCK_THREADS
PyErr_SetString(BackendError,(e.message()).c_str());
return NULL;
return false;
}
catch (CapiWrongState e) {
Py_BLOCK_THREADS
PyErr_SetString(CallGoneError,"Call was finished from partner.");
return NULL;
return false;
}
catch (CapiExternalError e) {
Py_BLOCK_THREADS
PyErr_SetString(BackendError,(e.message()).c_str());
return NULL;
return false;
}
Py_XINCREF(Py_None);
return (Py_None);
return true;
}
/** @brief Accept an incoming call and connect with voice service.
@ -554,7 +554,11 @@ capisuite_connect_voice(PyObject *, PyObject *args)
if (!PyArg_ParseTuple(args,"O&|i:connect_voice",convertConnRef,&conn,&delay))
return NULL;
return capisuite_connect(conn,delay,Connection::VOICE,"","");
if (capisuite_connect(conn,delay,Connection::VOICE,"","")) {
Py_XINCREF(Py_None);
return (Py_None);
} else
return NULL;
}
/** @brief Accept an incoming call and connect with fax (analog, group 3) service.
@ -571,7 +575,11 @@ capisuite_connect_voice(PyObject *, PyObject *args)
- <b>faxStationID (string)</b> the station ID to use
- <b>faxHeadline (string)</b> the fax headline to use
- <b>delay (integer, optional)</b> delay in seconds _before_ connection will be established (default: 0=immediate connect)
@return None
@return None or a tuple (stationID,rate,hiRes,format) containing the values:
- fax station ID from the calling party (String)
- bit rate which was used for connecting
- high (1) or low (0) resolution
- transmit format: 0=SFF,black&white, 1=ColorJPEG
*/
static PyObject*
capisuite_connect_faxG3(PyObject *, PyObject *args)
@ -583,7 +591,17 @@ capisuite_connect_faxG3(PyObject *, PyObject *args)
if (!PyArg_ParseTuple(args,"O&ss|i:connect_faxG3",convertConnRef,&conn,&faxStationID,&faxHeadline,&delay))
return NULL;
return capisuite_connect(conn,delay,Connection::FAXG3,faxStationID,faxHeadline);
if (capisuite_connect(conn,delay,Connection::FAXG3,faxStationID,faxHeadline)) {
Connection::fax_info_t* fax_info = conn->getFaxInfo();
if (fax_info) {
PyObject *r=Py_BuildValue("siii",fax_info->stationID.c_str(),fax_info->rate,fax_info->hiRes,fax_info->format);
return (r);
} else {
Py_XINCREF(Py_None);
return (Py_None);
}
} else
return NULL;
}
/** @brief helper function for capisuite_call_voice() and capisuite_call_faxG3()
@ -937,6 +955,9 @@ capisuitemodule_init () throw (ApplicationError)
/* History
$Log: capisuitemodule.cpp,v $
Revision 1.4 2003/05/25 13:38:30 gernot
- support reception of color fax documents
Revision 1.3 2003/04/17 10:53:54 gernot
- update documentation of capisuite_call_* to the new behaviour (timeout for
outgoing calls starts when other party gets signalled), moved error code

View File

@ -2,7 +2,7 @@
@brief Contains Connection - Encapsulates a CAPI connection with all its states and methods.
@author Gernot Hillier <gernot@hillier.de>
$Revision: 1.8 $
$Revision: 1.9 $
*/
/***************************************************************************
@ -415,12 +415,12 @@ Connection::connect_b3_active_ind(_cmsg& message) throw (CapiWrongState, CapiExt
fax_info=new fax_info_t;
fax_info->rate=ncpi[1]+(ncpi[2]<<8);
fax_info->hiRes=((ncpi[3] & 0x01) == 0x01);
fax_info->colorJPEG=((ncpi[4] & 0x04) == 0x04);
fax_info->format=((ncpi[4] & 0x04) == 0x04);
fax_info->pages=ncpi[7]+(ncpi[8]<<8);
fax_info->stationID.assign(reinterpret_cast<char*>(&ncpi[10]),static_cast<int>(ncpi[9])); // indx 9 helds the length, string starts at 10
if (debug_level >= 2) {
debug << prefix() << "fax connected with rate " << dec << fax_info->rate
<< (fax_info->hiRes ? ", hiRes" : ", lowRes") << (fax_info->colorJPEG ? ", JPEG" : "")
<< (fax_info->hiRes ? ", hiRes" : ", lowRes") << (fax_info->format ? ", JPEG" : "")
<< ", ID: " << fax_info->stationID << endl;
}
}
@ -449,12 +449,12 @@ Connection::disconnect_b3_ind(_cmsg& message) throw (CapiWrongState)
fax_info=new fax_info_t;
fax_info->rate=ncpi[1]+(ncpi[2]<<8);
fax_info->hiRes=((ncpi[3] & 0x01) == 0x01);
fax_info->colorJPEG=((ncpi[4] & 0x04) == 0x04);
fax_info->format=((ncpi[4] & 0x04) == 0x04);
fax_info->pages=ncpi[7]+(ncpi[8]<<8);
fax_info->stationID.assign(reinterpret_cast<char*>(&ncpi[10]),static_cast<int>(ncpi[9])); // indx 9 helds the length, string starts at 10
if (debug_level >= 2) {
debug << prefix() << "fax finished with rate " << dec << fax_info->rate
<< (fax_info->hiRes ? ", hiRes" : ", lowRes") << (fax_info->colorJPEG ? ", JPEG" : "")
<< (fax_info->hiRes ? ", hiRes" : ", lowRes") << (fax_info->format ? ", JPEG" : "")
<< ", ID: " << fax_info->stationID << ", " << fax_info->pages << " pages" << endl;
}
}
@ -1040,6 +1040,9 @@ Connection::buildBconfiguration(_cdword controller, service_t service, string fa
/* History
$Log: connection.cpp,v $
Revision 1.9 2003/05/25 13:38:30 gernot
- support reception of color fax documents
Revision 1.8 2003/05/24 13:48:54 gernot
- get fax details (calling station ID, transfer format, ...), handle PLCI

View File

@ -2,7 +2,7 @@
@brief Contains Connection - Encapsulates a CAPI connection with all its states and methods.
@author Gernot Hillier <gernot@hillier.de>
$Revision: 1.4 $
$Revision: 1.5 $
*/
/***************************************************************************
@ -316,7 +316,7 @@ class Connection
struct fax_info_t {
int rate; ///< bit rate used at connect or at disconnect (depends when you ask for it)
bool hiRes; ///< fax is transferred in high resolution
bool colorJPEG; ///< color fax transmitted as JPEG file
unsigned short format; ///< 0=SFF,black&white, 1=colorJPEG
int pages; ///< number of transmitted pages (only available after disconnection!)
std::string stationID; ///< ID of the sending station
};
@ -657,6 +657,9 @@ class Connection
/* History
$Log: connection.h,v $
Revision 1.5 2003/05/25 13:38:30 gernot
- support reception of color fax documents
Revision 1.4 2003/05/24 13:48:54 gernot
- get fax details (calling station ID, transfer format, ...), handle PLCI