[Asterisk-cvs] asterisk/apps app_rpt.c,1.19,1.20

jim at lists.digium.com jim at lists.digium.com
Sat Aug 21 17:55:49 CDT 2004


Update of /usr/cvsroot/asterisk/apps
In directory localhost.localdomain:/tmp/cvs-serv6347/apps

Modified Files:
	app_rpt.c 
Log Message:
Made some what turned out to be several changes to allow for radio channels
to be handled properly in the case of an Alarm state on their span.


Index: app_rpt.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_rpt.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- app_rpt.c	16 Aug 2004 01:35:02 -0000	1.19
+++ app_rpt.c	21 Aug 2004 21:41:54 -0000	1.20
@@ -3,7 +3,7 @@
  * Asterisk -- A telephony toolkit for Linux.
  *
  * Radio Repeater / Remote Base program 
- *  version 0.14 8/15/04
+ *  version 0.15 8/21/04
  * 
  * See http://www.zapatatelephony.org/app_rpt.html
  *
@@ -103,6 +103,8 @@
 enum {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE};
 enum {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT};
 
+enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM};
+
 #include <asterisk/utils.h>
 #include <asterisk/lock.h>
 #include <asterisk/file.h>
@@ -114,7 +116,6 @@
 #include <asterisk/translate.h>
 #include <asterisk/options.h>
 #include <asterisk/config.h>
-#include <asterisk/utils.h>
 #include <asterisk/say.h>
 #include <asterisk/localtime.h>
 #include <stdio.h>
@@ -136,7 +137,7 @@
 #include <tonezone.h>
 #include <linux/zaptel.h>
 
-static  char *tdesc = "Radio Repeater / Remote Base  version 0.14  08/15/2004";
+static  char *tdesc = "Radio Repeater / Remote Base  version 0.15  08/21/2004";
 static char *app = "Rpt";
 
 static char *synopsis = "Radio Repeater/Remote Base Control System";
@@ -160,6 +161,7 @@
 #define	IDTIME 300000
 #define	MAXRPTS 20
 #define POLITEID 30000
+#define FUNCTDELAY 1500
 
 static  pthread_t rpt_master_thread;
 
@@ -621,20 +623,34 @@
 * 4 types of telemtry are handled: Morse ID, Morse Message, Tone Sequence, and a File containing a recording.
 */
 
-static int telem_lookup(struct ast_channel *chan, char *name)
+static int telem_lookup(struct ast_channel *chan, char *node, char *name)
 {
 	
 	int res;
 	int i;
 	char *entry;
+	char *telemetry;
+	char *telemetry_save;
 
 	res = 0;
+	telemetry_save = NULL;
 	entry = NULL;
 	
 	
+	/* Retrieve the section name for telemetry from the node section */
+	
+	telemetry = ast_variable_retrieve(cfg, node, TELEMETRY);
+	if(telemetry){
+		telemetry_save = ast_strdupa(telemetry);
+		if(!telemetry_save){
+			ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n");
+			return res;
+		}
+		entry = ast_variable_retrieve(cfg, telemetry_save, name);
+	}
+	
 	/* Try to look up the telemetry name */
 	
-	entry = ast_variable_retrieve(cfg, TELEMETRY, name);
 	if(!entry){
 		/* Telemetry name wasn't found in the config file, use the default */
 		for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
@@ -651,6 +667,67 @@
 	return res;
 }
 
+/*
+* Wait a configurable interval of time 
+*/
+
+
+static void wait_interval(struct rpt *myrpt, int type)
+{
+	int interval;
+	char *wait_times;
+	char *wait_times_save;
+	
+	wait_times_save = NULL;
+	wait_times = ast_variable_retrieve(cfg, myrpt->name, "wait_times");
+	
+	if(wait_times){
+		wait_times_save = ast_strdupa(wait_times);
+		if(!wait_times_save){
+			ast_log(LOG_WARNING, "Out of memory in wait_interval()\n");
+			wait_times = NULL;
+		}
+	}
+	
+	switch(type){
+		case DLY_TELEM:
+			if(wait_times)
+				interval = retrieve_astcfgint(wait_times_save, "telemwait", 500, 5000, 1000);
+			else
+				interval = 1000;
+			break;
+		
+		case DLY_ID:
+			if(wait_times)
+				interval = retrieve_astcfgint(wait_times_save, "idwait",250,5000,500);
+			else
+				interval = 500;
+			break;
+			
+		case DLY_UNKEY:
+			if(wait_times)
+				interval = retrieve_astcfgint(wait_times_save, "unkeywait",500,5000,1000);
+			else
+				interval = 1000;
+			break;
+			
+		case DLY_CALLTERM:
+			if(wait_times)
+				interval = retrieve_astcfgint(wait_times_save, "calltermwait",500,5000,1500);
+			else
+				interval = 1500;
+			break;
+			
+		default:
+			return;
+	}
+	
+	usleep(1000 * interval);
+	return;
+}
+
+	
+
 static void *rpt_tele_thread(void *this)
 {
 ZT_CONFINFO ci;  /* conference info */
@@ -713,8 +790,7 @@
 	    case ID:
 	    case ID1:
 		/* wait a bit */
-		usleep(500000);
-	
+		wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM);
 		res = telem_any(mychannel, ident); 
 		imdone=1;
 	
@@ -730,22 +806,22 @@
 	    		
 	    case PROC:
 		/* wait a little bit longer */
-		usleep(1500000);
+		wait_interval(myrpt, DLY_TELEM);
 		res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language);
 		break;
 	    case TERM:
 		/* wait a little bit longer */
