[Asterisk-cvs] asterisk/apps app_rpt.c,1.9,1.10

jim at lists.digium.com jim at lists.digium.com
Fri Jun 25 15:47:29 CDT 2004


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

Modified Files:
	app_rpt.c 
Log Message:
Fixed problems with multiple links and added timeout message


Index: app_rpt.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_rpt.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- app_rpt.c	23 Jun 2004 14:37:46 -0000	1.9
+++ app_rpt.c	25 Jun 2004 19:33:22 -0000	1.10
@@ -3,7 +3,7 @@
  * Asterisk -- A telephony toolkit for Linux.
  *
  * Radio Repeater / Remote Base program 
- *  version 0.5 6/22/04
+ *  version 0.7 6/25/04
  * 
  * Copyright (C) 2002-2004, Jim Dixon, WB6NIL
  *
@@ -23,7 +23,9 @@
  *  *6 - autopatch access/send (*)
  *  *7 - system status
  *  *8 - force ID
- *  *9 - system reset
+ *  *90 - system disable (and reset)
+ *  *91 - system enable
+ *  *99 - system reset
  *
  *  To send an asterisk (*) while dialing or talking on phone,
  *  use the autopatch acess code.
@@ -32,7 +34,9 @@
 /* number of digits for function after *. Must be at least 1 */
 #define	FUNCTION_LEN 4
 /* string containing all of the 1 digit functions */
-#define	SHORTFUNCS "056789"
+#define	SHORTFUNCS "05678"
+/* string containing all of the 2 digit functions */
+#define	MEDFUNCS "9"
 
 /* maximum digits in DTMF buffer, and seconds after * for DTMF command timeout */
 
@@ -48,7 +52,7 @@
 enum {REM_OFF,REM_MONITOR,REM_TX};
 
 enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
-	CONNECTED,CONNFAIL,STATUS};
+	CONNECTED,CONNFAIL,STATUS,TIMEOUT};
 
 #include <asterisk/lock.h>
 #include <asterisk/file.h>
@@ -80,7 +84,7 @@
 #include <tonezone.h>
 #include <linux/zaptel.h>
 
-static  char *tdesc = "Radio Repeater / Remote Base  version 0.3  06/18/2004";
+static  char *tdesc = "Radio Repeater / Remote Base  version 0.7  06/25/2004";
 static char *app = "Rpt";
 
 static char *synopsis = "Radio Repeater/Remote Base Control System";
@@ -154,6 +158,9 @@
 	char remoteon;
 	char simple;
 	char remote;
+	char tounkeyed;
+	char tonotify;
+	char enable;
 	char dtmfbuf[MAXDTMF];
 	char rem_dtmfbuf[MAXDTMF];
 	char cmdnode[50];
@@ -402,6 +409,16 @@
 		}			
 		imdone = 1;
 		break;
