[Asterisk-cvs] asterisk/apps app_rpt.c,1.28,1.29

jim at lists.digium.com jim at lists.digium.com
Sat Jan 29 01:29:26 CST 2005


Update of /usr/cvsroot/asterisk/apps
In directory mongoose.digium.com:/tmp/cvs-serv22267/apps

Modified Files:
	app_rpt.c 
Log Message:
Fixed more bugs.


Index: app_rpt.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_rpt.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- app_rpt.c	25 Jan 2005 06:10:19 -0000	1.28
+++ app_rpt.c	29 Jan 2005 07:31:17 -0000	1.29
@@ -3,11 +3,11 @@
  * Asterisk -- A telephony toolkit for Linux.
  *
  * Radio Repeater / Remote Base program 
- *  version 0.20 01/14/05
+ *  version 0.23 01/28/05
  * 
  * See http://www.zapatatelephony.org/app_rpt.html
  *
- * Copyright (C) 2002 - 2005, Jim Dixon, WB6NIL
+ * Copyright (C) 2002-2004, Jim Dixon, WB6NIL
  *
  * Jim Dixon, WB6NIL <jim at lambdatel.com>
  * Serious contributions by Steve RoDgers, WA6ZFT <hwstar at rodgers.sdcoxmail.com>
@@ -80,6 +80,8 @@
 #define	DISC_TIME 10000  /* report disc after 10 seconds of no connect */
 #define	MAX_RETRIES 5
 
+#define	REDUNDANT_TX_TIME 2000
+
 #define	RETRY_TIMER_MS 5000
 
 #define	MAXREMSTR 15
@@ -107,7 +109,7 @@
 
 enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
 	CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME,
-	STATS_VERSION, IDTALKOVER, ARB_ALPHA};
+	STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE};
 
 enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
 
@@ -131,6 +133,7 @@
 #include <asterisk/config.h>
 #include <asterisk/say.h>
 #include <asterisk/localtime.h>
+#include <signal.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
@@ -150,7 +153,8 @@
 #include <tonezone.h>
 #include <linux/zaptel.h>
 
-static  char *tdesc = "Radio Repeater / Remote Base  version 0.20  01/14/2005";
+static  char *tdesc = "Radio Repeater / Remote Base  version 0.23  01/28/2005";
+
 static char *app = "Rpt";
 
 static char *synopsis = "Radio Repeater/Remote Base Control System";
@@ -190,11 +194,14 @@
 	char	lasttx;
 	char	lastrx;
 	char	connected;
+	char	hasconnected;
 	char	outbound;
 	char	disced;
+	char	killme;
 	long	elaptime;
 	long	disctime;
 	long 	retrytimer;
+	long	retxtimer;
 	int	retries;
 	struct ast_channel *chan;	
 	struct ast_channel *pchan;	
@@ -272,6 +279,7 @@
 	int mustid;
 	int politeid;
 	int dtmfidx,rem_dtmfidx;
+	long	retxtimer;
 	char mydtmf;
 	int iobase;
 	char exten[AST_MAX_EXTENSION];
@@ -282,6 +290,7 @@
 	char rxplon;
 	char funcchar;
 	char endchar;
+	char stopgen;
 	int link_longestfunc;
 	int longestfunc;
 	int longestnode;	
@@ -792,6 +801,7 @@
 	if (!mychannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
+		ast_mutex_lock(&myrpt->lock);
 		remque((struct qelem *)mytele);
 		ast_mutex_unlock(&myrpt->lock);
 		free(mytele);		
@@ -981,6 +991,11 @@
 			if (!m)
 			{
 				ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name);
+				ast_mutex_lock(&myrpt->lock);
+				remque((struct qelem *)mytele);
+				ast_mutex_unlock(&myrpt->lock);
+				free(mytele);		
+				ast_hangup(mychannel);
 				pthread_exit(NULL);
 			}
 			memcpy(m,l,sizeof(struct rpt_link));
@@ -1135,9 +1150,20 @@
 	    		saycharstr(mychannel, mytele->param);
 	    	imdone = 1;
 		break;
