[asterisk-commits] jdixon: branch jdixon/chan_usbradio-1.4 r159699 - /team/jdixon/chan_usbradio-...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Nov 26 18:48:35 CST 2008


Author: jdixon
Date: Wed Nov 26 18:48:35 2008
New Revision: 159699

URL: http://svn.digium.com/view/asterisk?view=rev&rev=159699
Log:
Brought 0.172 up into production release

Modified:
    team/jdixon/chan_usbradio-1.4/apps/app_rpt.c

Modified: team/jdixon/chan_usbradio-1.4/apps/app_rpt.c
URL: http://svn.digium.com/view/asterisk/team/jdixon/chan_usbradio-1.4/apps/app_rpt.c?view=diff&rev=159699&r1=159698&r2=159699
==============================================================================
--- team/jdixon/chan_usbradio-1.4/apps/app_rpt.c (original)
+++ team/jdixon/chan_usbradio-1.4/apps/app_rpt.c Wed Nov 26 18:48:35 2008
@@ -1,6 +1,5 @@
 /* #define	NEW_ASTERISK */
 /* #define OLD_ASTERISK */
-
 /*
  * Asterisk -- An open source telephony toolkit.
  *
@@ -22,7 +21,7 @@
 /*! \file
  *
  * \brief Radio Repeater / Remote Base program 
- *  version 0.153 10/18/08 
+ *  version 0.172 11/26/08 
  * 
  * \author Jim Dixon, WB6NIL <jim at lambdatel.com>
  *
@@ -91,6 +90,13 @@
  *  30 - Recall Memory Setting in Attached Xcvr
  *  31 - Channel Selector for Parallel Programmed Xcvr
  *  32 - Touchtone pad test: command + Digit string + # to playback all digits pressed
+ *  33 - Local Telemetry Output Enable
+ *  34 - Local Telemetry Output Disable
+ *  35 - Local Telemetry Output on Demand
+ *  36 - Foreign Link Local Output Path Enable
+ *  37 - Foreign Link Local Output Path Disable
+ *  38 - Foreign Link Local Output Path Follows Local Telemetry
+ *  39 - Foreign Link Local Output Path on Demand
  *
  * ilink cmds:
  *
@@ -192,6 +198,7 @@
 #define	TOPKEYN 32
 #define	TOPKEYWAIT 3
 #define	TOPKEYMAXSTR 30
+#define	NEWKEYTIME 2000
 
 #define	AUTHTELLTIME 7000
 #define	AUTHTXTIME 1000
@@ -249,6 +256,9 @@
 
 #define	PARROTTIME 1000
 
+#define	TELEM_HANG_TIME 120000
+#define	LINK_HANG_TIME 120000
+
 #define	DEFAULT_IOBASE 0x378
 
 #define	DEFAULT_CIV_ADDR 0x58
@@ -266,7 +276,7 @@
 
 #define ACTIONSIZE 32
 
-#define TELEPARAMSIZE 256
+#define TELEPARAMSIZE 400
 
 #define REM_SCANTIME 100
 
@@ -294,6 +304,9 @@
 
 enum {REM_OFF,REM_MONITOR,REM_TX};
 
+enum {LINKMODE_OFF,LINKMODE_ON,LINKMODE_FOLLOW,LINKMODE_DEMAND,
+	LINKMODE_GUI,LINKMODE_PHONE,LINKMODE_ECHOLINK,LINKMODE_IRLP};
+
 enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
 	CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME, PLAYBACK,
 	LOCALPLAY, STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH,
@@ -301,7 +314,7 @@
 	MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS,
 	REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE, TOPKEY,
 	TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX, PARROT,
-	STATS_TIME_LOCAL};
+	STATS_TIME_LOCAL, VARCMD, LOCUNKEY};
 
 
 enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
@@ -318,6 +331,17 @@
 
 enum {HF_SCAN_OFF,HF_SCAN_DOWN_SLOW,HF_SCAN_DOWN_QUICK,
       HF_SCAN_DOWN_FAST,HF_SCAN_UP_SLOW,HF_SCAN_UP_QUICK,HF_SCAN_UP_FAST};
+
+#define	DEFAULT_RPT_TELEMDEFAULT 2
+#define	DEFAULT_RPT_TELEMDYNAMIC 1
+#define	DEFAULT_GUI_LINK_MODE LINKMODE_ON
+#define	DEFAULT_GUI_LINK_MODE_DYNAMIC 1
+#define	DEFAULT_PHONE_LINK_MODE LINKMODE_ON
+#define	DEFAULT_PHONE_LINK_MODE_DYNAMIC 1
+#define	DEFAULT_ECHOLINK_LINK_MODE LINKMODE_DEMAND
+#define	DEFAULT_ECHOLINK_LINK_MODE_DYNAMIC 1
+#define	DEFAULT_IRLP_LINK_MODE LINKMODE_DEMAND
+#define	DEFAULT_IRLP_LINK_MODE_DYNAMIC 1
 
 #include "asterisk.h"
 
@@ -383,7 +407,7 @@
 /*! Stop the tones from playing */
 void ast_playtones_stop(struct ast_channel *chan);
 
-static  char *tdesc = "Radio Repeater / Remote Base  version 0.153  10/18/2008";
+static  char *tdesc = "Radio Repeater / Remote Base  version 0.172  11/26/2008";
 
 static char *app = "Rpt";
 
@@ -582,10 +606,17 @@
 	int voxtotimer;
 	char voxtostate;
 	char newkey;
+	int linkmode;
+	int newkeytimer;
 #ifdef OLD_ASTERISK
         AST_LIST_HEAD(, ast_frame) rxq;
 #else
 	AST_LIST_HEAD_NOLOCK(, ast_frame) rxq;
+#endif
+#ifdef OLD_ASTERISK
+        AST_LIST_HEAD(, ast_frame) textq;
+#else
+	AST_LIST_HEAD_NOLOCK(, ast_frame) textq;
 #endif
 } ;
 
@@ -745,8 +776,14 @@
 		int voxrecover_ms;
 		int simplexpatchdelay;
 		int simplexphonedelay;
