[asterisk-commits] jdixon: branch 1.4 r77846 - /branches/1.4/apps/app_rpt.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 31 16:09:40 CDT 2007
Author: jdixon
Date: Tue Jul 31 16:09:39 2007
New Revision: 77846
URL: http://svn.digium.com/view/asterisk?view=rev&rev=77846
Log:
Much newer version, 0.70 with much additions
Modified:
branches/1.4/apps/app_rpt.c
Modified: branches/1.4/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_rpt.c?view=diff&rev=77846&r1=77845&r2=77846
==============================================================================
--- branches/1.4/apps/app_rpt.c (original)
+++ branches/1.4/apps/app_rpt.c Tue Jul 31 16:09:39 2007
@@ -1,7 +1,9 @@
+/* #define OLD_ASTERISK */
+#define OLDKEY
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 2002-2005, Jim Dixon, WB6NIL
+ * Copyright (C) 2002-2007, Jim Dixon, WB6NIL
*
* Jim Dixon, WB6NIL <jim at lambdatel.com>
* Serious contributions by Steve RoDgers, WA6ZFT <hwstar at rodgers.sdcoxmail.com>
@@ -20,7 +22,7 @@
/*! \file
*
* \brief Radio Repeater / Remote Base program
- * version 0.48 06/13/06
+ * version 0.70 07/22/07
*
* \author Jim Dixon, WB6NIL <jim at lambdatel.com>
*
@@ -60,9 +62,23 @@
* 1 - System warm boot
* 2 - System enable
* 3 - System disable
- * 4 - Test Tone On
+ * 4 - Test Tone On/Off
* 5 - Dump System Variables on Console (debug)
* 6 - PTT (phone mode only)
+ * 7 - Time out timer enable
+ * 8 - Time out timer disable
+ * 9 - Autopatch enable
+ * 10 - Autopatch disable
+ * 11 - Link enable
+ * 12 - Link disable
+ * 13 - Query System State
+ * 14 - Change System State
+ * 15 - Scheduler Enable
+ * 16 - Scheduler Disable
+ * 17 - User functions (time, id, etc) enable
+ * 18 - User functions (time, id, etc) disable
+ * 19 - Select alternate hang timer
+ * 20 - Select standard hang timer
*
* ilink cmds:
*
@@ -72,6 +88,12 @@
* 4 - Enter command mode on specified link
* 5 - System status
* 6 - Disconnect all links
+ * 11 - Disconnect a previously permanently connected link
+ * 12 - Permanently connect specified link -- monitor only
+ * 13 - Permanently connect specified link -- tranceive
+ * 15 - Full system status (all nodes)
+ * 16 - Reconnect links disconnected with "disconnect all links"
+ * 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
*
* remote cmds:
*
@@ -102,7 +124,7 @@
* 118 - Scan Up Fast
* 119 - Transmit allowing auto-tune
* 140 - Link Status (brief)
- *
+ * 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
*
*
* 'duplex' modes: (defaults to duplex=2)
@@ -133,9 +155,17 @@
#define MAXDTMF 32
#define MAXMACRO 2048
+#define MAXLINKLIST 512
+#define LINKLISTTIME 10000
+#define LINKLISTSHORTTIME 200
#define MACROTIME 100
#define MACROPTIME 500
#define DTMF_TIMEOUT 3
+#define KENWOOD_RETRIES 5
+
+#define AUTHTELLTIME 7000
+#define AUTHTXTIME 1000
+#define AUTHLOGOUTTIME 25000
#ifdef __RPT_NOTCH
#define MAXFILTERS 10
@@ -143,10 +173,13 @@
#define DISC_TIME 10000 /* report disc after 10 seconds of no connect */
#define MAX_RETRIES 5
+#define MAX_RETRIES_PERM 1000000000
#define REDUNDANT_TX_TIME 2000
#define RETRY_TIMER_MS 5000
+
+#define START_DELAY 10
#define MAXPEERSTR 31
#define MAXREMSTR 15
@@ -154,7 +187,16 @@
#define DELIMCHR ','
#define QUOTECHR 34
+#define MONITOR_DISK_BLOCKS_PER_MINUTE 38
+
+#define DEFAULT_MONITOR_MIN_DISK_BLOCKS 10000
+#define DEFAULT_REMOTE_INACT_TIMEOUT (15 * 60)
+#define DEFAULT_REMOTE_TIMEOUT (60 * 60)
+#define DEFAULT_REMOTE_TIMEOUT_WARNING (3 * 60)
+#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ 30
+
#define NODES "nodes"
+#define EXTNODES "extnodes"
#define MEMORY "memory"
#define MACRO "macro"
#define FUNCTIONS "functions"
@@ -162,9 +204,12 @@
#define MORSE "morse"
#define FUNCCHAR '*'
#define ENDCHAR '#'
+#define EXTNODEFILE "/var/lib/asterisk/rpt_extnodes"
#define DEFAULT_IOBASE 0x378
+#define DEFAULT_CIV_ADDR 0x58
+
#define MAXCONNECTTIME 5000
#define MAXNODESTR 300
@@ -177,23 +222,31 @@
#define REM_SCANTIME 100
+#define DTMF_LOCAL_TIME 250
+#define DTMF_LOCAL_STARTTIME 500
+
+#define IC706_PL_MEMORY_OFFSET 50
enum {REM_OFF,REM_MONITOR,REM_TX};
enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME,
STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH,
- TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY};
+ TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY, FULLSTATUS,
+ MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS,
+ REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE,
+ TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX};
+
enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
enum {REM_LOWPWR,REM_MEDPWR,REM_HIPWR};
-enum {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_DOKEY};
+enum {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY};
enum {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE};
-enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM};
+enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM, DLY_COMP, DLY_LINKUNKEY};
enum {REM_MODE_FM,REM_MODE_USB,REM_MODE_LSB,REM_MODE_AM};
@@ -220,9 +273,15 @@
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/io.h>
+#include <sys/vfs.h>
#include <math.h>
+#ifdef OLD_ASTERISK
+#include <linux/zaptel.h>
+#include <tonezone.h>
+#else
#include <zaptel/zaptel.h>
#include <zaptel/tonezone.h>
+#endif
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -241,6 +300,15 @@
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
+#include "asterisk/cdr.h"
+#include <termios.h>
+
+/* Start a tone-list going */
+int ast_playtones_start(struct ast_channel *chan, int vol, const char* tonelist, int interruptible);
+/*! Stop the tones from playing */
+void ast_playtones_stop(struct ast_channel *chan);
+
+static char *tdesc = "Radio Repeater / Remote Base version 0.70 07/22/2007";
static char *app = "Rpt";
@@ -281,20 +349,36 @@
" available to the phone user.\n"
"\n";
-static unsigned int vmajor = 0;
-static unsigned int vminor = 47;
-
-static int debug = 0; /* FIXME Set this >0 for extra debug output */
+static int debug = 0; /* Set this >0 for extra debug output */
static int nrpts = 0;
+
+static char remdtmfstr[] = "0123456789*#ABCD";
+
+enum {TOP_TOP,TOP_WON,WON_BEFREAD,BEFREAD_AFTERREAD};
+
+int max_chan_stat [] = {22000,1000,22000,100,22000,2000,22000};
+
+#define NRPTSTAT 7
+
+struct rpt_chan_stat
+{
+ struct timeval last;
+ long long total;
+ unsigned long count;
+ unsigned long largest;
+ struct timeval largest_time;
+};
char *discstr = "!!DISCONNECT!!";
static char *remote_rig_ft897="ft897";
static char *remote_rig_rbi="rbi";
+static char *remote_rig_kenwood="kenwood";
+static char *remote_rig_ic706="ic706";
#ifdef OLD_ASTERISK
STANDARD_LOCAL_USER;
+LOCAL_USER_DECL;
#endif
-
#define MSWAIT 200
#define HANGTIME 5000
@@ -305,6 +389,23 @@
#define POLITEID 30000
#define FUNCTDELAY 1500
+#define MAXXLAT 20
+#define MAXXLATTIME 3
+
+#define MAX_SYSSTATES 10
+
+struct rpt_xlat
+{
+char funccharseq[MAXXLAT];
+char endcharseq[MAXXLAT];
+char passchars[MAXXLAT];
+int funcindex;
+int endindex;
+time_t lastone;
+} ;
+
+static time_t starttime = 0;
+
static pthread_t rpt_master_thread;
struct rpt;
@@ -319,8 +420,11 @@
char name[MAXNODESTR]; /* identifier (routing) string */
char lasttx;
char lastrx;
+ char lastrx1;
char connected;
char hasconnected;
+ char perma;
+ char thisconnected;
char outbound;
char disced;
char killme;
@@ -328,11 +432,20 @@
long disctime;
long retrytimer;
long retxtimer;
+ long rerxtimer;
int retries;
+ int max_retries;
int reconnects;
long long connecttime;
struct ast_channel *chan;
struct ast_channel *pchan;
+ char linklist[MAXLINKLIST];
+ time_t linklistreceived;
+ long linklisttimer;
+ int dtmfed;
+ int linkunkeytocttimer;
+ struct ast_frame *lastf1,*lastf2;
+ struct rpt_chan_stat chan_stat[NRPTSTAT];
} ;
struct rpt_lstat
@@ -344,7 +457,9 @@
char mode;
char outbound;
char reconnects;
+ char thisconnected;
long long connecttime;
+ struct rpt_chan_stat chan_stat[NRPTSTAT];
} ;
struct rpt_tele
@@ -356,6 +471,7 @@
int mode;
struct rpt_link mylink;
char param[TELEPARAMSIZE];
+ int submode;
pthread_t threadid;
} ;
@@ -381,9 +497,21 @@
} ;
+struct sysstate
+{
+ char txdisable;
+ char totdisable;
+ char linkfundisable;
+ char autopatchdisable;
+ char schedulerdisable;
+ char userfundisable;
+ char alternatetail;
+};
+
static struct rpt
{
ast_mutex_t lock;
+ ast_mutex_t remlock;
struct ast_config *cfg;
char reload;
@@ -391,21 +519,25 @@
char *rxchanname;
char *txchanname;
char *remote;
+ struct rpt_chan_stat chan_stat[NRPTSTAT];
+ unsigned int scram;
struct {
-
- const char *ourcontext;
- const char *ourcallerid;
- const char *acctcode;
- const char *ident;
+ char *ourcontext;
+ char *ourcallerid;
+ char *acctcode;
+ char *ident;
char *tonezone;
char simple;
- const char *functions;
- const char *link_functions;
- const char *phone_functions;
- const char *dphone_functions;
- const char *nodes;
+ char *functions;
+ char *link_functions;
+ char *phone_functions;
+ char *dphone_functions;
+ char *nodes;
+ char *extnodes;
+ char *extnodefile;
int hangtime;
+ int althangtime;
int totime;
int idtime;
int tailmessagetime;
@@ -414,13 +546,33 @@
int politeid;
char *tailmessages[500];
int tailmessagemax;
- const char *memory;
- const char *macro;
- const char *startupmacro;
+ char *memory;
+ char *macro;
+ char *startupmacro;
int iobase;
+ char *ioport;
char funcchar;
char endchar;
- char nobusyout;
+ char nobusyout;
+ char notelemtx;
+ char propagate_dtmf;
+ char propagate_phonedtmf;
+ char linktolink;
+ unsigned char civaddr;
+ struct rpt_xlat inxlat;
+ struct rpt_xlat outxlat;
+ char *archivedir;
+ int authlevel;
+ char *csstanzaname;
+ char *skedstanzaname;
+ char *txlimitsstanzaname;
+ long monminblocks;
+ int remoteinacttimeout;
+ int remotetimeout;
+ int remotetimeoutwarning;
+ int remotetimeoutwarningfreq;
+ int sysstate_cur;
+ struct sysstate s[MAX_SYSSTATES];
} p;
struct rpt_link links;
int unkeytocttimer;
@@ -430,16 +582,17 @@
char remoterx;
char remotetx;
char remoteon;
+ char remtxfreqok;
char tounkeyed;
char tonotify;
- char enable;
char dtmfbuf[MAXDTMF];
char macrobuf[MAXMACRO];
char rem_dtmfbuf[MAXDTMF];
char lastdtmfcommand[MAXDTMF];
char cmdnode[50];
- struct ast_channel *rxchannel,*txchannel;
- struct ast_channel *pchannel,*txpchannel, *remchannel;
+ struct ast_channel *rxchannel,*txchannel, *monchannel;
+ struct ast_channel *pchannel,*txpchannel;
+ struct ast_frame *lastf1,*lastf2;
struct rpt_tele tele;
struct timeval lasttv,curtv;
pthread_t rpt_call_thread,rpt_thread;
@@ -452,6 +605,7 @@
int dailytxtime,dailykerchunks,totalkerchunks,dailykeyups,totalkeyups,timeouts;
int totalexecdcommands, dailyexecdcommands;
long retxtimer;
+ long rerxtimer;
long long totaltxtime;
char mydtmf;
char exten[AST_MAX_EXTENSION];
@@ -464,8 +618,10 @@
char tunerequest;
char hfscanmode;
int hfscanstatus;
+ char hfscanstop;
char lastlinknode[MAXNODESTR];
- char stopgen;
+ char savednodes[MAXNODESTR];
+ int stopgen;
char patchfarenddisconnect;
char patchnoct;
char patchquiet;
@@ -483,6 +639,15 @@
time_t lastthreadrestarttime;
long macrotimer;
char lastnodewhichkeyedusup[MAXNODESTR];
+ int dtmf_local_timer;
+ char dtmf_local_str[100];
+ struct ast_filestream *monstream;
+ char loginuser[50];
+ char loginlevel[10];
+ long authtelltimer;
+ long authtimer;
+ int iofd;
+ time_t start_time,last_activity_time;
#ifdef __RPT_NOTCH
struct rptfilter
{
@@ -505,6 +670,23 @@
#endif
} rpt_vars[MAXRPTS];
+struct nodelog {
+struct nodelog *next;
+struct nodelog *prev;
+time_t timestamp;
+char archivedir[MAXNODESTR];
+char str[MAXNODESTR * 2];
+} nodelog;
+
+static int service_scan(struct rpt *myrpt);
+static int set_mode_ft897(struct rpt *myrpt, char newmode);
+static int set_mode_ic706(struct rpt *myrpt, char newmode);
+static int simple_command_ft897(struct rpt *myrpt, char command);
+static int setrem(struct rpt *myrpt);
+
+AST_MUTEX_DEFINE_STATIC(nodeloglock);
+
+AST_MUTEX_DEFINE_STATIC(nodelookuplock);
#ifdef APP_RPT_LOCK_DEBUG
@@ -531,7 +713,6 @@
struct rpt *rpt;
struct lockthread lockthread;
} lock_ring[32];
-
int lock_ring_index = 0;
@@ -691,6 +872,19 @@
#endif /* APP_RPT_LOCK_DEBUG */
/*
+* Return 1 if rig is multimode capable
+*/
+
+static int multimode_capable(struct rpt *myrpt)
+{
+ if(!strcmp(myrpt->remote, remote_rig_ft897))
+ return 1;
+ if(!strcmp(myrpt->remote, remote_rig_ic706))
+ return 1;
+ return 0;
+}
+
+/*
* CLI extensions
*/
@@ -699,8 +893,10 @@
static int rpt_do_dump(int fd, int argc, char *argv[]);
static int rpt_do_stats(int fd, int argc, char *argv[]);
static int rpt_do_lstats(int fd, int argc, char *argv[]);
+static int rpt_do_nodes(int fd, int argc, char *argv[]);
static int rpt_do_reload(int fd, int argc, char *argv[]);
static int rpt_do_restart(int fd, int argc, char *argv[]);
+static int rpt_do_fun(int fd, int argc, char *argv[]);
static char debug_usage[] =
"Usage: rpt debug level {0-7}\n"
@@ -718,6 +914,10 @@
"Usage: rpt lstats <nodename>\n"
" Dumps link statistics to console\n";
+static char dump_nodes[] =
+"Usage: rpt nodes <nodename>\n"
+" Dumps a list of directly and indirectly connected nodes to the console\n";
+
static char reload_usage[] =
"Usage: rpt reload\n"
" Reloads app_rpt running config parameters\n";
@@ -726,30 +926,42 @@
"Usage: rpt restart\n"
" Restarts app_rpt\n";
-static struct ast_cli_entry cli_rpt[] = {
- { { "rpt", "debug", "level" },
- rpt_do_debug, "Enable app_rpt debugging",
- debug_usage },
-
- { { "rpt", "dump" },
- rpt_do_dump, "Dump app_rpt structs for debugging",
- dump_usage },
-
- { { "rpt", "stats" },
- rpt_do_stats, "Dump node statistics",
- dump_stats },
- { { "rpt", "lstats" },
- rpt_do_lstats, "Dump link statistics",
- dump_lstats },
-
- { { "rpt", "reload" },
- rpt_do_reload, "Reload app_rpt config",
- reload_usage },
-
- { { "rpt", "restart" },
- rpt_do_restart, "Restart app_rpt",
- restart_usage },
-};
+static char fun_usage[] =
+"Usage: rpt fun <nodename> <command>\n"
+" Send a DTMF function to a node\n";
+
+
+static struct ast_cli_entry cli_debug =
+ { { "rpt", "debug", "level" }, rpt_do_debug,
+ "Enable app_rpt debugging", debug_usage };
+
+static struct ast_cli_entry cli_dump =
+ { { "rpt", "dump" }, rpt_do_dump,
+ "Dump app_rpt structs for debugging", dump_usage };
+
+static struct ast_cli_entry cli_stats =
+ { { "rpt", "stats" }, rpt_do_stats,
+ "Dump node statistics", dump_stats };
+
+static struct ast_cli_entry cli_nodes =
+ { { "rpt", "nodes" }, rpt_do_nodes,
+ "Dump node list", dump_nodes };
+
+static struct ast_cli_entry cli_lstats =
+ { { "rpt", "lstats" }, rpt_do_lstats,
+ "Dump link statistics", dump_lstats };
+
+static struct ast_cli_entry cli_reload =
+ { { "rpt", "reload" }, rpt_do_reload,
+ "Reload app_rpt config", reload_usage };
+
+static struct ast_cli_entry cli_restart =
+ { { "rpt", "restart" }, rpt_do_restart,
+ "Restart app_rpt", restart_usage };
+
+static struct ast_cli_entry cli_fun =
+ { { "rpt", "fun" }, rpt_do_fun,
+ "Execute a DTMF function", fun_usage };
/*
* Telemetry defaults
@@ -776,6 +988,10 @@
*/
static int setrbi(struct rpt *myrpt);
+static int set_ft897(struct rpt *myrpt);
+static int set_ic706(struct rpt *myrpt);
+static int setkenwood(struct rpt *myrpt);
+static int setrbi_check(struct rpt *myrpt);
@@ -803,6 +1019,228 @@
{"remote", function_remote},
{"macro", function_macro}
} ;
+
+static long diskavail(struct rpt *myrpt)
+{
+struct statfs statfsbuf;
+
+ if (!myrpt->p.archivedir) return(0);
+ if (statfs(myrpt->p.archivedir,&statfsbuf) == -1)
+ {
+ ast_log(LOG_WARNING,"Cannot get filesystem size for %s node %s\n",
+ myrpt->p.archivedir,myrpt->name);
+ return(-1);
+ }
+ return(statfsbuf.f_bavail);
+}
+
+static void do_dtmf_phone(struct rpt *myrpt, struct rpt_link *mylink, char c)
+{
+struct rpt_link *l;
+
+ l = myrpt->links.next;
+ /* go thru all the links */
+ while(l != &myrpt->links)
+ {
+ if (!l->phonemode)
+ {
+ l = l->next;
+ continue;
+ }
+ /* dont send to self */
+ if (mylink && (l == mylink))
+ {
+ l = l->next;
+ continue;
+ }
+ if (l->chan) ast_senddigit(l->chan,c);
+ l = l->next;
+ }
+ return;
+}
+
+/* node logging function */
+static void donodelog(struct rpt *myrpt,char *str)
+{
+struct nodelog *nodep;
+char datestr[100];
+
+ if (!myrpt->p.archivedir) return;
+ nodep = (struct nodelog *)malloc(sizeof(struct nodelog));
+ if (nodep == NULL)
+ {
+ ast_log(LOG_ERROR,"Cannot get memory for node log");
+ return;
+ }
+ time(&nodep->timestamp);
+ strncpy(nodep->archivedir,myrpt->p.archivedir,
+ sizeof(nodep->archivedir) - 1);
+ strftime(datestr,sizeof(datestr) - 1,"%Y%m%d%H%M%S",
+ localtime(&nodep->timestamp));
+ snprintf(nodep->str,sizeof(nodep->str) - 1,"%s %s,%s\n",
+ myrpt->name,datestr,str);
+ ast_mutex_lock(&nodeloglock);
+ insque((struct qelem *) nodep, (struct qelem *) nodelog.prev);
+ ast_mutex_unlock(&nodeloglock);
+}
+
+/* must be called locked */
+static void do_dtmf_local(struct rpt *myrpt, char c)
+{
+int i;
+char digit;
+static const char* dtmf_tones[] = {
+ "!941+1336/200,!0/200", /* 0 */
+ "!697+1209/200,!0/200", /* 1 */
+ "!697+1336/200,!0/200", /* 2 */
+ "!697+1477/200,!0/200", /* 3 */
+ "!770+1209/200,!0/200", /* 4 */
+ "!770+1336/200,!0/200", /* 5 */
+ "!770+1477/200,!0/200", /* 6 */
+ "!852+1209/200,!0/200", /* 7 */
+ "!852+1336/200,!0/200", /* 8 */
+ "!852+1477/200,!0/200", /* 9 */
+ "!697+1633/200,!0/200", /* A */
+ "!770+1633/200,!0/200", /* B */
+ "!852+1633/200,!0/200", /* C */
+ "!941+1633/200,!0/200", /* D */
+ "!941+1209/200,!0/200", /* * */
+ "!941+1477/200,!0/200" }; /* # */
+
+
+ if (c)
+ {
+ snprintf(myrpt->dtmf_local_str + strlen(myrpt->dtmf_local_str),sizeof(myrpt->dtmf_local_str) - 1,"%c",c);
+ if (!myrpt->dtmf_local_timer)
+ myrpt->dtmf_local_timer = DTMF_LOCAL_STARTTIME;
+ }
+ /* if at timeout */
+ if (myrpt->dtmf_local_timer == 1)
+ {
+ /* if anything in the string */
+ if (myrpt->dtmf_local_str[0])
+ {
+ digit = myrpt->dtmf_local_str[0];
+ myrpt->dtmf_local_str[0] = 0;
+ for(i = 1; myrpt->dtmf_local_str[i]; i++)
+ {
+ myrpt->dtmf_local_str[i - 1] =
+ myrpt->dtmf_local_str[i];
+ }
+ myrpt->dtmf_local_str[i - 1] = 0;
+ myrpt->dtmf_local_timer = DTMF_LOCAL_TIME;
+ rpt_mutex_unlock(&myrpt->lock);
+ if (digit >= '0' && digit <='9')
+ ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'0'], 0);
+ else if (digit >= 'A' && digit <= 'D')
+ ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'A'+10], 0);
+ else if (digit == '*')
+ ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[14], 0);
+ else if (digit == '#')
+ ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[15], 0);
+ else {
+ /* not handled */
+ ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, myrpt->txchannel->name);
+ }
+ rpt_mutex_lock(&myrpt->lock);
+ }
+ else
+ {
+ myrpt->dtmf_local_timer = 0;
+ }
+ }
+}
+
+static int openserial(char *fname)
+{
+ struct termios mode;
+ int fd;
+
+ fd = open(fname,O_RDWR);
+ if (fd == -1)
+ {
+ ast_log(LOG_WARNING,"Cannot open serial port %s\n",fname);
+ return -1;
+ }
+ memset(&mode, 0, sizeof(mode));
+ if (tcgetattr(fd, &mode)) {
+ ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", fname, strerror(errno));
+ return -1;
+ }
+#ifndef SOLARIS
+ cfmakeraw(&mode);
+#else
+ mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+ |INLCR|IGNCR|ICRNL|IXON);
+ mode.c_oflag &= ~OPOST;
+ mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+ mode.c_cflag &= ~(CSIZE|PARENB|CRTSCTS);
+ mode.c_cflag |= CS8;
+ mode.c_cc[TIME] = 3;
+ mode.c_cc[MAX] = 1;
+#endif
+
+ cfsetispeed(&mode, B9600);
+ cfsetospeed(&mode, B9600);
+ if (tcsetattr(fd, TCSANOW, &mode))
+ ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", fname, strerror(errno));
+ return(fd);
+}
+
+static char func_xlat(struct rpt *myrpt,char c,struct rpt_xlat *xlat)
+{
+time_t now;
+int gotone;
+
+ time(&now);
+ gotone = 0;
+ /* if too much time, reset the skate machine */
+ if ((now - xlat->lastone) > MAXXLATTIME)
+ {
+ xlat->funcindex = xlat->endindex = 0;
+ }
+ if (xlat->funccharseq[0] && (c == xlat->funccharseq[xlat->funcindex++]))
+ {
+ time(&xlat->lastone);
+ gotone = 1;
+ if (!xlat->funccharseq[xlat->funcindex])
+ {
+ xlat->funcindex = xlat->endindex = 0;
+ return(myrpt->p.funcchar);
+ }
+ } else xlat->funcindex = 0;
+ if (xlat->endcharseq[0] && (c == xlat->endcharseq[xlat->endindex++]))
+ {
+ time(&xlat->lastone);
+ gotone = 1;
+ if (!xlat->endcharseq[xlat->endindex])
+ {
+ xlat->funcindex = xlat->endindex = 0;
+ return(myrpt->p.endchar);
+ }
+ } else xlat->endindex = 0;
+ /* if in middle of decode seq, send nothing back */
+ if (gotone) return(0);
+ /* if no pass chars specified, return em all */
+ if (!xlat->passchars[0]) return(c);
+ /* if a "pass char", pass it */
+ if (strchr(xlat->passchars,c)) return(c);
+ return(0);
+}
+
+/*
+ * Return a pointer to the first non-whitespace character
+ */
+
+static char *eatwhite(char *s)
+{
+ while((*s == ' ') || (*s == 0x09)){ /* get rid of any leading white space */
+ if(!*s)
+ break;
+ s++;
+ }
+ return s;
+}
/*
* Break up a delimited string into a table of substrings
@@ -853,9 +1291,135 @@
}
+/* must be called locked */
+static void __mklinklist(struct rpt *myrpt, struct rpt_link *mylink, char *buf)
+{
+struct rpt_link *l;
+char mode;
+int i,spos;
+
+ buf[0] = 0; /* clear output buffer */
+ /* go thru all links */
+ for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
+ {
+ /* if is not a real link, ignore it */
+ if (l->name[0] == '0') continue;
+ /* dont count our stuff */
+ if (l == mylink) continue;
+ if (mylink && (!strcmp(l->name,mylink->name))) continue;
+ /* figure out mode to report */
+ mode = 'T'; /* use Tranceive by default */
+ if (!l->mode) mode = 'R'; /* indicate RX for our mode */
+ if (!l->thisconnected) mode = 'C'; /* indicate connecting */
+ spos = strlen(buf); /* current buf size (b4 we add our stuff) */
+ if (spos)
+ {
+ strcat(buf,",");
+ spos++;
+ }
+ /* add nodes into buffer */
+ if (l->linklist[0])
+ {
+ snprintf(buf + spos,MAXLINKLIST - spos,
+ "%c%s,%s",mode,l->name,l->linklist);
+ }
+ else /* if no nodes, add this node into buffer */
+ {
+ snprintf(buf + spos,MAXLINKLIST - spos,
+ "%c%s",mode,l->name);
+ }
+ /* if we are in tranceive mode, let all modes stand */
+ if (mode == 'T') continue;
+ /* downgrade everyone on this node if appropriate */
+ for(i = spos; buf[i]; i++)
+ {
+ if (buf[i] == 'T') buf[i] = mode;
+ if ((buf[i] == 'R') && (mode == 'C')) buf[i] = mode;
+ }
+ }
+ return;
+}
+
+/* must be called locked */
+static void __kickshort(struct rpt *myrpt)
+{
+struct rpt_link *l;
+
+ for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
+ {
+ /* if is not a real link, ignore it */
+ if (l->name[0] == '0') continue;
+ l->linklisttimer = LINKLISTSHORTTIME;
+ }
+ return;
+}
+
+static char *node_lookup(struct rpt *myrpt,char *digitbuf)
+{
+
+char *val;
+int longestnode,j;
+struct stat mystat;
+static time_t last = 0;
+static struct ast_config *ourcfg = NULL;
+struct ast_variable *vp;
+
+ /* try to look it up locally first */
+ val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf);
+ if (val) return(val);
+ ast_mutex_lock(&nodelookuplock);
+ /* if file does not exist */
+ if (stat(myrpt->p.extnodefile,&mystat) == -1)
+ {
+ if (ourcfg) ast_config_destroy(ourcfg);
+ ourcfg = NULL;
+ ast_mutex_unlock(&nodelookuplock);
+ return(NULL);
+ }
+ /* if we need to reload */
+ if (mystat.st_mtime > last)
+ {
+ if (ourcfg) ast_config_destroy(ourcfg);
+ ourcfg = ast_config_load(myrpt->p.extnodefile);
+ /* if file not there, just bail */
+ if (!ourcfg)
+ {
+ ast_mutex_unlock(&nodelookuplock);
+ return(NULL);
+ }
+ /* reset "last" time */
+ last = mystat.st_mtime;
+
+ /* determine longest node length again */
+ longestnode = 0;
+ vp = ast_variable_browse(myrpt->cfg, myrpt->p.nodes);
+ while(vp){
+ j = strlen(vp->name);
+ if (j > longestnode)
+ longestnode = j;
+ vp = vp->next;
+ }
+
+ vp = ast_variable_browse(ourcfg, myrpt->p.extnodes);
+ while(vp){
+ j = strlen(vp->name);
+ if (j > longestnode)
+ longestnode = j;
+ vp = vp->next;
+ }
+
+ myrpt->longestnode = longestnode;
+ }
+ val = NULL;
+ if (ourcfg)
+ val = (char *) ast_variable_retrieve(ourcfg, myrpt->p.extnodes, digitbuf);
+ ast_mutex_unlock(&nodelookuplock);
+ return(val);
+}
+
/*
-* Match a keyword in a list, and return index of string plus 1 if there was a match,
-* else return 0. If param is passed in non-null, then it will be set to the first character past the match
+* Match a keyword in a list, and return index of string plus 1 if there was a match,* else return 0.
+* If param is passed in non-null, then it will be set to the first character past the match
*/
static int matchkeyword(char *string, char **param, char *keywords[])
@@ -900,7 +1464,7 @@
-static int myatoi(const char *str)
+static int myatoi(char *str)
{
int ret;
@@ -910,6 +1474,16 @@
return ret;
}
+static int mycompar(const void *a, const void *b)
+{
+char **x = (char **) a;
+char **y = (char **) b;
+int xoff,yoff;
+
+ if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0;
+ if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0;
+ return(strcmp((*x) + xoff,(*y) + yoff));
+}
#ifdef __RPT_NOTCH
@@ -937,16 +1511,50 @@
#endif
+
+/*
+ Get the time for the machine's time zone
+ Note: Asterisk requires a copy of localtime
+ in the /etc directory for this to work properly.
+ If /etc/localtime is not present, you will get
+ GMT time! This is especially important on systems
+ running embedded linux distributions as they don't usually
+ have support for locales.
+
+ If OLD_ASTERISK is defined, then the older localtime_r
+ function will be used. The /etc/localtime file is not
+ required in this case. This provides backward compatibility
+ with Asterisk 1.2 systems.
+
+*/
+
+static void rpt_localtime( time_t * t, struct tm *lt)
+{
+#ifdef OLD_ASTERISK
+ localtime_r(t, lt);
+#else
+ ast_localtime(t, lt, NULL);
+#endif
+}
+
/* Retrieve an int from a config file */
static int retrieve_astcfgint(struct rpt *myrpt,char *category, char *name, int min, int max, int defl)
{
- const char *var;
+ char *var;
int ret;
-
- var = ast_variable_retrieve(myrpt->cfg, category, name);
+ char include_zero = 0;
+
+ if(min < 0){ /* If min is negative, this means include 0 as a valid entry */
+ min = -min;
+ include_zero = 1;
+ }
+
+ var = (char *) ast_variable_retrieve(myrpt->cfg, category, name);
if(var){
ret = myatoi(var);
+ if(include_zero && !ret)
+ return 0;
if(ret < min)
ret = min;
if(ret > max)
@@ -960,15 +1568,14 @@
static void load_rpt_vars(int n,int init)
{
-char *this;
- const char *val;
-int j,longestnode;
+char *this,*val;
+int i,j,longestnode;
struct ast_variable *vp;
struct ast_config *cfg;
-#ifdef __RPT_NOTCH
-int i;
char *strs[100];
-#endif
+char s1[256];
+static char *cs_keywords[] = {"rptena","rptdis","apena","apdis","lnkena","lnkdis","totena","totdis","skena","skdis",
+ "ufena","ufdis","atena","atdis",NULL};
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "%s config for repeater %s\n",
@@ -1001,76 +1608,118 @@
/* zot out filters stuff */
memset(&rpt_vars[n].filters,0,sizeof(rpt_vars[n].filters));
#endif
- val = ast_variable_retrieve(cfg,this,"context");
+ val = (char *) ast_variable_retrieve(cfg,this,"context");
if (val) rpt_vars[n].p.ourcontext = val;
else rpt_vars[n].p.ourcontext = this;
- val = ast_variable_retrieve(cfg,this,"callerid");
+ val = (char *) ast_variable_retrieve(cfg,this,"callerid");
if (val) rpt_vars[n].p.ourcallerid = val;
- val = ast_variable_retrieve(cfg,this,"accountcode");
+ val = (char *) ast_variable_retrieve(cfg,this,"accountcode");
if (val) rpt_vars[n].p.acctcode = val;
- val = ast_variable_retrieve(cfg,this,"idrecording");
+ val = (char *) ast_variable_retrieve(cfg,this,"idrecording");
if (val) rpt_vars[n].p.ident = val;
- val = ast_variable_retrieve(cfg,this,"hangtime");
+ val = (char *) ast_variable_retrieve(cfg,this,"hangtime");
if (val) rpt_vars[n].p.hangtime = atoi(val);
else rpt_vars[n].p.hangtime = HANGTIME;
- val = ast_variable_retrieve(cfg,this,"totime");
+ val = (char *) ast_variable_retrieve(cfg,this,"althangtime");
+ if (val) rpt_vars[n].p.althangtime = atoi(val);
+ else rpt_vars[n].p.althangtime = HANGTIME;
+ val = (char *) ast_variable_retrieve(cfg,this,"totime");
if (val) rpt_vars[n].p.totime = atoi(val);
else rpt_vars[n].p.totime = TOTIME;
rpt_vars[n].p.tailmessagetime = retrieve_astcfgint(&rpt_vars[n],this, "tailmessagetime", 0, 2400000, 0);
rpt_vars[n].p.tailsquashedtime = retrieve_astcfgint(&rpt_vars[n],this, "tailsquashedtime", 0, 2400000, 0);
rpt_vars[n].p.duplex = retrieve_astcfgint(&rpt_vars[n],this,"duplex",0,4,2);
- rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", 60000, 2400000, IDTIME); /* Enforce a min max */
+ rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", -60000, 2400000, IDTIME); /* Enforce a min max including zero */
rpt_vars[n].p.politeid = retrieve_astcfgint(&rpt_vars[n],this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */
- val = ast_variable_retrieve(cfg,this,"tonezone");
- if (val) rpt_vars[n].p.tonezone = ast_strdupa(val);
+ val = (char *) ast_variable_retrieve(cfg,this,"tonezone");
+ if (val) rpt_vars[n].p.tonezone = val;
rpt_vars[n].p.tailmessages[0] = 0;
rpt_vars[n].p.tailmessagemax = 0;
- val = ast_variable_retrieve(cfg,this,"tailmessagelist");
- if (val) rpt_vars[n].p.tailmessagemax = finddelim(ast_strdupa(val), rpt_vars[n].p.tailmessages, 500);
- val = ast_variable_retrieve(cfg,this,"memory");
+ val = (char *) ast_variable_retrieve(cfg,this,"tailmessagelist");
+ if (val) rpt_vars[n].p.tailmessagemax = finddelim(val, rpt_vars[n].p.tailmessages, 500);
+ val = (char *) ast_variable_retrieve(cfg,this,"memory");
if (!val) val = MEMORY;
rpt_vars[n].p.memory = val;
- val = ast_variable_retrieve(cfg,this,"macro");
+ val = (char *) ast_variable_retrieve(cfg,this,"macro");
if (!val) val = MACRO;
rpt_vars[n].p.macro = val;
- val = ast_variable_retrieve(cfg,this,"startup_macro");
+ val = (char *) ast_variable_retrieve(cfg,this,"startup_macro");
if (val) rpt_vars[n].p.startupmacro = val;
- val = ast_variable_retrieve(cfg,this,"iobase");
+ val = (char *) ast_variable_retrieve(cfg,this,"iobase");
/* do not use atoi() here, we need to be able to have
the input specified in hex or decimal so we use
sscanf with a %i */
if ((!val) || (sscanf(val,"%i",&rpt_vars[n].p.iobase) != 1))
rpt_vars[n].p.iobase = DEFAULT_IOBASE;
- val = ast_variable_retrieve(cfg,this,"functions");
+ val = (char *) ast_variable_retrieve(cfg,this,"ioport");
+ rpt_vars[n].p.ioport = val;
+ val = (char *) ast_variable_retrieve(cfg,this,"functions");
if (!val)
{
val = FUNCTIONS;
rpt_vars[n].p.simple = 1;
}
rpt_vars[n].p.functions = val;
- val = ast_variable_retrieve(cfg,this,"link_functions");
+ val = (char *) ast_variable_retrieve(cfg,this,"link_functions");
if (val) rpt_vars[n].p.link_functions = val;
else
rpt_vars[n].p.link_functions = rpt_vars[n].p.functions;
- val = ast_variable_retrieve(cfg,this,"phone_functions");
+ val = (char *) ast_variable_retrieve(cfg,this,"phone_functions");
if (val) rpt_vars[n].p.phone_functions = val;
- val = ast_variable_retrieve(cfg,this,"dphone_functions");
+ val = (char *) ast_variable_retrieve(cfg,this,"dphone_functions");
if (val) rpt_vars[n].p.dphone_functions = val;
- val = ast_variable_retrieve(cfg,this,"funcchar");
+ val = (char *) ast_variable_retrieve(cfg,this,"funcchar");
if (!val) rpt_vars[n].p.funcchar = FUNCCHAR; else
rpt_vars[n].p.funcchar = *val;
- val = ast_variable_retrieve(cfg,this,"endchar");
+ val = (char *) ast_variable_retrieve(cfg,this,"endchar");
if (!val) rpt_vars[n].p.endchar = ENDCHAR; else
rpt_vars[n].p.endchar = *val;
- val = ast_variable_retrieve(cfg,this,"nobusyout");
+ val = (char *) ast_variable_retrieve(cfg,this,"nobusyout");
if (val) rpt_vars[n].p.nobusyout = ast_true(val);
- val = ast_variable_retrieve(cfg,this,"nodes");
+ val = (char *) ast_variable_retrieve(cfg,this,"notelemtx");
+ if (val) rpt_vars[n].p.notelemtx = ast_true(val);
+ val = (char *) ast_variable_retrieve(cfg,this,"propagate_dtmf");
+ if (val) rpt_vars[n].p.propagate_dtmf = ast_true(val);
+ val = (char *) ast_variable_retrieve(cfg,this,"propagate_phonedtmf");
+ if (val) rpt_vars[n].p.propagate_phonedtmf = ast_true(val);
+ val = (char *) ast_variable_retrieve(cfg,this,"linktolink");
+ if (val) rpt_vars[n].p.linktolink = ast_true(val);
+ val = (char *) ast_variable_retrieve(cfg,this,"nodes");
if (!val) val = NODES;
rpt_vars[n].p.nodes = val;
+ val = (char *) ast_variable_retrieve(cfg,this,"extnodes");
+ if (!val) val = EXTNODES;
+ rpt_vars[n].p.extnodes = val;
+ val = (char *) ast_variable_retrieve(cfg,this,"extnodefile");
+ if (!val) val = EXTNODEFILE;
+ rpt_vars[n].p.extnodefile = val;
+ val = (char *) ast_variable_retrieve(cfg,this,"archivedir");
+ if (val) rpt_vars[n].p.archivedir = val;
+ val = (char *) ast_variable_retrieve(cfg,this,"authlevel");
+ if (val) rpt_vars[n].p.authlevel = atoi(val);
+ else rpt_vars[n].p.authlevel = 0;
+ val = (char *) ast_variable_retrieve(cfg,this,"monminblocks");
+ if (val) rpt_vars[n].p.monminblocks = atol(val);
+ else rpt_vars[n].p.monminblocks = DEFAULT_MONITOR_MIN_DISK_BLOCKS;
+ val = (char *) ast_variable_retrieve(cfg,this,"remote_inact_timeout");
+ if (val) rpt_vars[n].p.remoteinacttimeout = atoi(val);
+ else rpt_vars[n].p.remoteinacttimeout = DEFAULT_REMOTE_INACT_TIMEOUT;
+ val = (char *) ast_variable_retrieve(cfg,this,"civaddr");
+ if (val) rpt_vars[n].p.civaddr = atoi(val);
+ else rpt_vars[n].p.civaddr = DEFAULT_CIV_ADDR;
+ val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout");
+ if (val) rpt_vars[n].p.remotetimeout = atoi(val);
+ else rpt_vars[n].p.remotetimeout = DEFAULT_REMOTE_TIMEOUT;
+ val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning");
+ if (val) rpt_vars[n].p.remotetimeoutwarning = atoi(val);
+ else rpt_vars[n].p.remotetimeoutwarning = DEFAULT_REMOTE_TIMEOUT_WARNING;
+ val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning_freq");
+ if (val) rpt_vars[n].p.remotetimeoutwarningfreq = atoi(val);
+ else rpt_vars[n].p.remotetimeoutwarningfreq = DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ;
#ifdef __RPT_NOTCH
- val = ast_variable_retrieve(cfg,this,"rxnotch");
+ val = (char *) ast_variable_retrieve(cfg,this,"rxnotch");
if (val) {
- i = finddelim(ast_strdupa(val),strs,MAXFILTERS * 2);
+ i = finddelim(val,strs,MAXFILTERS * 2);
i &= ~1; /* force an even number, rounded down */
if (i >= 2) for(j = 0; j < i; j += 2)
{
@@ -1085,6 +1734,34 @@
}
#endif
+ val = (char *) ast_variable_retrieve(cfg,this,"inxlat");
+ if (val) {
+ memset(&rpt_vars[n].p.inxlat,0,sizeof(struct rpt_xlat));
+ i = finddelim(val,strs,3);
+ if (i) strncpy(rpt_vars[n].p.inxlat.funccharseq,strs[0],MAXXLAT - 1);
+ if (i > 1) strncpy(rpt_vars[n].p.inxlat.endcharseq,strs[1],MAXXLAT - 1);
+ if (i > 2) strncpy(rpt_vars[n].p.inxlat.passchars,strs[2],MAXXLAT - 1);
+ }
+ val = (char *) ast_variable_retrieve(cfg,this,"outxlat");
+ if (val) {
+ memset(&rpt_vars[n].p.outxlat,0,sizeof(struct rpt_xlat));
+ i = finddelim(val,strs,3);
+ if (i) strncpy(rpt_vars[n].p.outxlat.funccharseq,strs[0],MAXXLAT - 1);
+ if (i > 1) strncpy(rpt_vars[n].p.outxlat.endcharseq,strs[1],MAXXLAT - 1);
+ if (i > 2) strncpy(rpt_vars[n].p.outxlat.passchars,strs[2],MAXXLAT - 1);
+ }
+ /* retreive the stanza name for the control states if there is one */
+ val = (char *) ast_variable_retrieve(cfg,this,"controlstates");
+ rpt_vars[n].p.csstanzaname = val;
+
+ /* retreive the stanza name for the scheduler if there is one */
+ val = (char *) ast_variable_retrieve(cfg,this,"scheduler");
+ rpt_vars[n].p.skedstanzaname = val;
+
+ /* retreive the stanza name for the txlimits */
+ val = (char *) ast_variable_retrieve(cfg,this,"txlimits");
+ rpt_vars[n].p.txlimitsstanzaname = val;
+
longestnode = 0;
vp = ast_variable_browse(cfg, rpt_vars[n].p.nodes);
@@ -1150,6 +1827,88 @@
rpt_vars[n].macro_longest = j;
vp = vp->next;
}
+
+ /* Browse for control states */
+ if(rpt_vars[n].p.csstanzaname)
+ vp = ast_variable_browse(cfg, rpt_vars[n].p.csstanzaname);
+ else
+ vp = NULL;
+ for( i = 0 ; vp && (i < MAX_SYSSTATES) ; i++){ /* Iterate over the number of control state lines in the stanza */
+ int k,nukw,statenum;
+ statenum=atoi(vp->name);
+ strncpy(s1, vp->value, 255);
+ s1[255] = 0;
+ nukw = finddelim(s1,strs,32);
+
+ for (k = 0 ; k < nukw ; k++){ /* for each user specified keyword */
+ for(j = 0 ; cs_keywords[j] != NULL ; j++){ /* try to match to one in our internal table */
+ if(!strcmp(strs[k],cs_keywords[j])){
+ switch(j){
+ case 0: /* rptena */
+ rpt_vars[n].p.s[statenum].txdisable = 0;
+ break;
+ case 1: /* rptdis */
+ rpt_vars[n].p.s[statenum].txdisable = 1;
+ break;
+
+ case 2: /* apena */
+ rpt_vars[n].p.s[statenum].autopatchdisable = 0;
+ break;
+
+ case 3: /* apdis */
+ rpt_vars[n].p.s[statenum].autopatchdisable = 1;
+ break;
+
+ case 4: /* lnkena */
+ rpt_vars[n].p.s[statenum].linkfundisable = 0;
+ break;
+
+ case 5: /* lnkdis */
+ rpt_vars[n].p.s[statenum].linkfundisable = 1;
+ break;
+
+ case 6: /* totena */
+ rpt_vars[n].p.s[statenum].totdisable = 0;
+ break;
+
+ case 7: /* totdis */
+ rpt_vars[n].p.s[statenum].totdisable = 1;
+ break;
+
+ case 8: /* skena */
+ rpt_vars[n].p.s[statenum].schedulerdisable = 0;
+ break;
+
+ case 9: /* skdis */
+ rpt_vars[n].p.s[statenum].schedulerdisable = 1;
+ break;
+
+ case 10: /* ufena */
+ rpt_vars[n].p.s[statenum].userfundisable = 0;
+ break;
+
+ case 11: /* ufdis */
+ rpt_vars[n].p.s[statenum].userfundisable = 1;
+ break;
+
+ case 12: /* atena */
+ rpt_vars[n].p.s[statenum].alternatetail = 1;
+ break;
+
+ case 13: /* atdis */
+ rpt_vars[n].p.s[statenum].alternatetail = 0;
+ break;
+
+ default:
+ ast_log(LOG_WARNING,
+ "Unhandled control state keyword %s", cs_keywords[i]);
+ break;
+ }
+ }
+ }
+ }
+ vp = vp->next;
+ }
ast_mutex_unlock(&rpt_vars[n].lock);
}
@@ -1213,7 +1972,8 @@
char *listoflinks[MAX_STAT_LINKS];
char *lastnodewhichkeyedusup, *lastdtmfcommand;
char *tot_state, *ider_state, *patch_state;
- char *reverse_patch_state, *enable_state, *input_signal, *called_number;
[... 7385 lines stripped ...]
More information about the asterisk-commits
mailing list