+	    case TEST_TONE:
+		imdone = 1;
+		myrpt->stopgen = 0;
+	        if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0))) 
+			break;
+	        while(mychannel->generatordata && (!myrpt->stopgen)) {
+			if (ast_safe_sleep(mychannel,1)) break;
+		    	imdone = 1;
+			}
+		break;
 	    default:
 	    	break;
 	}
+	myrpt->stopgen = 0;
 	if (!imdone)
 	{
 		if (!res) 
@@ -1197,7 +1223,7 @@
 ZT_CONFINFO ci;  /* conference info */
 struct	rpt *myrpt = (struct rpt *)this;
 int	res;
-struct	ast_frame *f,wf;
+struct	ast_frame wf;
 int stopped,congstarted;
 struct ast_channel *mychannel,*genchannel;
 
@@ -1284,7 +1310,7 @@
 			/* start congestion tone */
 			tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION);
 		}
-		res = ast_waitfor(mychannel, MSWAIT);
+		res = ast_safe_sleep(mychannel, MSWAIT);
 		if (res < 0)
 		{
 			ast_hangup(mychannel);
@@ -1294,29 +1320,6 @@
 			ast_mutex_unlock(&myrpt->lock);
 			pthread_exit(NULL);
 		}
-		if (res == 0) continue;
-		f = ast_read(mychannel);
-		if (f == NULL) 
-		{
-			ast_hangup(mychannel);
-			ast_hangup(genchannel);
-			ast_mutex_lock(&myrpt->lock);
-			myrpt->callmode = 0;
-			ast_mutex_unlock(&myrpt->lock);
-			pthread_exit(NULL);			
-		}
-		if ((f->frametype == AST_FRAME_CONTROL) &&
-		    (f->subclass == AST_CONTROL_HANGUP))
-		{
-			ast_frfree(f);
-			ast_hangup(mychannel);
-			ast_hangup(genchannel);
-			ast_mutex_lock(&myrpt->lock);
-			myrpt->callmode = 0;
-			ast_mutex_unlock(&myrpt->lock);
-			pthread_exit(NULL);			
-		}
-		ast_frfree(f);
 	}
 	/* stop any tone generation */
 	tone_zone_play_tone(mychannel->fds[0],-1);
@@ -1393,11 +1396,7 @@
 			myrpt->mydtmf = 0;
 		}
 		ast_mutex_unlock(&myrpt->lock);
-		if (ast_safe_sleep(mychannel,25)) 
-		{
-			ast_mutex_unlock(&myrpt->lock);
-			break;
-		}
+		usleep(MSWAIT * 1000);
 		ast_mutex_lock(&myrpt->lock);
 	}
 	ast_mutex_unlock(&myrpt->lock);
@@ -1455,7 +1454,7 @@
 {
 
 	char *val, *s, *s1, *tele;
-	char tmp[300], deststr[300] = "";
+	char tmp[300], deststr[300] = "",modechange = 0;
 	struct rpt_link *l;
 	ZT_CONFINFO ci;  /* conference info */
 
@@ -1542,14 +1541,18 @@
 					return DC_COMPLETE;
 					
 				}
+				ast_mutex_unlock(&myrpt->lock);
 				if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
-			}
-			ast_mutex_unlock(&myrpt->lock);
+				l->retries = MAX_RETRIES + 1;
+				l->disced = 2;
+				modechange = 1;
+			} else
+				ast_mutex_unlock(&myrpt->lock);
 			/* establish call in monitor mode */
 			l = malloc(sizeof(struct rpt_link));
 			if (!l){
 				ast_log(LOG_WARNING, "Unable to malloc\n");
-				pthread_exit(NULL);
+				return DC_ERROR;
 			}
 			/* zero the silly thing */
 			memset((char *)l,0,sizeof(struct rpt_link));
@@ -1557,12 +1560,13 @@
 			tele = strchr(deststr,'/');
 			if (!tele){
 				fprintf(stderr,"link2:Dial number (%s) must be in format tech/number\n",deststr);
-				pthread_exit(NULL);
+				return DC_ERROR;
 			}
 			*tele++ = 0;
 			l->isremote = (s && ast_true(s));
 			strncpy(l->name, digitbuf, MAXNODESTR - 1);
 			l->chan = ast_request(deststr,AST_FORMAT_SLINEAR,tele,NULL);