+		char telemdefault;
+		char telemdynamic;		
 		char *statpost_program;
 		char *statpost_url;
+		char linkmode[10];
+		char linkmodedynamic[10];
+		char *locallist[16];
+		int nlocallist;
 	} p;
 	struct rpt_link links;
 	int unkeytocttimer;
@@ -774,6 +811,7 @@
 	char parrotstate;
 	int  parrottimer;
 	unsigned int parrotcnt;
+	int telemmode;
 	struct ast_channel *rxchannel,*txchannel, *monchannel, *parrotchannel;
 	struct ast_channel *pchannel,*txpchannel, *zaprxchannel, *zaptxchannel;
 	struct ast_channel *voxchannel;
@@ -850,6 +888,7 @@
 	char newkey;
 	char inpadtest;
 	long rxlingertimer;
+	char localoverride;
 #ifdef OLD_ASTERISK
 	AST_LIST_HEAD(, ast_frame) txq;
 #else
@@ -1424,8 +1463,99 @@
 /*
 */
 
-
-
+static void init_linkmode(struct rpt *myrpt, struct rpt_link *mylink, int linktype)
+{
+
+	if (!myrpt) return;
+	if (!mylink) return;
+	switch(myrpt->p.linkmode[linktype])
+	{
+	    case LINKMODE_OFF:
+		mylink->linkmode = 0;
+		break;
+	    case LINKMODE_ON:
+		mylink->linkmode = 0x7fffffff;
+		break;
+	    case LINKMODE_FOLLOW:
+		mylink->linkmode = 0x7ffffffe;
+		break;
+	    case LINKMODE_DEMAND:
+		mylink->linkmode = 1;
+		break;
+	}
+	return;
+}
+
+static void set_linkmode(struct rpt_link *mylink, int linkmode)
+{
+
+	if (!mylink) return;
+ 	switch(linkmode)
+	{
+	    case LINKMODE_OFF:
+		mylink->linkmode = 0;
+		break;
+	    case LINKMODE_ON:
+		mylink->linkmode = 0x7fffffff;
+		break;
+	    case LINKMODE_FOLLOW:
+		mylink->linkmode = 0x7ffffffe;
+		break;
+	    case LINKMODE_DEMAND:
+		mylink->linkmode = 1;
+		break;
+	}
+	return;
+}
+
+static void rpt_telem_select(struct rpt *myrpt, int command_source, struct rpt_link *mylink)
+{
+int	src;
+
+	if (mylink && mylink->chan)
+	{
+		src = LINKMODE_GUI;
+		if (mylink->phonemode) src = LINKMODE_PHONE;
+		else if (!strncasecmp(mylink->chan->name,"echolink",8)) src = LINKMODE_ECHOLINK;
+		else if (!strncasecmp(mylink->chan->name,"irlp",4)) src = LINKMODE_IRLP;
+		if (myrpt->p.linkmodedynamic[src] && (mylink->linkmode >= 1) && 
+		    (mylink->linkmode < 0x7ffffffe))
+				mylink->linkmode = LINK_HANG_TIME;
+	}
+	if (!myrpt->p.telemdynamic) return;
+	if (myrpt->telemmode == 0) return;
+	if (myrpt->telemmode == 0x7fffffff) return;
+	myrpt->telemmode = TELEM_HANG_TIME;
+	return;
+}
+
+static int altlink(struct rpt *myrpt,struct rpt_link *mylink)
+{
+	if (!myrpt) return(0);
+	if (!mylink) return(0);
+	if (!mylink->chan) return(0);
+	/* if doesnt qual as a foreign link */
+	if ((mylink->name[0] != '0') && (!mylink->phonemode) &&
+	    strncasecmp(mylink->chan->name,"echolink",8) &&
+		strncasecmp(mylink->chan->name,"irlp",4)) return(0);
+	if ((myrpt->p.duplex < 2) && (myrpt->tele.next == &myrpt->tele)) return(0);
+	if (mylink->linkmode < 2) return(0);
+	if (mylink->linkmode == 0x7fffffff) return(1);
+	if (mylink->linkmode < 0x7ffffffe) return(1);
+	if (myrpt->telemmode > 1) return(1);
+	return(0);
+}
+
+static void rpt_qwrite(struct rpt_link *l,struct ast_frame *f)
+{
+struct	ast_frame *f1;
+
+	if (!l->chan) return;
+	f1 = ast_frdup(f);
+	memset(&f1->frame_list,0,sizeof(f1->frame_list));
+	AST_LIST_INSERT_TAIL(&l->textq,f1,frame_list);
+	return;
+}
 
 static int linkcount(struct rpt *myrpt)
 {
@@ -1798,6 +1928,7 @@
 	wf.mallocd = 0;
 	wf.datalen = strlen(str) + 1;
 	wf.samples = 0;
+	wf.src = "mdc1200_send";
 
 
 	l = myrpt->links.next;
@@ -1810,7 +1941,7 @@
 			continue;
 		}
 		wf.data = str;
-		if (l->chan) ast_write(l->chan,&wf); 
+		if (l->chan) rpt_qwrite(l,&wf); 
 		l = l->next;
 	}
 	return;
@@ -1936,6 +2067,7 @@
 	wf.datalen = strlen(txt) + 1;
 	wf.data = txt;
 	wf.samples = 0;
+	wf.src = "send_usb_txt";
 	ast_write(myrpt->txchannel,&wf); 
 	return 0;
 }
@@ -2474,6 +2606,52 @@
 
 	}
 #endif