+	    case TIMEOUT:
+		res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
+		if (!res) 
+			res = ast_waitstream(mychannel, "");
+		else
+			 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
+		ast_stopstream(mychannel);
+		ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
+		res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language);
+		break;
 	}
 	if (!imdone)
 	{
@@ -667,15 +684,12 @@
 	/* first, see if our dude is there */
 	while(l != &myrpt->links)
 	{
-		if (!l->isremote)
+		/* if we found it, write it and were done */
+		if (!strcmp(l->name,myrpt->cmdnode))
 		{
-			/* if we found it, write it and were done */
-			if (!strcmp(l->name,myrpt->cmdnode))
-			{
-				wf.data = strdup(str);
-				ast_write(l->chan,&wf);
-				return;
-			}
+			wf.data = strdup(str);
+			ast_write(l->chan,&wf);
+			return;
 		}
 		l = l->next;
 	}
@@ -683,11 +697,8 @@
 	/* if not, give it to everyone */
 	while(l != &myrpt->links)
 	{
-		if (!l->isremote) 
-		{
-			wf.data = strdup(str);
-			ast_write(l->chan,&wf);
-		}
+		wf.data = strdup(str);
+		ast_write(l->chan,&wf);
 		l = l->next;
 	}
 	return;
@@ -703,6 +714,7 @@
 	switch(atoi(cmd) / 1000)
 	{
 	case 6:	/* autopatch on / send asterisk (*) */
+		if (!myrpt->enable) return;
 		ast_mutex_lock(&myrpt->lock);
 		/* if on call, force * into current audio stream */
 		if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
@@ -725,6 +737,7 @@
 		pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt);
 		return;
 	case 0:	/* autopatch off */
+		if (!myrpt->enable) return;
 		ast_mutex_lock(&myrpt->lock);
 		if (!myrpt->callmode)
 		{
@@ -735,8 +748,19 @@
 		ast_mutex_unlock(&myrpt->lock);
 		rpt_telemetry(myrpt,TERM,NULL);
 		return;
-	case 9: /* master reset */
+	case 9: /* system control group */
+		/* if invalid, just ignore */
+		if ((cmd[1] >= '2') && (cmd[1] <= '8')) return;
 		ast_mutex_lock(&myrpt->lock);
+		if (cmd[1] == '1') /* system enable */
+		{
+			myrpt->enable = 1;
+		}
+		if (cmd[1] == '0') /* system disable */
+		{
+			myrpt->enable = 0;
+		}
+		/* reset system */
 		myrpt->callmode = 0;
 		ast_mutex_unlock(&myrpt->lock);
 		l = myrpt->links.next;
@@ -748,6 +772,7 @@
 		}
 		break;
 	case 1: /* remote base off */
+		if (!myrpt->enable) return;
 		val = ast_variable_retrieve(cfg,NODES,cmd + 1);
 		if (!val)
 		{
@@ -775,6 +800,7 @@
 		ast_mutex_unlock(&myrpt->lock);
 		return;
 	case 2: /* remote base monitor */
+		if (!myrpt->enable) return;
 		val = ast_variable_retrieve(cfg,NODES,cmd + 1);
 		if (!val)
 		{
@@ -872,6 +898,7 @@
 		ast_mutex_unlock(&myrpt->lock);
 		break;
 	case 3: /* remote base tranceieve */
+		if (!myrpt->enable) return;
 		val = ast_variable_retrieve(cfg,NODES,cmd + 1);
 		if (!val)
 		{
@@ -888,6 +915,7 @@
 		{
 			/* if found matching string */
 			if (!strcmp(l->name,cmd + 1)) break;
+			l = l->next;
 		}
 		/* if found */
 		if (l != &myrpt->links) 
@@ -970,6 +998,7 @@
 		ast_mutex_unlock(&myrpt->lock);
 		break;
 	case 4: /* remote cmd mode */
+		if (!myrpt->enable) return;
 		/* if doesnt allow link cmd, return */
  		if ((!allow_linkcmd) || (myrpt->links.next == &myrpt->links)) return;
 		/* if already in cmd mode, or selected self, forget it */
@@ -995,18 +1024,22 @@
 		rpt_telemetry(myrpt,REMGO,NULL);				
 		return;
 	case 7: /* system status */
+		if (!myrpt->enable) return;
 		rpt_telemetry(myrpt,STATUS,NULL);
 		return;
 	case 8: /* force ID */
+		if (!myrpt->enable) return;
 		myrpt->idtimer = 0;
 		return;
 	default:
 		return;
 	}
+	if (!myrpt->enable) return;
 	rpt_telemetry(myrpt,COMPLETE,NULL);
 }
 
-static void handle_link_data(struct rpt *myrpt, char *str)
+static void handle_link_data(struct rpt *myrpt, struct rpt_link *mylink,
+	char *str)
 {
 char	tmp[300],cmd[300],dest[300],src[300],c;
 int	seq;
@@ -1021,7 +1054,6 @@
 	wf.mallocd = 1;
 	wf.datalen = strlen(str) + 1;
 	wf.samples = 0;
-	l = myrpt->links.next;
  	/* put string in our buffer */
 	strncpy(tmp,str,sizeof(tmp) - 1);
 	if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
@@ -1038,10 +1070,39 @@
 	if (strcmp(dest,myrpt->name))
 	{
 		l = myrpt->links.next;
+		/* see if this is one in list */
 		while(l != &myrpt->links)
 		{
-			if (!l->isremote)
+			/* dont send back from where it came */
+			if ((l == mylink) || (!strcmp(l->name,mylink->name)))
+			{
+				l = l->next;
+				continue;
+			}
+			/* if it is, send it and we're done */
+			if (!strcmp(l->name,dest))
+			{
+				/* send, but not to src */
+				if (strcmp(l->name,src)) {
+					wf.data = strdup(str);
+					ast_write(l->chan,&wf);
+				}
+				return;
+			}
+			l = l->next;
+		}
+		l = myrpt->links.next;
+		/* otherwise, send it to all of em */
+		while(l != &myrpt->links)
+		{
+			/* dont send back from where it came */
+			if ((l == mylink) || (!strcmp(l->name,mylink->name)))
 			{
+				l = l->next;
+				continue;
+			}
+			/* send, but not to src */
+			if (strcmp(l->name,src)) {
 				wf.data = strdup(str);
 				ast_write(l->chan,&wf);
 			}
@@ -1072,6 +1133,13 @@
 					myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = '0';
 				myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
 			}
+			/* if to terminate function now */
+			if ((myrpt->rem_dtmfidx == 2) && strchr(MEDFUNCS,myrpt->rem_dtmfbuf[0]))
+			{
+				while(myrpt->rem_dtmfidx < FUNCTION_LEN)
+					myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = '0';
+				myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
+			}
 		}
 		if (myrpt->rem_dtmfidx == FUNCTION_LEN)
 		{
@@ -1087,6 +1155,29 @@
 	return;
 }
 
+static void handle_remote_data(struct rpt *myrpt, char *str)
+{
+char	tmp[300],cmd[300],dest[300],src[300],c;
+int	seq;
+
+ 	/* put string in our buffer */
+	strncpy(tmp,str,sizeof(tmp) - 1);
+	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);
+		return;
+	}
+	if (strcmp(cmd,"D"))
+	{
+		ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
+		return;
+	}
+	/* if not for me, ignore */
+	if (strcmp(dest,myrpt->name)) return;
+	printf("Remote %s got DTMF %c\n",myrpt->name,c);
+	return;
+}
+
 /* single thread with one file (request) to dial */
 static void *rpt(void *this)
 {
@@ -1223,7 +1314,8 @@
 	myrpt->totimer = 0;
 	myrpt->idtimer = 0;
 	myrpt->callmode = 0;
-	ast_mutex_unlock(&myrpt->lock);
+	myrpt->tounkeyed = 0;
+	myrpt->tonotify = 0;
 	lasttx = 0;
 	keyed = 0;
 	myrpt->dtmfidx = -1;
@@ -1232,6 +1324,8 @@
 	myrpt->rem_dtmfbuf[0] = 0;
 	dtmf_time = 0;
 	myrpt->rem_dtmf_time = 0;
+	myrpt->enable = 1;
+	ast_mutex_unlock(&myrpt->lock);
 	val = 0;
 	ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
 	val = 1;
@@ -1258,15 +1352,32 @@
 		totx = (keyed || myrpt->callmode || 
 			(myrpt->tele.next != &myrpt->tele));
 		myrpt->exttx = totx;
-		totx |= remrx;
-		if (!totx) myrpt->totimer = myrpt->totime;
+		totx = totx || remrx;
+		if (!totx) 
+		{
+			myrpt->totimer = myrpt->totime;
+			myrpt->tounkeyed = 0;
+			myrpt->tonotify = 0;
+		}
 		else myrpt->tailtimer = myrpt->hangtime;
-		totx = (totx || myrpt->tailtimer) && myrpt->totimer;
+		totx = totx && myrpt->totimer;
+		/* if timed-out and not said already, say it */
+		if ((!myrpt->totimer) && (!myrpt->tonotify))
+		{
+			myrpt->tonotify = 1;
+			rpt_telemetry(myrpt,TIMEOUT,NULL);
+		}
 		/* if wants to transmit and in phone call, but timed out, 
 			reset time-out timer if keyed */
-		if ((!totx) && (!myrpt->totimer) && myrpt->callmode && keyed)
+		if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!keyed))
+		{
+			myrpt->tounkeyed = 1;
+		}
+		if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && keyed)
 		{
 			myrpt->totimer = myrpt->totime;
+			myrpt->tounkeyed = 0;
+			myrpt->tonotify = 0;
 			ast_mutex_unlock(&myrpt->lock);
 			continue;
 		}
