mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-02 03:48:02 +00:00
New version, including half/semi-half duplex modes and system announcements
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7566 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
142
apps/app_rpt.c
142
apps/app_rpt.c
@@ -20,7 +20,7 @@
|
||||
/*
|
||||
*
|
||||
* Radio Repeater / Remote Base program
|
||||
* version 0.37 11/3/05
|
||||
* version 0.39 12/19/05
|
||||
*
|
||||
* See http://www.zapatatelephony.org/app_rpt.html
|
||||
*
|
||||
@@ -114,6 +114,9 @@
|
||||
|
||||
#define MAXREMSTR 15
|
||||
|
||||
#define DELIMCHR ','
|
||||
#define QUOTECHR 34
|
||||
|
||||
#define NODES "nodes"
|
||||
#define MEMORY "memory"
|
||||
#define FUNCTIONS "functions"
|
||||
@@ -139,7 +142,8 @@ enum {REM_OFF,REM_MONITOR,REM_TX};
|
||||
|
||||
enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
|
||||
CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME,
|
||||
STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH};
|
||||
STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH,
|
||||
TAILMSG};
|
||||
|
||||
enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
|
||||
|
||||
@@ -153,7 +157,8 @@ enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM};
|
||||
|
||||
enum {REM_MODE_FM,REM_MODE_USB,REM_MODE_LSB,REM_MODE_AM};
|
||||
|
||||
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};
|
||||
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};
|
||||
|
||||
#include "asterisk.h"
|
||||
|
||||
@@ -197,7 +202,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include "asterisk/say.h"
|
||||
#include "asterisk/localtime.h"
|
||||
|
||||
static char *tdesc = "Radio Repeater / Remote Base version 0.37 11/03/2005";
|
||||
static char *tdesc = "Radio Repeater / Remote Base version 0.39 12/19/2005";
|
||||
|
||||
static char *app = "Rpt";
|
||||
|
||||
@@ -341,6 +346,7 @@ static struct rpt
|
||||
int totime;
|
||||
int idtime;
|
||||
int unkeytocttimer;
|
||||
int duplex;
|
||||
char keyed;
|
||||
char exttx;
|
||||
char localtx;
|
||||
@@ -360,7 +366,7 @@ static struct rpt
|
||||
struct rpt_tele tele;
|
||||
pthread_t rpt_call_thread,rpt_thread;
|
||||
time_t rem_dtmf_time,dtmf_time_rem;
|
||||
int tailtimer,totimer,idtimer,txconf,conf,callmode,cidx,scantimer;
|
||||
int tailtimer,totimer,idtimer,txconf,conf,callmode,cidx,scantimer,tmsgtimer;
|
||||
int mustid;
|
||||
int politeid;
|
||||
int dtmfidx,rem_dtmfidx;
|
||||
@@ -387,6 +393,11 @@ static struct rpt
|
||||
int longestfunc;
|
||||
int longestnode;
|
||||
int threadrestarts;
|
||||
int tailmessagetime;
|
||||
int tailsquashedtime;
|
||||
char *tailmessages[500];
|
||||
int tailmessagemax;
|
||||
int tailmessagen;
|
||||
time_t disgorgetime;
|
||||
time_t lastthreadrestarttime;
|
||||
char nobusyout;
|
||||
@@ -459,6 +470,44 @@ static struct function_table_tag function_table[] = {
|
||||
{"remote", function_remote}
|
||||
} ;
|
||||
|
||||
static int finddelim(char *str,char *strp[])
|
||||
{
|
||||
int i,inquo;
|
||||
|
||||
inquo = 0;
|
||||
i = 0;
|
||||
strp[i++] = str;
|
||||
if (!*str)
|
||||
{
|
||||
strp[0] = 0;
|
||||
return(0);
|
||||
}
|
||||
for(; *str; str++)
|
||||
{
|
||||
if (*str == QUOTECHR)
|
||||
{
|
||||
if (inquo)
|
||||
{
|
||||
*str = 0;
|
||||
inquo = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strp[i - 1] = str + 1;
|
||||
inquo = 1;
|
||||
}
|
||||
}
|
||||
if ((*str == DELIMCHR) && (!inquo))
|
||||
{
|
||||
*str = 0;
|
||||
strp[i++] = str + 1;
|
||||
}
|
||||
}
|
||||
strp[i] = 0;
|
||||
return(i);
|
||||
|
||||
}
|
||||
|
||||
static int myatoi(char *str)
|
||||
{
|
||||
int ret;
|
||||
@@ -1006,8 +1055,9 @@ struct tm localtm;
|
||||
ci.chan = 0;
|
||||
/* If there's an ID queued, 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)) ?
|
||||
myrpt->txconf : myrpt->conf);
|
||||
ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) ||
|
||||
(mytele->mode == TAILMSG)) ?
|
||||
myrpt->txconf : myrpt->conf);
|
||||
ci.confmode = ZT_CONF_CONFANN;
|
||||
/* first put the channel on the conference in announce mode */
|
||||
if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
|
||||
@@ -1023,15 +1073,18 @@ struct tm localtm;
|
||||
ast_stopstream(mychannel);
|
||||
switch(mytele->mode)
|
||||
{
|
||||
|
||||
case ID:
|
||||
case ID1:
|
||||
/* wait a bit */
|
||||
wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel);
|
||||
res = telem_any(mychannel, ident);
|
||||
imdone=1;
|
||||
|
||||
imdone=1;
|
||||
break;
|
||||
|
||||
case TAILMSG:
|
||||
res = ast_streamfile(mychannel, myrpt->tailmessages[myrpt->tailmessagen], mychannel->language);
|
||||
break;
|
||||
|
||||
case IDTALKOVER:
|
||||
p = ast_variable_retrieve(cfg, nodename, "idtalkover");
|
||||
@@ -1482,6 +1535,18 @@ struct tm localtm;
|
||||
}
|
||||
ast_stopstream(mychannel);
|
||||
ast_mutex_lock(&myrpt->lock);
|
||||
if (mytele->mode == TAILMSG)
|
||||
{
|
||||
if (!res)
|
||||
{
|
||||
myrpt->tailmessagen++;
|
||||
if(myrpt->tailmessagen >= myrpt->tailmessagemax) myrpt->tailmessagen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
myrpt->tmsgtimer = myrpt->tailsquashedtime;
|
||||
}
|
||||
}
|
||||
remque((struct qelem *)mytele);
|
||||
ast_mutex_unlock(&myrpt->lock);
|
||||
free(mytele);
|
||||
@@ -2823,7 +2888,7 @@ struct zt_radio_param r;
|
||||
}
|
||||
}
|
||||
|
||||
static int serial_remote_io(struct rpt *myrpt, char *txbuf, int txbytes, char *rxbuf,
|
||||
static int serial_remote_io(struct rpt *myrpt, unsigned char *txbuf, int txbytes, char *rxbuf,
|
||||
int rxmaxbytes, int asciiflag)
|
||||
{
|
||||
int i;
|
||||
@@ -2855,7 +2920,8 @@ static int serial_remote_io(struct rpt *myrpt, char *txbuf, int txbytes, char *r
|
||||
|
||||
static int setrbi(struct rpt *myrpt)
|
||||
{
|
||||
char tmp[MAXREMSTR] = "",rbicmd[5],*s;
|
||||
char tmp[MAXREMSTR] = "",*s;
|
||||
unsigned char rbicmd[5];
|
||||
int band,txoffset = 0,txpower = 0,txpl;
|
||||
|
||||
/* must be a remote system */
|
||||
@@ -4528,7 +4594,7 @@ static void *rpt(void *this)
|
||||
{
|
||||
struct rpt *myrpt = (struct rpt *)this;
|
||||
char *tele,*idtalkover;
|
||||
int ms = MSWAIT,lasttx=0,val,remrx=0,identqueued,nonidentqueued,res;
|
||||
int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,nonidentqueued,res, tailmessagequeued;
|
||||
struct ast_channel *who;
|
||||
ZT_CONFINFO ci; /* conference info */
|
||||
time_t dtmf_time,t;
|
||||
@@ -4676,7 +4742,8 @@ char cmd[MAXDTMF+1] = "";
|
||||
/* make a conference for the pseudo */
|
||||
ci.chan = 0;
|
||||
ci.confno = -1; /* make a new conf */
|
||||
ci.confmode = ZT_CONF_CONFANNMON;
|
||||
ci.confmode = (myrpt->duplex == 2) ? ZT_CONF_CONFANNMON :
|
||||
(ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER);
|
||||
/* first put the channel on the conference in announce mode */
|
||||
if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
|
||||
{
|
||||
@@ -4728,6 +4795,7 @@ char cmd[MAXDTMF+1] = "";
|
||||
myrpt->links.prev = &myrpt->links;
|
||||
myrpt->tailtimer = 0;
|
||||
myrpt->totimer = 0;
|
||||
myrpt->tmsgtimer = myrpt->tailmessagetime;
|
||||
myrpt->idtimer = myrpt->politeid;
|
||||
myrpt->mustid = 0;
|
||||
myrpt->callmode = 0;
|
||||
@@ -4835,35 +4903,46 @@ char cmd[MAXDTMF+1] = "";
|
||||
|
||||
/* Build a fresh totx from myrpt->keyed and autopatch activated */
|
||||
|
||||
totx = myrpt->localtx || myrpt->callmode;
|
||||
totx = myrpt->callmode;
|
||||
if (myrpt->duplex > 1) totx = totx || myrpt->localtx;
|
||||
|
||||
/* Traverse the telemetry list to see if there's an ID queued and if there is not an ID queued */
|
||||
|
||||
identqueued = 0;
|
||||
nonidentqueued = 0;
|
||||
|
||||
tailmessagequeued = 0;
|
||||
|
||||
telem = myrpt->tele.next;
|
||||
while(telem != &myrpt->tele)
|
||||
{
|
||||
|
||||
if((telem->mode == ID) || (telem->mode == IDTALKOVER)){
|
||||
identqueued = 1;
|
||||
}
|
||||
else if(telem->mode == TAILMSG)
|
||||
{
|
||||
tailmessagequeued = 1;
|
||||
}
|
||||
else
|
||||
nonidentqueued = 1;
|
||||
{
|
||||
if (telem->mode != UNKEY) nonidentqueued = 1;
|
||||
}
|
||||
telem = telem->next;
|
||||
}
|
||||
|
||||
/* Add in any non-id telemetry */
|
||||
|
||||
totx = totx || nonidentqueued;
|
||||
if (myrpt->duplex > 0) totx = totx || nonidentqueued;
|
||||
|
||||
/* Update external transmitter PTT state with everything but ID telemetry */
|
||||
|
||||
myrpt->exttx = totx;
|
||||
if (myrpt->duplex < 2) myrpt->exttx = myrpt->exttx || myrpt->localtx;
|
||||
|
||||
/* Add in ID telemetry to local transmitter */
|
||||
|
||||
totx = totx || remrx || identqueued;
|
||||
totx = totx || remrx;
|
||||
if (myrpt->duplex > 0) totx = totx || identqueued || (telem->mode == UNKEY);
|
||||
|
||||
if (!totx)
|
||||
{
|
||||
@@ -4905,7 +4984,8 @@ char cmd[MAXDTMF+1] = "";
|
||||
/* if not timed-out, add in tail */
|
||||
if (myrpt->totimer) totx = totx || myrpt->tailtimer;
|
||||
/* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */
|
||||
if (identqueued && (myrpt->keyed || remrx) && idtalkover) {
|
||||
/* If tail message, kill the message if someone keys up over it */
|
||||
if ((myrpt->keyed || remrx) && ((identqueued && idtalkover) || (tailmessagequeued))) {
|
||||
int hasid = 0,hastalkover = 0;
|
||||
|
||||
telem = myrpt->tele.next;
|
||||
@@ -4914,6 +4994,9 @@ char cmd[MAXDTMF+1] = "";
|
||||
if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
|
||||
hasid = 1;
|
||||
}
|
||||
if(telem->mode == TAILMSG){
|
||||
if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
|
||||
}
|
||||
if (telem->mode == IDTALKOVER) hastalkover = 1;
|
||||
telem = telem->next;
|
||||
}
|
||||
@@ -4936,7 +5019,7 @@ char cmd[MAXDTMF+1] = "";
|
||||
ast_mutex_lock(&myrpt->lock);
|
||||
}
|
||||
/* let telemetry transmit anyway (regardless of timeout) */
|
||||
totx = totx || (myrpt->tele.next != &myrpt->tele);
|
||||
if (myrpt->duplex > 0) totx = totx || (myrpt->tele.next != &myrpt->tele);
|
||||
if (totx && (!lasttx))
|
||||
{
|
||||
lasttx = 1;
|
||||
@@ -5114,12 +5197,21 @@ char cmd[MAXDTMF+1] = "";
|
||||
#endif
|
||||
l = l->next;
|
||||
}
|
||||
i = myrpt->tailtimer;
|
||||
if (myrpt->tailtimer) myrpt->tailtimer -= elap;
|
||||
if (myrpt->tailtimer < 0) myrpt->tailtimer = 0;
|
||||
if ((myrpt->tailmessagetime) && (myrpt->tailtimer == 0) && i && (myrpt->tmsgtimer == 0)){
|
||||
myrpt->tmsgtimer = myrpt->tailmessagetime;
|
||||
rpt_telemetry(myrpt, TAILMSG, NULL);
|
||||
}
|
||||
if (myrpt->tailtimer < 0) myrpt->tailtimer = 0;
|
||||
if (myrpt->totimer) myrpt->totimer -= elap;
|
||||
if (myrpt->totimer < 0) myrpt->totimer = 0;
|
||||
if (myrpt->idtimer) myrpt->idtimer -= elap;
|
||||
if (myrpt->idtimer < 0) myrpt->idtimer = 0;
|
||||
if (myrpt->tmsgtimer) myrpt->tmsgtimer -= elap;
|
||||
if (myrpt->tmsgtimer < 0) myrpt->tmsgtimer = 0;
|
||||
|
||||
ast_mutex_unlock(&myrpt->lock);
|
||||
if (!ms) continue;
|
||||
if (who == myrpt->rxchannel) /* if it was a read from rx */
|
||||
@@ -5652,11 +5744,19 @@ pthread_attr_t attr;
|
||||
val = ast_variable_retrieve(cfg,this,"totime");
|
||||
if (val) rpt_vars[n].totime = atoi(val);
|
||||
else rpt_vars[n].totime = TOTIME;
|
||||
|
||||
|
||||
rpt_vars[n].tailmessagetime = retrieve_astcfgint(this, "tailmessagetime", 0, 2400000, 0);
|
||||
rpt_vars[n].tailsquashedtime = retrieve_astcfgint(this, "tailsquashedtime", 0, 2400000, 0);
|
||||
rpt_vars[n].duplex = retrieve_astcfgint(this,"duplex",0,3,2);
|
||||
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");
|
||||
rpt_vars[n].tailmessages[0] = 0;
|
||||
rpt_vars[n].tailmessagemax = 0;
|
||||
rpt_vars[n].tailmessagen = 0;
|
||||
val = ast_variable_retrieve(cfg,this,"tailmessagelist");
|
||||
if (val) rpt_vars[n].tailmessagemax = finddelim(val,rpt_vars[n].tailmessages);
|
||||
val = ast_variable_retrieve(cfg,this,"iobase");
|
||||
/* do not use atoi() here, we need to be able to have
|
||||
the input specified in hex or decimal so we use
|
||||
|
||||
Reference in New Issue
Block a user