+	val = (char *) ast_variable_retrieve(cfg,this,"telemdefault");
+	if (val) rpt_vars[n].p.telemdefault = (ast_true(val) != 0) + 1;
+	else rpt_vars[n].p.telemdefault = DEFAULT_RPT_TELEMDEFAULT;
+	val = (char *) ast_variable_retrieve(cfg,this,"telemdynamic");
+	if (val) rpt_vars[n].p.telemdynamic = ast_true(val);
+	else rpt_vars[n].p.telemdynamic = DEFAULT_RPT_TELEMDYNAMIC;
+	if (rpt_vars[n].p.telemdefault == 1) 
+		rpt_vars[n].telemmode = 0;
+	else if (rpt_vars[n].p.telemdefault > 1)
+		rpt_vars[n].telemmode = 0x7fffffff;
+	else rpt_vars[n].telemmode = 1;
+
+	val = (char *) ast_variable_retrieve(cfg,this,"guilinkdefault");
+	if (val) rpt_vars[n].p.linkmode[LINKMODE_GUI] = atoi(val) + 3;
+	else rpt_vars[n].p.linkmode[LINKMODE_GUI] = DEFAULT_GUI_LINK_MODE;
+	val = (char *) ast_variable_retrieve(cfg,this,"guilinkdynamic");
+	if (val) rpt_vars[n].p.linkmodedynamic[LINKMODE_GUI] = ast_true(val);
+	else rpt_vars[n].p.linkmodedynamic[LINKMODE_GUI] = DEFAULT_GUI_LINK_MODE_DYNAMIC;
+
+	val = (char *) ast_variable_retrieve(cfg,this,"phonelinkdefault");
+	if (val) rpt_vars[n].p.linkmode[LINKMODE_PHONE] = atoi(val) + 3;
+	else rpt_vars[n].p.linkmode[LINKMODE_PHONE] = DEFAULT_PHONE_LINK_MODE;
+	val = (char *) ast_variable_retrieve(cfg,this,"phonelinkdynamic");
+	if (val) rpt_vars[n].p.linkmodedynamic[LINKMODE_PHONE] = ast_true(val);
+	else rpt_vars[n].p.linkmodedynamic[LINKMODE_PHONE] = DEFAULT_PHONE_LINK_MODE_DYNAMIC;
+
+	val = (char *) ast_variable_retrieve(cfg,this,"echolinkdefault");
+	if (val) rpt_vars[n].p.linkmode[LINKMODE_ECHOLINK] = atoi(val) + 3;
+	else rpt_vars[n].p.linkmode[LINKMODE_ECHOLINK] = DEFAULT_ECHOLINK_LINK_MODE;
+	val = (char *) ast_variable_retrieve(cfg,this,"echolinkdynamic");
+	if (val) rpt_vars[n].p.linkmodedynamic[LINKMODE_ECHOLINK] = ast_true(val);
+	else rpt_vars[n].p.linkmodedynamic[LINKMODE_ECHOLINK] = DEFAULT_ECHOLINK_LINK_MODE_DYNAMIC;
+
+	val = (char *) ast_variable_retrieve(cfg,this,"irlplinkdefault");
+	if (val) rpt_vars[n].p.linkmode[LINKMODE_IRLP] = atoi(val) + 3;
+	else rpt_vars[n].p.linkmode[LINKMODE_IRLP] = DEFAULT_IRLP_LINK_MODE;
+	val = (char *) ast_variable_retrieve(cfg,this,"irlplinkdynamic");
+	if (val) rpt_vars[n].p.linkmodedynamic[LINKMODE_IRLP] = ast_true(val);
+	else rpt_vars[n].p.linkmodedynamic[LINKMODE_IRLP] = DEFAULT_IRLP_LINK_MODE_DYNAMIC;
+
+	val = (char *) ast_variable_retrieve(cfg,this,"locallist");
+	if (val) {
+		memset(rpt_vars[n].p.locallist,0,sizeof(rpt_vars[n].p.locallist));
+		rpt_vars[n].p.nlocallist = finddelim(val,rpt_vars[n].p.locallist,16);
+	}
+
 	val = (char *) ast_variable_retrieve(cfg,this,"inxlat");
 	if (val) {
 		memset(&rpt_vars[n].p.inxlat,0,sizeof(struct rpt_xlat));
@@ -3820,13 +3998,26 @@
 	return res;
 }
 
+static int sayphoneticstr(struct ast_channel *mychannel,char *str)
+{
+int	res;
+
+	res = ast_say_phonetic_str(mychannel,str,NULL,mychannel->language);
+	if (!res) 
+		res = ast_waitstream(mychannel, "");
+	else
+		 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
+	ast_stopstream(mychannel);
+	return res;
+}
+
 /* say a node and nodename. Try to look in dir referred to by nodenames in
 config, and see if there's a custom node file to play, and if so, play it */
 
 static int saynode(struct rpt *myrpt, struct ast_channel *mychannel, char *name)
 {
 int	res;
-char	*val,fname[300];
+char	*val,fname[300],dbstr[100],actstr[100];
 
 	val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "nodenames");
 	if (!val) val = NODENAMES;
@@ -3836,6 +4027,11 @@
 	res = sayfile(mychannel,"rpt/node");
 	if (!res) 
 		res = ast_say_character_str(mychannel,name,NULL,mychannel->language);
+	if (name[0] != '3') return res;
+	if (ast_db_get(EL_DB_ROOT,"active",actstr,sizeof(actstr) - 1)) return res;
+	sprintf(dbstr,"%s/nodenum-call/%d",actstr,atoi(name + 1));
+	if (ast_db_get(EL_DB_ROOT,dbstr,fname,sizeof(fname))) return res;
+	res = sayphoneticstr(mychannel,fname);
 	return res;
 }
 
@@ -4038,6 +4234,239 @@
 
 static int split_freq(char *mhz, char *decimals, char *freq);
 