@@ -1275,6 +1386,11 @@
 		{
 			myrpt->callmode = 0;
 		}
+		/* get rid of tail if timed out */
+		if (!myrpt->totimer) myrpt->tailtimer = 0;
+		/* if not timed-out, add in tail */
+		if (myrpt->totimer) totx = totx || myrpt->tailtimer;
+		/* if time to ID */
 		if (totx && (!myrpt->idtimer))
 		{
 			myrpt->idtimer = myrpt->idtime;
@@ -1282,6 +1398,8 @@
 			rpt_telemetry(myrpt,ID,NULL);
 			ast_mutex_lock(&myrpt->lock);
 		}
+		/* let telemetry transmit anyway (regardless of timeout) */
+		totx = totx || (myrpt->tele.next != &myrpt->tele);
 		if (totx && (!lasttx))
 		{
 			lasttx = 1;
@@ -1289,6 +1407,7 @@
 			ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
 			ast_mutex_lock(&myrpt->lock);
 		}
+		totx = totx && myrpt->enable;
 		if ((!totx) && lasttx)
 		{
 			lasttx = 0;
@@ -1421,6 +1540,13 @@
 									myrpt->dtmfbuf[myrpt->dtmfidx++] = '0';
 								myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
 							}
+							/* if to terminate function now */
+							if ((myrpt->dtmfidx == 2) && strchr(MEDFUNCS,myrpt->dtmfbuf[0]))
+							{
+								while(myrpt->dtmfidx < FUNCTION_LEN)
+									myrpt->dtmfbuf[myrpt->dtmfidx++] = '0';
+								myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
+							}
 						}
 						if (myrpt->dtmfidx == FUNCTION_LEN)
 						{
@@ -1589,7 +1715,7 @@
 				}
 				if (f->frametype == AST_FRAME_TEXT)
 				{
-					handle_link_data(myrpt,f->data);
+					handle_link_data(myrpt,l,f->data);
 				}
 				if (f->frametype == AST_FRAME_CONTROL)
 				{
@@ -1839,6 +1965,7 @@
 		{
 			/* if found matching string */
 			if (!strcmp(l->name,b1)) break;
+			l = l->next;
 		}
 		/* if found */
 		if (l != &myrpt->links) 
@@ -2027,7 +2154,7 @@
 			}
 			else if (f->frametype == AST_FRAME_TEXT)
 			{
-				handle_link_data(myrpt,f->data);
+				handle_remote_data(myrpt,f->data);
 			}
 			else if (f->frametype == AST_FRAME_CONTROL)
 			{
@@ -2113,9 +2240,12 @@
 int unload_module(void)
 {
 	int i;
+
 	STANDARD_HANGUP_LOCALUSERS;
 	for(i = 0; i < nrpts; i++) {
+		if (!strcmp(rpt_vars[i].name,NODES)) continue;
                 ast_mutex_destroy(&rpt_vars[i].lock);
+	}
 	return ast_unregister_application(app);
 	return 0;
 }




More information about the svn-commits mailing list