From 866bbaa5156d0afa70888f555adfeae5e2250dcd Mon Sep 17 00:00:00 2001 From: Steve Murphy Date: Tue, 19 Jun 2007 23:36:34 +0000 Subject: Via bug9228, no way to create macros via AEL, and some of the apps allow you to call macros..., I modded the apps that allow macro calls to allow gosubs calls also, to make them AEL compliant. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@70161 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_rpt.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) (limited to 'apps/app_rpt.c') diff --git a/apps/app_rpt.c b/apps/app_rpt.c index 7ae10fb24..40880dae2 100644 --- a/apps/app_rpt.c +++ b/apps/app_rpt.c @@ -133,8 +133,11 @@ #define MAXDTMF 32 #define MAXMACRO 2048 +#define MAXGOSUB 2048 #define MACROTIME 100 +#define GOSUBTIME 100 #define MACROPTIME 500 +#define GOSUBPTIME 500 #define DTMF_TIMEOUT 3 #ifdef __RPT_NOTCH @@ -157,6 +160,7 @@ #define NODES "nodes" #define MEMORY "memory" #define MACRO "macro" +#define GOSUB "gosub" #define FUNCTIONS "functions" #define TELEMETRY "telemetry" #define MORSE "morse" @@ -183,7 +187,7 @@ 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, GOSUB_NOTFOUND, MACRO_BUSY, GOSUB_BUSY, LASTNODEKEY}; enum {REM_SIMPLEX, REM_MINUS, REM_PLUS}; @@ -418,7 +422,9 @@ static struct rpt ); char memory[80]; char macro[80]; + char gosub[80]; char startupmacro[80]; + char startupgosub[80]; int iobase; char funcchar; char endchar; @@ -437,6 +443,7 @@ static struct rpt char enable; char dtmfbuf[MAXDTMF]; char macrobuf[MAXMACRO]; + char gosubbuf[MAXGOSUB]; char rem_dtmfbuf[MAXDTMF]; char lastdtmfcommand[MAXDTMF]; char cmdnode[50]; @@ -474,6 +481,7 @@ static struct rpt char patchcontext[MAXPATCHCONTEXT]; int patchdialtime; int macro_longest; + int gosub_longest; int phone_longestfunc; int dphone_longestfunc; int link_longestfunc; @@ -484,6 +492,7 @@ static struct rpt time_t disgorgetime; time_t lastthreadrestarttime; long macrotimer; + long gosubtimer; char lastnodewhichkeyedusup[MAXNODESTR]; #ifdef __RPT_NOTCH struct rptfilter @@ -784,6 +793,7 @@ static int function_status(struct rpt *myrpt, char *param, char *digitbuf, int c static int function_cop(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink); static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink); static int function_macro(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink); +static int function_gosub(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink); /* * Function table */ @@ -796,6 +806,7 @@ static struct function_table_tag function_table[] = { {"status", function_status}, {"remote", function_remote}, {"macro", function_macro} + {"gosub", function_gosub} } ; /* @@ -955,6 +966,7 @@ static void load_rpt_vars(int n, int init) rpt_vars[n].p.politeid = POLITEID; ast_copy_string(rpt_vars[n].p.memory, MEMORY, sizeof(rpt_vars[n].p.memory)); ast_copy_string(rpt_vars[n].p.macro, MACRO, sizeof(rpt_vars[n].p.macro)); + ast_copy_string(rpt_vars[n].p.gosub, GOSUB, sizeof(rpt_vars[n].p.gosub)); rpt_vars[n].p.iobase = DEFAULT_IOBASE; ast_copy_string(rpt_vars[n].p.functions, FUNCTIONS, sizeof(rpt_vars[n].p.functions)); rpt_vars[n].p.simple = 1; @@ -1014,8 +1026,12 @@ static void load_rpt_vars(int n, int init) ast_copy_string(rpt_vars[n].p.memory, var->value, sizeof(rpt_vars[n].p.memory)); } else if (!strcmp(var->name, "macro")) { ast_copy_string(rpt_vars[n].p.macro, var->value, sizeof(rpt_vars[n].p.macro)); + } else if (!strcmp(var->name, "gosub")) { + ast_copy_string(rpt_vars[n].p.gosub, var->value, sizeof(rpt_vars[n].p.gosub)); } else if (!strcmp(var->name, "startup_macro")) { ast_copy_string(rpt_vars[n].p.startupmacro, var->value, sizeof(rpt_vars[n].p.startupmacro)); + } else if (!strcmp(var->name, "startup_gosub")) { + ast_copy_string(rpt_vars[n].p.startupgosub, var->value, sizeof(rpt_vars[n].p.startupgosub)); } else if (!strcmp(var->name, "iobase")) { /* do not use atoi() here, we need to be able to have the input specified in hex or decimal so we use @@ -1101,6 +1117,12 @@ static void load_rpt_vars(int n, int init) if ((j = strlen(vp->name)) > rpt_vars[n].macro_longest) rpt_vars[n].macro_longest = j; } + + rpt_vars[n].gosub_longest = 1; + for (vp = ast_variable_browse(cfg, rpt_vars[n].p.gosub); vp; vp = vp->next) { + if ((j = strlen(vp->name)) > rpt_vars[n].gosub_longest) + rpt_vars[n].gosub_longest = j; + } ast_mutex_unlock(&rpt_vars[n].lock); } @@ -1961,11 +1983,21 @@ static void *rpt_tele_thread(void *this) wait_interval(myrpt, DLY_TELEM, mychannel); res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language); break; + case GOSUB_NOTFOUND: + /* wait a little bit */ + wait_interval(myrpt, DLY_TELEM, mychannel); + res = ast_streamfile(mychannel, "rpt/gosub_notfound", mychannel->language); + break; case MACRO_BUSY: /* wait a little bit */ wait_interval(myrpt, DLY_TELEM, mychannel); res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language); break; + case GOSUB_BUSY: + /* wait a little bit */ + wait_interval(myrpt, DLY_TELEM, mychannel); + res = ast_streamfile(mychannel, "rpt/gosub_busy", mychannel->language); + break; case UNKEY: if (myrpt->patchnoct && myrpt->callmode) { /* If no CT during patch configured, then don't send one */ imdone = 1; @@ -3283,6 +3315,54 @@ static int function_macro(struct rpt *myrpt, char *param, char *digitbuf, int co return DC_COMPLETE; } +/* +* Gosub +*/ + +static int function_gosub(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) +{ + + const char *val; + int i; + struct ast_channel *mychannel; + + if ((!myrpt->remote) && (!myrpt->enable)) + return DC_ERROR; + + if (debug) + ast_log(LOG_DEBUG, "@@@@ gosub param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); + + mychannel = myrpt->remchannel; + + if (ast_strlen_zero(digitbuf)) /* needs 1 digit */ + return DC_INDETERMINATE; + + for (i = 0; i < digitbuf[i]; i++) { + if ((digitbuf[i] < '0') || (digitbuf[i] > '9')) + return DC_ERROR; + } + + if (*digitbuf == '0') + val = myrpt->p.startupgosub; + else + val = ast_variable_retrieve(myrpt->cfg, myrpt->p.gosub, digitbuf); + /* param was 1 for local buf */ + if (!val) { + rpt_telemetry(myrpt, GOSUB_NOTFOUND, NULL); + return DC_COMPLETE; + } + rpt_mutex_lock(&myrpt->lock); + if ((sizeof(myrpt->gosubbuf) - strlen(myrpt->gosubbuf)) < strlen(val)) { + rpt_mutex_unlock(&myrpt->lock); + rpt_telemetry(myrpt, GOSUB_BUSY, NULL); + return DC_ERROR; + } + myrpt->gosubtimer = GOSUBTIME; + strncat(myrpt->gosubbuf, val, sizeof(myrpt->gosubbuf) - 1); + rpt_mutex_unlock(&myrpt->lock); + return DC_COMPLETE; +} + /* * COP - Control operator */ @@ -5798,6 +5878,9 @@ static void *rpt(void *this) if (myrpt->p.startupmacro) { snprintf(myrpt->macrobuf, sizeof(myrpt->macrobuf), "PPPP%s", myrpt->p.startupmacro); } + if (myrpt->p.startupgosub) { + snprintf(myrpt->gosubbuf, sizeof(myrpt->gosubbuf), "PPPP%s", myrpt->p.startupgosub); + } rpt_mutex_unlock(&myrpt->lock); val = 0; ast_channel_setoption(myrpt->rxchannel, AST_OPTION_TONE_VERIFY, &val, sizeof(char), 0); @@ -6228,6 +6311,11 @@ static void *rpt(void *this) myrpt->macrotimer -= elap; if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; + /* do gosub timers */ + if (myrpt->gosubtimer) + myrpt->gosubtimer -= elap; + if (myrpt->gosubtimer < 0) + myrpt->gosubtimer = 0; /* Execute scheduler appx. every 2 tenths of a second */ if (myrpt->skedtimer <= 0) { myrpt->skedtimer = 200; @@ -6248,6 +6336,16 @@ static void *rpt(void *this) local_dtmf_helper(myrpt, c); } else rpt_mutex_unlock(&myrpt->lock); + c = myrpt->gosubbuf[0]; + if (c && (!myrpt->gosubtimer)) { + myrpt->gosubtimer = GOSUBTIME; + memmove(myrpt->gosubbuf, myrpt->gosubbuf + 1, sizeof(myrpt->gosubbuf) - 1); + if ((c == 'p') || (c == 'P')) + myrpt->gosubtimer = GOSUBPTIME; + rpt_mutex_unlock(&myrpt->lock); + local_dtmf_helper(myrpt, c); + } else + rpt_mutex_unlock(&myrpt->lock); if (who == myrpt->rxchannel) { /* if it was a read from rx */ f = ast_read(myrpt->rxchannel); if (!f) { @@ -7072,6 +7170,10 @@ static int rpt_exec(struct ast_channel *chan, void *data) myrpt->remchannel = chan; /* Save copy of channel */ snprintf(myrpt->macrobuf, sizeof(myrpt->macrobuf), "PPPP%s", myrpt->p.startupmacro); } + if (myrpt->p.startupgosub) { + myrpt->remchannel = chan; /* Save copy of channel */ + snprintf(myrpt->gosubbuf, sizeof(myrpt->gosubbuf), "PPPP%s", myrpt->p.startupgosub); + } myrpt->reload = 0; rpt_mutex_unlock(&myrpt->lock); setrem(myrpt); @@ -7123,6 +7225,10 @@ static int rpt_exec(struct ast_channel *chan, void *data) myrpt->macrotimer -= elap; if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; + if (myrpt->gosubtimer) + myrpt->gosubtimer -= elap; + if (myrpt->gosubtimer < 0) + myrpt->gosubtimer = 0; rpt_mutex_unlock(&myrpt->lock); if (!ms) continue; @@ -7244,6 +7350,17 @@ static int rpt_exec(struct ast_channel *chan, void *data) if (handle_remote_dtmf_digit(myrpt, c, &keyed, 0) == -1) break; continue; + } + c = myrpt->gosubbuf[0]; + if (c && (!myrpt->gosubtimer)) { + myrpt->gosubtimer = GOSUBTIME; + memmove(myrpt->gosubbuf, myrpt->gosubbuf + 1, sizeof(myrpt->gosubbuf) - 1); + if ((c == 'p') || (c == 'P')) + myrpt->gosubtimer = GOSUBPTIME; + rpt_mutex_unlock(&myrpt->lock); + if (handle_remote_dtmf_digit(myrpt, c, &keyed, 0) == -1) + break; + continue; } rpt_mutex_unlock(&myrpt->lock); continue; -- cgit v1.2.3