+static void handle_varcmd_tele(struct rpt *myrpt,struct ast_channel *mychannel,char *varcmd)
+{
+char	*strs[100],*p;
+int	i,n,res,vmajor,vminor;
+time_t	t;
+unsigned int t1;
+struct	tm localtm;
+
+	n = finddelim(varcmd,strs,100);
+	if (n < 1) return;
+	if (!strcasecmp(strs[0],"REMGO"))
+	{
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		sayfile(mychannel, "rpt/remote_go");
+		return;
+	}
+	if (!strcasecmp(strs[0],"REMALREADY"))
+	{
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		sayfile(mychannel, "rpt/remote_already");
+		return;
+	}
+	if (!strcasecmp(strs[0],"REMNOTFOUND"))
+	{
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		sayfile(mychannel, "rpt/remote_notfound");
+		return;
+	}
+	if (!strcasecmp(strs[0],"COMPLETE"))
+	{
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
+		if (!res) 
+			res = ast_waitstream(mychannel, "");
+		else
+			 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
+		ast_stopstream(mychannel);
+		return;
+	}
+	if (!strcasecmp(strs[0],"PROC"))
+	{
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		res = telem_lookup(myrpt, mychannel, myrpt->name, "patchup");
+		if(res < 0){ /* Then default message */
+			sayfile(mychannel, "rpt/callproceeding");
+		}
+		return;
+	}
+	if (!strcasecmp(strs[0],"TERM"))
+	{
+		/* wait a little bit longer */
+		wait_interval(myrpt, DLY_CALLTERM, mychannel);
+		res = telem_lookup(myrpt, mychannel, myrpt->name, "patchdown");
+		if(res < 0){ /* Then default message */
+			sayfile(mychannel, "rpt/callterminated");
+		}
+		return;
+	}
+	if (!strcasecmp(strs[0],"MACRO_NOTFOUND"))
+	{
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		sayfile(mychannel, "rpt/macro_notfound");
+		return;
+	}
+	if (!strcasecmp(strs[0],"MACRO_BUSY"))
+	{
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		sayfile(mychannel, "rpt/macro_busy");
+		return;
+	}
+	if (!strcasecmp(strs[0],"CONNECTED"))
+	{
+
+		if (n < 3) return;
+		wait_interval(myrpt, DLY_TELEM,  mychannel);
+		res = saynode(myrpt,mychannel,strs[2]);
+		if (!res)
+		    res = ast_streamfile(mychannel, "rpt/connected", mychannel->language);
+		if (!res) 
+			res = ast_waitstream(mychannel, "");
+		else
+			 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
+		ast_stopstream(mychannel);
+		res = ast_streamfile(mychannel, "digits/2", mychannel->language);
+		if (!res) 
+			res = ast_waitstream(mychannel, "");
+		else
+			 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
+		ast_stopstream(mychannel);
+		saynode(myrpt,mychannel,strs[1]);
+		return;
+	}
+	if (!strcasecmp(strs[0],"CONNFAIL"))
+	{
+
+		if (n < 2) return;			
+		res = saynode(myrpt,mychannel,strs[1]);
+		if (!res) 
+		   sayfile(mychannel, "rpt/connection_failed");
+		return;
+	}
+	if (!strcasecmp(strs[0],"REMDISC"))
+	{
+
+		if (n < 2) return;			
+		res = saynode(myrpt,mychannel,strs[1]);
+		if (!res) 
+		   sayfile(mychannel, "rpt/remote_disc");
+		return;
+	}
+	if (!strcasecmp(strs[0],"STATS_TIME"))
+	{
+		if (n < 2) return;
+		if (sscanf(strs[1],"%u",&t1) != 1) return;
+		t = t1;
+	    	wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
+		rpt_localtime(&t, &localtm);
+		/* Say the phase of the day is before the time */
+		if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12))
+			p = "rpt/goodmorning";
+		else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18))
+			p = "rpt/goodafternoon";
+		else
+			p = "rpt/goodevening";
+		if (sayfile(mychannel,p) == -1) return;
+		/* Say the time is ... */		
+		if (sayfile(mychannel,"rpt/thetimeis") == -1) return;
+		/* Say the time */				
+	    	res = ast_say_time(mychannel, t, "", mychannel->language);
+		if (!res) 
+			res = ast_waitstream(mychannel, "");
+		ast_stopstream(mychannel);		
+		return;
+	}		
+	if (!strcasecmp(strs[0],"STATS_VERSION"))
+	{
+		if (n < 2) return;
+		if(sscanf(strs[1], "%d.%d", &vmajor, &vminor) != 2) return;
+    		wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
+		/* Say "version" */
+		if (sayfile(mychannel,"rpt/version") == -1) return;
+		res = ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL);
+		if (!res) 
+			res = ast_waitstream(mychannel, "");
+		ast_stopstream(mychannel);	
+		if (saycharstr(mychannel,".") == -1) return;
+		if(!res) /* Say "Y" */
+			ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL);
+		if (!res){
+			res = ast_waitstream(mychannel, "");
+			ast_stopstream(mychannel);
+		}	
+		else
+			 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
+		return;
+	}		
+	if (!strcasecmp(strs[0],"ARB_ALPHA"))
+	{
+		if (n < 2) return;
+	    	wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
+	    	saycharstr(mychannel, strs[1]);
+		return;
+	}		
+	if (!strcasecmp(strs[0],"REV_PATCH"))
+	{
+		/* Parts of this section taken from app_parkandannounce */
+		char *tpl_working, *tpl_current, *tpl_copy;
+		char *tmp[100], *myparm;
+		int looptemp=0,i=0, dres = 0;
+
+		if (n < 3) return;
+	    	wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
+	
+
+		tpl_working = ast_strdup(strs[2]);
+		tpl_copy = tpl_working;
+		myparm = strsep(&tpl_working,"^");
+		tpl_current=strsep(&tpl_working, ":");
+		while(tpl_current && looptemp < sizeof(tmp)) {
+			tmp[looptemp]=tpl_current;
+			looptemp++;
+			tpl_current=strsep(&tpl_working,":");
+		}
+		for(i=0; i<looptemp; i++) {
+			if(!strcmp(tmp[i], "PARKED")) {
+				ast_say_digits(mychannel, atoi(myparm), "", mychannel->language);
+			} else if(!strcmp(tmp[i], "NODE")) {
+				ast_say_digits(mychannel, atoi(strs[1]), "", mychannel->language);
+			} else {
+				dres = ast_streamfile(mychannel, tmp[i], mychannel->language);
+				if(!dres) {
+					dres = ast_waitstream(mychannel, "");
+				} else {
+					ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name);
+					dres = 0;
+				}
+			}
+		}
+		ast_free(tpl_copy);
+		return;
+	}
+	if (!strcasecmp(strs[0],"LASTNODEKEY"))
+	{
+		if (n < 2) return;
+		if (!atoi(strs[1])) return;
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		saynode(myrpt,mychannel,strs[1]);
+		return;
+	}
+	if (!strcasecmp(strs[0],"STATUS"))
+	{
+		if (n < 3) return;
+		wait_interval(myrpt, DLY_TELEM, mychannel);
+		saynode(myrpt,mychannel,strs[1]);
+		if (atoi(strs[2]) > 0) sayfile(mychannel, "rpt/autopatch_on");
+		else if (n == 3)
+		{
+			sayfile(mychannel,"rpt/repeat_only");
+			return;
+		}
+		for(i = 3; i < n; i++)
+		{
+			saynode(myrpt,mychannel,strs[i] + 1);
+			if (*strs[i] == 'T') sayfile(mychannel,"rpt/tranceive");
+			else if (*strs[i] == 'R') sayfile(mychannel,"rpt/monitor");
+			else sayfile(mychannel,"rpt/connecting");
+		}
+		return;
+	}
+	ast_log(LOG_WARNING,"Got unknown link telemetry command: %s\n",strs[0]);
+	return;
+}
+
 static void *rpt_tele_thread(void *this)
 {
 ZT_CONFINFO ci;  /* conference info */
@@ -4131,7 +4560,7 @@
 	rpt_mutex_unlock(&myrpt->lock);
 
 	while((mytele->mode != SETREMOTE) && (mytele->mode != UNKEY) &&
-		(mytele->mode != LINKUNKEY))
+		(mytele->mode != LINKUNKEY) && (mytele->mode != LOCUNKEY))
 	{	
                 rpt_mutex_lock(&myrpt->lock);
 		if (!myrpt->active_telem)
@@ -4149,10 +4578,8 @@
 	/* If the telemetry is only intended for a local audience, */
 	/* 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) || (mytele->mode == LINKUNKEY) || (mytele->mode == TIMEOUT) || 
-		(mytele->mode == PARROT) || (mytele->mode == STATS_TIME_LOCAL) || (mytele->mode == LOCALPLAY)) ? 
-		 	myrpt->txconf : myrpt->conf);
+	ci.confno = (((mytele->mode == ID1) || (mytele->mode == PLAYBACK) || (mytele->mode == TEST_TONE)) ? 
+		myrpt->conf : myrpt->txconf);
 	ci.confmode = ZT_CONF_CONFANN;
 	/* first put the channel on the conference in announce mode */
 	if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
@@ -4173,6 +4600,10 @@
 	ast_stopstream(mychannel);
 	switch(mytele->mode)
 	{
+	    case VARCMD:
+		handle_varcmd_tele(myrpt,mychannel,mytele->param);
+		imdone = 1;
+		break;
 	    case ID:
 	    case ID1:
 		if (*ident)
@@ -4229,6 +4660,7 @@
 		res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language);
 		break;
 	    case UNKEY:
+	    case LOCUNKEY:
 		if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */
 			imdone = 1;
 			break;
@@ -4253,7 +4685,8 @@
                 {
                         rpt_mutex_lock(&myrpt->lock);
                         while(tlist != &myrpt->tele){
-                                if (tlist->mode == UNKEY) unkeys_queued++;
+                                if ((tlist->mode == UNKEY) || 
+				    (tlist->mode == LOCUNKEY)) unkeys_queued++;
                                 tlist = tlist->next;
                         }
                         rpt_mutex_unlock(&myrpt->lock);
@@ -4295,6 +4728,19 @@
 		myrpt->totalkerchunks++;
 		rpt_mutex_unlock(&myrpt->lock);
 	
+		if ((mytele->mode == LOCUNKEY) &&
+		    ((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "localct")))) { /* Local override ct */
+			ct_copy = ast_strdup(ct);
+			if(ct_copy)
+			{
+				res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
+				ast_free(ct_copy);
+			}
+			else
+				res = -1;
+			if(res)
+			 	ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);		
+		}
 		haslink = 0;
 		hastx = 0;
 		hasremote = 0;		