+			if (modechange) l->connected = 1;
 			if (l->chan){
 				ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
 				ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
@@ -1590,7 +1594,9 @@
 			l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
 			if (!l->pchan){
 				fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
-				pthread_exit(NULL);
+				ast_hangup(l->chan);
+				free(l);
+				return DC_ERROR;
 			}
 			ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
 			ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
@@ -1602,7 +1608,10 @@
 			if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1)
 			{
 				ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
-				pthread_exit(NULL);
+				ast_hangup(l->chan);
+				ast_hangup(l->pchan);
+				free(l);
+				return DC_ERROR;
 			}
 			ast_mutex_lock(&myrpt->lock);
 			/* insert at end of queue */
@@ -1637,14 +1646,18 @@
 					rpt_telemetry(myrpt, REMALREADY, NULL);
 					return DC_COMPLETE;
 				}
+				ast_mutex_unlock(&myrpt->lock);
 				if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV);
-			} 
-			ast_mutex_unlock(&myrpt->lock);
+				l->retries = MAX_RETRIES + 1;
+				l->disced = 2;
+				modechange = 1;
+			} else
+				ast_mutex_unlock(&myrpt->lock);
 			/* establish call in tranceive mode */
 			l = malloc(sizeof(struct rpt_link));
 			if (!l){
 				ast_log(LOG_WARNING, "Unable to malloc\n");
-				pthread_exit(NULL);
+				return(DC_ERROR);
 			}
 			/* zero the silly thing */
 			memset((char *)l,0,sizeof(struct rpt_link));
@@ -1652,11 +1665,13 @@
 			l->outbound = 1;
 			strncpy(l->name, digitbuf, MAXNODESTR - 1);
 			l->isremote = (s && ast_true(s));
+			if (modechange) l->connected = 1;
 			snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
 			tele = strchr(deststr, '/');
 			if (!tele){
 				fprintf(stderr,"link3:Dial number (%s) must be in format tech/number\n",deststr);
-				pthread_exit(NULL);
+				free(l);
+				return DC_ERROR;
 			}
 			*tele++ = 0;
 			l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
@@ -1686,7 +1701,9 @@
 			l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
 			if (!l->pchan){
 				fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
-				pthread_exit(NULL);
+				ast_hangup(l->chan);
+				free(l);
+				return DC_ERROR;
 			}
 			ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR);
 			ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR);
@@ -1698,7 +1715,10 @@
 			if (ioctl(l->pchan->fds[0], ZT_SETCONF, &ci) == -1)
 			{
 				ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
-				pthread_exit(NULL);
+				ast_hangup(l->chan);
+				ast_hangup(l->pchan);
+				free(l);
+				return DC_ERROR;
 			}
 			ast_mutex_lock(&myrpt->lock);
 			/* insert at end of queue */
@@ -1776,7 +1796,6 @@
 	
 	if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){
 		myrpt->mydtmf = myrpt->funcchar;
-		ast_mutex_unlock(&myrpt->lock);
 	}
 	if (myrpt->callmode){
 		ast_mutex_unlock(&myrpt->lock);
@@ -1872,6 +1891,10 @@
 			myrpt->enable = 0;
 			return DC_COMPLETE;
 			
+		case 4: /* test tone on */
+			rpt_telemetry(myrpt, TEST_TONE, NULL);
+			return DC_COMPLETE;
+
 	}	
 	return DC_INDETERMINATE;
 }
@@ -2064,8 +2087,7 @@
 			
 			if(debug)
 				printf("@@@@ Frequency entered: %s\n", myrpt->freq);
-	
-			
+
 			strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1);
 			myrpt->offset = offset;
 	
@@ -2320,6 +2342,7 @@
 	wf.samples = 0;
  	/* put string in our buffer */
 	strncpy(tmp,str,sizeof(tmp) - 1);
+
         if (!strcmp(tmp,discstr))
         {
                 mylink->disced = 1;
@@ -2390,7 +2413,7 @@
 		if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
 		{
 			myrpt->callmode = 2;
-			rpt_telemetry(myrpt,PROC,NULL);
+			rpt_telemetry(myrpt,PROC,NULL); 
 		}
 		/* if can continue, do so */
 		if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) 
