[asterisk-addons-commits] tilghman: trunk r497 - in /trunk: ./ build_tools/
SVN commits to the Asterisk addons project
asterisk-addons-commits at lists.digium.com
Fri Dec 14 15:56:07 CST 2007
Author: tilghman
Date: Fri Dec 14 15:56:06 2007
New Revision: 497
URL: http://svn.digium.com/view/asterisk-addons?view=rev&rev=497
Log:
Add faxing application
Patch by: dimas
(Closes issue #10815)
Added:
trunk/app_fax.c (with props)
Modified:
trunk/Makefile
trunk/build_tools/menuselect-deps.in
trunk/configure
trunk/configure.ac
trunk/makeopts.in
trunk/menuselect-tree
Modified: trunk/Makefile
URL: http://svn.digium.com/view/asterisk-addons/trunk/Makefile?view=diff&rev=497&r1=496&r2=497
==============================================================================
--- trunk/Makefile (original)
+++ trunk/Makefile Fri Dec 14 15:56:06 2007
@@ -61,7 +61,7 @@
endif
MODULES_DIR=$(ASTLIBDIR)/modules
-MODS:=app_addon_sql_mysql app_saycountpl cdr_addon_mysql chan_ooh323 format_mp3 res_config_mysql chan_mobile
+MODS:=app_addon_sql_mysql app_saycountpl cdr_addon_mysql chan_ooh323 format_mp3 res_config_mysql chan_mobile app_fax
SELECTED_MODS:=$(patsubst %,%.so,$(filter-out $(MENUSELECT_ADDONS),$(MODS)))
@@ -138,6 +138,9 @@
endif
ASTCFLAGS+=$(ASTERISK_INCLUDE)
+
+app_fax.so: app_fax.o
+ $(CC) $(SOLINK) -o $@ $< $(SPANDSP_LIB)
cdr_addon_mysql.so: cdr_addon_mysql.o
$(CC) $(SOLINK) -o $@ $< $(MYSQLCLIENT_LIB)
Added: trunk/app_fax.c
URL: http://svn.digium.com/view/asterisk-addons/trunk/app_fax.c?view=auto&rev=497
==============================================================================
--- trunk/app_fax.c (added)
+++ trunk/app_fax.c Fri Dec 14 15:56:06 2007
@@ -1,0 +1,532 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Simple fax applications
+ *
+ * 2007, Dmitry Andrianov <asterisk at dima.spb.ru>
+ *
+ * Code based on original implementation by Steve Underwood <steveu at coppice.org>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ *
+ */
+
+/*** MODULEINFO
+ <depend>spandsp</depend>
+***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision:$")
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <errno.h>
+#include <tiffio.h>
+
+#include <spandsp.h>
+
+#include "asterisk/lock.h"
+#include "asterisk/file.h"
+#include "asterisk/logger.h"
+#include "asterisk/channel.h"
+#include "asterisk/pbx.h"
+#include "asterisk/app.h"
+#include "asterisk/module.h"
+#include "asterisk/manager.h"
+
+#ifndef AST_MODULE
+#define AST_MODULE "app_fax"
+#endif
+
+static char *app_sndfax_name = "SendFAX";
+static char *app_sndfax_synopsis = "Send a FAX";
+static char *app_sndfax_desc =
+" SendFAX(filename[,options]):\n"
+"Send a given TIFF file to the channel as a FAX.\n"
+"The option string may contain zero or more of the following characters:\n"
+" 'a' -- makes the application behave as an answering machine\n"
+" The default behaviour is to behave as a calling machine.\n"
+" 'd' -- turn on debug output. This option may be specified multiple\n"
+" times (max 2) to increase verbosity.\n"
+"\n"
+"This application uses following variables:\n"
+" LOCALSTATIONID to identify itself to the remote end.\n"
+" LOCALHEADERINFO to generate a header line on each page.\n"
+"\n"
+"This application sets the following channel variables upon completion:\n"
+" FAXSTATUS - status of operation:\n"
+" SUCCESS | FAILED\n"
+" FAXERROR - Error when FAILED\n"
+" REMOTESTATIONID - CSID of the remote side.\n"
+" FAXPAGES - number of pages sent.\n"
+" FAXBITRATE - transmition rate.\n"
+" FAXRESOLUTION - resolution.\n"
+"\n"
+"Returns -1 in case of user hang up or any channel error.\n"
+"Returns 0 on success.\n";
+
+static char *app_rcvfax_name = "ReceiveFAX";
+static char *app_rcvfax_synopsis = "Receive a FAX";
+static char *app_rcvfax_desc =
+" ReceiveFAX(filename[,options]):\n"
+"Receives a fax from the channel into the given filename overwriting\n"
+"the file if it already exists. File created will have TIFF format.\n"
+"The option string may contain zero or more of the following characters:\n"
+" 'c' -- makes the application behave as a calling machine\n"
+" The default behaviour is to behave as an answering machine.\n"
+" 'd' -- turn on debug output. This option may be specified multiple\n"
+" times (max 2) to increase verbosity.\n"
+"\n"
+"This application uses following variables:\n"
+" LOCALSTATIONID to identify itself to the remote end.\n"
+" LOCALHEADERINFO to generate a header line on each page.\n"
+"\n"
+"This application sets the following channel variables upon completion:\n"
+" FAXSTATUS - status of operation:\n"
+" SUCCESS | FAILED\n"
+" FAXERROR - Error when FAILED\n"
+" REMOTESTATIONID - CSID of the remote side.\n"
+" FAXPAGES - number of pages sent.\n"
+" FAXBITRATE - transmition rate.\n"
+" FAXRESOLUTION - resolution.\n"
+"\n"
+"Returns -1 in case of user hang up or any channel error.\n"
+"Returns 0 on success.\n";
+
+#define MAX_BLOCK_SIZE 240
+
+typedef struct {
+ struct ast_channel *chan;
+ fax_state_t fax;
+ volatile int finished;
+} fax_session;
+
+static void span_message(int level, const char *msg)
+{
+ if (level == SPAN_LOG_ERROR)
+ ast_log(LOG_ERROR, msg);
+ else if (level == SPAN_LOG_WARNING)
+ ast_log(LOG_WARNING, msg);
+ else
+ ast_log(LOG_WARNING, msg);
+}
+
+static void phase_e_handler(t30_state_t *f, void *user_data, int result)
+{
+ char local_ident[T30_MAX_IDENT_LEN];
+ char far_ident[T30_MAX_IDENT_LEN];
+ char buf[20];
+ fax_session *s = (fax_session *) user_data;
+ t30_stats_t stat;
+
+ t30_get_transfer_statistics(f, &stat);
+
+ s = (fax_session *) user_data;
+
+ if (result == T30_ERR_OK) {
+ s->finished = 1;
+
+ t30_get_local_ident(f, local_ident);
+ t30_get_far_ident(f, far_ident);
+ pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "SUCCESS");
+ pbx_builtin_setvar_helper(s->chan, "FAXERROR", NULL);
+ pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", far_ident);
+ snprintf(buf, sizeof(buf), "%d", stat.pages_transferred);
+ pbx_builtin_setvar_helper(s->chan, "FAXPAGES", buf);
+ snprintf(buf, sizeof(buf), "%d", stat.y_resolution);
+ pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", buf);
+ snprintf(buf, sizeof(buf), "%d", stat.bit_rate);
+ pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", buf);
+
+ ast_debug(1, "Fax transmitted successfully.\n");
+ ast_debug(1, " Remote station ID: %s\n", far_ident);
+ ast_debug(1, " Pages transferred: %d\n", stat.pages_transferred);
+ ast_debug(1, " Image resolution: %d x %i\n", stat.x_resolution, stat.y_resolution);
+ ast_debug(1, " Transfer Rate: %d\n", stat.bit_rate);
+
+ manager_event(EVENT_FLAG_CALL,
+ f->tx_file ? "FaxSent" : "FaxReceived",
+ "Channel: %s\r\n"
+ "Exten: %s\r\n"
+ "CallerID: %s\r\n"
+ "RemoteStationID: %s\r\n"
+ "LocalStationID: %s\r\n"
+ "PagesTransferred: %d\r\n"
+ "Resolution: %d\r\n"
+ "TransferRate: %d\r\n"
+ "FileName: %s\r\n",
+ s->chan->name,
+ s->chan->exten,
+ S_OR(s->chan->cid.cid_num, ""),
+ far_ident,
+ local_ident,
+ stat.pages_transferred,
+ stat.y_resolution,
+ stat.bit_rate,
+ S_OR(f->tx_file, f->rx_file));
+ } else {
+ s->finished = -1;
+
+ /* FAXSTATUS is already set to FAILED */
+ pbx_builtin_setvar_helper(s->chan, "FAXERROR", t30_completion_code_to_str(result));
+
+ ast_log(LOG_WARNING, "Error sending fax - result (%d) %s.\n", result, t30_completion_code_to_str(result));
+ }
+}
+
+static int transmit(fax_session *s)
+{
+ int res = 0, res2;
+
+ int original_read_fmt;
+ int original_write_fmt;
+
+ const char *x;
+ int len;
+ int samples;
+
+ struct ast_frame *inf = NULL;
+ struct ast_frame outf;
+
+ uint8_t buffer[AST_FRIENDLY_OFFSET + MAX_BLOCK_SIZE * sizeof(uint16_t)];
+ int16_t *buf = (int16_t *) (buffer + AST_FRIENDLY_OFFSET);
+
+ int last_state = 0;
+ struct timeval now, start, state_change;
+
+ pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "FAILED");
+ pbx_builtin_setvar_helper(s->chan, "FAXERROR", "Channel problems");
+
+ pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", NULL);
+ pbx_builtin_setvar_helper(s->chan, "FAXPAGES", NULL);
+ pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", NULL);
+ pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", NULL);
+
+ if (s->chan->_state != AST_STATE_UP) {
+ /* Shouldn't need this, but checking to see if channel is already answered
+ * Theoretically asterisk should already have answered before running the app */
+ res = ast_answer(s->chan);
+ if (res) {
+ ast_log(LOG_WARNING, "Could not answer channel '%s'\n", s->chan->name);
+ goto done;
+ }
+ }
+
+ original_read_fmt = s->chan->readformat;
+ if (original_read_fmt != AST_FORMAT_SLINEAR) {
+ res = ast_set_read_format(s->chan, AST_FORMAT_SLINEAR);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
+ res = -1;
+ goto done;
+ }
+ }
+
+ original_write_fmt = s->chan->writeformat;
+ if (original_write_fmt != AST_FORMAT_SLINEAR) {
+ res = ast_set_write_format(s->chan, AST_FORMAT_SLINEAR);
+ if (res < 0) {
+ ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
+ res = -1;
+ goto done1;
+ }
+ }
+
+
+ x = pbx_builtin_getvar_helper(s->chan, "LOCALSTATIONID");
+ if (!ast_strlen_zero(x))
+ t30_set_local_ident(&s->fax.t30_state, x);
+
+ x = pbx_builtin_getvar_helper(s->chan, "LOCALHEADERINFO");
+ if (!ast_strlen_zero(x))
+ t30_set_header_info(&s->fax.t30_state, x);
+
+ t30_set_phase_e_handler(&s->fax.t30_state, phase_e_handler, s);
+
+ t30_set_ecm_capability(&s->fax.t30_state, TRUE);
+ t30_set_supported_compressions(&s->fax.t30_state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
+
+ start = state_change = ast_tvnow();
+ while (!s->finished) {
+
+ if (ast_waitfor(s->chan, -1) < 0) {
+ res = -1;
+ break;
+ }
+
+ inf = ast_read(s->chan);
+ if (inf == NULL)
+ break;
+
+ /* Check the frame type. Format also must be checked because there is a chance
+ that a frame in old format was already queued before we set chanel format
+ to slinear so it will still be received by ast_read */
+ if (inf->frametype == AST_FRAME_VOICE && inf->subclass == AST_FORMAT_SLINEAR) {
+
+ if (fax_rx(&s->fax, inf->data, inf->samples) < 0) {
+ /* I know fax_rx never returns errors. The check here is for good style only */
+ ast_log(LOG_WARNING, "fax_rx returned error\n");
+ res = -1;
+ break;
+ }
+
+ samples = (inf->samples <= MAX_BLOCK_SIZE) ? inf->samples : MAX_BLOCK_SIZE;
+ len = fax_tx(&s->fax, buf, samples);
+
+ if (len < 0) {
+ /* fax_tx also never returns errors. The check here is for good style only */
+ ast_log(LOG_WARNING, "fax_tx returned error\n");
+ res = -1;
+ break;
+ } else if (len) {
+ memset(&outf, 0, sizeof(outf));
+ outf.frametype = AST_FRAME_VOICE;
+ outf.subclass = AST_FORMAT_SLINEAR;
+ outf.samples = len;
+ AST_FRAME_SET_BUFFER(&outf, buffer, AST_FRIENDLY_OFFSET, len * sizeof(int16_t));
+ if (ast_write(s->chan, &outf) < 0) {
+ ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
+ res = -1;
+ break;
+ }
+ }
+
+ if (last_state != s->fax.t30_state.state) {
+ state_change = ast_tvnow();
+ last_state = s->fax.t30_state.state;
+ }
+ }
+
+ ast_frfree(inf);
+ inf = NULL;
+
+ /* Watchdog. I have seen situations when remote fax disconnects (because of poor line
+ quality) while SpanDSP continues staying in T30_STATE_IV_CTC state forever.
+ To avoid this, we terminate when we see that T30 state does not change for 5 minutes.
+ We also terminate application when more than 30 minutes passed regardless of
+ state changes. This is just a precaution measure - no fax should take that long */
+
+ now = ast_tvnow();
+ if (ast_tvdiff_ms(now, start) > 30 * 60 * 1000 || ast_tvdiff_ms(now, state_change) > 5 * 60 * 1000) {
+ ast_log(LOG_WARNING, "It looks like we hung. Aborting.\n");
+ res = -1;
+ break;
+ }
+ }
+
+ if (inf)
+ ast_frfree(inf);
+
+ if (res) {
+ ast_log(LOG_WARNING, "Transmission loop error\n");
+ res = -1;
+ } else if (s->finished < 0) {
+ ast_log(LOG_WARNING, "Transmission error\n");
+ } else if (s->finished > 0) {
+ ast_debug(1, "Transmission finished Ok\n");
+ } else if (inf == NULL) {
+ ast_debug(1, "Channel hangup\n");
+ res = -1;
+ }
+
+
+ if (original_write_fmt != AST_FORMAT_SLINEAR) {
+ res2 = ast_set_write_format(s->chan, original_write_fmt);
+ if (res2)
+ ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", s->chan->name);
+ }
+
+done1:
+ if (original_read_fmt != AST_FORMAT_SLINEAR) {
+ res2 = ast_set_read_format(s->chan, original_read_fmt);
+ if (res2)
+ ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", s->chan->name);
+ }
+
+done:
+
+ return res;
+}
+
+static int sndfax_exec(struct ast_channel *chan, void *data)
+{
+ int res = 0;
+ char *parse;
+ char *pos;
+ int calling_party;
+ int verbose;
+
+ fax_session session;
+
+ struct ast_module_user *u;
+
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(file_name);
+ AST_APP_ARG(options);
+ );
+
+ if (chan == NULL) {
+ ast_log(LOG_ERROR, "Fax channel is NULL. Giving up.\n");
+ return -1;
+ }
+
+ span_set_message_handler(span_message);
+
+ /* The next few lines of code parse out the filename and header from the input string */
+ if (ast_strlen_zero(data)) {
+ /* No data implies no filename or anything is present */
+ ast_log(LOG_ERROR, "SendFAX requires an argument (filename)\n");
+ return -1;
+ }
+
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ calling_party = TRUE;
+ verbose = 0;
+
+ if (args.options) {
+ if (strchr(args.options, 'a'))
+ calling_party = FALSE;
+
+ pos = args.options;
+ while ((pos = strchr(pos, 'd')) != NULL) {
+ verbose++;
+ pos++;
+ }
+ }
+
+ /* Done parsing */
+
+ u = ast_module_user_add(chan);
+
+ session.chan = chan;
+ session.finished = 0;
+
+ /* Initialize SpanDSP fax for transmission */
+ fax_init(&session.fax, calling_party);
+ t30_set_tx_file(&session.fax.t30_state, args.file_name, -1, -1);
+
+ if (verbose) {
+ span_log_set_level(&session.fax.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
+ if (verbose > 1)
+ span_log_set_level(&session.fax.t30_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
+ }
+
+ res = transmit(&session);
+
+ t30_terminate(&session.fax.t30_state);
+
+ ast_module_user_remove(u);
+
+ return res;
+}
+
+static int rcvfax_exec(struct ast_channel *chan, void *data)
+{
+ int res = 0;
+ char *parse;
+ char *pos;
+ int calling_party;
+ int verbose;
+
+ fax_session session;
+
+ struct ast_module_user *u;
+
+ AST_DECLARE_APP_ARGS(args,
+ AST_APP_ARG(file_name);
+ AST_APP_ARG(options);
+ );
+
+ if (chan == NULL) {
+ ast_log(LOG_ERROR, "Fax channel is NULL. Giving up.\n");
+ return -1;
+ }
+
+ span_set_message_handler(span_message);
+
+ /* The next few lines of code parse out the filename and header from the input string */
+ if (ast_strlen_zero(data)) {
+ /* No data implies no filename or anything is present */
+ ast_log(LOG_ERROR, "ReceiveFAX requires an argument (filename)\n");
+ return -1;
+ }
+
+ parse = ast_strdupa(data);
+ AST_STANDARD_APP_ARGS(args, parse);
+
+ calling_party = FALSE;
+ verbose = 0;
+
+ if (args.options) {
+ if (strchr(args.options, 'c'))
+ calling_party = TRUE;
+
+ pos = args.options;
+ while ((pos = strchr(pos, 'd')) != NULL) {
+ verbose++;
+ pos++;
+ }
+ }
+
+ /* Done parsing */
+
+ u = ast_module_user_add(chan);
+
+ session.chan = chan;
+ session.finished = 0;
+
+ /* Initialize SpanDSP fax for receiving */
+ fax_init(&session.fax, calling_party);
+ t30_set_rx_file(&session.fax.t30_state, args.file_name, -1);
+
+ if (verbose) {
+ span_log_set_level(&session.fax.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
+ if (verbose > 1)
+ span_log_set_level(&session.fax.t30_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
+ }
+
+ res = transmit(&session);
+
+ t30_terminate(&session.fax.t30_state);
+
+ ast_module_user_remove(u);
+
+ return res;
+}
+
+static int unload_module(void)
+{
+ int res;
+
+ ast_module_user_hangup_all();
+
+ res = ast_unregister_application(app_sndfax_name);
+ res |= ast_unregister_application(app_rcvfax_name);
+
+ return res;
+}
+
+static int load_module(void)
+{
+ int res ;
+
+ res = ast_register_application(app_sndfax_name, sndfax_exec, app_sndfax_synopsis, app_sndfax_desc);
+ res |= ast_register_application(app_rcvfax_name, rcvfax_exec, app_rcvfax_synopsis, app_rcvfax_desc);
+
+ return res;
+}
+
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Simple FAX Application",
+ .load = load_module,
+ .unload = unload_module,
+ );
+
+
Propchange: trunk/app_fax.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/app_fax.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: trunk/app_fax.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: trunk/build_tools/menuselect-deps.in
URL: http://svn.digium.com/view/asterisk-addons/trunk/build_tools/menuselect-deps.in?view=diff&rev=497&r1=496&r2=497
==============================================================================
--- trunk/build_tools/menuselect-deps.in (original)
+++ trunk/build_tools/menuselect-deps.in Fri Dec 14 15:56:06 2007
@@ -1,3 +1,4 @@
BLUETOOTH=@PBX_BLUETOOTH@
MYSQLCLIENT=@PBX_MYSQLCLIENT@
ASTERISK=@PBX_ASTERISK@
+SPANDSP=@PBX_SPANDSP@
Modified: trunk/configure
URL: http://svn.digium.com/view/asterisk-addons/trunk/configure?view=diff&rev=497&r1=496&r2=497
==============================================================================
--- trunk/configure (original)
+++ trunk/configure Fri Dec 14 15:56:06 2007
@@ -714,6 +714,9 @@
ASTERISK_LIB
ASTERISK_INCLUDE
PBX_ASTERISK
+SPANDSP_LIB
+SPANDSP_INCLUDE
+PBX_SPANDSP
CPP
EGREP
AST_DECLARATION_AFTER_STATEMENT
@@ -1316,6 +1319,7 @@
--with-ncurses=PATH use ncurses files in PATH
--with-mysqlclient=PATH use mysqlclient files in PATH
--with-asterisk=PATH use asterisk files in PATH
+ --with-spandsp=PATH use spandsp Library files in PATH
Some influential environment variables:
CC C compiler command
@@ -4614,6 +4618,33 @@
+SPANDSP_DESCRIP="spandsp Library"
+SPANDSP_OPTION="spandsp"
+
+# Check whether --with-spandsp was given.
+if test "${with_spandsp+set}" = set; then
+ withval=$with_spandsp;
+case ${withval} in
+ n|no)
+ USE_SPANDSP=no
+ ;;
+ y|ye|yes)
+ SPANDSP_MANDATORY="yes"
+ ;;
+ *)
+ SPANDSP_DIR="${withval}"
+ SPANDSP_MANDATORY="yes"
+ ;;
+esac
+
+fi
+
+PBX_SPANDSP=0
+
+
+
+
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -6432,6 +6463,401 @@
echo "$as_me: *** Either correct the installation" >&or run configure;}
{ echo "$as_me:$LINENO: *** without explicitly specifying --with-${NCURSES_OPTION}" >&5
echo "$as_me: *** without explicitly specifying --with-${NCURSES_OPTION}" >&6;}
+ exit 1
+ fi
+fi
+
+
+if test "${USE_SPANDSP}" != "no"; then
+ pbxlibdir=""
+ if test "x${SPANDSP_DIR}" != "x"; then
+ if test -d ${SPANDSP_DIR}/lib; then
+ pbxlibdir="-L${SPANDSP_DIR}/lib"
+ else
+ pbxlibdir="-L${SPANDSP_DIR}"
+ fi
+ fi
+ { echo "$as_me:$LINENO: checking for fax_init in -lspandsp" >&5
+echo $ECHO_N "checking for fax_init in -lspandsp... $ECHO_C" >&6; }
+if test "${ac_cv_lib_spandsp_fax_init+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lspandsp ${pbxlibdir} -ltiff $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fax_init ();
+int
+main ()
+{
+return fax_init ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_lib_spandsp_fax_init=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_spandsp_fax_init=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_spandsp_fax_init" >&5
+echo "${ECHO_T}$ac_cv_lib_spandsp_fax_init" >&6; }
+if test $ac_cv_lib_spandsp_fax_init = yes; then
+ AST_SPANDSP_FOUND=yes
+else
+ AST_SPANDSP_FOUND=no
+fi
+
+
+ if test "${AST_SPANDSP_FOUND}" = "yes"; then
+ SPANDSP_LIB="-lspandsp -ltiff"
+ SPANDSP_HEADER_FOUND="1"
+ if test "x${SPANDSP_DIR}" != "x"; then
+ SPANDSP_LIB="${pbxlibdir} ${SPANDSP_LIB}"
+ SPANDSP_INCLUDE="-I${SPANDSP_DIR}/include"
+ if test "xspandsp.h" != "x" ; then
+ as_ac_Header=`echo "ac_cv_header_${SPANDSP_DIR}/include/spandsp.h" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for ${SPANDSP_DIR}/include/spandsp.h" >&5
+echo $ECHO_N "checking for ${SPANDSP_DIR}/include/spandsp.h... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking ${SPANDSP_DIR}/include/spandsp.h usability" >&5
+echo $ECHO_N "checking ${SPANDSP_DIR}/include/spandsp.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <${SPANDSP_DIR}/include/spandsp.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking ${SPANDSP_DIR}/include/spandsp.h presence" >&5
+echo $ECHO_N "checking ${SPANDSP_DIR}/include/spandsp.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <${SPANDSP_DIR}/include/spandsp.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: ${SPANDSP_DIR}/include/spandsp.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: ${SPANDSP_DIR}/include/spandsp.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: ${SPANDSP_DIR}/include/spandsp.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: ${SPANDSP_DIR}/include/spandsp.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: ${SPANDSP_DIR}/include/spandsp.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: ${SPANDSP_DIR}/include/spandsp.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: ${SPANDSP_DIR}/include/spandsp.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: ${SPANDSP_DIR}/include/spandsp.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: ${SPANDSP_DIR}/include/spandsp.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: ${SPANDSP_DIR}/include/spandsp.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: ${SPANDSP_DIR}/include/spandsp.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: ${SPANDSP_DIR}/include/spandsp.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: ${SPANDSP_DIR}/include/spandsp.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ${SPANDSP_DIR}/include/spandsp.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: ${SPANDSP_DIR}/include/spandsp.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: ${SPANDSP_DIR}/include/spandsp.h: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for ${SPANDSP_DIR}/include/spandsp.h" >&5
+echo $ECHO_N "checking for ${SPANDSP_DIR}/include/spandsp.h... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ SPANDSP_HEADER_FOUND=1
+else
+ SPANDSP_HEADER_FOUND=0
+fi
+
+
+ fi
+ else
+ if test "xspandsp.h" != "x" ; then
+ if test "${ac_cv_header_spandsp_h+set}" = set; then
+ { echo "$as_me:$LINENO: checking for spandsp.h" >&5
+echo $ECHO_N "checking for spandsp.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_spandsp_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_spandsp_h" >&5
+echo "${ECHO_T}$ac_cv_header_spandsp_h" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking spandsp.h usability" >&5
+echo $ECHO_N "checking spandsp.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <spandsp.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking spandsp.h presence" >&5
+echo $ECHO_N "checking spandsp.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <spandsp.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: spandsp.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: spandsp.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: spandsp.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: spandsp.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: spandsp.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: spandsp.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: spandsp.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: spandsp.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: spandsp.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: spandsp.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: spandsp.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: spandsp.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: spandsp.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: spandsp.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: spandsp.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: spandsp.h: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for spandsp.h" >&5
+echo $ECHO_N "checking for spandsp.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_spandsp_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_spandsp_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_spandsp_h" >&5
+echo "${ECHO_T}$ac_cv_header_spandsp_h" >&6; }
+
+fi
+if test $ac_cv_header_spandsp_h = yes; then
+ SPANDSP_HEADER_FOUND=1
+else
+ SPANDSP_HEADER_FOUND=0
+fi
+
+
+ fi
+ fi
+ if test "x${SPANDSP_HEADER_FOUND}" = "x0" ; then
+ if test ! -z "${SPANDSP_MANDATORY}" ;
+ then
+ { echo "$as_me:$LINENO: ***" >&5
+echo "$as_me: ***" >&6;}
+ { echo "$as_me:$LINENO: *** It appears that you do not have the spandsp development package installed." >&5
+echo "$as_me: *** It appears that you do not have the spandsp development package installed." >&6;}
+ { echo "$as_me:$LINENO: *** Please install it to include ${SPANDSP_DESCRIP} support" >&5
+echo "$as_me: *** Please install it to include ${SPANDSP_DESCRIP} support" >&or re-run configure;}
+ { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SPANDSP_OPTION}" >&5
+echo "$as_me: *** without explicitly specifying --with-${SPANDSP_OPTION}" >&6;}
+ exit 1
+ fi
+ SPANDSP_LIB=""
+ SPANDSP_INCLUDE=""
+ PBX_SPANDSP=0
+ else
+ PBX_SPANDSP=1
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SPANDSP 1
+_ACEOF
+
+ fi
+ elif test ! -z "${SPANDSP_MANDATORY}";
+ then
+ { echo "$as_me:$LINENO: ***" >&5
+echo "$as_me: ***" >&6;}
+ { echo "$as_me:$LINENO: *** The ${SPANDSP_DESCRIP} installation on this system appears to be broken." >&5
+echo "$as_me: *** The ${SPANDSP_DESCRIP} installation on this system appears to be broken." >&6;}
+ { echo "$as_me:$LINENO: *** Either correct the installation" >&5
+echo "$as_me: *** Either correct the installation" >&or run configure;}
+ { echo "$as_me:$LINENO: *** without explicitly specifying --with-${SPANDSP_OPTION}" >&5
+echo "$as_me: *** without explicitly specifying --with-${SPANDSP_OPTION}" >&6;}
exit 1
fi
fi
@@ -7630,6 +8056,9 @@
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+SPANDSP_LIB!$SPANDSP_LIB$ac_delim
+SPANDSP_INCLUDE!$SPANDSP_INCLUDE$ac_delim
+PBX_SPANDSP!$PBX_SPANDSP$ac_delim
CPP!$CPP$ac_delim
EGREP!$EGREP$ac_delim
AST_DECLARATION_AFTER_STATEMENT!$AST_DECLARATION_AFTER_STATEMENT$ac_delim
@@ -7638,7 +8067,7 @@
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 6; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 9; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
Modified: trunk/configure.ac
URL: http://svn.digium.com/view/asterisk-addons/trunk/configure.ac?view=diff&rev=497&r1=496&r2=497
==============================================================================
--- trunk/configure.ac (original)
+++ trunk/configure.ac Fri Dec 14 15:56:06 2007
@@ -173,10 +173,12 @@
AST_EXT_LIB_SETUP([NCURSES], [ncurses], [ncurses])
AST_EXT_LIB_SETUP([MYSQLCLIENT], [mysqlclient], [mysqlclient])
AST_EXT_LIB_SETUP([ASTERISK], [asterisk], [asterisk])
+AST_EXT_LIB_SETUP([SPANDSP], [spandsp Library], [spandsp])
AST_EXT_LIB_CHECK([BLUETOOTH], [bluetooth], [ba2str], [bluetooth/bluetooth.h])
AST_EXT_LIB_CHECK([CURSES], [curses], [initscr], [curses.h])
AST_EXT_LIB_CHECK([NCURSES], [ncurses], [initscr], [curses.h])
+AST_EXT_LIB_CHECK([SPANDSP], [spandsp], [fax_init], [spandsp.h], [-ltiff])
AC_MSG_CHECKING(for -Wdeclaration-after-statement support)
if $(${CC} -Wdeclaration-after-statement -S -o /dev/null -xc /dev/null > /dev/null 2>&1); then
Modified: trunk/makeopts.in
URL: http://svn.digium.com/view/asterisk-addons/trunk/makeopts.in?view=diff&rev=497&r1=496&r2=497
==============================================================================
--- trunk/makeopts.in (original)
+++ trunk/makeopts.in Fri Dec 14 15:56:06 2007
@@ -49,3 +49,6 @@
NCURSES_LIB=@NCURSES_LIB@
NCURSES_INCLUDE=@NCURSES_INCLUDE@
+
+SPANDSP_INCLUDE=@SPANDSP_INCLUDE@
+SPANDSP_LIB=@SPANDSP_LIB@
Modified: trunk/menuselect-tree
URL: http://svn.digium.com/view/asterisk-addons/trunk/menuselect-tree?view=diff&rev=497&r1=496&r2=497
==============================================================================
--- trunk/menuselect-tree (original)
+++ trunk/menuselect-tree Fri Dec 14 15:56:06 2007
@@ -7,6 +7,10 @@
<depend>asterisk</depend>
</member>
<member name="app_saycountpl" remove_on_change="app_saycountpl.so app_saycountpl.so" displayname="Say Polish Counting Words">
+ <depend>asterisk</depend>
+ </member>
+ <member name="app_fax" remove_on_change="app_fax.so app_fax.o" displayname="Send and receive FAXes">
+ <depend>spandsp</depend>
<depend>asterisk</depend>
</member>
<member name="cdr_addon_mysql" remove_on_change="cdr_addon_mysql.so cdr_addon_mysql.o" displayname="MySQL CDR Backend">
More information about the asterisk-addons-commits
mailing list