@@ -5336,20 +5782,29 @@
 	pthread_exit(NULL);
 }
 
+static void send_tele_link(struct rpt *myrpt,char *cmd);
+
 static void rpt_telemetry(struct rpt *myrpt,int mode, void *data)
 {
 struct rpt_tele *tele;
 struct rpt_link *mylink = NULL;
-int res;
+int res,vmajor,vminor,i;
 pthread_attr_t attr;
-char *v1, *v2;
+char *v1, *v2,mystr[300],*p,haslink;
+time_t	t;
+struct rpt_link *l;
+
 
 	if(debug > 6)
 		ast_log(LOG_NOTICE,"mode=%i  data=%s\n",mode, (char *)data);
 
 	switch(mode)
 	{
+	    case VARCMD:
+		if (myrpt->telemmode < 2) return; 
+		break;
 	    case UNKEY:
+	    case LOCUNKEY:
 		/* if any of the following are defined, go ahead and do it,
 		   otherwise, dont bother */
 		v1 = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, 
@@ -5369,6 +5824,138 @@
 	    default:
 		break;
 	}
+	l = myrpt->links.next;
+	res = 0;
+	if (l && (l != &myrpt->links))
+	{
+		if (l->chan && (l->name[0] != '0') && (l->newkey == 1)) res = 1;
+		l = l->next;
+	}
+	if (!res) /* no-one on without newkey */
+	{
+		/* send appropriate commands to everyone on link(s) */
+		switch(mode)
+		{
+
+		    case REMGO:
+			send_tele_link(myrpt,"REMGO");
+			return;
+		    case REMALREADY:
+			send_tele_link(myrpt,"REMALREADY");
+			return;
+		    case REMNOTFOUND:
+			send_tele_link(myrpt,"REMNOTFOUND");
+			return;
+		    case COMPLETE:
+			send_tele_link(myrpt,"COMPLETE");
+			return;
+		    case PROC:
+			send_tele_link(myrpt,"PROC");
+			return;
+		    case TERM:
+			send_tele_link(myrpt,"TERM");
+			return;
+		    case MACRO_NOTFOUND:
+			send_tele_link(myrpt,"MACRO_NOTFOUND");
+			return;
+		    case MACRO_BUSY:
+			send_tele_link(myrpt,"MACRO_BUSY");
+			return;
+		    case CONNECTED:
+			mylink = (struct rpt_link *) data;
+			if ((!mylink) || (mylink->name[0] == '0')) return;
+			sprintf(mystr,"CONNECTED,%s,%s",myrpt->name,mylink->name);
+			send_tele_link(myrpt,mystr);
+			return;
+		    case CONNFAIL:
+			mylink = (struct rpt_link *) data;
+			if ((!mylink) || (mylink->name[0] == '0')) return;
+			sprintf(mystr,"CONNFAIL,%s",mylink->name);
+			send_tele_link(myrpt,mystr);
+			return;
+		    case REMDISC:
+			mylink = (struct rpt_link *) data;
+			if ((!mylink) || (mylink->name[0] == '0')) return;
+			l = myrpt->links.next;
+			haslink = 0;
+			/* dont report if a link for this one still on system */
+			if (l != &myrpt->links)
+			{
+				rpt_mutex_lock(&myrpt->lock);
+				while(l != &myrpt->links)
+				{
+					if (l->name[0] == '0')
+					{
+						l = l->next;
+						continue;
+					}
+					if (!strcmp(l->name,mylink->name))
+					{
+						haslink = 1;
+						break;
+					}
+					l = l->next;
+				}
+				rpt_mutex_unlock(&myrpt->lock);
+			}
+			if (haslink) return;
+			sprintf(mystr,"REMDISC,%s",mylink->name);
+			send_tele_link(myrpt,mystr);
+			return;
+		    case STATS_TIME:
+			t = time(NULL);
+			sprintf(mystr,"STATS_TIME,%u",(unsigned int) t);
+			send_tele_link(myrpt,mystr);
+			return;
+		    case STATS_VERSION:
+			p = strstr(tdesc, "version");	
+			if (!p) return;
+			if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2)
+				return;
+			sprintf(mystr,"STATS_VERSION,%d.%d",vmajor,vminor);
+			send_tele_link(myrpt,mystr);
+			return;
+		    case ARB_ALPHA:
+			sprintf(mystr,"ARB_ALPHA,%s",(char *)data);
+			send_tele_link(myrpt,mystr);
+			return;
+		    case REV_PATCH:
+			p = (char *)data;
+			for(i = 0; p[i]; i++) if (p[i] == ',') p[i] = '^';
+			sprintf(mystr,"REV_PATCH,%s,%s",myrpt->name,p);
+			send_tele_link(myrpt,mystr);
+			return;
+		    case LASTNODEKEY:
+			if (!myrpt->lastnodewhichkeyedusup[0]) return;
+			sprintf(mystr,"LASTNODEKEY,%s",myrpt->lastnodewhichkeyedusup);
+			send_tele_link(myrpt,mystr);
+			return;
+		    case STATUS:
+			rpt_mutex_lock(&myrpt->lock);
+			sprintf(mystr,"STATUS,%s,%d",myrpt->name,myrpt->callmode);
+			/* make our own list of links */
+			l = myrpt->links.next;
+			while(l != &myrpt->links)
+			{
+				char s;
+
+				if (l->name[0] == '0')
+				{
+					l = l->next;
+					continue;
+				}
+				s = 'T';
+				if (!l->mode) s = 'R';
+				if (!l->thisconnected) s = 'C';
+				snprintf(mystr + strlen(mystr),sizeof(mystr),",%c%s",
+					s,l->name);
+				l = l->next;
+			}
+			rpt_mutex_unlock(&myrpt->lock);
+			send_tele_link(myrpt,mystr);
+			return;
+		}
+	}
 	tele = ast_malloc(sizeof(struct rpt_tele));
 	if (!tele)
 	{
@@ -5390,7 +5977,8 @@
 			memcpy(&tele->mylink,mylink,sizeof(struct rpt_link));
 		}
 	}
