[asterisk-commits] trunk r11146 - /trunk/apps/app_rpt.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Sat Feb 25 22:11:36 MST 2006
Author: jdixon
Date: Sat Feb 25 23:11:34 2006
New Revision: 11146
URL: http://svn.digium.com/view/asterisk?rev=11146&view=rev
Log:
Fixed nasty lockup bug and added command macros (not to be confused with
macro-oni).
Modified:
trunk/apps/app_rpt.c
Modified: trunk/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_rpt.c?rev=11146&r1=11145&r2=11146&view=diff
==============================================================================
--- trunk/apps/app_rpt.c (original)
+++ trunk/apps/app_rpt.c Sat Feb 25 23:11:34 2006
@@ -20,8 +20,8 @@
/*! \file
*
* \brief Radio Repeater / Remote Base program
- * version 0.39 12/19/05
- *
+ * version 0.42 02/25/06
+ *
* \author Jim Dixon, WB6NIL <jim at lambdatel.com>
*
* \note Serious contributions by Steve RoDgers, WA6ZFT <hwstar at rodgers.sdcoxmail.com>
@@ -107,6 +107,9 @@
/* maximum digits in DTMF buffer, and seconds after * for DTMF command timeout */
#define MAXDTMF 32
+#define MAXMACRO 2048
+#define MACROTIME 100
+#define MACROPTIME 500
#define DTMF_TIMEOUT 3
#define DISC_TIME 10000 /* report disc after 10 seconds of no connect */
@@ -123,6 +126,7 @@
#define NODES "nodes"
#define MEMORY "memory"
+#define MACRO "macro"
#define FUNCTIONS "functions"
#define TELEMETRY "telemetry"
#define MORSE "morse"
@@ -147,7 +151,7 @@
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};
+ TAILMSG, MACRO_NOTFOUND, MACRO_BUSY};
enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
@@ -206,7 +210,7 @@
#include "asterisk/say.h"
#include "asterisk/localtime.h"
-static char *tdesc = "Radio Repeater / Remote Base version 0.39 12/19/2005";
+static char *tdesc = "Radio Repeater / Remote Base version 0.42 02/25/2006";
static char *app = "Rpt";
@@ -247,7 +251,7 @@
" available to the phone user.\n"
"\n";
-static int debug = 0; /* Set this >0 for extra debug output */
+static int debug = 0; /* FIXME Set this >0 for extra debug output */
static int nrpts = 0;
char *discstr = "!!DISCONNECT!!";
@@ -256,6 +260,7 @@
struct ast_config *cfg;
+STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
#define MSWAIT 200
@@ -362,15 +367,16 @@
char tonotify;
char enable;
char dtmfbuf[MAXDTMF];
+ char macrobuf[MAXMACRO];
char rem_dtmfbuf[MAXDTMF];
char cmdnode[50];
struct ast_channel *rxchannel,*txchannel;
struct ast_channel *pchannel,*txpchannel, *remchannel;
struct rpt_tele tele;
pthread_t rpt_call_thread,rpt_thread;
- time_t rem_dtmf_time,dtmf_time_rem;
+ time_t dtmf_time,rem_dtmf_time,dtmf_time_rem;
int tailtimer,totimer,idtimer,txconf,conf,callmode,cidx,scantimer,tmsgtimer;
- int mustid;
+ int mustid,tailid;
int politeid;
int dtmfidx,rem_dtmfidx;
long retxtimer;
@@ -390,6 +396,7 @@
char funcchar;
char endchar;
char stopgen;
+ int macro_longest;
int phone_longestfunc;
int dphone_longestfunc;
int link_longestfunc;
@@ -403,8 +410,197 @@
int tailmessagen;
time_t disgorgetime;
time_t lastthreadrestarttime;
+ long macrotimer;
+ char *macro;
+ char *startupmacro;
+ char *memory;
char nobusyout;
} rpt_vars[MAXRPTS];
+
+
+#ifdef APP_RPT_LOCK_DEBUG
+
+#warning COMPILING WITH LOCK-DEBUGGING ENABLED!!
+
+#define MAXLOCKTHREAD 100
+
+#define rpt_mutex_lock(x) _rpt_mutex_lock(x,myrpt,__LINE__)
+#define rpt_mutex_unlock(x) _rpt_mutex_unlock(x,myrpt,__LINE__)
+
+struct lockthread
+{
+ pthread_t id;
+ int lockcount;
+ int lastlock;
+ int lastunlock;
+} lockthreads[MAXLOCKTHREAD];
+
+
+struct by_lightning
+{
+ int line;
+ struct timeval tv;
+ struct rpt *rpt;
+ struct lockthread lockthread;
+} lock_ring[32];
+
+
+int lock_ring_index = 0;
+
+AST_MUTEX_DEFINE_STATIC(locklock);
+
+static struct lockthread *get_lockthread(pthread_t id)
+{
+int i;
+
+ for(i = 0; i < MAXLOCKTHREAD; i++)
+ {
+ if (lockthreads[i].id == id) return(&lockthreads[i]);
+ }
+ return(NULL);
+}
+
+static struct lockthread *put_lockthread(pthread_t id)
+{
+int i;
+
+ for(i = 0; i < MAXLOCKTHREAD; i++)
+ {
+ if (lockthreads[i].id == id)
+ return(&lockthreads[i]);
+ }
+ for(i = 0; i < MAXLOCKTHREAD; i++)
+ {
+ if (!lockthreads[i].id)
+ {
+ lockthreads[i].lockcount = 0;
+ lockthreads[i].lastlock = 0;
+ lockthreads[i].lastunlock = 0;
+ lockthreads[i].id = id;
+ return(&lockthreads[i]);
+ }
+ }
+ return(NULL);
+}
+
+
+static void rpt_mutex_spew(void)
+{
+ struct by_lightning lock_ring_copy[32];
+ int lock_ring_index_copy;
+ int i,j;
+ long long diff;
+ char a[100];
+ struct timeval lasttv;
+
+ ast_mutex_lock(&locklock);
+ memcpy(&lock_ring_copy, &lock_ring, sizeof(lock_ring_copy));
+ lock_ring_index_copy = lock_ring_index;
+ ast_mutex_unlock(&locklock);
+
+ lasttv.tv_sec = lasttv.tv_usec = 0;
+ for(i = 0 ; i < 32 ; i++)
+ {
+ j = (i + lock_ring_index_copy) % 32;
+ strftime(a,sizeof(a) - 1,"%m/%d/%Y %H:%M:%S",
+ localtime(&lock_ring_copy[j].tv.tv_sec));
+ diff = 0;
+ if(lasttv.tv_sec)
+ {
+ diff = (lock_ring_copy[j].tv.tv_sec - lasttv.tv_sec)
+ * 1000000;
+ diff += (lock_ring_copy[j].tv.tv_usec - lasttv.tv_usec);
+ }
+ lasttv.tv_sec = lock_ring_copy[j].tv.tv_sec;
+ lasttv.tv_usec = lock_ring_copy[j].tv.tv_usec;
+ if (!lock_ring_copy[j].tv.tv_sec) continue;
+ if (lock_ring_copy[j].line < 0)
+ {
+ ast_log(LOG_NOTICE,"LOCKDEBUG [#%d] UNLOCK app_rpt.c:%d node %s pid %x diff %lld us at %s.%06d\n",
+ i - 31,-lock_ring_copy[j].line,lock_ring_copy[j].rpt->name,(int) lock_ring_copy[j].lockthread.id,diff,a,(int)lock_ring_copy[j].tv.tv_usec);
+ }
+ else
+ {
+ ast_log(LOG_NOTICE,"LOCKDEBUG [#%d] LOCK app_rpt.c:%d node %s pid %x diff %lld us at %s.%06d\n",
+ i - 31,lock_ring_copy[j].line,lock_ring_copy[j].rpt->name,(int) lock_ring_copy[j].lockthread.id,diff,a,(int)lock_ring_copy[j].tv.tv_usec);
+ }
+ }
+}
+
+
+static void _rpt_mutex_lock(ast_mutex_t *lockp, struct rpt *myrpt, int line)
+{
+struct lockthread *t;
+pthread_t id;
+
+ id = pthread_self();
+ ast_mutex_lock(&locklock);
+ t = put_lockthread(id);
+ if (!t)
+ {
+ ast_mutex_unlock(&locklock);
+ return;
+ }
+ if (t->lockcount)
+ {
+ int lastline = t->lastlock;
+ ast_mutex_unlock(&locklock);
+ ast_log(LOG_NOTICE,"rpt_mutex_lock: Double lock request line %d node %s pid %x, last lock was line %d\n",line,myrpt->name,(int) t->id,lastline);
+ rpt_mutex_spew();
+ return;
+ }
+ t->lastlock = line;
+ t->lockcount = 1;
+ gettimeofday(&lock_ring[lock_ring_index].tv, NULL);
+ lock_ring[lock_ring_index].rpt = myrpt;
+ memcpy(&lock_ring[lock_ring_index].lockthread,t,sizeof(struct lockthread));
+ lock_ring[lock_ring_index++].line = line;
+ if(lock_ring_index == 32)
+ lock_ring_index = 0;
+ ast_mutex_unlock(&locklock);
+ ast_mutex_lock(lockp);
+}
+
+
+static void _rpt_mutex_unlock(ast_mutex_t *lockp, struct rpt *myrpt, int line)
+{
+struct lockthread *t;
+pthread_t id;
+
+ id = pthread_self();
+ ast_mutex_lock(&locklock);
+ t = put_lockthread(id);
+ if (!t)
+ {
+ ast_mutex_unlock(&locklock);
+ return;
+ }
+ if (!t->lockcount)
+ {
+ int lastline = t->lastunlock;
+ ast_mutex_unlock(&locklock);
+ ast_log(LOG_NOTICE,"rpt_mutex_lock: Double un-lock request line %d node %s pid %x, last un-lock was line %d\n",line,myrpt->name,(int) t->id,lastline);
+ rpt_mutex_spew();
+ return;
+ }
+ t->lastunlock = line;
+ t->lockcount = 0;
+ gettimeofday(&lock_ring[lock_ring_index].tv, NULL);
+ lock_ring[lock_ring_index].rpt = myrpt;
+ memcpy(&lock_ring[lock_ring_index].lockthread,t,sizeof(struct lockthread));
+ lock_ring[lock_ring_index++].line = -line;
+ if(lock_ring_index == 32)
+ lock_ring_index = 0;
+ ast_mutex_unlock(&locklock);
+ ast_mutex_unlock(lockp);
+}
+
+#else /* APP_RPT_LOCK_DEBUG */
+
+#define rpt_mutex_lock(x) ast_mutex_lock(x)
+#define rpt_mutex_unlock(x) ast_mutex_unlock(x)
+
+#endif /* APP_RPT_LOCK_DEBUG */
/*
* CLI extensions
@@ -412,15 +608,32 @@
/* Debug mode */
static int rpt_do_debug(int fd, int argc, char *argv[]);
+static int rpt_do_dump(int fd, int argc, char *argv[]);
+static int rpt_do_frog(int fd, int argc, char *argv[]);
static char debug_usage[] =
"Usage: rpt debug level {0-7}\n"
" Enables debug messages in app_rpt\n";
-
+
+static char dump_usage[] =
+"Usage: rpt dump <nodename>\n"
+" Dumps struct debug info to log\n";
+
+static char frog_usage[] =
+"Usage: frog [warp_factor]\n"
+" Performs frog-in-a-blender calculations (Jacobsen Corollary)\n";
+
static struct ast_cli_entry cli_debug =
- { { "rpt", "debug", "level" }, rpt_do_debug, "Enable app_rpt debugging", debug_usage };
-
-
+ { { "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_frog =
+ { { "frog" }, rpt_do_frog,
+ "Perform frog-in-a-blender calculations", frog_usage };
/*
* Telemetry defaults
@@ -460,6 +673,7 @@
static int function_status(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
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);
/*
* Function table
*/
@@ -470,7 +684,8 @@
{"autopatchdn", function_autopatchdn},
{"ilink", function_ilink},
{"status", function_status},
- {"remote", function_remote}
+ {"remote", function_remote},
+ {"macro", function_macro}
} ;
static int finddelim(char *str,char *strp[])
@@ -542,8 +757,49 @@
debug = newlevel;
return RESULT_SUCCESS;
}
+
+/*
+* Dump rpt struct debugging onto console
+*/
-
+static int rpt_do_dump(int fd, int argc, char *argv[])
+{
+ int i;
+
+ if (argc != 3)
+ return RESULT_SHOWUSAGE;
+
+ for(i = 0; i < nrpts; i++)
+ {
+ if (!strcmp(argv[2],rpt_vars[i].name))
+ {
+ rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
+ ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]);
+ return RESULT_SUCCESS;
+ }
+ }
+ return RESULT_FAILURE;
+}
+
+/*
+* Perform frong-in-a-blender calculations (Jacobsen Corollary)
+*/
+
+static int rpt_do_frog(int fd, int argc, char *argv[])
+{
+ double warpone = 75139293848.398696166028333356763;
+ double warpfactor = 1.0;
+
+ if (argc > 2) return RESULT_SHOWUSAGE;
+ if ((argc > 1) && (sscanf(argv[1],"%lf",&warpfactor) != 1))
+ return RESULT_SHOWUSAGE;
+
+ ast_cli(fd, "A frog in a blender with a base diameter of 3 inches going\n");
+ ast_cli(fd, "%lf RPM will be travelling at warp factor %lf,\n",
+ warpfactor * warpfactor * warpfactor * warpone,warpfactor);
+ ast_cli(fd,"based upon the Jacobsen Frog Corollary.\n");
+ return RESULT_FAILURE;
+}
static int play_tone_pair(struct ast_channel *chan, int f1, int f2, int duration, int amplitude)
{
@@ -1028,35 +1284,37 @@
time_t t;
struct tm localtm;
-
/* get a pointer to myrpt */
myrpt = mytele->rpt;
/* Snag copies of a few key myrpt variables */
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
+ insque((struct qelem *)mytele, (struct qelem *)myrpt->tele.next); /* Moved from rpt_telemetry() */
nodename = ast_strdupa(myrpt->name);
ident = ast_strdupa(myrpt->ident);
- ast_mutex_unlock(&myrpt->lock);
-
+ rpt_mutex_unlock(&myrpt->lock);
/* allocate a pseudo-channel thru asterisk */
- if (!(mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL)))
+ mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
+ if (!mychannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
remque((struct qelem *)mytele);
- ast_mutex_unlock(&myrpt->lock);
+ ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
+ rpt_mutex_unlock(&myrpt->lock);
free(mytele);
pthread_exit(NULL);
}
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
mytele->chan = mychannel; /* Save a copy of the channel so we can access it externally if need be */
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
/* make a conference for the tx */
ci.chan = 0;
- /* If there's an ID queued, only connect the ID audio to the local tx conference so
- linked systems can't hear it */
+ /* If there's an ID queued, or tail message queued, */
+ /* only connect the ID audio to the local tx conference so */
+ /* linked systems can't hear it */
ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) ||
(mytele->mode == TAILMSG)) ?
myrpt->txconf : myrpt->conf);
@@ -1065,9 +1323,10 @@
if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
{
ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
remque((struct qelem *)mytele);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
+ ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
free(mytele);
ast_hangup(mychannel);
pthread_exit(NULL);
@@ -1110,6 +1369,16 @@
wait_interval(myrpt, DLY_TELEM, mychannel);
res = telem_lookup(mychannel, myrpt->name, "functcomplete");
break;
+ case MACRO_NOTFOUND:
+ /* wait a little bit */
+ wait_interval(myrpt, DLY_TELEM, mychannel);
+ res = ast_streamfile(mychannel, "rpt/macro_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 UNKEY:
/*
@@ -1117,9 +1386,9 @@
*/
x = get_wait_interval(myrpt, DLY_UNKEY);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
/*
* If there's one already queued, don't do another
@@ -1129,12 +1398,12 @@
unkeys_queued = 0;
if (tlist != &myrpt->tele)
{
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
while(tlist != &myrpt->tele){
if (tlist->mode == UNKEY) unkeys_queued++;
tlist = tlist->next;
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
}
if( unkeys_queued > 1){
imdone = 1;
@@ -1143,7 +1412,6 @@
/* Wait for the telemetry timer to expire */
/* Periodically check the timer since it can be re-initialized above */
-
while(myrpt->unkeytocttimer)
{
int ctint;
@@ -1152,15 +1420,14 @@
else
ctint = myrpt->unkeytocttimer;
ast_safe_sleep(mychannel, ctint);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
if(myrpt->unkeytocttimer < ctint)
myrpt->unkeytocttimer = 0;
else
myrpt->unkeytocttimer -= ctint;
- ast_mutex_unlock(&myrpt->lock);
- }
-
-
+ rpt_mutex_unlock(&myrpt->lock);
+ }
+
/*
* Now, the carrier on the rptr rx should be gone.
* If it re-appeared, then forget about sending the CT
@@ -1176,7 +1443,7 @@
l = myrpt->links.next;
if (l != &myrpt->links)
{
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
while(l != &myrpt->links)
{
if (l->name[0] == '0')
@@ -1191,7 +1458,7 @@
}
l = l->next;
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
}
if (haslink)
{
@@ -1217,7 +1484,6 @@
if(res)
ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);
}
-
if (hasremote && (!myrpt->cmdnode[0]))
{
/* set for all to hear */
@@ -1228,9 +1494,10 @@
if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
{
ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
remque((struct qelem *)mytele);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
+ ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
free(mytele);
ast_hangup(mychannel);
pthread_exit(NULL);
@@ -1301,7 +1568,7 @@
hastx = 0;
linkbase.next = &linkbase;
linkbase.prev = &linkbase;
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
/* make our own list of links */
l = myrpt->links.next;
while(l != &myrpt->links)
@@ -1310,12 +1577,14 @@
{
l = l->next;
continue;
- }
- if (!(m = ast_malloc(sizeof(*m))))
+ }
+ m = malloc(sizeof(struct rpt_link));
+ if (!m)
{
- ast_mutex_lock(&myrpt->lock);
+ ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name);
remque((struct qelem *)mytele);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
+ ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
free(mytele);
ast_hangup(mychannel);
pthread_exit(NULL);
@@ -1325,7 +1594,7 @@
insque((struct qelem *)m,(struct qelem *)linkbase.next);
l = l->next;
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
if (!res)
res = ast_waitstream(mychannel, "");
@@ -1534,7 +1803,7 @@
}
}
ast_stopstream(mychannel);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
if (mytele->mode == TAILMSG)
{
if (!res)
@@ -1548,9 +1817,20 @@
}
}
remque((struct qelem *)mytele);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
free(mytele);
ast_hangup(mychannel);
+#ifdef APP_RPT_LOCK_DEBUG
+ {
+ struct lockthread *t;
+
+ sleep(5);
+ ast_mutex_lock(&locklock);
+ t = get_lockthread(pthread_self());
+ if (t) memset(t,0,sizeof(struct lockthread));
+ ast_mutex_unlock(&locklock);
+ }
+#endif
pthread_exit(NULL);
}
@@ -1558,16 +1838,21 @@
{
struct rpt_tele *tele;
struct rpt_link *mylink = (struct rpt_link *) data;
+int res;
pthread_attr_t attr;
-
- if (!(tele = ast_calloc(1, sizeof(*tele))))
- {
+
+ tele = malloc(sizeof(struct rpt_tele));
+ if (!tele)
+ {
+ ast_log(LOG_WARNING, "Unable to allocate memory\n");
pthread_exit(NULL);
return;
}
+ /* zero it out */
+ memset((char *)tele,0,sizeof(struct rpt_tele));
tele->rpt = myrpt;
tele->mode = mode;
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED)){
memset(&tele->mylink,0,sizeof(struct rpt_link));
if (mylink){
@@ -1578,11 +1863,12 @@
strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
tele->param[TELEPARAMSIZE - 1] = 0;
}
- insque((struct qelem *)tele,(struct qelem *)myrpt->tele.next);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele);
+ res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele);
+ if(res < 0)
+ ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res));
return;
}
@@ -1597,7 +1883,8 @@
myrpt->mydtmf = 0;
/* allocate a pseudo-channel thru asterisk */
- if (!(mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL)))
+ mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
+ if (!mychannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
pthread_exit(NULL);
@@ -1615,7 +1902,8 @@
pthread_exit(NULL);
}
/* allocate a pseudo-channel thru asterisk */
- if (!(genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL)))
+ genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
+ if (!genchannel)
{
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
ast_hangup(mychannel);
@@ -1681,9 +1969,9 @@
{
ast_hangup(mychannel);
ast_hangup(genchannel);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
myrpt->callmode = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
pthread_exit(NULL);
}
}
@@ -1694,9 +1982,9 @@
{
ast_hangup(mychannel);
ast_hangup(genchannel);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
myrpt->callmode = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
pthread_exit(NULL);
}
@@ -1730,23 +2018,23 @@
ast_log(LOG_WARNING, "Unable to start PBX!!\n");
ast_hangup(mychannel);
ast_hangup(genchannel);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
myrpt->callmode = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
pthread_exit(NULL);
}
usleep(10000);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
myrpt->callmode = 3;
while(myrpt->callmode)
{
if ((!mychannel->pbx) && (myrpt->callmode != 4))
{
myrpt->callmode = 4;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
/* start congestion tone */
tone_zone_play_tone(genchannel->fds[0],ZT_TONE_CONGESTION);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
}
if (myrpt->mydtmf)
{
@@ -1757,22 +2045,22 @@
wf.data = NULL;
wf.datalen = 0;
wf.samples = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
ast_write(genchannel,&wf);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
myrpt->mydtmf = 0;
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
usleep(MSWAIT * 1000);
- ast_mutex_lock(&myrpt->lock);
- }
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
+ }
+ rpt_mutex_unlock(&myrpt->lock);
tone_zone_play_tone(genchannel->fds[0],-1);
if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV);
ast_hangup(genchannel);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
myrpt->callmode = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
pthread_exit(NULL);
}
@@ -1857,7 +2145,7 @@
s = tmp;
s1 = strsep(&s,",");
s2 = strsep(&s,",");
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
l = myrpt->links.next;
/* try to find this one in queue */
while(l != &myrpt->links){
@@ -1877,7 +2165,7 @@
strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1);
l->retries = MAX_RETRIES + 1;
l->disced = 1;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
wf.frametype = AST_FRAME_TEXT;
wf.subclass = 0;
wf.offset = 0;
@@ -1894,7 +2182,7 @@
rpt_telemetry(myrpt, COMPLETE, NULL);
return DC_COMPLETE;
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
return DC_COMPLETE;
case 2: /* Link Monitor */
if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
@@ -1909,7 +2197,7 @@
s = tmp;
s1 = strsep(&s,",");
s2 = strsep(&s,",");
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
l = myrpt->links.next;
/* try to find this one in queue */
while(l != &myrpt->links){
@@ -1928,24 +2216,27 @@
{
/* if already in this mode, just ignore */
if ((!l->mode) || (!l->chan)) {
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt,REMALREADY,NULL);
return DC_COMPLETE;
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
l->retries = MAX_RETRIES + 1;
l->disced = 2;
modechange = 1;
} else
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1);
- /* establish call in monitor mode */
- if (!(l = ast_calloc(1, sizeof(*l)))) {
+ /* establish call in monitor mode */
+ l = malloc(sizeof(struct rpt_link));
+ if (!l){
+ ast_log(LOG_WARNING, "Unable to malloc\n");
return DC_ERROR;
}
/* zero the silly thing */
+ memset((char *)l,0,sizeof(struct rpt_link));
snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
tele = strchr(deststr,'/');
if (!tele){
@@ -1981,7 +2272,8 @@
return DC_ERROR;
}
/* allocate a pseudo-channel thru asterisk */
- if (!(l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL))) {
+ l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
+ if (!l->pchan){
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
ast_hangup(l->chan);
free(l);
@@ -2002,10 +2294,10 @@
free(l);
return DC_ERROR;
}
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
/* insert at end of queue */
insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt,COMPLETE,NULL);
return DC_COMPLETE;
case 3: /* Link transceive */
@@ -2021,7 +2313,7 @@
s = tmp;
s1 = strsep(&s,",");
s2 = strsep(&s,",");
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
l = myrpt->links.next;
/* try to find this one in queue */
while(l != &myrpt->links){
@@ -2039,22 +2331,26 @@
if (l != &myrpt->links){
/* if already in this mode, just ignore */
if ((l->mode) || (!l->chan)) {
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt, REMALREADY, NULL);
return DC_COMPLETE;
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV);
l->retries = MAX_RETRIES + 1;
l->disced = 2;
modechange = 1;
} else
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1);
/* establish call in tranceive mode */
- if (!(l = ast_calloc(1, sizeof(*l)))) {
+ l = malloc(sizeof(struct rpt_link));
+ if (!l){
+ ast_log(LOG_WARNING, "Unable to malloc\n");
return(DC_ERROR);
}
+ /* zero the silly thing */
+ memset((char *)l,0,sizeof(struct rpt_link));
l->mode = 1;
l->outbound = 1;
strncpy(l->name, digitbuf, MAXNODESTR - 1);
@@ -2092,7 +2388,8 @@
return DC_ERROR;
}
/* allocate a pseudo-channel thru asterisk */
- if (!(l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL))) {
+ l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
+ if (!l->pchan){
fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
ast_hangup(l->chan);
free(l);
@@ -2113,10 +2410,10 @@
free(l);
return DC_ERROR;
}
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
/* insert at end of queue */
insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt,COMPLETE,NULL);
return DC_COMPLETE;
case 4: /* Enter Command Mode */
@@ -2141,10 +2438,10 @@
break;
}
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
strcpy(myrpt->lastlinknode,digitbuf);
strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt, REMGO, NULL);
return DC_COMPLETE;
@@ -2186,7 +2483,7 @@
if(debug)
printf("@@@@ Autopatch up\n");
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
/* if on call, force * into current audio stream */
@@ -2194,13 +2491,13 @@
myrpt->mydtmf = myrpt->funcchar;
}
if (myrpt->callmode){
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
return DC_COMPLETE;
}
myrpt->callmode = 1;
myrpt->cidx = 0;
myrpt->exten[myrpt->cidx] = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt);
@@ -2219,15 +2516,15 @@
if(debug)
printf("@@@@ Autopatch down\n");
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
if (!myrpt->callmode){
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
return DC_COMPLETE;
}
myrpt->callmode = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt, TERM, NULL);
return DC_COMPLETE;
}
@@ -2239,10 +2536,9 @@
static int function_status(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
{
- if(!param)
+ if (!param)
return DC_ERROR;
-
-
+
if (!myrpt->enable)
return DC_ERROR;
@@ -2262,6 +2558,53 @@
return DC_ERROR;
}
return DC_INDETERMINATE;
+}
+
+/*
+* Macro-oni (without Salami)
+*/
+
+static int function_macro(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
+{
+
+char *val;
+int i;
+struct ast_channel *mychannel;
+
+ if ((!myrpt->remote) && (!myrpt->enable))
+ return DC_ERROR;
+
+ if(debug)
+ printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
+
+ mychannel = myrpt->remchannel;
+
+ if(strlen(digitbuf) < 1) /* 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->startupmacro;
+ else val = ast_variable_retrieve(cfg, myrpt->macro, digitbuf);
+ /* param was 1 for local buf */
+ if (!val){
+ rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL);
+ return DC_COMPLETE;
+ }
+ rpt_mutex_lock(&myrpt->lock);
+ if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val))
+ {
+ rpt_mutex_unlock(&myrpt->lock);
+ rpt_telemetry(myrpt, MACRO_BUSY, NULL);
+ return DC_ERROR;
+ }
+ myrpt->macrotimer = MACROTIME;
+ strncat(myrpt->macrobuf,val,MAXMACRO - 1);
+ rpt_mutex_unlock(&myrpt->lock);
+ return DC_COMPLETE;
}
/*
@@ -2476,7 +2819,7 @@
}
return;
}
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
if (c == myrpt->endchar) myrpt->stopgen = 1;
if (myrpt->callmode == 1)
{
@@ -2486,7 +2829,9 @@
if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
{
myrpt->callmode = 2;
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt,PROC,NULL);
+ rpt_mutex_lock(&myrpt->lock);
}
/* if can continue, do so */
if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
@@ -2504,7 +2849,7 @@
myrpt->rem_dtmfidx = 0;
myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
time(&myrpt->rem_dtmf_time);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
return;
}
else if ((c != myrpt->endchar) && (myrpt->rem_dtmfidx >= 0))
@@ -2515,10 +2860,10 @@
myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink);
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
switch(res){
@@ -2547,7 +2892,7 @@
}
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
return;
}
@@ -2558,13 +2903,13 @@
char cmd[300];
int res;
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
if (c == myrpt->endchar)
{
if (mylink->lastrx)
{
mylink->lastrx = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
return;
}
myrpt->stopgen = 1;
@@ -2573,15 +2918,14 @@
myrpt->cmdnode[0] = 0;
myrpt->dtmfidx = -1;
myrpt->dtmfbuf[0] = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt,COMPLETE,NULL);
- ast_mutex_unlock(&myrpt->lock);
return;
}
}
if (myrpt->cmdnode[0])
{
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
send_link_dtmf(myrpt,c);
return;
}
@@ -2593,7 +2937,9 @@
if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
{
myrpt->callmode = 2;
+ rpt_mutex_unlock(&myrpt->lock);
rpt_telemetry(myrpt,PROC,NULL);
+ rpt_mutex_lock(&myrpt->lock);
}
/* if can continue, do so */
if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
@@ -2611,7 +2957,7 @@
myrpt->rem_dtmfidx = 0;
myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
time(&myrpt->rem_dtmf_time);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
return;
}
else if ((c != myrpt->endchar) && (myrpt->rem_dtmfidx >= 0))
@@ -2622,11 +2968,25 @@
myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
- res = collect_function_digits(myrpt, cmd,
- ((mylink->phonemode == 2) ? SOURCE_DPHONE : SOURCE_PHONE), mylink);
- ast_mutex_lock(&myrpt->lock);
+ switch(mylink->phonemode)
+ {
+ case 1:
+ res = collect_function_digits(myrpt, cmd,
+ SOURCE_PHONE, mylink);
+ break;
+ case 2:
+ res = collect_function_digits(myrpt, cmd,
+ SOURCE_DPHONE,mylink);
+ break;
+ default:
+ res = collect_function_digits(myrpt, cmd,
+ SOURCE_LNK, mylink);
+ break;
+ }
+
+ rpt_mutex_lock(&myrpt->lock);
switch(res){
@@ -2659,7 +3019,7 @@
}
}
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
return;
}
@@ -3695,7 +4055,7 @@
return DC_ERROR;
}
- val = ast_variable_retrieve(cfg, MEMORY, digitbuf);
+ val = ast_variable_retrieve(cfg, myrpt->memory, digitbuf);
if (!val){
if (ast_safe_sleep(mychannel,1000) == -1)
return DC_ERROR;
@@ -4527,10 +4887,10 @@
return -1;
}
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
/* remove from queue */
remque((struct qelem *) l);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
strncpy(tmp,val,sizeof(tmp) - 1);
s = tmp;
s1 = strsep(&s,",");
@@ -4566,37 +4926,179 @@
deststr,tele,l->chan->name);
return -1;
}
- ast_mutex_lock(&myrpt->lock);
+ rpt_mutex_lock(&myrpt->lock);
/* put back in queue queue */
insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
- ast_mutex_unlock(&myrpt->lock);
+ rpt_mutex_unlock(&myrpt->lock);
ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name);
return 0;
}
+/* 0 return=continue, 1 return = break, -1 return = error */
+static void local_dtmf_helper(struct rpt *myrpt,char c)
+{
+int res;
+pthread_attr_t attr;
+char cmd[MAXDTMF+1] = "";
+
+ if (c == myrpt->endchar)
+ {
+ /* if in simple mode, kill autopatch */
+ if (myrpt->simple && myrpt->callmode)
+ {
+ rpt_mutex_lock(&myrpt->lock);
+ myrpt->callmode = 0;
+ rpt_mutex_unlock(&myrpt->lock);
+ rpt_telemetry(myrpt,TERM,NULL);
+ return;
+ }
+ rpt_mutex_lock(&myrpt->lock);
+ myrpt->stopgen = 1;
+ if (myrpt->cmdnode[0])
+ {
+ myrpt->cmdnode[0] = 0;
+ myrpt->dtmfidx = -1;
+ myrpt->dtmfbuf[0] = 0;
+ rpt_mutex_unlock(&myrpt->lock);
+ rpt_telemetry(myrpt,COMPLETE,NULL);
+ } else rpt_mutex_unlock(&myrpt->lock);
+ return;
+ }
+ rpt_mutex_lock(&myrpt->lock);
+ if (myrpt->cmdnode[0])
+ {
+ rpt_mutex_unlock(&myrpt->lock);
+ send_link_dtmf(myrpt,c);
+ return;
+ }
+ if (!myrpt->simple)
+ {
+ if (c == myrpt->funcchar)
+ {
+ myrpt->dtmfidx = 0;
+ myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
+ rpt_mutex_unlock(&myrpt->lock);
+ time(&myrpt->dtmf_time);
+ return;
+ }
+ else if ((c != myrpt->endchar) && (myrpt->dtmfidx >= 0))
+ {
+ time(&myrpt->dtmf_time);
+
+ if (myrpt->dtmfidx < MAXDTMF)
+ {
+ myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
+ myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
+
+ strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1);
+
+ rpt_mutex_unlock(&myrpt->lock);
+ res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL);
+ rpt_mutex_lock(&myrpt->lock);
+ switch(res){
+ case DC_INDETERMINATE:
+ break;
+ case DC_REQ_FLUSH:
+ myrpt->dtmfidx = 0;
+ myrpt->dtmfbuf[0] = 0;
+ break;
+ case DC_COMPLETE:
+ myrpt->dtmfbuf[0] = 0;
+ myrpt->dtmfidx = -1;
+ myrpt->dtmf_time = 0;
+ break;
+
+ case DC_ERROR:
+ default:
+ myrpt->dtmfbuf[0] = 0;
+ myrpt->dtmfidx = -1;
+ myrpt->dtmf_time = 0;
+ break;
+ }
+ if(res != DC_INDETERMINATE) {
+ rpt_mutex_unlock(&myrpt->lock);
+ return;
+ }
+ }
+ }
+ }
+ else /* if simple */
+ {
+ if ((!myrpt->callmode) && (c == myrpt->funcchar))
+ {
+ myrpt->callmode = 1;
+ myrpt->cidx = 0;
+ myrpt->exten[myrpt->cidx] = 0;
+ rpt_mutex_unlock(&myrpt->lock);
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt);
+ return;
+ }
+ }
+ if (myrpt->callmode == 1)
+ {
+ myrpt->exten[myrpt->cidx++] = c;
+ myrpt->exten[myrpt->cidx] = 0;
+ /* if this exists */
+ if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
+ {
+ myrpt->callmode = 2;
+ rpt_mutex_unlock(&myrpt->lock);
+ rpt_telemetry(myrpt,PROC,NULL);
+ return;
+ }
+ /* if can continue, do so */
+ if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
+ {
+ /* call has failed, inform user */
+ myrpt->callmode = 4;
+ }
+ rpt_mutex_unlock(&myrpt->lock);
+ return;
+ }
+ if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
+ {
+ myrpt->mydtmf = c;
+ }
+ rpt_mutex_unlock(&myrpt->lock);
+ return;
+}
+
+
+/* place an ID event in the telemetry queue */
+
+static void queue_id(struct rpt *myrpt)
+{
+ myrpt->mustid = myrpt->tailid = 0;
+ myrpt->idtimer = myrpt->idtime; /* Reset our ID timer */
+ rpt_mutex_unlock(&myrpt->lock);
+ rpt_telemetry(myrpt,ID,NULL);
+ rpt_mutex_lock(&myrpt->lock);
+}
+
+
/* single thread with one file (request) to dial */
static void *rpt(void *this)
{
struct rpt *myrpt = (struct rpt *)this;
-char *tele,*idtalkover;
-int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,nonidentqueued,res, tailmessagequeued;
+char *tele,*idtalkover,c;
+int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,nonidentqueued,tailmessagequeued,ctqueued;
struct ast_channel *who;
ZT_CONFINFO ci; /* conference info */
-time_t dtmf_time,t;
+time_t t;
struct rpt_link *l,*m;
struct rpt_tele *telem;
-pthread_attr_t attr;
char tmpstr[300];
-char cmd[MAXDTMF+1] = "";
-
-
- ast_mutex_lock(&myrpt->lock);
+
+
+ rpt_mutex_lock(&myrpt->lock);
[... 1144 lines stripped ...]
More information about the asterisk-commits
mailing list