00001
00002 #define OLDKEY
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
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
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
00305 int ast_playtones_start(struct ast_channel *chan, int vol, const char* tonelist, int interruptible);
00306
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;
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;
00416 char isremote;
00417 char phonemode;
00418 char name[MAXNODESTR];
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
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 }