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