@@ -2425,7 +2448,7 @@
 			ast_mutex_lock(&myrpt->lock);
 			
 			switch(res){
-			
+
 				case DC_INDETERMINATE:
 					break;
 				
@@ -2845,6 +2868,7 @@
 
  	/* put string in our buffer */
 	strncpy(tmp,str,sizeof(tmp) - 1);
+	if (!strcmp(tmp,discstr)) return 0;
 	if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
 	{
 		ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
@@ -2886,15 +2910,17 @@
 		fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name);
 		return -1;
 	}
+	ast_mutex_lock(&myrpt->lock);
+	/* remove from queue */
+	remque((struct qelem *) l);
+	ast_mutex_unlock(&myrpt->lock);
 	strncpy(tmp,val,sizeof(tmp) - 1);
 	s = tmp;
 	s1 = strsep(&s,",");
-	ast_mutex_lock(&myrpt->lock);
 	snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
 	tele = strchr(deststr, '/');
 	if (!tele) {
 		fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr);
-		ast_mutex_unlock(&myrpt->lock);
 		return -1;
 	}
 	*tele++ = 0;
@@ -2919,9 +2945,11 @@
 		if (option_verbose > 2)
 			ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n",
 				deststr,tele,l->chan->name);
-		ast_mutex_unlock(&myrpt->lock);
 		return -1;
 	}
+	ast_mutex_lock(&myrpt->lock);
+	/* put back in queue queue */
+	insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
 	ast_mutex_unlock(&myrpt->lock);
 	return 0;
 }
@@ -2996,6 +3024,7 @@
 		{
 			fprintf(stderr,"rpt:Dial number (%s) must be in format tech/number\n",myrpt->txchanname);
 			ast_mutex_unlock(&myrpt->lock);
+			ast_hangup(myrpt->rxchannel);
 			myrpt->rpt_thread = AST_PTHREADT_STOP;
 			pthread_exit(NULL);
 		}
@@ -3133,6 +3162,7 @@
 	myrpt->callmode = 0;
 	myrpt->tounkeyed = 0;
 	myrpt->tonotify = 0;
+	myrpt->retxtimer = 0;
 	lasttx = 0;
 	keyed = 0;
 	idtalkover = ast_variable_retrieve(cfg, myrpt->name, "idtalkover");
@@ -3154,11 +3184,11 @@
 		struct ast_channel *cs[300];
 		int totx,elap,n,toexit;
 
+		ast_mutex_lock(&myrpt->lock);
 		if (ast_check_hangup(myrpt->rxchannel)) break;
 		if (ast_check_hangup(myrpt->txchannel)) break;
 		if (ast_check_hangup(myrpt->pchannel)) break;
 		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 */
@@ -3219,7 +3249,9 @@
 		if ((!myrpt->totimer) && (!myrpt->tonotify))
 		{
 			myrpt->tonotify = 1;
+			ast_mutex_unlock(&myrpt->lock);
 			rpt_telemetry(myrpt,TIMEOUT,NULL);
+			ast_mutex_lock(&myrpt->lock);
 		}
 		/* if wants to transmit and in phone call, but timed out, 
 			reset time-out timer if keyed */
@@ -3305,6 +3337,27 @@
 			myrpt->rem_dtmfidx = -1;
 			myrpt->rem_dtmfbuf[0] = 0;
 		}			
+		l = myrpt->links.next;
+		while(l != &myrpt->links)
+		{
+			if (l->killme)
+			{
+				/* remove from queue */
+				remque((struct qelem *) l);
+				if (!strcmp(myrpt->cmdnode,l->name))
+					myrpt->cmdnode[0] = 0;
+				ast_mutex_unlock(&myrpt->lock);
+				/* hang-up on call to device */
+				if (l->chan) ast_hangup(l->chan);
+				ast_hangup(l->pchan);
+				free(l);
+				ast_mutex_lock(&myrpt->lock);
+				/* re-start link traversal */
+				l = myrpt->links.next;
+				continue;
+			}
+			l = l->next;
+		}
 		n = 0;
 		cs[n++] = myrpt->rxchannel;
 		cs[n++] = myrpt->pchannel;