-		usleep(1500000);
+		wait_interval(myrpt, DLY_CALLTERM);
 		res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language);
 		break;
 	    case COMPLETE:
 		/* wait a little bit */
-		usleep(1000000);
-		res = telem_lookup(mychannel, "functcomplete");
+		wait_interval(myrpt, DLY_TELEM);
+		res = telem_lookup(mychannel, myrpt->name, "functcomplete");
 		break;
 	    case UNKEY:
 		/* wait a little bit */
-		usleep(1000000);
+		wait_interval(myrpt, DLY_UNKEY);
 		hastx = 0;
 		
 		
@@ -760,7 +836,7 @@
 			}
 			ast_mutex_unlock(&myrpt->lock);
 
-			res = telem_lookup(mychannel,(!hastx) ? "remotemon" : "remotetx");
+			res = telem_lookup(mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx");
 			if(res)
 				ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name);
 			
@@ -769,7 +845,7 @@
 			if (myrpt->cmdnode[0])
 			{
 				ast_safe_sleep(mychannel,200);
-				res = telem_lookup(mychannel, "cmdmode");
+				res = telem_lookup(mychannel, myrpt->name, "cmdmode");
 				if(res)
 				 	ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name);
 				ast_stopstream(mychannel);
@@ -777,7 +853,7 @@
 		}
 		else if((ct = ast_variable_retrieve(cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */
 			ct_copy = ast_strdupa(ct);
-			res = telem_lookup(mychannel, ct_copy);
+			res = telem_lookup(mychannel, myrpt->name, ct_copy);
 			if(res)
 			 	ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);		
 		}	
@@ -786,7 +862,7 @@
 		break;
 	    case REMDISC:
 		/* wait a little bit */
-		usleep(1000000);
+		wait_interval(myrpt, DLY_TELEM);
 		res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
 		if (!res) 
 			res = ast_waitstream(mychannel, "");
@@ -799,22 +875,22 @@
 		break;
 	    case REMALREADY:
 		/* wait a little bit */
-		usleep(1000000);
+		wait_interval(myrpt, DLY_TELEM);
 		res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language);
 		break;
 	    case REMNOTFOUND:
 		/* wait a little bit */
-		usleep(1000000);
+		wait_interval(myrpt, DLY_TELEM);
 		res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language);
 		break;
 	    case REMGO:
 		/* wait a little bit */
-		usleep(1000000);
+		wait_interval(myrpt, DLY_TELEM);
 		res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language);
 		break;
 	    case CONNECTED:
 		/* wait a little bit */
-		usleep(1000000);
+		wait_interval(myrpt, DLY_TELEM);
 		res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
 		if (!res) 
 			res = ast_waitstream(mychannel, "");
@@ -836,7 +912,7 @@
 		break;
 	    case STATUS:
 		/* wait a little bit */
-		usleep(1000000);
+		wait_interval(myrpt, DLY_TELEM);
 		hastx = 0;
 		linkbase.next = &linkbase;
 		linkbase.prev = &linkbase;
@@ -936,7 +1012,7 @@
 		break;
 		
 	    case STATS_TIME:
-	    	usleep(1000000); /* Wait a little bit */
+	    	wait_interval(myrpt, DLY_TELEM); /* Wait a little bit */
 		t = time(NULL);
 		ast_localtime(&t, &localtm, NULL);
 		/* Say the phase of the day is before the time */
@@ -970,7 +1046,7 @@
 			break;	
 		if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2)
 			break;
-    		usleep(1000000); /* Wait a little bit */
+    		wait_interval(myrpt, DLY_TELEM); /* Wait a little bit */
 		/* Say "version" */
 		if (sayfile(mychannel,"rpt/version") == -1)
 		{
@@ -998,7 +1074,7 @@
 		imdone = 1;
 	    	break;
 	    case ARB_ALPHA:
-	    	usleep(1000000); /* Wait a little bit */
+	    	wait_interval(myrpt, DLY_TELEM); /* Wait a little bit */
 	    	if(mytele->param)
 	    		saycharstr(mychannel, mytele->param);
 	    	imdone = 1;
@@ -2666,7 +2742,7 @@
 		ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_KEY);
 	}
 	if (ast_safe_sleep(myrpt->remchannel,1000) == -1) return -1;
