Newer
Older
#define NEW_ASTERISK
/* #define OLD_ASTERISK */
/*
* Asterisk -- An open source telephony toolkit.
* Copyright (C) 2002-2008, Jim Dixon, WB6NIL
* Jim Dixon, WB6NIL <jim@lambdatel.com>
* Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.com>
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
* \brief Radio Repeater / Remote Base program
* version 0.115 5/12/08 2055 EDT
* \author Jim Dixon, WB6NIL <jim@lambdatel.com>
*
* \note Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.com>
* \note Steven Henke, W9SH, <w9sh@arrl.net> added a few features here and there.
*
* See http://www.zapatatelephony.org/app_rpt.html
*
* Repeater / Remote Functions:
* "Simple" Mode: * - autopatch access, # - autopatch hangup
* Normal mode:
Jim Dixon
committed
* See the function list in rpt.conf (autopatchup, autopatchdn)
* autopatchup can optionally take comma delimited setting=value pairs:
*
*
* context=string : Override default context with "string"
* dialtime=ms : Specify the max number of milliseconds between phone number digits (1000 milliseconds = 1 second)
* farenddisconnect=1 : Automatically disconnect when called party hangs up
* noct=1 : Don't send repeater courtesy tone during autopatch calls
* quiet=1 : Don't send dial tone, or connect messages. Do not send patch down message when called party hangs up
*
*
* Example: 123=autopatchup,dialtime=20000,noct=1,farenddisconnect=1
*
* To send an asterisk (*) while dialing or talking on phone,
* use the autopatch acess code.
*
*
* status cmds:
*
* 1 - Force ID (global)
* 2 - Give Time of Day (global)
* 3 - Give software Version (global)
* 11 - Force ID (local only)
* 12 - Give Time of Day (local only)
*
* cop (control operator) cmds:
*
* 1 - System warm boot
* 2 - System enable
* 3 - System disable
* 5 - Dump System Variables on Console (debug)
* 6 - PTT (phone mode only)
* 7 - Time out timer enable
* 8 - Time out timer disable
* 9 - Autopatch enable
* 10 - Autopatch disable
* 11 - Link enable
* 12 - Link disable
* 13 - Query System State
* 14 - Change System State
* 15 - Scheduler Enable
* 16 - Scheduler Disable
* 17 - User functions (time, id, etc) enable
* 18 - User functions (time, id, etc) disable
* 19 - Select alternate hang timer
* 20 - Select standard hang timer
* 21 - Enable Parrot Mode
* 22 - Disable Parrot Mode
* 23 - Birdbath (Current Parrot Cleanup/Flush)
* 24 - Flush all telemetry
* 25 - Query last node un-keyed
* 26 - Query all nodes keyed/unkeyed
* 30 - Recall Memory Setting in Attached Xcvr
* 31 - Channel Selector for Parallel Programmed Xcvr
* 32 - Touchtone pad test: command + Digit string + # to playback all digits pressed
*
* ilink cmds:
*
* 1 - Disconnect specified link
* 2 - Connect specified link -- monitor only
* 3 - Connect specified link -- tranceive
* 4 - Enter command mode on specified link
* 5 - System status
* 6 - Disconnect all links
* 11 - Disconnect a previously permanently connected link
* 12 - Permanently connect specified link -- monitor only
* 13 - Permanently connect specified link -- tranceive
* 15 - Full system status (all nodes)
* 16 - Reconnect links disconnected with "disconnect all links"
* 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
*
* remote cmds:
*
* 1 - Recall Memory MM (*000-*099) (Gets memory from rpt.conf)
* 2 - Set VFO MMMMM*KKK*O (Mhz digits, Khz digits, Offset)
* 3 - Set Rx PL Tone HHH*D*
* 4 - Set Tx PL Tone HHH*D* (Not currently implemented with DHE RBI-1)
* 5 - Link Status (long)
* 6 - Set operating mode M (FM, USB, LSB, AM, etc)
* 100 - RX PL off (Default)
* 101 - RX PL On
* 102 - TX PL Off (Default)
* 103 - TX PL On
* 104 - Low Power
* 105 - Med Power
* 106 - Hi Power
* 107 - Bump Down 20 Hz
* 108 - Bump Down 100 Hz
* 109 - Bump Down 500 Hz
* 110 - Bump Up 20 Hz
* 111 - Bump Up 100 Hz
* 112 - Bump Up 500 Hz
* 113 - Scan Down Slow
* 114 - Scan Down Medium
* 115 - Scan Down Fast
* 116 - Scan Up Slow
* 117 - Scan Up Medium
* 118 - Scan Up Fast
* 119 - Transmit allowing auto-tune
* 140 - Link Status (brief)
* 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
*
* playback cmds:
* specify the name of the file to be played (for example, 25=rpt/foo)
*
Jim Dixon
committed
*
* 'duplex' modes: (defaults to duplex=2)
*
* 0 - Only remote links key Tx and no main repeat audio.
* 1 - Everything other then main Rx keys Tx, no main repeat audio.
* 2 - Normal mode
* 3 - Normal except no main repeat audio.
* 4 - Normal except no main repeat audio during autopatch only
*
*/
Kevin P. Fleming
committed
/*** MODULEINFO
<depend>dahdi</depend>
<depend>tonezone</depend>
Kevin P. Fleming
committed
<defaultenabled>no</defaultenabled>
***/
Jim Dixon
committed
/* Un-comment the following to include support for MDC-1200 digital tone
signalling protocol (using KA6SQG's GPL'ed implementation) */
/* #include "mdc_decode.c" */
/* Un-comment the following to include support for notch filters in the
rx audio stream (using Tony Fisher's mknotch (mkfilter) implementation) */
/* #include "rpt_notch.c" */
/* maximum digits in DTMF buffer, and seconds after * for DTMF command timeout */
#ifdef OLD_ASTERISK
#define ast_free free
#define ast_malloc malloc
#define ast_strdup strdup
#endif
#define MAXDTMF 32
#define MAXMACRO 2048
#define MAXLINKLIST 512
#define LINKLISTTIME 10000
#define LINKLISTSHORTTIME 200
#define LINKPOSTTIME 30000
#define LINKPOSTSHORTTIME 200
#define KEYPOSTTIME 30000
#define KEYPOSTSHORTTIME 200
#define MACROTIME 100
#define MACROPTIME 500
#define DTMF_TIMEOUT 3
#define KENWOOD_RETRIES 5
#define TOPKEYN 32
#define TOPKEYWAIT 3
#define TOPKEYMAXSTR 30
#define AUTHTELLTIME 7000
#define AUTHTXTIME 1000
#define AUTHLOGOUTTIME 25000
Jim Dixon
committed
#ifdef __RPT_NOTCH
#define MAXFILTERS 10
#endif
#define DISC_TIME 10000 /* report disc after 10 seconds of no connect */
#define MAX_RETRIES 5
#define MAX_RETRIES_PERM 1000000000
#define PATCH_DIALPLAN_TIMEOUT 1500
#ifdef OLD_ASTERISK
#define START_DELAY 10
#else
#define START_DELAY 2
#endif
#define RPT_LOCKOUT_SECS 10
Jim Dixon
committed
#define MAXPEERSTR 31
#define MAXREMSTR 15
#define DELIMCHR ','
#define QUOTECHR 34
#define MONITOR_DISK_BLOCKS_PER_MINUTE 38
#define DEFAULT_MONITOR_MIN_DISK_BLOCKS 10000
#define DEFAULT_REMOTE_INACT_TIMEOUT (15 * 60)
#define DEFAULT_REMOTE_TIMEOUT (60 * 60)
#define DEFAULT_REMOTE_TIMEOUT_WARNING (3 * 60)
#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ 30
#define NODES "nodes"
#define EXTNODES "extnodes"
#define MEMORY "memory"
#define MACRO "macro"
#define FUNCTIONS "functions"
#define TELEMETRY "telemetry"
#define MORSE "morse"
#define TONEMACRO "tonemacro"
#define FUNCCHAR '*'
#define ENDCHAR '#'
#define EXTNODEFILE "/var/lib/asterisk/rpt_extnodes"
#define NODENAMES "rpt/nodenames"
#define PARROTFILE "/tmp/parrot_%s_%u"
#define PARROTTIME 1000
#define DEFAULT_IOBASE 0x378
#define DEFAULT_CIV_ADDR 0x58
#define MAXCONNECTTIME 5000
#define MAXNODESTR 300
#define MAXNODELEN 16
#define MAXIDENTLEN 32
Jim Dixon
committed
#define MAXPATCHCONTEXT 100
#define ACTIONSIZE 32
#define TELEPARAMSIZE 256
#define REM_SCANTIME 100
#define DTMF_LOCAL_TIME 250
#define DTMF_LOCAL_STARTTIME 500
#define IC706_PL_MEMORY_OFFSET 50
#define VOX_ON_DEBOUNCE_COUNT 3
#define VOX_OFF_DEBOUNCE_COUNT 20
#define VOX_MAX_THRESHOLD 10000.0
#define VOX_MIN_THRESHOLD 3000.0
#define VOX_TIMEOUT_MS 5000
#define VOX_RECOVER_MS 500
#define SIMPLEX_PATCH_DELAY 25
#define SIMPLEX_PHONE_DELAY 25
#define STATPOST_PROGRAM "/usr/bin/wget,-q,--output-document=/dev/null,--no-check-certificate"
#define ALLOW_LOCAL_CHANNELS
enum {REM_OFF,REM_MONITOR,REM_TX};
enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME, PLAYBACK,
STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH,
TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY, FULLSTATUS,
MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS,
REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE, TOPKEY,
TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX, PARROT,
STATS_TIME_LOCAL};
enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
enum {REM_LOWPWR,REM_MEDPWR,REM_HIPWR};
enum {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY};
enum {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE, SOURCE_ALT};
enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM, DLY_COMP, DLY_LINKUNKEY, DLY_PARROT};
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};
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/io.h>
#include <dahdi/user.h>
#include <dahdi/tonezone.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
#include "asterisk/cdr.h"
#include "asterisk/options.h"
#include "asterisk/manager.h"
#include "asterisk/app.h"
#ifdef NEW_ASTERISK
struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS };
#endif
/* Start a tone-list going */
int ast_playtones_start(struct ast_channel *chan, int vol, const char* tonelist, int interruptible);
/*! Stop the tones from playing */
void ast_playtones_stop(struct ast_channel *chan);
static char *tdesc = "Radio Repeater / Remote Base version 0.115 5/12/2008";
static char *app = "Rpt";
static char *synopsis = "Radio Repeater/Remote Base Control System";
static char *descrip =
" Rpt(nodename[|options][|M][|*]): \n"
" Radio Remote Link or Remote Base Link Endpoint Process.\n"
"\n"
" Not specifying an option puts it in normal endpoint mode (where source\n"
" IP and nodename are verified).\n"
"\n"
" Options are as follows:\n"
"\n"
" X - Normal endpoint mode WITHOUT security check. Only specify\n"
" this if you have checked security already (like with an IAX2\n"
" user/password or something).\n"
"\n"
" Rannounce-string[|timeout[|timeout-destination]] - Amateur Radio\n"
" Reverse Autopatch. Caller is put on hold, and announcement (as\n"
" specified by the 'announce-string') is played on radio system.\n"
" Users of radio system can access autopatch, dial specified\n"
" code, and pick up call. Announce-string is list of names of\n"
" recordings, or \"PARKED\" to substitute code for un-parking,\n"
" or \"NODE\" to substitute node number.\n"
"\n"
" P - Phone Control mode. This allows a regular phone user to have\n"
" full control and audio access to the radio system. For the\n"
" user to have DTMF control, the 'phone_functions' parameter\n"
" must be specified for the node in 'rpt.conf'. An additional\n"
" function (cop,6) must be listed so that PTT control is available.\n"
"\n"
" D - Dumb Phone Control mode. This allows a regular phone user to\n"
" have full control and audio access to the radio system. In this\n"
" mode, the PTT is activated for the entire length of the call.\n"
" For the user to have DTMF control (not generally recomended in\n"
" this mode), the 'dphone_functions' parameter must be specified\n"
" for the node in 'rpt.conf'. Otherwise no DTMF control will be\n"
" available to the phone user.\n"
"\n"
" S - Simplex Dumb Phone Control mode. This allows a regular phone user\n"
" audio-only access to the radio system. In this mode, the\n"
" transmitter is toggled on and off when the phone user presses the\n"
" funcchar (*) key on the telephone set. In addition, the transmitter\n"
" will turn off if the endchar (#) key is pressed. When a user first\n"
" calls in, the transmitter will be off, and the user can listen for\n"
" radio traffic. When the user wants to transmit, they press the *\n"
" key, start talking, then press the * key again or the # key to turn\n"
" the transmitter off. No other functions can be executed by the\n"
" user on the phone when this mode is selected. Note: If your\n"
" radio system is full-duplex, we recommend using either P or D\n"
" modes as they provide more flexibility.\n"
"\n"
" q - Query Status. Sets channel variables and returns + 101 in plan.\n"
"\n"
" M - Memory Channel Steer as MXX where XX is the memory channel number.\n"
"\n"
" * - Alt Macro to execute (e.g. *7 for status)\n"
"\n";
static int debug = 0; /* Set this >0 for extra debug output */
static int nrpts = 0;
static const char remdtmfstr[] = "0123456789*#ABCD";
enum {TOP_TOP,TOP_WON,WON_BEFREAD,BEFREAD_AFTERREAD};
int max_chan_stat [] = {22000,1000,22000,100,22000,2000,22000};
#define NRPTSTAT 7
struct rpt_chan_stat
{
struct timeval last;
long long total;
unsigned long count;
unsigned long largest;
struct timeval largest_time;
};
char *newkeystr = "!NEWKEY!";
static char *remote_rig_ft897="ft897";
static char *remote_rig_rbi="rbi";
static char *remote_rig_kenwood="kenwood";
static char *remote_rig_tm271="tm271";
static char *remote_rig_ic706="ic706";
static char *remote_rig_rtx150="rtx150";
static char *remote_rig_rtx450="rtx450";
static char *remote_rig_ppp16="ppp16"; // parallel port programmable 16 channels
#define ISRIG_RTX(x) ((!strcmp(x,remote_rig_rtx150)) || (!strcmp(x,remote_rig_rtx450)))
#define IS_XPMR(x) (!strncasecmp(x->rxchanname,"rad",3))
#ifdef OLD_ASTERISK
STANDARD_LOCAL_USER;
LOCAL_USER_DECL;
#endif
#define MSWAIT 200
#define HANGTIME 5000
#define TOTIME 180000
#define IDTIME 300000
#define MAXRPTS 20
Jim Dixon
committed
#define MAX_STAT_LINKS 32
Jim Dixon
committed
#define POLITEID 30000
#define FUNCTDELAY 1500
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
#define MAXXLAT 20
#define MAXXLATTIME 3
#define MAX_SYSSTATES 10
struct vox {
float speech_energy;
float noise_energy;
int enacount;
char voxena;
char lastvox;
int offdebcnt;
int ondebcnt;
} ;
#define mymax(x,y) ((x > y) ? x : y)
#define mymin(x,y) ((x < y) ? x : y)
struct rpt_topkey
{
char node[TOPKEYMAXSTR];
int timesince;
int keyed;
} ;
struct rpt_xlat
{
char funccharseq[MAXXLAT];
char endcharseq[MAXXLAT];
char passchars[MAXXLAT];
int funcindex;
int endindex;
time_t lastone;
} ;
static time_t starttime = 0;
static pthread_t rpt_master_thread;
struct rpt;
struct rpt_link
{
struct rpt_link *next;
struct rpt_link *prev;
char mode; /* 1 if in tx mode */
char isremote;
char phonemode;
char phonevox; /* vox the phone */
char name[MAXNODESTR]; /* identifier (routing) string */
char lasttx;
char lastrx;
char lastrealrx;
char lastrx1;
char connected;
char perma;
char thisconnected;
char outbound;
long elaptime;
long disctime;
long retrytimer;
Jim Dixon
committed
int reconnects;
long long connecttime;
struct ast_channel *chan;
struct ast_channel *pchan;
char linklist[MAXLINKLIST];
time_t linklistreceived;
long linklisttimer;
int dtmfed;
int linkunkeytocttimer;
struct timeval lastlinktv;
struct ast_frame *lastf1,*lastf2;
struct rpt_chan_stat chan_stat[NRPTSTAT];
struct vox vox;
char wasvox;
int voxtotimer;
char voxtostate;
char newkey;
#ifdef OLD_ASTERISK
AST_LIST_HEAD(, ast_frame) rxq;
#else
AST_LIST_HEAD_NOLOCK(, ast_frame) rxq;
#endif
} ;
Jim Dixon
committed
struct rpt_lstat
{
struct rpt_lstat *next;
struct rpt_lstat *prev;
char peer[MAXPEERSTR];
char name[MAXNODESTR];
char mode;
char outbound;
char reconnects;
Jim Dixon
committed
long long connecttime;
struct rpt_chan_stat chan_stat[NRPTSTAT];
Jim Dixon
committed
} ;
struct rpt_tele
{
struct rpt_tele *next;
struct rpt_tele *prev;
struct rpt *rpt;
struct ast_channel *chan;
int mode;
struct rpt_link mylink;
char param[TELEPARAMSIZE];
pthread_t threadid;
} ;
struct function_table_tag
{
char action[ACTIONSIZE];
int (*function)(struct rpt *myrpt, char *param, char *digitbuf,
int command_source, struct rpt_link *mylink);
} ;
/* Used to store the morse code patterns */
struct morse_bits
{
int len;
int ddcomb;
} ;
struct telem_defaults
{
char name[20];
char value[80];
} ;
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
struct sysstate
{
char txdisable;
char totdisable;
char linkfundisable;
char autopatchdisable;
char schedulerdisable;
char userfundisable;
char alternatetail;
};
/* rpt cmd support */
#define CMD_DEPTH 1
#define CMD_STATE_IDLE 0
#define CMD_STATE_BUSY 1
#define CMD_STATE_READY 2
#define CMD_STATE_EXECUTING 3
struct rpt_cmd_struct
{
int state;
int functionNumber;
char param[MAXDTMF];
char digits[MAXDTMF];
int command_source;
};
ast_mutex_t lock;
ast_mutex_t remlock;
ast_mutex_t statpost_lock;
Jim Dixon
committed
struct ast_config *cfg;
char reload;
char xlink; // cross link state of a share repeater/remote radio
unsigned int statpost_seqno;
Jim Dixon
committed
char *name;
char remote;
char *remoterig;
struct rpt_chan_stat chan_stat[NRPTSTAT];
unsigned int scram;
Jim Dixon
committed
struct {
char *ourcontext;
char *ourcallerid;
char *acctcode;
char *ident;
char *tonezone;
Jim Dixon
committed
char simple;
char *functions;
char *link_functions;
char *phone_functions;
char *dphone_functions;
char *alt_functions;
char *nodes;
char *extnodes;
char *extnodefile;
Jim Dixon
committed
int hangtime;
Jim Dixon
committed
int totime;
int idtime;
int tailmessagetime;
int tailsquashedtime;
int duplex;
int politeid;
char *tailmessages[500];
int tailmessagemax;
char *memory;
char *macro;
char *tonemacro;
char *startupmacro;
Jim Dixon
committed
int iobase;
Jim Dixon
committed
char funcchar;
char endchar;
char nobusyout;
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
char notelemtx;
char propagate_dtmf;
char propagate_phonedtmf;
char linktolink;
unsigned char civaddr;
struct rpt_xlat inxlat;
struct rpt_xlat outxlat;
char *archivedir;
int authlevel;
char *csstanzaname;
char *skedstanzaname;
char *txlimitsstanzaname;
long monminblocks;
int remoteinacttimeout;
int remotetimeout;
int remotetimeoutwarning;
int remotetimeoutwarningfreq;
int sysstate_cur;
struct sysstate s[MAX_SYSSTATES];
char parrotmode;
int parrottime;
char *rptnode;
char remote_mars;
int voxtimeout_ms;
int voxrecover_ms;
int simplexpatchdelay;
int simplexphonedelay;
char *statpost_program;
char *statpost_url;
Jim Dixon
committed
} p;
struct rpt_link links;
int unkeytocttimer;
time_t lastkeyedtime;
time_t lasttxkeyedtime;
char exttx;
char localtx;
char remoterx;
char remotetx;
char remoteon;
char tounkeyed;
char tonotify;
char dtmfbuf[MAXDTMF];
char macrobuf[MAXMACRO];
char rem_dtmfbuf[MAXDTMF];
Jim Dixon
committed
char lastdtmfcommand[MAXDTMF];
char cmdnode[50];
char nowchan; // channel now
char waschan; // channel selected initially or by command
char bargechan; // barge in channel
char macropatch; // autopatch via tonemacro state
char parrotstate;
int parrottimer;
unsigned int parrotcnt;
struct ast_channel *rxchannel,*txchannel, *monchannel, *parrotchannel;
struct ast_channel *pchannel,*txpchannel, *dahdirxchannel, *dahditxchannel;
struct ast_channel *voxchannel;
struct ast_frame *lastf1,*lastf2;
struct rpt_tele tele;
struct timeval lasttv,curtv;
pthread_t rpt_call_thread,rpt_thread;
time_t dtmf_time,rem_dtmf_time,dtmf_time_rem;
int calldigittimer;
int tailtimer,totimer,idtimer,txconf,conf,callmode,cidx,scantimer,tmsgtimer,skedtimer;
int mustid,tailid;
Jim Dixon
committed
int tailevent;
int telemrefcount;
int dtmfidx,rem_dtmfidx;
int dailytxtime,dailykerchunks,totalkerchunks,dailykeyups,totalkeyups,timeouts;
Jim Dixon
committed
int totalexecdcommands, dailyexecdcommands;
long retxtimer;
long rerxtimer;
Jim Dixon
committed
long long totaltxtime;
char mydtmf;
char freq[MAXREMSTR],rxpl[MAXREMSTR],txpl[MAXREMSTR];
char offset;
char powerlevel;
char txplon;
char rxplon;
char remmode;
char tunerequest;
char hfscanmode;
int hfscanstatus;
char lastlinknode[MAXNODESTR];
char savednodes[MAXNODESTR];
int stopgen;
Jim Dixon
committed
char patchfarenddisconnect;
char patchnoct;
char patchquiet;
char patchcontext[MAXPATCHCONTEXT];
int patchdialtime;
int macro_longest;
int phone_longestfunc;
int dphone_longestfunc;
int link_longestfunc;
int longestfunc;
int longestnode;
int threadrestarts;
int tailmessagen;
time_t disgorgetime;
time_t lastthreadrestarttime;
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
long macrotimer;
char lastnodewhichkeyedusup[MAXNODESTR];
int dtmf_local_timer;
char dtmf_local_str[100];
struct ast_filestream *monstream,*parrotstream;
char loginuser[50];
char loginlevel[10];
long authtelltimer;
long authtimer;
int iofd;
time_t start_time,last_activity_time;
char lasttone[32];
struct rpt_tele *active_telem;
struct rpt_topkey topkey[TOPKEYN];
int topkeystate;
time_t topkeytime;
int topkeylong;
struct vox vox;
char wasvox;
int voxtotimer;
char voxtostate;
int linkposttimer;
int keyposttimer;
char newkey;
char inpadtest;
#ifdef OLD_ASTERISK
AST_LIST_HEAD(, ast_frame) txq;
#else
AST_LIST_HEAD_NOLOCK(, ast_frame) txq;
#endif
char txrealkeyed;
Jim Dixon
committed
#ifdef __RPT_NOTCH
struct rptfilter
{
char desc[100];
float x0;
float x1;
float x2;
float y0;
float y1;
float y2;
float gain;
float const0;
float const1;
float const2;
Jim Dixon
committed
} filters[MAXFILTERS];
#endif
#ifdef _MDC_DECODE_H_
mdc_decoder_t *mdc;
unsigned short lastunit;
#endif
struct rpt_cmd_struct cmdAction;
} rpt_vars[MAXRPTS];
struct nodelog {
struct nodelog *next;
struct nodelog *prev;
time_t timestamp;
char archivedir[MAXNODESTR];
char str[MAXNODESTR * 2];
} nodelog;
static int service_scan(struct rpt *myrpt);
static int set_mode_ft897(struct rpt *myrpt, char newmode);
static int set_mode_ic706(struct rpt *myrpt, char newmode);
static int simple_command_ft897(struct rpt *myrpt, char command);
static int setrem(struct rpt *myrpt);
static int setrtx_check(struct rpt *myrpt);
static int channel_revert(struct rpt *myrpt);
static int channel_steer(struct rpt *myrpt, char *data);
AST_MUTEX_DEFINE_STATIC(nodeloglock);
AST_MUTEX_DEFINE_STATIC(nodelookuplock);
#ifdef APP_RPT_LOCK_DEBUG
#warning COMPILING WITH LOCK-DEBUGGING ENABLED!!
#define MAXLOCKTHREAD 100
#define rpt_mutex_lock(x) _rpt_mutex_lock(x,myrpt,__LINE__)
#define rpt_mutex_unlock(x) _rpt_mutex_unlock(x,myrpt,__LINE__)
struct lockthread
{
pthread_t id;
int lockcount;
int lastlock;
int lastunlock;
} lockthreads[MAXLOCKTHREAD];
struct by_lightning
{
int line;
struct timeval tv;
struct rpt *rpt;
struct lockthread lockthread;
} lock_ring[32];
int lock_ring_index = 0;
AST_MUTEX_DEFINE_STATIC(locklock);
static struct lockthread *get_lockthread(pthread_t id)
{
for(i = 0; i < MAXLOCKTHREAD; i++)
{
if (lockthreads[i].id == id) return(&lockthreads[i]);
}
static struct lockthread *put_lockthread(pthread_t id)
{
for(i = 0; i < MAXLOCKTHREAD; i++)
{
if (lockthreads[i].id == id)
return(&lockthreads[i]);
}
for(i = 0; i < MAXLOCKTHREAD; i++)
{
if (!lockthreads[i].id)
{
lockthreads[i].lockcount = 0;
lockthreads[i].lastlock = 0;
lockthreads[i].lastunlock = 0;
lockthreads[i].id = id;
return(&lockthreads[i]);
}
}
}
static void rpt_mutex_spew(void)
{
struct by_lightning lock_ring_copy[32];
int lock_ring_index_copy;
long long diff;
struct timeval lasttv;
ast_mutex_lock(&locklock);
memcpy(&lock_ring_copy, &lock_ring, sizeof(lock_ring_copy));
lock_ring_index_copy = lock_ring_index;
ast_mutex_unlock(&locklock);
lasttv.tv_sec = lasttv.tv_usec = 0;
for(i = 0 ; i < 32 ; i++)
{
j = (i + lock_ring_index_copy) % 32;
strftime(a,sizeof(a) - 1,"%m/%d/%Y %H:%M:%S",
localtime(&lock_ring_copy[j].tv.tv_sec));
diff = 0;
if(lasttv.tv_sec)
{
diff = (lock_ring_copy[j].tv.tv_sec - lasttv.tv_sec)
* 1000000;
diff += (lock_ring_copy[j].tv.tv_usec - lasttv.tv_usec);
}
lasttv.tv_sec = lock_ring_copy[j].tv.tv_sec;
lasttv.tv_usec = lock_ring_copy[j].tv.tv_usec;
if (!lock_ring_copy[j].tv.tv_sec) continue;
if (lock_ring_copy[j].line < 0)
{
ast_log(LOG_NOTICE,"LOCKDEBUG [#%d] UNLOCK app_rpt.c:%d node %s pid %x diff %lld us at %s.%06d\n",
i - 31,-lock_ring_copy[j].line,lock_ring_copy[j].rpt->name,(int) lock_ring_copy[j].lockthread.id,diff,a,(int)lock_ring_copy[j].tv.tv_usec);
}
else
{
ast_log(LOG_NOTICE,"LOCKDEBUG [#%d] LOCK app_rpt.c:%d node %s pid %x diff %lld us at %s.%06d\n",
i - 31,lock_ring_copy[j].line,lock_ring_copy[j].rpt->name,(int) lock_ring_copy[j].lockthread.id,diff,a,(int)lock_ring_copy[j].tv.tv_usec);