@@ -3313,7 +3366,7 @@
 		l = myrpt->links.next;
 		while(l != &myrpt->links)
 		{
-			if ((!l->disctime) && l->chan)
+			if ((!l->killme) && (!l->disctime) && l->chan)
 			{
 				cs[n++] = l->chan;
 				cs[n++] = l->pchan;
@@ -3329,6 +3382,14 @@
 		l = myrpt->links.next;
 		while(l != &myrpt->links)
 		{
+			if (!l->lasttx)
+			{
+				if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME)
+				{
+					l->retxtimer = 0;
+					if (l->chan) ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY);
+				}
+			} else l->retxtimer = 0;
 #ifdef	RECONNECT_KLUDGE
 			if (l->disctime && l->chan)
 			{
@@ -3368,7 +3429,7 @@
 			}
 #ifdef	RECONNECT_KLUDGE
 			if ((!l->chan) && (!l->retrytimer) && l->outbound && 
-				(l->retries++ < MAX_RETRIES))
+				(l->retries++ < MAX_RETRIES) && (l->hasconnected))
 			{
 				if (l->chan) ast_hangup(l->chan);
 				ast_mutex_unlock(&myrpt->lock);
@@ -3377,6 +3438,7 @@
 					l->retrytimer = RETRY_TIMER_MS;
 				}
 				ast_mutex_lock(&myrpt->lock);
+				break;
 			}
 			if ((!l->chan) && (!l->retrytimer) && l->outbound &&
 				(l->retries >= MAX_RETRIES))
@@ -3386,10 +3448,13 @@
 				if (!strcmp(myrpt->cmdnode,l->name))
 					myrpt->cmdnode[0] = 0;
 				ast_mutex_unlock(&myrpt->lock);
-				rpt_telemetry(myrpt,REMDISC,l);
+				if (!l->hasconnected)
+					rpt_telemetry(myrpt,CONNFAIL,l);
+				else rpt_telemetry(myrpt,REMDISC,l);
 				/* hang-up on call to device */
 				ast_hangup(l->pchan);
 				free(l);
+                                ast_mutex_lock(&myrpt->lock);
 				break;
 			}
                         if ((!l->chan) && (!l->disctime) && (!l->outbound))
@@ -3403,6 +3468,7 @@
                                 /* hang-up on call to device */
                                 ast_hangup(l->pchan);
                                 free(l);
+                                ast_mutex_lock(&myrpt->lock);
                                 break;
                         }
 #endif
@@ -3441,11 +3507,14 @@
 					/* if in simple mode, kill autopatch */
 					if (myrpt->simple && myrpt->callmode)
 					{
+						ast_mutex_lock(&myrpt->lock);
 						myrpt->callmode = 0;
+						ast_mutex_unlock(&myrpt->lock);
 						rpt_telemetry(myrpt,TERM,NULL);
 						continue;
 					}
 					ast_mutex_lock(&myrpt->lock);
+					myrpt->stopgen = 1;
 					if (myrpt->cmdnode[0])
 					{
 						myrpt->cmdnode[0] = 0;
@@ -3456,8 +3525,10 @@
 					} else ast_mutex_unlock(&myrpt->lock);
 					continue;
 				}
+				ast_mutex_lock(&myrpt->lock);
 				if (myrpt->cmdnode[0])
 				{
+					ast_mutex_unlock(&myrpt->lock);
 					send_link_dtmf(myrpt,c);
 					continue;
 				}
