#include "asterisk.h"#include <signal.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <search.h>#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#include <dirent.h>#include <ctype.h>#include <sys/time.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/io.h>#include <math.h>#include <tonezone.h>#include <linux/zaptel.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"

Go to the source code of this file.
Data Structures | |
| struct | function_table_tag |
| struct | morse_bits |
| struct | rpt |
| struct | rpt_link |
| struct | rpt_tele |
| struct | telem_defaults |
Defines | |
| #define | ACTIONSIZE 32 |
| #define | DEFAULT_IOBASE 0x378 |
| #define | DISC_TIME 10000 |
| #define | DTMF_TIMEOUT 3 |
| #define | ENDCHAR '#' |
| #define | FUNCCHAR '*' |
| #define | FUNCTDELAY 1500 |
| #define | FUNCTIONS "functions" |
| #define | HANGTIME 5000 |
| #define | IDTIME 300000 |
| #define | MAX_RETRIES 5 |
| #define | MAXCONNECTTIME 5000 |
| #define | MAXDTMF 32 |
| #define | MAXNODESTR 300 |
| #define | MAXREMSTR 15 |
| #define | MAXRPTS 20 |
| #define | MEMORY "memory" |
| #define | MORSE "morse" |
| #define | MSWAIT 200 |
| #define | NODES "nodes" |
| #define | POLITEID 30000 |
| #define | RECONNECT_KLUDGE |
| #define | REDUNDANT_TX_TIME 2000 |
| #define | REM_SCANTIME 100 |
| #define | RETRY_TIMER_MS 5000 |
| #define | TELEMETRY "telemetry" |
| #define | TELEPARAMSIZE 256 |
| #define | TOTIME 180000 |
Enumerations | |
| enum | { REM_OFF, REM_MONITOR, REM_TX } |
| enum | { ID, PROC, TERM, COMPLETE, UNKEY, REMDISC, REMALREADY, REMNOTFOUND, REMGO, CONNECTED, CONNFAIL, STATUS, TIMEOUT, ID1, STATS_TIME, STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH } |
| 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_DOKEY } |
| enum | { SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE } |
| enum | { DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM } |
| enum | { REM_MODE_FM, REM_MODE_USB, REM_MODE_LSB, REM_MODE_AM } |
| enum | { HF_SCAN_OFF, HF_SCAN_DOWN_SLOW, HF_SCAN_DOWN_QUICK, HF_SCAN_DOWN_FAST, HF_SCAN_UP_SLOW, HF_SCAN_UP_QUICK, HF_SCAN_UP_FAST } |
Functions | |
| static int | attempt_reconnect (struct rpt *myrpt, struct rpt_link *l) |
| static int | check_freq (struct rpt *myrpt, int m, int d, int *defmode) |
| static int | check_freq_ft897 (int m, int d, int *defmode) |
| static int | check_freq_rbi (int m, int d, int *defmode) |
| static int | closerem (struct rpt *myrpt) |
| static int | closerem_ft897 (struct rpt *myrpt) |
| static int | collect_function_digits (struct rpt *myrpt, char *digits, int command_source, struct rpt_link *mylink) |
| char * | description (void) |
| Provides a description of the module. | |
| static int | function_autopatchdn (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
| static int | function_autopatchup (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
| static int | function_cop (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
| static int | function_ilink (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
| static int | function_remote (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
| static int | function_status (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
| static int | get_wait_interval (struct rpt *myrpt, int type) |
| static void | handle_link_data (struct rpt *myrpt, struct rpt_link *mylink, char *str) |
| static void | handle_link_phone_dtmf (struct rpt *myrpt, struct rpt_link *mylink, char c) |
| static int | handle_remote_data (struct rpt *myrpt, char *str) |
| static int | handle_remote_dtmf_digit (struct rpt *myrpt, char c, char *keyed, int phonemode) |
| static int | handle_remote_phone_dtmf (struct rpt *myrpt, char c, char *keyed, int phonemode) |
| char * | key () |
| Returns the ASTERISK_GPL_KEY. | |
| int | load_module (void) |
| Initialize the module. | |
| static int | multimode_bump_freq (struct rpt *myrpt, int interval) |
| static int | multimode_bump_freq_ft897 (struct rpt *myrpt, int interval) |
| static int | multimode_capable (struct rpt *myrpt) |
| static int | myatoi (char *str) |
| static int | play_silence (struct ast_channel *chan, int duration) |
| static int | play_tone (struct ast_channel *chan, int freq, int duration, int amplitude) |
| static int | play_tone_pair (struct ast_channel *chan, int f1, int f2, int duration, int amplitude) |
| static int | rbi_mhztoband (char *str) |
| static void | rbi_out (struct rpt *myrpt, unsigned char *data) |
| static void | rbi_out_parallel (struct rpt *myrpt, unsigned char *data) |
| static int | rbi_pltocode (char *str) |
| static int | retrieve_astcfgint (char *category, char *name, int min, int max, int defl) |
| static int | rmt_saycharstr (struct rpt *myrpt, struct ast_channel *chan, int delay, char *charstr) |
| static int | rmt_sayfile (struct rpt *myrpt, struct ast_channel *chan, int delay, char *filename) |
| static int | rmt_telem_finish (struct rpt *myrpt, struct ast_channel *chan) |
| static int | rmt_telem_start (struct rpt *myrpt, struct ast_channel *chan, int delay) |
| static void * | rpt (void *this) |
| static void * | rpt_call (void *this) |
| static int | rpt_do_debug (int fd, int argc, char *argv[]) |
| static int | rpt_exec (struct ast_channel *chan, void *data) |
| static void * | rpt_master (void *ignore) |
| static void * | rpt_tele_thread (void *this) |
| static void | rpt_telemetry (struct rpt *myrpt, int mode, void *data) |
| static int | saycharstr (struct ast_channel *mychannel, char *str) |
| static int | sayfile (struct ast_channel *mychannel, char *fname) |
| static int | saynum (struct ast_channel *mychannel, int num) |
| static void | send_link_dtmf (struct rpt *myrpt, char c) |
| static int | send_morse (struct ast_channel *chan, char *string, int speed, int freq, int amplitude) |
| static int | send_tone_telemetry (struct ast_channel *chan, char *tonestring) |
| static int | serial_remote_io (struct rpt *myrpt, char *txbuf, int txbytes, char *rxbuf, int rxmaxbytes, int asciiflag) |
| static int | service_scan (struct rpt *myrpt) |
| static int | set_ctcss_freq_ft897 (struct rpt *myrpt, char *txtone, char *rxtone) |
| static int | set_ctcss_mode_ft897 (struct rpt *myrpt, char txplon, char rxplon) |
| static int | set_freq_ft897 (struct rpt *myrpt, char *newfreq) |
| static int | set_ft897 (struct rpt *myrpt) |
| static int | set_mode_ft897 (struct rpt *myrpt, char newmode) |
| static int | set_offset_ft897 (struct rpt *myrpt, char offset) |
| static int | setrbi (struct rpt *myrpt) |
| static int | setrem (struct rpt *myrpt) |
| static int | simple_command_ft897 (struct rpt *myrpt, char command) |
| static int | split_ctcss_freq (char *hertz, char *decimal, char *freq) |
| static int | split_freq (char *mhz, char *decimals, char *freq) |
| static void | stop_scan (struct rpt *myrpt, int flag) |
| static int | telem_any (struct ast_channel *chan, char *entry) |
| static int | telem_lookup (struct ast_channel *chan, char *node, char *name) |
| int | unload_module (void) |
| Cleanup all module structures, sockets, etc. | |
| int | usecount (void) |
| Provides a usecount. | |
| static void | wait_interval (struct rpt *myrpt, int type, struct ast_channel *chan) |
Variables | |
| static char * | app = "Rpt" |
| struct ast_config * | cfg |
| static struct ast_cli_entry | cli_debug |
| static int | debug = 0 |
| static char | debug_usage [] |
| static char * | descrip |
| char * | discstr = "!!DISCONNECT!!" |
| static struct function_table_tag | function_table [] |
| LOCAL_USER_DECL | |
| static int | nrpts = 0 |
| static char * | remote_rig_ft897 = "ft897" |
| static char * | remote_rig_rbi = "rbi" |
| static pthread_t | rpt_master_thread |
| static struct rpt | rpt_vars [MAXRPTS] |
| STANDARD_LOCAL_USER | |
| static char * | synopsis = "Radio Repeater/Remote Base Control System" |
| static char * | tdesc = "Radio Repeater / Remote Base version 0.37 11/03/2005" |
| static struct telem_defaults | tele_defs [] |
| #define DEFAULT_IOBASE 0x378 |
| #define DTMF_TIMEOUT 3 |
| #define ENDCHAR '#' |
| #define FUNCCHAR '*' |
| #define FUNCTIONS "functions" |
| #define HANGTIME 5000 |
| #define IDTIME 300000 |
| #define MAX_RETRIES 5 |
Definition at line 109 of file app_rpt.c.
Referenced by function_ilink(), handle_link_data(), rpt(), and rpt_exec().
| #define MAXDTMF 32 |
Definition at line 105 of file app_rpt.c.
Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and rpt().
| #define MAXNODESTR 300 |
| #define MAXREMSTR 15 |
Definition at line 115 of file app_rpt.c.
Referenced by function_remote(), multimode_bump_freq_ft897(), service_scan(), set_ctcss_freq_ft897(), set_freq_ft897(), setrbi(), split_ctcss_freq(), and split_freq().
| #define MEMORY "memory" |
| #define MORSE "morse" |
| #define MSWAIT 200 |
| #define NODES "nodes" |
| #define POLITEID 30000 |
| #define REDUNDANT_TX_TIME 2000 |
| #define REM_SCANTIME 100 |
| #define TELEMETRY "telemetry" |
| #define TELEPARAMSIZE 256 |
| #define TOTIME 180000 |
| anonymous enum |
| anonymous enum |
| ID | |
| PROC | |
| TERM | |
| COMPLETE | |
| UNKEY | |
| REMDISC | |
| REMALREADY | |
| REMNOTFOUND | |
| REMGO | |
| CONNECTED | |
| CONNFAIL | |
| STATUS | |
| TIMEOUT | |
| ID1 | |
| STATS_TIME | |
| STATS_VERSION | |
| IDTALKOVER | |
| ARB_ALPHA | |
| TEST_TONE | |
| REV_PATCH |
Definition at line 140 of file app_rpt.c.
00140 {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};
| anonymous enum |
| anonymous enum |
| anonymous enum |
Definition at line 148 of file app_rpt.c.
00148 {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_DOKEY};
| anonymous enum |
Definition at line 150 of file app_rpt.c.
00150 {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE};
| anonymous enum |
| anonymous enum |
Definition at line 154 of file app_rpt.c.
00154 {REM_MODE_FM,REM_MODE_USB,REM_MODE_LSB,REM_MODE_AM};
| anonymous 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 |
Definition at line 156 of file app_rpt.c.
00156 {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};
Definition at line 4468 of file app_rpt.c.
References ast_call(), AST_FORMAT_SLINEAR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_variable_retrieve(), ast_verbose(), free, rpt::links, rpt::lock, LOG_NOTICE, rpt::name, rpt_link::name, rpt_link::next, rpt::nodes, option_verbose, s, strdup, strsep(), and VERBOSE_PREFIX_3.
Referenced by rpt().
04469 { 04470 char *val, *s, *s1, *s2, *tele; 04471 char tmp[300], deststr[300] = ""; 04472 04473 val = ast_variable_retrieve(cfg, myrpt->nodes, l->name); 04474 if (!val) 04475 { 04476 fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name); 04477 return -1; 04478 } 04479 04480 ast_mutex_lock(&myrpt->lock); 04481 /* remove from queue */ 04482 remque((struct qelem *) l); 04483 ast_mutex_unlock(&myrpt->lock); 04484 strncpy(tmp,val,sizeof(tmp) - 1); 04485 s = tmp; 04486 s1 = strsep(&s,","); 04487 s2 = strsep(&s,","); 04488 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 04489 tele = strchr(deststr, '/'); 04490 if (!tele) { 04491 fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr); 04492 return -1; 04493 } 04494 *tele++ = 0; 04495 l->elaptime = 0; 04496 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 04497 if (l->chan){ 04498 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 04499 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 04500 l->chan->whentohangup = 0; 04501 l->chan->appl = "Apprpt"; 04502 l->chan->data = "(Remote Rx)"; 04503 if (option_verbose > 2) 04504 ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n", 04505 deststr, tele, l->chan->name); 04506 if(l->chan->cid.cid_num) 04507 free(l->chan->cid.cid_num); 04508 l->chan->cid.cid_num = strdup(myrpt->name); 04509 ast_call(l->chan,tele,999); 04510 04511 } 04512 else 04513 { 04514 if (option_verbose > 2) 04515 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 04516 deststr,tele,l->chan->name); 04517 return -1; 04518 } 04519 ast_mutex_lock(&myrpt->lock); 04520 /* put back in queue queue */ 04521 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 04522 ast_mutex_unlock(&myrpt->lock); 04523 ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name); 04524 return 0; 04525 }
| static int check_freq | ( | struct rpt * | myrpt, | |
| int | m, | |||
| int | d, | |||
| int * | defmode | |||
| ) | [static] |
Definition at line 3437 of file app_rpt.c.
References check_freq_ft897(), check_freq_rbi(), and rpt::remote.
Referenced by function_remote().
03438 { 03439 if(!strcmp(myrpt->remote, remote_rig_ft897)) 03440 return check_freq_ft897(m, d, defmode); 03441 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 03442 return check_freq_rbi(m, d, defmode); 03443 else 03444 return -1; 03445 }
| static int check_freq_ft897 | ( | int | m, | |
| int | d, | |||
| int * | defmode | |||
| ) | [static] |
Definition at line 3042 of file app_rpt.c.
References REM_MODE_FM, REM_MODE_LSB, and REM_MODE_USB.
Referenced by check_freq(), and multimode_bump_freq_ft897().
03043 { 03044 int dflmd = REM_MODE_FM; 03045 03046 if(m == 1){ /* 160 meters */ 03047 dflmd = REM_MODE_LSB; 03048 if(d < 80001) 03049 return -1; 03050 } 03051 else if(m == 3){ /* 80 meters */ 03052 dflmd = REM_MODE_LSB; 03053 if(d < 75001) 03054 return -1; 03055 } 03056 else if(m == 7){ /* 40 meters */ 03057 dflmd = REM_MODE_LSB; 03058 if((d < 15001) || (d > 29999)) 03059 return -1; 03060 } 03061 else if(m == 14){ /* 20 meters */ 03062 dflmd = REM_MODE_USB; 03063 if((d < 15001) || (d > 34999)) 03064 return -1; 03065 } 03066 else if(m == 18){ /* 17 meters */ 03067 dflmd = REM_MODE_USB; 03068 if((d < 11001) || (d > 16797)) 03069 return -1; 03070 } 03071 else if(m == 21){ /* 15 meters */ 03072 dflmd = REM_MODE_USB; 03073 if((d < 20001) || (d > 44999)) 03074 return -1; 03075 } 03076 else if(m == 24){ /* 12 meters */ 03077 dflmd = REM_MODE_USB; 03078 if((d < 93001) || (d > 98999)) 03079 return -1; 03080 } 03081 else if(m == 28){ /* 10 meters */ 03082 dflmd = REM_MODE_USB; 03083 if(d < 30001) 03084 return -1; 03085 } 03086 else if(m == 29){ 03087 if(d >= 51000) 03088 dflmd = REM_MODE_FM; 03089 else 03090 dflmd = REM_MODE_USB; 03091 if(d > 69999) 03092 return -1; 03093 } 03094 else if(m == 50){ /* 6 meters */ 03095 if(d < 10100) 03096 return -1; 03097 if(d >= 30000) 03098 dflmd = REM_MODE_FM; 03099 else 03100 dflmd = REM_MODE_USB; 03101 03102 } 03103 else if((m >= 51) && ( m < 54)){ 03104 dflmd = REM_MODE_FM; 03105 } 03106 else if(m == 144){ /* 2 meters */ 03107 if(d < 10100) 03108 return -1; 03109 if(d >= 30000) 03110 dflmd = REM_MODE_FM; 03111 else 03112 dflmd = REM_MODE_USB; 03113 } 03114 else if((m >= 145) && (m < 148)){ 03115 dflmd = REM_MODE_FM; 03116 } 03117 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 03118 if(m < 438) 03119 dflmd = REM_MODE_USB; 03120 else 03121 dflmd = REM_MODE_FM; 03122 ; 03123 } 03124 else 03125 return -1; 03126 03127 if(defmode) 03128 *defmode = dflmd; 03129 03130 return 0; 03131 }
| static int check_freq_rbi | ( | int | m, | |
| int | d, | |||
| int * | defmode | |||
| ) | [static] |
Definition at line 2951 of file app_rpt.c.
References REM_MODE_FM.
Referenced by check_freq().
02952 { 02953 int dflmd = REM_MODE_FM; 02954 02955 if(m == 50){ /* 6 meters */ 02956 if(d < 10100) 02957 return -1; 02958 } 02959 else if((m >= 51) && ( m < 54)){ 02960 ; 02961 } 02962 else if(m == 144){ /* 2 meters */ 02963 if(d < 10100) 02964 return -1; 02965 } 02966 else if((m >= 145) && (m < 148)){ 02967 ; 02968 } 02969 else if((m >= 222) && (m < 225)){ /* 1.25 meters */ 02970 ; 02971 } 02972 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 02973 ; 02974 } 02975 else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */ 02976 ; 02977 } 02978 else 02979 return -1; 02980 02981 if(defmode) 02982 *defmode = dflmd; 02983 02984 02985 return 0; 02986 }
| static int closerem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 3425 of file app_rpt.c.
References closerem_ft897(), and rpt::remote.
Referenced by rpt_exec().
03426 { 03427 if(!strcmp(myrpt->remote, remote_rig_ft897)) 03428 return closerem_ft897(myrpt); 03429 else 03430 return 0; 03431 }
| static int closerem_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 3359 of file app_rpt.c.
References simple_command_ft897().
Referenced by closerem().
03360 { 03361 simple_command_ft897(myrpt, 0x88); /* PTT off */ 03362 return 0; 03363 }
| static int collect_function_digits | ( | struct rpt * | myrpt, | |
| char * | digits, | |||
| int | command_source, | |||
| struct rpt_link * | mylink | |||
| ) | [static] |
Definition at line 2261 of file app_rpt.c.
References ast_variable_browse(), DC_ERROR, DC_INDETERMINATE, rpt::dphone_functions, rpt::dphone_longestfunc, rpt::functions, rpt::link_functions, rpt::link_longestfunc, rpt::longestfunc, n, ast_variable::name, ast_variable::next, rpt::phone_functions, rpt::phone_longestfunc, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, strsep(), and ast_variable::value.
Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and rpt().
02263 { 02264 int i; 02265 char *stringp,*action,*param,*functiondigits; 02266 char function_table_name[30] = ""; 02267 char workstring[80]; 02268 02269 struct ast_variable *vp; 02270 02271 if(debug) 02272 printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source); 02273 02274 if (command_source == SOURCE_DPHONE) { 02275 if (!myrpt->dphone_functions) return DC_INDETERMINATE; 02276 strncpy(function_table_name, myrpt->dphone_functions, sizeof(function_table_name) - 1); 02277 } 02278 else if (command_source == SOURCE_PHONE) { 02279 if (!myrpt->phone_functions) return DC_INDETERMINATE; 02280 strncpy(function_table_name, myrpt->phone_functions, sizeof(function_table_name) - 1); 02281 } 02282 else if (command_source == SOURCE_LNK) 02283 strncpy(function_table_name, myrpt->link_functions, sizeof(function_table_name) - 1); 02284 else 02285 strncpy(function_table_name, myrpt->functions, sizeof(function_table_name) - 1); 02286 vp = ast_variable_browse(cfg, function_table_name); 02287 while(vp) { 02288 if(!strncasecmp(vp->name, digits, strlen(vp->name))) 02289 break; 02290 vp = vp->next; 02291 } 02292 if(!vp) { 02293 int n; 02294 02295 n = myrpt->longestfunc; 02296 if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc; 02297 else 02298 if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc; 02299 else 02300 if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc; 02301 02302 if(strlen(digits) >= n) 02303 return DC_ERROR; 02304 else 02305 return DC_INDETERMINATE; 02306 } 02307 /* Found a match, retrieve value part and parse */ 02308 strncpy(workstring, vp->value, sizeof(workstring) - 1 ); 02309 stringp = workstring; 02310 action = strsep(&stringp, ","); 02311 param = stringp; 02312 if(debug) 02313 printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)"); 02314 /* Look up the action */ 02315 for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){ 02316 if(!strncasecmp(action, function_table[i].action, strlen(action))) 02317 break; 02318 } 02319 if(debug) 02320 printf("@@@@ table index i = %d\n",i); 02321 if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){ 02322 /* Error, action not in table */ 02323 return DC_ERROR; 02324 } 02325 if(function_table[i].function == NULL){ 02326 /* Error, function undefined */ 02327 if(debug) 02328 printf("@@@@ NULL for action: %s\n",action); 02329 return DC_ERROR; 02330 } 02331 functiondigits = digits + strlen(vp->name); 02332 return (*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink); 02333 }
| char* description | ( | void | ) |
| static int function_autopatchdn | ( | struct rpt * | myrpt, | |
| char * | param, | |||
| char * | digitbuf, | |||
| int | command_source, | |||
| struct rpt_link * | mylink | |||
| ) | [static] |
Definition at line 2165 of file app_rpt.c.
References ast_mutex_lock(), ast_mutex_unlock(), rpt::callmode, DC_COMPLETE, DC_ERROR, rpt::enable, rpt::lock, rpt_telemetry(), and TERM.
02166 { 02167 if (!myrpt->enable) 02168 return DC_ERROR; 02169 02170 if(debug) 02171 printf("@@@@ Autopatch down\n"); 02172 02173 ast_mutex_lock(&myrpt->lock); 02174 02175 if (!myrpt->callmode){ 02176 ast_mutex_unlock(&myrpt->lock); 02177 return DC_COMPLETE; 02178 } 02179 02180 myrpt->callmode = 0; 02181 ast_mutex_unlock(&myrpt->lock); 02182 rpt_telemetry(myrpt, TERM, NULL); 02183 return DC_COMPLETE; 02184 }
| static int function_autopatchup | ( | struct rpt * | myrpt, | |
| char * | param, | |||
| char * | digitbuf, | |||
| int | command_source, | |||
| struct rpt_link * | mylink | |||
| ) | [static] |
Definition at line 2128 of file app_rpt.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, rpt::callmode, rpt::cidx, DC_COMPLETE, DC_ERROR, rpt::enable, rpt::exten, rpt::funcchar, rpt::lock, rpt::mydtmf, rpt_call(), and rpt::rpt_call_thread.
02129 { 02130 pthread_attr_t attr; 02131 02132 02133 if (!myrpt->enable) 02134 return DC_ERROR; 02135 02136 if(debug) 02137 printf("@@@@ Autopatch up\n"); 02138 02139 ast_mutex_lock(&myrpt->lock); 02140 02141 /* if on call, force * into current audio stream */ 02142 02143 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){ 02144 myrpt->mydtmf = myrpt->funcchar; 02145 } 02146 if (myrpt->callmode){ 02147 ast_mutex_unlock(&myrpt->lock); 02148 return DC_COMPLETE; 02149 } 02150 myrpt->callmode = 1; 02151 myrpt->cidx = 0; 02152 myrpt->exten[myrpt->cidx] = 0; 02153 ast_mutex_unlock(&myrpt->lock); 02154 pthread_attr_init(&attr); 02155 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02156 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt); 02157 pthread_attr_destroy(&attr); 02158 return DC_COMPLETE; 02159 }
| static int function_cop | ( | struct rpt * | myrpt, | |
| char * | param, | |||
| char * | digitbuf, | |||
| int | command_source, | |||
| struct rpt_link * | mylink | |||
| ) | [static] |
Definition at line 2222 of file app_rpt.c.
References ARB_ALPHA, DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, rpt::disgorgetime, rpt::enable, myatoi(), rpt_telemetry(), SOURCE_PHONE, and TEST_TONE.
02223 { 02224 if(!param) 02225 return DC_ERROR; 02226 02227 switch(myatoi(param)){ 02228 case 1: /* System reset */ 02229 system("killall -9 asterisk"); /* FIXME to drastic? */ 02230 return DC_COMPLETE; 02231 02232 case 2: 02233 myrpt->enable = 1; 02234 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA"); 02235 return DC_COMPLETE; 02236 02237 case 3: 02238 myrpt->enable = 0; 02239 return DC_COMPLETE; 02240 02241 case 4: /* test tone on */ 02242 rpt_telemetry(myrpt, TEST_TONE, NULL); 02243 return DC_COMPLETE; 02244 02245 case 5: /* Disgorge variables to log for debug purposes */ 02246 myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 02247 return DC_COMPLETE; 02248 02249 case 6: /* Simulate COR being activated (phone only) */ 02250 if (command_source != SOURCE_PHONE) return DC_INDETERMINATE; 02251 return DC_DOKEY; 02252 02253 } 02254 return DC_INDETERMINATE; 02255 }
| static int function_ilink | ( | struct rpt * | myrpt, | |
| char * | param, | |||
| char * | digitbuf, | |||
| int | command_source, | |||
| struct rpt_link * | mylink | |||
| ) | [static] |
Definition at line 1766 of file app_rpt.c.
References ast_call(), AST_FORMAT_SLINEAR, AST_FRAME_TEXT, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_safe_sleep(), ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_true(), ast_variable_retrieve(), ast_verbose(), ast_write(), rpt_link::chan, rpt::cmdnode, COMPLETE, rpt::conf, CONNFAIL, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt_link::disced, rpt::enable, ast_frame::frametype, free, rpt::lastlinknode, rpt::links, rpt::lock, LOG_WARNING, rpt::longestnode, malloc, ast_frame::mallocd, MAX_RETRIES, MAXNODESTR, rpt_link::mode, myatoi(), rpt::name, rpt_link::name, rpt_link::next, rpt::nodes, ast_frame::offset, option_verbose, REMALREADY, REMGO, rpt_link::retries, rpt_telemetry(), s, ast_frame::samples, SOURCE_DPHONE, SOURCE_PHONE, SOURCE_RPT, STATUS, strdup, strsep(), ast_frame::subclass, and VERBOSE_PREFIX_3.
01767 { 01768 01769 char *val, *s, *s1, *s2, *tele; 01770 char tmp[300], deststr[300] = "",modechange = 0; 01771 char digitbuf[MAXNODESTR]; 01772 struct rpt_link *l; 01773 ZT_CONFINFO ci; /* conference info */ 01774 01775 if(!param) 01776 return DC_ERROR; 01777 01778 01779 if (!myrpt->enable) 01780 return DC_ERROR; 01781 01782 strncpy(digitbuf,digits,MAXNODESTR - 1); 01783 01784 if(debug) 01785 printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 01786 01787 switch(myatoi(param)){ 01788 case 1: /* Link off */ 01789 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 01790 strcpy(digitbuf,myrpt->lastlinknode); 01791 val = ast_variable_retrieve(cfg, myrpt->nodes, digitbuf); 01792 if (!val){ 01793 if(strlen(digitbuf) >= myrpt->longestnode) 01794 return DC_ERROR; 01795 break; 01796 } 01797 strncpy(tmp,val,sizeof(tmp) - 1); 01798 s = tmp; 01799 s1 = strsep(&s,","); 01800 s2 = strsep(&s,","); 01801 ast_mutex_lock(&myrpt->lock); 01802 l = myrpt->links.next; 01803 /* try to find this one in queue */ 01804 while(l != &myrpt->links){ 01805 if (l->name[0] == '0') 01806 { 01807 l = l->next; 01808 continue; 01809 } 01810 /* if found matching string */ 01811 if (!strcmp(l->name, digitbuf)) 01812 break; 01813 l = l->next; 01814 } 01815 if (l != &myrpt->links){ /* if found */ 01816 struct ast_frame wf; 01817 01818 strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1); 01819 l->retries = MAX_RETRIES + 1; 01820 l->disced = 1; 01821 ast_mutex_unlock(&myrpt->lock); 01822 wf.frametype = AST_FRAME_TEXT; 01823 wf.subclass = 0; 01824 wf.offset = 0; 01825 wf.mallocd = 1; 01826 wf.datalen = strlen(discstr) + 1; 01827 wf.samples = 0; 01828 wf.data = strdup(discstr); 01829 if (l->chan) 01830 { 01831 ast_write(l->chan,&wf); 01832 if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR; 01833 ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 01834 } 01835 rpt_telemetry(myrpt, COMPLETE, NULL); 01836 return DC_COMPLETE; 01837 } 01838 ast_mutex_unlock(&myrpt->lock); 01839 return DC_COMPLETE; 01840 case 2: /* Link Monitor */ 01841 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 01842 strcpy(digitbuf,myrpt->lastlinknode); 01843 val = ast_variable_retrieve(cfg, myrpt->nodes, digitbuf); 01844 if (!val){ 01845 if(strlen(digitbuf) >= myrpt->longestnode) 01846 return DC_ERROR; 01847 break; 01848 } 01849 strncpy(tmp,val,sizeof(tmp) - 1); 01850 s = tmp; 01851 s1 = strsep(&s,","); 01852 s2 = strsep(&s,","); 01853 ast_mutex_lock(&myrpt->lock); 01854 l = myrpt->links.next; 01855 /* try to find this one in queue */ 01856 while(l != &myrpt->links){ 01857 if (l->name[0] == '0') 01858 { 01859 l = l->next; 01860 continue; 01861 } 01862 /* if found matching string */ 01863 if (!strcmp(l->name, digitbuf)) 01864 break; 01865 l = l->next; 01866 } 01867 /* if found */ 01868 if (l != &myrpt->links) 01869 { 01870 /* if already in this mode, just ignore */ 01871 if ((!l->mode) || (!l->chan)) { 01872 ast_mutex_unlock(&myrpt->lock); 01873 rpt_telemetry(myrpt,REMALREADY,NULL); 01874 return DC_COMPLETE; 01875 01876 } 01877 ast_mutex_unlock(&myrpt->lock); 01878 if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 01879 l->retries = MAX_RETRIES + 1; 01880 l->disced = 2; 01881 modechange = 1; 01882 } else 01883 ast_mutex_unlock(&myrpt->lock); 01884 strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1); 01885 /* establish call in monitor mode */ 01886 l = malloc(sizeof(struct rpt_link)); 01887 if (!l){ 01888 ast_log(LOG_WARNING, "Unable to malloc\n"); 01889 return DC_ERROR; 01890 } 01891 /* zero the silly thing */ 01892 memset((char *)l,0,sizeof(struct rpt_link)); 01893 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 01894 tele = strchr(deststr,'/'); 01895 if (!tele){ 01896 fprintf(stderr,"link2:Dial number (%s) must be in format tech/number\n",deststr); 01897 return DC_ERROR; 01898 } 01899 *tele++ = 0; 01900 l->isremote = (s && ast_true(s)); 01901 strncpy(l->name, digitbuf, MAXNODESTR - 1); 01902 l->chan = ast_request(deststr,AST_FORMAT_SLINEAR,tele,NULL); 01903 if (modechange) l->connected = 1; 01904 if (l->chan){ 01905 ast_set_read_format(l->chan,AST_FORMAT_SLINEAR); 01906 ast_set_write_format(l->chan,AST_FORMAT_SLINEAR); 01907 l->chan->whentohangup = 0; 01908 l->chan->appl = "Apprpt"; 01909 l->chan->data = "(Remote Rx)"; 01910 if (option_verbose > 2) 01911 ast_verbose(VERBOSE_PREFIX_3 "rpt (remote) initiating call to %s/%s on %s\n", 01912 deststr,tele,l->chan->name); 01913 if(l->chan->cid.cid_num) 01914 free(l->chan->cid.cid_num); 01915 l->chan->cid.cid_num = strdup(myrpt->name); 01916 ast_call(l->chan,tele,0); 01917 } 01918 else 01919 { 01920 rpt_telemetry(myrpt,CONNFAIL,l); 01921 free(l); 01922 if (option_verbose > 2) 01923 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 01924 deststr,tele,l->chan->name); 01925 return DC_ERROR; 01926 } 01927 /* allocate a pseudo-channel thru asterisk */ 01928 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 01929 if (!l->pchan){ 01930 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 01931 ast_hangup(l->chan); 01932 free(l); 01933 return DC_ERROR; 01934 } 01935 ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR); 01936 ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR); 01937 /* make a conference for the pseudo-one */ 01938 ci.chan = 0; 01939 ci.confno = myrpt->conf; 01940 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 01941 /* first put the channel on the conference in proper mode */ 01942 if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1) 01943 { 01944 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 01945 ast_hangup(l->chan); 01946 ast_hangup(l->pchan); 01947 free(l); 01948 return DC_ERROR; 01949 } 01950 ast_mutex_lock(&myrpt->lock); 01951 /* insert at end of queue */ 01952 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 01953 ast_mutex_unlock(&myrpt->lock); 01954 rpt_telemetry(myrpt,COMPLETE,NULL); 01955 return DC_COMPLETE; 01956 case 3: /* Link transceive */ 01957 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 01958 strcpy(digitbuf,myrpt->lastlinknode); 01959 val = ast_variable_retrieve(cfg, myrpt->nodes, digitbuf); 01960 if (!val){ 01961 if(strlen(digitbuf) >= myrpt->longestnode) 01962 return DC_ERROR; 01963 break; 01964 } 01965 strncpy(tmp,val,sizeof(tmp) - 1); 01966 s = tmp; 01967 s1 = strsep(&s,","); 01968 s2 = strsep(&s,","); 01969 ast_mutex_lock(&myrpt->lock); 01970 l = myrpt->links.next; 01971 /* try to find this one in queue */ 01972 while(l != &myrpt->links){ 01973 if (l->name[0] == '0') 01974 { 01975 l = l->next; 01976 continue; 01977 } 01978 /* if found matching string */ 01979 if (!strcmp(l->name, digitbuf)) 01980 break; 01981 l = l->next; 01982 } 01983 /* if found */ 01984 if (l != &myrpt->links){ 01985 /* if already in this mode, just ignore */ 01986 if ((l->mode) || (!l->chan)) { 01987 ast_mutex_unlock(&myrpt->lock); 01988 rpt_telemetry(myrpt, REMALREADY, NULL); 01989 return DC_COMPLETE; 01990 } 01991 ast_mutex_unlock(&myrpt->lock); 01992 if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV); 01993 l->retries = MAX_RETRIES + 1; 01994 l->disced = 2; 01995 modechange = 1; 01996 } else 01997 ast_mutex_unlock(&myrpt->lock); 01998 strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1); 01999 /* establish call in tranceive mode */ 02000 l = malloc(sizeof(struct rpt_link)); 02001 if (!l){ 02002 ast_log(LOG_WARNING, "Unable to malloc\n"); 02003 return(DC_ERROR); 02004 } 02005 /* zero the silly thing */ 02006 memset((char *)l,0,sizeof(struct rpt_link)); 02007 l->mode = 1; 02008 l->outbound = 1; 02009 strncpy(l->name, digitbuf, MAXNODESTR - 1); 02010 l->isremote = (s && ast_true(s)); 02011 if (modechange) l->connected = 1; 02012 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 02013 tele = strchr(deststr, '/'); 02014 if (!tele){ 02015 fprintf(stderr,"link3:Dial number (%s) must be in format tech/number\n",deststr); 02016 free(l); 02017 return DC_ERROR; 02018 } 02019 *tele++ = 0; 02020 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 02021 if (l->chan){ 02022 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 02023 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 02024 l->chan->whentohangup = 0; 02025 l->chan->appl = "Apprpt"; 02026 l->chan->data = "(Remote Rx)"; 02027 if (option_verbose > 2) 02028 ast_verbose(VERBOSE_PREFIX_3 "rpt (remote) initiating call to %s/%s on %s\n", 02029 deststr, tele, l->chan->name); 02030 if(l->chan->cid.cid_num) 02031 free(l->chan->cid.cid_num); 02032 l->chan->cid.cid_num = strdup(myrpt->name); 02033 ast_call(l->chan,tele,999); 02034 } 02035 else{ 02036 rpt_telemetry(myrpt,CONNFAIL,l); 02037 free(l); 02038 if (option_verbose > 2) 02039 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 02040 deststr,tele,l->chan->name); 02041 return DC_ERROR; 02042 } 02043 /* allocate a pseudo-channel thru asterisk */ 02044 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 02045 if (!l->pchan){ 02046 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 02047 ast_hangup(l->chan); 02048 free(l); 02049 return DC_ERROR; 02050 } 02051 ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR); 02052 ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR); 02053 /* make a conference for the tx */ 02054 ci.chan = 0; 02055 ci.confno = myrpt->conf; 02056 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 02057 /* first put the channel on the conference in proper mode */ 02058 if (ioctl(l->pchan->fds[0], ZT_SETCONF, &ci) == -1) 02059 { 02060 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02061 ast_hangup(l->chan); 02062 ast_hangup(l->pchan); 02063 free(l); 02064 return DC_ERROR; 02065 } 02066 ast_mutex_lock(&myrpt->lock); 02067 /* insert at end of queue */ 02068 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 02069 ast_mutex_unlock(&myrpt->lock); 02070 rpt_telemetry(myrpt,COMPLETE,NULL); 02071 return DC_COMPLETE; 02072 case 4: /* Enter Command Mode */ 02073 02074 /* if doesnt allow link cmd, or no links active, return */ 02075 if (((command_source != SOURCE_RPT) && (command_source != SOURCE_PHONE) && (command_source != SOURCE_DPHONE)) || (myrpt->links.next == &myrpt->links)) 02076 return DC_COMPLETE; 02077 02078 /* if already in cmd mode, or selected self, fughetabahtit */ 02079 if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){ 02080 02081 rpt_telemetry(myrpt, REMALREADY, NULL); 02082 return DC_COMPLETE; 02083 } 02084 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 02085 strcpy(digitbuf,myrpt->lastlinknode); 02086 /* node must at least exist in list */ 02087 val = ast_variable_retrieve(cfg, myrpt->nodes, digitbuf); 02088 if (!val){ 02089 if(strlen(digitbuf) >= myrpt->longestnode) 02090 return DC_ERROR; 02091 break; 02092 02093 } 02094 ast_mutex_lock(&myrpt->lock); 02095 strcpy(myrpt->lastlinknode,digitbuf); 02096 strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1); 02097 ast_mutex_unlock(&myrpt->lock); 02098 rpt_telemetry(myrpt, REMGO, NULL); 02099 return DC_COMPLETE; 02100 02101 case 5: /* Status */ 02102 rpt_telemetry(myrpt, STATUS, NULL); 02103 return DC_COMPLETE; 02104 02105 02106 case 6: /* All Links Off */ 02107 l = myrpt->links.next; 02108 02109 while(l != &myrpt->links){ 02110 if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV); /* Hang 'em up */ 02111 l = l->next; 02112 } 02113 rpt_telemetry(myrpt, COMPLETE, NULL); 02114 break; 02115 02116 default: 02117 return DC_ERROR; 02118 02119 } 02120 02121 return DC_INDETERMINATE; 02122 }
| static int function_remote | ( | struct rpt * | myrpt, | |
| char * | param, | |||
| char * | digitbuf, | |||
| int | command_source, | |||
| struct rpt_link * | mylink | |||
| ) | [static] |
Definition at line 3619 of file app_rpt.c.
References AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_safe_sleep(), ast_variable_retrieve(), check_freq(), DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt::freq, HF_SCAN_DOWN_FAST, HF_SCAN_DOWN_QUICK, HF_SCAN_DOWN_SLOW, HF_SCAN_UP_FAST, HF_SCAN_UP_QUICK, HF_SCAN_UP_SLOW, rpt::hfscanmode, MAXREMSTR, MEMORY, multimode_bump_freq(), multimode_capable(), myatoi(), rpt::name, rpt::offset, offset, rpt::powerlevel, REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, REM_PLUS, REM_SCANTIME, REM_SIMPLEX, rpt::remchannel, rpt::remmode, rpt::remoterx, rpt::remotetx, rmt_saycharstr(), rmt_sayfile(), rmt_telem_finish(), rmt_telem_start(), rpt::rxpl, rpt::rxplon, s, saycharstr(), sayfile(), saynum(), rpt::scantimer, setrem(), SOURCE_LNK, SOURCE_RPT, split_freq(), strsep(), rpt::tunerequest, rpt::txchannel, rpt::txpl, and rpt::txplon.
03620 { 03621 char *s,*s1,*s2,*val; 03622 int i,j,ht,k,l,ls2,m,d,res,offset,offsave, modesave, defmode; 03623 char multimode = 0; 03624 char oc; 03625 char tmp[20], freq[20] = "", savestr[20] = ""; 03626 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 03627 struct ast_channel *mychannel; 03628 03629 if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK)) 03630 return DC_ERROR; 03631 03632 multimode = multimode_capable(myrpt); 03633 03634 mychannel = myrpt->remchannel; 03635 03636 03637 switch(myatoi(param)){ 03638 03639 case 1: /* retrieve memory */ 03640 if(strlen(digitbuf) < 2) /* needs 2 digits */ 03641 break; 03642 03643 for(i = 0 ; i < 2 ; i++){ 03644 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 03645 return DC_ERROR; 03646 } 03647 03648 val = ast_variable_retrieve(cfg, MEMORY, digitbuf); 03649 if (!val){ 03650 if (ast_safe_sleep(mychannel,1000) == -1) 03651 return DC_ERROR; 03652 sayfile(mychannel,"rpt/memory_notfound"); 03653 return DC_COMPLETE; 03654 } 03655 strncpy(tmp,val,sizeof(tmp) - 1); 03656 s = strchr(tmp,','); 03657 if (!s) 03658 return DC_ERROR; 03659 *s++ = 0; 03660 s1 = strchr(s,','); 03661 if (!s1) 03662 return DC_ERROR; 03663 *s1++ = 0; 03664 strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1); 03665 strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1); 03666 strncpy(myrpt->txpl, s, sizeof(myrpt->rxpl) - 1); 03667 myrpt->remmode = REM_MODE_FM; 03668 myrpt->offset = REM_SIMPLEX; 03669 myrpt->powerlevel = REM_MEDPWR; 03670 myrpt->txplon = myrpt->rxplon = 0; 03671 while(*s1) 03672 { 03673 switch(*s1++){ 03674 case 'A': 03675 case 'a': 03676 strcpy(myrpt->rxpl, "100.0"); 03677 strcpy(myrpt->txpl, "100.0"); 03678 myrpt->remmode = REM_MODE_AM; 03679 break; 03680 03681 case 'B': 03682 case 'b': 03683 strcpy(myrpt->rxpl, "100.0"); 03684 strcpy(myrpt->txpl, "100.0"); 03685 myrpt->remmode = REM_MODE_LSB; 03686 break; 03687 03688 case 'F': 03689 myrpt->remmode = REM_MODE_FM; 03690 break; 03691 03692 case 'L': 03693 case 'l': 03694 myrpt->powerlevel = REM_LOWPWR; 03695 break; 03696 case 'H': 03697 case 'h': 03698 myrpt->powerlevel = REM_HIPWR; 03699 break; 03700 03701 case 'M': 03702 case 'm': 03703 myrpt->powerlevel = REM_MEDPWR; 03704 break; 03705 03706 case '-': 03707 myrpt->offset = REM_MINUS; 03708 break; 03709 03710 case '+': 03711 myrpt->offset = REM_PLUS; 03712 break; 03713 03714 case 'S': 03715 case 's': 03716 myrpt->offset = REM_SIMPLEX; 03717 break; 03718 03719 case 'T': 03720 case 't': 03721 myrpt->txplon = 1; 03722 break; 03723 03724 case 'R': 03725 case 'r': 03726 myrpt->rxplon = 1; 03727 break; 03728 03729 case 'U': 03730 case 'u': 03731 strcpy(myrpt->rxpl, "100.0"); 03732 strcpy(myrpt->txpl, "100.0"); 03733 myrpt->remmode = REM_MODE_USB; 03734 break; 03735 } 03736 } 03737 03738 03739 if (setrem(myrpt) == -1) 03740 return DC_ERROR; 03741 03742 03743 return DC_COMPLETE; 03744 03745 case 2: /* set freq and offset */ 03746 03747 03748 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */ 03749 if(digitbuf[i] == '*'){ 03750 j++; 03751 continue; 03752 } 03753 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 03754 goto invalid_freq; 03755 else{ 03756 if(j == 0) 03757 l++; /* # of digits before first * */ 03758 if(j == 1) 03759 k++; /* # of digits after first * */ 03760 } 03761 } 03762 03763 i = strlen(digitbuf) - 1; 03764 if(multimode){ 03765 if((j > 2) || (l > 3) || (k > 6)) 03766 goto invalid_freq; /* &^@#! */ 03767 } 03768 else{ 03769 if((j > 2) || (l > 4) || (k > 3)) 03770 goto invalid_freq; /* &^@#! */ 03771 } 03772 03773 /* Wait for M+*K+* */ 03774 03775 if(j < 2) 03776 break; /* Not yet */ 03777 03778 /* We have a frequency */ 03779 03780 strncpy(tmp, digitbuf ,sizeof(tmp) - 1); 03781 03782 s = tmp; 03783 s1 = strsep(&s, "*"); /* Pick off MHz */ 03784 s2 = strsep(&s,"*"); /* Pick off KHz and Hz */ 03785 ls2 = strlen(s2); 03786 03787 switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */ 03788 case 1: 03789 ht = 0; 03790 k = 100 * atoi(s2); 03791 break; 03792 03793 case 2: 03794 ht = 0; 03795 k = 10 * atoi(s2); 03796 break; 03797 03798 case 3: 03799 if(!multimode){ 03800 if((s2[2] != '0')&&(s2[2] != '5')) 03801 goto invalid_freq; 03802 } 03803 ht = 0; 03804 k = atoi(s2); 03805 break; 03806 case 4: 03807 k = atoi(s2)/10; 03808 ht = 10 * (atoi(s2+(ls2-1))); 03809 break; 03810 03811 case 5: 03812 k = atoi(s2)/100; 03813 ht = (atoi(s2+(ls2-2))); 03814 break; 03815 03816 default: 03817 goto invalid_freq; 03818 } 03819 03820 /* Check frequency for validity and establish a default mode */ 03821 03822 snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht); 03823 03824 if(debug) 03825 printf("New frequency: %s\n", freq); 03826 03827 split_freq(mhz, decimals, freq); 03828 m = atoi(mhz); 03829 d = atoi(decimals); 03830 03831 if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */ 03832 goto invalid_freq; 03833 03834 03835 if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */ 03836 break; /* Not yet */ 03837 03838 03839 offset = REM_SIMPLEX; /* Assume simplex */ 03840 03841 if(defmode == REM_MODE_FM){ 03842 oc = *s; /* Pick off offset */ 03843 03844 if (oc){ 03845 switch(oc){ 03846 case '1': 03847 offset = REM_MINUS; 03848 break; 03849 03850 case '2': 03851 offset = REM_SIMPLEX; 03852 break; 03853 03854 case '3': 03855 offset = REM_PLUS; 03856 break; 03857 03858 default: 03859 goto invalid_freq; 03860 } 03861 } 03862 } 03863 offsave = myrpt->offset; 03864 modesave = myrpt->remmode; 03865 strncpy(savestr, myrpt->freq, sizeof(savestr) - 1); 03866 strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1); 03867 myrpt->offset = offset; 03868 myrpt->remmode = defmode; 03869 03870 if (setrem(myrpt) == -1){ 03871 myrpt->offset = offsave; 03872 myrpt->remmode = modesave; 03873 strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1); 03874 goto invalid_freq; 03875 } 03876 03877 return DC_COMPLETE; 03878 03879 03880 invalid_freq: 03881 03882 rmt_sayfile(myrpt, mychannel, 1000, "rpt/invalid-freq"); 03883 03884 return DC_ERROR; 03885 03886 case 3: /* set rx PL tone */ 03887 03888 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 03889 if(digitbuf[i] == '*'){ 03890 j++; 03891 continue; 03892 } 03893 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 03894 return DC_ERROR; 03895 else{ 03896 if(j) 03897 l++; 03898 else 03899 k++; 03900 } 03901 } 03902 if((j > 1) || (k > 3) || (l > 1)) 03903 return DC_ERROR; /* &$@^! */ 03904 i = strlen(digitbuf) - 1; 03905 if((j != 1) || (k < 2)|| (l != 1)) 03906 break; /* Not yet */ 03907 if(debug) 03908 printf("PL digits entered %s\n", digitbuf); 03909 03910 strncpy(tmp, digitbuf, sizeof(tmp) - 1); 03911 /* see if we have at least 1 */ 03912 s = strchr(tmp,'*'); 03913 if(s) 03914 *s = '.'; 03915 strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1); 03916 strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1); 03917 03918 if (setrem(myrpt) == -1){ 03919 strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1); 03920 return DC_ERROR; 03921 } 03922 03923 03924 return DC_COMPLETE; 03925 03926 case 4: /* set tx PL tone */ 03927 03928 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 03929 if(digitbuf[i] == '*'){ 03930 j++; 03931 continue; 03932 } 03933 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 03934 return DC_ERROR; 03935 else{ 03936 if(j) 03937 l++; 03938 else 03939 k++; 03940 } 03941 } 03942 if((j > 1) || (k > 3) || (l > 1)) 03943 return DC_ERROR; /* &$@^! */ 03944 i = strlen(digitbuf) - 1; 03945 if((j != 1) || (k < 2)|| (l != 1)) 03946 break; /* Not yet */ 03947 if(debug) 03948 printf("PL digits entered %s\n", digitbuf); 03949 03950 strncpy(tmp, digitbuf, sizeof(tmp) - 1); 03951 /* see if we have at least 1 */ 03952 s = strchr(tmp,'*'); 03953 if(s) 03954 *s = '.'; 03955 strncpy(savestr, myrpt->txpl, sizeof(savestr) - 1); 03956 strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1); 03957 03958 if (setrem(myrpt) == -1){ 03959 strncpy(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1); 03960 return DC_ERROR; 03961 } 03962 03963 03964 return DC_COMPLETE; 03965 03966 03967 case 6: /* MODE (FM,USB,LSB,AM) */ 03968 if(strlen(digitbuf) < 1) 03969 break; 03970 03971 if(!multimode) 03972 return DC_ERROR; /* Multimode radios only */ 03973 03974 switch(*digitbuf){ 03975 case '1': 03976 split_freq(mhz, decimals, myrpt->freq); 03977 m=atoi(mhz); 03978 if(m < 29) /* No FM allowed below 29MHz! */ 03979 return DC_ERROR; 03980 myrpt->remmode = REM_MODE_FM; 03981 res = rmt_saycharstr(myrpt, mychannel, 1000,"FM"); 03982 break; 03983 03984 case '2': 03985 myrpt->remmode = REM_MODE_USB; 03986 res = rmt_saycharstr(myrpt, mychannel, 1000,"USB"); 03987 break; 03988 03989 case '3': 03990 myrpt->remmode = REM_MODE_LSB; 03991 res = rmt_saycharstr(myrpt, mychannel, 1000,"LSB"); 03992 break; 03993 03994 case '4': 03995 myrpt->remmode = REM_MODE_AM; 03996 res = rmt_saycharstr(myrpt, mychannel, 1000,"AM"); 03997 break; 03998 03999 default: 04000 return DC_ERROR; 04001 } 04002 if(res) 04003 return DC_ERROR; 04004 04005 if(setrem(myrpt)) 04006 return DC_ERROR; 04007 return DC_COMPLETE; 04008 04009 case 100: /* other stuff */ 04010 case 101: 04011 case 102: 04012 case 103: 04013 case 104: 04014 case 105: 04015 case 106: 04016 res = rmt_telem_start(myrpt, mychannel, 1000); 04017 switch(myatoi(param)){ /* Quick commands requiring a setrem call */ 04018 case 100: /* RX PL Off */ 04019 myrpt->rxplon = 0; 04020 if(!res) 04021 res = sayfile(mychannel, "rpt/rxpl"); 04022 if(!res) 04023 sayfile(mychannel, "rpt/off"); 04024 break; 04025 04026 case 101: /* RX PL On */ 04027 myrpt->rxplon = 1; 04028 if(!res) 04029 res = sayfile(mychannel, "rpt/rxpl"); 04030 if(!res) 04031 sayfile(mychannel, "rpt/on"); 04032 break; 04033 04034 04035 case 102: /* TX PL Off */ 04036 myrpt->txplon = 0; 04037 if(!res) 04038 res = sayfile(mychannel, "rpt/txpl"); 04039 if(!res) 04040 sayfile(mychannel, "rpt/off"); 04041 break; 04042 04043 case 103: /* TX PL On */ 04044 myrpt->txplon = 1; 04045 if(!res) 04046 res = sayfile(mychannel, "rpt/txpl"); 04047 if(!res) 04048 sayfile(mychannel, "rpt/on"); 04049 break; 04050 04051 case 104: /* Low Power */ 04052 myrpt->powerlevel = REM_LOWPWR; 04053 if(!res) 04054 res = sayfile(mychannel, "rpt/lopwr"); 04055 break; 04056 04057 case 105: /* Medium Power */ 04058 myrpt->powerlevel = REM_MEDPWR; 04059 if(!res) 04060 res = sayfile(mychannel, "rpt/medpwr"); 04061 break; 04062 04063 case 106: /* Hi Power */ 04064 myrpt->powerlevel = REM_HIPWR; 04065 if(!res) 04066 res = sayfile(mychannel, "rpt/hipwr"); 04067 break; 04068 04069 default: 04070 if(!res) 04071 rmt_telem_finish(myrpt, mychannel); 04072 return DC_ERROR; 04073 } 04074 if(!res) 04075 res = rmt_telem_finish(myrpt, mychannel); 04076 if(res) 04077 return DC_ERROR; 04078 04079 if (setrem(myrpt) == -1) 04080 return DC_ERROR; 04081 return DC_COMPLETE; 04082 04083 case 107: /* Bump down 20Hz */ 04084 multimode_bump_freq(myrpt, -20); 04085 return DC_COMPLETE; 04086 04087 case 108: /* Bump down 100Hz */ 04088 multimode_bump_freq(myrpt, -100); 04089 return DC_COMPLETE; 04090 04091 case 109: /* Bump down 500Hz */ 04092 multimode_bump_freq(myrpt, -500); 04093 return DC_COMPLETE; 04094 04095 case 110: /* Bump up 20Hz */ 04096 multimode_bump_freq(myrpt, 20); 04097 return DC_COMPLETE; 04098 04099 case 111: /* Bump up 100Hz */ 04100 multimode_bump_freq(myrpt, 100); 04101 return DC_COMPLETE; 04102 04103 case 112: /* Bump up 500Hz */ 04104 multimode_bump_freq(myrpt, 500); 04105 return DC_COMPLETE; 04106 04107 04108 case 113: 04109 case 114: 04110 case 115: 04111 case 116: 04112 case 117: 04113 case 118: 04114 myrpt->remotetx = 0; 04115 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 04116 if (!myrpt->remoterx) 04117 ast_indicate(mychannel,AST_CONTROL_RADIO_KEY); 04118 if (ast_safe_sleep(mychannel,1000) == -1) 04119 return DC_ERROR; 04120 04121 switch(myatoi(param)){ 04122 04123 case 113: /* Scan down slow */ 04124 res = sayfile(mychannel,"rpt/down"); 04125 if(!res) 04126 res = sayfile(mychannel, "rpt/slow"); 04127 if(!res){ 04128 myrpt->scantimer = REM_SCANTIME; 04129 myrpt->hfscanmode = HF_SCAN_DOWN_SLOW; 04130 } 04131 break; 04132 04133 case 114: /* Scan down quick */ 04134 res = sayfile(mychannel,"rpt/down"); 04135 if(!res) 04136 res = sayfile(mychannel, "rpt/quick"); 04137 if(!res){ 04138 myrpt->scantimer = REM_SCANTIME; 04139 myrpt->hfscanmode = HF_SCAN_DOWN_QUICK; 04140 } 04141 break; 04142 04143 case 115: /* Scan down fast */ 04144 res = sayfile(mychannel,"rpt/down"); 04145 if(!res) 04146 res = sayfile(mychannel, "rpt/fast"); 04147 if(!res){ 04148 myrpt->scantimer = REM_SCANTIME; 04149 myrpt->hfscanmode = HF_SCAN_DOWN_FAST; 04150 } 04151 break; 04152 04153 case 116: /* Scan up slow */ 04154 res = sayfile(mychannel,"rpt/up"); 04155 if(!res) 04156 res = sayfile(mychannel, "rpt/slow"); 04157 if(!res){ 04158 myrpt->scantimer = REM_SCANTIME; 04159 myrpt->hfscanmode = HF_SCAN_UP_SLOW; 04160 } 04161 break; 04162 04163 case 117: /* Scan up quick */ 04164 res = sayfile(mychannel,"rpt/up"); 04165 if(!res) 04166 res = sayfile(mychannel, "rpt/quick"); 04167 if(!res){ 04168 myrpt->scantimer = REM_SCANTIME; 04169 myrpt->hfscanmode = HF_SCAN_UP_QUICK; 04170 } 04171 break; 04172 04173 case 118: /* Scan up fast */ 04174 res = sayfile(mychannel,"rpt/up"); 04175 if(!res) 04176 res = sayfile(mychannel, "rpt/fast"); 04177 if(!res){ 04178 myrpt->scantimer = REM_SCANTIME; 04179 myrpt->hfscanmode = HF_SCAN_UP_FAST; 04180 } 04181 break; 04182 } 04183 rmt_telem_finish(myrpt,mychannel); 04184 return DC_COMPLETE; 04185 04186 04187 case 119: /* Tune Request */ 04188 myrpt->tunerequest = 1; 04189 return DC_COMPLETE; 04190 04191 case 5: /* Long Status */ 04192 case 140: /* Short Status */ 04193 res = rmt_telem_start(myrpt, mychannel, 1000); 04194 04195 res = sayfile(mychannel,"rpt/node"); 04196 if(!res) 04197 res = saycharstr(mychannel, myrpt->name); 04198 if(!res) 04199 res = sayfile(mychannel,"rpt/frequency"); 04200 if(!res) 04201 res = split_freq(mhz, decimals, myrpt->freq); 04202 if(!res){ 04203 m = atoi(mhz); 04204 if(m < 100) 04205 res = saynum(mychannel, m); 04206 else 04207 res = saycharstr(mychannel, mhz); 04208 } 04209 if(!res) 04210 res = sayfile(mychannel, "letters/dot"); 04211 if(!res) 04212 res = saycharstr(mychannel, decimals); 04213 04214 if(res){ 04215 rmt_telem_finish(myrpt,mychannel); 04216 return DC_ERROR; 04217 } 04218 if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */ 04219 switch(myrpt->offset){ 04220 04221 case REM_MINUS: 04222 res = sayfile(mychannel,"rpt/minus"); 04223 break; 04224 04225 case REM_SIMPLEX: 04226 res = sayfile(mychannel,"rpt/simplex"); 04227 break; 04228 04229 case REM_PLUS: 04230 res = sayfile(mychannel,"rpt/plus"); 04231 break; 04232 04233 default: 04234 return DC_ERROR; 04235 04236 } 04237 } 04238 else{ /* Must be USB, LSB, or AM */ 04239 switch(myrpt->remmode){ 04240 04241 case REM_MODE_USB: 04242 res = saycharstr(mychannel, "USB"); 04243 break; 04244 04245 case REM_MODE_LSB: 04246 res = saycharstr(mychannel, "LSB"); 04247 break; 04248 04249 case REM_MODE_AM: 04250 res = saycharstr(mychannel, "AM"); 04251 break; 04252 04253 04254 default: 04255 return DC_ERROR; 04256 } 04257 } 04258 04259 if (res == -1){ 04260 rmt_telem_finish(myrpt,mychannel); 04261 return DC_ERROR; 04262 } 04263 04264 if(myatoi(param) == 140){ /* Short status? */ 04265 if(!res) 04266 res = rmt_telem_finish(myrpt, mychannel); 04267 if(res) 04268 return DC_ERROR; 04269 return DC_COMPLETE; 04270 } 04271 04272 switch(myrpt->powerlevel){ 04273 04274 case REM_LOWPWR: 04275 res = sayfile(mychannel,"rpt/lopwr") ; 04276 break; 04277 04278 case REM_MEDPWR: 04279 res = sayfile(mychannel,"rpt/medpwr"); 04280 break; 04281 case REM_HIPWR: 04282 res = sayfile(mychannel,"rpt/hipwr"); 04283 break; 04284 } 04285 if (res || (sayfile(mychannel,"rpt/rxpl") == -1) || 04286 (sayfile(mychannel,"rpt/frequency") == -1) || 04287 (saycharstr(mychannel,myrpt->rxpl) == -1) || 04288 (sayfile(mychannel,"rpt/txpl") == -1) || 04289 (sayfile(mychannel,"rpt/frequency") == -1) || 04290 (saycharstr(mychannel,myrpt->txpl) == -1) || 04291 (sayfile(mychannel,"rpt/txpl") == -1) || 04292 (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1) || 04293 (sayfile(mychannel,"rpt/rxpl") == -1) || 04294 (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1)) 04295 { 04296 rmt_telem_finish(myrpt,mychannel); 04297 return DC_ERROR; 04298 } 04299 if(!res) 04300 res = rmt_telem_finish(myrpt,mychannel); 04301 if(res) 04302 return DC_ERROR; 04303 04304 return DC_COMPLETE; 04305 default: 04306 return DC_ERROR; 04307 } 04308 04309 return DC_INDETERMINATE; 04310 }
| static int function_status | ( | struct rpt * | myrpt, | |
| char * | param, | |||
| char * | digitbuf, | |||
| int | command_source, | |||
| struct rpt_link * | mylink | |||
| ) | [static] |
Definition at line 2190 of file app_rpt.c.
References DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt::enable, ID1, myatoi(), rpt_telemetry(), STATS_TIME, and STATS_VERSION.
02191 { 02192 02193 if(!param) 02194 return DC_ERROR; 02195 02196 02197 if (!myrpt->enable) 02198 return DC_ERROR; 02199 02200 if(debug) 02201 printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 02202 02203 switch(myatoi(param)){ 02204 case 1: /* System ID */ 02205 rpt_telemetry(myrpt, ID1, NULL); 02206 return DC_COMPLETE; 02207 case 2: /* System Time */ 02208 rpt_telemetry(myrpt, STATS_TIME, NULL); 02209 return DC_COMPLETE; 02210 case 3: /* app_rpt.c version */ 02211 rpt_telemetry(myrpt, STATS_VERSION, NULL); 02212 default: 02213 return DC_ERROR; 02214 } 02215 return DC_INDETERMINATE; 02216 }
| static int get_wait_interval | ( | struct rpt * | myrpt, | |
| int | type | |||
| ) | [static] |
Definition at line 898 of file app_rpt.c.
References ast_log(), ast_strdupa, ast_variable_retrieve(), DLY_CALLTERM, DLY_ID, DLY_TELEM, DLY_UNKEY, LOG_WARNING, rpt::name, and retrieve_astcfgint().
Referenced by rpt_tele_thread(), and wait_interval().
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 }
Definition at line 2336 of file app_rpt.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_TEXT, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt::callmode, rpt_link::chan, rpt::cidx, collect_function_digits(), ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt_link::disced, rpt::endchar, rpt::exten, ast_frame::frametype, rpt::funcchar, rpt::links, rpt::lock, LOG_WARNING, ast_frame::mallocd, MAX_RETRIES, MAXDTMF, rpt::mydtmf, rpt_link::name, rpt::name, rpt_link::next, ast_frame::offset, rpt::ourcontext, rpt::pchannel, PROC, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, rpt_link::retries, rpt_telemetry(), ast_frame::samples, seq, SOURCE_LNK, rpt::stopgen, strdup, and ast_frame::subclass.
Referenced by rpt().
02338 { 02339 char tmp[300],cmd[300] = "",dest[300],src[300],c; 02340 int seq, res; 02341 struct rpt_link *l; 02342 struct ast_frame wf; 02343 02344 wf.frametype = AST_FRAME_TEXT; 02345 wf.subclass = 0; 02346 wf.offset = 0; 02347 wf.mallocd = 1; 02348 wf.datalen = strlen(str) + 1; 02349 wf.samples = 0; 02350 /* put string in our buffer */ 02351 strncpy(tmp,str,sizeof(tmp) - 1); 02352 02353 if (!strcmp(tmp,discstr)) 02354 { 02355 mylink->disced = 1; 02356 mylink->retries = MAX_RETRIES + 1; 02357 ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV); 02358 return; 02359 } 02360 if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5) 02361 { 02362 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 02363 return; 02364 } 02365 if (strcmp(cmd,"D")) 02366 { 02367 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 02368 return; 02369 } 02370 02371 if (dest[0] == '0') 02372 { 02373 strcpy(dest,myrpt->name); 02374 } 02375 02376 /* if not for me, redistribute to all links */ 02377 if (strcmp(dest,myrpt->name)) 02378 { 02379 l = myrpt->links.next; 02380 /* see if this is one in list */ 02381 while(l != &myrpt->links) 02382 { 02383 if (l->name[0] == '0') 02384 { 02385 l = l->next; 02386 continue; 02387 } 02388 /* dont send back from where it came */ 02389 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 02390 { 02391 l = l->next; 02392 continue; 02393 } 02394 /* if it is, send it and we're done */ 02395 if (!strcmp(l->name,dest)) 02396 { 02397 /* send, but not to src */ 02398 if (strcmp(l->name,src)) { 02399 wf.data = strdup(str); 02400 if (l->chan) ast_write(l->chan,&wf); 02401 } 02402 return; 02403 } 02404 l = l->next; 02405 } 02406 l = myrpt->links.next; 02407 /* otherwise, send it to all of em */ 02408 while(l != &myrpt->links) 02409 { 02410 if (l->name[0] == '0') 02411 { 02412 l = l->next; 02413 continue; 02414 } 02415 /* dont send back from where it came */ 02416 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 02417 { 02418 l = l->next; 02419 continue; 02420 } 02421 /* send, but not to src */ 02422 if (strcmp(l->name,src)) { 02423 wf.data = strdup(str); 02424 if (l->chan) ast_write(l->chan,&wf); 02425 } 02426 l = l->next; 02427 } 02428 return; 02429 } 02430 ast_mutex_lock(&myrpt->lock); 02431 if (c == myrpt->endchar) myrpt->stopgen = 1; 02432 if (myrpt->callmode == 1) 02433 { 02434 myrpt->exten[myrpt->cidx++] = c; 02435 myrpt->exten[myrpt->cidx] = 0; 02436 /* if this exists */ 02437 if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) 02438 { 02439 myrpt->callmode = 2; 02440 rpt_telemetry(myrpt,PROC,NULL); 02441 } 02442 /* if can continue, do so */ 02443 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) 02444 { 02445 /* call has failed, inform user */ 02446 myrpt->callmode = 4; 02447 } 02448 } 02449 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 02450 { 02451 myrpt->mydtmf = c; 02452 } 02453 if (c == myrpt->funcchar) 02454 { 02455 myrpt->rem_dtmfidx = 0; 02456 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 02457 time(&myrpt->rem_dtmf_time); 02458 ast_mutex_unlock(&myrpt->lock); 02459 return; 02460 } 02461 else if ((c != myrpt->endchar) && (myrpt->rem_dtmfidx >= 0)) 02462 { 02463 time(&myrpt->rem_dtmf_time); 02464 if (myrpt->rem_dtmfidx < MAXDTMF) 02465 { 02466 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 02467 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 02468 02469 ast_mutex_unlock(&myrpt->lock); 02470 strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1); 02471 res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink); 02472 ast_mutex_lock(&myrpt->lock); 02473 02474 switch(res){ 02475 02476 case DC_INDETERMINATE: 02477 break; 02478 02479 case DC_REQ_FLUSH: 02480 myrpt->rem_dtmfidx = 0; 02481 myrpt->rem_dtmfbuf[0] = 0; 02482 break; 02483 02484 02485 case DC_COMPLETE: 02486 myrpt->rem_dtmfbuf[0] = 0; 02487 myrpt->rem_dtmfidx = -1; 02488 myrpt->rem_dtmf_time = 0; 02489 break; 02490 02491 case DC_ERROR: 02492 default: 02493 myrpt->rem_dtmfbuf[0] = 0; 02494 myrpt->rem_dtmfidx = -1; 02495 myrpt->rem_dtmf_time = 0; 02496 break; 02497 } 02498 } 02499 02500 } 02501 ast_mutex_unlock(&myrpt->lock); 02502 return; 02503 }
| static void handle_link_phone_dtmf | ( | struct rpt * | myrpt, | |
| struct rpt_link * | mylink, | |||
| char | c | |||
| ) | [static] |
Definition at line 2505 of file app_rpt.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_mutex_lock(), ast_mutex_unlock(), rpt::callmode, rpt::cidx, rpt::cmdnode, collect_function_digits(), COMPLETE, DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt::dtmfbuf, rpt::dtmfidx, rpt::endchar, rpt::exten, rpt::funcchar, rpt_link::lastrx, rpt::lock, MAXDTMF, rpt::mydtmf, rpt::ourcontext, rpt::pchannel, rpt_link::phonemode, PROC, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, rpt_telemetry(), send_link_dtmf(), SOURCE_DPHONE, SOURCE_PHONE, and rpt::stopgen.
Referenced by rpt().
02507 { 02508 02509 char cmd[300]; 02510 int res; 02511 02512 ast_mutex_lock(&myrpt->lock); 02513 if (c == myrpt->endchar) 02514 { 02515 if (mylink->lastrx) 02516 { 02517 mylink->lastrx = 0; 02518 ast_mutex_unlock(&myrpt->lock); 02519 return; 02520 } 02521 myrpt->stopgen = 1; 02522 if (myrpt->cmdnode[0]) 02523 { 02524 myrpt->cmdnode[0] = 0; 02525 myrpt->dtmfidx = -1; 02526 myrpt->dtmfbuf[0] = 0; 02527 ast_mutex_unlock(&myrpt->lock); 02528 rpt_telemetry(myrpt,COMPLETE,NULL); 02529 ast_mutex_unlock(&myrpt->lock); 02530 return; 02531 } 02532 } 02533 if (myrpt->cmdnode[0]) 02534 { 02535 ast_mutex_unlock(&myrpt->lock); 02536 send_link_dtmf(myrpt,c); 02537 return; 02538 } 02539 if (myrpt->callmode == 1) 02540 { 02541 myrpt->exten[myrpt->cidx++] = c; 02542 myrpt->exten[myrpt->cidx] = 0; 02543 /* if this exists */ 02544 if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) 02545 { 02546 myrpt->callmode = 2; 02547 rpt_telemetry(myrpt,PROC,NULL); 02548 } 02549 /* if can continue, do so */ 02550 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) 02551 { 02552 /* call has failed, inform user */ 02553 myrpt->callmode = 4; 02554 } 02555 } 02556 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 02557 { 02558 myrpt->mydtmf = c; 02559 } 02560 if (c == myrpt->funcchar) 02561 { 02562 myrpt->rem_dtmfidx = 0; 02563 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 02564 time(&myrpt->rem_dtmf_time); 02565 ast_mutex_unlock(&myrpt->lock); 02566 return; 02567 } 02568 else if ((c != myrpt->endchar) && (myrpt->rem_dtmfidx >= 0)) 02569 { 02570 time(&myrpt->rem_dtmf_time); 02571 if (myrpt->rem_dtmfidx < MAXDTMF) 02572 { 02573 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 02574 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 02575 02576 ast_mutex_unlock(&myrpt->lock); 02577 strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1); 02578 res = collect_function_digits(myrpt, cmd, 02579 ((mylink->phonemode == 2) ? SOURCE_DPHONE : SOURCE_PHONE), mylink); 02580 ast_mutex_lock(&myrpt->lock); 02581 02582 switch(res){ 02583 02584 case DC_INDETERMINATE: 02585 break; 02586 02587 case DC_DOKEY: 02588 mylink->lastrx = 1; 02589 break; 02590 02591 case DC_REQ_FLUSH: 02592 myrpt->rem_dtmfidx = 0; 02593 myrpt->rem_dtmfbuf[0] = 0; 02594 break; 02595 02596 02597 case DC_COMPLETE: 02598 myrpt->rem_dtmfbuf[0] = 0; 02599 myrpt->rem_dtmfidx = -1; 02600 myrpt->rem_dtmf_time = 0; 02601 break; 02602 02603 case DC_ERROR: 02604 default: 02605 myrpt->rem_dtmfbuf[0] = 0; 02606 myrpt->rem_dtmfidx = -1; 02607 myrpt->rem_dtmf_time = 0; 02608 break; 02609 } 02610 } 02611 02612 } 02613 ast_mutex_unlock(&myrpt->lock); 02614 return; 02615 }
| static int handle_remote_data | ( | struct rpt * | myrpt, | |
| char * | str | |||
| ) | [static] |
Definition at line 4407 of file app_rpt.c.
References AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_log(), ast_safe_sleep(), handle_remote_dtmf_digit(), LOG_WARNING, rpt::name, rpt::remchannel, rpt::remoterx, rpt::remotetx, rmt_telem_finish(), seq, telem_lookup(), and rpt::txchannel.
Referenced by rpt_exec().
04408 { 04409 char tmp[300],cmd[300],dest[300],src[300],c; 04410 int seq,res; 04411 04412 /* put string in our buffer */ 04413 strncpy(tmp,str,sizeof(tmp) - 1); 04414 if (!strcmp(tmp,discstr)) return 0; 04415 if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5) 04416 { 04417 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 04418 return 0; 04419 } 04420 if (strcmp(cmd,"D")) 04421 { 04422 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 04423 return 0; 04424 } 04425 /* if not for me, ignore */ 04426 if (strcmp(dest,myrpt->name)) return 0; 04427 res = handle_remote_dtmf_digit(myrpt,c, NULL, 0); 04428 if (res != 1) 04429 return res; 04430 myrpt->remotetx = 0; 04431 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 04432 if (!myrpt->remoterx) 04433 { 04434 ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_KEY); 04435 } 04436 if (ast_safe_sleep(myrpt->remchannel,1000) == -1) return -1; 04437 res = telem_lookup(myrpt->remchannel, myrpt->name, "functcomplete"); 04438 rmt_telem_finish(myrpt,myrpt->remchannel); 04439 return res; 04440 }
| static int handle_remote_dtmf_digit | ( | struct rpt * | myrpt, | |
| char | c, | |||
| char * | keyed, | |||
| int | phonemode | |||
| ) | [static] |
Definition at line 4312 of file app_rpt.c.
References collect_function_digits(), DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt::dtmf_time_rem, DTMF_TIMEOUT, rpt::dtmfbuf, rpt::dtmfidx, rpt::funcchar, rpt::hfscanmode, MAXDTMF, SOURCE_DPHONE, SOURCE_PHONE, SOURCE_RMT, and stop_scan().
Referenced by handle_remote_data(), and handle_remote_phone_dtmf().
04313 { 04314 time_t now; 04315 int ret,res = 0,src; 04316 04317 /* Stop scan mode if in scan mode */ 04318 if(myrpt->hfscanmode){ 04319 stop_scan(myrpt,0); 04320 return 0; 04321 } 04322 04323 time(&now); 04324 /* if timed-out */ 04325 if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now) 04326 { 04327 myrpt->dtmfidx = -1; 04328 myrpt->dtmfbuf[0] = 0; 04329 myrpt->dtmf_time_rem = 0; 04330 } 04331 /* if decode not active */ 04332 if (myrpt->dtmfidx == -1) 04333 { 04334 /* if not lead-in digit, dont worry */ 04335 if (c != myrpt->funcchar) return 0; 04336 myrpt->dtmfidx = 0; 04337 myrpt->dtmfbuf[0] = 0; 04338 myrpt->dtmf_time_rem = now; 04339 return 0; 04340 } 04341 /* if too many in buffer, start over */ 04342 if (myrpt->dtmfidx >= MAXDTMF) 04343 { 04344 myrpt->dtmfidx = 0; 04345 myrpt->dtmfbuf[0] = 0; 04346 myrpt->dtmf_time_rem = now; 04347 } 04348 if (c == myrpt->funcchar) 04349 { 04350 /* if star at beginning, or 2 together, erase buffer */ 04351 if ((myrpt->dtmfidx < 1) || 04352 (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->funcchar)) 04353 { 04354 myrpt->dtmfidx = 0; 04355 myrpt->dtmfbuf[0] = 0; 04356 myrpt->dtmf_time_rem = now; 04357 return 0; 04358 } 04359 } 04360 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 04361 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 04362 myrpt->dtmf_time_rem = now; 04363 04364 04365 src = SOURCE_RMT; 04366 if (phonemode > 1) src = SOURCE_DPHONE; 04367 else if (phonemode) src = SOURCE_PHONE; 04368 ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL); 04369 04370 switch(ret){ 04371 04372 case DC_INDETERMINATE: 04373 res = 0; 04374 break; 04375 04376 case DC_DOKEY: 04377 if (keyed) *keyed = 1; 04378 res = 0; 04379 break; 04380 04381 case DC_REQ_FLUSH: 04382 myrpt->dtmfidx = 0; 04383 myrpt->dtmfbuf[0] = 0; 04384 res = 0; 04385 break; 04386 04387 04388 case DC_COMPLETE: 04389 myrpt->dtmfbuf[0] = 0; 04390 myrpt->dtmfidx = -1; 04391 myrpt->dtmf_time_rem = 0; 04392 res = 1; 04393 break; 04394 04395 case DC_ERROR: 04396 default: 04397 myrpt->dtmfbuf[0] = 0; 04398 myrpt->dtmfidx = -1; 04399 myrpt->dtmf_time_rem = 0; 04400 res = 0; 04401 break; 04402 } 04403 04404 return res; 04405 }
| static int handle_remote_phone_dtmf | ( | struct rpt * | myrpt, | |
| char | c, | |||
| char * | keyed, | |||
| int | phonemode | |||
| ) | [static] |
Definition at line 4442 of file app_rpt.c.
References AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_safe_sleep(), DC_INDETERMINATE, rpt::endchar, handle_remote_dtmf_digit(), rpt::name, rpt::remchannel, rpt::remoterx, rpt::remotetx, rmt_telem_finish(), telem_lookup(), and rpt::txchannel.
Referenced by rpt_exec().
04443 { 04444 int res; 04445 04446 04447 if (keyed && *keyed && (c == myrpt->endchar)) 04448 { 04449 *keyed = 0; 04450 return DC_INDETERMINATE; 04451 } 04452 04453 res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode); 04454 if (res != 1) 04455 return res; 04456 myrpt->remotetx = 0; 04457 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 04458 if (!myrpt->remoterx) 04459 { 04460 ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_KEY); 04461 } 04462 if (ast_safe_sleep(myrpt->remchannel,1000) == -1) return -1; 04463 res = telem_lookup(myrpt->remchannel, myrpt->name, "functcomplete"); 04464 rmt_telem_finish(myrpt,myrpt->remchannel); 04465 return res; 04466 }
| char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 6560 of file app_rpt.c.
References ASTERISK_GPL_KEY.
06561 { 06562 return ASTERISK_GPL_KEY; 06563 }
| int load_module | ( | void | ) |
Initialize the module.
This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.
Definition at line 6538 of file app_rpt.c.
References ast_cli_register(), ast_pthread_create, ast_register_application(), rpt_exec(), and rpt_master().
06539 { 06540 ast_pthread_create(&rpt_master_thread,NULL,rpt_master,NULL); 06541 06542 /* Register cli extensions */ 06543 ast_cli_register(&cli_debug); 06544 06545 return ast_register_application(app, rpt_exec, synopsis, descrip); 06546 }
| static int multimode_bump_freq | ( | struct rpt * | myrpt, | |
| int | interval | |||
| ) | [static] |
Definition at line 3462 of file app_rpt.c.
References multimode_bump_freq_ft897(), and rpt::remote.
Referenced by function_remote(), and service_scan().
03463 { 03464 if(!strcmp(myrpt->remote, remote_rig_ft897)) 03465 return multimode_bump_freq_ft897(myrpt, interval); 03466 else 03467 return -1; 03468 }
| static int multimode_bump_freq_ft897 | ( | struct rpt * | myrpt, | |
| int | interval | |||
| ) | [static] |
Definition at line 3371 of file app_rpt.c.
References check_freq_ft897(), rpt::freq, MAXREMSTR, set_freq_ft897(), and split_freq().
Referenced by multimode_bump_freq().
03372 { 03373 int m,d; 03374 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 03375 03376 if(debug) 03377 printf("Before bump: %s\n", myrpt->freq); 03378 03379 if(split_freq(mhz, decimals, myrpt->freq)) 03380 return -1; 03381 03382 m = atoi(mhz); 03383 d = atoi(decimals); 03384 03385 d += (interval / 10); /* 10Hz resolution */ 03386 if(d < 0){ 03387 m--; 03388 d += 100000; 03389 } 03390 else if(d >= 100000){ 03391 m++; 03392 d -= 100000; 03393 } 03394 03395 if(check_freq_ft897(m, d, NULL)){ 03396 if(debug) 03397 printf("Bump freq invalid\n"); 03398 return -1; 03399 } 03400 03401 snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d); 03402 03403 if(debug) 03404 printf("After bump: %s\n", myrpt->freq); 03405 03406 return set_freq_ft897(myrpt, myrpt->freq); 03407 }
| static int multimode_capable | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 3451 of file app_rpt.c.
References rpt::remote.
Referenced by function_remote().
03452 { 03453 if(!strcmp(myrpt->remote, remote_rig_ft897)) 03454 return 1; 03455 return 0; 03456 }
| static int myatoi | ( | char * | str | ) | [static] |
Definition at line 462 of file app_rpt.c.
Referenced by function_cop(), function_ilink(), function_remote(), function_status(), retrieve_astcfgint(), and rpt_do_debug().
00463 { 00464 int ret; 00465 00466 if (str == NULL) return -1; 00467 /* leave this %i alone, non-base-10 input is useful here */ 00468 if (sscanf(str,"%i",&ret) != 1) return -1; 00469 return ret; 00470 }
| static int play_silence | ( | struct ast_channel * | chan, | |
| int | duration | |||
| ) | [static] |
Definition at line 515 of file app_rpt.c.
References play_tone_pair().
Referenced by send_morse().
00516 { 00517 return play_tone_pair(chan, 0, 0, duration, 0); 00518 }
| static int play_tone | ( | struct ast_channel * | chan, | |
| int | freq, | |||
| int | duration, | |||
| int | amplitude | |||
| ) | [static] |
Definition at line 510 of file app_rpt.c.
References play_tone_pair().
Referenced by rpt_exec(), and send_morse().
00511 { 00512 return play_tone_pair(chan, freq, 0, duration, amplitude); 00513 }
| static int play_tone_pair | ( | struct ast_channel * | chan, | |
| int | f1, | |||
| int | f2, | |||
| int | duration, | |||
| int | amplitude | |||
| ) | [static] |
Definition at line 496 of file app_rpt.c.
References ast_safe_sleep(), ast_tonepair_start(), and ast_channel::generatordata.
Referenced by play_silence(), play_tone(), and send_tone_telemetry().
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 }
| static int rbi_mhztoband | ( | char * | str | ) | [static] |
Definition at line 2648 of file app_rpt.c.
Referenced by setrbi().
02649 { 02650 int i; 02651 02652 i = atoi(str) / 10; /* get the 10's of mhz */ 02653 switch(i) 02654 { 02655 case 2: 02656 return 10; 02657 case 5: 02658 return 11; 02659 case 14: 02660 return 2; 02661 case 22: 02662 return 3; 02663 case 44: 02664 return 4; 02665 case 124: 02666 return 0; 02667 case 125: 02668 return 1; 02669 case 126: 02670 return 8; 02671 case 127: 02672 return 5; 02673 case 128: 02674 return 6; 02675 case 129: 02676 return 7; 02677 default: 02678 break; 02679 } 02680 return -1; 02681 }
| static void rbi_out | ( | struct rpt * | myrpt, | |
| unsigned char * | data | |||
| ) | [static] |
Definition at line 2805 of file app_rpt.c.
References ast_log(), ast_channel::fds, LOG_WARNING, ast_channel::name, rbi_out_parallel(), and rpt::rxchannel.
Referenced by setrbi().
02806 { 02807 struct zt_radio_param r; 02808 02809 memset(&r,0,sizeof(struct zt_radio_param)); 02810 r.radpar = ZT_RADPAR_REMMODE; 02811 r.data = ZT_RADPAR_REM_RBI1; 02812 /* if setparam ioctl fails, its probably not a pciradio card */ 02813 if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1) 02814 { 02815 rbi_out_parallel(myrpt,data); 02816 return; 02817 } 02818 r.radpar = ZT_RADPAR_REMCOMMAND; 02819 memcpy(&r.data,data,5); 02820 if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1) 02821 { 02822 ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->rxchannel->name); 02823 return; 02824 } 02825 }
| static void rbi_out_parallel | ( | struct rpt * | myrpt, | |
| unsigned char * | data | |||
| ) | [static] |
Definition at line 2779 of file app_rpt.c.
References rpt::iobase.
Referenced by rbi_out().
02780 { 02781 int i,j; 02782 unsigned char od,d; 02783 static volatile long long delayvar; 02784 02785 for(i = 0 ; i < 5 ; i++){ 02786 od = *data++; 02787 for(j = 0 ; j < 8 ; j++){ 02788 d = od & 1; 02789 outb(d,myrpt->iobase); 02790 /* >= 15 us */ 02791 for(delayvar = 1; delayvar < 15000; delayvar++); 02792 od >>= 1; 02793 outb(d | 2,myrpt->iobase); 02794 /* >= 30 us */ 02795 for(delayvar = 1; delayvar < 30000; delayvar++); 02796 outb(d,myrpt->iobase); 02797 /* >= 10 us */ 02798 for(delayvar = 1; delayvar < 10000; delayvar++); 02799 } 02800 } 02801 /* >= 50 us */ 02802 for(delayvar = 1; delayvar < 50000; delayvar++); 02803 }
| static int rbi_pltocode | ( | char * | str | ) | [static] |
Definition at line 2684 of file app_rpt.c.
References s.
Referenced by setrbi().
02685 { 02686 int i; 02687 char *s; 02688 02689 s = strchr(str,'.'); 02690 i = 0; 02691 if (s) i = atoi(s + 1); 02692 i += atoi(str) * 10; 02693 switch(i) 02694 { 02695 case 670: 02696 return 0; 02697 case 719: 02698 return 1; 02699 case 744: 02700 return 2; 02701 case 770: 02702 return 3; 02703 case 797: 02704 return 4; 02705 case 825: 02706 return 5; 02707 case 854: 02708 return 6; 02709 case 885: 02710 return 7; 02711 case 915: 02712 return 8; 02713 case 948: 02714 return 9; 02715 case 974: 02716 return 10; 02717 case 1000: 02718 return 11; 02719 case 1035: 02720 return 12; 02721 case 1072: 02722 return 13; 02723 case 1109: 02724 return 14; 02725 case 1148: 02726 return 15; 02727 case 1188: 02728 return 16; 02729 case 1230: 02730 return 17; 02731 case 1273: 02732 return 18; 02733 case 1318: 02734 return 19; 02735 case 1365: 02736 return 20; 02737 case 1413: 02738 return 21; 02739 case 1462: 02740 return 22; 02741 case 1514: 02742 return 23; 02743 case 1567: 02744 return 24; 02745 case 1622: 02746 return 25; 02747 case 1679: 02748 return 26; 02749 case 1738: 02750 return 27; 02751 case 1799: 02752 return 28; 02753 case 1862: 02754 return 29; 02755 case 1928: 02756 return 30; 02757 case 2035: 02758 return 31; 02759 case 2107: 02760 return 32; 02761 case 2181: 02762 return 33; 02763 case 2257: 02764 return 34; 02765 case 2336: 02766 return 35; 02767 case 2418: 02768 return 36; 02769 case 2503: 02770 return 37; 02771 } 02772 return -1; 02773 }
| static int retrieve_astcfgint | ( | char * | category, | |
| char * | name, | |||
| int | min, | |||
| int | max, | |||
| int | defl | |||
| ) | [static] |
Definition at line 776 of file app_rpt.c.
References ast_variable_retrieve(), myatoi(), and var.
Referenced by get_wait_interval(), rpt_master(), and telem_any().
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 }
| static int rmt_saycharstr | ( | struct rpt * | myrpt, | |
| struct ast_channel * | chan, | |||
| int | delay, | |||
| char * | charstr | |||
| ) | [static] |
Definition at line 3599 of file app_rpt.c.
References rmt_telem_finish(), rmt_telem_start(), and saycharstr().
Referenced by function_remote().
03600 { 03601 int res; 03602 03603 res = rmt_telem_start(myrpt, chan, delay); 03604 03605 if(!res) 03606 res = saycharstr(chan, charstr); 03607 03608 if(!res) 03609 res = rmt_telem_finish(myrpt, chan); 03610 return res; 03611 }
| static int rmt_sayfile | ( | struct rpt * | myrpt, | |
| struct ast_channel * | chan, | |||
| int | delay, | |||
| char * | filename | |||
| ) | [static] |
Definition at line 3585 of file app_rpt.c.
References rmt_telem_finish(), rmt_telem_start(), and sayfile().
Referenced by function_remote().
03586 { 03587 int res; 03588 03589 res = rmt_telem_start(myrpt, chan, delay); 03590 03591 if(!res) 03592 res = sayfile(chan, filename); 03593 03594 if(!res) 03595 res = rmt_telem_finish(myrpt, chan); 03596 return res; 03597 }
| static int rmt_telem_finish | ( | struct rpt * | myrpt, | |
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 3562 of file app_rpt.c.
References AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_channel::fds, rpt::remchannel, rpt::remoterx, and rpt::txchannel.
Referenced by function_remote(), handle_remote_data(), handle_remote_phone_dtmf(), rmt_saycharstr(), rmt_sayfile(), and rpt_exec().
03563 { 03564 03565 struct zt_params par; 03566 03567 if (ioctl(myrpt->txchannel->fds[0],ZT_GET_PARAMS,&par) == -1) 03568 { 03569 return -1; 03570 03571 } 03572 if (!par.rxisoffhook) 03573 { 03574 ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_UNKEY); 03575 myrpt->remoterx = 0; 03576 } 03577 else 03578 { 03579 myrpt->remoterx = 1; 03580 } 03581 return 0; 03582 }
| static int rmt_telem_start | ( | struct rpt * | myrpt, | |
| struct ast_channel * | chan, | |||
| int | delay | |||
| ) | [static] |
Definition at line 3550 of file app_rpt.c.
References AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_safe_sleep(), rpt::remoterx, rpt::remotetx, and rpt::txchannel.
Referenced by function_remote(), rmt_saycharstr(), and rmt_sayfile().
03551 { 03552 myrpt->remotetx = 0; 03553 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 03554 if (!myrpt->remoterx) 03555 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 03556 if (ast_safe_sleep(chan, delay) == -1) 03557 return -1; 03558 return 0; 03559 }
| static void* rpt | ( | void * | this | ) | [static] |
Definition at line 4528 of file app_rpt.c.
References ast_channel::_state, ast_channel::appl, ast_call(), ast_canmatch_extension(), ast_channel_setoption(), ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_exists_extension(), AST_FORMAT_SLINEAR, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frfree(), ast_hangup(), ast_indicate(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_RELAXDTMF, AST_OPTION_TONE_VERIFY, ast_pthread_create, AST_PTHREADT_STOP, ast_read(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_BUSY, AST_STATE_UP, ast_variable_retrieve(), ast_verbose(), ast_waitfor_n(), ast_write(), attempt_reconnect(), rpt::callmode, rpt_link::chan, rpt_tele::chan, rpt::cidx, rpt::cmdnode, collect_function_digits(), COMPLETE, rpt::conf, CONNECTED, rpt_link::connected, CONNFAIL, ast_frame::data, ast_channel::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, DISC_TIME, rpt_link::disced, rpt_link::disctime, rpt::disgorgetime, DTMF_TIMEOUT, rpt::dtmfbuf, rpt::dtmfidx, rpt_link::elaptime, rpt::enable, rpt::endchar, rpt::exten, rpt::exttx, ast_channel::fds, ast_frame::frametype, free, rpt::funcchar, handle_link_data(), handle_link_phone_dtmf(), rpt::hangtime, rpt_link::hasconnected, ID, IDTALKOVER, rpt::idtime, rpt::idtimer, rpt_link::isremote, rpt::keyed, rpt_link::killme, rpt_link::lastrx, rpt_link::lasttx, rpt::links, rpt::localtx, rpt::lock, LOG_NOTICE, LOG_WARNING, MAX_RETRIES, MAXCONNECTTIME, MAXDTMF, rpt_link::mode, rpt_tele::mode, MSWAIT, rpt::mustid, rpt::mydtmf, n, rpt_link::name, rpt::name, ast_channel::name, rpt_tele::next, rpt_link::next, option_verbose, rpt::ourcontext, rpt_link::outbound, rpt_link::pchan, rpt::pchannel, rpt_link::phonemode, rpt::politeid, rpt_link::prev, PROC, REDUNDANT_TX_TIME, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, REMDISC, rpt_link::retries, RETRY_TIMER_MS, rpt_link::retrytimer, rpt_link::retxtimer, rpt::retxtimer, rpt_call(), rpt::rpt_call_thread, rpt_telemetry(), rpt::rpt_thread, rpt::rxchanname, rpt::rxchannel, send_link_dtmf(), rpt::simple, SOURCE_RPT, rpt::stopgen, ast_frame::subclass, t, rpt::tailtimer, rpt::tele, TERM, TIMEOUT, rpt::tonotify, rpt::totime, rpt::totimer, rpt::tounkeyed, rpt::txchanname, rpt::txchannel, rpt::txconf, rpt::txpchannel, UNKEY, VERBOSE_PREFIX_3, and ast_channel::whentohangup.
04529 { 04530 struct rpt *myrpt = (struct rpt *)this; 04531 char *tele,*idtalkover; 04532 int ms = MSWAIT,lasttx=0,val,remrx=0,identqueued,nonidentqueued,res; 04533 struct ast_channel *who; 04534 ZT_CONFINFO ci; /* conference info */ 04535 time_t dtmf_time,t; 04536 struct rpt_link *l,*m; 04537 struct rpt_tele *telem; 04538 pthread_attr_t attr; 04539 char tmpstr[300]; 04540 char cmd[MAXDTMF+1] = ""; 04541 04542 04543 ast_mutex_lock(&myrpt->lock); 04544 strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1); 04545 tele = strchr(tmpstr,'/'); 04546 if (!tele) 04547 { 04548 fprintf(stderr,"rpt:Dial number (%s) must be in format tech/number\n",myrpt->rxchanname); 04549 ast_mutex_unlock(&myrpt->lock); 04550 myrpt->rpt_thread = AST_PTHREADT_STOP; 04551 pthread_exit(NULL); 04552 } 04553 *tele++ = 0; 04554 myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 04555 if (myrpt->rxchannel) 04556 { 04557 if (myrpt->rxchannel->_state == AST_STATE_BUSY) 04558 { 04559 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 04560 ast_mutex_unlock(&myrpt->lock); 04561 ast_hangup(myrpt->rxchannel); 04562 myrpt->rpt_thread = AST_PTHREADT_STOP; 04563 pthread_exit(NULL); 04564 } 04565 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 04566 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 04567 myrpt->rxchannel->whentohangup = 0; 04568 myrpt->rxchannel->appl = "Apprpt"; 04569 myrpt->rxchannel->data = "(Repeater Rx)"; 04570 if (option_verbose > 2) 04571 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 04572 tmpstr,tele,myrpt->rxchannel->name); 04573 ast_call(myrpt->rxchannel,tele,999); 04574 if (myrpt->rxchannel->_state != AST_STATE_UP) 04575 { 04576 ast_mutex_unlock(&myrpt->lock); 04577 ast_hangup(myrpt->rxchannel); 04578 myrpt->rpt_thread = AST_PTHREADT_STOP; 04579 pthread_exit(NULL); 04580 } 04581 } 04582 else 04583 { 04584 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 04585 ast_mutex_unlock(&myrpt->lock); 04586 myrpt->rpt_thread = AST_PTHREADT_STOP; 04587 pthread_exit(NULL); 04588 } 04589 if (myrpt->txchanname) 04590 { 04591 strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1); 04592 tele = strchr(tmpstr,'/'); 04593 if (!tele) 04594 { 04595 fprintf(stderr,"rpt:Dial number (%s) must be in format tech/number\n",myrpt->txchanname); 04596 ast_mutex_unlock(&myrpt->lock); 04597 ast_hangup(myrpt->rxchannel); 04598 myrpt->rpt_thread = AST_PTHREADT_STOP; 04599 pthread_exit(NULL); 04600 } 04601 *tele++ = 0; 04602 myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 04603 if (myrpt->txchannel) 04604 { 04605 if (myrpt->txchannel->_state == AST_STATE_BUSY) 04606 { 04607 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 04608 ast_mutex_unlock(&myrpt->lock); 04609 ast_hangup(myrpt->txchannel); 04610 ast_hangup(myrpt->rxchannel); 04611 myrpt->rpt_thread = AST_PTHREADT_STOP; 04612 pthread_exit(NULL); 04613 } 04614 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 04615 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 04616 myrpt->txchannel->whentohangup = 0; 04617 myrpt->txchannel->appl = "Apprpt"; 04618 myrpt->txchannel->data = "(Repeater Tx)"; 04619 if (option_verbose > 2) 04620 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 04621 tmpstr,tele,myrpt->txchannel->name); 04622 ast_call(myrpt->txchannel,tele,999); 04623 if (myrpt->rxchannel->_state != AST_STATE_UP) 04624 { 04625 ast_mutex_unlock(&myrpt->lock); 04626 ast_hangup(myrpt->rxchannel); 04627 ast_hangup(myrpt->txchannel); 04628 myrpt->rpt_thread = AST_PTHREADT_STOP; 04629 pthread_exit(NULL); 04630 } 04631 } 04632 else 04633 { 04634 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 04635 ast_mutex_unlock(&myrpt->lock); 04636 ast_hangup(myrpt->rxchannel); 04637 myrpt->rpt_thread = AST_PTHREADT_STOP; 04638 pthread_exit(NULL); 04639 } 04640 } 04641 else 04642 { 04643 myrpt->txchannel = myrpt->rxchannel; 04644 } 04645 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 04646 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 04647 /* allocate a pseudo-channel thru asterisk */ 04648 myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04649 if (!myrpt->pchannel) 04650 { 04651 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 04652 ast_mutex_unlock(&myrpt->lock); 04653 if (myrpt->txchannel != myrpt->rxchannel) 04654 ast_hangup(myrpt->txchannel); 04655 ast_hangup(myrpt->rxchannel); 04656 myrpt->rpt_thread = AST_PTHREADT_STOP; 04657 pthread_exit(NULL); 04658 } 04659 /* make a conference for the tx */ 04660 ci.chan = 0; 04661 ci.confno = -1; /* make a new conf */ 04662 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER; 04663 /* first put the channel on the conference in proper mode */ 04664 if (ioctl(myrpt->txchannel->fds[0],ZT_SETCONF,&ci) == -1) 04665 { 04666 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04667 ast_mutex_unlock(&myrpt->lock); 04668 ast_hangup(myrpt->pchannel); 04669 if (myrpt->txchannel != myrpt->rxchannel) 04670 ast_hangup(myrpt->txchannel); 04671 ast_hangup(myrpt->rxchannel); 04672 myrpt->rpt_thread = AST_PTHREADT_STOP; 04673 pthread_exit(NULL); 04674 } 04675 /* save tx conference number */ 04676 myrpt->txconf = ci.confno; 04677 /* make a conference for the pseudo */ 04678 ci.chan = 0; 04679 ci.confno = -1; /* make a new conf */ 04680 ci.confmode = ZT_CONF_CONFANNMON; 04681 /* first put the channel on the conference in announce mode */ 04682 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 04683 { 04684 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04685 ast_mutex_unlock(&myrpt->lock); 04686 ast_hangup(myrpt->pchannel); 04687 if (myrpt->txchannel != myrpt->rxchannel) 04688 ast_hangup(myrpt->txchannel); 04689 ast_hangup(myrpt->rxchannel); 04690 myrpt->rpt_thread = AST_PTHREADT_STOP; 04691 pthread_exit(NULL); 04692 } 04693 /* save pseudo channel conference number */ 04694 myrpt->conf = ci.confno; 04695 /* allocate a pseudo-channel thru asterisk */ 04696 myrpt->txpchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04697 if (!myrpt->txpchannel) 04698 { 04699 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 04700 ast_mutex_unlock(&myrpt->lock); 04701 ast_hangup(myrpt->pchannel); 04702 if (myrpt->txchannel != myrpt->rxchannel) 04703 ast_hangup(myrpt->txchannel); 04704 ast_hangup(myrpt->rxchannel); 04705 myrpt->rpt_thread = AST_PTHREADT_STOP; 04706 pthread_exit(NULL); 04707 } 04708 /* make a conference for the tx */ 04709 ci.chan = 0; 04710 ci.confno = myrpt->txconf; 04711 ci.confmode = ZT_CONF_CONF | ZT_CONF_TALKER ; 04712 /* first put the channel on the conference in proper mode */ 04713 if (ioctl(myrpt->txpchannel->fds[0],ZT_SETCONF,&ci) == -1) 04714 { 04715 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04716 ast_mutex_unlock(&myrpt->lock); 04717 ast_hangup(myrpt->txpchannel); 04718 ast_hangup(myrpt->pchannel); 04719 if (myrpt->txchannel != myrpt->rxchannel) 04720 ast_hangup(myrpt->txchannel); 04721 ast_hangup(myrpt->rxchannel); 04722 myrpt->rpt_thread = AST_PTHREADT_STOP; 04723 pthread_exit(NULL); 04724 } 04725 /* Now, the idea here is to copy from the physical rx channel buffer 04726 into the pseudo tx buffer, and from the pseudo rx buffer into the 04727 tx channel buffer */ 04728 myrpt->links.next = &myrpt->links; 04729 myrpt->links.prev = &myrpt->links; 04730 myrpt->tailtimer = 0; 04731 myrpt->totimer = 0; 04732 myrpt->idtimer = myrpt->politeid; 04733 myrpt->mustid = 0; 04734 myrpt->callmode = 0; 04735 myrpt->tounkeyed = 0; 04736 myrpt->tonotify = 0; 04737 myrpt->retxtimer = 0; 04738 lasttx = 0; 04739 myrpt->keyed = 0; 04740 idtalkover = ast_variable_retrieve(cfg, myrpt->name, "idtalkover"); 04741 myrpt->dtmfidx = -1; 04742 myrpt->dtmfbuf[0] = 0; 04743 myrpt->rem_dtmfidx = -1; 04744 myrpt->rem_dtmfbuf[0] = 0; 04745 dtmf_time = 0; 04746 myrpt->rem_dtmf_time = 0; 04747 myrpt->enable = 1; 04748 myrpt->disgorgetime = 0; 04749 ast_mutex_unlock(&myrpt->lock); 04750 val = 0; 04751 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0); 04752 val = 1; 04753 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0); 04754 while (ms >= 0) 04755 { 04756 struct ast_frame *f; 04757 struct ast_channel *cs[300]; 04758 int totx=0,elap=0,n,toexit=0; 04759 04760 /* DEBUG Dump */ 04761 if((myrpt->disgorgetime) && (time(NULL) >= myrpt->disgorgetime)){ 04762 struct rpt_link *zl; 04763 struct rpt_tele *zt; 04764 04765 myrpt->disgorgetime = 0; 04766 ast_log(LOG_NOTICE,"********** Variable Dump Start (app_rpt) **********\n"); 04767 ast_log(LOG_NOTICE,"totx = %d\n",totx); 04768 ast_log(LOG_NOTICE,"remrx = %d\n",remrx); 04769 ast_log(LOG_NOTICE,"lasttx = %d\n",lasttx); 04770 ast_log(LOG_NOTICE,"elap = %d\n",elap); 04771 ast_log(LOG_NOTICE,"toexit = %d\n",toexit); 04772 04773 ast_log(LOG_NOTICE,"myrpt->keyed = %d\n",myrpt->keyed); 04774 ast_log(LOG_NOTICE,"myrpt->localtx = %d\n",myrpt->localtx); 04775 ast_log(LOG_NOTICE,"myrpt->callmode = %d\n",myrpt->callmode); 04776 ast_log(LOG_NOTICE,"myrpt->enable = %d\n",myrpt->enable); 04777 ast_log(LOG_NOTICE,"myrpt->mustid = %d\n",myrpt->mustid); 04778 ast_log(LOG_NOTICE,"myrpt->tounkeyed = %d\n",myrpt->tounkeyed); 04779 ast_log(LOG_NOTICE,"myrpt->tonotify = %d\n",myrpt->tonotify); 04780 ast_log(LOG_NOTICE,"myrpt->retxtimer = %ld\n",myrpt->retxtimer); 04781 ast_log(LOG_NOTICE,"myrpt->totimer = %d\n",myrpt->totimer); 04782 ast_log(LOG_NOTICE,"myrpt->tailtimer = %d\n",myrpt->tailtimer); 04783 04784 zl = myrpt->links.next; 04785 while(zl != &myrpt->links){ 04786 ast_log(LOG_NOTICE,"*** Link Name: %s ***\n",zl->name); 04787 ast_log(LOG_NOTICE," link->lasttx %d\n",zl->lasttx); 04788 ast_log(LOG_NOTICE," link->lastrx %d\n",zl->lastrx); 04789 ast_log(LOG_NOTICE," link->connected %d\n",zl->connected); 04790 ast_log(LOG_NOTICE," link->hasconnected %d\n",zl->hasconnected); 04791 ast_log(LOG_NOTICE," link->outbound %d\n",zl->outbound); 04792 ast_log(LOG_NOTICE," link->disced %d\n",zl->disced); 04793 ast_log(LOG_NOTICE," link->killme %d\n",zl->killme); 04794 ast_log(LOG_NOTICE," link->disctime %ld\n",zl->disctime); 04795 ast_log(LOG_NOTICE," link->retrytimer %ld\n",zl->retrytimer); 04796 ast_log(LOG_NOTICE," link->retries = %d\n",zl->retries); 04797 04798 zl = zl->next; 04799 } 04800 04801 zt = myrpt->tele.next; 04802 if(zt != &myrpt->tele) 04803 ast_log(LOG_NOTICE,"*** Telemetry Queue ***\n"); 04804 while(zt != &myrpt->tele){ 04805 ast_log(LOG_NOTICE," Telemetry mode: %d\n",zt->mode); 04806 zt = zt->next; 04807 } 04808 ast_log(LOG_NOTICE,"******* Variable Dump End (app_rpt) *******\n"); 04809 04810 } 04811 04812 04813 04814 04815 04816 ast_mutex_lock(&myrpt->lock); 04817 if (ast_check_hangup(myrpt->rxchannel)) break; 04818 if (ast_check_hangup(myrpt->txchannel)) break; 04819 if (ast_check_hangup(myrpt->pchannel)) break; 04820 if (ast_check_hangup(myrpt->txpchannel)) break; 04821 myrpt->localtx = myrpt->keyed && (myrpt->dtmfidx == -1) && (!myrpt->cmdnode[0]); 04822 04823 /* If someone's connected, and they're transmitting from their end to us, set remrx true */ 04824 04825 l = myrpt->links.next; 04826 remrx = 0; 04827 while(l != &myrpt->links) 04828 { 04829 if (l->lastrx) remrx = 1; 04830 l = l->next; 04831 } 04832 04833 /* Create a "must_id" flag for the cleanup ID */ 04834 04835 myrpt->mustid |= (myrpt->idtimer) && (myrpt->keyed || remrx) ; 04836 04837 /* Build a fresh totx from myrpt->keyed and autopatch activated */ 04838 04839 totx = myrpt->localtx || myrpt->callmode; 04840 04841 /* Traverse the telemetry list to see if there's an ID queued and if there is not an ID queued */ 04842 04843 identqueued = 0; 04844 nonidentqueued = 0; 04845 04846 telem = myrpt->tele.next; 04847 while(telem != &myrpt->tele) 04848 { 04849 if((telem->mode == ID) || (telem->mode == IDTALKOVER)){ 04850 identqueued = 1; 04851 } 04852 else 04853 nonidentqueued = 1; 04854 telem = telem->next; 04855 } 04856 04857 /* Add in any non-id telemetry */ 04858 04859 totx = totx || nonidentqueued; 04860 04861 /* Update external transmitter PTT state with everything but ID telemetry */ 04862 04863 myrpt->exttx = totx; 04864 04865 /* Add in ID telemetry to local transmitter */ 04866 04867 totx = totx || remrx || identqueued; 04868 04869 if (!totx) 04870 { 04871 myrpt->totimer = myrpt->totime; 04872 myrpt->tounkeyed = 0; 04873 myrpt->tonotify = 0; 04874 } 04875 else myrpt->tailtimer = myrpt->hangtime; 04876 totx = totx && myrpt->totimer; 04877 /* if timed-out and not said already, say it */ 04878 if ((!myrpt->totimer) && (!myrpt->tonotify)) 04879 { 04880 myrpt->tonotify = 1; 04881 ast_mutex_unlock(&myrpt->lock); 04882 rpt_telemetry(myrpt,TIMEOUT,NULL); 04883 ast_mutex_lock(&myrpt->lock); 04884 } 04885 /* if wants to transmit and in phone call, but timed out, 04886 reset time-out timer if keyed */ 04887 if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!myrpt->keyed)) 04888 { 04889 myrpt->tounkeyed = 1; 04890 } 04891 if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->keyed) 04892 { 04893 myrpt->totimer = myrpt->totime; 04894 myrpt->tounkeyed = 0; 04895 myrpt->tonotify = 0; 04896 ast_mutex_unlock(&myrpt->lock); 04897 continue; 04898 } 04899 /* if timed-out and in circuit busy after call */ 04900 if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4)) 04901 { 04902 myrpt->callmode = 0; 04903 } 04904 /* get rid of tail if timed out */ 04905 if (!myrpt->totimer) myrpt->tailtimer = 0; 04906 /* if not timed-out, add in tail */ 04907 if (myrpt->totimer) totx = totx || myrpt->tailtimer; 04908 /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */ 04909 if (identqueued && (myrpt->keyed || remrx) && idtalkover) { 04910 int hasid = 0,hastalkover = 0; 04911 04912 telem = myrpt->tele.next; 04913 while(telem != &myrpt->tele){ 04914 if(telem->mode == ID){ 04915 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 04916 hasid = 1; 04917 } 04918 if (telem->mode == IDTALKOVER) hastalkover = 1; 04919 telem = telem->next; 04920 } 04921 ast_mutex_unlock(&myrpt->lock); 04922 if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */ 04923 ast_mutex_lock(&myrpt->lock); 04924 } 04925 /* Try to be polite */ 04926 /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/ 04927 /* If within 30 seconds of the time to ID, try do it in the tail */ 04928 /* else if at ID time limit, do it right over the top of them */ 04929 /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */ 04930 if (((totx && (!myrpt->exttx) && (myrpt->idtimer <= myrpt->politeid) && myrpt->tailtimer)) || 04931 (myrpt->mustid && (!myrpt->idtimer))) 04932 { 04933 myrpt->mustid = 0; 04934 myrpt->idtimer = myrpt->idtime; /* Reset our ID timer */ 04935 ast_mutex_unlock(&myrpt->lock); 04936 rpt_telemetry(myrpt,ID,NULL); 04937 ast_mutex_lock(&myrpt->lock); 04938 } 04939 /* let telemetry transmit anyway (regardless of timeout) */ 04940 totx = totx || (myrpt->tele.next != &myrpt->tele); 04941 if (totx && (!lasttx)) 04942 { 04943 lasttx = 1; 04944 ast_mutex_unlock(&myrpt->lock); 04945 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 04946 ast_mutex_lock(&myrpt->lock); 04947 } 04948 totx = totx && myrpt->enable; 04949 if ((!totx) && lasttx) 04950 { 04951 lasttx = 0; 04952 ast_mutex_unlock(&myrpt->lock); 04953 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 04954 ast_mutex_lock(&myrpt->lock); 04955 } 04956 time(&t); 04957 /* if DTMF timeout */ 04958 if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((dtmf_time + DTMF_TIMEOUT) < t)) 04959 { 04960 myrpt->dtmfidx = -1; 04961 myrpt->dtmfbuf[0] = 0; 04962 } 04963 /* if remote DTMF timeout */ 04964 if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t)) 04965 { 04966 myrpt->rem_dtmfidx = -1; 04967 myrpt->rem_dtmfbuf[0] = 0; 04968 } 04969 04970 /* Reconnect kludge */ 04971 l = myrpt->links.next; 04972 while(l != &myrpt->links) 04973 { 04974 if (l->killme) 04975 { 04976 /* remove from queue */ 04977 remque((struct qelem *) l); 04978 if (!strcmp(myrpt->cmdnode,l->name)) 04979 myrpt->cmdnode[0] = 0; 04980 ast_mutex_unlock(&myrpt->lock); 04981 /* hang-up on call to device */ 04982 if (l->chan) ast_hangup(l->chan); 04983 ast_hangup(l->pchan); 04984 free(l); 04985 ast_mutex_lock(&myrpt->lock); 04986 /* re-start link traversal */ 04987 l = myrpt->links.next; 04988 continue; 04989 } 04990 l = l->next; 04991 } 04992 n = 0; 04993 cs[n++] = myrpt->rxchannel; 04994 cs[n++] = myrpt->pchannel; 04995 cs[n++] = myrpt->txpchannel; 04996 if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel; 04997 l = myrpt->links.next; 04998 while(l != &myrpt->links) 04999 { 05000 if ((!l->killme) && (!l->disctime) && l->chan) 05001 { 05002 cs[n++] = l->chan; 05003 cs[n++] = l->pchan; 05004 } 05005 l = l->next; 05006 } 05007 ast_mutex_unlock(&myrpt->lock); 05008 ms = MSWAIT; 05009 who = ast_waitfor_n(cs,n,&ms); 05010 if (who == NULL) ms = 0; 05011 elap = MSWAIT - ms; 05012 ast_mutex_lock(&myrpt->lock); 05013 l = myrpt->links.next; 05014 while(l != &myrpt->links) 05015 { 05016 if (!l->lasttx) 05017 { 05018 if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME) 05019 { 05020 l->retxtimer = 0; 05021 if (l->chan) ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 05022 } 05023 } else l->retxtimer = 0; 05024 #ifdef RECONNECT_KLUDGE 05025 if (l->disctime) /* Disconnect timer active on a channel ? */ 05026 { 05027 l->disctime -= elap; 05028 if (l->disctime <= 0) /* Disconnect timer expired on inbound channel ? */ 05029 l->disctime = 0; /* Yep */ 05030 } 05031 05032 if (l->retrytimer) 05033 { 05034 l->retrytimer -= elap; 05035 if (l->retrytimer < 0) l->retrytimer = 0; 05036 } 05037 #endif 05038 /* ignore non-timing channels */ 05039 if (l->elaptime < 0) 05040 { 05041 l = l->next; 05042 continue; 05043 } 05044 l->elaptime += elap; 05045 /* if connection has taken too long */ 05046 if ((l->elaptime > MAXCONNECTTIME) && 05047 ((!l->chan) || (l->chan->_state != AST_STATE_UP))) 05048 { 05049 l->elaptime = 0; 05050 ast_mutex_unlock(&myrpt->lock); 05051 if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 05052 #ifndef RECONNECT_KLUDGE 05053 rpt_telemetry(myrpt,CONNFAIL,l); 05054 #endif 05055 ast_mutex_lock(&myrpt->lock); 05056 break; 05057 } 05058 #ifdef RECONNECT_KLUDGE 05059 if ((!l->chan) && (!l->retrytimer) && l->outbound && 05060 (l->retries++ < MAX_RETRIES) && (l->hasconnected)) 05061 { 05062 if (l->chan) ast_hangup(l->chan); 05063 ast_mutex_unlock(&myrpt->lock); 05064 if ((l->name[0] != '0') && (!l->isremote)) 05065 { 05066 l->retrytimer = MAX_RETRIES + 1; 05067 } 05068 else 05069 { 05070 if (attempt_reconnect(myrpt,l) == -1) 05071 { 05072 l->retrytimer = RETRY_TIMER_MS; 05073 } 05074 } 05075 ast_mutex_lock(&myrpt->lock); 05076 break; 05077 } 05078 if ((!l->chan) && (!l->retrytimer) && l->outbound && 05079 (l->retries >= MAX_RETRIES)) 05080 { 05081 /* remove from queue */ 05082 remque((struct qelem *) l); 05083 if (!strcmp(myrpt->cmdnode,l->name)) 05084 myrpt->cmdnode[0] = 0; 05085 ast_mutex_unlock(&myrpt->lock); 05086 if (l->name[0] != '0') 05087 { 05088 if (!l->hasconnected) 05089 rpt_telemetry(myrpt,CONNFAIL,l); 05090 else rpt_telemetry(myrpt,REMDISC,l); 05091 } 05092 /* hang-up on call to device */ 05093 ast_hangup(l->pchan); 05094 free(l); 05095 ast_mutex_lock(&myrpt->lock); 05096 break; 05097 } 05098 if ((!l->chan) && (!l->disctime) && (!l->outbound)) 05099 { 05100 /* remove from queue */ 05101 remque((struct qelem *) l); 05102 if (!strcmp(myrpt->cmdnode,l->name)) 05103 myrpt->cmdnode[0] = 0; 05104 ast_mutex_unlock(&myrpt->lock); 05105 if (l->name[0] != '0') 05106 { 05107 rpt_telemetry(myrpt,REMDISC,l); 05108 } 05109 /* hang-up on call to device */ 05110 ast_hangup(l->pchan); 05111 free(l); 05112 ast_mutex_lock(&myrpt->lock); 05113 break; 05114 } 05115 #endif 05116 l = l->next; 05117 } 05118 if (myrpt->tailtimer) myrpt->tailtimer -= elap; 05119 if (myrpt->tailtimer < 0) myrpt->tailtimer = 0; 05120 if (myrpt->totimer) myrpt->totimer -= elap; 05121 if (myrpt->totimer < 0) myrpt->totimer = 0; 05122 if (myrpt->idtimer) myrpt->idtimer -= elap; 05123 if (myrpt->idtimer < 0) myrpt->idtimer = 0; 05124 ast_mutex_unlock(&myrpt->lock); 05125 if (!ms) continue; 05126 if (who == myrpt->rxchannel) /* if it was a read from rx */ 05127 { 05128 f = ast_read(myrpt->rxchannel); 05129 if (!f) 05130 { 05131 if (debug) printf("@@@@ rpt:Hung Up\n"); 05132 break; 05133 } 05134 if (f->frametype == AST_FRAME_VOICE) 05135 { 05136 if (!myrpt->localtx) 05137 memset(f->data,0,f->datalen); 05138 ast_write(myrpt->pchannel,f); 05139 } 05140 else if (f->frametype == AST_FRAME_DTMF) 05141 { 05142 char c; 05143 05144 c = (char) f->subclass; /* get DTMF char */ 05145 ast_frfree(f); 05146 if (!myrpt->keyed) continue; 05147 if (c == myrpt->endchar) 05148 { 05149 /* if in simple mode, kill autopatch */ 05150 if (myrpt->simple && myrpt->callmode) 05151 { 05152 ast_mutex_lock(&myrpt->lock); 05153 myrpt->callmode = 0; 05154 ast_mutex_unlock(&myrpt->lock); 05155 rpt_telemetry(myrpt,TERM,NULL); 05156 continue; 05157 } 05158 ast_mutex_lock(&myrpt->lock); 05159 myrpt->stopgen = 1; 05160 if (myrpt->cmdnode[0]) 05161 { 05162 myrpt->cmdnode[0] = 0; 05163 myrpt->dtmfidx = -1; 05164 myrpt->dtmfbuf[0] = 0; 05165 ast_mutex_unlock(&myrpt->lock); 05166 rpt_telemetry(myrpt,COMPLETE,NULL); 05167 } else ast_mutex_unlock(&myrpt->lock); 05168 continue; 05169 } 05170 ast_mutex_lock(&myrpt->lock); 05171 if (myrpt->cmdnode[0]) 05172 { 05173 ast_mutex_unlock(&myrpt->lock); 05174 send_link_dtmf(myrpt,c); 05175 continue; 05176 } 05177 if (!myrpt->simple) 05178 { 05179 if (c == myrpt->funcchar) 05180 { 05181 myrpt->dtmfidx = 0; 05182 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 05183 ast_mutex_unlock(&myrpt->lock); 05184 time(&dtmf_time); 05185 continue; 05186 } 05187 else if ((c != myrpt->endchar) && (myrpt->dtmfidx >= 0)) 05188 { 05189 time(&dtmf_time); 05190 05191 if (myrpt->dtmfidx < MAXDTMF) 05192 { 05193 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 05194 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 05195 05196 strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1); 05197 05198 ast_mutex_unlock(&myrpt->lock); 05199 res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL); 05200 ast_mutex_lock(&myrpt->lock); 05201 05202 switch(res){ 05203 05204 case DC_INDETERMINATE: 05205 break; 05206 05207 case DC_REQ_FLUSH: 05208 myrpt->dtmfidx = 0; 05209 myrpt->dtmfbuf[0] = 0; 05210 break; 05211 05212 05213 case DC_COMPLETE: 05214 myrpt->dtmfbuf[0] = 0; 05215 myrpt->dtmfidx = -1; 05216 dtmf_time = 0; 05217 break; 05218 05219 case DC_ERROR: 05220 default: 05221 myrpt->dtmfbuf[0] = 0; 05222 myrpt->dtmfidx = -1; 05223 dtmf_time = 0; 05224 break; 05225 } 05226 if(res != DC_INDETERMINATE) { 05227 ast_mutex_unlock(&myrpt->lock); 05228 continue; 05229 } 05230 } 05231 } 05232 } 05233 else /* if simple */ 05234 { 05235 if ((!myrpt->callmode) && (c == myrpt->funcchar)) 05236 { 05237 myrpt->callmode = 1; 05238 myrpt->cidx = 0; 05239 myrpt->exten[myrpt->cidx] = 0; 05240 ast_mutex_unlock(&myrpt->lock); 05241 pthread_attr_init(&attr); 05242 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05243 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt); 05244 pthread_attr_destroy(&attr); 05245 continue; 05246 } 05247 } 05248 if (myrpt->callmode == 1) 05249 { 05250 myrpt->exten[myrpt->cidx++] = c; 05251 myrpt->exten[myrpt->cidx] = 0; 05252 /* if this exists */ 05253 if (ast_exists_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) 05254 { 05255 myrpt->callmode = 2; 05256 ast_mutex_unlock(&myrpt->lock); 05257 rpt_telemetry(myrpt,PROC,NULL); 05258 continue; 05259 } 05260 /* if can continue, do so */ 05261 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->ourcontext,myrpt->exten,1,NULL)) 05262 { 05263 /* call has failed, inform user */ 05264 myrpt->callmode = 4; 05265 } 05266 ast_mutex_unlock(&myrpt->lock); 05267 continue; 05268 } 05269 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 05270 { 05271 myrpt->mydtmf = c; 05272 } 05273 ast_mutex_unlock(&myrpt->lock); 05274 continue; 05275 } 05276 else if (f->frametype == AST_FRAME_CONTROL) 05277 { 05278 if (f->subclass == AST_CONTROL_HANGUP) 05279 { 05280 if (debug) printf("@@@@ rpt:Hung Up\n"); 05281 ast_frfree(f); 05282 break; 05283 } 05284 /* if RX key */ 05285 if (f->subclass == AST_CONTROL_RADIO_KEY) 05286 { 05287 if (debug) printf("@@@@ rx key\n"); 05288 myrpt->keyed = 1; 05289 } 05290 /* if RX un-key */ 05291 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 05292 { 05293 if (debug) printf("@@@@ rx un-key\n"); 05294 if(myrpt->keyed) { 05295 rpt_telemetry(myrpt,UNKEY,NULL); 05296 } 05297 myrpt->keyed = 0; 05298 } 05299 } 05300 ast_frfree(f); 05301 continue; 05302 } 05303 if (who == myrpt->pchannel) /* if it was a read from pseudo */ 05304 { 05305 f = ast_read(myrpt->pchannel); 05306 if (!f) 05307 { 05308 if (debug) printf("@@@@ rpt:Hung Up\n"); 05309 break; 05310 } 05311 if (f->frametype == AST_FRAME_VOICE) 05312 { 05313 ast_write(myrpt->txpchannel,f); 05314 } 05315 if (f->frametype == AST_FRAME_CONTROL) 05316 { 05317 if (f->subclass == AST_CONTROL_HANGUP) 05318 { 05319 if (debug) printf("@@@@ rpt:Hung Up\n"); 05320 ast_frfree(f); 05321 break; 05322 } 05323 } 05324 ast_frfree(f); 05325 continue; 05326 } 05327 if (who == myrpt->txchannel) /* if it was a read from tx */ 05328 { 05329 f = ast_read(myrpt->txchannel); 05330 if (!f) 05331 { 05332 if (debug) printf("@@@@ rpt:Hung Up\n"); 05333 break; 05334 } 05335 if (f->frametype == AST_FRAME_CONTROL) 05336 { 05337 if (f->subclass == AST_CONTROL_HANGUP) 05338 { 05339 if (debug) printf("@@@@ rpt:Hung Up\n"); 05340 ast_frfree(f); 05341 break; 05342 } 05343 } 05344 ast_frfree(f); 05345 continue; 05346 } 05347 toexit = 0; 05348 ast_mutex_lock(&myrpt->lock); 05349 l = myrpt->links.next; 05350 while(l != &myrpt->links) 05351 { 05352 if (l->disctime) 05353 { 05354 l = l->next; 05355 continue; 05356 } 05357 if (who == l->chan) /* if it was a read from rx */ 05358 { 05359 remrx = 0; 05360 /* see if any other links are receiving */ 05361 m = myrpt->links.next; 05362 while(m != &myrpt->links) 05363 { 05364 /* if not us, count it */ 05365 if ((m != l) && (m->lastrx)) remrx = 1; 05366 m = m->next; 05367 } 05368 ast_mutex_unlock(&myrpt->lock); 05369 totx = (((l->isremote) ? myrpt->localtx : 05370 myrpt->exttx) || remrx) && l->mode; 05371 if (l->chan && (l->lasttx != totx)) 05372 { 05373 if (totx) 05374 { 05375 ast_indicate(l->chan,AST_CONTROL_RADIO_KEY); 05376 } 05377 else 05378 { 05379 ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 05380 } 05381 } 05382 l->lasttx = totx; 05383 f = ast_read(l->chan); 05384 if (!f) 05385 { 05386 #ifdef RECONNECT_KLUDGE 05387 if ((!l->disced) && (!l->outbound)) 05388 { 05389 if ((l->name[0] == '0') || l->isremote) 05390 l->disctime = 1; 05391 else 05392 l->disctime = DISC_TIME; 05393 ast_mutex_lock(&myrpt->lock); 05394 ast_hangup(l->chan); 05395 l->chan = 0; 05396 break; 05397 } 05398 05399 if (l->retrytimer) 05400 { 05401 ast_mutex_lock(&myrpt->lock); 05402 break; 05403 } 05404 if (l->outbound && (l->retries++ < MAX_RETRIES) && (l->hasconnected)) 05405 { 05406 ast_mutex_lock(&myrpt->lock); 05407 ast_hangup(l->chan); 05408 l->chan = 0; 05409 ast_mutex_unlock(&myrpt->lock); 05410 if (attempt_reconnect(myrpt,l) == -1) 05411 { 05412 l->retrytimer = RETRY_TIMER_MS; 05413 } 05414 ast_mutex_lock(&myrpt->lock); 05415 break; 05416 } 05417 #endif 05418 ast_mutex_lock(&myrpt->lock); 05419 /* remove from queue */ 05420 remque((struct qelem *) l); 05421 if (!strcmp(myrpt->cmdnode,l->name)) 05422 myrpt->cmdnode[0] = 0; 05423 ast_mutex_unlock(&myrpt->lock); 05424 if (!l->hasconnected) 05425 rpt_telemetry(myrpt,CONNFAIL,l); 05426 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 05427 /* hang-up on call to device */ 05428 ast_hangup(l->chan); 05429 ast_hangup(l->pchan); 05430 free(l); 05431 ast_mutex_lock(&myrpt->lock); 05432 break; 05433 } 05434 if (f->frametype == AST_FRAME_VOICE) 05435 { 05436 if (l->phonemode && (!l->lastrx)) 05437 { 05438 memset(f->data,0,f->datalen); 05439 } 05440 ast_write(l->pchan,f); 05441 } 05442 if (f->frametype == AST_FRAME_TEXT) 05443 { 05444 handle_link_data(myrpt,l,f->data); 05445 } 05446 if (f->frametype == AST_FRAME_DTMF) 05447 { 05448 handle_link_phone_dtmf(myrpt,l,f->subclass); 05449 } 05450 if (f->frametype == AST_FRAME_CONTROL) 05451 { 05452 if (f->subclass == AST_CONTROL_ANSWER) 05453 { 05454 char lconnected = l->connected; 05455 l->connected = 1; 05456 l->hasconnected = 1; 05457 l->elaptime = -1; 05458 l->retries = 0; 05459 if (!lconnected) rpt_telemetry(myrpt,CONNECTED,l); 05460 } 05461 /* if RX key */ 05462 if (f->subclass == AST_CONTROL_RADIO_KEY) 05463 { 05464 if (debug) printf("@@@@ rx key\n"); 05465 l->lastrx = 1; 05466 } 05467 /* if RX un-key */ 05468 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 05469 { 05470 if (debug) printf("@@@@ rx un-key\n"); 05471 l->lastrx = 0; 05472 } 05473 if (f->subclass == AST_CONTROL_HANGUP) 05474 { 05475 ast_frfree(f); 05476 #ifdef RECONNECT_KLUDGE 05477 if ((!l->outbound) && (!l->disced)) 05478 { 05479 if ((l->name[0] == '0') || l->isremote) 05480 l->disctime = 1; 05481 else 05482 l->disctime = DISC_TIME; 05483 ast_mutex_lock(&myrpt->lock); 05484 ast_hangup(l->chan); 05485 l->chan = 0; 05486 break; 05487 } 05488 if (l->retrytimer) 05489 { 05490 ast_mutex_lock(&myrpt->lock); 05491 break; 05492 } 05493 if (l->outbound && (l->retries++ < MAX_RETRIES) && (l->hasconnected)) 05494 { 05495 ast_mutex_lock(&myrpt->lock); 05496 ast_hangup(l->chan); 05497 l->chan = 0; 05498 ast_mutex_unlock(&myrpt->lock); 05499 if (attempt_reconnect(myrpt,l) == -1) 05500 { 05501 l->retrytimer = RETRY_TIMER_MS; 05502 } 05503 ast_mutex_lock(&myrpt->lock); 05504 break; 05505 } 05506 #endif 05507 ast_mutex_lock(&myrpt->lock); 05508 /* remove from queue */ 05509 remque((struct qelem *) l); 05510 if (!strcmp(myrpt->cmdnode,l->name)) 05511 myrpt->cmdnode[0] = 0; 05512 ast_mutex_unlock(&myrpt->lock); 05513 if (!l->hasconnected) 05514 rpt_telemetry(myrpt,CONNFAIL,l); 05515 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 05516 /* hang-up on call to device */ 05517 ast_hangup(l->chan); 05518 ast_hangup(l->pchan); 05519 free(l); 05520 ast_mutex_lock(&myrpt->lock); 05521 break; 05522 } 05523 } 05524 ast_frfree(f); 05525 ast_mutex_lock(&myrpt->lock); 05526 break; 05527 } 05528 if (who == l->pchan) 05529 { 05530 ast_mutex_unlock(&myrpt->lock); 05531 f = ast_read(l->pchan); 05532 if (!f) 05533 { 05534 if (debug) printf("@@@@ rpt:Hung Up\n"); 05535 toexit = 1; 05536 ast_mutex_lock(&myrpt->lock); 05537 break; 05538 } 05539 if (f->frametype == AST_FRAME_VOICE) 05540 { 05541 if (l->chan) ast_write(l->chan,f); 05542 } 05543 if (f->frametype == AST_FRAME_CONTROL) 05544 { 05545 if (f->subclass == AST_CONTROL_HANGUP) 05546 { 05547 if (debug) printf("@@@@ rpt:Hung Up\n"); 05548 ast_frfree(f); 05549 toexit = 1; 05550 ast_mutex_lock(&myrpt->lock); 05551 break; 05552 } 05553 } 05554 ast_frfree(f); 05555 ast_mutex_lock(&myrpt->lock); 05556 break; 05557 } 05558 l = l->next; 05559 } 05560 ast_mutex_unlock(&myrpt->lock); 05561 if (toexit) break; 05562 if (who == myrpt->txpchannel) /* if it was a read from remote tx */ 05563 { 05564 f = ast_read(myrpt->txpchannel); 05565 if (!f) 05566 { 05567 if (debug) printf("@@@@ rpt:Hung Up\n"); 05568 break; 05569 } 05570 if (f->frametype == AST_FRAME_CONTROL) 05571 { 05572 if (f->subclass == AST_CONTROL_HANGUP) 05573 { 05574 if (debug) printf("@@@@ rpt:Hung Up\n"); 05575 ast_frfree(f); 05576 break; 05577 } 05578 } 05579 ast_frfree(f); 05580 continue; 05581 } 05582 } 05583 usleep(100000); 05584 ast_hangup(myrpt->pchannel); 05585 ast_hangup(myrpt->txpchannel); 05586 if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel); 05587 ast_hangup(myrpt->rxchannel); 05588 ast_mutex_lock(&myrpt->lock); 05589 l = myrpt->links.next; 05590 while(l != &myrpt->links) 05591 { 05592 struct rpt_link *ll = l; 05593 /* remove from queue */ 05594 remque((struct qelem *) l); 05595 /* hang-up on call to device */ 05596 if (l->chan) ast_hangup(l->chan); 05597 ast_hangup(l->pchan); 05598 l = l->next; 05599 free(ll); 05600 } 05601 ast_mutex_unlock(&myrpt->lock); 05602 if (debug) printf("@@@@ rpt:Hung up channel\n"); 05603 myrpt->rpt_thread = AST_PTHREADT_STOP; 05604 pthread_exit(NULL); 05605 return NULL; 05606 }
| static void* rpt_call | ( | void * | this | ) | [static] |
Definition at line 1528 of file app_rpt.c.
References ast_channel::accountcode, rpt::acctcode, ast_callerid_parse(), ast_channel_undefer_dtmf(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_request(), ast_safe_sleep(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt::callmode, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, rpt::cidx, rpt::conf, ast_channel::context, ast_frame::data, ast_frame::datalen, rpt::exten, ast_channel::exten, ast_channel::fds, ast_frame::frametype, free, rpt::lock, LOG_WARNING, ast_frame::mallocd, MSWAIT, rpt::mydtmf, name, ast_frame::offset, rpt::ourcallerid, rpt::ourcontext, ast_channel::pbx, ast_channel::priority, ast_frame::samples, strdup, ast_frame::subclass, and rpt::tonezone.
Referenced by function_autopatchup(), and rpt().
01529 { 01530 ZT_CONFINFO ci; /* conference info */ 01531 struct rpt *myrpt = (struct rpt *)this; 01532 int res; 01533 struct ast_frame wf; 01534 int stopped,congstarted; 01535 struct ast_channel *mychannel,*genchannel; 01536 01537 myrpt->mydtmf = 0; 01538 /* allocate a pseudo-channel thru asterisk */ 01539 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 01540 if (!mychannel) 01541 { 01542 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 01543 pthread_exit(NULL); 01544 } 01545 ci.chan = 0; 01546 ci.confno = myrpt->conf; /* use the pseudo conference */ 01547 ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER 01548 | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01549 /* first put the channel on the conference */ 01550 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 01551 { 01552 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 01553 ast_hangup(mychannel); 01554 myrpt->callmode = 0; 01555 pthread_exit(NULL); 01556 } 01557 /* allocate a pseudo-channel thru asterisk */ 01558 genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 01559 if (!genchannel) 01560 { 01561 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 01562 ast_hangup(mychannel); 01563 pthread_exit(NULL); 01564 } 01565 ci.chan = 0; 01566 ci.confno = myrpt->conf; 01567 ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER 01568 | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 01569 /* first put the channel on the conference */ 01570 if (ioctl(genchannel->fds[0],ZT_SETCONF,&ci) == -1) 01571 { 01572 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 01573 ast_hangup(mychannel); 01574 ast_hangup(genchannel); 01575 myrpt->callmode = 0; 01576 pthread_exit(NULL); 01577 } 01578 if (myrpt->tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->tonezone) == -1)) 01579 { 01580 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->tonezone); 01581 ast_hangup(mychannel); 01582 ast_hangup(genchannel); 01583 myrpt->callmode = 0; 01584 pthread_exit(NULL); 01585 } 01586 if (myrpt->tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->tonezone) == -1)) 01587 { 01588 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->tonezone); 01589 ast_hangup(mychannel); 01590 ast_hangup(genchannel); 01591 myrpt->callmode = 0; 01592 pthread_exit(NULL); 01593 } 01594 /* start dialtone */ 01595 if (tone_zone_play_tone(mychannel->fds[0],ZT_TONE_DIALTONE) < 0) 01596 { 01597 ast_log(LOG_WARNING, "Cannot start dialtone\n"); 01598 ast_hangup(mychannel); 01599 ast_hangup(genchannel); 01600 myrpt->callmode = 0; 01601 pthread_exit(NULL); 01602 } 01603 stopped = 0; 01604 congstarted = 0; 01605 while ((myrpt->callmode == 1) || (myrpt->callmode == 4)) 01606 { 01607 01608 if ((myrpt->callmode == 1) && (myrpt->cidx > 0) && (!stopped)) 01609 { 01610 stopped = 1; 01611 /* stop dial tone */ 01612 tone_zone_play_tone(mychannel->fds[0],-1); 01613 } 01614 if ((myrpt->callmode == 4) && (!congstarted)) 01615 { 01616 congstarted = 1; 01617 /* start congestion tone */ 01618 tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION); 01619 } 01620 res = ast_safe_sleep(mychannel, MSWAIT); 01621 if (res < 0) 01622 { 01623 ast_hangup(mychannel); 01624 ast_hangup(genchannel); 01625 ast_mutex_lock(&myrpt->lock); 01626 myrpt->callmode = 0; 01627 ast_mutex_unlock(&myrpt->lock); 01628 pthread_exit(NULL); 01629 } 01630 } 01631 /* stop any tone generation */ 01632 tone_zone_play_tone(mychannel->fds[0],-1); 01633 /* end if done */ 01634 if (!myrpt->callmode) 01635 { 01636 ast_hangup(mychannel); 01637 ast_hangup(genchannel); 01638 ast_mutex_lock(&myrpt->lock); 01639 myrpt->callmode = 0; 01640 ast_mutex_unlock(&myrpt->lock); 01641 pthread_exit(NULL); 01642 } 01643 01644 if (myrpt->ourcallerid && *myrpt->ourcallerid){ 01645 char *name, *loc, *instr; 01646 instr = strdup(myrpt->ourcallerid); 01647 if(instr){ 01648 ast_callerid_parse(instr, &name, &loc); 01649 if(loc){ 01650 if(mychannel->cid.cid_num) 01651 free(mychannel->cid.cid_num); 01652 mychannel->cid.cid_num = strdup(loc); 01653 } 01654 if(name){ 01655 if(mychannel->cid.cid_name) 01656 free(mychannel->cid.cid_name); 01657 mychannel->cid.cid_name = strdup(name); 01658 } 01659 free(instr); 01660 } 01661 } 01662 01663 strncpy(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1); 01664 strncpy(mychannel->context, myrpt->ourcontext, sizeof(mychannel->context) - 1); 01665 if (myrpt->acctcode) 01666 strncpy(mychannel->accountcode, myrpt->acctcode, sizeof(mychannel->accountcode) - 1); 01667 mychannel->priority = 1; 01668 ast_channel_undefer_dtmf(mychannel); 01669 if (ast_pbx_start(mychannel) < 0) 01670 { 01671 ast_log(LOG_WARNING, "Unable to start PBX!!\n"); 01672 ast_hangup(mychannel); 01673 ast_hangup(genchannel); 01674 ast_mutex_lock(&myrpt->lock); 01675 myrpt->callmode = 0; 01676 ast_mutex_unlock(&myrpt->lock); 01677 pthread_exit(NULL); 01678 } 01679 usleep(10000); 01680 ast_mutex_lock(&myrpt->lock); 01681 myrpt->callmode = 3; 01682 while(myrpt->callmode) 01683 { 01684 if ((!mychannel->pbx) && (myrpt->callmode != 4)) 01685 { 01686 myrpt->callmode = 4; 01687 ast_mutex_unlock(&myrpt->lock); 01688 /* start congestion tone */ 01689 tone_zone_play_tone(genchannel->fds[0],ZT_TONE_CONGESTION); 01690 ast_mutex_lock(&myrpt->lock); 01691 } 01692 if (myrpt->mydtmf) 01693 { 01694 wf.frametype = AST_FRAME_DTMF; 01695 wf.subclass = myrpt->mydtmf; 01696 wf.offset = 0; 01697 wf.mallocd = 0; 01698 wf.data = NULL; 01699 wf.datalen = 0; 01700 wf.samples = 0; 01701 ast_mutex_unlock(&myrpt->lock); 01702 ast_write(genchannel,&wf); 01703 ast_mutex_lock(&myrpt->lock); 01704 myrpt->mydtmf = 0; 01705 } 01706 ast_mutex_unlock(&myrpt->lock); 01707 usleep(MSWAIT * 1000); 01708 ast_mutex_lock(&myrpt->lock); 01709 } 01710 ast_mutex_unlock(&myrpt->lock); 01711 tone_zone_play_tone(genchannel->fds[0],-1); 01712 if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV); 01713 ast_hangup(genchannel); 01714 ast_mutex_lock(&myrpt->lock); 01715 myrpt->callmode = 0; 01716 ast_mutex_unlock(&myrpt->lock); 01717 pthread_exit(NULL); 01718 }
| static int rpt_do_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 476 of file app_rpt.c.
References ast_cli(), myatoi(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
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 }
| static int rpt_exec | ( | struct ast_channel * | chan, | |
| void * | data | |||
| ) | [static] |
Definition at line 5834 of file app_rpt.c.
References ast_channel::_state, ahp, ast_channel::appl, ast_answer(), ast_call(), ast_callerid_parse(), ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_HANGUP, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_exists_extension(), AST_FORMAT_SLINEAR, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frfree(), ast_gethostbyname(), ast_hangup(), ast_indicate(), ast_inet_ntoa(), ast_log(), ast_masq_park_call(), ast_mutex_lock(), ast_mutex_unlock(), AST_PBX_KEEPALIVE, ast_read(), ast_request(), ast_safe_sleep(), ast_set_callerid(), ast_set_read_format(), ast_set_write_format(), ast_shrink_phone_number(), AST_STATE_UP, ast_strlen_zero(), ast_variable_retrieve(), ast_verbose(), ast_waitfor_n(), ast_write(), rpt::callmode, ast_channel::cid, ast_callerid::cid_num, closerem(), rpt::conf, ast_channel::context, context, ast_frame::data, ast_channel::data, ast_frame::datalen, rpt_link::disced, rpt::dtmf_time_rem, rpt::dtmfbuf, rpt::dtmfidx, ast_channel::exten, exten, ast_channel::fds, ast_frame::frametype, free, handle_remote_data(), handle_remote_phone_dtmf(), rpt::hfscanmode, rpt::hfscanstatus, hp, rpt::iobase, rpt_link::killme, rpt::links, LOCAL_USER_ADD, LOCAL_USER_REMOVE, rpt::lock, LOG_WARNING, malloc, MAX_RETRIES, MAXNODESTR, MSWAIT, n, rpt_link::name, rpt::name, ast_channel::name, name, rpt_link::next, rpt::nobusyout, rpt::nodes, option_verbose, pbx_substitute_variables_helper(), play_tone(), ast_channel::priority, REDUNDANT_TX_TIME, REM_MODE_AM, REM_SCANTIME, rpt::remchannel, rpt::remote, rpt::remoteon, rpt::remoterx, rpt::remotetx, rpt_link::retries, rpt::retxtimer, REV_PATCH, rmt_telem_finish(), rpt_telemetry(), rpt_vars, rpt::rxchanname, rpt::rxchannel, s, sayfile(), saynum(), rpt::scantimer, service_scan(), set_mode_ft897(), setrem(), simple_command_ft897(), strsep(), ast_frame::subclass, rpt::tunerequest, rpt::txchanname, rpt::txchannel, VERBOSE_PREFIX_3, and ast_channel::whentohangup.
Referenced by load_module().
05835 { 05836 int res=-1,i,rem_totx,n,phone_mode = 0; 05837 struct localuser *u; 05838 char tmp[256], keyed = 0; 05839 char *options,*stringp,*tele; 05840 struct rpt *myrpt; 05841 struct ast_frame *f; 05842 struct ast_channel *who; 05843 struct ast_channel *cs[20]; 05844 struct rpt_link *l; 05845 ZT_CONFINFO ci; /* conference info */ 05846 ZT_PARAMS par; 05847 int ms,elap; 05848 05849 if (ast_strlen_zero(data)) { 05850 ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n"); 05851 return -1; 05852 } 05853 strncpy(tmp, (char *)data, sizeof(tmp)-1); 05854 stringp=tmp; 05855 strsep(&stringp, "|"); 05856 options = stringp; 05857 myrpt = NULL; 05858 /* see if we can find our specified one */ 05859 for(i = 0; i < nrpts; i++) 05860 { 05861 /* if name matches, assign it and exit loop */ 05862 if (!strcmp(tmp,rpt_vars[i].name)) 05863 { 05864 myrpt = &rpt_vars[i]; 05865 break; 05866 } 05867 } 05868 if (myrpt == NULL) 05869 { 05870 ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp); 05871 return -1; 05872 } 05873 05874 /* if not phone access, must be an IAX connection */ 05875 if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R'))) 05876 { 05877 phone_mode = 1; 05878 if (*options == 'D') phone_mode = 2; 05879 ast_set_callerid(chan,"0","app_rpt user","0"); 05880 } 05881 else 05882 { 05883 if (strncmp(chan->name,"IAX2",4)) 05884 { 05885 ast_log(LOG_WARNING, "We only accept links via IAX2!!\n"); 05886 return -1; 05887 } 05888 } 05889 if (options && (*options == 'R')) 05890 { 05891 05892 /* Parts of this section taken from app_parkandannounce */ 05893 char *return_context; 05894 int l, m, lot, timeout = 0; 05895 char tmp[256],*template; 05896 char *working, *context, *exten, *priority; 05897 char *s,*orig_s; 05898 05899 05900 ast_mutex_lock(&myrpt->lock); 05901 m = myrpt->callmode; 05902 ast_mutex_unlock(&myrpt->lock); 05903 05904 if ((!myrpt->nobusyout) && m) 05905 { 05906 if (chan->_state != AST_STATE_UP) 05907 { 05908 ast_indicate(chan,AST_CONTROL_BUSY); 05909 } 05910 while(ast_safe_sleep(chan,10000) != -1); 05911 return -1; 05912 } 05913 05914 if (chan->_state != AST_STATE_UP) 05915 { 05916 ast_answer(chan); 05917 } 05918 05919 l=strlen(options)+2; 05920 orig_s=malloc(l); 05921 if(!orig_s) { 05922 ast_log(LOG_WARNING, "Out of memory\n"); 05923 return -1; 05924 } 05925 s=orig_s; 05926 strncpy(s,options,l); 05927 05928 template=strsep(&s,"|"); 05929 if(!template) { 05930 ast_log(LOG_WARNING, "An announce template must be defined\n"); 05931 free(orig_s); 05932 return -1; 05933 } 05934 05935 if(s) { 05936 timeout = atoi(strsep(&s, "|")); 05937 timeout *= 1000; 05938 } 05939 05940 return_context = s; 05941 05942 if(return_context != NULL) { 05943 /* set the return context. Code borrowed from the Goto builtin */ 05944 05945 working = return_context; 05946 context = strsep(&working, "|"); 05947 exten = strsep(&working, "|"); 05948 if(!exten) { 05949 /* Only a priority in this one */ 05950 priority = context; 05951 exten = NULL; 05952 context = NULL; 05953 } else { 05954 priority = strsep(&working, "|"); 05955 if(!priority) { 05956 /* Only an extension and priority in this one */ 05957 priority = exten; 05958 exten = context; 05959 context = NULL; 05960 } 05961 } 05962 if(atoi(priority) < 0) { 05963 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority); 05964 free(orig_s); 05965 return -1; 05966 } 05967 /* At this point we have a priority and maybe an extension and a context */ 05968 chan->priority = atoi(priority); 05969 if(exten && strcasecmp(exten, "BYEXTENSION")) 05970 strncpy(chan->exten, exten, sizeof(chan->exten)-1); 05971 if(context) 05972 strncpy(chan->context, context, sizeof(chan->context)-1); 05973 } else { /* increment the priority by default*/ 05974 chan->priority++; 05975 } 05976 05977 if(option_verbose > 2) { 05978 ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num); 05979 if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 05980 ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n"); 05981 } 05982 } 05983 05984 /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout 05985 before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */ 05986 05987 ast_masq_park_call(chan, NULL, timeout, &lot); 05988 05989 if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context); 05990 05991 snprintf(tmp,sizeof(tmp) - 1,"%d,%s",lot,template + 1); 05992 05993 rpt_telemetry(myrpt,REV_PATCH,tmp); 05994 05995 free(orig_s); 05996 05997 return 0; 05998 05999 } 06000 06001 if (!options) 06002 { 06003 struct ast_hostent ahp; 06004 struct hostent *hp; 06005 struct in_addr ia; 06006 char hisip[100],nodeip[100],*val, *s, *s1, *s2, *b,*b1; 06007 06008 /* look at callerid to see what node this comes from */ 06009 if (!chan->cid.cid_num) /* if doesn't have caller id */ 06010 { 06011 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 06012 return -1; 06013 } 06014 06015 /* get his IP from IAX2 module */ 06016 memset(hisip,0,sizeof(hisip)); 06017 pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1); 06018 if (!hisip[0]) 06019 { 06020 ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n"); 06021 return -1; 06022 } 06023 06024 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 06025 ast_shrink_phone_number(b1); 06026 if (!strcmp(myrpt->name,b1)) 06027 { 06028 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 06029 return -1; 06030 } 06031 06032 if (*b1 < '1') 06033 { 06034 ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1); 06035 return -1; 06036 } 06037 06038 06039 /* look for his reported node string */ 06040 val = ast_variable_retrieve(cfg, myrpt->nodes, b1); 06041 if (!val) 06042 { 06043 ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1); 06044 return -1; 06045 } 06046 strncpy(tmp,val,sizeof(tmp) - 1); 06047 s = tmp; 06048 s1 = strsep(&s,","); 06049 s2 = strsep(&s,","); 06050 if (!s2) 06051 { 06052 ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1); 06053 return -1; 06054 } 06055 if (strcmp(s2,"NONE")) { 06056 hp = ast_gethostbyname(s2, &ahp); 06057 if (!hp) 06058 { 06059 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2); 06060 return -1; 06061 } 06062 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 06063 ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia); 06064 if (strcmp(hisip,nodeip)) 06065 { 06066 char *s3 = strchr(s1,'@'); 06067 if (s3) s1 = s3 + 1; 06068 s3 = strchr(s1,'/'); 06069 if (s3) *s3 = 0; 06070 hp = ast_gethostbyname(s1, &ahp); 06071 if (!hp) 06072 { 06073 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1); 06074 return -1; 06075 } 06076 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 06077 ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia); 06078 if (strcmp(hisip,nodeip)) 06079 { 06080 ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip); 06081 return -1; 06082 } 06083 } 06084 } 06085 } 06086 06087 /* if is not a remote */ 06088 if (!myrpt->remote) 06089 { 06090 06091 char *b,*b1; 06092 06093 /* look at callerid to see what node this comes from */ 06094 if (!chan->cid.cid_num) /* if doesn't have caller id */ 06095 { 06096 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 06097 return -1; 06098 } 06099 06100 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 06101 ast_shrink_phone_number(b1); 06102 if (!strcmp(myrpt->name,b1)) 06103 { 06104 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 06105 return -1; 06106 } 06107 ast_mutex_lock(&myrpt->lock); 06108 l = myrpt->links.next; 06109 /* try to find this one in queue */ 06110 while(l != &myrpt->links) 06111 { 06112 if (l->name[0] == '0') 06113 { 06114 l = l->next; 06115 continue; 06116 } 06117 /* if found matching string */ 06118 if (!strcmp(l->name,b1)) break; 06119 l = l->next; 06120 } 06121 /* if found */ 06122 if (l != &myrpt->links) 06123 { 06124 l->killme = 1; 06125 l->retries = MAX_RETRIES + 1; 06126 l->disced = 2; 06127 ast_mutex_unlock(&myrpt->lock); 06128 usleep(500000); 06129 } else 06130 ast_mutex_unlock(&myrpt->lock); 06131 /* establish call in tranceive mode */ 06132 l = malloc(sizeof(struct rpt_link)); 06133 if (!l) 06134 { 06135 ast_log(LOG_WARNING, "Unable to malloc\n"); 06136 pthread_exit(NULL); 06137 } 06138 /* zero the silly thing */ 06139 memset((char *)l,0,sizeof(struct rpt_link)); 06140 l->mode = 1; 06141 strncpy(l->name,b1,MAXNODESTR - 1); 06142 l->isremote = 0; 06143 l->chan = chan; 06144 l->connected = 1; 06145 l->hasconnected = 1; 06146 l->phonemode = phone_mode; 06147 ast_set_read_format(l->chan,AST_FORMAT_SLINEAR); 06148 ast_set_write_format(l->chan,AST_FORMAT_SLINEAR); 06149 /* allocate a pseudo-channel thru asterisk */ 06150 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 06151 if (!l->pchan) 06152 { 06153 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 06154 pthread_exit(NULL); 06155 } 06156 ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR); 06157 ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR); 06158 /* make a conference for the tx */ 06159 ci.chan = 0; 06160 ci.confno = myrpt->conf; 06161 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 06162 /* first put the channel on the conference in proper mode */ 06163 if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1) 06164 { 06165 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 06166 pthread_exit(NULL); 06167 } 06168 ast_mutex_lock(&myrpt->lock); 06169 if (phone_mode > 1) l->lastrx = 1; 06170 /* insert at end of queue */ 06171 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 06172 ast_mutex_unlock(&myrpt->lock); 06173 if (chan->_state != AST_STATE_UP) { 06174 ast_answer(chan); 06175 } 06176 return AST_PBX_KEEPALIVE; 06177 } 06178 ast_mutex_lock(&myrpt->lock); 06179 /* if remote, error if anyone else already linked */ 06180 if (myrpt->remoteon) 06181 { 06182 ast_mutex_unlock(&myrpt->lock); 06183 usleep(500000); 06184 if (myrpt->remoteon) 06185 { 06186 ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp); 06187 return -1; 06188 } 06189 ast_mutex_lock(&myrpt->lock); 06190 } 06191 myrpt->remoteon = 1; 06192 if (ioperm(myrpt->iobase,1,1) == -1) 06193 { 06194 ast_mutex_unlock(&myrpt->lock); 06195 ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->iobase); 06196 return -1; 06197 } 06198 LOCAL_USER_ADD(u); 06199 tele = strchr(myrpt->rxchanname,'/'); 06200 if (!tele) 06201 { 06202 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 06203 ast_mutex_unlock(&myrpt->lock); 06204 pthread_exit(NULL); 06205 } 06206 *tele++ = 0; 06207 myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL); 06208 if (myrpt->rxchannel) 06209 { 06210 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 06211 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 06212 myrpt->rxchannel->whentohangup = 0; 06213 myrpt->rxchannel->appl = "Apprpt"; 06214 myrpt->rxchannel->data = "(Link Rx)"; 06215 if (option_verbose > 2) 06216 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 06217 myrpt->rxchanname,tele,myrpt->rxchannel->name); 06218 ast_mutex_unlock(&myrpt->lock); 06219 ast_call(myrpt->rxchannel,tele,999); 06220 ast_mutex_lock(&myrpt->lock); 06221 } 06222 else 06223 { 06224 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 06225 ast_mutex_unlock(&myrpt->lock); 06226 pthread_exit(NULL); 06227 } 06228 *--tele = '/'; 06229 if (myrpt->txchanname) 06230 { 06231 tele = strchr(myrpt->txchanname,'/'); 06232 if (!tele) 06233 { 06234 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 06235 ast_mutex_unlock(&myrpt->lock); 06236 ast_hangup(myrpt->rxchannel); 06237 pthread_exit(NULL); 06238 } 06239 *tele++ = 0; 06240 myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL); 06241 if (myrpt->txchannel) 06242 { 06243 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 06244 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 06245 myrpt->txchannel->whentohangup = 0; 06246 myrpt->txchannel->appl = "Apprpt"; 06247 myrpt->txchannel->data = "(Link Tx)"; 06248 if (option_verbose > 2) 06249 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 06250 myrpt->txchanname,tele,myrpt->txchannel->name); 06251 ast_mutex_unlock(&myrpt->lock); 06252 ast_call(myrpt->txchannel,tele,999); 06253 ast_mutex_lock(&myrpt->lock); 06254 } 06255 else 06256 { 06257 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 06258 ast_mutex_unlock(&myrpt->lock); 06259 ast_hangup(myrpt->rxchannel); 06260 pthread_exit(NULL); 06261 } 06262 *--tele = '/'; 06263 } 06264 else 06265 { 06266 myrpt->txchannel = myrpt->rxchannel; 06267 } 06268 myrpt->remoterx = 0; 06269 myrpt->remotetx = 0; 06270 myrpt->retxtimer = 0; 06271 myrpt->remoteon = 1; 06272 myrpt->dtmfidx = -1; 06273 myrpt->dtmfbuf[0] = 0; 06274 myrpt->dtmf_time_rem = 0; 06275 myrpt->hfscanmode = 0; 06276 myrpt->hfscanstatus = 0; 06277 ast_mutex_unlock(&myrpt->lock); 06278 setrem(myrpt); 06279 ast_set_write_format(chan, AST_FORMAT_SLINEAR); 06280 ast_set_read_format(chan, AST_FORMAT_SLINEAR); 06281 /* if we are on 2w loop and are a remote, turn EC on */ 06282 if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel)) 06283 { 06284 i = 128; 06285 ioctl(myrpt->rxchannel->fds[0],ZT_ECHOCANCEL,&i); 06286 } 06287 if (chan->_state != AST_STATE_UP) { 06288 ast_answer(chan); 06289 } 06290 06291 if (ioctl(myrpt->txchannel->fds[0],ZT_GET_PARAMS,&par) != -1) 06292 { 06293 if (par.rxisoffhook) 06294 { 06295 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 06296 myrpt->remoterx = 1; 06297 } 06298 } 06299 n = 0; 06300 cs[n++] = chan; 06301 cs[n++] = myrpt->rxchannel; 06302 if (myrpt->rxchannel != myrpt->txchannel) 06303 cs[n++] = myrpt->txchannel; 06304 for(;;) 06305 { 06306 if (ast_check_hangup(chan)) break; 06307 if (ast_check_hangup(myrpt->rxchannel)) break; 06308 ms = MSWAIT; 06309 who = ast_waitfor_n(cs,n,&ms); 06310 if (who == NULL) ms = 0; 06311 elap = MSWAIT - ms; 06312 if (!ms) continue; 06313 rem_totx = keyed; 06314 06315 06316 if ((!myrpt->remoterx) && (!myrpt->remotetx)) 06317 { 06318 if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME) 06319 { 06320 myrpt->retxtimer = 0; 06321 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 06322 } 06323 } else myrpt->retxtimer = 0; 06324 if (rem_totx && (!myrpt->remotetx)) /* Remote base radio TX key */ 06325 { 06326 myrpt->remotetx = 1; 06327 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 06328 } 06329 if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */ 06330 { 06331 myrpt->remotetx = 0; 06332 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 06333 } 06334 06335 if(myrpt->tunerequest && (!strcmp(myrpt->remote, remote_rig_ft897))){ /* ft-897 specific for now... */ 06336 myrpt->tunerequest = 0; 06337 set_mode_ft897(myrpt, REM_MODE_AM); 06338 simple_command_ft897(myrpt, 8); 06339 myrpt->remotetx = 0; 06340 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 06341 if (!myrpt->remoterx) 06342 ast_indicate(chan, AST_CONTROL_RADIO_KEY); 06343 if(play_tone(chan, 800, 6000, 8192) == -1) 06344 break; 06345 06346 rmt_telem_finish(myrpt,chan); 06347 set_mode_ft897(myrpt, 0x88); 06348 setrem(myrpt); 06349 } 06350 06351 if (myrpt->hfscanmode){ 06352 myrpt->scantimer -= elap; 06353 if(myrpt->scantimer <= 0){ 06354 myrpt->scantimer = REM_SCANTIME; 06355 service_scan(myrpt); 06356 } 06357 } 06358 06359 06360 if (who == chan) /* if it was a read from incomming */ 06361 { 06362 f = ast_read(chan); 06363 if (!f) 06364 { 06365 if (debug) printf("@@@@ link:Hung Up\n"); 06366 break; 06367 } 06368 if (f->frametype == AST_FRAME_VOICE) 06369 { 06370 /* if not transmitting, zero-out audio */ 06371 if (!myrpt->remotetx) 06372 memset(f->data,0,f->datalen); 06373 ast_write(myrpt->txchannel,f); 06374 } 06375 if (f->frametype == AST_FRAME_DTMF) 06376 { 06377 myrpt->remchannel = chan; /* Save copy of channel */ 06378 if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1) 06379 { 06380 if (debug) printf("@@@@ rpt:Hung Up\n"); 06381 ast_frfree(f); 06382 break; 06383 } 06384 } 06385 if (f->frametype == AST_FRAME_TEXT) 06386 { 06387 myrpt->remchannel = chan; /* Save copy of channel */ 06388 if (handle_remote_data(myrpt,f->data) == -1) 06389 { 06390 if (debug) printf("@@@@ rpt:Hung Up\n"); 06391 ast_frfree(f); 06392 break; 06393 } 06394 } 06395 if (f->frametype == AST_FRAME_CONTROL) 06396 { 06397 if (f->subclass == AST_CONTROL_HANGUP) 06398 { 06399 if (debug) printf("@@@@ rpt:Hung Up\n"); 06400 ast_frfree(f); 06401 break; 06402 } 06403 /* if RX key */ 06404 if (f->subclass == AST_CONTROL_RADIO_KEY) 06405 { 06406 if (debug) printf("@@@@ rx key\n"); 06407 keyed = 1; 06408 } 06409 /* if RX un-key */ 06410 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 06411 { 06412 if (debug) printf("@@@@ rx un-key\n"); 06413 keyed = 0; 06414 } 06415 } 06416 if (myrpt->hfscanstatus){ 06417 myrpt->remchannel = chan; /* Save copy of channel */ 06418 myrpt->remotetx = 0; 06419 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 06420 if (!myrpt->remoterx) 06421 { 06422 ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_KEY); 06423 } 06424 if(myrpt->hfscanstatus < 0) { 06425 if (myrpt->hfscanstatus == -1) { 06426 if (ast_safe_sleep(myrpt->remchannel,1000) == -1) break; 06427 } 06428 sayfile(myrpt->remchannel, "rpt/stop"); 06429 } 06430 else 06431 { 06432 saynum(myrpt->remchannel, myrpt->hfscanstatus ); 06433 } 06434 rmt_telem_finish(myrpt,myrpt->remchannel); 06435 myrpt->hfscanstatus = 0; 06436 } 06437 ast_frfree(f); 06438 continue; 06439 } 06440 if (who == myrpt->rxchannel) /* if it was a read from radio */ 06441 { 06442 f = ast_read(myrpt->rxchannel); 06443 if (!f) 06444 { 06445 if (debug) printf("@@@@ link:Hung Up\n"); 06446 break; 06447 } 06448 if (f->frametype == AST_FRAME_VOICE) 06449 { 06450 if ((myrpt->remote) && (myrpt->remotetx)) 06451 memset(f->data,0,f->datalen); 06452 ast_write(chan,f); 06453 } 06454 else if (f->frametype == AST_FRAME_CONTROL) 06455 { 06456 if (f->subclass == AST_CONTROL_HANGUP) 06457 { 06458 if (debug) printf("@@@@ rpt:Hung Up\n"); 06459 ast_frfree(f); 06460 break; 06461 } 06462 /* if RX key */ 06463 if (f->subclass == AST_CONTROL_RADIO_KEY) 06464 { 06465 if (debug) printf("@@@@ remote rx key\n"); 06466 if (!myrpt->remotetx) 06467 { 06468 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 06469 myrpt->remoterx = 1; 06470 } 06471 } 06472 /* if RX un-key */ 06473 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 06474 { 06475 if (debug) printf("@@@@ remote rx un-key\n"); 06476 if (!myrpt->remotetx) 06477 { 06478 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 06479 myrpt->remoterx = 0; 06480 } 06481 } 06482 } 06483 ast_frfree(f); 06484 continue; 06485 } 06486 if ((myrpt->rxchannel != myrpt->txchannel) && 06487 (who == myrpt->txchannel)) /* do this cuz you have to */ 06488 { 06489 f = ast_read(myrpt->txchannel); 06490 if (!f) 06491 { 06492 if (debug) printf("@@@@ link:Hung Up\n"); 06493 break; 06494 } 06495 if (f->frametype == AST_FRAME_CONTROL) 06496 { 06497 if (f->subclass == AST_CONTROL_HANGUP) 06498 { 06499 if (debug) printf("@@@@ rpt:Hung Up\n"); 06500 ast_frfree(f); 06501 break; 06502 } 06503 } 06504 ast_frfree(f); 06505 continue; 06506 } 06507 06508 } 06509 ast_mutex_lock(&myrpt->lock); 06510 if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel); 06511 ast_hangup(myrpt->rxchannel); 06512 myrpt->hfscanmode = 0; 06513 myrpt->hfscanstatus = 0; 06514 myrpt->remoteon = 0; 06515 ast_mutex_unlock(&myrpt->lock); 06516 closerem(myrpt); 06517 LOCAL_USER_REMOVE(u); 06518 return res; 06519 }
| static void* rpt_master | ( | void * | ignore | ) | [static] |
Definition at line 5609 of file app_rpt.c.
References rpt::acctcode, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_init(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_true(), ast_variable_browse(), ast_variable_retrieve(), DEFAULT_IOBASE, rpt::dphone_functions, rpt::dphone_longestfunc, ENDCHAR, rpt::endchar, FUNCCHAR, rpt::funcchar, FUNCTIONS, rpt::functions, HANGTIME, rpt::hangtime, rpt::ident, IDTIME, rpt::idtime, rpt::iobase, rpt::lastthreadrestarttime, rpt::link_functions, rpt::link_longestfunc, lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, rpt::longestfunc, rpt::longestnode, n, name, ast_variable::name, rpt::name, ast_variable::next, rpt_tele::next, rpt::nobusyout, NODES, rpt::nodes, rpt::offset, rpt::ourcallerid, rpt::ourcontext, rpt::phone_functions, rpt::phone_longestfunc, POLITEID, rpt::politeid, rpt::powerlevel, rpt_tele::prev, REM_MEDPWR, REM_MODE_FM, REM_SIMPLEX, rpt::remmode, rpt::remote, retrieve_astcfgint(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, rpt::simple, rpt::tele, rpt::threadrestarts, rpt::tonezone, TOTIME, rpt::totime, and rpt::txchanname.
Referenced by load_module().
05610 { 05611 char *this,*val; 05612 struct ast_variable *vp; 05613 int i,j,n,longestnode; 05614 pthread_attr_t attr; 05615 05616 /* start with blank config */ 05617 memset(&rpt_vars,0,sizeof(rpt_vars)); 05618 05619 cfg = ast_config_load("rpt.conf"); 05620 if (!cfg) { 05621 ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); 05622 pthread_exit(NULL); 05623 } 05624 05625 /* go thru all the specified repeaters */ 05626 this = NULL; 05627 n = 0; 05628 while((this = ast_category_browse(cfg,this)) != NULL) 05629 { 05630 05631 for(i = 0 ; i < strlen(this) ; i++){ 05632 if((this[i] < '0') || (this[i] > '9')) 05633 break; 05634 } 05635 if(i != strlen(this)) 05636 continue; /* Not a node defn */ 05637 05638 ast_log(LOG_DEBUG,"Loading config for repeater %s\n",this); 05639 ast_mutex_init(&rpt_vars[n].lock); 05640 rpt_vars[n].tele.next = &rpt_vars[n].tele; 05641 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 05642 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 05643 rpt_vars[n].name = this; 05644 rpt_vars[n].rxchanname = ast_variable_retrieve(cfg,this,"rxchannel"); 05645 rpt_vars[n].txchanname = ast_variable_retrieve(cfg,this,"txchannel"); 05646 rpt_vars[n].ourcontext = ast_variable_retrieve(cfg,this,"context"); 05647 if (!rpt_vars[n].ourcontext) rpt_vars[n].ourcontext = this; 05648 rpt_vars[n].ourcallerid = ast_variable_retrieve(cfg,this,"callerid"); 05649 rpt_vars[n].acctcode = ast_variable_retrieve(cfg,this,"accountcode"); 05650 rpt_vars[n].ident = ast_variable_retrieve(cfg,this,"idrecording"); 05651 val = ast_variable_retrieve(cfg,this,"hangtime"); 05652 if (val) rpt_vars[n].hangtime = atoi(val); 05653 else rpt_vars[n].hangtime = HANGTIME; 05654 val = ast_variable_retrieve(cfg,this,"totime"); 05655 if (val) rpt_vars[n].totime = atoi(val); 05656 else rpt_vars[n].totime = TOTIME; 05657 05658 rpt_vars[n].idtime = retrieve_astcfgint( this, "idtime", 60000, 2400000, IDTIME); /* Enforce a min max */ 05659 rpt_vars[n].politeid = retrieve_astcfgint( this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */ 05660 rpt_vars[n].remote = ast_variable_retrieve(cfg,this,"remote"); 05661 rpt_vars[n].tonezone = ast_variable_retrieve(cfg,this,"tonezone"); 05662 val = ast_variable_retrieve(cfg,this,"iobase"); 05663 /* do not use atoi() here, we need to be able to have 05664 the input specified in hex or decimal so we use 05665 sscanf with a %i */ 05666 if ((!val) || (sscanf(val,"%i",&rpt_vars[n].iobase) != 1)) 05667 rpt_vars[n].iobase = DEFAULT_IOBASE; 05668 rpt_vars[n].simple = 0; 05669 rpt_vars[n].functions = ast_variable_retrieve(cfg,this,"functions"); 05670 if (!rpt_vars[n].functions) 05671 { 05672 rpt_vars[n].functions = FUNCTIONS; 05673 rpt_vars[n].simple = 1; 05674 } 05675 rpt_vars[n].link_functions = ast_variable_retrieve(cfg,this,"link_functions"); 05676 if (!rpt_vars[n].link_functions) 05677 rpt_vars[n].link_functions = rpt_vars[n].functions; 05678 rpt_vars[n].phone_functions = ast_variable_retrieve(cfg,this,"phone_functions"); 05679 rpt_vars[n].dphone_functions = ast_variable_retrieve(cfg,this,"dphone_functions"); 05680 val = ast_variable_retrieve(cfg,this,"funcchar"); 05681 if (!val) rpt_vars[n].funcchar = FUNCCHAR; else 05682 rpt_vars[n].funcchar = *val; 05683 val = ast_variable_retrieve(cfg,this,"endchar"); 05684 if (!val) rpt_vars[n].endchar = ENDCHAR; else 05685 rpt_vars[n].endchar = *val; 05686 val = ast_variable_retrieve(cfg,this,"nobusyout"); 05687 if (val) rpt_vars[n].nobusyout = ast_true(val); 05688 rpt_vars[n].nodes = ast_variable_retrieve(cfg,this,"nodes"); 05689 if (!rpt_vars[n].nodes) 05690 rpt_vars[n].nodes = NODES; 05691 n++; 05692 } 05693 nrpts = n; 05694 ast_log(LOG_DEBUG, "Total of %d repeaters configured.\n",n); 05695 /* start em all */ 05696 for(i = 0; i < n; i++) 05697 { 05698 05699 /* 05700 * Go through the node list to determine the longest node 05701 */ 05702 longestnode = 0; 05703 05704 vp = ast_variable_browse(cfg, rpt_vars[i].nodes); 05705 05706 while(vp){ 05707 j = strlen(vp->name); 05708 if (j > longestnode) 05709 longestnode = j; 05710 vp = vp->next; 05711 } 05712 05713 05714 rpt_vars[i].longestnode = longestnode; 05715 05716 /* 05717 * For this repeater, Determine the length of the longest function 05718 */ 05719 rpt_vars[i].longestfunc = 0; 05720 vp = ast_variable_browse(cfg, rpt_vars[i].functions); 05721 while(vp){ 05722 j = strlen(vp->name); 05723 if (j > rpt_vars[i].longestfunc) 05724 rpt_vars[i].longestfunc = j; 05725 vp = vp->next; 05726 } 05727 /* 05728 * For this repeater, Determine the length of the longest function 05729 */ 05730 rpt_vars[i].link_longestfunc = 0; 05731 vp = ast_variable_browse(cfg, rpt_vars[i].link_functions); 05732 while(vp){ 05733 j = strlen(vp->name); 05734 if (j > rpt_vars[i].link_longestfunc) 05735 rpt_vars[i].link_longestfunc = j; 05736 vp = vp->next; 05737 } 05738 rpt_vars[i].phone_longestfunc = 0; 05739 if (rpt_vars[i].phone_functions) 05740 { 05741 vp = ast_variable_browse(cfg, rpt_vars[i].phone_functions); 05742 while(vp){ 05743 j = strlen(vp->name); 05744 if (j > rpt_vars[i].phone_longestfunc) 05745 rpt_vars[i].phone_longestfunc = j; 05746 vp = vp->next; 05747 } 05748 } 05749 rpt_vars[i].dphone_longestfunc = 0; 05750 if (rpt_vars[i].dphone_functions) 05751 { 05752 vp = ast_variable_browse(cfg, rpt_vars[i].dphone_functions); 05753 while(vp){ 05754 j = strlen(vp->name); 05755 if (j > rpt_vars[i].dphone_longestfunc) 05756 rpt_vars[i].dphone_longestfunc = j; 05757 vp = vp->next; 05758 } 05759 } 05760 if (!rpt_vars[i].rxchanname) 05761 { 05762 ast_log(LOG_WARNING,"Did not specify rxchanname for node %s\n",rpt_vars[i].name); 05763 ast_config_destroy(cfg); 05764 pthread_exit(NULL); 05765 } 05766 /* if is a remote, dont start one for it */ 05767 if (rpt_vars[i].remote) 05768 { 05769 strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1); 05770 strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1); 05771 05772 strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1); 05773 rpt_vars[i].remmode = REM_MODE_FM; 05774 rpt_vars[i].offset = REM_SIMPLEX; 05775 rpt_vars[i].powerlevel = REM_MEDPWR; 05776 continue; 05777 } 05778 if (!rpt_vars[i].ident) 05779 { 05780 ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name); 05781 ast_config_destroy(cfg); 05782 pthread_exit(NULL); 05783 } 05784 pthread_attr_init(&attr); 05785 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05786 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 05787 pthread_attr_destroy(&attr); 05788 } 05789 usleep(500000); 05790 for(;;) 05791 { 05792 /* Now monitor each thread, and restart it if necessary */ 05793 for(i = 0; i < n; i++) 05794 { 05795 int rv; 05796 if (rpt_vars[i].remote) continue; 05797 if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP) 05798 rv = -1; 05799 else 05800 rv = pthread_kill(rpt_vars[i].rpt_thread,0); 05801 if (rv) 05802 { 05803 if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15) 05804 { 05805 if(rpt_vars[i].threadrestarts >= 5) 05806 { 05807 ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n"); 05808 exit(1); /* Stuck in a restart loop, kill Asterisk and start over */ 05809 } 05810 else 05811 { 05812 ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name); 05813 rpt_vars[i].threadrestarts++; 05814 } 05815 } 05816 else 05817 rpt_vars[i].threadrestarts = 0; 05818 05819 rpt_vars[i].lastthreadrestarttime = time(NULL); 05820 pthread_attr_init(&attr); 05821 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05822 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 05823 pthread_attr_destroy(&attr); 05824 ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name); 05825 } 05826 05827 } 05828 usleep(2000000); 05829 } 05830 ast_config_destroy(cfg); 05831 pthread_exit(NULL); 05832 }
| static void* rpt_tele_thread | ( | void * | this | ) | [static] |
Definition at line 964 of file app_rpt.c.
References ARB_ALPHA, AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_safe_sleep(), ast_say_character_str(), ast_say_digits(), ast_say_number(), ast_say_time(), ast_stopstream(), ast_strdupa, ast_streamfile(), ast_tonepair_start(), ast_variable_retrieve(), ast_waitstream(), rpt_tele::chan, COMPLETE, CONNECTED, rpt_link::connected, CONNFAIL, DLY_CALLTERM, DLY_ID, DLY_TELEM, DLY_UNKEY, ast_channel::fds, free, ast_channel::generatordata, get_wait_interval(), ID, ID1, IDTALKOVER, rpt_link::isremote, ast_channel::language, LOG_WARNING, malloc, rpt_link::mode, rpt_tele::mode, rpt_tele::mylink, rpt_link::name, ast_channel::name, rpt_link::next, rpt_tele::next, rpt_tele::param, rpt_link::prev, PROC, REMALREADY, REMDISC, REMGO, REMNOTFOUND, REV_PATCH, rpt_tele::rpt, saycharstr(), sayfile(), STATS_TIME, STATS_VERSION, STATUS, strsep(), t, telem_any(), telem_lookup(), TERM, TEST_TONE, TIMEOUT, UNKEY, and wait_interval().
Referenced by rpt_telemetry().
00965 { 00966 ZT_CONFINFO ci; /* conference info */ 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 /* get a pointer to myrpt */ 00980 myrpt = mytele->rpt; 00981 00982 /* Snag copies of a few key myrpt variables */ 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 /* allocate a pseudo-channel thru asterisk */ 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; /* Save a copy of the channel so we can access it externally if need be */ 01002 ast_mutex_unlock(&myrpt->lock); 01003 01004 /* make a conference for the tx */ 01005 ci.chan = 0; 01006 /* If there's an ID queued, only connect the ID audio to the local tx conference so 01007 linked systems can't hear it */ 01008 ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY)) ? 01009 myrpt->txconf : myrpt->conf); 01010 ci.confmode = ZT_CONF_CONFANN; 01011 /* first put the channel on the conference in announce mode */ 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->mode) 01024 { 01025 case ID: 01026 case ID1: 01027 /* wait a bit */ 01028 wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel); 01029 res = telem_any(mychannel, ident); 01030 imdone=1; 01031 01032 break; 01033 01034 01035 case IDTALKOVER: 01036 p = ast_variable_retrieve(cfg, nodename, "idtalkover"); 01037 if(p) 01038 res = telem_any(mychannel, p); 01039 imdone=1; 01040 break; 01041 01042 case PROC: 01043 /* wait a little bit longer */ 01044 wait_interval(myrpt, DLY_TELEM, mychannel); 01045 res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language); 01046 break; 01047 case TERM: 01048 /* wait a little bit longer */ 01049 wait_interval(myrpt, DLY_CALLTERM, mychannel); 01050 res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language); 01051 break; 01052 case COMPLETE: 01053 /* wait a little bit */ 01054 wait_interval(myrpt, DLY_TELEM, mychannel); 01055 res = telem_lookup(mychannel, myrpt->name, "functcomplete"); 01056 break; 01057 case UNKEY: 01058 01059 /* 01060 * Reset the Unkey to CT timer 01061 */ 01062 01063 x = get_wait_interval(myrpt, DLY_UNKEY); 01064 ast_mutex_lock(&myrpt->lock); 01065 myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */ 01066 ast_mutex_unlock(&myrpt->lock); 01067 01068 /* 01069 * If there's one already queued, don't do another 01070 */ 01071 01072 tlist = myrpt->tele.next; 01073 unkeys_queued = 0; 01074 if (tlist != &myrpt->tele) 01075 { 01076 ast_mutex_lock(&myrpt->lock); 01077 while(tlist != &myrpt->tele){ 01078 if (tlist->mode == UNKEY) unkeys_queued++; 01079 tlist = tlist->next; 01080 } 01081 ast_mutex_unlock(&myrpt->lock); 01082 } 01083 if( unkeys_queued > 1){ 01084 imdone = 1; 01085 break; 01086 } 01087 01088 /* Wait for the telemetry timer to expire */ 01089 /* Periodically check the timer since it can be re-initialized above */ 01090 01091 while(myrpt->unkeytocttimer) 01092 { 01093 int ctint; 01094 if(myrpt->unkeytocttimer > 100) 01095 ctint = 100; 01096 else 01097 ctint = myrpt->unkeytocttimer; 01098 ast_safe_sleep(mychannel, ctint); 01099 ast_mutex_lock(&myrpt->lock); 01100 if(myrpt->unkeytocttimer < ctint) 01101 myrpt->unkeytocttimer = 0; 01102 else 01103 myrpt->unkeytocttimer -= ctint; 01104 ast_mutex_unlock(&myrpt->lock); 01105 } 01106 01107 01108 /* 01109 * Now, the carrier on the rptr rx should be gone. 01110 * If it re-appeared, then forget about sending the CT 01111 */ 01112 if(myrpt->keyed){ 01113 imdone = 1; 01114 break; 01115 } 01116 01117 haslink = 0; 01118 hastx = 0; 01119 hasremote = 0; 01120 l = myrpt->links.next; 01121 if (l != &myrpt->links) 01122 { 01123 ast_mutex_lock(&myrpt->lock); 01124 while(l != &myrpt->links) 01125 { 01126 if (l->name[0] == '0') 01127 { 01128 l = l->next; 01129 continue; 01130 } 01131 haslink = 1; 01132 if (l->mode) { 01133 hastx++; 01134 if (l->isremote) hasremote++; 01135 } 01136 l = l->next; 01137 } 01138 ast_mutex_unlock(&myrpt->lock); 01139 } 01140 if (haslink) 01141 { 01142 01143 res = telem_lookup(mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx"); 01144 if(res) 01145 ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name); 01146 01147 01148 /* if in remote cmd mode, indicate it */ 01149 if (myrpt->cmdnode[0]) 01150 { 01151 ast_safe_sleep(mychannel,200); 01152 res = telem_lookup(mychannel, myrpt->name, "cmdmode"); 01153 if(res) 01154 ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name); 01155 ast_stopstream(mychannel); 01156 } 01157 } 01158 else if((ct = ast_variable_retrieve(cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */ 01159 ct_copy = ast_strdupa(ct); 01160 res = telem_lookup(mychannel, myrpt->name, ct_copy); 01161 if(res) 01162 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 01163 } 01164 01165 if (hasremote && (!myrpt->cmdnode[0])) 01166 { 01167 /* set for all to hear */ 01168 ci.chan = 0; 01169 ci.confno = myrpt->conf; 01170 ci.confmode = ZT_CONF_CONFANN; 01171 /* first put the channel on the conference in announce mode */ 01172 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 01173 { 01174 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 01175 ast_mutex_lock(&myrpt->lock); 01176 remque((struct qelem *)mytele); 01177 ast_mutex_unlock(&myrpt->lock); 01178 free(mytele); 01179 ast_hangup(mychannel); 01180 pthread_exit(NULL); 01181 } 01182 if((ct = ast_variable_retrieve(cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */ 01183 ast_safe_sleep(mychannel,200); 01184 ct_copy = ast_strdupa(ct); 01185 res = telem_lookup(mychannel, myrpt->name, ct_copy); 01186 if(res) 01187 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 01188 } 01189 } 01190 imdone = 1; 01191 break; 01192 case REMDISC: 01193 /* wait a little bit */ 01194 wait_interval(myrpt, DLY_TELEM, mychannel); 01195 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 01196 if (!res) 01197 res = ast_waitstream(mychannel, ""); 01198 else 01199 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01200 ast_stopstream(mychannel); 01201 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 01202 res = ast_streamfile(mychannel, ((mytele->mylink.connected) ? 01203 "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language); 01204 break; 01205 case REMALREADY: 01206 /* wait a little bit */ 01207 wait_interval(myrpt, DLY_TELEM, mychannel); 01208 res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language); 01209 break; 01210 case REMNOTFOUND: 01211 /* wait a little bit */ 01212 wait_interval(myrpt, DLY_TELEM, mychannel); 01213 res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language); 01214 break; 01215 case REMGO: 01216 /* wait a little bit */ 01217 wait_interval(myrpt, DLY_TELEM, mychannel); 01218 res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language); 01219 break; 01220 case CONNECTED: 01221 /* wait a little bit */ 01222 wait_interval(myrpt, DLY_TELEM, mychannel); 01223 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 01224 if (!res) 01225 res = ast_waitstream(mychannel, ""); 01226 else 01227 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01228 ast_stopstream(mychannel); 01229 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 01230 res = ast_streamfile(mychannel, "rpt/connected", mychannel->language); 01231 break; 01232 case CONNFAIL: 01233 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 01234 if (!res) 01235 res = ast_waitstream(mychannel, ""); 01236 else 01237 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01238 ast_stopstream(mychannel); 01239 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 01240 res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language); 01241 break; 01242 case STATUS: 01243 /* wait a little bit */ 01244 wait_interval(myrpt, DLY_TELEM, mychannel); 01245 hastx = 0; 01246 linkbase.next = &linkbase; 01247 linkbase.prev = &linkbase; 01248 ast_mutex_lock(&myrpt->lock); 01249 /* make our own list of links */ 01250 l = myrpt->links.next; 01251 while(l != &myrpt->links) 01252 { 01253 if (l->name[0] == '0') 01254 { 01255 l = l->next; 01256 continue; 01257 } 01258 m = malloc(sizeof(struct rpt_link)); 01259 if (!m) 01260 { 01261 ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name); 01262 ast_mutex_lock(&myrpt->lock); 01263 remque((struct qelem *)mytele); 01264 ast_mutex_unlock(&myrpt->lock); 01265 free(mytele); 01266 ast_hangup(mychannel); 01267 pthread_exit(NULL); 01268 } 01269 memcpy(m,l,sizeof(struct rpt_link)); 01270 m->next = m->prev = NULL; 01271 insque((struct qelem *)m,(struct qelem *)linkbase.next); 01272 l = l->next; 01273 } 01274 ast_mutex_unlock(&myrpt->lock); 01275 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 01276 if (!res) 01277 res = ast_waitstream(mychannel, ""); 01278 else 01279 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01280 ast_stopstream(mychannel); 01281 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 01282 if (!res) 01283 res = ast_waitstream(mychannel, ""); 01284 else 01285 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01286 ast_stopstream(mychannel); 01287 if (myrpt->callmode) 01288 { 01289 hastx = 1; 01290 res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language); 01291 if (!res) 01292 res = ast_waitstream(mychannel, ""); 01293 else 01294 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01295 ast_stopstream(mychannel); 01296 } 01297 l = linkbase.next; 01298 while(l != &linkbase) 01299 { 01300 hastx = 1; 01301 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 01302 if (!res) 01303 res = ast_waitstream(mychannel, ""); 01304 else 01305 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01306 ast_stopstream(mychannel); 01307 ast_say_character_str(mychannel,l->name,NULL,mychannel->language); 01308 if (!res) 01309 res = ast_waitstream(mychannel, ""); 01310 else 01311 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01312 ast_stopstream(mychannel); 01313 res = ast_streamfile(mychannel, ((l->mode) ? 01314 "rpt/tranceive" : "rpt/monitor"), mychannel->language); 01315 if (!res) 01316 res = ast_waitstream(mychannel, ""); 01317 else 01318 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01319 ast_stopstream(mychannel); 01320 l = l->next; 01321 } 01322 if (!hastx) 01323 { 01324 res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language); 01325 if (!res) 01326 res = ast_waitstream(mychannel, ""); 01327 else 01328 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01329 ast_stopstream(mychannel); 01330 } 01331 /* destroy our local link queue */ 01332 l = linkbase.next; 01333 while(l != &linkbase) 01334 { 01335 m = l; 01336 l = l->next; 01337 remque((struct qelem *)m); 01338 free(m); 01339 } 01340 imdone = 1; 01341 break; 01342 case TIMEOUT: 01343 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 01344 if (!res) 01345 res = ast_waitstream(mychannel, ""); 01346 else 01347 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01348 ast_stopstream(mychannel); 01349 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 01350 res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language); 01351 break; 01352 01353 case STATS_TIME: 01354 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 01355 t = time(NULL); 01356 localtime_r(&t, &localtm); 01357 /* Say the phase of the day is before the time */ 01358 if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12)) 01359 p = "rpt/goodmorning"; 01360 else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18)) 01361 p = "rpt/goodafternoon"; 01362 else 01363 p = "rpt/goodevening"; 01364 if (sayfile(mychannel,p) == -1) 01365 { 01366 imdone = 1; 01367 break; 01368 } 01369 /* Say the time is ... */ 01370 if (sayfile(mychannel,"rpt/thetimeis") == -1) 01371 { 01372 imdone = 1; 01373 break; 01374 } 01375 /* Say the time */ 01376 res = ast_say_time(mychannel, t, "", mychannel->language); 01377 if (!res) 01378 res = ast_waitstream(mychannel, ""); 01379 ast_stopstream(mychannel); 01380 imdone = 1; 01381 break; 01382 case STATS_VERSION: 01383 p = strstr(tdesc, "version"); 01384 if(!p) 01385 break; 01386 if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2) 01387 break; 01388 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 01389 /* Say "version" */ 01390 if (sayfile(mychannel,"rpt/version") == -1) 01391 { 01392 imdone = 1; 01393 break; 01394 } 01395 if(!res) /* Say "X" */ 01396 ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL); 01397 if (!res) 01398 res = ast_waitstream(mychannel, ""); 01399 ast_stopstream(mychannel); 01400 if (saycharstr(mychannel,".") == -1) 01401 { 01402 imdone = 1; 01403 break; 01404 } 01405 if(!res) /* Say "Y" */ 01406 ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL); 01407 if (!res){ 01408 res = ast_waitstream(mychannel, ""); 01409 ast_stopstream(mychannel); 01410 } 01411 else 01412 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01413 imdone = 1; 01414 break; 01415 case ARB_ALPHA: 01416 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 01417 if(mytele->param) 01418 saycharstr(mychannel, mytele->param); 01419 imdone = 1; 01420 break; 01421 case REV_PATCH: 01422 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 01423 if(mytele->param) { 01424 01425 /* Parts of this section taken from app_parkandannounce */ 01426 char *tpl_working, *tpl_current; 01427 char *tmp[100], *myparm; 01428 int looptemp=0,i=0, dres = 0; 01429 01430 01431 tpl_working = strdupa(mytele->param); 01432 myparm = strsep(&tpl_working,","); 01433 tpl_current=strsep(&tpl_working, ":"); 01434 01435 while(tpl_current && looptemp < sizeof(tmp)) { 01436 tmp[looptemp]=tpl_current; 01437 looptemp++; 01438 tpl_current=strsep(&tpl_working,":"); 01439 } 01440 01441 for(i=0; i<looptemp; i++) { 01442 if(!strcmp(tmp[i], "PARKED")) { 01443 ast_say_digits(mychannel, atoi(myparm), "", mychannel->language); 01444 } else if(!strcmp(tmp[i], "NODE")) { 01445 ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language); 01446 } else { 01447 dres = ast_streamfile(mychannel, tmp[i], mychannel->language); 01448 if(!dres) { 01449 dres = ast_waitstream(mychannel, ""); 01450 } else { 01451 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name); 01452 dres = 0; 01453 } 01454 } 01455 } 01456 } 01457 imdone = 1; 01458 break; 01459 case TEST_TONE: 01460 imdone = 1; 01461 myrpt->stopgen = 0; 01462 if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0))) 01463 break; 01464 while(mychannel->generatordata && (!myrpt->stopgen)) { 01465 if (ast_safe_sleep(mychannel,1)) break; 01466 imdone = 1; 01467 } 01468 break; 01469 default: 01470 break; 01471 } 01472 myrpt->stopgen = 0; 01473 if (!imdone) 01474 { 01475 if (!res) 01476 res = ast_waitstream(mychannel, ""); 01477 else { 01478 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01479 res = 0; 01480 } 01481 } 01482 ast_stopstream(mychannel); 01483 ast_mutex_lock(&myrpt->lock); 01484 remque((struct qelem *)mytele); 01485 ast_mutex_unlock(&myrpt->lock); 01486 free(mytele); 01487 ast_hangup(mychannel); 01488 pthread_exit(NULL); 01489 }
| static void rpt_telemetry | ( | struct rpt * | myrpt, | |
| int | mode, | |||
| void * | data | |||
| ) | [static] |
Definition at line 1491 of file app_rpt.c.
References ARB_ALPHA, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, CONNECTED, CONNFAIL, rpt::lock, LOG_WARNING, malloc, rpt_tele::next, REMDISC, REV_PATCH, rpt_tele_thread(), rpt::tele, and TELEPARAMSIZE.
Referenced by function_autopatchdn(), function_cop(), function_ilink(), function_status(), handle_link_data(), handle_link_phone_dtmf(), rpt(), and rpt_exec().
01492 { 01493 struct rpt_tele *tele; 01494 struct rpt_link *mylink = (struct rpt_link *) data; 01495 pthread_attr_t attr; 01496 01497 tele = malloc(sizeof(struct rpt_tele)); 01498 if (!tele) 01499 { 01500 ast_log(LOG_WARNING, "Unable to allocate memory\n"); 01501 pthread_exit(NULL); 01502 return; 01503 } 01504 /* zero it out */ 01505 memset((char *)tele,0,sizeof(struct rpt_tele)); 01506 tele->rpt = myrpt; 01507 tele->mode = mode; 01508 ast_mutex_lock(&myrpt->lock); 01509 if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED)){ 01510 memset(&tele->mylink,0,sizeof(struct rpt_link)); 01511 if (mylink){ 01512 memcpy(&tele->mylink,mylink,sizeof(struct rpt_link)); 01513 } 01514 } 01515 else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) { 01516 strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1); 01517 tele->param[TELEPARAMSIZE - 1] = 0; 01518 } 01519 insque((struct qelem *)tele,(struct qelem *)myrpt->tele.next); 01520 ast_mutex_unlock(&myrpt->lock); 01521 pthread_attr_init(&attr); 01522 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 01523 ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele); 01524 pthread_attr_destroy(&attr); 01525 return; 01526 }
| static int saycharstr | ( | struct ast_channel * | mychannel, | |
| char * | str | |||
| ) | [static] |
Definition at line 748 of file app_rpt.c.
References ast_log(), ast_say_character_str(), ast_stopstream(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.
Referenced by function_remote(), rmt_saycharstr(), and rpt_tele_thread().
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 }
| static int sayfile | ( | struct ast_channel * | mychannel, | |
| char * | fname | |||
| ) | [static] |
Definition at line 735 of file app_rpt.c.
References ast_log(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.
Referenced by function_remote(), rmt_sayfile(), rpt_exec(), rpt_tele_thread(), and telem_any().
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 }
| static int saynum | ( | struct ast_channel * | mychannel, | |
| int | num | |||
| ) | [static] |
Definition at line 761 of file app_rpt.c.
References ast_log(), ast_say_number(), ast_stopstream(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.
Referenced by function_remote(), and rpt_exec().
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 }
| static void send_link_dtmf | ( | struct rpt * | myrpt, | |
| char | c | |||
| ) | [static] |
Definition at line 1720 of file app_rpt.c.
References AST_FRAME_TEXT, ast_write(), rpt_link::chan, rpt::cmdnode, ast_frame::data, ast_frame::datalen, rpt::dtmfidx, ast_frame::frametype, rpt::links, ast_frame::mallocd, rpt_link::name, rpt::name, rpt_link::next, ast_frame::offset, ast_frame::samples, strdup, and ast_frame::subclass.
Referenced by handle_link_phone_dtmf(), and rpt().
01721 { 01722 char str[300]; 01723 struct ast_frame wf; 01724 struct rpt_link *l; 01725 01726 snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c); 01727 wf.frametype = AST_FRAME_TEXT; 01728 wf.subclass = 0; 01729 wf.offset = 0; 01730 wf.mallocd = 1; 01731 wf.datalen = strlen(str) + 1; 01732 wf.samples = 0; 01733 l = myrpt->links.next; 01734 /* first, see if our dude is there */ 01735 while(l != &myrpt->links) 01736 { 01737 if (l->name[0] == '0') 01738 { 01739 l = l->next; 01740 continue; 01741 } 01742 /* if we found it, write it and were done */ 01743 if (!strcmp(l->name,myrpt->cmdnode)) 01744 { 01745 wf.data = strdup(str); 01746 if (l->chan) ast_write(l->chan,&wf); 01747 return; 01748 } 01749 l = l->next; 01750 } 01751 l = myrpt->links.next; 01752 /* if not, give it to everyone */ 01753 while(l != &myrpt->links) 01754 { 01755 wf.data = strdup(str); 01756 if (l->chan) ast_write(l->chan,&wf); 01757 l = l->next; 01758 } 01759 return; 01760 }
| static int send_morse | ( | struct ast_channel * | chan, | |
| char * | string, | |||
| int | speed, | |||
| int | freq, | |||
| int | amplitude | |||
| ) | [static] |
Definition at line 521 of file app_rpt.c.
References ast_safe_sleep(), ast_stopstream(), ast_waitstream(), morse_bits::ddcomb, ast_channel::fds, morse_bits::len, play_silence(), and play_tone().
Referenced by telem_any().
00522 { 00523 00524 static struct morse_bits mbits[] = { 00525 {0, 0}, /* SPACE */ 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},/* 0 */ 00542 {5, 30},/* 1 */ 00543 {5, 28},/* 2 */ 00544 {5, 24},/* 3 */ 00545 {5, 16},/* 4 */ 00546 {5, 0}, /* 5 */ 00547 {5, 1}, /* 6 */ 00548 {5, 3}, /* 7 */ 00549 {5, 7}, /* 8 */ 00550 {5, 15},/* 9 */ 00551 {6, 7}, /* : */ 00552 {6, 21},/* ; */ 00553 {0, 0}, 00554 {5, 33},/* = */ 00555 {0, 0}, 00556 {6, 12},/* ? */ 00557 {0, 0}, 00558 {2, 2}, /* A */ 00559 {4, 1}, /* B */ 00560 {4, 5}, /* C */ 00561 {3, 1}, /* D */ 00562 {1, 0}, /* E */ 00563 {4, 4}, /* F */ 00564 {3, 3}, /* G */ 00565 {4, 0}, /* H */ 00566 {2, 0}, /* I */ 00567 {4, 14},/* J */ 00568 {3, 5}, /* K */ 00569 {4, 2}, /* L */ 00570 {2, 3}, /* M */ 00571 {2, 1}, /* N */ 00572 {3, 7}, /* O */ 00573 {4, 6}, /* P */ 00574 {4, 11},/* Q */ 00575 {3, 2}, /* R */ 00576 {3, 0}, /* S */ 00577 {1, 1}, /* T */ 00578 {3, 4}, /* U */ 00579 {4, 8}, /* V */ 00580 {3, 6}, /* W */ 00581 {4, 9}, /* X */ 00582 {4, 13},/* Y */ 00583 {4, 3} /* Z */ 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 /* Approximate the dot time from the speed arg. */ 00601 00602 dottime = 900/speed; 00603 00604 /* Establish timing releationships */ 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 /* Convert lower case to upper case */ 00616 00617 if((c >= 'a') && (c <= 'z')) 00618 c -= 0x20; 00619 00620 /* Can't deal with any char code greater than Z, skip it */ 00621 00622 if(c > 'Z') 00623 continue; 00624 00625 /* If space char, wait the inter word time */ 00626 00627 if(c == ' '){ 00628 if(!res) 00629 res = play_silence(chan, interwordtime); 00630 continue; 00631 } 00632 00633 /* Subtract out control char offset to match our table */ 00634 00635 c -= 0x20; 00636 00637 /* Get the character data */ 00638 00639 len = mbits[c].len; 00640 ddcomb = mbits[c].ddcomb; 00641 00642 /* Send the character */ 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 /* Wait the interletter time */ 00653 00654 if(!res) 00655 res = play_silence(chan, interlettertime - intralettertime); 00656 } 00657 00658 /* Wait for all the frames to be sent */ 00659 00660 if (!res) 00661 res = ast_waitstream(chan, ""); 00662 ast_stopstream(chan); 00663 00664 /* 00665 * Wait for the zaptel driver to physically write the tone blocks to the hardware 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 }
| static int send_tone_telemetry | ( | struct ast_channel * | chan, | |
| char * | tonestring | |||
| ) | [static] |
Definition at line 683 of file app_rpt.c.
References ast_safe_sleep(), ast_stopstream(), ast_strdupa, ast_waitstream(), ast_channel::fds, play_tone_pair(), and strsep().
Referenced by telem_any().
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); /* This is needed to ensure the last tone segment is timed correctly */ 00710 00711 if (!res) 00712 res = ast_waitstream(chan, ""); 00713 ast_stopstream(chan); 00714 00715 /* 00716 * Wait for the zaptel driver to physically write the tone blocks to the hardware 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 }
| static int serial_remote_io | ( | struct rpt * | myrpt, | |
| char * | txbuf, | |||
| int | txbytes, | |||
| char * | rxbuf, | |||
| int | rxmaxbytes, | |||
| int | asciiflag | |||
| ) | [static] |
Definition at line 2827 of file app_rpt.c.
References ast_channel::fds, and rpt::rxchannel.
Referenced by set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), and simple_command_ft897().
02829 { 02830 int i; 02831 struct zt_radio_param prm; 02832 02833 if(debug){ 02834 printf("String output was: "); 02835 for(i = 0; i < txbytes; i++) 02836 printf("%02X ", (unsigned char ) txbuf[i]); 02837 printf("\n"); 02838 } 02839 02840 prm.radpar = ZT_RADPAR_REMMODE; 02841 if (asciiflag) prm.data = ZT_RADPAR_REM_SERIAL_ASCII; 02842 else prm.data = ZT_RADPAR_REM_SERIAL; 02843 if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 02844 prm.radpar = ZT_RADPAR_REMCOMMAND; 02845 prm.data = rxmaxbytes; 02846 memcpy(prm.buf,txbuf,txbytes); 02847 prm.index = txbytes; 02848 if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 02849 if (rxbuf) 02850 { 02851 *rxbuf = 0; 02852 memcpy(rxbuf,prm.buf,prm.index); 02853 } 02854 return(prm.index); 02855 }
| static int service_scan | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 3486 of file app_rpt.c.
References rpt::freq, HF_SCAN_DOWN_FAST, HF_SCAN_DOWN_QUICK, HF_SCAN_DOWN_SLOW, HF_SCAN_UP_FAST, HF_SCAN_UP_QUICK, HF_SCAN_UP_SLOW, rpt::hfscanmode, rpt::hfscanstatus, MAXREMSTR, multimode_bump_freq(), split_freq(), and stop_scan().
Referenced by rpt_exec().
03487 { 03488 int res, interval; 03489 char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0; 03490 03491 switch(myrpt->hfscanmode){ 03492 03493 case HF_SCAN_DOWN_SLOW: 03494 interval = -10; /* 100Hz /sec */ 03495 break; 03496 03497 case HF_SCAN_DOWN_QUICK: 03498 interval = -50; /* 500Hz /sec */ 03499 break; 03500 03501 case HF_SCAN_DOWN_FAST: 03502 interval = -200; /* 2KHz /sec */ 03503 break; 03504 03505 case HF_SCAN_UP_SLOW: 03506 interval = 10; /* 100Hz /sec */ 03507 break; 03508 03509 case HF_SCAN_UP_QUICK: 03510 interval = 50; /* 500 Hz/sec */ 03511 break; 03512 03513 case HF_SCAN_UP_FAST: 03514 interval = 200; /* 2KHz /sec */ 03515 break; 03516 03517 default: 03518 myrpt->hfscanmode = 0; /* Huh? */ 03519 return -1; 03520 } 03521 03522 res = split_freq(mhz, decimals, myrpt->freq); 03523 03524 if(!res){ 03525 k100 =decimals[0]; 03526 k10 = decimals[1]; 03527 res = multimode_bump_freq(myrpt, interval); 03528 } 03529 03530 if(!res) 03531 res = split_freq(mhz, decimals, myrpt->freq); 03532 03533 03534 if(res){ 03535 stop_scan(myrpt,1); 03536 return -1; 03537 } 03538 03539 /* Announce 10KHz boundaries */ 03540 if(k10 != decimals[1]){ 03541 int myhund = (interval < 0) ? k100 : decimals[0]; 03542 int myten = (interval < 0) ? k10 : decimals[1]; 03543 myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10; 03544 } 03545 return res; 03546 03547 }
| static int set_ctcss_freq_ft897 | ( | struct rpt * | myrpt, | |
| char * | txtone, | |||
| char * | rxtone | |||
| ) | [static] |
Definition at line 3268 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_ctcss_freq().
Referenced by set_ft897().
03269 { 03270 unsigned char cmdstr[5]; 03271 char hertz[MAXREMSTR],decimal[MAXREMSTR]; 03272 int h,d; 03273 03274 memset(cmdstr, 0, 5); 03275 03276 if(split_ctcss_freq(hertz, decimal, txtone)) 03277 return -1; 03278 03279 h = atoi(hertz); 03280 d = atoi(decimal); 03281 03282 cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10; 03283 cmdstr[1] = ((h % 10) << 4) + (d % 10); 03284 03285 if(rxtone){ 03286 03287 if(split_ctcss_freq(hertz, decimal, rxtone)) 03288 return -1; 03289 03290 h = atoi(hertz); 03291 d = atoi(decimal); 03292 03293 cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10; 03294 cmdstr[3] = ((h % 10) << 4) + (d % 10); 03295 } 03296 cmdstr[4] = 0x0B; 03297 03298 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 03299 }
| static int set_ctcss_mode_ft897 | ( | struct rpt * | myrpt, | |
| char | txplon, | |||
| char | rxplon | |||
| ) | [static] |
Definition at line 3245 of file app_rpt.c.
References serial_remote_io().
Referenced by set_ft897().
03246 { 03247 unsigned char cmdstr[5]; 03248 03249 memset(cmdstr, 0, 5); 03250 03251 if(rxplon && txplon) 03252 cmdstr[0] = 0x2A; /* Encode and Decode */ 03253 else if (!rxplon && txplon) 03254 cmdstr[0] = 0x4A; /* Encode only */ 03255 else if (rxplon && !txplon) 03256 cmdstr[0] = 0x3A; /* Encode only */ 03257 else 03258 cmdstr[0] = 0x8A; /* OFF */ 03259 03260 cmdstr[4] = 0x0A; 03261 03262 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 03263 }
| static int set_freq_ft897 | ( | struct rpt * | myrpt, | |
| char * | newfreq | |||
| ) | [static] |
Definition at line 3137 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_freq().
Referenced by multimode_bump_freq_ft897(), and set_ft897().
03138 { 03139 char mhz[MAXREMSTR]; 03140 char decimals[MAXREMSTR]; 03141 unsigned char cmdstr[5]; 03142 int fd,m,d; 03143 03144 fd = 0; 03145 if(debug) 03146 printf("New frequency: %s\n",newfreq); 03147 03148 if(split_freq(mhz, decimals, newfreq)) 03149 return -1; 03150 03151 m = atoi(mhz); 03152 d = atoi(decimals); 03153 03154 /* The FT-897 likes packed BCD frequencies */ 03155 03156 cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10); /* 100MHz 10Mhz */ 03157 cmdstr[1] = ((m % 10) << 4) + (d / 10000); /* 1MHz 100KHz */ 03158 cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100); /* 10KHz 1KHz */ 03159 cmdstr[3] = (((d % 100)/10) << 4) + (d % 10); /* 100Hz 10Hz */ 03160 cmdstr[4] = 0x01; /* command */ 03161 03162 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 03163 03164 }
| static int set_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 3303 of file app_rpt.c.
References rpt::freq, rpt::offset, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, rpt::remmode, rpt::rxpl, rpt::rxplon, set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), simple_command_ft897(), rpt::txpl, and rpt::txplon.
Referenced by setrem().
03304 { 03305 int res; 03306 03307 if(debug) 03308 printf("@@@@ lock on\n"); 03309 03310 res = simple_command_ft897(myrpt, 0x00); /* LOCK on */ 03311 03312 if(debug) 03313 printf("@@@@ ptt off\n"); 03314 03315 if(!res) 03316 res = simple_command_ft897(myrpt, 0x88); /* PTT off */ 03317 03318 if(debug) 03319 printf("Modulation mode\n"); 03320 03321 if(!res) 03322 res = set_mode_ft897(myrpt, myrpt->remmode); /* Modulation mode */ 03323 03324 if(debug) 03325 printf("Split off\n"); 03326 03327 if(!res) 03328 simple_command_ft897(myrpt, 0x82); /* Split off */ 03329 03330 if(debug) 03331 printf("Frequency\n"); 03332 03333 if(!res) 03334 res = set_freq_ft897(myrpt, myrpt->freq); /* Frequency */ 03335 if((myrpt->remmode == REM_MODE_FM)){ 03336 if(debug) 03337 printf("Offset\n"); 03338 if(!res) 03339 res = set_offset_ft897(myrpt, myrpt->offset); /* Offset if FM */ 03340 if((!res)&&(myrpt->rxplon || myrpt->txplon)){ 03341 if(debug) 03342 printf("CTCSS tone freqs.\n"); 03343 res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */ 03344 } 03345 if(!res){ 03346 if(debug) 03347 printf("CTCSS mode\n"); 03348 res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */ 03349 } 03350 } 03351 if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){ 03352 if(debug) 03353 printf("Clarifier off\n"); 03354 simple_command_ft897(myrpt, 0x85); /* Clarifier off if LSB or USB */ 03355 } 03356 return res; 03357 }
| static int set_mode_ft897 | ( | struct rpt * | myrpt, | |
| char | newmode | |||
| ) | [static] |
Definition at line 3212 of file app_rpt.c.
References REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, and serial_remote_io().
Referenced by rpt_exec(), and set_ft897().
03213 { 03214 unsigned char cmdstr[5]; 03215 03216 memset(cmdstr, 0, 5); 03217 03218 switch(newmode){ 03219 case REM_MODE_FM: 03220 cmdstr[0] = 0x08; 03221 break; 03222 03223 case REM_MODE_USB: 03224 cmdstr[0] = 0x01; 03225 break; 03226 03227 case REM_MODE_LSB: 03228 cmdstr[0] = 0x00; 03229 break; 03230 03231 case REM_MODE_AM: 03232 cmdstr[0] = 0x04; 03233 break; 03234 03235 default: 03236 return -1; 03237 } 03238 cmdstr[4] = 0x07; 03239 03240 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 03241 }
| static int set_offset_ft897 | ( | struct rpt * | myrpt, | |
| char | offset | |||
| ) | [static] |
Definition at line 3182 of file app_rpt.c.
References REM_MINUS, REM_PLUS, REM_SIMPLEX, and serial_remote_io().
Referenced by set_ft897().
03183 { 03184 unsigned char cmdstr[5]; 03185 03186 memset(cmdstr, 0, 5); 03187 03188 switch(offset){ 03189 case REM_SIMPLEX: 03190 cmdstr[0] = 0x89; 03191 break; 03192 03193 case REM_MINUS: 03194 cmdstr[0] = 0x09; 03195 break; 03196 03197 case REM_PLUS: 03198 cmdstr[0] = 0x49; 03199 break; 03200 03201 default: 03202 return -1; 03203 } 03204 03205 cmdstr[4] = 0x09; 03206 03207 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 03208 }
| static int setrbi | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 2857 of file app_rpt.c.
References rpt::freq, MAXREMSTR, rpt::offset, rpt::powerlevel, rbi_mhztoband(), rbi_out(), rbi_pltocode(), REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_PLUS, REM_SIMPLEX, rpt::remote, rpt::rxplon, s, rpt::txpl, and rpt::txplon.
Referenced by setrem().
02858 { 02859 char tmp[MAXREMSTR] = "",rbicmd[5],*s; 02860 int band,txoffset = 0,txpower = 0,txpl; 02861 02862 /* must be a remote system */ 02863 if (!myrpt->remote) return(0); 02864 /* must have rbi hardware */ 02865 if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0); 02866 strncpy(tmp, myrpt->freq, sizeof(tmp) - 1); 02867 s = strchr(tmp,'.'); 02868 /* if no decimal, is invalid */ 02869 02870 if (s == NULL){ 02871 if(debug) 02872 printf("@@@@ Frequency needs a decimal\n"); 02873 return -1; 02874 } 02875 02876 *s++ = 0; 02877 if (strlen(tmp) < 2){ 02878 if(debug) 02879 printf("@@@@ Bad MHz digits: %s\n", tmp); 02880 return -1; 02881 } 02882 02883 if (strlen(s) < 3){ 02884 if(debug) 02885 printf("@@@@ Bad KHz digits: %s\n", s); 02886 return -1; 02887 } 02888 02889 if ((s[2] != '0') && (s[2] != '5')){ 02890 if(debug) 02891 printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]); 02892 return -1; 02893 } 02894 02895 band = rbi_mhztoband(tmp); 02896 if (band == -1){ 02897 if(debug) 02898 printf("@@@@ Bad Band: %s\n", tmp); 02899 return -1; 02900 } 02901 02902 txpl = rbi_pltocode(myrpt->txpl); 02903 02904 if (txpl == -1){ 02905 if(debug) 02906 printf("@@@@ Bad TX PL: %s\n", myrpt->txpl); 02907 return -1; 02908 } 02909 02910 02911 switch(myrpt->offset) 02912 { 02913 case REM_MINUS: 02914 txoffset = 0; 02915 break; 02916 case REM_PLUS: 02917 txoffset = 0x10; 02918 break; 02919 case REM_SIMPLEX: 02920 txoffset = 0x20; 02921 break; 02922 } 02923 switch(myrpt->powerlevel) 02924 { 02925 case REM_LOWPWR: 02926 txpower = 0; 02927 break; 02928 case REM_MEDPWR: 02929 txpower = 0x20; 02930 break; 02931 case REM_HIPWR: 02932 txpower = 0x10; 02933 break; 02934 } 02935 rbicmd[0] = 0; 02936 rbicmd[1] = band | txpower | 0xc0; 02937 rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80; 02938 if (s[2] == '5') rbicmd[2] |= 0x40; 02939 rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0'); 02940 rbicmd[4] = txpl; 02941 if (myrpt->txplon) rbicmd[4] |= 0x40; 02942 if (myrpt->rxplon) rbicmd[4] |= 0x80; 02943 rbi_out(myrpt,rbicmd); 02944 return 0; 02945 }
| static int setrem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 3415 of file app_rpt.c.
References rpt::remote, set_ft897(), and setrbi().
Referenced by function_remote(), and rpt_exec().
03416 { 03417 if(!strcmp(myrpt->remote, remote_rig_ft897)) 03418 return set_ft897(myrpt); 03419 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 03420 return setrbi(myrpt); 03421 else 03422 return -1; 03423 }
| static int simple_command_ft897 | ( | struct rpt * | myrpt, | |
| char | command | |||
| ) | [static] |
Definition at line 3168 of file app_rpt.c.
References serial_remote_io().
Referenced by closerem_ft897(), rpt_exec(), and set_ft897().
03169 { 03170 unsigned char cmdstr[5]; 03171 03172 memset(cmdstr, 0, 5); 03173 03174 cmdstr[4] = command; 03175 03176 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 03177 03178 }
| static int split_ctcss_freq | ( | char * | hertz, | |
| char * | decimal, | |||
| char * | freq | |||
| ) | [static] |
Definition at line 3015 of file app_rpt.c.
References MAXREMSTR.
Referenced by set_ctcss_freq_ft897().
03016 { 03017 char freq_copy[MAXREMSTR]; 03018 char *decp; 03019 03020 decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.'); 03021 if(decp){ 03022 *decp++ = 0; 03023 strncpy(hertz, freq_copy, MAXREMSTR); 03024 strncpy(decimal, decp, strlen(decp)); 03025 decimal[strlen(decp)] = '\0'; 03026 return 0; 03027 } 03028 else 03029 return -1; 03030 }
| static int split_freq | ( | char * | mhz, | |
| char * | decimals, | |||
| char * | freq | |||
| ) | [static] |
Definition at line 2992 of file app_rpt.c.
References MAXREMSTR.
Referenced by function_remote(), multimode_bump_freq_ft897(), service_scan(), and set_freq_ft897().
02993 { 02994 char freq_copy[MAXREMSTR]; 02995 char *decp; 02996 02997 decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.'); 02998 if(decp){ 02999 *decp++ = 0; 03000 strncpy(mhz, freq_copy, MAXREMSTR); 03001 strcpy(decimals, "00000"); 03002 strncpy(decimals, decp, strlen(decp)); 03003 decimals[5] = 0; 03004 return 0; 03005 } 03006 else 03007 return -1; 03008 03009 }
| static void stop_scan | ( | struct rpt * | myrpt, | |
| int | flag | |||
| ) | [static] |
Definition at line 3475 of file app_rpt.c.
References rpt::hfscanmode, and rpt::hfscanstatus.
Referenced by handle_remote_dtmf_digit(), and service_scan().
03476 { 03477 myrpt->hfscanmode = 0; 03478 myrpt->hfscanstatus = ((flag) ? -2 : -1); 03479 }
| static int telem_any | ( | struct ast_channel * | chan, | |
| char * | entry | |||
| ) | [static] |
Definition at line 794 of file app_rpt.c.
References MORSE, retrieve_astcfgint(), sayfile(), send_morse(), and send_tone_telemetry().
Referenced by rpt_tele_thread(), and telem_lookup().
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){ /* Get the morse parameters if not already loaded */ 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 /* Is it a file, or a tone sequence? */ 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': /* Morse ID */ 00825 res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl); 00826 break; 00827 00828 case 'M': /* Morse Message */ 00829 res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl); 00830 break; 00831 00832 case 'T': /* Tone sequence */ 00833 res = send_tone_telemetry(chan, entry + 2); 00834 break; 00835 default: 00836 res = -1; 00837 } 00838 } 00839 else 00840 res = sayfile(chan, entry); /* File */ 00841 return res; 00842 }
| static int telem_lookup | ( | struct ast_channel * | chan, | |
| char * | node, | |||
| char * | name | |||
| ) | [static] |
Definition at line 850 of file app_rpt.c.
References ast_log(), ast_strdupa, ast_variable_retrieve(), LOG_WARNING, telem_any(), and TELEMETRY.
Referenced by handle_remote_data(), handle_remote_phone_dtmf(), and rpt_tele_thread().
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 /* Retrieve the section name for telemetry from the node section */ 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 /* Try to look up the telemetry name */ 00877 00878 if(!entry){ 00879 /* Telemetry name wasn't found in the config file, use the default */ 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 }
| int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 6521 of file app_rpt.c.
References ast_cli_unregister(), ast_mutex_destroy(), ast_unregister_application(), lock, name, rpt_vars, and STANDARD_HANGUP_LOCALUSERS.
06522 { 06523 int i; 06524 06525 STANDARD_HANGUP_LOCALUSERS; 06526 for(i = 0; i < nrpts; i++) { 06527 if (!strcmp(rpt_vars[i].name,rpt_vars[i].nodes)) continue; 06528 ast_mutex_destroy(&rpt_vars[i].lock); 06529 } 06530 i = ast_unregister_application(app); 06531 06532 /* Unregister cli extensions */ 06533 ast_cli_unregister(&cli_debug); 06534 06535 return i; 06536 }
| int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 6553 of file app_rpt.c.
References STANDARD_USECOUNT.
06554 { 06555 int res; 06556 STANDARD_USECOUNT(res); 06557 return res; 06558 }
| static void wait_interval | ( | struct rpt * | myrpt, | |
| int | type, | |||
| struct ast_channel * | chan | |||
| ) | [static] |
Definition at line 955 of file app_rpt.c.
References ast_safe_sleep(), and get_wait_interval().
Referenced by rpt_tele_thread().
00956 { 00957 int interval; 00958 if((interval = get_wait_interval(myrpt, type))) 00959 ast_safe_sleep(chan,interval); 00960 return; 00961 }
| struct ast_config* cfg |
Definition at line 248 of file app_rpt.c.
Referenced by ast_enum_init(), ast_load_resource(), ast_readconfig(), ast_rtp_reload(), authenticate(), conf_exec(), config_load(), directory_exec(), festival_exec(), find_conf(), handle_save_dialplan(), iax_provision_reload(), ind_load_module(), init_logger_chain(), init_manager(), load_config(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), loadconfigurationfile(), misdn_cfg_init(), my_load_module(), odbc_load_module(), parse_config(), pbx_load_module(), privacy_exec(), read_agent_config(), realtime_directory(), realtime_multi_odbc(), realtime_switch_common(), reload_config(), reload_queues(), set_config(), setup_zap(), and tds_load_module().
struct ast_cli_entry cli_debug [static] |
Initial value:
{ { "rpt", "debug", "level" }, rpt_do_debug, "Enable app_rpt debugging", debug_usage }
char debug_usage[] [static] |
struct function_table_tag function_table[] [static] |
char* remote_rig_ft897 = "ft897" [static] |
char* remote_rig_rbi = "rbi" [static] |
pthread_t rpt_master_thread [static] |
Referenced by rpt_exec(), rpt_master(), and unload_module().
char* synopsis = "Radio Repeater/Remote Base Control System" [static] |
char* tdesc = "Radio Repeater / Remote Base version 0.37 11/03/2005" [static] |
struct telem_defaults tele_defs[] [static] |
1.5.6