[packages/asterisk/ASTERISK_12] removing obsolete files
jajcus
jajcus at pld-linux.org
Wed Jan 8 16:05:07 CET 2014
commit 26052d13ebb998d467375b8bdf677ad6193d4dda
Author: Jacek Konieczny <j.konieczny at eggsoft.pl>
Date: Wed Jan 8 12:19:41 2014 +0100
removing obsolete files
app_rxfax.c | 593 ---
app_txfax.c | 544 ---
asterisk-bristuff-build.patch | 139 -
asterisk-bristuff-libpri.patch | 22 -
asterisk-bristuff.patch | 7998 ----------------------------------------
asterisk-txfax-Makefile.patch | 26 -
asterisk-zhone.patch | 65 -
7 files changed, 9387 deletions(-)
---
diff --git a/app_rxfax.c b/app_rxfax.c
deleted file mode 100644
index 462f306..0000000
--- a/app_rxfax.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/*
- * Application to receive a TIFF FAX file
- * based on app_rxfax.c from: Copyright (C) 2003, Steve Underwood <steveu at coppice.org>
- * based on app_rxfax.c from www.callweaver.org
- * PATCHED BY (C) 20007 by Antonio Gallo <agx at linux.it>
- * - added ECM support
- * - added more env variables
- *
- */
-
-/*** MODULEINFO
-Depends: libspandsp
-Desciption: Receive a FAX to a file
-DisplayName: RxFAX
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <pthread.h>
-#include <errno.h>
-#include <tiffio.h>
-
-#include <spandsp.h>
-#include <spandsp/version.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/manager.h"
-
-#ifndef AST_MODULE
-#define AST_MODULE "app_rxfax"
-#endif
-
-static char *app = "RxFAX";
-
-static char *synopsis = "Receive a FAX to a file";
-
-static char *descrip =
- " RxFAX(filename[|caller][|debug]): Receives a FAX from the channel into the\n"
- "given filename. If the file exists it will be overwritten. The file\n"
- "should be in TIFF/F format.\n"
- "The \"caller\" option makes the application behave as a calling machine,\n"
- "rather than the answering machine. The default behaviour is to behave as\n"
- "an answering machine.\n"
- "The \"ecm\" option enables ECM.\n"
- "Uses LOCALSTATIONID to identify itself to the remote end.\n"
- " LOCALSUBADDRESS to specify a sub-address to the remote end.\n"
- " LOCALHEADERINFO to generate a header line on each page.\n"
-
- " FAX_FORCE_V17 to force V.17 only\n"
- " FAX_FORCE_V27 to force V.27 only\n"
- " FAX_FORCE_V29 to force V.29 only\n"
- " FAX_FORCE_V34 to force V.34 only\n"
-
- "Sets REMOTESTATIONID to the sender CSID.\n"
- " FAXPAGES to the number of pages received.\n"
- " FAXBITRATE to the transmition rate.\n"
- " FAXRESOLUTION to the resolution.\n"
- " PHASEESTATUS to the phase E result status.\n"
- " PHASEESTRING to the phase E result string.\n"
- "Note that PHASEESTATUS=0 means that the fax was handled correctly. But that doesn't\n"
- "imply that any pages were sent. Actually you should also check FAXPAGES to be\n"
- "greater than zero.\n"
- "Returns -1 when the user hangs up.\n"
- "Returns 0 otherwise.\n";
-
-#define MAX_BLOCK_SIZE 240
-
-static FILE *rxfax_logfile = NULL;
-
-static void file_log(const char *msg)
-{
- if (msg==NULL)
- return;
- if (rxfax_logfile==NULL)
- return;
- fprintf(rxfax_logfile, msg);
-}
-
-static void span_message(int level, const char *msg)
-{
- if (msg==NULL) return;
- int ast_level;
- if (level == SPAN_LOG_ERROR)
- ast_level = __LOG_ERROR;
- else if (level == SPAN_LOG_WARNING)
- ast_level = __LOG_WARNING;
- else
- ast_level = __LOG_DEBUG;
- ast_log(ast_level, _A_, "%s", msg);
- file_log(msg);
-}
-
-/*- End of function --------------------------------------------------------*/
-
-static int phase_b_handler(t30_state_t *s, void *user_data, int result)
-{
- if (rxfax_logfile!=NULL) {
- fprintf( rxfax_logfile, "[phase_b_handler] mark\n" );
- fflush(rxfax_logfile);
- }
- return T30_ERR_OK;
-}
-
-/*- End of function --------------------------------------------------------*/
-static void phase_e_handler(t30_state_t *s, void *user_data, int result)
-{
- struct ast_channel *chan;
- const char *tx_ident;
- const char *rx_ident;
- char buf[128];
- t30_stats_t t;
-
- chan = (struct ast_channel *) user_data;
- t30_get_transfer_statistics(s, &t);
-
- tx_ident = t30_get_tx_ident(s);
- if (tx_ident == NULL)
- tx_ident = "";
- rx_ident = t30_get_rx_ident(s);
- if (rx_ident == NULL)
- rx_ident = "";
- pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", rx_ident);
- snprintf(buf, sizeof(buf), "%d", t.pages_transferred);
- pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
- snprintf(buf, sizeof(buf), "%d", t.y_resolution);
- pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", buf);
- snprintf(buf, sizeof(buf), "%d", t.bit_rate);
- pbx_builtin_setvar_helper(chan, "FAXBITRATE", buf);
- snprintf(buf, sizeof(buf), "%d", result);
- pbx_builtin_setvar_helper(chan, "PHASEESTATUS", buf);
- snprintf(buf, sizeof(buf), "%s", t30_completion_code_to_str(result));
- pbx_builtin_setvar_helper(chan, "PHASEESTRING", buf);
-
- ast_log(LOG_DEBUG, "==============================================================================\n");
- if (result == T30_ERR_OK)
- {
- ast_log(LOG_DEBUG, "Fax successfully received.\n");
- ast_log(LOG_DEBUG, "Remote station id: %s\n", rx_ident);
- ast_log(LOG_DEBUG, "Local station id: %s\n", tx_ident);
- ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
- ast_log(LOG_DEBUG, "Image resolution: %i x %i\n", t.x_resolution, t.y_resolution);
- ast_log(LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
- manager_event(EVENT_FLAG_CALL,
- "FaxReceived", "Channel: %s\nExten: %s\nCallerID: %s\nRemoteStationID: %s\nLocalStationID: %s\nPagesTransferred: %i\nResolution: %i\nTransferRate: %i\nFileName: %s\n",
- chan->name,
- chan->exten,
- (chan->cid.cid_num) ? chan->cid.cid_num : "",
- rx_ident,
- tx_ident,
- t.pages_transferred,
- t.y_resolution,
- t.bit_rate,
- s->rx_file);
- if (rxfax_logfile!=NULL) {
- fprintf( rxfax_logfile, "\n[FAX OK] Remote: %s Local: %s Pages: %i Speed: %i\n\n",
- rx_ident, tx_ident, t.pages_transferred, t.bit_rate
- );
- fflush(rxfax_logfile);
- }
- }
- else
- {
- ast_log(LOG_DEBUG, "Fax receive not successful - result (%d) %s.\n", result, t30_completion_code_to_str(result));
- if (rxfax_logfile!=NULL) {
- fprintf( rxfax_logfile, "\n[FAX ERROR] code: %d %s\n\n", result, t30_completion_code_to_str(result) );
- fflush(rxfax_logfile);
- }
- }
- ast_log(LOG_DEBUG, "==============================================================================\n");
-}
-/*- End of function --------------------------------------------------------*/
-
-static int phase_d_handler(t30_state_t *s, void *user_data, int result)
-{
- struct ast_channel *chan;
- t30_stats_t t;
-
- chan = (struct ast_channel *) user_data;
- if (result)
- {
- t30_get_transfer_statistics(s, &t);
- ast_log(LOG_DEBUG, "==============================================================================\n");
- ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
- ast_log(LOG_DEBUG, "Image size: %i x %i\n", t.width, t.length);
- ast_log(LOG_DEBUG, "Image resolution %i x %i\n", t.x_resolution, t.y_resolution);
- ast_log(LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
- ast_log(LOG_DEBUG, "Bad rows %i\n", t.bad_rows);
- ast_log(LOG_DEBUG, "Longest bad row run %i\n", t.longest_bad_row_run);
- ast_log(LOG_DEBUG, "Compression type %s\n", t4_encoding_to_str(t.encoding));
- ast_log(LOG_DEBUG, "Image size (bytes) %i\n", t.image_size);
- ast_log(LOG_DEBUG, "==============================================================================\n");
- if (rxfax_logfile!=NULL) {
- fprintf( rxfax_logfile, "\n[phase_d_handler] Page: %i at %i\n\n", t.pages_transferred, t.bit_rate );
- fflush(rxfax_logfile);
- }
- }
- return T30_ERR_OK;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int rxfax_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- char target_file[256];
- char template_file[256];
- int samples;
- char *s;
- char *t;
- char *v;
- const char *x;
- int option;
- int len;
- int i;
- fax_state_t fax;
- struct ast_frame *inf = NULL;
- struct ast_frame outf;
- int calling_party;
- int verbose;
- int ecm = FALSE;
-
- struct ast_module_user *u;
-
- int original_read_fmt;
- int original_write_fmt;
-
-
- /* Basic initial checkings */
-
- if (chan == NULL) {
- ast_log(LOG_WARNING, "Fax receive channel is NULL. Giving up.\n");
- file_log("FATAL ERROR: Fax receive channel is NULL. Giving up.\n");
- return -1;
- }
-
- //span_set_message_handler(span_message);
- /* make sure they are initialized to zero */
- memset( &fax, 0, sizeof(fax));
-
- /* Resetting channel variables related to T38 */
- pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", "");
- pbx_builtin_setvar_helper(chan, "FAXPAGES", "");
- pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", "");
- pbx_builtin_setvar_helper(chan, "FAXBITRATE", "");
- pbx_builtin_setvar_helper(chan, "PHASEESTATUS", "");
- pbx_builtin_setvar_helper(chan, "PHASEESTRING", "");
-
- /* Parsig parameters */
-
- /* The next few lines of code parse out the filename and header from the input string */
- if (data == NULL)
- {
- /* No data implies no filename or anything is present */
- ast_log(LOG_WARNING, "Rxfax requires an argument (filename)\n");
- file_log("ERROR: Rxfax requires an argument (filename)\n");
- return -1;
- }
-
- calling_party = FALSE;
- verbose = FALSE;
- target_file[0] = '\0';
-
- char tbuf[256];
- for (option = 0, v = s = data; v; option++, s++) {
- t = s;
- v = strchr(s, '|');
- s = (v) ? v : s + strlen(s);
- strncpy((char *) tbuf, t, s - t);
- tbuf[s - t] = '\0';
- if (option == 0) {
- /* The first option is always the file name */
- len = s - t;
- if (len > 255)
- len = 255;
- strncpy(target_file, t, len);
- target_file[len] = '\0';
- /* Allow the use of %d in the file name for a wild card of sorts, to
- create a new file with the specified name scheme */
- if ((x = strchr(target_file, '%')) && x[1] == 'd') {
- strcpy(template_file, target_file);
- i = 0;
- do {
- snprintf(target_file, 256, template_file, 1);
- i++;
- } while (ast_fileexists(target_file, "", chan->language) != -1);
- }
- } else if (strncmp("caller", t, s - t) == 0) {
- calling_party = TRUE;
- } else if (strncmp("debug", t, s - t) == 0) {
- verbose = TRUE;
- } else if (strncmp("ecm", t, s - t) == 0) {
- ecm = TRUE;
- }
- }
-
- /* Done parsing */
-
- u = ast_module_user_add(chan);
-
- if (chan->_state != AST_STATE_UP)
- {
- /* Shouldn't need this, but checking to see if channel is already answered
- * Theoretically the PBX should already have answered before running the app */
- res = ast_answer(chan);
- /* NO NEED TO WARN ANYMORE
- if (!res)
- {
- ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
- file_log("Could not answer channel\n" );
- }
- */
- }
-
- /* Setting read and write formats */
-
- original_read_fmt = chan->readformat;
- if (original_read_fmt != AST_FORMAT_SLINEAR)
- {
- res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0)
- {
- ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
- file_log("ERROR: Unable to set to linear read mode, giving up\n");
- ast_module_user_remove(u);
- return -1;
- }
- }
-
- original_write_fmt = chan->writeformat;
- if (original_write_fmt != AST_FORMAT_SLINEAR)
- {
- res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0)
- {
- ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
- file_log("ERROR: Unable to set to linear write mode, giving up\n");
- res = ast_set_read_format(chan, original_read_fmt);
- if (res)
- ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
- ast_module_user_remove(u);
- return -1;
- }
- }
-
- /* Remove any app level gain adjustments and disable echo cancel. */
- signed char sc;
- sc = 0;
- ast_channel_setoption(chan, AST_OPTION_RXGAIN, &sc, sizeof(sc), 0);
- ast_channel_setoption(chan, AST_OPTION_TXGAIN, &sc, sizeof(sc), 0);
- ast_channel_setoption(chan, AST_OPTION_ECHOCAN, &sc, sizeof(sc), 0);
-
- /* This is the main loop */
-
- uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE + 2*AST_FRIENDLY_OFFSET];
- uint8_t *buf = __buf + AST_FRIENDLY_OFFSET;
-
- memset(&fax, 0, sizeof(fax));
-
- if (fax_init(&fax, calling_party) == NULL)
- {
- ast_log(LOG_WARNING, "Unable to set to start fax_init\n");
- file_log("ERROR: Unable to set to start fax_init\n");
- ast_module_user_remove(u);
- return -1;
- }
- fax_set_transmit_on_idle(&fax, TRUE);
- span_log_set_message_handler(&fax.logging, span_message);
- span_log_set_message_handler(&fax.t30_state.logging, span_message);
- if (verbose)
- {
- span_log_set_level(&fax.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- span_log_set_level(&fax.t30_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- }
- x = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
- if (x && x[0])
- t30_set_tx_ident(&fax.t30_state, x);
- x = pbx_builtin_getvar_helper(chan, "LOCALSUBADDRESS");
- if (x && x[0])
- t30_set_tx_sub_address(&fax.t30_state, x);
- x = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO");
- if (x && x[0])
- t30_set_tx_page_header_info(&fax.t30_state, x);
- t30_set_rx_file(&fax.t30_state, target_file, -1);
- t30_set_phase_b_handler(&fax.t30_state, phase_b_handler, chan);
- t30_set_phase_d_handler(&fax.t30_state, phase_d_handler, chan);
- t30_set_phase_e_handler(&fax.t30_state, phase_e_handler, chan);
-
- // Default Support ALL
- t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V29 | T30_SUPPORT_V27TER | T30_SUPPORT_V17 );
-
- x = pbx_builtin_getvar_helper(chan, "FAX_DISABLE_V17");
- if (x && x[0])
- t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
-
- x = pbx_builtin_getvar_helper(chan, "FAX_FORCE_V17");
- if (x && x[0])
- t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V17);
- x = pbx_builtin_getvar_helper(chan, "FAX_FORCE_V27");
- if (x && x[0])
- t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V27TER);
- x = pbx_builtin_getvar_helper(chan, "FAX_FORCE_V29");
- if (x && x[0])
- t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V29);
- x = pbx_builtin_getvar_helper(chan, "FAX_FORCE_V34");
- if (x && x[0])
- t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V34);
-
- /* Support for different image sizes && resolutions*/
- t30_set_supported_image_sizes(&fax.t30_state, T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH
- | T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH | T30_SUPPORT_303MM_WIDTH);
- t30_set_supported_resolutions(&fax.t30_state, T30_SUPPORT_STANDARD_RESOLUTION | T30_SUPPORT_FINE_RESOLUTION | T30_SUPPORT_SUPERFINE_RESOLUTION
- | T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
- if (ecm) {
- t30_set_ecm_capability(&(fax.t30_state), TRUE);
- t30_set_supported_compressions(&(fax.t30_state), T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
- ast_log(LOG_DEBUG, "Enabling ECM mode for app_rxfax\n" );
- file_log("DEBUG: Enabling ECM mode for app_rxfax\n" );
- } else {
- t30_set_ecm_capability(&(fax.t30_state), FALSE);
- t30_set_supported_compressions(&(fax.t30_state), T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION );
- }
-
-
- /* This is the main loop */
-
- res = 0;
-
- /* temporary workwaround vars */
- int donotspam=10;
- int watchdog=256;
-
- while ( chan )
- {
- if (ast_check_hangup(chan)) {
- ast_log(LOG_WARNING, "Channel has been hanged at fax.\n");
- file_log("INFO: Channel has been hanged at fax.\n");
- res = 0;
- break;
- }
-
- if ((res = ast_waitfor(chan, 20)) < 0) {
- ast_log(LOG_WARNING, "Channel ast_waitfor < 0.\n");
- file_log("WARNING: Channel ast_waitfor < 0.\n");
- res = 0;
- break;
- }
-
- if ((fax.current_rx_type == T30_MODEM_DONE) || (fax.current_tx_type == T30_MODEM_DONE)) {
- /* Avoid spamming debug info */
- if (donotspam>0) {
- ast_log(LOG_WARNING, "Channel T30 DONE < 0.\n");
- file_log("DEBUG: Channel T30 DONE.\n");
- donotspam--;
- }
- /*
- * NOTE: if i break here it seems to have bad behavios on some faxes that
- * will not result as successfull send even if it has benn fully received
- */
-/*JUST WARNING: res = 0;
- break;*/
- /*
- * Workaround: let 256 more packet to pass thru then definitively hangup
- */
- if (watchdog>0) {
- watchdog--;
- } else {
- break;
- }
- }
-
- inf = ast_read(chan);
- if (inf == NULL)
- {
- ast_log(LOG_WARNING, "Channel INF is NULL.\n");
- file_log("DEBUG: Channel INF is NULL.\n");
-
- // While trasmiitting i got: Received a DCN from remote after sending a page
- // at last page
- continue;
- //res = 0;
- //break;
- }
-
- /* We got a frame */
- //if (inf->frametype == AST_FRAME_VOICE) {
- /* 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(&fax, inf->data, inf->samples)) {
- ast_log(LOG_WARNING, "RXFAX: fax_rx returned error\n");
- res = -1;
- break;
- }
-
- samples = (inf->samples <= MAX_BLOCK_SIZE) ? inf->samples : MAX_BLOCK_SIZE;
- len = fax_tx(&fax, (int16_t *) &buf[AST_FRIENDLY_OFFSET], samples);
- if (len>0) {
- /*if (len <= 0) {
- ast_log(LOG_WARNING, "len <=0 using samples.\n");
- file_log("len <= 0 using samples.\n");
- len = samples;
- }*/
- memset(&outf, 0, sizeof(outf));
- outf.frametype = AST_FRAME_VOICE;
- outf.subclass = AST_FORMAT_SLINEAR;
- outf.datalen = len*sizeof(int16_t);
- outf.samples = len;
- outf.data = &buf[AST_FRIENDLY_OFFSET];
- outf.offset = AST_FRIENDLY_OFFSET;
- outf.src = "RxFAX";
- /*if (len <= 0) {
- memset(&buf[AST_FRIENDLY_OFFSET], 0, outf.datalen);
- }*/
- if (ast_write(chan, &outf) < 0)
- {
- ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
- file_log("ERROR: Unable to write frame to channel\n");
- res = -1;
- break;
- }
- }
- }
- ast_frfree(inf);
- inf = NULL;
- /* TODO put a Watchdog here */
- }
-
- if (inf != NULL)
- {
- ast_frfree(inf);
- inf = NULL;
- }
-
- t30_terminate(&fax.t30_state);
- fax_release(&fax);
-
- /* Restoring initial channel formats. */
-
- if (original_read_fmt != AST_FORMAT_SLINEAR)
- {
- res = ast_set_read_format(chan, original_read_fmt);
- if (res)
- ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
- }
- if (original_write_fmt != AST_FORMAT_SLINEAR)
- {
- res = ast_set_write_format(chan, original_write_fmt);
- if (res)
- ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", chan->name);
- }
- ast_module_user_remove(u);
- return res;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int unload_module(void)
-{
- int res;
- ast_module_user_hangup_all();
- res = ast_unregister_application(app);
- if (rxfax_logfile) {
- fclose(rxfax_logfile);
- rxfax_logfile = NULL;
- }
- return res;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int load_module(void)
-{
- ast_log(LOG_NOTICE, "RxFax using spandsp %i %i\n", SPANDSP_RELEASE_DATE, SPANDSP_RELEASE_TIME );
- rxfax_logfile = fopen("/var/log/rxfax.log", "w+" );
- if (rxfax_logfile)
- ast_log(LOG_WARNING, "RxFax output also available in /var/log/rxfax.log\n" );
- return ast_register_application(app, rxfax_exec, synopsis, descrip);
-}
-/*- End of function --------------------------------------------------------*/
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Trivial FAX Receive Application");
-
-/*- End of file ------------------------------------------------------------*/
diff --git a/app_txfax.c b/app_txfax.c
deleted file mode 100644
index 25c69f4..0000000
--- a/app_txfax.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Application to send a TIFF file as a FAX
- * based on app_txfax.c from: Copyright (C) 2003, Steve Underwood <steveu at coppice.org>
- * PATCHED BY (C) 20007 by Antonio Gallo <agx at linux.it>
- * - added ECM support
- * - added more env variables
- * - added logging to external file
- */
-
-/*** MODULEINFO
-Depends: libspandsp
-Desciption: Send a FAX file
-DisplayName: TxFAX
- ***/
-
-#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 <spandsp/version.h>
-
-#include "asterisk/lock.h"
-#include "asterisk/file.h"
-#include "asterisk/logger.h"
-#include "asterisk/channel.h"
-#include "asterisk/pbx.h"
-#include "asterisk/module.h"
-#include "asterisk/manager.h"
-
-#ifndef AST_MODULE
-#define AST_MODULE "app_txfax"
-#endif
-
-static char *app = "TxFAX";
-
-static char *synopsis = "Send a FAX file";
-
-static char *descrip =
- " TxFAX(filename[|caller][|debug][|ecm]): Send a given TIFF file to the channel as a FAX.\n"
- "The \"caller\" option makes the application behave as a calling machine,\n"
- "rather than the answering machine. The default behaviour is to behave as\n"
- "an answering machine.\n"
- "The \"ecm\" option enables ECM.\n"
- "Uses LOCALSTATIONID to identify itself to the remote end.\n"
- " LOCALHEADERINFO to generate a header line on each page.\n"
- "Sets REMOTESTATIONID to the receiver CSID.\n"
- " FAXPAGES to the number of pages sent.\n"
- " FAXBITRATE to the transmition rate.\n"
- " FAXRESOLUTION to the resolution.\n"
- " PHASEESTATUS to the phase E result status.\n"
- " PHASEESTRING to the phase E result string.\n"
- "Returns -1 when the user hangs up, or if the file does not exist.\n"
- "Returns 0 otherwise.\n";
-
-#define MAX_BLOCK_SIZE 240
-
-static FILE *txfax_logfile = NULL;
-
-static void file_log(const char *msg)
-{
- if (msg==NULL)
- return;
- if (txfax_logfile==NULL)
- return;
- fprintf(txfax_logfile, msg);
-}
-
-static void span_message(int level, const char *msg)
-{
- if (msg==NULL) return;
- int ast_level;
- if (level == SPAN_LOG_ERROR)
- ast_level = __LOG_ERROR;
- else if (level == SPAN_LOG_WARNING)
- ast_level = __LOG_WARNING;
- else
- ast_level = __LOG_DEBUG;
- ast_log(ast_level, _A_, "%s", msg);
- file_log(msg);
-}
-/*- End of function --------------------------------------------------------*/
-
-typedef struct {
- struct ast_channel *chan;
- fax_state_t fax;
- volatile int finished;
-} fax_session;
-
-static void phase_b_handler(t30_state_t *s, void *user_data, int result)
-{
- if (txfax_logfile!=NULL) {
- fprintf( txfax_logfile, "[phase_b_handler] mark\n" );
- fflush(txfax_logfile);
- }
-}
-
-static void phase_e_handler(t30_state_t *s, void *user_data, int result)
-{
- struct ast_channel *chan;
- char local_ident[21];
- char far_ident[21];
- char buf[128];
- t30_stats_t t;
-
- fax_session *fax = (fax_session *) user_data;
- chan = fax->chan;
- t30_get_transfer_statistics(s, &t);
-
- t30_get_local_ident(s, local_ident);
- t30_get_far_ident(s, far_ident);
- pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", far_ident);
- snprintf(buf, sizeof(buf), "%d", t.pages_transferred);
- pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
- snprintf(buf, sizeof(buf), "%d", t.y_resolution);
- pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", buf);
- snprintf(buf, sizeof(buf), "%d", t.bit_rate);
- pbx_builtin_setvar_helper(chan, "FAXBITRATE", buf);
- snprintf(buf, sizeof(buf), "%d", result);
- pbx_builtin_setvar_helper(chan, "PHASEESTATUS", buf);
- snprintf(buf, sizeof(buf), "%s", t30_completion_code_to_str(result));
- pbx_builtin_setvar_helper(chan, "PHASEESTRING", buf);
-
- // This is to tell asterisk later that the fax has finished (with or without error)
- fax->finished = 1;
-
- ast_log(LOG_DEBUG, "==============================================================================\n");
- if (result == T30_ERR_OK)
- {
- ast_log(LOG_DEBUG, "Fax successfully sent.\n");
- ast_log(LOG_DEBUG, "Remote station id: %s\n", far_ident);
- ast_log(LOG_DEBUG, "Local station id: %s\n", local_ident);
- ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
- ast_log(LOG_DEBUG, "Image resolution: %i x %i\n", t.x_resolution, t.y_resolution);
- ast_log(LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
- manager_event(EVENT_FLAG_CALL,
- "FaxSent", "Channel: %s\nExten: %s\nCallerID: %s\nRemoteStationID: %s\nLocalStationID: %s\nPagesTransferred: %i\nResolution: %i\nTransferRate: %i\nFileName: %s\n",
- chan->name,
- chan->exten,
- (chan->cid.cid_num) ? chan->cid.cid_num : "",
- far_ident,
- local_ident,
- t.pages_transferred,
- t.y_resolution,
- t.bit_rate,
- s->rx_file);
- if (txfax_logfile!=NULL) {
- fprintf( txfax_logfile, "\n[FAX OK] Remote: %s Local: %s Pages: %i Speed: %i\n\n",
- far_ident, local_ident, t.pages_transferred, t.bit_rate
- );
- fflush(txfax_logfile);
- }
- }
- else
- {
- ast_log(LOG_DEBUG, "Fax send not successful - result (%d) %s.\n", result, t30_completion_code_to_str(result));
- if (txfax_logfile!=NULL) {
- fprintf( txfax_logfile, "\n[FAX ERROR] code: %d %s\n\n", result, t30_completion_code_to_str(result) );
- fflush(txfax_logfile);
- }
- }
- ast_log(LOG_DEBUG, "==============================================================================\n");
-}
-/*- End of function --------------------------------------------------------*/
-
-static void phase_d_handler(t30_state_t *s, void *user_data, int result)
-{
-// struct ast_channel *chan;
- t30_stats_t t;
-
-// chan = (struct ast_channel *) user_data;
- if (result)
- {
- t30_get_transfer_statistics(s, &t);
- ast_log(LOG_DEBUG, "[ TXFAX ]=====================================================================\n");
- ast_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_transferred);
- ast_log(LOG_DEBUG, "Image size: %i x %i\n", t.width, t.length);
- ast_log(LOG_DEBUG, "Image resolution %i x %i\n", t.x_resolution, t.y_resolution);
- ast_log(LOG_DEBUG, "Transfer Rate: %i\n", t.bit_rate);
- ast_log(LOG_DEBUG, "Bad rows %i\n", t.bad_rows);
- ast_log(LOG_DEBUG, "Longest bad row run %i\n", t.longest_bad_row_run);
- ast_log(LOG_DEBUG, "Compression type %s\n", t4_encoding_to_str(t.encoding));
- ast_log(LOG_DEBUG, "Image size (bytes) %i\n", t.image_size);
- ast_log(LOG_DEBUG, "==============================================================================\n");
- if (txfax_logfile!=NULL) {
- fprintf( txfax_logfile, "\n[phase_d_handler] Page: %i at %i\n\n", t.pages_transferred, t.bit_rate );
- fflush(txfax_logfile);
- }
- }
-}
-/*- End of function --------------------------------------------------------*/
-
-static int txfax_exec(struct ast_channel *chan, void *data)
-{
- int res = 0;
- char source_file[256];
- int samples;
- char *s;
- char *t;
- char *v;
- const char *x;
- int option;
- int len;
- fax_state_t fax;
- struct ast_frame *inf = NULL;
- struct ast_frame outf;
- int calling_party;
- int verbose;
- int ecm = FALSE;
-
- struct ast_module_user *u;
-
- int original_read_fmt;
- int original_write_fmt;
-
- fax_session session;
- session.chan = chan;
- session.finished = 0;
-
- /* Basic initial checkings */
-
- if (chan == NULL) {
- ast_log(LOG_WARNING, "Fax transmit channel is NULL. Giving up.\n");
- file_log("ERROR: Fax receive channel is NULL. Giving up.\n");
- return -1;
- }
-
- span_set_message_handler(span_message);
- /* make sure they are initialized to zero */
- memset( &fax, 0, sizeof(fax));
-
- /* Resetting channel variables related to T38 */
- pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", "");
- pbx_builtin_setvar_helper(chan, "FAXPAGES", "");
- pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", "");
- pbx_builtin_setvar_helper(chan, "FAXBITRATE", "");
- pbx_builtin_setvar_helper(chan, "PHASEESTATUS", "");
- pbx_builtin_setvar_helper(chan, "PHASEESTRING", "");
-
- /* Parsig parameters */
-
- /* The next few lines of code parse out the filename and header from the input string */
- if (data == NULL)
- {
- /* No data implies no filename or anything is present */
- ast_log(LOG_WARNING, "Txfax requires an argument (filename)\n");
- file_log("ERROR: Txfax requires an argument (filename)\n");
- return -1;
- }
-
- calling_party = FALSE;
- verbose = FALSE;
- source_file[0] = '\0';
-
- char tbuf[256];
- for (option = 0, v = s = data; v; option++, s++) {
- t = s;
- v = strchr(s, '|');
- s = (v) ? v : s + strlen(s);
- strncpy((char *) tbuf, t, s - t);
- tbuf[s - t] = '\0';
- if (option == 0) {
- /* The first option is always the file name */
- len = s - t;
- if (len > 255)
- len = 255;
- strncpy(source_file, t, len);
- source_file[len] = '\0';
- } else if (strncmp("caller", t, s - t) == 0) {
- calling_party = TRUE;
- } else if (strncmp("debug", t, s - t) == 0) {
- verbose = TRUE;
- } else if (strncmp("ecm", t, s - t) == 0) {
- ecm = TRUE;
- }
- }
-
- /* Done parsing */
-
- u = ast_module_user_add(chan);
-
- if (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(chan);
- /* NO NEED TO WARN ANYMORE
- if (!res)
- {
- ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name);
- file_log("Could not answer channel\n" );
- }
- */
- }
-
- /* Setting read and write formats */
-
- original_read_fmt = chan->readformat;
- if (original_read_fmt != AST_FORMAT_SLINEAR)
- {
- res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0)
- {
- ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
- file_log("ERROR: Unable to set to linear read mode, giving up\n");
- ast_module_user_remove(u);
- return -1;
- }
- }
-
- original_write_fmt = chan->writeformat;
- if (original_write_fmt != AST_FORMAT_SLINEAR)
- {
- res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
- if (res < 0)
- {
- ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
- file_log("Unable to set to linear write mode, giving up\n");
- res = ast_set_read_format(chan, original_read_fmt);
- if (res)
- ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
- ast_module_user_remove(u);
- return -1;
- }
- }
-
- /* Remove any app level gain adjustments and disable echo cancel. */
- signed char sc;
- sc = 0;
- ast_channel_setoption(chan, AST_OPTION_RXGAIN, &sc, sizeof(sc), 0);
- ast_channel_setoption(chan, AST_OPTION_TXGAIN, &sc, sizeof(sc), 0);
- ast_channel_setoption(chan, AST_OPTION_ECHOCAN, &sc, sizeof(sc), 0);
-
- /* This is the main loop */
-
- uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE + 2*AST_FRIENDLY_OFFSET];
- uint8_t *buf = __buf + AST_FRIENDLY_OFFSET;
-
- memset(&fax, 0, sizeof(fax));
-
- if (fax_init(&fax, calling_party) == NULL)
- {
- ast_log(LOG_WARNING, "Unable to start FAX\n");
- file_log("Unable to set to start fax_init\n");
- ast_module_user_remove(u);
- return -1;
- }
- fax_set_transmit_on_idle(&fax, TRUE);
- span_log_set_message_handler(&fax.logging, span_message);
- span_log_set_message_handler(&fax.t30_state.logging, span_message);
- if (verbose)
- {
- span_log_set_level(&fax.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- span_log_set_level(&fax.t30_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
- }
- x = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID");
- if (x && x[0])
- t30_set_local_ident(&fax.t30_state, x);
- x = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO");
- if (x && x[0])
- t30_set_header_info(&fax.t30_state, x);
- t30_set_tx_file(&fax.t30_state, source_file, -1, -1);
- t30_set_phase_b_handler(&fax.t30_state, phase_b_handler, chan);
- t30_set_phase_d_handler(&fax.t30_state, phase_d_handler, chan);
- t30_set_phase_e_handler(&fax.t30_state, phase_e_handler, &session);
-
- x = pbx_builtin_getvar_helper(chan, "FAX_DISABLE_V17");
- if (x && x[0])
- t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V29 | T30_SUPPORT_V27TER);
- else
- t30_set_supported_modems(&(fax.t30_state), T30_SUPPORT_V29 | T30_SUPPORT_V27TER | T30_SUPPORT_V17 );
-
- /* Support for different image sizes && resolutions*/
- t30_set_supported_image_sizes(&fax.t30_state, T30_SUPPORT_US_LETTER_LENGTH | T30_SUPPORT_US_LEGAL_LENGTH | T30_SUPPORT_UNLIMITED_LENGTH
- | T30_SUPPORT_215MM_WIDTH | T30_SUPPORT_255MM_WIDTH | T30_SUPPORT_303MM_WIDTH);
- t30_set_supported_resolutions(&fax.t30_state, T30_SUPPORT_STANDARD_RESOLUTION | T30_SUPPORT_FINE_RESOLUTION | T30_SUPPORT_SUPERFINE_RESOLUTION
- | T30_SUPPORT_R8_RESOLUTION | T30_SUPPORT_R16_RESOLUTION);
- if (ecm) {
- t30_set_ecm_capability(&(fax.t30_state), TRUE);
- t30_set_supported_compressions(&(fax.t30_state), T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
- ast_log(LOG_DEBUG, "Enabling ECM mode for app_txfax\n" );
- file_log("Enabling ECM mode for app_rxfax\n" );
- }
-
-
- /* This is the main loop */
-
- res = 0;
- while ( (!session.finished) && chan )
- {
- if (ast_check_hangup(chan)) {
- ast_log(LOG_WARNING, "TXFAX: Channel has been hanged at fax.\n");
- file_log("INFO: Channel has been hanged at fax.\n");
- res = 0;
- break;
- }
-
- if ((res = ast_waitfor(chan, 20)) < 0) {
- ast_log(LOG_WARNING, "TXFAX: ast_waitfor returned less then 0.\n");
- file_log("WARNING: Channel ast_waitfor < 0.\n");
- res = 0;
- break;
- }
-
- /*if ((fax.current_rx_type == T30_MODEM_DONE) || (fax.current_tx_type == T30_MODEM_DONE)) {
- ast_log(LOG_WARNING, "Channel T30 DONE < 0.\n");
- file_log("Channel T30 DONE.\n");
- res = 0;
- break;
- }*/
-
- inf = ast_read(chan);
- if (inf == NULL)
- {
- //ast_log(LOG_WARNING, "TXFAX: transmission done with ast_read(chan) == NULL\n");
- ast_log(LOG_WARNING, "Channel INF is NULL.\n");
- file_log("DEBUG: Channel INF is NULL.\n");
-
- // While trasmiitting i got: Received a DCN from remote after sending a page
- // at last page
- continue;
-#ifdef AGX_DEBUGGING
- res = 0;
- break;
-#endif
- }
-
- /* We got a frame */
- //if (inf->frametype == AST_FRAME_VOICE) {
- /* 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(&fax, inf->data, inf->samples)) {
- ast_log(LOG_WARNING, "TXFAX: fax_rx returned error\n");
- res = -1;
- break;
- }
-
- samples = (inf->samples <= MAX_BLOCK_SIZE) ? inf->samples : MAX_BLOCK_SIZE;
- len = fax_tx(&fax, (int16_t *) &buf[AST_FRIENDLY_OFFSET], samples);
- if (len>0) {
- /*if (len <= 0) {
- ast_log(LOG_WARNING, "len <=0 using samples.\n");
- file_log("len <= 0 using samples.\n");
- len = samples;
- }*/
- memset(&outf, 0, sizeof(outf));
- outf.frametype = AST_FRAME_VOICE;
- outf.subclass = AST_FORMAT_SLINEAR;
- outf.datalen = len*sizeof(int16_t);
- outf.samples = len;
- outf.data = &buf[AST_FRIENDLY_OFFSET];
- outf.offset = AST_FRIENDLY_OFFSET;
- outf.src = "TxFAX";
- /*if (len <= 0) {
- memset(&buf[AST_FRIENDLY_OFFSET], 0, outf.datalen);
- }*/
- if (ast_write(chan, &outf) < 0)
- {
- ast_log(LOG_WARNING, "TXFAX: Unable to write frame to channel; %s\n", strerror(errno));
- file_log("FATAL ERROR: Unable to write frame to channel\n");
- res = -1;
- break;
- }
- }
- }
- ast_frfree(inf);
- inf = NULL;
- /* TODO put a Watchdog here */
- }
-
- if (inf != NULL)
- {
- ast_frfree(inf);
- inf = NULL;
- }
-
- t30_terminate(&fax.t30_state);
- fax_release(&fax);
- if (session.finished > 0) {
- ast_log(LOG_WARNING, "Fax Transmission complete, check return code\n");
- res = 0;
- } else {
- ast_log(LOG_WARNING, "Fax Transmission INCOMPLETE, check error code\n");
- res = -1;
- }
- if (res!=0) {
- ast_log(LOG_WARNING, "Transmission RES error\n");
- }
-
- /* Restoring initial channel formats. */
-
- if (original_read_fmt != AST_FORMAT_SLINEAR)
- {
- res = ast_set_read_format(chan, original_read_fmt);
- if (res)
- ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
- }
- if (original_write_fmt != AST_FORMAT_SLINEAR)
- {
- res = ast_set_write_format(chan, original_write_fmt);
- if (res)
- ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", chan->name);
- }
- ast_module_user_remove(u);
- return res;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int unload_module(void)
-{
- int res;
- ast_module_user_hangup_all();
- res = ast_unregister_application(app);
- if (txfax_logfile) {
- fclose(txfax_logfile);
- txfax_logfile = NULL;
- }
- return res;
-}
-/*- End of function --------------------------------------------------------*/
-
-static int load_module(void)
-{
- ast_log(LOG_NOTICE, "TxFax using spandsp %i %i\n", SPANDSP_RELEASE_DATE, SPANDSP_RELEASE_TIME );
- txfax_logfile = fopen("/var/log/txfax.log", "w+" );
- if (txfax_logfile)
- ast_log(LOG_WARNING, "TxFax output also available in /var/log/txfax.log\n" );
- return ast_register_application(app, txfax_exec, synopsis, descrip);
-}
-/*- End of function --------------------------------------------------------*/
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Trivial FAX Transmit Application");
-
-/*- End of file ------------------------------------------------------------*/
diff --git a/asterisk-bristuff-build.patch b/asterisk-bristuff-build.patch
deleted file mode 100644
index 028fffa..0000000
--- a/asterisk-bristuff-build.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-diff -ur -x '*.c' -x '*.orig' -x configure asterisk-1.4.21.1.new/build_tools/menuselect-deps.in asterisk-1.4.21.1.old/build_tools/menuselect-deps.in
---- asterisk-1.4.21.1.new/build_tools/menuselect-deps.in 2008-05-06 00:10:05.000000000 +0200
-+++ asterisk-1.4.21.1.old/build_tools/menuselect-deps.in 2008-07-18 08:18:42.813626657 +0200
-@@ -2,6 +2,7 @@
- CURL=@PBX_CURL@
- FREETDS=@PBX_FREETDS@
- GSM=@PBX_GSM@
-+GSMAT=@PBX_GSMAT@
- GTK=@PBX_GTK@
- GTK2=@PBX_GTK2@
- H323=@PBX_H323@
-diff -ur asterisk-1.4.21.1.org/channels/chan_zap.c asterisk-1.4.21.1/channels/chan_zap.c
---- asterisk-1.4.21.1/channels/chan_zap.c~ 2008-07-18 21:56:54.854339111 +0200
-+++ asterisk-1.4.21.1/channels/chan_zap.c 2008-07-18 22:02:00.487649563 +0200
-@@ -47,6 +47,7 @@
- <depend>zaptel</depend>
- <depend>tonezone</depend>
- <depend>res_features</depend>
-+ <depend>gsmat</depend>
- <use>pri</use>
- ***/
-
-diff -ur -x '*.c' -x '*.orig' -x configure asterisk-1.4.21.1.new/channels/.chan_zap.moduleinfo asterisk-1.4.21.1.old/channels/.chan_zap.moduleinfo
---- asterisk-1.4.21.1.new/channels/.chan_zap.moduleinfo 2008-06-30 18:24:08.000000000 +0200
-+++ asterisk-1.4.21.1.old/channels/.chan_zap.moduleinfo 2008-07-18 08:18:42.808831904 +0200
-@@ -4,5 +4,6 @@
- <depend>zaptel</depend>
- <depend>tonezone</depend>
- <depend>res_features</depend>
-+ <depend>gsmat</depend>
- <use>pri</use>
- </member>
-diff -ur -x '*.c' -x '*.orig' -x configure asterisk-1.4.21.1.new/channels/.moduleinfo asterisk-1.4.21.1.old/channels/.moduleinfo
---- asterisk-1.4.21.1.new/channels/.moduleinfo 2008-06-30 18:24:08.000000000 +0200
-+++ asterisk-1.4.21.1.old/channels/.moduleinfo 2008-07-18 08:18:42.808831904 +0200
-@@ -51,6 +51,7 @@
- <depend>zaptel</depend>
- <depend>tonezone</depend>
- <depend>res_features</depend>
-+ <depend>gsmat</depend>
- <use>pri</use>
- </member>
- <member name="chan_vpb" displayname="Voicetronix API driver" remove_on_change="channels/chan_vpb.oo channels/chan_vpb.so">
-diff -ur -x '*.c' -x '*.orig' -x configure asterisk-1.4.21.1.new/configure.ac asterisk-1.4.21.1.old/configure.ac
---- asterisk-1.4.21.1.new/configure.ac 2008-07-18 08:18:57.389246988 +0200
-+++ asterisk-1.4.21.1.old/configure.ac 2008-07-18 08:18:42.806528869 +0200
-@@ -504,6 +504,8 @@
- fi
- fi
-
-+AST_EXT_LIB_CHECK([GSMAT], [gsmat], [gsm_new_call], [libgsmat.h])
-+
- AST_EXT_LIB_CHECK([IKSEMEL], [iksemel], [iks_start_sasl], [iksemel.h])
-
- if test "${PBX_IKSEMEL}" = 1; then
-diff -ur -x '*.c' -x '*.orig' -x configure asterisk-1.4.21.1.new/makeopts.in asterisk-1.4.21.1.old/makeopts.in
---- asterisk-1.4.21.1.new/makeopts.in 2008-03-11 15:07:59.000000000 +0100
-+++ asterisk-1.4.21.1.old/makeopts.in 2008-07-18 08:18:42.813626657 +0200
-@@ -83,6 +83,9 @@
- GSM_INCLUDE=@GSM_INCLUDE@
- GSM_LIB=@GSM_LIB@
-
-+GSMAT_INCLUDE=@GSMAT_INCLUDE@
-+GSMAT_LIB=@GSMAT_LIB@
-+
- GTK_INCLUDE=@GTK_INCLUDE@
- GTK_LIB=@GTK_LIB@
-
-diff -ur -x '*.c' -x '*.orig' -x configure asterisk-1.4.21.1.new/menuselect-tree asterisk-1.4.21.1.old/menuselect-tree
---- asterisk-1.4.21.1.new/menuselect-tree 2008-06-30 18:24:08.000000000 +0200
-+++ asterisk-1.4.21.1.old/menuselect-tree 2008-07-18 08:18:42.813626657 +0200
-@@ -251,6 +251,7 @@
- <depend>zaptel</depend>
- <depend>tonezone</depend>
- <depend>res_features</depend>
-+ <depend>gsmat</depend>
- <use>pri</use>
- </member>
- <member name="chan_vpb" displayname="Voicetronix API driver" remove_on_change="channels/chan_vpb.oo channels/chan_vpb.so">
---- asterisk-1.4.21.1/configure.ac~ 2008-07-20 18:07:54.188016698 +0200
-+++ asterisk-1.4.21.1/configure.ac 2008-07-20 18:09:56.831337972 +0200
-@@ -178,7 +178,7 @@
- AST_EXT_LIB_SETUP([CURSES], [curses], [curses])
- AST_EXT_LIB_SETUP([GNUTLS], [GNU TLS support (used for iksemel only)], [gnutls])
- AST_EXT_LIB_SETUP([GSM], [GSM], [gsm], [, or 'internal'])
--AST_EXT_LIB_SETUP([GSMAT], [GSMAT], [GSM AT command signalling], [gsmat])
-+AST_EXT_LIB_SETUP([GSMAT], [GSM AT command signalling], [gsmat])
- AST_EXT_LIB_SETUP([IKSEMEL], [Iksemel Jabber Library], [iksemel])
- AST_EXT_LIB_SETUP([IMAP_TK], [UW IMAP Toolkit], [imap])
- AST_EXT_LIB_SETUP([ISDNNET], [ISDN4Linux Library], [isdnnet])
---- asterisk/channels/chan_zap.c~ 2008-07-20 18:15:39.464637514 +0200
-+++ asterisk/channels/chan_zap.c 2008-07-20 21:38:13.280088092 +0200
-@@ -7573,7 +7573,7 @@
- }
- #endif
- #ifdef HAVE_GSMAT
-- if (conf->chan.sig == SIG_GSM) {
-+ if (chan_sig == SIG_GSM) {
- struct zt_bufferinfo bi;
- ast_mutex_init(&tmp->gsm.lock);
- strncpy(tmp->gsm.pin, gsm_modem_pin, sizeof(tmp->gsm.pin) - 1);
---- asterisk/channels/chan_zap.c~ 2008-07-20 21:39:17.274665128 +0200
-+++ asterisk/channels/chan_zap.c 2008-07-20 22:18:57.866822681 +0200
-@@ -743,9 +743,7 @@
- .send_digit_begin = zt_digit_begin,
- .send_digit_end = zt_digit_end,
- .send_text = zt_sendtext,
--#if 0 /* we (Debian) disable that addition because of ABI breakage */
- .send_message = zt_sendmessage,
--#endif
- .call = zt_call,
- .hangup = zt_hangup,
- .answer = zt_answer,
---- asterisk/include/asterisk/channel.h~ 2008-07-20 22:20:30.489834448 +0200
-+++ asterisk/include/asterisk/channel.h 2008-07-20 22:24:21.859824471 +0200
-@@ -250,10 +250,8 @@
- /*! \brief Display or transmit text */
- int (* const send_text)(struct ast_channel *chan, const char *text);
-
--#if 0 /* we (Debian) disable that addition because of ABI breakage */
- /*! \brief send a message */
- int (* const send_message)(struct ast_channel *chan, const char *dest, const char *text, int ispdu);
--#endif
-
- /*! \brief Display or send an image */
- int (* const send_image)(struct ast_channel *chan, struct ast_frame *frame);
---- asterisk/main/channel.c~ 2008-07-20 22:20:30.489834448 +0200
-+++ asterisk/main/channel.c 2008-07-20 22:25:38.689861614 +0200
-@@ -2496,10 +2496,8 @@
- if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
- return -1;
- CHECK_BLOCKING(chan);
--#if 0 /* we (Debian) disable that addition because of ABI breakage */
- if (chan->tech->send_message)
- res = chan->tech->send_message(chan, dest, text, ispdu);
--#endif
- ast_clear_flag(chan, AST_FLAG_BLOCKING);
- return res;
- }
diff --git a/asterisk-bristuff-libpri.patch b/asterisk-bristuff-libpri.patch
deleted file mode 100644
index 414afd6..0000000
--- a/asterisk-bristuff-libpri.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/configure.ac
-+++ b/configure.ac
-@@ -823,7 +823,7 @@ fi
-
- AST_EXT_LIB_CHECK([POPT], [popt], [poptStrerror], [popt.h])
-
--AST_EXT_LIB_CHECK([PRI], [pri], [pri_keypad_facility], [libpri.h])
-+AST_EXT_LIB_CHECK([PRI], [pri-bristuff], [pri_keypad_facility], [bristuff/libpri.h])
-
- if test "${USE_PWLIB}" != "no"; then
- if test -n "${PWLIB_DIR}"; then
---- a/channels/chan_zap.c
-+++ b/channels/chan_zap.c
-@@ -71,7 +71,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi
- #include <zaptel/tonezone.h>
-
- #ifdef HAVE_PRI
--#include <libpri.h>
-+#include <bristuff/libpri.h>
- #endif
-
- #include "asterisk/lock.h"
diff --git a/asterisk-bristuff.patch b/asterisk-bristuff.patch
deleted file mode 100644
index 85f9a30..0000000
--- a/asterisk-bristuff.patch
+++ /dev/null
@@ -1,7998 +0,0 @@
---- a/README
-+++ b/README
-@@ -4,6 +4,8 @@ and the Asterisk.org developer community
-
- Copyright (C) 2001-2006 Digium, Inc.
- and other copyright holders.
-+Copyright (C) 2002-2005 Junghanns.NET GmbH
-+and other copyright holders.
- ================================================================
-
- * SECURITY
---- a/LICENSE
-+++ b/LICENSE
-@@ -1,7 +1,7 @@
--Asterisk is distributed under the GNU General Public License version 2
--and is also available under alternative licenses negotiated directly
--with Digium, Inc. If you obtained Asterisk under the GPL, then the GPL
--applies to all loadable Asterisk modules used on your system as well,
-+BRIstuffed Asterisk is distributed under the GNU General Public License version 2
-+and is not available under any alternative licenses.
-+If you obtained BRIstuffed Asterisk under the GPL, then the GPL
-+applies to all loadable BRIstuffed Asterisk modules used on your system as well,
- except as defined below. The GPL (version 2) is included in this
- source tree in the file COPYING.
-
---- a/doc/hardware.txt
-+++ b/doc/hardware.txt
-@@ -31,6 +31,19 @@ Zaptel compatible hardware
- * Wildcard TE410P - Quad T1/E1 switchable interface. Supports PRI and
- RBS signalling, as well as PPP, FR, and HDLC data modes.
-
-+-- Junghanns.NET (Primary author of BRIstuff)
-+ http://www.junghanns.net
-+
-+ * quadBRI PCI ISDN - 4port BRI ISDN interface, supports NT and TE mode
-+
-+ * octoBRI PCI ISDN - 8port BRI ISDN interface, supports NT and TE mode
-+
-+ * singleE1 PCI ISDN - Single E1 interface
-+
-+ * doubleE1 PCI ISDN - Double E1 interface
-+
-+ * uno/duo/quad GSM PCI - 1/2/4 channel GSM interface cards
-+
- Non-zaptel compatible hardware
- ==============================
-
---- a/build_tools/make_defaults_h
-+++ b/build_tools/make_defaults_h
-@@ -17,6 +17,7 @@ cat << END
- #define AST_KEY_DIR "${INSTALL_PATH}${ASTDATADIR}/keys"
- #define AST_DB "${INSTALL_PATH}${ASTVARLIBDIR}/astdb"
- #define AST_TMP_DIR "${INSTALL_PATH}${ASTSPOOLDIR}/tmp"
-+#define AST_SYSTEM_NAME "asterisk"
-
- #define AST_CONFIG_FILE "${INSTALL_PATH}${ASTCONFPATH}"
-
---- a/main/asterisk.c
-+++ b/main/asterisk.c
-@@ -2427,6 +2427,7 @@ static void ast_readconfig(void)
- ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID));
- ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET));
- ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR));
-+ ast_copy_string(ast_config_AST_SYSTEM_NAME, AST_SYSTEM_NAME, sizeof(ast_config_AST_SYSTEM_NAME));
-
- /* no asterisk.conf? no problem, use buildtime config! */
- if (!cfg) {
-@@ -2551,6 +2552,8 @@ static void ast_readconfig(void)
- ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
- } else if (!strcasecmp(v->name, "systemname")) {
- ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
-+ } else if (!strcasecmp(v->name, "uniquename")) {
-+ ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
- } else if (!strcasecmp(v->name, "languageprefix")) {
- ast_language_is_prefix = ast_true(v->value);
- }
---- a/include/asterisk/agi.h
-+++ b/include/asterisk/agi.h
-@@ -30,6 +30,7 @@ extern "C" {
- typedef struct agi_state {
- int fd; /* FD for general output */
- int audio; /* FD for audio output */
-+ int audio_in; /* FD for audio output */
- int ctrl; /* FD for input control */
- unsigned int fast:1; /* flag for fast agi or not */
- } AGI;
---- a/res/res_agi.c
-+++ b/res/res_agi.c
-@@ -11,6 +11,9 @@
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
-+ * Copyright (C) 2005 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
-@@ -75,16 +78,19 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi
-
- static char *app = "AGI";
-
-+static char *xapp = "XAGI";
-+
- static char *eapp = "EAGI";
-
- static char *deadapp = "DeadAGI";
-
- static char *synopsis = "Executes an AGI compliant application";
-+static char *xsynopsis = "Executes an XAGI compliant application";
- static char *esynopsis = "Executes an EAGI compliant application";
- static char *deadsynopsis = "Executes AGI on a hungup channel";
-
- static char *descrip =
--" [E|Dead]AGI(command|args): Executes an Asterisk Gateway Interface compliant\n"
-+" [E|Dead|X]AGI(command|args): Executes an Asterisk Gateway Interface compliant\n"
- "program on a channel. AGI allows Asterisk to launch external programs\n"
- "written in any language to control a telephony channel, play audio,\n"
- "read DTMF digits, etc. by communicating with the AGI protocol on stdin\n"
-@@ -97,6 +103,8 @@ static char *descrip =
- "variable to \"no\" before executing the AGI application.\n"
- " Using 'EAGI' provides enhanced AGI, with incoming audio available out of band\n"
- "on file descriptor 3\n\n"
-+"Using 'XAGI' provides enhanced AGI, with incoming audio available out of band"
-+" on file descriptor 3 and outgoing audio available out of band on file descriptor 4\n\n"
- " Use the CLI command 'agi show' to list available agi commands\n"
- " This application sets the following channel variable upon completion:\n"
- " AGISTATUS The status of the attempt to the run the AGI script\n"
-@@ -236,13 +244,14 @@ static enum agi_result launch_netscript(
- return AGI_RESULT_SUCCESS_FAST;
- }
-
--static enum agi_result launch_script(char *script, char *argv[], int *fds, int *efd, int *opid)
-+static enum agi_result launch_script(char *script, char *argv[], int *fds, int *efd, int *efd2, int *opid)
- {
- char tmp[256];
- int pid;
- int toast[2];
- int fromast[2];
- int audio[2];
-+ int audio2[2];
- int x;
- int res;
- sigset_t signal_set, old_set;
-@@ -287,6 +296,33 @@ static enum agi_result launch_script(cha
- return AGI_RESULT_FAILURE;
- }
- }
-+ if (efd2) {
-+ if (pipe(audio2)) {
-+ ast_log(LOG_WARNING, "unable to create audio pipe: %s\n", strerror(errno));
-+ close(fromast[0]);
-+ close(fromast[1]);
-+ close(toast[0]);
-+ close(toast[1]);
-+ close(audio[0]);
-+ close(audio[1]);
-+ return AGI_RESULT_FAILURE;
-+ }
-+ res = fcntl(audio2[0], F_GETFL);
-+ if (res > -1)
-+ res = fcntl(audio2[0], F_SETFL, res | O_NONBLOCK);
-+ if (res < 0) {
-+ ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
-+ close(fromast[0]);
-+ close(fromast[1]);
-+ close(toast[0]);
-+ close(toast[1]);
-+ close(audio[0]);
-+ close(audio[1]);
-+ close(audio2[0]);
-+ close(audio2[1]);
-+ return AGI_RESULT_FAILURE;
-+ }
-+ }
-
- /* Block SIGHUP during the fork - prevents a race */
- sigfillset(&signal_set);
-@@ -322,6 +358,11 @@ static enum agi_result launch_script(cha
- } else {
- close(STDERR_FILENO + 1);
- }
-+ if (efd2) {
-+ dup2(audio2[1], STDERR_FILENO + 2);
-+ } else {
-+ close(STDERR_FILENO + 2);
-+ }
-
- /* Before we unblock our signals, return our trapped signals back to the defaults */
- signal(SIGHUP, SIG_DFL);
-@@ -339,7 +380,7 @@ static enum agi_result launch_script(cha
- }
-
- /* Close everything but stdin/out/error */
-- for (x=STDERR_FILENO + 2;x<1024;x++)
-+ for (x=STDERR_FILENO + 3;x<1024;x++)
- close(x);
-
- /* Execute script */
-@@ -359,12 +400,19 @@ static enum agi_result launch_script(cha
- if (efd) {
- *efd = audio[1];
- }
-+ if (efd2) {
-+ *efd2 = audio2[0];
-+ }
- /* close what we're not using in the parent */
- close(toast[1]);
- close(fromast[0]);
-
-- if (efd)
-+ if (efd) {
- close(audio[0]);
-+ }
-+ if (efd2) {
-+ close(audio2[1]);
-+ }
-
- *opid = pid;
- return AGI_RESULT_SUCCESS;
-@@ -394,7 +442,7 @@ static void setup_env(struct ast_channel
- fdprintf(fd, "agi_context: %s\n", chan->context);
- fdprintf(fd, "agi_extension: %s\n", chan->exten);
- fdprintf(fd, "agi_priority: %d\n", chan->priority);
-- fdprintf(fd, "agi_enhanced: %s\n", enhanced ? "1.0" : "0.0");
-+ fdprintf(fd, "agi_enhanced: %d%s\n", enhanced, ".0");
-
- /* User information */
- fdprintf(fd, "agi_accountcode: %s\n", chan->accountcode ? chan->accountcode : "");
-@@ -1835,8 +1883,13 @@ static enum agi_result run_agi(struct as
- int ms;
- enum agi_result returnstatus = AGI_RESULT_SUCCESS;
- struct ast_frame *f;
-+ struct ast_frame fr;
- char buf[AGI_BUF_LEN];
-+ char audiobuf[AGI_BUF_LEN];
- char *res = NULL;
-+ int audiobytes;
-+ int fds[2];
-+ int enhanced = 0;
- FILE *readf;
- /* how many times we'll retry if ast_waitfor_nandfs will return without either
- channel or file descriptor in case select is interrupted by a system call (EINTR) */
-@@ -1850,10 +1903,22 @@ static enum agi_result run_agi(struct as
- return AGI_RESULT_FAILURE;
- }
- setlinebuf(readf);
-- setup_env(chan, request, agi->fd, (agi->audio > -1));
-+ if (agi->audio > -1) {
-+ enhanced = 1;
-+ }
-+ if (agi->audio_in > -1) {
-+ enhanced++;
-+ }
-+ setup_env(chan, request, agi->fd, enhanced);
-+ fds[0] = agi->ctrl;
-+ fds[1] = agi->audio_in;
- for (;;) {
- ms = -1;
-- c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
-+ if (agi->audio_in > -1) {
-+ c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, fds, 2, NULL, &outfd, &ms);
-+ } else {
-+ c = ast_waitfor_nandfds(&chan, dead ? 0 : 1, &agi->ctrl, 1, NULL, &outfd, &ms);
-+ }
- if (c) {
- retry = AGI_NANDFS_RETRY;
- /* Idle the channel until we get a command */
-@@ -1871,6 +1936,16 @@ static enum agi_result run_agi(struct as
- ast_frfree(f);
- }
- } else if (outfd > -1) {
-+ if ((agi->audio_in > -1) && (outfd == agi->audio_in)) {
-+ audiobytes = read(agi->audio_in, audiobuf, sizeof(audiobuf));
-+ if (audiobytes > 0) {
-+ fr.frametype = AST_FRAME_VOICE;
-+ fr.subclass = AST_FORMAT_SLINEAR;
-+ fr.datalen = audiobytes;
-+ fr.data = audiobuf;
-+ ast_write(chan, &fr);
-+ }
-+ } else {
- size_t len = sizeof(buf);
- size_t buflen = 0;
-
-@@ -1922,6 +1997,7 @@ static enum agi_result run_agi(struct as
- if ((returnstatus < 0) || (returnstatus == AST_PBX_KEEPALIVE)) {
- break;
- }
-+ }
- } else {
- if (--retry <= 0) {
- ast_log(LOG_WARNING, "No channel, no fd?\n");
-@@ -2030,6 +2106,7 @@ static int agi_exec_full(struct ast_chan
- int argc = 0;
- int fds[2];
- int efd = -1;
-+ int efd2 = -1;
- int pid;
- char *stringp;
- AGI agi;
-@@ -2056,12 +2133,13 @@ static int agi_exec_full(struct ast_chan
- }
- #endif
- ast_replace_sigchld();
-- res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, &pid);
-+ res = launch_script(argv[0], argv, fds, enhanced ? &efd : NULL, (enhanced == 2) ? &efd2 : NULL, &pid);
- if (res == AGI_RESULT_SUCCESS || res == AGI_RESULT_SUCCESS_FAST) {
- int status = 0;
- agi.fd = fds[1];
- agi.ctrl = fds[0];
- agi.audio = efd;
-+ agi.audio_in = efd2;
- agi.fast = (res == AGI_RESULT_SUCCESS_FAST) ? 1 : 0;
- res = run_agi(chan, argv[0], &agi, pid, &status, dead);
- /* If the fork'd process returns non-zero, set AGISTATUS to FAILURE */
-@@ -2071,6 +2149,8 @@ static int agi_exec_full(struct ast_chan
- close(fds[1]);
- if (efd > -1)
- close(efd);
-+ if (efd2 > -1)
-+ close(efd2);
- }
- ast_unreplace_sigchld();
- ast_module_user_remove(u);
-@@ -2119,6 +2199,35 @@ static int eagi_exec(struct ast_channel
- return res;
- }
-
-+static int xagi_exec(struct ast_channel *chan, void *data)
-+{
-+ int readformat, writeformat;
-+ int res;
-+
-+ if (chan->_softhangup)
-+ ast_log(LOG_WARNING, "If you want to run AGI on hungup channels you should use DeadAGI!\n");
-+ readformat = chan->readformat;
-+ if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
-+ ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
-+ return -1;
-+ }
-+ writeformat = chan->writeformat;
-+ if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
-+ ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
-+ return -1;
-+ }
-+ res = agi_exec_full(chan, data, 2, 0);
-+ if (!res) {
-+ if (ast_set_read_format(chan, readformat)) {
-+ ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
-+ }
-+ if (ast_set_write_format(chan, writeformat)) {
-+ ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(writeformat));
-+ }
-+ }
-+ return res;
-+}
-+
- static int deadagi_exec(struct ast_channel *chan, void *data)
- {
- if (!ast_check_hangup(chan))
-@@ -2174,6 +2283,7 @@ static int unload_module(void)
- {
- ast_module_user_hangup_all();
- ast_cli_unregister_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry));
-+ ast_unregister_application(xapp);
- ast_unregister_application(eapp);
- ast_unregister_application(deadapp);
- return ast_unregister_application(app);
-@@ -2184,6 +2294,7 @@ static int load_module(void)
- ast_cli_register_multiple(cli_agi, sizeof(cli_agi) / sizeof(struct ast_cli_entry));
- ast_register_application(deadapp, deadagi_exec, deadsynopsis, descrip);
- ast_register_application(eapp, eagi_exec, esynopsis, descrip);
-+ ast_register_application(xapp, xagi_exec, xsynopsis, descrip);
- return ast_register_application(app, agi_exec, synopsis, descrip);
- }
-
---- /dev/null
-+++ b/agi/xagi-test.c
-@@ -0,0 +1,175 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * XAGI sample script
-+ *
-+ * Copyright (C) 2005 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * based on eagi-test.c
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <sys/select.h>
-+#ifdef SOLARIS
-+#include <solaris-compat/compat.h>
-+#endif
-+
-+#define AUDIO_FILENO_IN (STDERR_FILENO + 1)
-+#define AUDIO_FILENO_OUT (STDERR_FILENO + 2)
-+
-+static int read_environment(void)
-+{
-+ char buf[256];
-+ char *val;
-+ /* Read environment */
-+ for(;;) {
-+ fgets(buf, sizeof(buf), stdin);
-+ if (feof(stdin))
-+ return -1;
-+ buf[strlen(buf) - 1] = '\0';
-+ /* Check for end of environment */
-+ if (!strlen(buf))
-+ return 0;
-+ val = strchr(buf, ':');
-+ if (!val) {
-+ fprintf(stderr, "Invalid environment: '%s'\n", buf);
-+ return -1;
-+ }
-+ *val = '\0';
-+ val++;
-+ val++;
-+ /* Skip space */
-+ // fprintf(stderr, "Environment: '%s' is '%s'\n", buf, val);
-+
-+ /* Load into normal environment */
-+ setenv(buf, val, 1);
-+
-+ }
-+ /* Never reached */
-+ return 0;
-+}
-+
-+static void app_echo(void)
-+{
-+ fd_set fds;
-+ int res;
-+ int bytes = 0;
-+ static char astresp[256];
-+ char audiobuf[16000]; /* 1 second of audio */
-+ for (;;) {
-+ FD_ZERO(&fds);
-+ FD_SET(STDIN_FILENO, &fds);
-+ FD_SET(AUDIO_FILENO_IN, &fds);
-+ /* Wait for *some* sort of I/O */
-+ res = select(AUDIO_FILENO_IN + 1, &fds, NULL, NULL, NULL);
-+ if (res < 0) {
-+ fprintf(stderr, "Error in select: %s\n", strerror(errno));
-+ return;
-+ }
-+ if (FD_ISSET(STDIN_FILENO, &fds)) {
-+ fgets(astresp, sizeof(astresp), stdin);
-+ if (feof(stdin)) {
-+ return;
-+ }
-+ astresp[strlen(astresp) - 1] = '\0';
-+ fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
-+ return;
-+ }
-+ if (FD_ISSET(AUDIO_FILENO_IN, &fds)) {
-+ /* what goes in.... */
-+ res = read(AUDIO_FILENO_IN, audiobuf, sizeof(audiobuf));
-+ if (res > 0) {
-+ bytes = res;
-+ /* must come out */
-+ write(AUDIO_FILENO_OUT, audiobuf, bytes);
-+ }
-+ }
-+ }
-+}
-+
-+static char *wait_result(void)
-+{
-+ fd_set fds;
-+ int res;
-+ static char astresp[256];
-+ char audiobuf[4096];
-+ for (;;) {
-+ FD_ZERO(&fds);
-+ FD_SET(STDIN_FILENO, &fds);
-+ FD_SET(AUDIO_FILENO_IN, &fds);
-+ /* Wait for *some* sort of I/O */
-+ res = select(AUDIO_FILENO_IN + 1, &fds, NULL, NULL, NULL);
-+ if (res < 0) {
-+ fprintf(stderr, "Error in select: %s\n", strerror(errno));
-+ return NULL;
-+ }
-+ if (FD_ISSET(STDIN_FILENO, &fds)) {
-+ fgets(astresp, sizeof(astresp), stdin);
-+ if (feof(stdin)) {
-+ fprintf(stderr, "Got hungup on apparently\n");
-+ return NULL;
-+ }
-+ astresp[strlen(astresp) - 1] = '\0';
-+ fprintf(stderr, "Ooh, got a response from Asterisk: '%s'\n", astresp);
-+ return astresp;
-+ }
-+ if (FD_ISSET(AUDIO_FILENO_IN, &fds)) {
-+ res = read(AUDIO_FILENO_IN, audiobuf, sizeof(audiobuf));
-+ /* drop it, like it's hot */
-+ }
-+ }
-+
-+}
-+
-+static char *run_command(char *command)
-+{
-+ fprintf(stdout, "%s\n", command);
-+ return wait_result();
-+}
-+
-+
-+static int run_script(void)
-+{
-+ char *res;
-+ res = run_command("STREAM FILE demo-echotest \"\"");
-+ if (!res) {
-+ fprintf(stderr, "Failed to execute command\n");
-+ return -1;
-+ }
-+ app_echo();
-+ return 0;
-+}
-+
-+int main(int argc, char *argv[])
-+{
-+ char *tmp;
-+ int ver = 0;
-+ int subver = 0;
-+ /* Setup stdin/stdout for line buffering */
-+ setlinebuf(stdin);
-+ setlinebuf(stdout);
-+ if (read_environment()) {
-+ fprintf(stderr, "Failed to read environment: %s\n", strerror(errno));
-+ exit(1);
-+ }
-+ tmp = getenv("agi_enhanced");
-+ if (tmp) {
-+ if (sscanf(tmp, "%d.%d", &ver, &subver) != 2)
-+ ver = 0;
-+ }
-+ if (ver < 2) {
-+ fprintf(stderr, "No XAGI services available. Use XAGI, not AGI or EAGI\n");
-+ exit(1);
-+ }
-+ if (run_script())
-+ return -1;
-+ exit(0);
-+}
---- a/agi/Makefile
-+++ b/agi/Makefile
-@@ -13,7 +13,7 @@
-
- .PHONY: clean all uninstall
-
--AGIS=agi-test.agi eagi-test eagi-sphinx-test jukebox.agi
-+AGIS=agi-test.agi eagi-test eagi-sphinx-test jukebox.agi xagi-test
-
- ifeq ($(OSARCH),SunOS)
- LIBS+=-lsocket -lnsl
-@@ -38,7 +38,7 @@ uninstall:
- for x in $(AGIS); do rm -f $(DESTDIR)$(AGI_DIR)/$$x ; done
-
- clean:
-- rm -f *.so *.o look eagi-test eagi-sphinx-test
-+ rm -f *.so *.o look eagi-test eagi-sphinx-test xagi-test
- rm -f .*.o.d .*.oo.d *.s *.i
- rm -f strcompat.c
-
---- /dev/null
-+++ b/apps/app_segfault.c
-@@ -0,0 +1,55 @@
-+/*
-+ * Segfault application
-+ *
-+ * An application to provoke a segmentation fault from the dialplan.
-+ * (I know what you are thinking now...., but since Asterisk is too stable...
-+ * I needed something to test my failover switches.)
-+ *
-+ * Copyright (C) 2005 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License. THIS APPLICATION _WILL_ CRASH YOUR
-+ * ASTERISK SERVER SO OF COURSE THERE IS NOT LIABILITY FOR NOTHING!
-+ */
-+
-+#include "asterisk.h"
-+
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdio.h>
-+#include <asterisk/lock.h>
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+
-+static char *app = "Segfault";
-+
-+static char *synopsis = "This application will crash Asterisk with a segmentation fault.";
-+
-+static char *descrip =
-+" Segfault(): Crash with a segfault. Never returns nufin.\n";
-+
-+static int segfault_exec(struct ast_channel *chan, void *data)
-+{
-+ ((char *)0)[0] = 0;
-+ return 0;
-+}
-+
-+static int unload_module(void)
-+{
-+ return ast_unregister_application(app);
-+}
-+
-+static int load_module(void)
-+{
-+ return ast_register_application(app, segfault_exec, synopsis, descrip);
-+}
-+
-+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Application for crashing Asterisk with a segmentation fault",
-+ .load = load_module,
-+ .unload = unload_module,
-+);
---- a/apps/app_directed_pickup.c
-+++ b/apps/app_directed_pickup.c
-@@ -45,7 +45,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi
-
- #define PICKUPMARK "PICKUPMARK"
-
--static const char *app = "Pickup";
-+static const char *app = "DPickup";
- static const char *synopsis = "Directed Call Pickup";
- static const char *descrip =
- " Pickup(extension[@context][&extension2 at context...]): This application can pickup any ringing channel\n"
---- /dev/null
-+++ b/apps/app_pickup.c
-@@ -0,0 +1,300 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * Pickup, channel independent call pickup
-+ *
-+ * Copyright (C) 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * Copyright (C) 2004, Florian Overkamp <florian at obsimref.com>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include "asterisk.h"
-+
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdio.h>
-+#include <signal.h>
-+#include <pthread.h>
-+#include <asterisk/lock.h>
-+#include <asterisk/file.h>
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/module.h>
-+#include <asterisk/features.h>
-+#include <asterisk/options.h>
-+
-+
-+static char *app = "PickUp";
-+
-+static char *synopsis = "Channel independent call pickup.";
-+
-+static char *descrip =
-+" PickDown([group]): Tries to pickup the first ringing channel with callgroup == group.\n"
-+" If called without the group argument, the pickupgroup of the channel will be used.\n";
-+
-+static char *app2 = "Steal";
-+
-+static char *synopsis2 = "Channel independent call stealing. Just like pickup but for answered channels.";
-+
-+static char *descrip2 =
-+" Steal([group]): Tries to steal the first bridged channel with callgroup == group.\n"
-+" If called without the group argument, the pickupgroup of the channel will be used.\n";
-+
-+static char *app3 = "PickDown";
-+
-+static char *synopsis3 = "Channel independent call pickdown.";
-+
-+static char *descrip3 =
-+" PickDown([group]): Tries to hangup the first ringing channel with callgroup == group.\n"
-+" If called without the group argument, the pickupgroup of the channel will be used.\n";
-+
-+static char *app4 = "PickupChan";
-+
-+static char *synopsis4 = "Channel independent call pickup.";
-+
-+static char *descrip4 =
-+" PickupChan(Technology/resource[&Technology2/resource2...]): Tries to pickup the first ringing channel in the parameter list.\n";
-+
-+static char *app5 = "StealChan";
-+
-+static char *synopsis5 = "Channel independent call stealing. Just like pickup but for answered channels.";
-+
-+static char *descrip5 =
-+" StealChan(Technology/resource[&Technology2/resource2...]): Tries to steal the first ringing channel in the parameter list.\n";
-+
-+
-+static int my_pickup_call(struct ast_channel *chan, unsigned int pickupgroup, int chanstate, int bridge) {
-+ struct ast_channel *cur;
-+ int res = -1;
-+ cur = ast_channel_walk_locked(NULL);
-+ while(cur) {
-+ if ((cur != chan) &&
-+ (pickupgroup & cur->callgroup) &&
-+ (cur->_state == chanstate)) {
-+ break;
-+ }
-+ ast_mutex_unlock(&cur->lock);
-+ cur = ast_channel_walk_locked(cur);
-+ }
-+ if (cur) {
-+ if(option_verbose > 2) {
-+ if (chanstate == AST_STATE_RINGING) {
-+ if (bridge == 1) {
-+ ast_verbose(VERBOSE_PREFIX_3 "Channel %s picked up ringing channel %s\n",chan->name,cur->name);
-+ } else {
-+ ast_verbose(VERBOSE_PREFIX_3 "Channel %s hung up ringing channel %s\n",chan->name,cur->name);
-+ }
-+ } else {
-+ ast_verbose(VERBOSE_PREFIX_3 "Channel %s stole channel %s\n",chan->name,cur->name);
-+ }
-+ }
-+ if (bridge == 1) {
-+ if (chan->_state != AST_STATE_UP) {
-+ ast_answer(chan);
-+ }
-+ if (ast_channel_masquerade(cur, chan)) {
-+ ast_log(LOG_ERROR, "unable to masquerade\n");
-+ }
-+ ast_mutex_unlock(&cur->lock);
-+ ast_mutex_unlock(&chan->lock);
-+ } else {
-+ cur->_softhangup = AST_SOFTHANGUP_DEV;
-+ ast_mutex_unlock(&cur->lock);
-+ }
-+ } else {
-+ if(option_verbose > 2) {
-+ ast_verbose(VERBOSE_PREFIX_3 "No channel found %d.\n",pickupgroup);
-+ }
-+ }
-+ return res;
-+}
-+
-+static int my_pickup_channel(struct ast_channel *chan, void *data, int chanstate, int bridge) {
-+ struct ast_channel *cur;
-+ char channels[256];
-+ char evalchan[256];
-+ char *endptr;
-+ int res = -1;
-+ cur = ast_channel_walk_locked(NULL);
-+ strncpy(channels, (char *)data, sizeof(channels) - 1);
-+ while(cur) {
-+ if ((cur != chan) &&
-+ (cur->_state == chanstate)) {
-+ /* This call is a candidate (correct ringstate and not ourselves), now check if the channel is in our list */
-+ strncpy(evalchan, (char *)cur->name, sizeof(evalchan) - 1);
-+ /* strip the subchannel tag */
-+ endptr = strrchr(evalchan, '-');
-+ if(endptr) {
-+ *endptr = '\0';
-+ }
-+ /* check for each of the members if they match (probably a stristr will do ?) */
-+ /* if we match the code, break */
-+ if(strstr(channels, evalchan) != NULL) {
-+ ast_verbose(VERBOSE_PREFIX_1 "Nice channel, I'll take it: %s\n",evalchan);
-+ break;
-+ }
-+ }
-+ ast_mutex_unlock(&cur->lock);
-+ cur = ast_channel_walk_locked(cur);
-+ }
-+ if (cur) {
-+ if(option_verbose > 2) {
-+ if (chanstate == AST_STATE_RINGING) {
-+ if (bridge == 1) {
-+ ast_verbose(VERBOSE_PREFIX_3 "Channel %s picked up ringing channel %s\n",chan->name,cur->name);
-+ } else {
-+ ast_verbose(VERBOSE_PREFIX_3 "Channel %s hung up ringing channel %s\n",chan->name,cur->name);
-+ }
-+ } else {
-+ ast_verbose(VERBOSE_PREFIX_3 "Channel %s stole channel %s\n",chan->name,cur->name);
-+ }
-+ }
-+ if (bridge == 1) {
-+ if (chan->_state != AST_STATE_UP) {
-+ ast_answer(chan);
-+ }
-+ if (ast_channel_masquerade(cur, chan)) {
-+ ast_log(LOG_ERROR, "unable to masquerade\n");
-+ }
-+ ast_mutex_unlock(&cur->lock);
-+ ast_mutex_unlock(&chan->lock);
-+ } else {
-+ cur->_softhangup = AST_SOFTHANGUP_DEV;
-+ ast_mutex_unlock(&cur->lock);
-+ }
-+ } else {
-+ if(option_verbose > 2) {
-+ ast_verbose(VERBOSE_PREFIX_3 "No channel found %s.\n",channels);
-+ }
-+ }
-+ return res;
-+}
-+
-+
-+static int pickup_exec(struct ast_channel *chan, void *data)
-+{
-+ int res=0;
-+ unsigned int pickupgroup=0;
-+ struct ast_module_user *u;
-+ if (!data || !strlen(data)) {
-+ pickupgroup = chan->pickupgroup;
-+ } else {
-+ pickupgroup = ast_get_group(data);
-+ }
-+ u = ast_module_user_add(chan);
-+ if (!res) {
-+ res = my_pickup_call(chan, pickupgroup, AST_STATE_RINGING, 1);
-+ }
-+ if (res > 0)
-+ res = 0;
-+ ast_module_user_remove(u);
-+ return res;
-+}
-+
-+static int steal_exec(struct ast_channel *chan, void *data)
-+{
-+ int res=0;
-+ unsigned int pickupgroup=0;
-+ struct ast_module_user *u;
-+ if (!data || !strlen(data)) {
-+ pickupgroup = chan->pickupgroup;
-+ } else {
-+ pickupgroup = ast_get_group(data);
-+ }
-+ u = ast_module_user_add(chan);
-+ if (!res) {
-+ res = my_pickup_call(chan, pickupgroup, AST_STATE_UP, 1);
-+ }
-+ if (res > 0)
-+ res = 0;
-+ ast_module_user_remove(u);
-+ return res;
-+}
-+
-+static int pickdown_exec(struct ast_channel *chan, void *data)
-+{
-+ int res=0;
-+ unsigned int pickupgroup=0;
-+ struct ast_module_user *u;
-+ if (!data || !strlen(data)) {
-+ pickupgroup = chan->pickupgroup;
-+ } else {
-+ pickupgroup = ast_get_group(data);
-+ }
-+ u = ast_module_user_add(chan);
-+ if (!res) {
-+ res = my_pickup_call(chan, pickupgroup, AST_STATE_RINGING, 0);
-+ }
-+ if (res > 0)
-+ res = 0;
-+ ast_module_user_remove(u);
-+ return res;
-+}
-+
-+static int pickupchan_exec(struct ast_channel *chan, void *data) {
-+ int res=0;
-+ struct ast_module_user *u;
-+ if (!data) {
-+ ast_log(LOG_WARNING, "PickupChan requires an argument (technology1/number1&technology2/number2...)\n");
-+ return -1;
-+ }
-+ u = ast_module_user_add(chan);
-+ if (!res) {
-+ res = my_pickup_channel(chan, data, AST_STATE_RINGING, 1);
-+ }
-+ if (res > 0)
-+ res = 0;
-+ ast_module_user_remove(u);
-+ return res;
-+}
-+
-+static int stealchan_exec(struct ast_channel *chan, void *data)
-+{
-+ int res=0;
-+ struct ast_module_user *u;
-+ if (!data) {
-+ ast_log(LOG_WARNING, "StealChan requires an argument (technology1/number1&technology2/number2...)\n");
-+ return -1;
-+ }
-+
-+ u = ast_module_user_add(chan);
-+ if (!res) {
-+ res = my_pickup_channel(chan, data, AST_STATE_UP, 1);
-+ }
-+ if (res > 0)
-+ res = 0;
-+ ast_module_user_remove(u);
-+ return res;
-+}
-+
-+
-+static int unload_module(void)
-+{
-+ ast_module_user_hangup_all();
-+ ast_unregister_application(app5);
-+ ast_unregister_application(app4);
-+ ast_unregister_application(app3);
-+ ast_unregister_application(app2);
-+ return ast_unregister_application(app);
-+}
-+
-+static int load_module(void)
-+{
-+ ast_register_application(app5, stealchan_exec, synopsis5, descrip5);
-+ ast_register_application(app4, pickupchan_exec, synopsis4, descrip4);
-+ ast_register_application(app3, pickdown_exec, synopsis3, descrip3);
-+ ast_register_application(app2, steal_exec, synopsis2, descrip2);
-+ return ast_register_application(app, pickup_exec, synopsis, descrip);
-+}
-+
-+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "PickUp/PickDown/Steal/PickupChan/StealChan",
-+ .load = load_module,
-+ .unload = unload_module,
-+);
---- /dev/null
-+++ b/apps/app_devstate.c
-@@ -0,0 +1,202 @@
-+/*
-+ * Devstate application
-+ *
-+ * Since we like the snom leds so much, a little app to
-+ * light the lights on the snom on demand ....
-+ *
-+ * Copyright (C) 2005, Druid Software
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include "asterisk.h"
-+
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdio.h>
-+
-+#include "asterisk/lock.h"
-+#include "asterisk/file.h"
-+#include "asterisk/logger.h"
-+#include "asterisk/channel.h"
-+#include "asterisk/pbx.h"
-+#include "asterisk/astdb.h"
-+#include "asterisk/cli.h"
-+#include "asterisk/manager.h"
-+#include "asterisk/devicestate.h"
-+#include "asterisk/module.h"
-+
-+
-+static char type[] = "DS";
-+static char tdesc[] = "Application for sending device state messages";
-+
-+static char app[] = "Devstate";
-+
-+static char synopsis[] = "Generate a device state change event given the input parameters";
-+
-+static char descrip[] = " Devstate(device|state): Generate a device state change event given the input parameters. Returns 0. State values match the asterisk device states. They are 0 = unknown, 1 = not inuse, 2 = inuse, 3 = busy, 4 = invalid, 5 = unavailable, 6 = ringing\n";
-+
-+static char devstate_cli_usage[] =
-+"Usage: devstate device state\n"
-+" Generate a device state change event given the input parameters.\n Mainly used for lighting the LEDs on the snoms.\n";
-+
-+static int devstate_cli(int fd, int argc, char *argv[]);
-+static struct ast_cli_entry cli_dev_state =
-+ { { "devstate", NULL }, devstate_cli, "Set the device state on one of the \"pseudo devices\".", devstate_cli_usage };
-+
-+
-+static int devstate_cli(int fd, int argc, char *argv[])
-+{
-+ char devName[128];
-+ if (argc != 3)
-+ return RESULT_SHOWUSAGE;
-+
-+ if (ast_db_put("DEVSTATES", argv[1], argv[2]))
-+ {
-+ ast_log(LOG_DEBUG, "ast_db_put failed\n");
-+ }
-+ snprintf(devName, sizeof(devName), "DS/%s", argv[1]);
-+ ast_device_state_changed_literal(devName);
-+ return RESULT_SUCCESS;
-+}
-+
-+static int devstate_exec(struct ast_channel *chan, void *data)
-+{
-+ char *device, *state, *info;
-+ char devName[128];
-+ struct ast_module_user *u;
-+
-+
-+ if (!(info = ast_strdupa(data))) {
-+ ast_log(LOG_WARNING, "Unable to dupe data :(\n");
-+ return -1;
-+ }
-+
-+ u = ast_module_user_add(chan);
-+ device = info;
-+ state = strchr(info, '|');
-+ if (state) {
-+ *state = '\0';
-+ state++;
-+ }
-+ else
-+ {
-+ ast_log(LOG_DEBUG, "No state argument supplied\n");
-+ return -1;
-+ }
-+
-+ if (ast_db_put("DEVSTATES", device, state))
-+ {
-+ ast_log(LOG_DEBUG, "ast_db_put failed\n");
-+ }
-+
-+ snprintf(devName, sizeof(devName), "DS/%s", device);
-+ ast_device_state_changed_literal(devName);
-+
-+ ast_module_user_remove(u);
-+ return 0;
-+}
-+
-+
-+static int ds_devicestate(void *data)
-+{
-+ char *dest = data;
-+ char stateStr[16];
-+ if (ast_db_get("DEVSTATES", dest, stateStr, sizeof(stateStr)))
-+ {
-+ ast_log(LOG_DEBUG, "ds_devicestate couldnt get state in astdb\n");
-+ return 0;
-+ }
-+ else
-+ {
-+ ast_log(LOG_DEBUG, "ds_devicestate dev=%s returning state %d\n",
-+ dest, atoi(stateStr));
-+ return (atoi(stateStr));
-+ }
-+}
-+
-+static struct ast_channel_tech devstate_tech = {
-+ .type = type,
-+ .description = tdesc,
-+ .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
-+ .devicestate = ds_devicestate,
-+ .requester = NULL,
-+ .send_digit_begin = NULL,
-+ .send_digit_end = NULL,
-+ .send_text = NULL,
-+ .call = NULL,
-+ .hangup = NULL,
-+ .answer = NULL,
-+ .read = NULL,
-+ .write = NULL,
-+ .bridge = NULL,
-+ .exception = NULL,
-+ .indicate = NULL,
-+ .fixup = NULL,
-+ .setoption = NULL,
-+};
-+
-+static char mandescr_devstate[] =
-+"Description: Put a value into astdb\n"
-+"Variables: \n"
-+" Family: ...\n"
-+" Key: ...\n"
-+" Value: ...\n";
-+
-+static int action_devstate(struct mansession *s, const struct message *m)
-+{
-+ const char *devstate = astman_get_header(m, "Devstate");
-+ const char *value = astman_get_header(m, "Value");
-+ const char *id = astman_get_header(m,"ActionID");
-+ char devName[128];
-+ char idText[256] = "";
-+
-+ if (!strlen(devstate)) {
-+ astman_send_error(s, m, "No Devstate specified");
-+ return 0;
-+ }
-+ if (!strlen(value)) {
-+ astman_send_error(s, m, "No Value specified");
-+ return 0;
-+ }
-+ if (!ast_strlen_zero(id))
-+ snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
-+
-+ if (!ast_db_put("DEVSTATES", devstate, (char *)value)) {
-+ snprintf(devName, sizeof(devName), "DS/%s", devstate);
-+ ast_device_state_changed_literal(devName);
-+ astman_append(s, "Response: Success\r\n%s\r\n", idText);
-+ } else {
-+ ast_log(LOG_DEBUG, "ast_db_put failed\n");
-+ astman_append(s, "Response: Failed\r\n%s\r\n", idText);
-+ }
-+ return 0;
-+}
-+
-+static int load_module(void)
-+{
-+ if (ast_channel_register(&devstate_tech)) {
-+ ast_log(LOG_DEBUG, "Unable to register channel class %s\n", type);
-+ return -1;
-+ }
-+ ast_cli_register(&cli_dev_state);
-+ ast_manager_register2( "Devstate", EVENT_FLAG_CALL, action_devstate, "Change a device state", mandescr_devstate );
-+ return ast_register_application(app, devstate_exec, synopsis, descrip);
-+}
-+
-+static int unload_module(void)
-+{
-+ int res = 0;
-+
-+ ast_module_user_hangup_all();
-+ ast_manager_unregister( "Devstate");
-+ ast_cli_unregister(&cli_dev_state);
-+ res = ast_unregister_application(app);
-+ ast_channel_unregister(&devstate_tech);
-+ return res;
-+}
-+
-+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Simple Devstate Application");
-+
---- /dev/null
-+++ b/configs/watchdog.conf.sample
-@@ -0,0 +1,22 @@
-+;
-+; Configuration file for res_watchdog
-+;
-+; type = isdnguard | watchdog
-+; device = /dev/...
-+; interval = interval to trigger the watchdog in ms
-+
-+;[ISDNguard-direct]
-+;type = isdnguard
-+;device = /dev/ttyS0
-+;interval = 200
-+
-+;[ISDNguard-with-daemon]
-+;type = isdnguard
-+;device = /var/run/guard.ctl
-+;interval = 200
-+
-+;[kernel_watchdog]
-+;type = watchdog
-+;device = /dev/watchdog
-+;interval = 100
-+
---- /dev/null
-+++ b/res/res_watchdog.c
-@@ -0,0 +1,137 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * Resource to make watchdogs happy
-+ *
-+ * Copyright (C) 2005, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include "asterisk.h"
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <sys/time.h>
-+#include <sys/signal.h>
-+#include <netinet/in.h>
-+
-+#include <asterisk/logger.h>
-+#include <asterisk/channel.h>
-+#include <asterisk/pbx.h>
-+#include <asterisk/options.h>
-+#include <asterisk/module.h>
-+#include <asterisk/translate.h>
-+#include <asterisk/say.h>
-+#include <asterisk/features.h>
-+#include <asterisk/musiconhold.h>
-+#include <asterisk/config.h>
-+#include <asterisk/cli.h>
-+#include <asterisk/manager.h>
-+#include <asterisk/utils.h>
-+#include <asterisk/lock.h>
-+#include <asterisk/adsi.h>
-+
-+static struct watchdog_pvt *watchdogs = NULL;
-+
-+typedef struct watchdog_pvt {
-+ char device[80];
-+ int fd;
-+ int type;
-+ int interval;
-+ pthread_t watchdog_thread;
-+ struct watchdog_pvt *next;
-+} watchdog_pvt;
-+
-+static void *do_watchdog_thread(void *data) {
-+ struct watchdog_pvt *woof = (struct watchdog_pvt *)data;
-+ for (;;) {
-+ if (woof->fd) {
-+ write(woof->fd, "PING\n", 5);
-+ }
-+ usleep(woof->interval * 1000);
-+ }
-+ return NULL;
-+}
-+
-+
-+static int load_module(void)
-+{
-+ int res = 0;
-+ const char *cat, *utype, *udevice, *uinterval;
-+ struct ast_config *cfg;
-+ struct watchdog_pvt *woof = NULL;
-+
-+ cfg = ast_config_load("watchdog.conf");
-+ if (cfg) {
-+ cat = ast_category_browse(cfg, NULL);
-+ while(cat) {
-+ cat = ast_category_browse(cfg, cat);
-+ utype = ast_variable_retrieve(cfg, cat, "type");
-+/* if (utype) {
-+ ast_log(LOG_NOTICE, "type = %s\n", utype);
-+ } */
-+ udevice = ast_variable_retrieve(cfg, cat, "device");
-+/* if (udevice) {
-+ ast_log(LOG_NOTICE, "device = %s\n", udevice);
-+ } */
-+ uinterval = ast_variable_retrieve(cfg, cat, "interval");
-+/* if (uinterval) {
-+ ast_log(LOG_NOTICE, "interval = %s\n", uinterval);
-+ } */
-+ if (uinterval && udevice && utype) {
-+ woof = malloc(sizeof(struct watchdog_pvt));
-+ if (!woof) {
-+ ast_log(LOG_ERROR, "unable to malloc!\n");
-+ return -1;
-+ }
-+ memset(woof, 0x0, sizeof(struct watchdog_pvt));
-+ strncpy(woof->device, udevice, sizeof(woof->device) - 1);
-+
-+ woof->interval = atoi(uinterval);;
-+ woof->next = watchdogs;
-+ watchdogs = woof;
-+ woof->fd = open(woof->device, O_WRONLY | O_SYNC);
-+ if (woof->fd) {
-+ if (!strncmp(utype, "isdnguard", sizeof(utype))) {
-+ woof->type = 1;
-+ write(woof->fd, "START\n", 6);
-+ }
-+ ast_pthread_create(&woof->watchdog_thread, NULL, do_watchdog_thread, woof);
-+ } else {
-+ ast_log(LOG_WARNING, "error opening watchdog device %s !\n", woof->device);
-+ }
-+ }
-+ }
-+ ast_config_destroy(cfg);
-+ }
-+ return res;
-+}
-+
-+
-+static int unload_module(void)
-+{
-+ struct watchdog_pvt *dogs, *woof;
-+ dogs = watchdogs;
-+ while (dogs) {
-+ pthread_cancel(dogs->watchdog_thread);
-+ pthread_join(dogs->watchdog_thread, NULL);
-+ close(dogs->fd);
-+ woof = dogs->next;
-+ free(dogs);
-+ dogs = woof;
-+ }
-+ return 0;
-+}
-+
-+
-+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Watchdog Resource",
-+ .load = load_module,
-+ .unload = unload_module,
-+);
---- a/main/db.c
-+++ b/main/db.c
-@@ -574,7 +574,7 @@ static int manager_dbget(struct mansessi
- astman_append(s, "Event: DBGetResponse\r\n"
- "Family: %s\r\n"
- "Key: %s\r\n"
-- "Val: %s\r\n"
-+ "Value: %s\r\n"
- "%s"
- "\r\n",
- family, key, tmp, idText);
-@@ -582,11 +582,35 @@ static int manager_dbget(struct mansessi
- return 0;
- }
-
-+static int manager_dbdel(struct mansession *s, const struct message *m)
-+{
-+ const char *family = astman_get_header(m, "Family");
-+ const char *key = astman_get_header(m, "Key");
-+
-+ if (!strlen(family)) {
-+ astman_send_error(s, m, "No family specified");
-+ return 0;
-+ }
-+ if (!strlen(key)) {
-+ astman_send_error(s, m, "No key specified");
-+ return 0;
-+ }
-+
-+ if (ast_db_del(family, key)) {
-+ astman_send_error(s, m, "Failed to delete entry");
-+ } else {
-+ astman_send_ack(s, m, "Deleted entry successfully");
-+ }
-+
-+ return 0;
-+}
-+
- int astdb_init(void)
- {
- dbinit();
- ast_cli_register_multiple(cli_database, sizeof(cli_database) / sizeof(struct ast_cli_entry));
-- ast_manager_register("DBGet", EVENT_FLAG_SYSTEM, manager_dbget, "Get DB Entry");
-- ast_manager_register("DBPut", EVENT_FLAG_SYSTEM, manager_dbput, "Put DB Entry");
-+ ast_manager_register("DBget", EVENT_FLAG_SYSTEM, manager_dbget, "Get DB Entry");
-+ ast_manager_register("DBput", EVENT_FLAG_SYSTEM, manager_dbput, "Put DB Entry");
-+ ast_manager_register("DBdel", EVENT_FLAG_SYSTEM, manager_dbdel, "Delete DB Entry");
- return 0;
- }
---- /dev/null
-+++ b/configs/esel.conf.sample
-@@ -0,0 +1,12 @@
-+;
-+; Configuration file for res_esel
-+;
-+
-+;[asterisk-2]
-+;host = 192.168.0.1
-+;port = 5038
-+;username = manager
-+;secret = donkey
-+
-+; export the extension snom in context phones to DS/100
-+;export => snom at phones,100
---- /dev/null
-+++ b/res/res_esel.c
-@@ -0,0 +1,384 @@
-+/*
-+ * Asterisk -- A telephony toolkit for Linux.
-+ *
-+ * Extension State Export Logic (E.S.E.L) (Sorry, i couldnt resist...)
-+ *
-+ * Resource to export extension states to other Asterisk servers
-+ *
-+ * Copyright (C) 2006, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ * This program is free software, distributed under the terms of
-+ * the GNU General Public License
-+ */
-+
-+#include "asterisk.h"
-+
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <sys/time.h>
-+#include <sys/signal.h>
-+#include <netinet/in.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+
-+#include "asterisk/file.h"
-+#include "asterisk/logger.h"
-+#include "asterisk/channel.h"
-+#include "asterisk/pbx.h"
-+#include "asterisk/options.h"
-+#include "asterisk/module.h"
-+#include "asterisk/translate.h"
-+#include "asterisk/say.h"
-+#include "asterisk/features.h"
-+#include "asterisk/musiconhold.h"
-+#include "asterisk/config.h"
-+#include "asterisk/cli.h"
-+#include "asterisk/manager.h"
-+#include "asterisk/utils.h"
-+#include "asterisk/lock.h"
-+#include "asterisk/adsi.h"
-+
-+
-+AST_MUTEX_DEFINE_STATIC(listlock);
-+
-+typedef struct esel_extension_state {
-+ char context[AST_MAX_EXTENSION];
-+ char exten[AST_MAX_EXTENSION];
-+ int state;
-+ char devstate[AST_MAX_EXTENSION];
-+ struct esel_extension_state *next;
-+ struct esel_extension_state *prev;
-+} esel_extension_state;
-+
-+typedef struct esel_export {
-+ char context[AST_MAX_EXTENSION];
-+ char exten[AST_MAX_EXTENSION];
-+ char devstate[AST_MAX_EXTENSION];
-+ struct esel_export *next;
-+} esel_export;
-+
-+typedef struct esel_queue {
-+ struct esel_extension_state *head;
-+ struct esel_extension_state *tail;
-+ int count;
-+ ast_cond_t cond;
-+ ast_mutex_t lock;
-+} esel_queue;
-+
-+typedef struct esel_pvt {
-+ char name[80];
-+ char username[80];
-+ char secret[80];
-+ char host[80];
-+ int port;
-+ struct sockaddr_in raddr;
-+ int sockfd;
-+ int connected;
-+ pthread_t esel_thread;
-+
-+ /* list of extensions to export */
-+ struct esel_export *extensions;
-+
-+ /* queue */
-+ struct esel_queue queue;
-+
-+ struct esel_pvt *next;
-+} esel_pvt;
-+
-+static struct esel_pvt *donkeys = NULL;
-+
-+static int esel_queue_extension_state(struct esel_queue *queue, char *context, char *exten, int state, void *data) {
-+ struct esel_extension_state *exstate = NULL;
-+
-+ exstate = malloc(sizeof(struct esel_extension_state));
-+ if (!exstate) {
-+ ast_log(LOG_ERROR, "Unable to malloc!\n");
-+ return 1;
-+ }
-+ memset(exstate,0,sizeof(struct esel_extension_state));
-+ exstate->next = NULL;
-+ exstate->prev = NULL;
-+
-+ ast_mutex_lock(&queue->lock);
-+ if (queue->count > 100) {
-+ ast_mutex_unlock(&queue->lock);
-+ free(exstate);
-+ if (option_verbose > 5)
-+ ast_log(LOG_WARNING, "E.S.E.L Queue too long.\n");
-+ return -1;
-+ }
-+ ast_copy_string(exstate->exten, exten, sizeof(exstate->exten));
-+ ast_copy_string(exstate->context, context, sizeof(exstate->context));
-+ exstate->state = state;
-+ if (!queue->head) {
-+ /* Empty queue */
-+ queue->head = exstate;
-+ queue->tail = exstate;
-+ } else {
-+ /* Double link */
-+ queue->tail->next = exstate;
-+ exstate->prev = queue->tail;
-+ queue->tail = exstate;
-+ }
-+ queue->count++;
-+ ast_cond_signal(&queue->cond);
-+ ast_mutex_unlock(&queue->lock);
-+ return 0;
-+}
-+
-+static int esel_is_exported(struct esel_export *extensions, struct esel_extension_state *exstate) {
-+ struct esel_export *export = NULL;
-+ export = extensions;
-+ while (export) {
-+ if ((!strcasecmp(export->exten, exstate->exten)) && (!strcasecmp(export->context, exstate->context))) {
-+ /* copy mapping */
-+ ast_copy_string(exstate->devstate, export->devstate, sizeof(exstate->devstate));
-+ return 1;
-+ }
-+ export = export->next;
-+ }
-+ return 0;
-+}
-+
-+static int esel_state2devstate(int state) {
-+ switch(state) {
-+ case 1:
-+ return 2;
-+ case 8:
-+ return 6;
-+ default:
-+ return state;
-+ }
-+}
-+
-+static void esel_export_to_remote(struct esel_extension_state *exstate, struct esel_pvt *esel) {
-+ char msg[1024];
-+ int sent = 0;
-+ memset(msg, 0x0, sizeof(msg));
-+ snprintf(msg, sizeof(msg) - 1, "Action: Devstate\r\nDevstate: %s\r\nValue: %d\r\n\r\n", exstate->devstate, esel_state2devstate(exstate->state));
-+ sent = send(esel->sockfd, msg, strlen(msg), 0);
-+ if (sent == -1) {
-+ esel->connected = 0;
-+ }
-+// ast_log(LOG_NOTICE, "%s", msg);
-+}
-+
-+static void *do_esel_thread(void *data) {
-+ struct esel_pvt *esel = (struct esel_pvt *)data;
-+ struct esel_queue *queue = &esel->queue;
-+ struct esel_extension_state *exstate = NULL;
-+ char msg[1024];
-+ char buf[1024];
-+ int numbytes = 0;
-+ int sent = 0;
-+ int res = 0;
-+ for (;;) {
-+ if (esel->connected) {
-+ ast_mutex_lock(&queue->lock);
-+ if (queue->count == 0)
-+ ast_cond_wait(&queue->cond, &queue->lock);
-+ exstate = queue->head;
-+ if (exstate) {
-+ if (exstate->next) {
-+ queue->head = exstate->next;
-+ } else {
-+ queue->head = NULL;
-+ queue->tail = NULL;
-+ }
-+ queue->count--;
-+ } else {
-+ ast_log(LOG_ERROR, "I SHOULD NEVER HAPPEN! EXPECT SOME MAJOR KABOOM! DUCK AND COVER!\n");
-+ }
-+ ast_mutex_unlock(&queue->lock);
-+
-+ if (exstate) {
-+ if (esel_is_exported(esel->extensions, exstate)) {
-+ esel_export_to_remote(exstate, esel);
-+ }
-+ free(exstate);
-+ exstate = NULL;
-+ }
-+ } else {
-+ if (esel->sockfd > 0)
-+ close(esel->sockfd);
-+ if ((esel->sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-+ ast_log(LOG_ERROR, "unable to request socket!\n");
-+ return NULL;
-+ }
-+ /* try to connect */
-+ res = connect(esel->sockfd, (struct sockaddr *)&esel->raddr, sizeof(struct sockaddr));
-+ if (res) {
-+ ast_log(LOG_NOTICE, "error connecting to %s:%d\n", esel->host, esel->port);
-+ } else {
-+ while (strncasecmp(buf, "Asterisk Call Manager:", 21)) {
-+ if ((numbytes=recv(esel->sockfd, buf, sizeof(buf), 0)) == -1) {
-+ esel->connected = 0;
-+ continue;
-+ }
-+ buf[numbytes] = '\0';
-+ // ast_log(LOG_NOTICE, "read: %s", buf);
-+ }
-+ /* log into remote manager */
-+ memset(msg, 0x0, sizeof(msg));
-+ snprintf(msg, sizeof(msg) - 1, "Action: Login\r\nUsername: %s\r\nSecret: %s\r\n\r\n", esel->username, esel->secret);
-+ sent = send(esel->sockfd, msg, strlen(msg), 0);
-+
-+ while (strncasecmp(buf, "Response:", 9)) {
-+ if ((numbytes=recv(esel->sockfd, buf, sizeof(buf), 0)) == -1) {
-+ continue;
-+ }
-+ buf[numbytes] = '\0';
-+ // ast_log(LOG_NOTICE, "read: %s", buf);
-+ }
-+
-+ if (!strncasecmp(buf, "Response: Success", 17)) {
-+ esel->connected = 1;
-+ } else {
-+ ast_log(LOG_ERROR, "error login into remote asterisk %s\n", esel->name);
-+ }
-+ }
-+ /* time heals everything... */
-+ sleep(10);
-+ }
-+ }
-+ return NULL;
-+}
-+
-+static int esel_state_cb(char *context, char *exten, int state, void *data) {
-+ struct esel_pvt *esel;
-+
-+ esel = donkeys;
-+ ast_mutex_lock(&listlock);
-+ while (esel) {
-+ esel_queue_extension_state(&esel->queue, context, exten, state, data);
-+ esel = esel->next;
-+ }
-+ ast_mutex_unlock(&listlock);
-+ return 0;
-+}
-+
-+
-+static int load_module(void)
-+{
-+ int res = 0;
-+ const char *cat, *host, *port, *username, *secret, *name;
-+ struct ast_config *cfg;
-+ struct ast_variable *var;
-+ struct esel_pvt *esel = NULL;
-+ struct esel_export *export = NULL;
-+ struct hostent *he;
-+ struct ast_hostent h;
-+
-+ cfg = ast_config_load("esel.conf");
-+ if (cfg) {
-+ cat = ast_category_browse(cfg, NULL);
-+ while(cat) {
-+ name = cat;
-+ host = ast_variable_retrieve(cfg, cat, "host");
-+ username = ast_variable_retrieve(cfg, cat, "username");
-+ secret = ast_variable_retrieve(cfg, cat, "secret");
-+ port = ast_variable_retrieve(cfg, cat, "port");
-+
-+ if (name && host && username && secret && port) {
-+ esel = malloc(sizeof(struct esel_pvt));
-+ if (!esel) {
-+ ast_log(LOG_ERROR, "unable to malloc!\n");
-+ return -1;
-+ }
-+ memset(esel, 0x0, sizeof(struct esel_pvt));
-+ ast_copy_string(esel->name, name, sizeof(esel->name));
-+ ast_copy_string(esel->host, host, sizeof(esel->host));
-+ ast_copy_string(esel->username, username, sizeof(esel->username));
-+ ast_copy_string(esel->secret, secret, sizeof(esel->secret));
-+
-+ esel->port = atoi(port);
-+ if ((he=ast_gethostbyname(host, &h)) == NULL) {
-+ ast_log(LOG_ERROR, "unknown host!\n");
-+ return -1;
-+ }
-+
-+ esel->raddr.sin_family = AF_INET;
-+ esel->raddr.sin_port = htons(esel->port);
-+ esel->raddr.sin_addr = *((struct in_addr *)he->h_addr);
-+ bzero(&(esel->raddr.sin_zero), 8);
-+
-+ esel->connected = 0;
-+
-+ ast_mutex_init(&esel->queue.lock);
-+ ast_cond_init(&esel->queue.cond, NULL);
-+
-+
-+ /* read exports */
-+ var = ast_variable_browse(cfg, cat);
-+ while (var) {
-+ if (!strcasecmp(var->name, "export")) {
-+ char *extenp = NULL, *contextp = NULL, *devstatep = NULL;
-+ extenp = var->value;
-+ devstatep = strchr(var->value, ',') + 1;
-+ contextp = strchr(var->value, '@') + 1;
-+ if (devstatep && contextp) {
-+ export = malloc(sizeof(struct esel_export));
-+ if (!export) {
-+ ast_log(LOG_ERROR, "unable to malloc!\n");
-+ return -1;
-+ }
-+ memset(export, 0x0, sizeof(struct esel_export));
-+ ast_copy_string(export->exten, extenp, contextp - extenp);
-+ ast_copy_string(export->context, contextp, devstatep - contextp);
-+ ast_copy_string(export->devstate, devstatep, sizeof(export->devstate));
-+ if (option_verbose > 2)
-+ ast_verbose(VERBOSE_PREFIX_3 "exporting %s @ %s as %s to %s\n", export->exten, export->context , export->devstate , esel->name);
-+ export->next = esel->extensions;
-+ esel->extensions = export;
-+ export = NULL;
-+ }
-+ }
-+ var = var->next;
-+ }
-+
-+
-+
-+ esel->next = donkeys;
-+ donkeys = esel;
-+
-+ ast_pthread_create(&esel->esel_thread, NULL, do_esel_thread, esel);
-+
-+ }
-+ cat = ast_category_browse(cfg, cat);
-+ }
-+ ast_config_destroy(cfg);
-+ }
-+ ast_extension_state_add(NULL, NULL, esel_state_cb, NULL);
-+ return res;
-+}
-+
-+
-+static int unload_module(void)
-+{
-+ struct esel_pvt *esel, *eseln;
-+ ast_module_user_hangup_all();
-+ esel = donkeys;
-+ ast_mutex_lock(&listlock);
-+ while (esel) {
-+ pthread_cancel(esel->esel_thread);
-+ pthread_join(esel->esel_thread, NULL);
-+ ast_mutex_destroy(&esel->queue.lock);
-+ close(esel->sockfd);
-+ eseln = esel->next;
-+ free(esel);
-+ esel = eseln;
-+ }
-+ ast_mutex_unlock(&listlock);
-+ return 0;
-+}
-+
-+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Extension State Export Logic (E.S.E.L.) Resource",
-+ .load = load_module,
-+ .unload = unload_module,
-+);
---- a/channels/chan_iax2.c
-+++ b/channels/chan_iax2.c
-@@ -11,6 +11,9 @@
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
-+ * Hangup cause signalling implementation by
-+ * Levent Guendogdu <levon at feature-it.com>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
-@@ -3362,7 +3365,7 @@ static int iax2_hangup(struct ast_channe
- ast_mutex_lock(&iaxsl[callno]);
- if (callno && iaxs[callno]) {
- if (option_debug)
-- ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
-+ ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
- alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
- /* Send the hangup unless we have had a transmission error or are already gone */
- iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
-@@ -3416,7 +3419,8 @@ static int iax2_setoption(struct ast_cha
-
- static struct ast_frame *iax2_read(struct ast_channel *c)
- {
-- ast_log(LOG_NOTICE, "I should never be called!\n");
-+ if (option_verbose > 3)
-+ ast_log(LOG_NOTICE, "I should never be called!\n");
- return &ast_null_frame;
- }
-
---- a/apps/app_zapras.c
-+++ b/apps/app_zapras.c
-@@ -183,7 +183,7 @@ static void run_ras(struct ast_channel *
- }
- }
- /* Throw back into audio mode */
-- x = 1;
-+ x = 0;
- ioctl(chan->fds[0], ZT_AUDIOMODE, &x);
-
- /* Restore saved values */
---- a/main/channel.c
-+++ b/main/channel.c
-@@ -3898,6 +3898,10 @@ enum ast_bridge_result ast_channel_bridg
- c1->name, c1->_bridge->name);
- return -1;
- }
-+
-+ if (IS_DIGITAL(c0->transfercapability) || IS_DIGITAL(c1->transfercapability)) {
-+ config->flags = 0;
-+ }
-
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
---- a/apps/app_meetme.c
-+++ b/apps/app_meetme.c
-@@ -1405,8 +1405,9 @@ static int conf_run(struct ast_channel *
- char members[10] = "";
- int dtmf, opt_waitmarked_timeout = 0;
- time_t timeout = 0;
-+ int dyna_buff = CONF_SIZE;
- ZT_BUFFERINFO bi;
-- char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
-+ char __buf[ZT_MAX_BUF_SPACE / ZT_DEFAULT_NUM_BUFS + AST_FRIENDLY_OFFSET];
- char *buf = __buf + AST_FRIENDLY_OFFSET;
- int setusercount = 0;
-
-@@ -1615,7 +1616,7 @@ static int conf_run(struct ast_channel *
- }
- /* Setup buffering information */
- memset(&bi, 0, sizeof(bi));
-- bi.bufsize = CONF_SIZE/2;
-+ bi.bufsize = dyna_buff / 2;
- bi.txbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.rxbufpolicy = ZT_POLICY_IMMEDIATE;
- bi.numbufs = audio_buffers;
-@@ -1926,6 +1927,14 @@ static int conf_run(struct ast_channel *
- f = ast_read(c);
- if (!f)
- break;
-+ if (f->datalen && f->datalen != dyna_buff) {
-+ ast_log(LOG_NOTICE, "Audio bytes: %d Buffer size: %d\n", f->datalen, dyna_buff);
-+ if (f->datalen < ZT_MAX_BUF_SPACE/audio_buffers) { /* skip too large frame to avoid overflow */
-+ dyna_buff = f->datalen;
-+ close(fd);
-+ goto zapretry;
-+ }
-+ }
- if ((f->frametype == AST_FRAME_VOICE) && (f->subclass == AST_FORMAT_SLINEAR)) {
- if (user->talk.actual)
- ast_frame_adjust_volume(f, user->talk.actual);
-Answer the channel before saying things (SayNumber, SayDigits,
-SayCharacters, SayPhonetic).
-
---- a/main/pbx.c
-+++ b/main/pbx.c
-@@ -6076,6 +6076,9 @@ static int pbx_builtin_saynumber(struct
- return -1;
- }
- }
-+ if (chan->_state != AST_STATE_UP) {
-+ ast_answer(chan);
-+ }
-
- if (ast_say_number(chan, atoi(tmp), "", chan->language, options)) {
- ast_log(LOG_WARNING, "We were unable to say the number %s, is it too large?\n", tmp);
-@@ -6088,8 +6091,12 @@ static int pbx_builtin_saydigits(struct
- {
- int res = 0;
-
-- if (data)
-+ if (data) {
-+ if (chan->_state != AST_STATE_UP) {
-+ ast_answer(chan);
-+ }
- res = ast_say_digit_str(chan, data, "", chan->language);
-+ }
- return res;
- }
-
-@@ -6097,8 +6104,12 @@ static int pbx_builtin_saycharacters(str
- {
- int res = 0;
-
-- if (data)
-+ if (data) {
-+ if (chan->_state != AST_STATE_UP) {
-+ ast_answer(chan);
-+ }
- res = ast_say_character_str(chan, data, "", chan->language);
-+ }
- return res;
- }
-
-@@ -6106,8 +6117,12 @@ static int pbx_builtin_sayphonetic(struc
- {
- int res = 0;
-
-- if (data)
-+ if (data) {
-+ if (chan->_state != AST_STATE_UP) {
-+ ast_answer(chan);
-+ }
- res = ast_say_phonetic_str(chan, data, "", chan->language);
-+ }
- return res;
- }
-
---- a/apps/app_dial.c
-+++ b/apps/app_dial.c
-@@ -11,6 +11,10 @@
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
-+ * Copyright (C) 2004, Junghanns.NET GmbH
-+ *
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
-@@ -130,7 +134,8 @@ static char *descrip =
- " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
- " i - Asterisk will ignore any forwarding requests it may receive on this\n"
- " dial attempt.\n"
--" j - Jump to priority n+101 if all of the requested channels were busy.\n"
-+" j - Jump to priority n+101 if the called party was busy.\n"
-+" Jump to priority n+201 if all of the requested channels were busy.\n"
- " k - Allow the called party to enable parking of the call by sending\n"
- " the DTMF sequence defined for call parking in features.conf.\n"
- " K - Allow the calling party to enable parking of the call by sending\n"
-@@ -1292,14 +1297,16 @@ static int dial_exec_full(struct ast_cha
- }
-
- if (!outgoing) {
-- strcpy(status, "CHANUNAVAIL");
-+ ast_copy_string(status, "CHANUNAVAIL", sizeof(status));
- if(fulldial == num_dialed) {
- res = -1;
- goto out;
- }
-+ /* See if there is a special message */
-+ ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
- } else {
- /* Our status will at least be NOANSWER */
-- strcpy(status, "NOANSWER");
-+ ast_copy_string(status, "NOANSWER", sizeof(status));
- if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
- moh = 1;
- if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
---- a/apps/app_dial.c
-+++ b/apps/app_dial.c
-@@ -71,6 +71,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi
- #include "asterisk/privacy.h"
- #include "asterisk/stringfields.h"
- #include "asterisk/global_datastores.h"
-+#include "asterisk/transcap.h"
-
- static char *app = "Dial";
-
-@@ -1652,23 +1653,25 @@ static int dial_exec_full(struct ast_cha
- ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
- if (play_to_callee)
- ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
-- if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
-+ if ((chan->transfercapability != AST_TRANS_CAP_DIGITAL) && (chan->transfercapability != AST_TRANS_CAP_RESTRICTED_DIGITAL)) {
-+ /* only non-digital calls are allowed to go through userspace */
-+ if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
- ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
-- if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
-+ if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
- ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
-- if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
-+ if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
- ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
-- if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
-+ if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
- ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
-- if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
-+ if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
- ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
-- if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
-+ if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
- ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
-- if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
-+ if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
- ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
-- if (ast_test_flag(peerflags, OPT_CALLER_PARK))
-+ if (ast_test_flag(peerflags, OPT_CALLER_PARK))
- ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
--
-+ }
- config.timelimit = timelimit;
- config.play_warning = play_warning;
- config.warning_freq = warning_freq;
---- a/apps/app_dial.c
-+++ b/apps/app_dial.c
-@@ -198,6 +198,8 @@ static char *descrip =
- " family/key is not specified.\n"
- " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
- " party until the called channel has answered.\n"
-+" R - indicate ringing to the calling party when the called party indicates\n"
-+" ringing, pass no audio until answered.\n"
- " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
- " answered the call.\n"
- " t - Allow the called party to transfer the calling party by sending the\n"
-@@ -254,6 +256,7 @@ enum {
- OPT_CALLEE_PARK = (1 << 25),
- OPT_CALLER_PARK = (1 << 26),
- OPT_IGNORE_FORWARDING = (1 << 27),
-+ OPT_NOINBAND = (1 << 28),
- } dial_exec_option_flags;
-
- #define DIAL_STILLGOING (1 << 30)
-@@ -297,6 +300,7 @@ AST_APP_OPTIONS(dial_exec_options, {
- AST_APP_OPTION('p', OPT_SCREENING),
- AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
- AST_APP_OPTION('r', OPT_RINGBACK),
-+ AST_APP_OPTION('R', OPT_NOINBAND),
- AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
- AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
- AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
-@@ -412,7 +416,7 @@ static struct ast_channel *wait_for_answ
- int orig = *to;
- struct ast_channel *peer = NULL;
- /* single is set if only one destination is enabled */
-- int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
-+ int single = (outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK | OPT_NOINBAND));
-
- if (single) {
- /* Turn off hold music, etc */
-@@ -633,7 +637,7 @@ static struct ast_channel *wait_for_answ
- /* Setup early media if appropriate */
- if (single && CAN_EARLY_BRIDGE(peerflags))
- ast_rtp_early_bridge(in, c);
-- if (!ast_test_flag(outgoing, OPT_RINGBACK))
-+ if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_NOINBAND))
- ast_indicate(in, AST_CONTROL_PROGRESS);
- break;
- case AST_CONTROL_VIDUPDATE:
-@@ -651,7 +655,7 @@ static struct ast_channel *wait_for_answ
- ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
- if (single && CAN_EARLY_BRIDGE(peerflags))
- ast_rtp_early_bridge(in, c);
-- if (!ast_test_flag(outgoing, OPT_RINGBACK))
-+ if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_NOINBAND))
- ast_indicate(in, AST_CONTROL_PROCEEDING);
- break;
- case AST_CONTROL_HOLD:
-@@ -669,7 +673,7 @@ static struct ast_channel *wait_for_answ
- /* Ignore going off hook and flash */
- break;
- case -1:
-- if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
-+ if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK | OPT_NOINBAND)) {
- if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
- ast_indicate(in, -1);
-@@ -1091,7 +1095,7 @@ static int dial_exec_full(struct ast_cha
- outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
- }
-
-- ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
-+ ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_NOINBAND);
- /* loop through the list of dial destinations */
- rest = args.peers;
- while ((cur = strsep(&rest, "&")) ) {
-@@ -1116,7 +1120,7 @@ static int dial_exec_full(struct ast_cha
- OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
- OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
- OPT_CALLEE_PARK | OPT_CALLER_PARK |
-- OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
-+ OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID | OPT_NOINBAND);
- ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
- }
- ast_copy_string(numsubst, number, sizeof(numsubst));
-@@ -1319,7 +1323,7 @@ static int dial_exec_full(struct ast_cha
- ast_moh_start(chan, NULL, NULL);
- }
- ast_indicate(chan, AST_CONTROL_PROGRESS);
-- } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
-+ } else if (ast_test_flag(outgoing, OPT_RINGBACK | OPT_NOINBAND)) {
- ast_indicate(chan, AST_CONTROL_RINGING);
- sentringing++;
- }
-@@ -1442,7 +1446,7 @@ static int dial_exec_full(struct ast_cha
-
- if (ast_test_flag(&opts, OPT_MUSICBACK)) {
- ast_moh_stop(chan);
-- } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
-+ } else if (ast_test_flag(&opts, OPT_RINGBACK | OPT_NOINBAND)) {
- ast_indicate(chan, -1);
- sentringing=0;
- }
---- a/apps/app_dial.c
-+++ b/apps/app_dial.c
-@@ -201,7 +201,8 @@ static char *descrip =
- " R - indicate ringing to the calling party when the called party indicates\n"
- " ringing, pass no audio until answered.\n"
- " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
--" answered the call.\n"
-+" answered the call.\n"
-+" c - callback initiation, ring once and hangup.\n"
- " t - Allow the called party to transfer the calling party by sending the\n"
- " DTMF sequence defined in features.conf.\n"
- " T - Allow the calling party to transfer the called party by sending the\n"
-@@ -257,6 +258,7 @@ enum {
- OPT_CALLER_PARK = (1 << 26),
- OPT_IGNORE_FORWARDING = (1 << 27),
- OPT_NOINBAND = (1 << 28),
-+ OPT_CALLBACK_INIT = (1 << 29),
- } dial_exec_option_flags;
-
- #define DIAL_STILLGOING (1 << 30)
-@@ -301,6 +303,7 @@ AST_APP_OPTIONS(dial_exec_options, {
- AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
- AST_APP_OPTION('r', OPT_RINGBACK),
- AST_APP_OPTION('R', OPT_NOINBAND),
-+ AST_APP_OPTION('c', OPT_CALLBACK_INIT),
- AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
- AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
- AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
-@@ -621,14 +624,20 @@ static struct ast_channel *wait_for_answ
- HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
- break;
- case AST_CONTROL_RINGING:
-- if (option_verbose > 2)
-+ if (ast_test_flag(peerflags, OPT_CALLBACK_INIT)) {
-+ if (option_verbose > 2)
-+ ast_verbose( VERBOSE_PREFIX_3 "%s is ringing, hanging up.\n", o->chan->name);
-+ return NULL;
-+ } else {
-+ if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
-- /* Setup early media if appropriate */
-- if (single && CAN_EARLY_BRIDGE(peerflags))
-+ /* Setup early media if appropriate */
-+ if (single && CAN_EARLY_BRIDGE(peerflags))
- ast_rtp_early_bridge(in, c);
-- if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
-+ if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
- ast_indicate(in, AST_CONTROL_RINGING);
- (*sentringing)++;
-+ }
- }
- break;
- case AST_CONTROL_PROGRESS:
-@@ -1095,7 +1104,7 @@ static int dial_exec_full(struct ast_cha
- outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
- }
-
-- ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_NOINBAND);
-+ ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_CALLBACK_INIT | OPT_NOINBAND);
- /* loop through the list of dial destinations */
- rest = args.peers;
- while ((cur = strsep(&rest, "&")) ) {
-# Allow as many spans as Zaptel can take (defualt: 128).
-# There is a static array of zt_pris allocated at this size.
-# For that reason upstream only sort-of merged it: made it a
-# compile-time option in 1.6 .
-
---- a/channels/chan_zap.c
-+++ b/channels/chan_zap.c
-@@ -190,7 +190,7 @@ static const char config[] = "zapata.con
- #define SIG_GR303FXOKS (0x0100000 | ZT_SIG_FXOKS)
- #define SIG_GR303FXSKS (0x0100000 | ZT_SIG_FXSKS)
-
--#define NUM_SPANS 32
-+#define NUM_SPANS ZT_MAX_SPANS
- #define NUM_DCHANS 4 /*!< No more than 4 d-channels */
- #define MAX_CHANNELS 672 /*!< No more than a DS3 per trunk group */
-
---- a/include/asterisk/channel.h
-+++ b/include/asterisk/channel.h
-@@ -435,6 +435,7 @@ struct ast_channel {
- unsigned int flags; /*!< channel flags of AST_FLAG_ type */
- unsigned short transfercapability; /*!< ISDN Transfer Capbility - AST_FLAG_DIGITAL is not enough */
- AST_LIST_HEAD_NOLOCK(, ast_frame) readq;
-+ char lowlayercompat[16]; /*!< ISDN Low Layer Compatibility */
- int alertpipe[2];
-
- int nativeformats; /*!< Kinds of data this channel can natively handle */
---- a/channels/chan_zap.c
-+++ b/channels/chan_zap.c
-@@ -11,6 +11,10 @@
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
-+ * Copyright (C) 2003-2006 Junghanns.NET GmbH
-+ * Klaus-Peter Junghanns <kpj at junghanns.net>
-+ *
-+ *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
-@@ -216,8 +220,6 @@ static struct ast_channel inuse;
- #ifdef PRI_GETSET_TIMERS
- static int pritimers[PRI_MAX_TIMERS];
- #endif
--static int pridebugfd = -1;
--static char pridebugfilename[1024] = "";
- #endif
-
- /*! \brief Wait up to 16 seconds for first digit (FXO logic) */
-@@ -235,10 +237,6 @@ AST_MUTEX_DEFINE_STATIC(iflock);
-
- static int ifcount = 0;
-
--#ifdef HAVE_PRI
--AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
--#endif
--
- /*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
- when it's doing something critical. */
- AST_MUTEX_DEFINE_STATIC(monlock);
-@@ -253,6 +251,7 @@ static enum ast_bridge_result zt_bridge(
-
- static int zt_sendtext(struct ast_channel *c, const char *text);
-
-+
- /*! \brief Avoid the silly zt_getevent which ignores a bunch of events */
- static inline int zt_get_event(int fd)
- {
-@@ -297,6 +296,14 @@ static int ringt_base = DEFAULT_RINGT;
- #define PRI_SPAN(p) (((p) >> 8) & 0xff)
- #define PRI_EXPLICIT(p) (((p) >> 16) & 0x01)
-
-+struct zt_suspended_call {
-+ ast_mutex_t lock; /* Mutex */
-+ char msn[AST_MAX_EXTENSION]; /* the MSN to which this parked call belongs */
-+ char callid[10]; /* the callID provided by the user */
-+ int parked_at; /* extension in the call parking context */
-+ struct zt_suspended_call *next;
-+};
-+
- struct zt_pri {
- pthread_t master; /*!< Thread of master */
- ast_mutex_t lock; /*!< Mutex */
-@@ -310,6 +317,8 @@ struct zt_pri {
- int nsf; /*!< Network-Specific Facilities */
- int dialplan; /*!< Dialing plan */
- int localdialplan; /*!< Local dialing plan */
-+ char nocid[AST_MAX_EXTENSION]; /*!< CallerID string to use if none provided */
-+ char withheldcid[AST_MAX_EXTENSION]; /*!< CallerID string to use if CallerID is withheld */
- char internationalprefix[10]; /*!< country access code ('00' for european dialplans) */
- char nationalprefix[10]; /*!< area access code ('0' for european dialplans) */
- char localprefix[20]; /*!< area access code + area code ('0'+area code for european dialplans) */
-@@ -321,6 +330,7 @@ struct zt_pri {
- int prilogicalspan; /*!< Logical span number within trunk group */
- int numchans; /*!< Num of channels we represent */
- int overlapdial; /*!< In overlap dialing mode */
-+ int usercid;
- int facilityenable; /*!< Enable facility IEs */
- struct pri *dchans[NUM_DCHANS]; /*!< Actual d-channels */
- int dchanavail[NUM_DCHANS]; /*!< Whether each channel is available */
-@@ -336,6 +346,8 @@ struct zt_pri {
- struct zt_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */
- struct zt_pvt *crvs; /*!< Member CRV structs */
- struct zt_pvt *crvend; /*!< Pointer to end of CRV structs */
-+ struct zt_suspended_call *suspended_calls; /* Calls parked with SUSPEND messages */
-+ int debugfd;
- };
-
-
-@@ -453,6 +465,8 @@ static struct zt_pvt {
- unsigned int echocanbridged:1;
- unsigned int echocanon:1;
- unsigned int faxhandled:1; /*!< Has a fax tone already been handled? */
-+ /*!< KPJ: i will abuse this flag to implement a zapata option for dialing out
-+ on a zap channel with EC to be off no matter what happens. */
- unsigned int firstradio:1;
- unsigned int hanguponpolarityswitch:1;
- unsigned int hardwaredtmf:1;
-@@ -467,7 +481,8 @@ static struct zt_pvt {
- unsigned int overlapdial:1;
- unsigned int permcallwaiting:1;
- unsigned int permhidecallerid:1; /*!< Whether to hide our outgoing caller ID or not */
-- unsigned int priindication_oob:1;
-+ unsigned int priindication_oob:2;
-+ unsigned int pritransfer:2;
- unsigned int priexclusive:1;
- unsigned int pulse:1;
- unsigned int pulsedial:1; /*!< whether a pulse dial phone is detected */
-@@ -504,6 +519,7 @@ static struct zt_pvt {
- #endif
- char cid_num[AST_MAX_EXTENSION];
- int cid_ton; /*!< Type Of Number (TON) */
-+ int cid_pres; /*!< Calling Presentation */
- char cid_name[AST_MAX_EXTENSION];
- char lastcid_num[AST_MAX_EXTENSION];
- char lastcid_name[AST_MAX_EXTENSION];
-@@ -569,6 +585,8 @@ static struct zt_pvt {
- struct zt_pvt *bearer;
- struct zt_pvt *realcall;
- q931_call *call;
-+ int tei; /* channel in use by this tei */
-+ q931_call *holdedcall;
- int prioffset;
- int logicalspan;
- #endif
-@@ -614,11 +632,14 @@ static struct zt_chan_conf zt_chan_conf_
- .minunused = 2,
- .idleext = "",
- .idledial = "",
-+ .nocid = "No CID available",
-+ .withheldcid = "CID withheld",
- .internationalprefix = "",
- .nationalprefix = "",
- .localprefix = "",
- .privateprefix = "",
- .unknownprefix = "",
-+ .usercid = 0,
-
- .resetinterval = 3600
- },
-@@ -630,6 +651,8 @@ static struct zt_chan_conf zt_chan_conf_
- .mohinterpret = "default",
- .mohsuggest = "",
- .transfertobusy = 1,
-+ .priindication_oob = 0,
-+ .pritransfer = 0,
-
- .cid_signalling = CID_SIG_BELL,
- .cid_start = CID_START_RING,
-@@ -684,6 +707,8 @@ static int zt_indicate(struct ast_channe
- static int zt_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
- static int zt_setoption(struct ast_channel *chan, int option, void *data, int datalen);
- static int zt_func_read(struct ast_channel *chan, char *function, char *data, char *buf, size_t len);
-+static void enable_dtmf_detect(struct zt_pvt *p);
-+static void disable_dtmf_detect(struct zt_pvt *p);
-
- static const struct ast_channel_tech zap_tech = {
- .type = "Zap",
-@@ -715,6 +740,13 @@ static const struct ast_channel_tech zap
- struct zt_pvt *round_robin[32];
-
- #ifdef HAVE_PRI
-+struct app_tmp {
-+ char app[256];
-+ char data[256];
-+ struct ast_channel *chan;
-+ pthread_t t;
-+};
-+
- static inline int pri_grab(struct zt_pvt *pvt, struct zt_pri *pri)
- {
- int res;
-@@ -1417,12 +1449,16 @@ static void zt_enable_ec(struct zt_pvt *
- int res;
- if (!p)
- return;
-+ if (p->faxhandled) {
-+ ast_log(LOG_DEBUG, "Not enabling echo cancellation on a fax/modem call\n");
-+ return;
-+ }
- if (p->echocanon) {
- ast_log(LOG_DEBUG, "Echo cancellation already on\n");
- return;
- }
- if (p->digital) {
-- ast_log(LOG_DEBUG, "Echo cancellation isn't required on digital connection\n");
-+ ast_log(LOG_DEBUG, "Echo cancellation does not make any sense on digital connections!\n");
- return;
- }
- if (p->echocancel) {
-@@ -1449,7 +1485,7 @@ static void zt_train_ec(struct zt_pvt *p
- {
- int x;
- int res;
-- if (p && p->echocancel && p->echotraining) {
-+ if (p && p->echocancel && p->echotraining && (!p->digital) && (!p->faxhandled)) {
- x = p->echotraining;
- res = ioctl(p->subs[SUB_REAL].zfd, ZT_ECHOTRAIN, &x);
- if (res)
-@@ -1810,7 +1846,12 @@ static int zt_call(struct ast_channel *a
- ast_log(LOG_WARNING, "Unable to flush input on channel %d\n", p->channel);
- p->outgoing = 1;
-
-- set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
-+ if (IS_DIGITAL(ast->transfercapability)) {
-+ set_actual_gain(p->subs[SUB_REAL].zfd, 0, 0, 0, p->law);
-+ } else {
-+ set_actual_gain(p->subs[SUB_REAL].zfd, 0, p->rxgain, p->txgain, p->law);
-+ }
-+
-
- mysig = p->sig;
- if (p->outsigmod > -1)
-@@ -2041,6 +2082,7 @@ static int zt_call(struct ast_channel *a
- case SIG_PRI:
- /* We'll get it in a moment -- but use dialdest to store pre-setup_ack digits */
- p->dialdest[0] = '\0';
-+ disable_dtmf_detect(p);
- break;
- default:
- ast_log(LOG_DEBUG, "not yet implemented\n");
-@@ -2061,6 +2103,12 @@ static int zt_call(struct ast_channel *a
- const char *rr_str;
- int redirect_reason;
-
-+ if ((p->pri->nodetype == BRI_NETWORK_PTMP) || (p->pri->nodetype == BRI_NETWORK)) {
-+ // pass NO audio when ringing an isdn phone
-+ p->dialing = 1;
-+ // maybe we could allow passing audio when calling a p2p PBX, but well... ;-)
-+ }
-+
- c = strchr(dest, '/');
- if (c)
- c++;
-@@ -2083,6 +2131,7 @@ static int zt_call(struct ast_channel *a
- ast_mutex_unlock(&p->lock);
- return -1;
- }
-+ strncpy(p->dnid, (c + p->stripmsd), sizeof(p->dnid)-1);
- if (mysig != SIG_FXSKS) {
- p->dop.op = ZT_DIAL_OP_REPLACE;
- s = strchr(c + p->stripmsd, 'w');
-@@ -2106,6 +2155,8 @@ static int zt_call(struct ast_channel *a
- pri_rel(p->pri);
- ast_mutex_unlock(&p->lock);
- return -1;
-+ } else {
-+ // ast_log(LOG_NOTICE, "call %d\n", p->call);
- }
- if (!(sr = pri_sr_new())) {
- ast_log(LOG_WARNING, "Failed to allocate setup request channel %d\n", p->channel);
-@@ -2135,7 +2186,7 @@ static int zt_call(struct ast_channel *a
- pri_sr_set_channel(sr, p->bearer ? PVT_TO_CHANNEL(p->bearer) : PVT_TO_CHANNEL(p), exclusive, 1);
- pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast->transfercapability,
- (p->digital ? -1 :
-- ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)));
-+ ((p->law == ZT_LAW_ALAW) ? PRI_LAYER_1_ALAW : PRI_LAYER_1_ULAW)), ast->lowlayercompat);
- if (p->pri->facilityenable)
- pri_facility_enable(p->pri->pri);
-
-@@ -2399,8 +2450,10 @@ static int pri_find_dchan(struct zt_pri
- }
- if (newslot < 0) {
- newslot = 0;
-- ast_log(LOG_WARNING, "No D-channels available! Using Primary channel %d as D-channel anyway!\n",
-+ if (pri->nodetype != BRI_CPE_PTMP) {
-+ ast_log(LOG_WARNING, "No D-channels available! Using Primary channel %d as D-channel anyway!\n",
- pri->dchannels[newslot]);
-+ }
- }
- if (old && (oldslot != newslot))
- ast_log(LOG_NOTICE, "Switching from from d-channel %d to channel %d!\n",
-@@ -2410,6 +2463,16 @@ static int pri_find_dchan(struct zt_pri
- }
- #endif
-
-+static int zt_setlaw(int zfd, int law)
-+{
-+ int res;
-+ res = ioctl(zfd, ZT_SETLAW, &law);
-+ if (res)
-+ return res;
-+ return 0;
-+}
-+
-+
- static int zt_hangup(struct ast_channel *ast)
- {
- int res;
-@@ -2457,8 +2520,7 @@ static int zt_hangup(struct ast_channel
- if (option_debug)
- ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
- p->channel, index, p->subs[SUB_REAL].zfd, p->subs[SUB_CALLWAIT].zfd, p->subs[SUB_THREEWAY].zfd);
-- p->ignoredtmf = 0;
--
-+
- if (index > -1) {
- /* Real channel, do some fixup */
- p->subs[index].owner = NULL;
-@@ -2560,6 +2622,7 @@ static int zt_hangup(struct ast_channel
- }
-
- if (!p->subs[SUB_REAL].owner && !p->subs[SUB_CALLWAIT].owner && !p->subs[SUB_THREEWAY].owner) {
-+ int outgoing = p->outgoing;
- p->owner = NULL;
- p->ringt = 0;
- p->distinctivering = 0;
-@@ -2602,7 +2665,7 @@ static int zt_hangup(struct ast_channel
- pri_call_set_useruser(p->call, useruser);
- #endif
-
-- pri_hangup(p->pri->pri, p->call, -1);
-+ pri_hangup(p->pri->pri, p->call, -1, -1);
- p->call = NULL;
- if (p->bearer)
- p->bearer->call = NULL;
-@@ -2622,7 +2685,28 @@ static int zt_hangup(struct ast_channel
- if (atoi(cause))
- icause = atoi(cause);
- }
-- pri_hangup(p->pri->pri, p->call, icause);
-+
-+ pri_hangup(p->pri->pri, p->call, icause, -1);
-+
-+ /* if we send a rel9999ease complete we wont ge no hangup event, so clear the call here */
-+ if (icause == 34 || icause == 44 || icause == 82 || icause == 1 || icause == 81 || icause == 17) {
-+ if ((ast->_state == AST_STATE_RING) || (ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING) || (ast->_state == AST_STATE_RESERVED)) {
-+ p->call = NULL;
-+ } else {
-+ ast_log(LOG_ERROR, "What is wrong with you? You cannot use cause %d number when in state %d!\n", icause, ast->_state);
-+ icause = 16; /* Note, in pri_hangup() libpri will already override the cause */
-+ }
-+ }
-+
-+ if (p->pri->nodetype == BRI_NETWORK_PTMP) {
-+ if ((icause == 16 || icause == -1) && (ast->_state != AST_STATE_UP)) {
-+ if (outgoing) {
-+ p->call = NULL;
-+ }
-+ }
-+ }
-+
-+
- }
- if (res < 0)
- ast_log(LOG_WARNING, "pri_disconnect failed\n");
-@@ -2806,10 +2890,14 @@ static int zt_answer(struct ast_channel
- p->proceeding = 1;
- res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
- pri_rel(p->pri);
-+ /* stop ignoring inband dtmf */
-+ enable_dtmf_detect(p);
- } else {
- ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
- res = -1;
- }
-+ /* the audio path is complete now, train the echo canceler */
-+ zt_train_ec(p);
- break;
- #endif
- case 0:
-@@ -3446,6 +3534,15 @@ static int zt_fixup(struct ast_channel *
- {
- struct zt_pvt *p = newchan->tech_pvt;
- int x;
-+ if (newchan && newchan->tech_pvt) {
-+ p = newchan->tech_pvt;
-+ }
-+ if (!p) {
-+ if (newchan) {
-+ ast_log(LOG_ERROR, "channel %s has no tech_pvt structure\n", newchan->name);
-+ }
-+ return 0;
-+ }
- ast_mutex_lock(&p->lock);
- ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
- if (p->owner == oldchan) {
-@@ -3655,8 +3752,10 @@ static void zt_handle_dtmfup(struct ast_
- pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
- if (ast_async_goto(ast, target_context, "fax", 1))
- ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
-- } else
-+ } else {
-+ if (option_verbose > 2)
- ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
-+ }
- } else if (option_debug)
- ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
- } else if (option_debug)
-@@ -3815,7 +3914,7 @@ static struct ast_frame *zt_handle_event
- if (p->call) {
- if (p->pri && p->pri->pri) {
- if (!pri_grab(p, p->pri)) {
-- pri_hangup(p->pri->pri, p->call, -1);
-+ pri_hangup(p->pri->pri, p->call, -1, -1);
- pri_destroycall(p->pri->pri, p->call);
- p->call = NULL;
- pri_rel(p->pri);
-@@ -4886,7 +4985,7 @@ static struct ast_frame *zt_read(struct
- p->subs[index].f.data = NULL;
- p->subs[index].f.datalen= 0;
- }
-- if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) {
-+ if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress) && !index) {
- /* Perform busy detection. etc on the zap line */
- f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
- if (f) {
-@@ -4898,8 +4997,9 @@ static struct ast_frame *zt_read(struct
- }
- } else if (f->frametype == AST_FRAME_DTMF) {
- #ifdef HAVE_PRI
-- if (!p->proceeding && p->sig==SIG_PRI && p->pri && p->pri->overlapdial) {
-- /* Don't accept in-band DTMF when in overlap dial mode */
-+ if (p->sig==SIG_PRI && p->pri && p->pri->overlapdial && p->ignoredtmf) {
-+ /* Don't accept in-band DTMF when in overlap dial mode
-+ or when in non-overlap overlapdialing mode ... */
- f->frametype = AST_FRAME_NULL;
- f->subclass = 0;
- }
-@@ -4974,7 +5074,9 @@ static int zt_write(struct ast_channel *
- #endif
- /* Write a frame of (presumably voice) data */
- if (frame->frametype != AST_FRAME_VOICE) {
-- if (frame->frametype != AST_FRAME_IMAGE)
-+ if (frame->frametype == AST_FRAME_TEXT) {
-+ ast_log(LOG_NOTICE, "text\n");
-+ } else if (frame->frametype != AST_FRAME_IMAGE)
- ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
- return 0;
- }
-@@ -5042,7 +5144,7 @@ static int zt_indicate(struct ast_channe
- switch (condition) {
- case AST_CONTROL_BUSY:
- #ifdef HAVE_PRI
-- if (p->priindication_oob && p->sig == SIG_PRI) {
-+ if ((p->priindication_oob == 1) && p->sig == SIG_PRI) {
- chan->hangupcause = AST_CAUSE_USER_BUSY;
- chan->_softhangup |= AST_SOFTHANGUP_DEV;
- res = 0;
-@@ -5124,7 +5226,7 @@ static int zt_indicate(struct ast_channe
- case AST_CONTROL_CONGESTION:
- chan->hangupcause = AST_CAUSE_CONGESTION;
- #ifdef HAVE_PRI
-- if (p->priindication_oob && p->sig == SIG_PRI) {
-+ if ((p->priindication_oob == 1) && p->sig == SIG_PRI) {
- chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
- chan->_softhangup |= AST_SOFTHANGUP_DEV;
- res = 0;
-@@ -5321,8 +5423,12 @@ static struct ast_channel *zt_new(struct
- if (state == AST_STATE_RING)
- tmp->rings = 1;
- tmp->tech_pvt = i;
-+#ifdef HAVE_PRI
-+ if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS) || (i->sig == SIG_PRI)) {
-+#else
- if ((i->sig == SIG_FXOKS) || (i->sig == SIG_FXOGS) || (i->sig == SIG_FXOLS)) {
-- /* Only FXO signalled stuff can be picked up */
-+#endif
<Skipped 5458 lines>
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/asterisk.git/commitdiff/353c2faa173186278727315a04fc22dd8863457e
More information about the pld-cvs-commit
mailing list