@@ -3467,23 +3538,25 @@
 					{
 						myrpt->dtmfidx = 0;
 						myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
+						ast_mutex_unlock(&myrpt->lock);
 						time(&dtmf_time);
 						continue;
 					} 
 					else if ((c != myrpt->endchar) && (myrpt->dtmfidx >= 0))
 					{
 						time(&dtmf_time);
+						
 						if (myrpt->dtmfidx < MAXDTMF)
 						{
 							myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
 							myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
 							
 							strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1);
-							ast_mutex_unlock(&myrpt->lock);
 							
+							ast_mutex_unlock(&myrpt->lock);
 							res = collect_function_digits(myrpt, cmd, SOURCE_RPT);
-
 							ast_mutex_lock(&myrpt->lock);
+
 							switch(res){
 			
 								case DC_INDETERMINATE:
@@ -3508,19 +3581,21 @@
 									dtmf_time = 0;
 									break;
 							}
-							ast_mutex_unlock(&myrpt->lock);
-							if(res != DC_INDETERMINATE)	
+							if(res != DC_INDETERMINATE) {
+								ast_mutex_unlock(&myrpt->lock);
 								continue;
-						}
+							}
+						} 
 					}
 				}
-				else
+				else /* if simple */
 				{
 					if ((!myrpt->callmode) && (c == myrpt->funcchar))
 					{
 						myrpt->callmode = 1;
 						myrpt->cidx = 0;
 						myrpt->exten[myrpt->cidx] = 0;
+						ast_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);
@@ -3535,18 +3610,24 @@
 					if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
 					{
 						myrpt->callmode = 2;
-						rpt_telemetry(myrpt,PROC,NULL);
+						ast_mutex_unlock(&myrpt->lock);
+						rpt_telemetry(myrpt,PROC,NULL); 
+						continue;
 					}
 					/* if can continue, do so */
-					if (ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) continue;
-					/* call has failed, inform user */
-					myrpt->callmode = 4;
+					if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL))
+					{
+						/* call has failed, inform user */
+						myrpt->callmode = 4;
+					}
+					ast_mutex_unlock(&myrpt->lock);
 					continue;
 				}
 				if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
 				{
 					myrpt->mydtmf = f->subclass;
 				}
+				ast_mutex_unlock(&myrpt->lock);
 				continue;
 			}						
 			else if (f->frametype == AST_FRAME_CONTROL)
@@ -3567,10 +3648,10 @@
 				if (f->subclass == AST_CONTROL_RADIO_UNKEY)
 				{
 					if (debug) printf("@@@@ rx un-key\n");
-					if(keyed)
+					if(keyed) {
 						rpt_telemetry(myrpt,UNKEY,NULL);
+					}
 					keyed = 0;
-
 				}
 			}
 			ast_frfree(f);
@@ -3621,6 +3702,7 @@
 			continue;
 		}
 		toexit = 0;
+		ast_mutex_lock(&myrpt->lock);
 		l = myrpt->links.next;
 		while(l != &myrpt->links)
 		{
@@ -3631,7 +3713,6 @@
 			}
 			if (who == l->chan) /* if it was a read from rx */
 			{
-				ast_mutex_lock(&myrpt->lock);
 				remrx = 0;
 				/* see if any other links are receiving */
 				m = myrpt->links.next;
@@ -3644,7 +3725,7 @@
 				ast_mutex_unlock(&myrpt->lock);
 				totx = (((l->isremote) ? myrpt->localtx : 
 					myrpt->exttx) || remrx) && l->mode;
-				if (l->lasttx != totx)
+				if (l->chan && (l->lasttx != totx))
 				{
 					if (totx)
 					{
@@ -3665,21 +3746,26 @@
 						l->disctime = DISC_TIME;
 						ast_mutex_lock(&myrpt->lock);
 						ast_hangup(l->chan);
-						ast_mutex_unlock(&myrpt->lock);
 						l->chan = 0;
 						break;
 					}
 
-					if (l->retrytimer) break; 
-					if (l->outbound && (l->retries++ < MAX_RETRIES))
+					if (l->retrytimer) 
+					{
+						ast_mutex_lock(&myrpt->lock);
+						break; 
+					}
+					if (l->outbound && (l->retries++ < MAX_RETRIES) && (l->hasconnected))
 					{
 						ast_mutex_lock(&myrpt->lock);
 						ast_hangup(l->chan);
+						l->chan = 0;
 						ast_mutex_unlock(&myrpt->lock);
 						if (attempt_reconnect(myrpt,l) == -1)
 						{
 							l->retrytimer = RETRY_TIMER_MS;
 						}
+						ast_mutex_lock(&myrpt->lock);
 						break;
 					}
 #endif
@@ -3689,11 +3775,14 @@
 					if (!strcmp(myrpt->cmdnode,l->name))
 						myrpt->cmdnode[0] = 0;
 					ast_mutex_unlock(&myrpt->lock);
-					rpt_telemetry(myrpt,REMDISC,l);
+					if (!l->hasconnected)
+						rpt_telemetry(myrpt,CONNFAIL,l);
+					else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l);
 					/* hang-up on call to device */
 					ast_hangup(l->chan);
 					ast_hangup(l->pchan);
 					free(l);
+					ast_mutex_lock(&myrpt->lock);
 					break;
 				}
 				if (f->frametype == AST_FRAME_VOICE)