-	res = telem_lookup(myrpt->remchannel,"functcomplete");
+	res = telem_lookup(myrpt->remchannel, myrpt->name, "functcomplete");
 	if (!myrpt->remoterx)
 	{
 		ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_UNKEY);
@@ -2686,11 +2762,13 @@
 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);
-	tele = strchr(myrpt->rxchanname,'/');
+	strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1);
+	tele = strchr(tmpstr,'/');
 	if (!tele)
 	{
 		fprintf(stderr,"rpt:Dial number (%s) must be in format tech/number\n",myrpt->rxchanname);
@@ -2698,9 +2776,16 @@
 		pthread_exit(NULL);
 	}
 	*tele++ = 0;
-	myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele);
+	myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele);
 	if (myrpt->rxchannel)
 	{
+		if (myrpt->rxchannel->_state == AST_STATE_BUSY)
+		{
+			fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
+			ast_mutex_unlock(&myrpt->lock);
+			ast_hangup(myrpt->rxchannel);
+			pthread_exit(NULL);
+		}
 		ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
 		ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
 		myrpt->rxchannel->whentohangup = 0;
@@ -2708,8 +2793,14 @@
 		myrpt->rxchannel->data = "(Repeater Rx)";
 		if (option_verbose > 2)
 			ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
-				myrpt->rxchanname,tele,myrpt->rxchannel->name);
+				tmpstr,tele,myrpt->rxchannel->name);
 		ast_call(myrpt->rxchannel,tele,999);
+		if (myrpt->rxchannel->_state != AST_STATE_UP)
+		{
+			ast_mutex_unlock(&myrpt->lock);
+			ast_hangup(myrpt->rxchannel);
+			pthread_exit(NULL);
+		}
 	}
 	else
 	{
@@ -2719,7 +2810,8 @@
 	}
 	if (myrpt->txchanname)
 	{
-		tele = strchr(myrpt->txchanname,'/');
+		strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1);
+		tele = strchr(tmpstr,'/');
 		if (!tele)
 		{
 			fprintf(stderr,"rpt:Dial number (%s) must be in format tech/number\n",myrpt->txchanname);
@@ -2727,9 +2819,17 @@
 			pthread_exit(NULL);
 		}
 		*tele++ = 0;
-		myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele);
+		myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele);
 		if (myrpt->txchannel)
 		{
+			if (myrpt->txchannel->_state == AST_STATE_BUSY)
+			{
+				fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
+				ast_mutex_unlock(&myrpt->lock);
+				ast_hangup(myrpt->txchannel);
+				ast_hangup(myrpt->rxchannel);
+				pthread_exit(NULL);
+			}			
 			ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
 			ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
 			myrpt->txchannel->whentohangup = 0;
@@ -2737,13 +2837,21 @@
 			myrpt->txchannel->data = "(Repeater Rx)";
 			if (option_verbose > 2)
 				ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
-					myrpt->txchanname,tele,myrpt->txchannel->name);
+					tmpstr,tele,myrpt->txchannel->name);
 			ast_call(myrpt->txchannel,tele,999);
+			if (myrpt->rxchannel->_state != AST_STATE_UP)
+			{
+				ast_mutex_unlock(&myrpt->lock);
+				ast_hangup(myrpt->rxchannel);
+				ast_hangup(myrpt->txchannel);
+				pthread_exit(NULL);
+			}
 		}
 		else
 		{
 			fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
 			ast_mutex_unlock(&myrpt->lock);
+			ast_hangup(myrpt->rxchannel);
 			pthread_exit(NULL);
 		}
 	}
@@ -2757,6 +2865,9 @@
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
 		ast_mutex_unlock(&myrpt->lock);
+		if (myrpt->txchannel != myrpt->rxchannel) 
+			ast_hangup(myrpt->txchannel);
+		ast_hangup(myrpt->rxchannel);
 		pthread_exit(NULL);
 	}
 	/* make a conference for the tx */
@@ -2768,6 +2879,10 @@
 	{
 		ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
 		ast_mutex_unlock(&myrpt->lock);
+		ast_hangup(myrpt->pchannel);
+		if (myrpt->txchannel != myrpt->rxchannel) 
+			ast_hangup(myrpt->txchannel);
+		ast_hangup(myrpt->rxchannel);
 		pthread_exit(NULL);
 	}
 	/* save tx conference number */