-	else if ((mode == ARB_ALPHA) || (mode == REV_PATCH) || (mode == PLAYBACK) || (mode == LOCALPLAY)) {
+	else if ((mode == ARB_ALPHA) || (mode == REV_PATCH) || 
+	    (mode == PLAYBACK) || (mode == LOCALPLAY) || (mode == VARCMD)) {
 		strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
 		tele->param[TELEPARAMSIZE - 1] = 0;
 	}
@@ -5674,16 +6262,22 @@
 		}
 		if (myrpt->mydtmf)
 		{
+			struct ast_channel *c;
 			struct ast_frame wf = {AST_FRAME_DTMF, } ;
+
 			wf.subclass = myrpt->mydtmf;
-			rpt_mutex_unlock(&myrpt->lock);
-			ast_queue_frame(mychannel,&wf);
+			c = ast_bridged_channel(mychannel);
+			if (c && c->_state == AST_STATE_UP)
+			{
+				rpt_mutex_unlock(&myrpt->lock);
+				ast_queue_frame(mychannel,&wf);
 #ifdef	NEW_ASTERISK
-			ast_senddigit(genchannel,myrpt->mydtmf,0);
+				ast_senddigit(genchannel,myrpt->mydtmf,0);
 #else
-			ast_senddigit(genchannel,myrpt->mydtmf);
+				ast_senddigit(genchannel,myrpt->mydtmf);
 #endif
-			rpt_mutex_lock(&myrpt->lock);
+				rpt_mutex_lock(&myrpt->lock);
+			}
 			myrpt->mydtmf = 0;
 		}
 		rpt_mutex_unlock(&myrpt->lock);
@@ -5728,6 +6322,7 @@
 	wf.mallocd = 0;
 	wf.datalen = strlen(str) + 1;
 	wf.samples = 0;
+	wf.src = "send_link_dtmf";
 	l = myrpt->links.next;
 	/* first, see if our dude is there */
 	while(l != &myrpt->links)
@@ -5741,7 +6336,7 @@
 		if (!strcmp(l->name,myrpt->cmdnode))
 		{
 			wf.data = str;
-			if (l->chan) ast_write(l->chan,&wf);
+			if (l->chan) rpt_qwrite(l,&wf);
 			return;
 		}
 		l = l->next;
@@ -5751,7 +6346,7 @@
 	while(l != &myrpt->links)
 	{
 		wf.data = str;
-		if (l->chan) ast_write(l->chan,&wf);
+		if (l->chan) rpt_qwrite(l,&wf);
 		l = l->next;
 	}
 	return;