@@ -3710,6 +3799,7 @@
 					{
 						char lconnected = l->connected;
 						l->connected = 1;
+						l->hasconnected = 1;
 						l->elaptime = -1;
 						l->retries = 0;
 						if (!lconnected) rpt_telemetry(myrpt,CONNECTED,l);
@@ -3735,21 +3825,25 @@
 							l->disctime = DISC_TIME;
 							ast_mutex_lock(&myrpt->lock);
 							ast_hangup(l->chan);
-							ast_mutex_unlock(&myrpt->lock);
 							l->chan = 0;
 							break;
 						}
-
-						if (l->retrytimer) break;
-						if (l->outbound && (l->retries++ < MAX_RETRIES))
+						if (l->retrytimer) 
+						{
+							ast_mutex_lock(&myrpt->lock);
+							break;
+						}
+						if (l->outbound && (l->retries++ < MAX_RETRIES) && (l->hasconnected))
 						{
 							ast_mutex_lock(&myrpt->lock);
 							ast_hangup(l->chan);
+							l->chan = 0;
 							ast_mutex_unlock(&myrpt->lock);
 							if (attempt_reconnect(myrpt,l) == -1)
 							{
 								l->retrytimer = RETRY_TIMER_MS;
 							}
+							ast_mutex_lock(&myrpt->lock);
 							break;
 						}
 #endif
@@ -3759,29 +3853,35 @@
 						if (!strcmp(myrpt->cmdnode,l->name))
 							myrpt->cmdnode[0] = 0;
 						ast_mutex_unlock(&myrpt->lock);
-						rpt_telemetry(myrpt,REMDISC,l);
+						if (!l->hasconnected)
+							rpt_telemetry(myrpt,CONNFAIL,l);
+						else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l);
 						/* hang-up on call to device */
 						ast_hangup(l->chan);
 						ast_hangup(l->pchan);
 						free(l);
+						ast_mutex_lock(&myrpt->lock);
 						break;
 					}
 				}
 				ast_frfree(f);
+				ast_mutex_lock(&myrpt->lock);
 				break;
 			}
 			if (who == l->pchan) 
 			{
+				ast_mutex_unlock(&myrpt->lock);
 				f = ast_read(l->pchan);
 				if (!f)
 				{
 					if (debug) printf("@@@@ rpt:Hung Up\n");
 					toexit = 1;
+					ast_mutex_lock(&myrpt->lock);
 					break;
 				}
 				if (f->frametype == AST_FRAME_VOICE)
 				{
-					ast_write(l->chan,f);
+					if (l->chan) ast_write(l->chan,f);
 				}
 				if (f->frametype == AST_FRAME_CONTROL)
 				{
@@ -3790,14 +3890,17 @@
 						if (debug) printf("@@@@ rpt:Hung Up\n");
 						ast_frfree(f);
 						toexit = 1;
+						ast_mutex_lock(&myrpt->lock);
 						break;
 					}
 				}
 				ast_frfree(f);
+				ast_mutex_lock(&myrpt->lock);
 				break;
 			}
 			l = l->next;
 		}
+		ast_mutex_unlock(&myrpt->lock);
 		if (toexit) break;
 		if (who == myrpt->txpchannel) /* if it was a read from remote tx */
 		{
@@ -3820,11 +3923,12 @@
 			continue;
 		}
 	}