@@ -2781,6 +2896,10 @@
 	{
 		ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
 		ast_mutex_unlock(&myrpt->lock);
+		ast_hangup(myrpt->pchannel);
+		if (myrpt->txchannel != myrpt->rxchannel) 
+			ast_hangup(myrpt->txchannel);
+		ast_hangup(myrpt->rxchannel);
 		pthread_exit(NULL);
 	}
 	/* save pseudo channel conference number */
@@ -2791,6 +2910,10 @@
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
 		ast_mutex_unlock(&myrpt->lock);
+		ast_hangup(myrpt->pchannel);
+		if (myrpt->txchannel != myrpt->rxchannel) 
+			ast_hangup(myrpt->txchannel);
+		ast_hangup(myrpt->rxchannel);
 		pthread_exit(NULL);
 	}
 	/* make a conference for the tx */
@@ -2802,6 +2925,11 @@
 	{
 		ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
 		ast_mutex_unlock(&myrpt->lock);
+		ast_hangup(myrpt->txpchannel);
+		ast_hangup(myrpt->pchannel);
+		if (myrpt->txchannel != myrpt->rxchannel) 
+			ast_hangup(myrpt->txchannel);
+		ast_hangup(myrpt->rxchannel);
 		pthread_exit(NULL);
 	}
 	/* Now, the idea here is to copy from the physical rx channel buffer
@@ -2843,6 +2971,9 @@
 		if (ast_check_hangup(myrpt->txpchannel)) break;
 		ast_mutex_lock(&myrpt->lock);
 		myrpt->localtx = keyed && (myrpt->dtmfidx == -1) && (!myrpt->cmdnode[0]);
+		
+		/* If someone's connected, and they're transmitting from their end to us, set remrx true */
+		
 		l = myrpt->links.next;
 		remrx = 0;
 		while(l != &myrpt->links)
@@ -2924,8 +3055,8 @@
 		if (!myrpt->totimer) myrpt->tailtimer = 0;
 		/* if not timed-out, add in tail */
 		if (myrpt->totimer) totx = totx || myrpt->tailtimer;
-		/* If user keys up or is keyed up over standard ID, switch to talkover ID, if one is defined */
-		if (identqueued && keyed && idtalkover) {
+		/* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */
+		if (identqueued && (keyed || remrx) && idtalkover) {
 			int hasid = 0,hastalkover = 0;
 
 			telem = myrpt->tele.next;
@@ -3384,8 +3515,8 @@
 	ast_mutex_lock(&myrpt->lock);
 	ast_hangup(myrpt->pchannel);
 	ast_hangup(myrpt->txpchannel);
-	ast_hangup(myrpt->rxchannel);
 	if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel);
+	ast_hangup(myrpt->rxchannel);
 	l = myrpt->links.next;
 	while(l != &myrpt->links)
 	{
@@ -3411,6 +3542,7 @@
 char *this,*val;
 struct ast_variable *vp;
 int	i,j,n,longestnode;
+pthread_attr_t attr;
 
 	/* start with blank config */
 	memset(&rpt_vars,0,sizeof(rpt_vars));
@@ -3452,6 +3584,7 @@
 		ast_mutex_init(&rpt_vars[n].lock);
 		rpt_vars[n].tele.next = &rpt_vars[n].tele;
 		rpt_vars[n].tele.prev = &rpt_vars[n].tele;
+		rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
 		rpt_vars[n].name = this;
 		rpt_vars[n].rxchanname = ast_variable_retrieve(cfg,this,"rxchannel");
 		rpt_vars[n].txchanname = ast_variable_retrieve(cfg,this,"txchannel");
@@ -3469,7 +3602,6 @@
 		
 		rpt_vars[n].idtime = retrieve_astcfgint( this, "idtime", 60000, 2400000, IDTIME);	/* Enforce a min max */
 		rpt_vars[n].politeid = retrieve_astcfgint( this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */
-		
 		rpt_vars[n].remote = ast_variable_retrieve(cfg,this,"remote");
 		rpt_vars[n].tonezone = ast_variable_retrieve(cfg,this,"tonezone");
 		val = ast_variable_retrieve(cfg,this,"iobase");
@@ -3543,8 +3675,24 @@
 		}
 		ast_pthread_create(&rpt_vars[i].rpt_thread,NULL,rpt,(void *) &rpt_vars[i]);
 	}
-	/* wait for first one to die (should be never) */
-	pthread_join(rpt_vars[0].rpt_thread,NULL);
+	usleep(500000);
+	for(;;)
+	{
+		/* Now monitor each thread, and restart it if necessary */
+		for(i = 0; i < n; i++)
+		{ 
+			if (rpt_vars[i].remote) continue;
+			if (pthread_kill(rpt_vars[i].rpt_thread,0))
+			{
+			        pthread_attr_init(&attr);
+	 		        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+				ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
+				ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name);
+			}
+
+		}
+		usleep(2000000);
+	}
 	pthread_exit(NULL);
 }
 




More information about the svn-commits mailing list