Sat Nov 1 06:28:20 2008

Asterisk developer's documentation


app_rpt.c

Go to the documentation of this file.
00001 /* #define OLD_ASTERISK */
00002 #define  OLDKEY
00003 /*
00004  * Asterisk -- An open source telephony toolkit.
00005  *
00006  * Copyright (C) 2002-2007, Jim Dixon, WB6NIL
00007  *
00008  * Jim Dixon, WB6NIL <jim@lambdatel.com>
00009  * Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.com>
00010  *
00011  * See http://www.asterisk.org for more information about
00012  * the Asterisk project. Please do not directly contact
00013  * any of the maintainers of this project for assistance;
00014  * the project provides a web site, mailing lists and IRC
00015  * channels for your use.
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 /*! \file
00022  *
00023  * \brief Radio Repeater / Remote Base program 
00024  *  version 0.73 09/04/07
00025  * 
00026  * \author Jim Dixon, WB6NIL <jim@lambdatel.com>
00027  *
00028  * \note Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.com>
00029  * 
00030  * See http://www.zapatatelephony.org/app_rpt.html
00031  *
00032  *
00033  * Repeater / Remote Functions:
00034  * "Simple" Mode:  * - autopatch access, # - autopatch hangup
00035  * Normal mode:
00036  * See the function list in rpt.conf (autopatchup, autopatchdn)
00037  * autopatchup can optionally take comma delimited setting=value pairs:
00038  *  
00039  *
00040  * context=string    :  Override default context with "string"
00041  * dialtime=ms       :  Specify the max number of milliseconds between phone number digits (1000 milliseconds = 1 second)
00042  * farenddisconnect=1      :  Automatically disconnect when called party hangs up
00043  * noct=1         :  Don't send repeater courtesy tone during autopatch calls
00044  * quiet=1        :  Don't send dial tone, or connect messages. Do not send patch down message when called party hangs up
00045  *
00046  *
00047  * Example: 123=autopatchup,dialtime=20000,noct=1,farenddisconnect=1
00048  *
00049  *  To send an asterisk (*) while dialing or talking on phone,
00050  *  use the autopatch acess code.
00051  *
00052  *
00053  * status cmds:
00054  *
00055  *  1 - Force ID
00056  *  2 - Give Time of Day
00057  *  3 - Give software Version
00058  *
00059  * cop (control operator) cmds:
00060  *
00061  *  1 - System warm boot
00062  *  2 - System enable
00063  *  3 - System disable
00064  *  4 - Test Tone On/Off
00065  *  5 - Dump System Variables on Console (debug)
00066  *  6 - PTT (phone mode only)
00067  *  7 - Time out timer enable
00068  *  8 - Time out timer disable
00069  *  9 - Autopatch enable
00070  *  10 - Autopatch disable
00071  *  11 - Link enable
00072  *  12 - Link disable
00073  *  13 - Query System State
00074  *  14 - Change System State
00075  *  15 - Scheduler Enable
00076  *  16 - Scheduler Disable
00077  *  17 - User functions (time, id, etc) enable
00078  *  18 - User functions (time, id, etc) disable
00079  *  19 - Select alternate hang timer
00080  *  20 - Select standard hang timer 
00081  *
00082  * ilink cmds:
00083  *
00084  *  1 - Disconnect specified link
00085  *  2 - Connect specified link -- monitor only
00086  *  3 - Connect specified link -- tranceive
00087  *  4 - Enter command mode on specified link
00088  *  5 - System status
00089  *  6 - Disconnect all links
00090  *  11 - Disconnect a previously permanently connected link
00091  *  12 - Permanently connect specified link -- monitor only
00092  *  13 - Permanently connect specified link -- tranceive
00093  *  15 - Full system status (all nodes)
00094  *  16 - Reconnect links disconnected with "disconnect all links"
00095  *  200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
00096  *
00097  * remote cmds:
00098  *
00099  *  1 - Recall Memory MM  (*000-*099) (Gets memory from rpt.conf)
00100  *  2 - Set VFO MMMMM*KKK*O   (Mhz digits, Khz digits, Offset)
00101  *  3 - Set Rx PL Tone HHH*D*
00102  *  4 - Set Tx PL Tone HHH*D* (Not currently implemented with DHE RBI-1)
00103  *  5 - Link Status (long)
00104  *  6 - Set operating mode M (FM, USB, LSB, AM, etc)
00105  *  100 - RX PL off (Default)
00106  *  101 - RX PL On
00107  *  102 - TX PL Off (Default)
00108  *  103 - TX PL On
00109  *  104 - Low Power
00110  *  105 - Med Power
00111  *  106 - Hi Power
00112  *  107 - Bump Down 20 Hz
00113  *  108 - Bump Down 100 Hz
00114  *  109 - Bump Down 500 Hz
00115  *  110 - Bump Up 20 Hz
00116  *  111 - Bump Up 100 Hz
00117  *  112 - Bump Up 500 Hz
00118  *  113 - Scan Down Slow
00119  *  114 - Scan Down Medium
00120  *  115 - Scan Down Fast
00121  *  116 - Scan Up Slow
00122  *  117 - Scan Up Medium
00123  *  118 - Scan Up Fast
00124  *  119 - Transmit allowing auto-tune
00125  *  140 - Link Status (brief)
00126  *  200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
00127  *
00128  *
00129  * 'duplex' modes:  (defaults to duplex=2)
00130  *
00131  * 0 - Only remote links key Tx and no main repeat audio.
00132  * 1 - Everything other then main Rx keys Tx, no main repeat audio.
00133  * 2 - Normal mode
00134  * 3 - Normal except no main repeat audio.
00135  * 4 - Normal except no main repeat audio during autopatch only
00136  *
00137 */
00138 
00139 /*** MODULEINFO
00140    <depend>dahdi</depend>
00141    <depend>tonezone</depend>
00142    <defaultenabled>no</defaultenabled>
00143  ***/
00144 
00145 /* Un-comment the following to include support for MDC-1200 digital tone
00146    signalling protocol (using KA6SQG's GPL'ed implementation) */
00147 /* #include "mdc_decode.c" */
00148 
00149 /* Un-comment the following to include support for notch filters in the
00150    rx audio stream (using Tony Fisher's mknotch (mkfilter) implementation) */
00151 /* #include "rpt_notch.c" */
00152 
00153 /* maximum digits in DTMF buffer, and seconds after * for DTMF command timeout */
00154 
00155 #define  MAXDTMF 32
00156 #define  MAXMACRO 2048
00157 #define  MAXLINKLIST 512
00158 #define  LINKLISTTIME 10000
00159 #define  LINKLISTSHORTTIME 200
00160 #define  MACROTIME 100
00161 #define  MACROPTIME 500
00162 #define  DTMF_TIMEOUT 3
00163 #define  KENWOOD_RETRIES 5
00164 
00165 #define  AUTHTELLTIME 7000
00166 #define  AUTHTXTIME 1000
00167 #define  AUTHLOGOUTTIME 25000
00168 
00169 #ifdef   __RPT_NOTCH
00170 #define  MAXFILTERS 10
00171 #endif
00172 
00173 #define  DISC_TIME 10000  /* report disc after 10 seconds of no connect */
00174 #define  MAX_RETRIES 5
00175 #define  MAX_RETRIES_PERM 1000000000
00176 
00177 #define  REDUNDANT_TX_TIME 2000
00178 
00179 #define  RETRY_TIMER_MS 5000
00180 
00181 #define  START_DELAY 2
00182 
00183 #define MAXPEERSTR 31
00184 #define  MAXREMSTR 15
00185 
00186 #define  DELIMCHR ','
00187 #define  QUOTECHR 34
00188 
00189 #define  MONITOR_DISK_BLOCKS_PER_MINUTE 38
00190 
00191 #define  DEFAULT_MONITOR_MIN_DISK_BLOCKS 10000
00192 #define  DEFAULT_REMOTE_INACT_TIMEOUT (15 * 60)
00193 #define  DEFAULT_REMOTE_TIMEOUT (60 * 60)
00194 #define  DEFAULT_REMOTE_TIMEOUT_WARNING (3 * 60)
00195 #define  DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ 30
00196 
00197 #define  NODES "nodes"
00198 #define  EXTNODES "extnodes"
00199 #define MEMORY "memory"
00200 #define MACRO "macro"
00201 #define  FUNCTIONS "functions"
00202 #define TELEMETRY "telemetry"
00203 #define MORSE "morse"
00204 #define  FUNCCHAR '*'
00205 #define  ENDCHAR '#'
00206 #define  EXTNODEFILE "/var/lib/asterisk/rpt_extnodes"
00207 
00208 #define  DEFAULT_IOBASE 0x378
00209 
00210 #define  DEFAULT_CIV_ADDR 0x58
00211 
00212 #define  MAXCONNECTTIME 5000
00213 
00214 #define MAXNODESTR 300
00215 
00216 #define MAXPATCHCONTEXT 100
00217 
00218 #define ACTIONSIZE 32
00219 
00220 #define TELEPARAMSIZE 256
00221 
00222 #define REM_SCANTIME 100
00223 
00224 #define  DTMF_LOCAL_TIME 250
00225 #define  DTMF_LOCAL_STARTTIME 500
00226 
00227 #define  IC706_PL_MEMORY_OFFSET 50
00228 
00229 #define  ALLOW_LOCAL_CHANNELS
00230 
00231 enum {REM_OFF,REM_MONITOR,REM_TX};
00232 
00233 enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
00234    CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME,
00235    STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH,
00236    TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY, FULLSTATUS,
00237    MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS,
00238    REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE,
00239    TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX};
00240 
00241 
00242 enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
00243 
00244 enum {REM_LOWPWR,REM_MEDPWR,REM_HIPWR};
00245 
00246 enum {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY};
00247 
00248 enum {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE};
00249 
00250 enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM, DLY_COMP, DLY_LINKUNKEY};
00251 
00252 enum {REM_MODE_FM,REM_MODE_USB,REM_MODE_LSB,REM_MODE_AM};
00253 
00254 enum {HF_SCAN_OFF,HF_SCAN_DOWN_SLOW,HF_SCAN_DOWN_QUICK,
00255       HF_SCAN_DOWN_FAST,HF_SCAN_UP_SLOW,HF_SCAN_UP_QUICK,HF_SCAN_UP_FAST};
00256 
00257 #include "asterisk.h"
00258 
00259 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 146244 $")
00260 
00261 #include <signal.h>
00262 #include <stdio.h>
00263 #include <unistd.h>
00264 #include <string.h>
00265 #include <stdlib.h>
00266 #include <search.h>
00267 #include <sys/types.h>
00268 #include <sys/stat.h>
00269 #include <errno.h>
00270 #include <dirent.h>
00271 #include <ctype.h>
00272 #include <sys/stat.h>
00273 #include <sys/time.h>
00274 #include <sys/file.h>
00275 #include <sys/ioctl.h>
00276 #include <sys/io.h>
00277 #include <sys/vfs.h>
00278 #include <math.h>
00279 #include <netinet/in.h>
00280 #include <arpa/inet.h>
00281 #include <termios.h>
00282 
00283 #include "asterisk/utils.h"
00284 #include "asterisk/lock.h"
00285 #include "asterisk/file.h"
00286 #include "asterisk/logger.h"
00287 #include "asterisk/channel.h"
00288 #include "asterisk/callerid.h"
00289 #include "asterisk/pbx.h"
00290 #include "asterisk/module.h"
00291 #include "asterisk/translate.h"
00292 #include "asterisk/features.h"
00293 #include "asterisk/options.h"
00294 #include "asterisk/cli.h"
00295 #include "asterisk/config.h"
00296 #include "asterisk/say.h"
00297 #include "asterisk/localtime.h"
00298 #include "asterisk/cdr.h"
00299 #include "asterisk/options.h"
00300 
00301 #include "asterisk/dahdi_compat.h"
00302 #include "asterisk/tonezone_compat.h"
00303 
00304 /* Start a tone-list going */
00305 int ast_playtones_start(struct ast_channel *chan, int vol, const char* tonelist, int interruptible);
00306 /*! Stop the tones from playing */
00307 void ast_playtones_stop(struct ast_channel *chan);
00308 
00309 static  char *tdesc = "Radio Repeater / Remote Base  version 0.73  09/04/2007";
00310 
00311 static char *app = "Rpt";
00312 
00313 static char *synopsis = "Radio Repeater/Remote Base Control System";
00314 
00315 static char *descrip = 
00316 "  Rpt(nodename[|options]):  Radio Remote Link or Remote Base Link Endpoint Process.\n"
00317 "\n"
00318 "    Not specifying an option puts it in normal endpoint mode (where source\n"
00319 "    IP and nodename are verified).\n"
00320 "\n"
00321 "    Options are as follows:\n"
00322 "\n"
00323 "        X - Normal endpoint mode WITHOUT security check. Only specify\n"
00324 "            this if you have checked security already (like with an IAX2\n"
00325 "            user/password or something).\n"
00326 "\n"
00327 "        Rannounce-string[|timeout[|timeout-destination]] - Amateur Radio\n"
00328 "            Reverse Autopatch. Caller is put on hold, and announcement (as\n"
00329 "            specified by the 'announce-string') is played on radio system.\n"
00330 "            Users of radio system can access autopatch, dial specified\n"
00331 "            code, and pick up call. Announce-string is list of names of\n"
00332 "            recordings, or \"PARKED\" to substitute code for un-parking,\n"
00333 "            or \"NODE\" to substitute node number.\n"
00334 "\n"
00335 "        P - Phone Control mode. This allows a regular phone user to have\n"
00336 "            full control and audio access to the radio system. For the\n"
00337 "            user to have DTMF control, the 'phone_functions' parameter\n"
00338 "            must be specified for the node in 'rpt.conf'. An additional\n"
00339 "            function (cop,6) must be listed so that PTT control is available.\n"
00340 "\n"
00341 "        D - Dumb Phone Control mode. This allows a regular phone user to\n"
00342 "            have full control and audio access to the radio system. In this\n"
00343 "            mode, the PTT is activated for the entire length of the call.\n"
00344 "            For the user to have DTMF control (not generally recomended in\n"
00345 "            this mode), the 'dphone_functions' parameter must be specified\n"
00346 "            for the node in 'rpt.conf'. Otherwise no DTMF control will be\n"
00347 "            available to the phone user.\n"
00348 "\n";
00349 
00350 static int debug = 0;  /* Set this >0 for extra debug output */
00351 static int nrpts = 0;
00352 
00353 static char remdtmfstr[] = "0123456789*#ABCD";
00354 
00355 enum {TOP_TOP,TOP_WON,WON_BEFREAD,BEFREAD_AFTERREAD};
00356 
00357 int max_chan_stat [] = {22000,1000,22000,100,22000,2000,22000};
00358 
00359 #define NRPTSTAT 7
00360 
00361 struct rpt_chan_stat
00362 {
00363    struct timeval last;
00364    long long total;
00365    unsigned long count;
00366    unsigned long largest;
00367    struct timeval largest_time;
00368 };
00369 
00370 char *discstr = "!!DISCONNECT!!";
00371 static char *remote_rig_ft897="ft897";
00372 static char *remote_rig_rbi="rbi";
00373 static char *remote_rig_kenwood="kenwood";
00374 static char *remote_rig_ic706="ic706";
00375 
00376 #ifdef   OLD_ASTERISK
00377 STANDARD_LOCAL_USER;
00378 LOCAL_USER_DECL;
00379 #endif
00380 
00381 #define  MSWAIT 200
00382 #define  HANGTIME 5000
00383 #define  TOTIME 180000
00384 #define  IDTIME 300000
00385 #define  MAXRPTS 20
00386 #define MAX_STAT_LINKS 32
00387 #define POLITEID 30000
00388 #define FUNCTDELAY 1500
00389 
00390 #define  MAXXLAT 20
00391 #define  MAXXLATTIME 3
00392 
00393 #define MAX_SYSSTATES 10
00394 
00395 struct rpt_xlat
00396 {
00397 char  funccharseq[MAXXLAT];
00398 char  endcharseq[MAXXLAT];
00399 char  passchars[MAXXLAT];
00400 int   funcindex;
00401 int   endindex;
00402 time_t   lastone;
00403 } ;
00404 
00405 static time_t  starttime = 0;
00406 
00407 static  pthread_t rpt_master_thread;
00408 
00409 struct rpt;
00410 
00411 struct rpt_link
00412 {
00413    struct rpt_link *next;
00414    struct rpt_link *prev;
00415    char  mode;       /* 1 if in tx mode */
00416    char  isremote;
00417    char  phonemode;
00418    char  name[MAXNODESTR]; /* identifier (routing) string */
00419    char  lasttx;
00420    char  lastrx;
00421    char  lastrx1;
00422    char  connected;
00423    char  hasconnected;
00424    char  perma;
00425    char  thisconnected;
00426    char  outbound;
00427    char  disced;
00428    char  killme;
00429    long  elaptime;
00430    long  disctime;
00431    long  retrytimer;
00432    long  retxtimer;
00433    long  rerxtimer;
00434    int   retries;
00435    int   max_retries;
00436    int   reconnects;
00437    long long connecttime;
00438    struct ast_channel *chan;  
00439    struct ast_channel *pchan; 
00440    char  linklist[MAXLINKLIST];
00441    time_t   linklistreceived;
00442    long  linklisttimer;
00443    int   dtmfed;
00444    int linkunkeytocttimer;
00445    struct   ast_frame *lastf1,*lastf2;
00446    struct   rpt_chan_stat chan_stat[NRPTSTAT];
00447 } ;
00448 
00449 struct rpt_lstat
00450 {
00451    struct   rpt_lstat *next;
00452    struct   rpt_lstat *prev;
00453    char  peer[MAXPEERSTR];
00454    char  name[MAXNODESTR];
00455    char  mode;
00456    char  outbound;
00457    char  reconnects;
00458    char  thisconnected;
00459    long long   connecttime;
00460    struct   rpt_chan_stat chan_stat[NRPTSTAT];
00461 } ;
00462 
00463 struct rpt_tele
00464 {
00465    struct rpt_tele *next;
00466    struct rpt_tele *prev;
00467    struct rpt *rpt;
00468    struct ast_channel *chan;
00469    int   mode;
00470    struct rpt_link mylink;
00471    char param[TELEPARAMSIZE];
00472    int   submode;
00473    pthread_t threadid;
00474 } ;
00475 
00476 struct function_table_tag
00477 {
00478    char action[ACTIONSIZE];
00479    int (*function)(struct rpt *myrpt, char *param, char *digitbuf, 
00480       int command_source, struct rpt_link *mylink);
00481 } ;
00482 
00483 /* Used to store the morse code patterns */
00484 
00485 struct morse_bits
00486 {       
00487    int len;
00488    int ddcomb;
00489 } ;
00490 
00491 struct telem_defaults
00492 {
00493    char name[20];
00494    char value[80];
00495 } ;
00496 
00497 
00498 struct sysstate
00499 {
00500    char txdisable;
00501    char totdisable;
00502    char linkfundisable;
00503    char autopatchdisable;
00504    char schedulerdisable;
00505    char userfundisable;
00506    char alternatetail;
00507 };
00508 
00509 static struct rpt
00510 {
00511    ast_mutex_t lock;
00512    ast_mutex_t remlock;
00513    struct ast_config *cfg;
00514    char reload;
00515 
00516    char *name;
00517    char *rxchanname;
00518    char *txchanname;
00519    char *remote;
00520    struct   rpt_chan_stat chan_stat[NRPTSTAT];
00521    unsigned int scram;
00522 
00523    struct {
00524       char *ourcontext;
00525       char *ourcallerid;
00526       char *acctcode;
00527       char *ident;
00528       char *tonezone;
00529       char simple;
00530       char *functions;
00531       char *link_functions;
00532       char *phone_functions;
00533       char *dphone_functions;
00534       char *nodes;
00535       char *extnodes;
00536       char *extnodefile;
00537       int hangtime;
00538       int althangtime;
00539       int totime;
00540       int idtime;
00541       int tailmessagetime;
00542       int tailsquashedtime;
00543       int duplex;
00544       int politeid;
00545       char *tailmessages[500];
00546       int tailmessagemax;
00547       char  *memory;
00548       char  *macro;
00549       char  *startupmacro;
00550       int iobase;
00551       char *ioport;
00552       char funcchar;
00553       char endchar;
00554       char nobusyout;
00555       char notelemtx;
00556       char propagate_dtmf;
00557       char propagate_phonedtmf;
00558       char linktolink;
00559       unsigned char civaddr;
00560       struct rpt_xlat inxlat;
00561       struct rpt_xlat outxlat;
00562       char *archivedir;
00563       int authlevel;
00564       char *csstanzaname;
00565       char *skedstanzaname;
00566       char *txlimitsstanzaname;
00567       long monminblocks;
00568       int remoteinacttimeout;
00569       int remotetimeout;
00570       int remotetimeoutwarning;
00571       int remotetimeoutwarningfreq;
00572       int sysstate_cur;
00573       struct sysstate s[MAX_SYSSTATES];
00574    } p;
00575    struct rpt_link links;
00576    int unkeytocttimer;
00577    char keyed;
00578    char exttx;
00579    char localtx;
00580    char remoterx;
00581    char remotetx;
00582    char remoteon;
00583    char remtxfreqok;
00584    char tounkeyed;
00585    char tonotify;
00586    char dtmfbuf[MAXDTMF];
00587    char macrobuf[MAXMACRO];
00588    char rem_dtmfbuf[MAXDTMF];
00589    char lastdtmfcommand[MAXDTMF];
00590    char cmdnode[50];
00591    struct ast_channel *rxchannel,*txchannel, *monchannel;
00592    struct ast_channel *pchannel,*txpchannel, *zaprxchannel, *zaptxchannel;
00593    struct ast_frame *lastf1,*lastf2;
00594    struct rpt_tele tele;
00595    struct timeval lasttv,curtv;
00596    pthread_t rpt_call_thread,rpt_thread;
00597    time_t dtmf_time,rem_dtmf_time,dtmf_time_rem;
00598    int tailtimer,totimer,idtimer,txconf,conf,callmode,cidx,scantimer,tmsgtimer,skedtimer;
00599    int mustid,tailid;
00600    int tailevent;
00601    int telemrefcount;
00602    int dtmfidx,rem_dtmfidx;
00603    int dailytxtime,dailykerchunks,totalkerchunks,dailykeyups,totalkeyups,timeouts;
00604    int totalexecdcommands, dailyexecdcommands;
00605    long  retxtimer;
00606    long  rerxtimer;
00607    long long totaltxtime;
00608    char mydtmf;
00609    char exten[AST_MAX_EXTENSION];
00610    char freq[MAXREMSTR],rxpl[MAXREMSTR],txpl[MAXREMSTR];
00611    char offset;
00612    char powerlevel;
00613    char txplon;
00614    char rxplon;
00615    char remmode;
00616    char tunerequest;
00617    char hfscanmode;
00618    int hfscanstatus;
00619    char hfscanstop;
00620    char lastlinknode[MAXNODESTR];
00621    char savednodes[MAXNODESTR];
00622    int stopgen;
00623    char patchfarenddisconnect;
00624    char patchnoct;
00625    char patchquiet;
00626    char patchcontext[MAXPATCHCONTEXT];
00627    int patchdialtime;
00628    int macro_longest;
00629    int phone_longestfunc;
00630    int dphone_longestfunc;
00631    int link_longestfunc;
00632    int longestfunc;
00633    int longestnode;
00634    int threadrestarts;     
00635    int tailmessagen;
00636    time_t disgorgetime;
00637    time_t lastthreadrestarttime;
00638    long  macrotimer;
00639    char  lastnodewhichkeyedusup[MAXNODESTR];
00640    int   dtmf_local_timer;
00641    char  dtmf_local_str[100];
00642    struct ast_filestream *monstream;
00643    char  loginuser[50];
00644    char  loginlevel[10];
00645    long  authtelltimer;
00646    long  authtimer;
00647    int iofd;
00648    time_t start_time,last_activity_time;
00649 #ifdef   __RPT_NOTCH
00650    struct rptfilter
00651    {
00652       char  desc[100];
00653       float x0;
00654       float x1;
00655       float x2;
00656       float y0;
00657       float y1;
00658       float y2;
00659       float gain;
00660       float const0;
00661       float const1;
00662       float const2;
00663    } filters[MAXFILTERS];
00664 #endif
00665 #ifdef   _MDC_DECODE_H_
00666    mdc_decoder_t *mdc;
00667    unsigned short lastunit;
00668 #endif
00669 } rpt_vars[MAXRPTS]; 
00670 
00671 struct nodelog {
00672 struct nodelog *next;
00673 struct nodelog *prev;
00674 time_t   timestamp;
00675 char archivedir[MAXNODESTR];
00676 char str[MAXNODESTR * 2];
00677 } nodelog;
00678 
00679 static int service_scan(struct rpt *myrpt);
00680 static int set_mode_ft897(struct rpt *myrpt, char newmode);
00681 static int set_mode_ic706(struct rpt *myrpt, char newmode);
00682 static int simple_command_ft897(struct rpt *myrpt, char command);
00683 static int setrem(struct rpt *myrpt);
00684 
00685 AST_MUTEX_DEFINE_STATIC(nodeloglock);
00686 
00687 AST_MUTEX_DEFINE_STATIC(nodelookuplock);
00688 
00689 #ifdef   APP_RPT_LOCK_DEBUG
00690 
00691 #warning COMPILING WITH LOCK-DEBUGGING ENABLED!!
00692 
00693 #define  MAXLOCKTHREAD 100
00694 
00695 #define rpt_mutex_lock(x) _rpt_mutex_lock(x,myrpt,__LINE__)
00696 #define rpt_mutex_unlock(x) _rpt_mutex_unlock(x,myrpt,__LINE__)
00697 
00698 struct lockthread
00699 {
00700    pthread_t id;
00701    int lockcount;
00702    int lastlock;
00703    int lastunlock;
00704 } lockthreads[MAXLOCKTHREAD];
00705 
00706 
00707 struct by_lightning
00708 {
00709    int line;
00710    struct timeval tv;
00711    struct rpt *rpt;
00712    struct lockthread lockthread;
00713 } lock_ring[32];
00714 
00715 int lock_ring_index = 0;
00716 
00717 AST_MUTEX_DEFINE_STATIC(locklock);
00718 
00719 static struct lockthread *get_lockthread(pthread_t id)
00720 {
00721 int   i;
00722 
00723    for(i = 0; i < MAXLOCKTHREAD; i++)
00724    {
00725       if (lockthreads[i].id == id) return(&lockthreads[i]);
00726    }
00727    return(NULL);
00728 }
00729 
00730 static struct lockthread *put_lockthread(pthread_t id)
00731 {
00732 int   i;
00733 
00734    for(i = 0; i < MAXLOCKTHREAD; i++)
00735    {
00736       if (lockthreads[i].id == id)
00737          return(&lockthreads[i]);
00738    }
00739    for(i = 0; i < MAXLOCKTHREAD; i++)
00740    {
00741       if (!lockthreads[i].id)
00742       {
00743          lockthreads[i].lockcount = 0;
00744          lockthreads[i].lastlock = 0;
00745          lockthreads[i].lastunlock = 0;
00746          lockthreads[i].id = id;
00747          return(&lockthreads[i]);
00748       }
00749    }
00750    return(NULL);
00751 }
00752 
00753 
00754 static void rpt_mutex_spew(void)
00755 {
00756    struct by_lightning lock_ring_copy[32];
00757    int lock_ring_index_copy;
00758    int i,j;
00759    long long diff;
00760    char a[100];
00761    struct timeval lasttv;
00762 
00763    ast_mutex_lock(&locklock);
00764    memcpy(&lock_ring_copy, &lock_ring, sizeof(lock_ring_copy));
00765    lock_ring_index_copy = lock_ring_index;
00766    ast_mutex_unlock(&locklock);
00767 
00768    lasttv.tv_sec = lasttv.tv_usec = 0;
00769    for(i = 0 ; i < 32 ; i++)
00770    {
00771       j = (i + lock_ring_index_copy) % 32;
00772       strftime(a,sizeof(a) - 1,"%m/%d/%Y %H:%M:%S",
00773          localtime(&lock_ring_copy[j].tv.tv_sec));
00774       diff = 0;
00775       if(lasttv.tv_sec)
00776       {
00777          diff = (lock_ring_copy[j].tv.tv_sec - lasttv.tv_sec)
00778             * 1000000;
00779          diff += (lock_ring_copy[j].tv.tv_usec - lasttv.tv_usec);
00780       }
00781       lasttv.tv_sec = lock_ring_copy[j].tv.tv_sec;
00782       lasttv.tv_usec = lock_ring_copy[j].tv.tv_usec;
00783       if (!lock_ring_copy[j].tv.tv_sec) continue;
00784       if (lock_ring_copy[j].line < 0)
00785       {
00786          ast_log(LOG_NOTICE,"LOCKDEBUG [#%d] UNLOCK app_rpt.c:%d node %s pid %x diff %lld us at %s.%06d\n",
00787             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);
00788       }
00789       else
00790       {
00791          ast_log(LOG_NOTICE,"LOCKDEBUG [#%d] LOCK app_rpt.c:%d node %s pid %x diff %lld us at %s.%06d\n",
00792             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);
00793       }
00794    }
00795 }
00796 
00797 
00798 static void _rpt_mutex_lock(ast_mutex_t *lockp, struct rpt *myrpt, int line)
00799 {
00800 struct lockthread *t;
00801 pthread_t id;
00802 
00803    id = pthread_self();
00804    ast_mutex_lock(&locklock);
00805    t = put_lockthread(id);
00806    if (!t)
00807    {
00808       ast_mutex_unlock(&locklock);
00809       return;
00810    }
00811    if (t->lockcount)
00812    {
00813       int lastline = t->lastlock;
00814       ast_mutex_unlock(&locklock);
00815       ast_log(LOG_NOTICE,"rpt_mutex_lock: Double lock request line %d node %s pid %x, last lock was line %d\n",line,myrpt->name,(int) t->id,lastline);
00816       rpt_mutex_spew();
00817       return;
00818    }