-	ast_mutex_lock(&myrpt->lock);
+	usleep(100000);
 	ast_hangup(myrpt->pchannel);
 	ast_hangup(myrpt->txpchannel);
 	if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel);
 	ast_hangup(myrpt->rxchannel);
+	ast_mutex_lock(&myrpt->lock);
 	l = myrpt->links.next;
 	while(l != &myrpt->links)
 	{
@@ -3845,7 +3949,6 @@
 }
 
 
-
 static void *rpt_master(void *ignore)
 {
 char *this,*val;
@@ -3856,7 +3959,7 @@
 	/* start with blank config */
 	memset(&rpt_vars,0,sizeof(rpt_vars));
 
-	cfg = ast_config_load("rpt.conf");
+	cfg = ast_load("rpt.conf");
 	if (!cfg) {
 		ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf.  Radio Repeater disabled.\n");
 		pthread_exit(NULL);
@@ -3971,7 +4074,7 @@
 		/* if is a remote, dont start one for it */
 		if (rpt_vars[i].remote)
 		{
-			strncpy(rpt_vars[i].freq, "146.460", sizeof(rpt_vars[i].freq) - 1);
+			strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1);
 			strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1);
 			rpt_vars[i].offset = REM_SIMPLEX;
 			rpt_vars[i].powerlevel = REM_MEDPWR;
@@ -4082,20 +4185,9 @@
 		/* if found */
 		if (l != &myrpt->links) 
 		{
-                        l->disctime = DISC_TIME;
-                        if (l->chan)
-                        {
-                                ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
-                                l->chan = 0;
-                        }
-                        else
-                        {
-                                remque((struct qelem *) l);
-                                if (!strcmp(myrpt->cmdnode,l->name))
-                                        myrpt->cmdnode[0] = 0;
-                                ast_hangup(l->pchan);
-                                free(l);
-                        }
+			l->killme = 1;
+			l->retries = MAX_RETRIES + 1;
+			l->disced = 2;
                         ast_mutex_unlock(&myrpt->lock);
 			usleep(500000);	
 		} else 
@@ -4114,6 +4206,7 @@
 		l->isremote = 0;
 		l->chan = chan;
 		l->connected = 1;
+		l->hasconnected = 1;
 		ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
 		ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
 		/* allocate a pseudo-channel thru asterisk */
@@ -4150,12 +4243,12 @@
 	{
 		ast_mutex_unlock(&myrpt->lock);
 		usleep(500000);
-		ast_mutex_lock(&myrpt->lock);
 		if (myrpt->remoteon)
 		{
 			ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp);
 			return -1;
 		}		
+		ast_mutex_lock(&myrpt->lock);
 	}
 	myrpt->remoteon = 1;
 	if (ioperm(myrpt->iobase,1,1) == -1)
@@ -4202,6 +4295,7 @@
 		{
 			fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
 			ast_mutex_unlock(&myrpt->lock);
+			ast_hangup(myrpt->rxchannel);
 			pthread_exit(NULL);
 		}
 		*tele++ = 0;
@@ -4224,6 +4318,7 @@
 		{
 			fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
 			ast_mutex_unlock(&myrpt->lock);
+			ast_hangup(myrpt->rxchannel);
 			pthread_exit(NULL);
 		}
 		*--tele = '/';
@@ -4234,6 +4329,7 @@
 	}
 	myrpt->remoterx = 0;
 	myrpt->remotetx = 0;
+	myrpt->retxtimer = 0;
 	myrpt->remoteon = 1;
 	myrpt->dtmfidx = -1;
 	myrpt->dtmfbuf[0] = 0;
@@ -4268,6 +4364,14 @@
 		rem_totx = keyed;
 		
 		
+		if ((!myrpt->remoterx) && (!myrpt->remotetx))
+		{
+			if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME)
+			{
+				myrpt->retxtimer = 0;
+				ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
+			}
+		} else myrpt->retxtimer = 0;
 		if (rem_totx && (!myrpt->remotetx)) /* Remote base radio TX key */
 		{
 			myrpt->remotetx = 1;
@@ -4440,3 +4544,4 @@
 {
 	return ASTERISK_GPL_KEY;
 }
+




More information about the svn-commits mailing list