@@ -5775,14 +6370,41 @@
 	wf.mallocd = 0;
 	wf.datalen = strlen(str) + 1;
 	wf.samples = 0;
+	wf.src = "send_link_keyquery";
 	l = myrpt->links.next;
 	/* give it to everyone */
 	while(l != &myrpt->links)
 	{
 		wf.data = str;
-		if (l->chan) ast_write(l->chan,&wf);
+		if (l->chan) rpt_qwrite(l,&wf);
 		l = l->next;
 	}
+	return;
+}
+
+static void send_tele_link(struct rpt *myrpt,char *cmd)
+{
+char	str[400];
+struct	ast_frame wf;
+struct	rpt_link *l;
+
+	snprintf(str, sizeof(str) - 1, "T %s %s", myrpt->name,cmd);
+	wf.frametype = AST_FRAME_TEXT;
+	wf.subclass = 0;
+	wf.offset = 0;
+	wf.mallocd = 0;
+	wf.datalen = strlen(str) + 1;
+	wf.samples = 0;
+	wf.src = "send_tele_link";
+	l = myrpt->links.next;
+	/* give it to everyone */
+	while(l != &myrpt->links)
+	{
+		wf.data = str;
+		if (l->chan) rpt_qwrite(l,&wf);
+		l = l->next;
+	}
+	rpt_telemetry(myrpt,VARCMD,cmd);
 	return;
 }
 
@@ -5941,6 +6563,9 @@
 	l->isremote = (s && ast_true(s));
 	if (modechange) l->connected = 1;
 	l->hasconnected = l->perma = perma;
+	l->newkeytimer = NEWKEYTIME;
+	l->newkey = 2;
+	if ((strncasecmp(s1,"echolink/",9) == 0) || (strncasecmp(s1,"irlp/",5) == 0)) l->newkey = 0;
 #ifdef ALLOW_LOCAL_CHANNELS
 	if ((strncasecmp(s1,"iax2/", 5) == 0) || (strncasecmp(s1, "local/", 6) == 0) ||
 	    (strncasecmp(s1,"echolink/",9) == 0) || (strncasecmp(s1,"irlp/",5) == 0))
@@ -6043,12 +6668,16 @@
 		return -1;
 	}
 	rpt_mutex_lock(&myrpt->lock);
+	if (node[0] == '4') init_linkmode(myrpt,l,LINKMODE_IRLP);
+	else if (node[0] == '3') init_linkmode(myrpt,l,LINKMODE_ECHOLINK);
+	else l->linkmode = 0;
 	l->reconnects = reconnects;
 	/* insert at end of queue */
 	l->max_retries = MAX_RETRIES;
 	if (perma)
 		l->max_retries = MAX_RETRIES_PERM;
 	if (l->isremote) l->retries = l->max_retries + 1;
+	l->rxlingertimer = RX_LINGER_TIME;
 	insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
 	__kickshort(myrpt);
 	rpt_mutex_unlock(&myrpt->lock);
@@ -6155,19 +6784,18 @@
 				l->disced = 1;
 				l->hasconnected = 1;
 				rpt_mutex_unlock(&myrpt->lock);
+				memset(&wf,0,sizeof(wf));
 				wf.frametype = AST_FRAME_TEXT;
-				wf.subclass = 0;
-				wf.offset = 0;
-				wf.mallocd = 0;
 				wf.datalen = strlen(discstr) + 1;
-				wf.samples = 0;
 				wf.data = discstr;
+				wf.src = "function_ilink:1";
 				if (l->chan)
 				{
-					ast_write(l->chan,&wf);
+					if (l->thisconnected) ast_write(l->chan,&wf);
 					if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR;
 					ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
 				}
+				rpt_telem_select(myrpt,command_source,mylink);
 				rpt_telemetry(myrpt, COMPLETE, NULL);
 				return DC_COMPLETE;
 			}
@@ -6188,6 +6816,7 @@
 					return DC_COMPLETE; /* Silent error */
 
 				case 0:
+					rpt_telem_select(myrpt,command_source,mylink);
 					rpt_telemetry(myrpt, COMPLETE, NULL);
 					return DC_COMPLETE;
 
@@ -6195,10 +6824,12 @@
 					break;
 				
 				case 2:
+					rpt_telem_select(myrpt,command_source,mylink);
 					rpt_telemetry(myrpt, REMALREADY, NULL);
 					return DC_COMPLETE;
 				
 				default:
+					rpt_telem_select(myrpt,command_source,mylink);
 					rpt_telemetry(myrpt, CONNFAIL, NULL);
 					return DC_COMPLETE;
 			}
@@ -6219,6 +6850,7 @@
 			/* if already in cmd mode, or selected self, fughetabahtit */
 			if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){
 			
+				rpt_telem_select(myrpt,command_source,mylink);
 				rpt_telemetry(myrpt, REMALREADY, NULL);
 				return DC_COMPLETE;
 			}
@@ -6241,30 +6873,23 @@
 			}
 			else
 			{
-#if	0
-				char actstr[10],dbstr[40],str1[40];
-#endif
-
 				if (strlen(digitbuf) < 7) break;
-#if	0
-				if (ast_db_get(EL_DB_ROOT,"active",actstr,sizeof(actstr) - 1))
-					return DC_ERROR;
-				sprintf(dbstr,"%s/nodenum/%d",actstr,atoi(digitbuf + 1));
-				if (ast_db_get(EL_DB_ROOT,dbstr,str1,sizeof(str1))) return DC_ERROR;
-#endif
 			}
 			rpt_mutex_lock(&myrpt->lock);
 			strcpy(myrpt->lastlinknode,digitbuf);
 			strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1);
 			rpt_mutex_unlock(&myrpt->lock);
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, REMGO, NULL);	
 			return DC_COMPLETE;
 			
 		case 5: /* Status */
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, STATUS, NULL);
 			return DC_COMPLETE;
 
 		case 15: /* Full Status */
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, FULLSTATUS, NULL);
 			return DC_COMPLETE;
 			
