mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	More improvements to app_rpt.c
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3338 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										186
									
								
								apps/app_rpt.c
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								apps/app_rpt.c
									
									
									
									
									
								
							| @@ -3,7 +3,7 @@ | ||||
|  * Asterisk -- A telephony toolkit for Linux. | ||||
|  * | ||||
|  * Radio Repeater / Remote Base program  | ||||
|  *  version 0.11 6/27/04 | ||||
|  *  version 0.12 6/28/04 | ||||
|  *  | ||||
|  * Copyright (C) 2002-2004, Jim Dixon, WB6NIL | ||||
|  * | ||||
| @@ -22,7 +22,9 @@ | ||||
|  *  *4XXX - remote link command mode | ||||
|  *  *6 - autopatch access/send (*) | ||||
|  *  *7 - system status | ||||
|  *  *8 - force ID | ||||
|  *  *80 - system ID | ||||
|  *  *81 - system time | ||||
|  *  *82 - system version  | ||||
|  *  *90 - system disable (and reset) | ||||
|  *  *91 - system enable | ||||
|  *  *99 - system reset | ||||
| @@ -50,9 +52,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 "05678" | ||||
| #define	SHORTFUNCS "0567" | ||||
| /* string containing all of the 2 digit functions */ | ||||
| #define	MEDFUNCS "9" | ||||
| #define	MEDFUNCS "89" | ||||
|  | ||||
| /* maximum digits in DTMF buffer, and seconds after * for DTMF command timeout */ | ||||
|  | ||||
| @@ -73,7 +75,7 @@ | ||||
| enum {REM_OFF,REM_MONITOR,REM_TX}; | ||||
|  | ||||
| enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO, | ||||
| 	CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1}; | ||||
| 	CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME, STATS_VERSION}; | ||||
|  | ||||
| enum {REM_SIMPLEX,REM_MINUS,REM_PLUS}; | ||||
|  | ||||
| @@ -91,6 +93,7 @@ enum {REM_LOWPWR,REM_MEDPWR,REM_HIPWR}; | ||||
| #include <asterisk/config.h> | ||||
| #include <asterisk/utils.h> | ||||
| #include <asterisk/say.h> | ||||
| #include <asterisk/localtime.h> | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <string.h> | ||||
| @@ -110,7 +113,7 @@ enum {REM_LOWPWR,REM_MEDPWR,REM_HIPWR}; | ||||
| #include <tonezone.h> | ||||
| #include <linux/zaptel.h> | ||||
|  | ||||
| static  char *tdesc = "Radio Repeater / Remote Base  version 0.10  06/26/2004"; | ||||
| static  char *tdesc = "Radio Repeater / Remote Base  version 0.12  06/28/2004"; | ||||
| static char *app = "Rpt"; | ||||
|  | ||||
| static char *synopsis = "Radio Repeater/Remote Base Control System"; | ||||
| @@ -210,6 +213,32 @@ static struct rpt | ||||
| 	char rxplon; | ||||
| } rpt_vars[MAXRPTS];		 | ||||
|  | ||||
| static int sayfile(struct ast_channel *mychannel,char *fname) | ||||
| { | ||||
| int	res; | ||||
|  | ||||
| 	res = ast_streamfile(mychannel, fname, 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; | ||||
| } | ||||
|  | ||||
| static int saycharstr(struct ast_channel *mychannel,char *str) | ||||
| { | ||||
| int	res; | ||||
|  | ||||
| 	res = ast_say_character_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; | ||||
| } | ||||
|  | ||||
| static void *rpt_tele_thread(void *this) | ||||
| { | ||||
| ZT_CONFINFO ci;  /* conference info */ | ||||
| @@ -218,6 +247,11 @@ struct	rpt_tele *mytele = (struct rpt_tele *)this; | ||||
| struct	rpt *myrpt; | ||||
| struct	rpt_link *l,*m,linkbase; | ||||
| struct	ast_channel *mychannel; | ||||
| int vmajor, vminor; | ||||
| char *p; | ||||
| time_t t; | ||||
| struct tm localtm; | ||||
|  | ||||
|  | ||||
| 	/* get a pointer to myrpt */ | ||||
| 	myrpt = mytele->rpt; | ||||
| @@ -460,6 +494,71 @@ struct	ast_channel *mychannel; | ||||
| 		ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); | ||||
| 		res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language); | ||||
| 		break; | ||||
| 		 | ||||
| 	    case STATS_TIME: | ||||
| 	    	usleep(1000000); /* Wait a little bit */ | ||||
| 		t = time(NULL); | ||||
| 		ast_localtime(&t, &localtm, NULL); | ||||
| 		/* 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) | ||||
| 		{ | ||||
| 			imdone = 1; | ||||
| 			break; | ||||
| 		} | ||||
| 		/* Say the time is ... */		 | ||||
| 		if (sayfile(mychannel,"rpt/thetimeis") == -1) | ||||
| 		{ | ||||
| 			imdone = 1; | ||||
| 			break; | ||||
| 		} | ||||
| 		/* Say the time */				 | ||||
| 	    	res = ast_say_time(mychannel, t, "", mychannel->language); | ||||
| 		if (!res)  | ||||
| 			res = ast_waitstream(mychannel, ""); | ||||
| 		ast_stopstream(mychannel);		 | ||||
| 		imdone = 1; | ||||
| 	    	break; | ||||
| 	    case STATS_VERSION: | ||||
| 		p = strstr(tdesc, "version");	 | ||||
| 		if(!p) | ||||
| 			break;	 | ||||
| 		if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2) | ||||
| 			break; | ||||
|     		usleep(1000000); /* Wait a little bit */ | ||||
| 		/* Say "version" */ | ||||
| 		if (sayfile(mychannel,"rpt/version") == -1) | ||||
| 		{ | ||||
| 			imdone = 1; | ||||
| 			break; | ||||
| 		} | ||||
| 		if(!res) /* Say "X" */ | ||||
| 			ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL); | ||||
| 		if (!res)  | ||||
| 			res = ast_waitstream(mychannel, ""); | ||||
| 		ast_stopstream(mychannel);	 | ||||
| 		if (saycharstr(mychannel,".") == -1) | ||||
| 		{ | ||||
| 			imdone = 1; | ||||
| 			break; | ||||
| 		} | ||||
| 		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); | ||||
| 		imdone = 1; | ||||
| 	    	break; | ||||
| 	    default: | ||||
| 	    	break; | ||||
| 	} | ||||
| 	if (!imdone) | ||||
| 	{ | ||||
| @@ -509,32 +608,6 @@ pthread_attr_t attr; | ||||
| 	return; | ||||
| } | ||||
|  | ||||
| static int sayfile(struct ast_channel *mychannel,char *fname) | ||||
| { | ||||
| int	res; | ||||
|  | ||||
| 	res = ast_streamfile(mychannel, fname, 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; | ||||
| } | ||||
|  | ||||
| static int saycharstr(struct ast_channel *mychannel,char *str) | ||||
| { | ||||
| int	res; | ||||
|  | ||||
| 	res = ast_say_character_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; | ||||
| } | ||||
|  | ||||
| static void *rpt_call(void *this) | ||||
| { | ||||
| ZT_CONFINFO ci;  /* conference info */ | ||||
| @@ -896,7 +969,6 @@ ZT_CONFINFO ci;  /* conference info */ | ||||
| 				return; | ||||
| 			} | ||||
| 			ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); | ||||
| 			usleep(500000);	 | ||||
| 		} | ||||
| 		ast_mutex_unlock(&myrpt->lock); | ||||
| 		/* establish call in monitor mode */ | ||||
| @@ -995,8 +1067,7 @@ ZT_CONFINFO ci;  /* conference info */ | ||||
| 				return; | ||||
| 			} | ||||
| 			ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); | ||||
| 			usleep(500000);	 | ||||
| 		} | ||||
| 		}  | ||||
| 		ast_mutex_unlock(&myrpt->lock); | ||||
| 		/* establish call in tranceive mode */ | ||||
| 		l = malloc(sizeof(struct rpt_link)); | ||||
| @@ -1094,10 +1165,28 @@ ZT_CONFINFO ci;  /* conference info */ | ||||
| 		if (!myrpt->enable) return; | ||||
| 		rpt_telemetry(myrpt,STATUS,NULL); | ||||
| 		return; | ||||
| 	case 8: /* force ID */ | ||||
| 		 | ||||
| 	case 8: /* Statistics */ | ||||
| 		if (!myrpt->enable) return; | ||||
| 		rpt_telemetry(myrpt,ID1,NULL); | ||||
| 		return; | ||||
| 		 | ||||
| 		switch(cmd[1]){ | ||||
| 		 | ||||
| 			case '0': /* Repeater ID */ | ||||
| 				rpt_telemetry(myrpt,ID1,NULL); | ||||
| 				return; | ||||
| 				 | ||||
| 			case '1': /* Time */ | ||||
| 				rpt_telemetry(myrpt, STATS_TIME, NULL); | ||||
| 				return; | ||||
| 				 | ||||
| 			case '2': /* Version */ | ||||
| 				rpt_telemetry(myrpt, STATS_VERSION, NULL); | ||||
| 				return; | ||||
| 				 | ||||
| 			default: | ||||
| 				return; | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		return; | ||||
| 	} | ||||
| @@ -2021,7 +2110,7 @@ pthread_attr_t attr; | ||||
| 		if (ast_check_hangup(myrpt->pchannel)) break; | ||||
| 		if (ast_check_hangup(myrpt->txpchannel)) break; | ||||
| 		ast_mutex_lock(&myrpt->lock); | ||||
| 		myrpt->localtx = keyed; | ||||
| 		myrpt->localtx = keyed && (myrpt->dtmfidx == -1) && (!myrpt->cmdnode[0]); | ||||
| 		l = myrpt->links.next; | ||||
| 		remrx = 0; | ||||
| 		while(l != &myrpt->links) | ||||
| @@ -2029,7 +2118,6 @@ pthread_attr_t attr; | ||||
| 			if (l->lastrx) remrx = 1; | ||||
| 			l = l->next; | ||||
| 		} | ||||
| 	 | ||||
| 		 | ||||
| 		/* Create a "must_id" flag for the cleanup ID */	 | ||||
| 			 | ||||
| @@ -2037,7 +2125,7 @@ pthread_attr_t attr; | ||||
|  | ||||
| 		/* Build a fresh totx from keyed and autopatch activated */ | ||||
| 		 | ||||
| 		totx = (keyed || myrpt->callmode); | ||||
| 		totx = myrpt->localtx || myrpt->callmode; | ||||
| 		  | ||||
| 		/* Traverse the telemetry list to see if there's an ID queued and if there is not an ID queued */ | ||||
| 		 | ||||
| @@ -2086,7 +2174,7 @@ pthread_attr_t attr; | ||||
| 		{ | ||||
| 			myrpt->tounkeyed = 1; | ||||
| 		} | ||||
| 		if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && keyed) | ||||
| 		if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->localtx) | ||||
| 		{ | ||||
| 			myrpt->totimer = myrpt->totime; | ||||
| 			myrpt->tounkeyed = 0; | ||||
| @@ -2204,6 +2292,8 @@ pthread_attr_t attr; | ||||
| 			} | ||||
| 			if (f->frametype == AST_FRAME_VOICE) | ||||
| 			{ | ||||
| 				if (!myrpt->localtx) | ||||
| 					memset(f->data,0,f->datalen); | ||||
| 				ast_write(myrpt->pchannel,f); | ||||
| 			} | ||||
| 			else if (f->frametype == AST_FRAME_DTMF) | ||||
| @@ -2685,7 +2775,7 @@ static int rpt_exec(struct ast_channel *chan, void *data) | ||||
| 		/* look at callerid to see what node this comes from */ | ||||
| 		if (!chan->callerid) /* if doesnt have callerid */ | ||||
| 		{ | ||||
| 			ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp); | ||||
| 			ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		ast_callerid_parse(chan->callerid,&b,&b1); | ||||
| @@ -2765,8 +2855,14 @@ static int rpt_exec(struct ast_channel *chan, void *data) | ||||
| 	if (myrpt->remoteon) | ||||
| 	{ | ||||
| 		ast_mutex_unlock(&myrpt->lock); | ||||
| 		ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp); | ||||
| 		return -1; | ||||
| 		usleep(500000); | ||||
| 		ast_mutex_lock(&myrpt->lock); | ||||
| 		if (myrpt->remoteon) | ||||
| 		{ | ||||
| 			ast_mutex_unlock(&myrpt->lock); | ||||
| 			ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp); | ||||
| 			return -1; | ||||
| 		}		 | ||||
| 	} | ||||
| 	if (ioperm(myrpt->iobase,1,1) == -1) | ||||
| 	{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user