00001
00002
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 #define RECONNECT_KLUDGE
00102
00103
00104
00105 #define MAXDTMF 32
00106 #define DTMF_TIMEOUT 3
00107
00108 #define DISC_TIME 10000
00109 #define MAX_RETRIES 5
00110
00111 #define REDUNDANT_TX_TIME 2000
00112
00113 #define RETRY_TIMER_MS 5000
00114
00115 #define MAXREMSTR 15
00116
00117 #define NODES "nodes"
00118 #define MEMORY "memory"
00119 #define FUNCTIONS "functions"
00120 #define TELEMETRY "telemetry"
00121 #define MORSE "morse"
00122 #define FUNCCHAR '*'
00123 #define ENDCHAR '#'
00124
00125 #define DEFAULT_IOBASE 0x378
00126
00127 #define MAXCONNECTTIME 5000
00128
00129 #define MAXNODESTR 300
00130
00131 #define ACTIONSIZE 32
00132
00133 #define TELEPARAMSIZE 256
00134
00135 #define REM_SCANTIME 100
00136
00137
00138 enum {REM_OFF,REM_MONITOR,REM_TX};
00139
00140 enum{ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO,
00141 CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME,
00142 STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH};
00143
00144 enum {REM_SIMPLEX,REM_MINUS,REM_PLUS};
00145
00146 enum {REM_LOWPWR,REM_MEDPWR,REM_HIPWR};
00147
00148 enum {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_DOKEY};
00149
00150 enum {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE};
00151
00152 enum {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM};
00153
00154 enum {REM_MODE_FM,REM_MODE_USB,REM_MODE_LSB,REM_MODE_AM};
00155
00156 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};
00157
00158 #include "asterisk.h"
00159
00160 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 53045 $")
00161
00162 #include <signal.h>
00163 #include <stdio.h>
00164 #include <unistd.h>
00165 #include <string.h>
00166 #include <stdlib.h>
00167 #include <search.h>
00168 #include <sys/types.h>
00169 #include <sys/stat.h>
00170 #include <errno.h>
00171 #include <dirent.h>
00172 #include <ctype.h>
00173 #include <sys/stat.h>
00174 #include <sys/time.h>
00175 #include <sys/file.h>
00176 #include <sys/ioctl.h>
00177 #include <sys/io.h>
00178 #include <math.h>
00179 #include <tonezone.h>
00180 #include <linux/zaptel.h>
00181 #include <netinet/in.h>
00182 #include <arpa/inet.h>
00183
00184 #include "asterisk/utils.h"
00185 #include "asterisk/lock.h"
00186 #include "asterisk/file.h"
00187 #include "asterisk/logger.h"
00188 #include "asterisk/channel.h"
00189 #include "asterisk/callerid.h"
00190 #include "asterisk/pbx.h"
00191 #include "asterisk/module.h"
00192 #include "asterisk/translate.h"
00193 #include "asterisk/features.h"
00194 #include "asterisk/options.h"
00195 #include "asterisk/cli.h"
00196 #include "asterisk/config.h"
00197 #include "asterisk/say.h"
00198 #include "asterisk/localtime.h"
00199
00200 static char *tdesc = "Radio Repeater / Remote Base version 0.37 11/03/2005";
00201
00202 static char *app = "Rpt";
00203
00204 static char *synopsis = "Radio Repeater/Remote Base Control System";
00205
00206 static char *descrip =
00207 " Rpt(nodename[|options]): Radio Remote Link or Remote Base Link Endpoint Process.\n"
00208 "\n"
00209 " Not specifying an option puts it in normal endpoint mode (where source\n"
00210 " IP and nodename are verified).\n"
00211 "\n"
00212 " Options are as follows:\n"
00213 "\n"
00214 " X - Normal endpoint mode WITHOUT security check. Only specify\n"
00215 " this if you have checked security already (like with an IAX2\n"
00216 " user/password or something).\n"
00217 "\n"
00218 " Rannounce-string[|timeout[|timeout-destination]] - Amateur Radio\n"
00219 " Reverse Autopatch. Caller is put on hold, and announcement (as\n"
00220 " specified by the 'announce-string') is played on radio system.\n"
00221 " Users of radio system can access autopatch, dial specified\n"
00222 " code, and pick up call. Announce-string is list of names of\n"
00223 " recordings, or \"PARKED\" to substitute code for un-parking,\n"
00224 " or \"NODE\" to substitute node number.\n"
00225 "\n"
00226 " P - Phone Control mode. This allows a regular phone user to have\n"
00227 " full control and audio access to the radio system. For the\n"
00228 " user to have DTMF control, the 'phone_functions' parameter\n"
00229 " must be specified for the node in 'rpt.conf'. An additional\n"
00230 " function (cop,6) must be listed so that PTT control is available.\n"
00231 "\n"
00232 " D - Dumb Phone Control mode. This allows a regular phone user to\n"
00233 " have full control and audio access to the radio system. In this\n"
00234 " mode, the PTT is activated for the entire length of the call.\n"
00235 " For the user to have DTMF control (not generally recomended in\n"
00236 " this mode), the 'dphone_functions' parameter must be specified\n"
00237 " for the node in 'rpt.conf'. Otherwise no DTMF control will be\n"
00238 " available to the phone user.\n"
00239 "\n";
00240
00241 static int debug = 0;
00242 static int nrpts = 0;
00243
00244 char *discstr = "!!DISCONNECT!!";
00245 static char *remote_rig_ft897="ft897";
00246 static char *remote_rig_rbi="rbi";
00247
00248 struct ast_config *cfg;
00249
00250 STANDARD_LOCAL_USER;
00251 LOCAL_USER_DECL;
00252
00253 #define MSWAIT 200
00254 #define HANGTIME 5000
00255 #define TOTIME 180000
00256 #define IDTIME 300000
00257 #define MAXRPTS 20
00258 #define POLITEID 30000
00259 #define FUNCTDELAY 1500
00260
00261 static pthread_t rpt_master_thread;
00262
00263 struct rpt;
00264
00265 struct rpt_link
00266 {
00267 struct rpt_link *next;
00268 struct rpt_link *prev;
00269 char mode;
00270 char isremote;
00271 char phonemode;
00272 char name[MAXNODESTR];
00273 char lasttx;
00274 char lastrx;
00275 char connected;
00276 char hasconnected;
00277 char outbound;
00278 char disced;
00279 char killme;
00280 long elaptime;
00281 long disctime;
00282 long retrytimer;
00283 long retxtimer;
00284 int retries;
00285 struct ast_channel *chan;
00286 struct ast_channel *pchan;
00287 } ;
00288
00289 struct rpt_tele
00290 {
00291 struct rpt_tele *next;
00292 struct rpt_tele *prev;
00293 struct rpt *rpt;
00294 struct ast_channel *chan;
00295 int mode;
00296 struct rpt_link mylink;
00297 char param[TELEPARAMSIZE];
00298 pthread_t threadid;
00299 } ;
00300
00301 struct function_table_tag
00302 {
00303 char action[ACTIONSIZE];
00304 int (*function)(struct rpt *myrpt, char *param, char *digitbuf,
00305 int command_source, struct rpt_link *mylink);
00306 } ;
00307
00308
00309
00310 struct morse_bits
00311 {
00312 int len;
00313 int ddcomb;
00314 } ;
00315
00316 struct telem_defaults
00317 {
00318 char name[20];
00319 char value[80];
00320 } ;
00321
00322
00323 static struct rpt
00324 {
00325 char *name;
00326 ast_mutex_t lock;
00327 char *rxchanname;
00328 char *txchanname;
00329 char *ourcontext;
00330 char *ourcallerid;
00331 char *acctcode;
00332 char *ident;
00333 char *tonezone;
00334 char *functions;
00335 char *link_functions;
00336 char *phone_functions;
00337 char *dphone_functions;
00338 char *nodes;
00339 struct rpt_link links;
00340 int hangtime;
00341 int totime;
00342 int idtime;
00343 int unkeytocttimer;
00344 char keyed;
00345 char exttx;
00346 char localtx;
00347 char remoterx;
00348 char remotetx;
00349 char remoteon;
00350 char simple;
00351 char *remote;
00352 char tounkeyed;
00353 char tonotify;
00354 char enable;
00355 char dtmfbuf[MAXDTMF];
00356 char rem_dtmfbuf[MAXDTMF];
00357 char cmdnode[50];
00358 struct ast_channel *rxchannel,*txchannel;
00359 struct ast_channel *pchannel,*txpchannel, *remchannel;
00360 struct rpt_tele tele;
00361 pthread_t rpt_call_thread,rpt_thread;
00362 time_t rem_dtmf_time,dtmf_time_rem;
00363 int tailtimer,totimer,idtimer,txconf,conf,callmode,cidx,scantimer;
00364 int mustid;
00365 int politeid;
00366 int dtmfidx,rem_dtmfidx;
00367 long retxtimer;
00368 char mydtmf;
00369 int iobase;
00370 char exten[AST_MAX_EXTENSION];
00371 char freq[MAXREMSTR],rxpl[MAXREMSTR],txpl[MAXREMSTR];
00372 char offset;
00373 char powerlevel;
00374 char txplon;
00375 char rxplon;
00376 char remmode;
00377 char tunerequest;
00378 char hfscanmode;
00379 int hfscanstatus;
00380 char lastlinknode[MAXNODESTR];
00381 char funcchar;
00382 char endchar;
00383 char stopgen;
00384 int phone_longestfunc;
00385 int dphone_longestfunc;
00386 int link_longestfunc;
00387 int longestfunc;
00388 int longestnode;
00389 int threadrestarts;
00390 time_t disgorgetime;
00391 time_t lastthreadrestarttime;
00392 char nobusyout;
00393 } rpt_vars[MAXRPTS];
00394
00395
00396
00397
00398
00399
00400 static int rpt_do_debug(int fd, int argc, char *argv[]);
00401
00402 static char debug_usage[] =
00403 "Usage: rpt debug level {0-7}\n"
00404 " Enables debug messages in app_rpt\n";
00405
00406 static struct ast_cli_entry cli_debug =
00407 { { "rpt", "debug", "level" }, rpt_do_debug, "Enable app_rpt debugging", debug_usage };
00408
00409
00410
00411
00412
00413
00414
00415
00416 static struct telem_defaults tele_defs[] = {
00417 {"ct1","|t(350,0,100,3072)(500,0,100,3072)(660,0,100,3072)"},
00418 {"ct2","|t(660,880,150,3072)"},
00419 {"ct3","|t(440,0,150,3072)"},
00420 {"ct4","|t(550,0,150,3072)"},
00421 {"ct5","|t(660,0,150,3072)"},
00422 {"ct6","|t(880,0,150,3072)"},
00423 {"ct7","|t(660,440,150,3072)"},
00424 {"ct8","|t(700,1100,150,3072)"},
00425 {"remotemon","|t(1600,0,75,2048)"},
00426 {"remotetx","|t(2000,0,75,2048)(0,0,75,0)(1600,0,75,2048)"},
00427 {"cmdmode","|t(900,904,200,2048)"},
00428 {"functcomplete","|t(1000,0,100,2048)(0,0,100,0)(1000,0,100,2048)"}
00429 } ;
00430
00431
00432
00433
00434
00435 static int setrbi(struct rpt *myrpt);
00436
00437
00438
00439
00440
00441
00442
00443 static int function_ilink(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
00444 static int function_autopatchup(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
00445 static int function_autopatchdn(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
00446 static int function_status(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
00447 static int function_cop(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
00448 static int function_remote(struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink);
00449
00450
00451
00452
00453 static struct function_table_tag function_table[] = {
00454 {"cop", function_cop},
00455 {"autopatchup", function_autopatchup},
00456 {"autopatchdn", function_autopatchdn},
00457 {"ilink", function_ilink},
00458 {"status", function_status},
00459 {"remote", function_remote}
00460 } ;
00461
00462 static int myatoi(char *str)
00463 {
00464 int ret;
00465
00466 if (str == NULL) return -1;
00467
00468 if (sscanf(str,"%i",&ret) != 1) return -1;
00469 return ret;
00470 }
00471
00472
00473
00474
00475
00476 static int rpt_do_debug(int fd, int argc, char *argv[])
00477 {
00478 int newlevel;
00479
00480 if (argc != 4)
00481 return RESULT_SHOWUSAGE;
00482 newlevel = myatoi(argv[3]);
00483 if((newlevel < 0) || (newlevel > 7))
00484 return RESULT_SHOWUSAGE;
00485 if(newlevel)
00486 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
00487 else
00488 ast_cli(fd, "app_rpt Debugging disabled\n");
00489
00490 debug = newlevel;
00491 return RESULT_SUCCESS;
00492 }
00493
00494
00495
00496 static int play_tone_pair(struct ast_channel *chan, int f1, int f2, int duration, int amplitude)
00497 {
00498 int res;
00499
00500 if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude)))
00501 return res;
00502
00503 while(chan->generatordata) {
00504 if (ast_safe_sleep(chan,1)) return -1;
00505 }
00506
00507 return 0;
00508 }
00509
00510 static int play_tone(struct ast_channel *chan, int freq, int duration, int amplitude)
00511 {
00512 return play_tone_pair(chan, freq, 0, duration, amplitude);
00513 }
00514
00515 static int play_silence(struct ast_channel *chan, int duration)
00516 {
00517 return play_tone_pair(chan, 0, 0, duration, 0);
00518 }
00519
00520
00521 static int send_morse(struct ast_channel *chan, char *string, int speed, int freq, int amplitude)
00522 {
00523
00524 static struct morse_bits mbits[] = {
00525 {0, 0},
00526 {0, 0},
00527 {6, 18},
00528 {0, 0},
00529 {7, 72},
00530 {0, 0},
00531 {0, 0},
00532 {6, 30},
00533 {5, 13},
00534 {6, 29},
00535 {0, 0},
00536 {5, 10},
00537 {6, 51},
00538 {6, 33},
00539 {6, 42},
00540 {5, 9},
00541 {5, 31},
00542 {5, 30},
00543 {5, 28},
00544 {5, 24},
00545 {5, 16},
00546 {5, 0},
00547 {5, 1},
00548 {5, 3},
00549 {5, 7},
00550 {5, 15},
00551 {6, 7},
00552 {6, 21},
00553 {0, 0},
00554 {5, 33},
00555 {0, 0},
00556 {6, 12},
00557 {0, 0},
00558 {2, 2},
00559 {4, 1},
00560 {4, 5},
00561 {3, 1},
00562 {1, 0},
00563 {4, 4},
00564 {3, 3},
00565 {4, 0},
00566 {2, 0},
00567 {4, 14},
00568 {3, 5},
00569 {4, 2},
00570 {2, 3},
00571 {2, 1},
00572 {3, 7},
00573 {4, 6},
00574 {4, 11},
00575 {3, 2},
00576 {3, 0},
00577 {1, 1},
00578 {3, 4},
00579 {4, 8},
00580 {3, 6},
00581 {4, 9},
00582 {4, 13},
00583 {4, 3}
00584 };
00585
00586
00587 int dottime;
00588 int dashtime;
00589 int intralettertime;
00590 int interlettertime;
00591 int interwordtime;
00592 int len, ddcomb;
00593 int res;
00594 int c;
00595 int i;
00596 int flags;
00597
00598 res = 0;
00599
00600
00601
00602 dottime = 900/speed;
00603
00604
00605
00606 dashtime = 3 * dottime;
00607 intralettertime = dottime;
00608 interlettertime = dottime * 4 ;
00609 interwordtime = dottime * 7;
00610
00611 for(;(*string) && (!res); string++){
00612
00613 c = *string;
00614
00615
00616
00617 if((c >= 'a') && (c <= 'z'))
00618 c -= 0x20;
00619
00620
00621
00622 if(c > 'Z')
00623 continue;
00624
00625
00626
00627 if(c == ' '){
00628 if(!res)
00629 res = play_silence(chan, interwordtime);
00630 continue;
00631 }
00632
00633
00634
00635 c -= 0x20;
00636
00637
00638
00639 len = mbits[c].len;
00640 ddcomb = mbits[c].ddcomb;
00641
00642
00643
00644 for(; len ; len--){
00645 if(!res)
00646 res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude);
00647 if(!res)
00648 res = play_silence(chan, intralettertime);
00649 ddcomb >>= 1;
00650 }
00651
00652
00653
00654 if(!res)
00655 res = play_silence(chan, interlettertime - intralettertime);
00656 }
00657
00658
00659
00660 if (!res)
00661 res = ast_waitstream(chan, "");
00662 ast_stopstream(chan);
00663
00664
00665
00666
00667
00668 for(i = 0; i < 20 ; i++){
00669 flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT;
00670 res = ioctl(chan->fds[0], ZT_IOMUX, &flags);
00671 if(flags & ZT_IOMUX_WRITEEMPTY)
00672 break;
00673 if( ast_safe_sleep(chan, 50)){
00674 res = -1;
00675 break;
00676 }
00677 }
00678
00679
00680 return res;
00681 }
00682
00683 static int send_tone_telemetry(struct ast_channel *chan, char *tonestring)
00684 {
00685 char *stringp;
00686 char *tonesubset;
00687 int f1,f2;
00688 int duration;
00689 int amplitude;
00690 int res;
00691 int i;
00692 int flags;
00693
00694 res = 0;
00695
00696 stringp = ast_strdupa(tonestring);
00697
00698 for(;tonestring;){
00699 tonesubset = strsep(&stringp,")");
00700 if(!tonesubset)
00701 break;
00702 if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &litude) != 4)
00703 break;
00704 res = play_tone_pair(chan, f1, f2, duration, amplitude);
00705 if(res)
00706 break;
00707 }
00708 if(!res)
00709 res = play_tone_pair(chan, 0, 0, 100, 0);
00710
00711 if (!res)
00712 res = ast_waitstream(chan, "");
00713 ast_stopstream(chan);
00714
00715
00716
00717
00718
00719 for(i = 0; i < 20 ; i++){
00720 flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT;
00721 res = ioctl(chan->fds[0], ZT_IOMUX, &flags);
00722 if(flags & ZT_IOMUX_WRITEEMPTY)
00723 break;
00724 if( ast_safe_sleep(chan, 50)){
00725 res = -1;
00726 break;
00727 }
00728 }
00729
00730 return res;
00731
00732 }
00733
00734
00735 static int sayfile(struct ast_channel *mychannel,char *fname)
00736 {
00737 int res;
00738
00739 res = ast_streamfile(mychannel, fname, mychannel->language);
00740 if (!res)
00741 res = ast_waitstream(mychannel, "");
00742 else
00743 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
00744 ast_stopstream(mychannel);
00745 return res;
00746 }
00747
00748 static int saycharstr(struct ast_channel *mychannel,char *str)
00749 {
00750 int res;
00751
00752 res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
00753 if (!res)
00754 res = ast_waitstream(mychannel, "");
00755 else
00756 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
00757 ast_stopstream(mychannel);
00758 return res;
00759 }
00760
00761 static int saynum(struct ast_channel *mychannel, int num)
00762 {
00763 int res;
00764 res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL);
00765 if(!res)
00766 res = ast_waitstream(mychannel, "");
00767 else
00768 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
00769 ast_stopstream(mychannel);
00770 return res;
00771 }
00772
00773
00774
00775
00776 static int retrieve_astcfgint(char *category, char *name, int min, int max, int defl)
00777 {
00778 char *var;
00779 int ret;
00780
00781 var = ast_variable_retrieve(cfg, category, name);
00782 if(var){
00783 ret = myatoi(var);
00784 if(ret < min)
00785 ret = min;
00786 if(ret > max)
00787 ret = max;
00788 }
00789 else
00790 ret = defl;
00791 return ret;
00792 }
00793
00794 static int telem_any(struct ast_channel *chan, char *entry)
00795 {
00796 int res;
00797 char c;
00798
00799 static int morsespeed;
00800 static int morsefreq;
00801 static int morseampl;
00802 static int morseidfreq = 0;
00803 static int morseidampl;
00804 static char mcat[] = MORSE;
00805
00806 res = 0;
00807
00808 if(!morseidfreq){
00809 morsespeed = retrieve_astcfgint( mcat, "speed", 5, 20, 20);
00810 morsefreq = retrieve_astcfgint( mcat, "frequency", 300, 3000, 800);
00811 morseampl = retrieve_astcfgint( mcat, "amplitude", 200, 8192, 4096);
00812 morseidampl = retrieve_astcfgint( mcat, "idamplitude", 200, 8192, 2048);
00813 morseidfreq = retrieve_astcfgint( mcat, "idfrequency", 300, 3000, 330);
00814 }
00815
00816
00817
00818 if(entry[0] == '|'){
00819 c = entry[1];
00820 if((c >= 'a')&&(c <= 'z'))
00821 c -= 0x20;
00822
00823 switch(c){
00824 case 'I':
00825 res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl);
00826 break;
00827
00828 case 'M':
00829 res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl);
00830 break;
00831
00832 case 'T':
00833 res = send_tone_telemetry(chan, entry + 2);
00834 break;
00835 default:
00836 res = -1;
00837 }
00838 }
00839 else
00840 res = sayfile(chan, entry);
00841 return res;
00842 }
00843
00844
00845
00846
00847
00848
00849
00850 static int telem_lookup(struct ast_channel *chan, char *node, char *name)
00851 {
00852
00853 int res;
00854 int i;
00855 char *entry;
00856 char *telemetry;
00857 char *telemetry_save;
00858
00859 res = 0;
00860 telemetry_save = NULL;
00861 entry = NULL;
00862
00863
00864
00865
00866 telemetry = ast_variable_retrieve(cfg, node, TELEMETRY);
00867 if(telemetry){
00868 telemetry_save = ast_strdupa(telemetry);
00869 if(!telemetry_save){
00870 ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n");
00871 return res;
00872 }
00873 entry = ast_variable_retrieve(cfg, telemetry_save, name);
00874 }
00875
00876
00877
00878 if(!entry){
00879
00880 for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
00881 if(!strcasecmp(tele_defs[i].name, name))
00882 entry = tele_defs[i].value;
00883 }
00884 }
00885 if(entry)
00886 telem_any(chan, entry);
00887 else{
00888 ast_log(LOG_WARNING, "Telemetry name not found: %s\n", name);
00889 res = -1;
00890 }
00891 return res;
00892 }
00893
00894
00895
00896
00897
00898 static int get_wait_interval(struct rpt *myrpt, int type)
00899 {
00900 int interval;
00901 char *wait_times;
00902 char *wait_times_save = NULL;
00903
00904 wait_times = ast_variable_retrieve(cfg, myrpt->name, "wait_times");
00905
00906 if (wait_times) {
00907 wait_times_save = ast_strdupa(wait_times);
00908 if (!wait_times_save) {
00909 ast_log(LOG_WARNING, "Out of memory in wait_interval()\n");
00910 wait_times = NULL;
00911 }
00912 }
00913
00914 switch (type) {
00915 case DLY_TELEM:
00916 if (wait_times)
00917 interval = retrieve_astcfgint(wait_times_save, "telemwait", 500, 5000, 1000);
00918 else
00919 interval = 1000;
00920 break;
00921
00922 case DLY_ID:
00923 if (wait_times)
00924 interval = retrieve_astcfgint(wait_times_save, "idwait", 250, 5000, 500);
00925 else
00926 interval = 500;
00927 break;
00928
00929 case DLY_UNKEY:
00930 if (wait_times)
00931 interval = retrieve_astcfgint(wait_times_save, "unkeywait", 500, 5000, 1000);
00932 else
00933 interval = 1000;
00934 break;
00935
00936 case DLY_CALLTERM:
00937 if (wait_times)
00938 interval = retrieve_astcfgint(wait_times_save, "calltermwait", 500, 5000, 1500);
00939 else
00940 interval = 1500;
00941 break;
00942
00943 default:
00944 return 0;
00945 }
00946 return interval;
00947 }
00948
00949
00950
00951
00952
00953
00954
00955 static void wait_interval(struct rpt *myrpt, int type, struct ast_channel *chan)
00956 {
00957 int interval;
00958 if((interval = get_wait_interval(myrpt, type)))
00959 ast_safe_sleep(chan,interval);
00960 return;
00961 }
00962
00963
00964 static void *rpt_tele_thread(void *this)
00965 {
00966 ZT_CONFINFO ci;
00967 int res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x;
00968 struct rpt_tele *mytele = (struct rpt_tele *)this;
00969 struct rpt_tele *tlist;
00970 struct rpt *myrpt;
00971 struct rpt_link *l,*m,linkbase;
00972 struct ast_channel *mychannel;
00973 int vmajor, vminor;
00974 char *p,*ct,*ct_copy,*ident, *nodename;
00975 time_t t;
00976 struct tm localtm;
00977
00978
00979
00980 myrpt = mytele->rpt;
00981
00982
00983 ast_mutex_lock(&myrpt->lock);
00984 nodename = ast_strdupa(myrpt->name);
00985 ident = ast_strdupa(myrpt->ident);
00986 ast_mutex_unlock(&myrpt->lock);
00987
00988
00989
00990 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
00991 if (!mychannel)
00992 {
00993 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
00994 ast_mutex_lock(&myrpt->lock);
00995 remque((struct qelem *)mytele);
00996 ast_mutex_unlock(&myrpt->lock);
00997 free(mytele);
00998 pthread_exit(NULL);
00999 }
01000 ast_mutex_lock(&myrpt->lock);
01001 mytele->chan = mychannel;
01002 ast_mutex_unlock(&myrpt->lock);
01003
01004
01005 ci.chan = 0;
01006
01007
01008 ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY)) ?
01009 myrpt->txconf : myrpt->conf);
01010 ci.confmode = ZT_CONF_CONFANN;
01011
01012 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
01013 {
01014 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
01015 ast_mutex_lock(&myrpt->lock);
01016 remque((struct qelem *)mytele);
01017 ast_mutex_unlock(&myrpt->lock);
01018 free(mytele);
01019 ast_hangup(mychannel);
01020 pthread_exit(NULL);
01021 }
01022 ast_stopstream(mychannel);
01023 switch(mytele->