@@ -6293,16 +6918,14 @@
                                 rpt_mutex_unlock(&myrpt->lock);
 				/* ast_log(LOG_NOTICE,"dumping link %s\n",l->name); */
                                 
+				memset(&wf,0,sizeof(wf));
                                 wf.frametype = AST_FRAME_TEXT;
-                                wf.subclass = 0;
-                                wf.offset = 0;
-                                wf.mallocd = 0;
                                 wf.datalen = strlen(discstr) + 1;
-                                wf.samples = 0;
                                 wf.data = discstr;
+				wf.src = "function_ilink:6";
                                 if (l->chan)
                                 {
-                                        ast_write(l->chan,&wf);
+                                        if (l->thisconnected) ast_write(l->chan,&wf);
                                         ast_safe_sleep(l->chan,250); /* It's dead already, why check the return value? */
                                         ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
                                 }
@@ -6312,10 +6935,12 @@
 			rpt_mutex_unlock(&myrpt->lock);
 			if(debug > 3)
 				ast_log(LOG_NOTICE,"Nodes disconnected: %s\n",myrpt->savednodes);
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, COMPLETE, NULL);
 			return DC_COMPLETE;
 
 		case 7: /* Identify last node which keyed us up */
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, LASTNODEKEY, NULL);
 			break;
 
@@ -6337,6 +6962,7 @@
 				perma = (s1[1] == 'P') ? 1 : 0;
 				connect_link(myrpt, s1 + 2, mode, perma); /* Try to reconnect */
 			}
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, COMPLETE, NULL);
 			break;
 	
@@ -6454,7 +7080,7 @@
 	/* if on call, force * into current audio stream */
 	
 	if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){
-		myrpt->mydtmf = myrpt->p.endchar;
+		myrpt->mydtmf = myrpt->p.funcchar;
 	}
 	if (myrpt->callmode){
 		rpt_mutex_unlock(&myrpt->lock);
@@ -6494,6 +7120,7 @@
 	myrpt->callmode = 0;
 	channel_revert(myrpt);
 	rpt_mutex_unlock(&myrpt->lock);
+	rpt_telem_select(myrpt,command_source,mylink);
 	rpt_telemetry(myrpt, TERM, NULL);
 	return DC_COMPLETE;
 }
@@ -6519,9 +7146,11 @@
 			rpt_telemetry(myrpt, ID1, NULL);
 			return DC_COMPLETE;
 		case 2: /* System Time */
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, STATS_TIME, NULL);
 			return DC_COMPLETE;
 		case 3: /* app_rpt.c version */
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, STATS_VERSION, NULL);
 			return DC_COMPLETE;
 		case 11: /* System ID (local only)*/
@@ -6562,6 +7191,7 @@
 	if (!val){
                 if (strlen(digitbuf) < myrpt->macro_longest)
                         return DC_INDETERMINATE;
+		rpt_telem_select(myrpt,command_source,mylink);
 		rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL);
 		return DC_COMPLETE;
 	}			
@@ -6569,6 +7199,7 @@
 	if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val))
 	{
 		rpt_mutex_unlock(&myrpt->lock);
+		rpt_telem_select(myrpt,command_source,mylink);
 		rpt_telemetry(myrpt, MACRO_BUSY, NULL);
 		return DC_ERROR;
 	}
@@ -6594,6 +7225,7 @@
 	if (ast_fileexists(param,NULL,myrpt->rxchannel->language) <= 0)
 		return DC_ERROR;
 
+	rpt_telem_select(myrpt,command_source,mylink);
 	rpt_telemetry(myrpt,PLAYBACK,param);
 	return DC_COMPLETE;
 }
@@ -6628,7 +7260,7 @@
 {
 	char string[16];
 
-	int i, r;
+	int i, r, src;
 
 	if(!param)
 		return DC_ERROR;
@@ -6640,6 +7272,7 @@
 
 		case 2:
 			myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 0;
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA");
 			return DC_COMPLETE;
 			
@@ -6670,31 +7303,37 @@
 
 		case 7: /* Time out timer enable */
 			myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 0;
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTENA");
 			return DC_COMPLETE;
 			
 		case 8: /* Time out timer disable */
 			myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 1;
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTDIS");
 			return DC_COMPLETE;
 
                 case 9: /* Autopatch enable */
                         myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 0;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APENA");
                         return DC_COMPLETE;
 
                 case 10: /* Autopatch disable */
                         myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 1;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APDIS");
                         return DC_COMPLETE;
 
                 case 11: /* Link Enable */
                         myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 0;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKENA");
                         return DC_COMPLETE;
 
                 case 12: /* Link Disable */
                         myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 1;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKDIS");
                         return DC_COMPLETE;
 
@@ -6702,6 +7341,7 @@
 			string[0] = string[1] = 'S';
 			string[2] = myrpt->p.sysstate_cur + '0';
 			string[3] = '\0';
+			rpt_telem_select(myrpt,command_source,mylink);
 			rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
 			return DC_COMPLETE;
 
@@ -6714,36 +7354,43 @@
                         string[0] = string[1] = 'S';
                         string[2] = myrpt->p.sysstate_cur + '0';
                         string[3] = '\0';
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
                         return DC_COMPLETE;
 
                 case 15: /* Scheduler Enable */
                         myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 0;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKENA");
                         return DC_COMPLETE;
 
                 case 16: /* Scheduler Disable */
                         myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 1;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKDIS");
                         return DC_COMPLETE;
 
                 case 17: /* User functions Enable */
                         myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 0;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFENA");
                         return DC_COMPLETE;
 
                 case 18: /* User Functions Disable */
                         myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 1;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFDIS");
                         return DC_COMPLETE;
 
                 case 19: /* Alternate Tail Enable */
                         myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 1;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATENA");
                         return DC_COMPLETE;
 
                 case 20: /* Alternate Tail Disable */
                         myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 0;
+			rpt_telem_select(myrpt,command_source,mylink);
                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATDIS");
                         return DC_COMPLETE;
 
@@ -6752,6 +7399,7 @@
 			if (myrpt->p.parrotmode < 2)
 			{

[... 726 lines stripped ...]



More information about the asterisk-commits mailing list