#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 <sys/vfs.h>
#include <math.h>
#include <zaptel/zaptel.h>
#include <zaptel/tonezone.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"
#include "asterisk/cdr.h"
#include <termios.h>
Go to the source code of this file.
Data Structures | |
struct | function_table_tag |
struct | morse_bits |
struct | nodelog |
struct | rpt |
struct | rpt_chan_stat |
struct | rpt_link |
struct | rpt_lstat |
struct | rpt_tele |
struct | rpt_xlat |
struct | sysstate |
struct | telem_defaults |
Defines | |
#define | ACTIONSIZE 32 |
#define | ALLOW_LOCAL_CHANNELS |
#define | AUTHLOGOUTTIME 25000 |
#define | AUTHTELLTIME 7000 |
#define | AUTHTXTIME 1000 |
#define | DEFAULT_CIV_ADDR 0x58 |
#define | DEFAULT_IOBASE 0x378 |
#define | DEFAULT_MONITOR_MIN_DISK_BLOCKS 10000 |
#define | DEFAULT_REMOTE_INACT_TIMEOUT (15 * 60) |
#define | DEFAULT_REMOTE_TIMEOUT (60 * 60) |
#define | DEFAULT_REMOTE_TIMEOUT_WARNING (3 * 60) |
#define | DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ 30 |
#define | DELIMCHR ',' |
#define | DISC_TIME 10000 |
#define | DTMF_LOCAL_STARTTIME 500 |
#define | DTMF_LOCAL_TIME 250 |
#define | DTMF_TIMEOUT 3 |
#define | ENDCHAR '#' |
#define | EXTNODEFILE "/var/lib/asterisk/rpt_extnodes" |
#define | EXTNODES "extnodes" |
#define | FUNCCHAR '*' |
#define | FUNCTDELAY 1500 |
#define | FUNCTIONS "functions" |
#define | HANGTIME 5000 |
#define | IC706_PL_MEMORY_OFFSET 50 |
#define | IDTIME 300000 |
#define | KENWOOD_RETRIES 5 |
#define | LINKLISTSHORTTIME 200 |
#define | LINKLISTTIME 10000 |
#define | MACRO "macro" |
#define | MACROPTIME 500 |
#define | MACROTIME 100 |
#define | MAX_RETRIES 5 |
#define | MAX_RETRIES_PERM 1000000000 |
#define | MAX_STAT_LINKS 32 |
#define | MAX_SYSSTATES 10 |
#define | MAXCONNECTTIME 5000 |
#define | MAXDTMF 32 |
#define | MAXLINKLIST 512 |
#define | MAXMACRO 2048 |
#define | MAXNODESTR 300 |
#define | MAXPATCHCONTEXT 100 |
#define | MAXPEERSTR 31 |
#define | MAXREMSTR 15 |
#define | MAXRPTS 20 |
#define | MAXXLAT 20 |
#define | MAXXLATTIME 3 |
#define | MEMORY "memory" |
#define | MONITOR_DISK_BLOCKS_PER_MINUTE 38 |
#define | MORSE "morse" |
#define | MSWAIT 200 |
#define | NODES "nodes" |
#define | NRPTSTAT 7 |
#define | OLDKEY |
#define | POLITEID 30000 |
#define | QUOTECHR 34 |
#define | REDUNDANT_TX_TIME 2000 |
#define | REM_SCANTIME 100 |
#define | RETRY_TIMER_MS 5000 |
#define | rpt_mutex_lock(x) ast_mutex_lock(x) |
#define | rpt_mutex_unlock(x) ast_mutex_unlock(x) |
#define | START_DELAY 2 |
#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, TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY, FULLSTATUS, MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS, REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE, TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX } |
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_COMPLETEQUIET, DC_DOKEY } |
enum | { SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE } |
enum | { DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM, DLY_COMP, DLY_LINKUNKEY } |
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 } |
enum | { TOP_TOP, TOP_WON, WON_BEFREAD, BEFREAD_AFTERREAD } |
Functions | |
static void | __kickshort (struct rpt *myrpt) |
static void | __mklinklist (struct rpt *myrpt, struct rpt_link *mylink, char *buf) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Radio Repeater/Remote Base Application",.load=load_module,.unload=unload_module,.reload=reload,) | |
AST_MUTEX_DEFINE_STATIC (nodelookuplock) | |
AST_MUTEX_DEFINE_STATIC (nodeloglock) | |
int | ast_playtones_start (struct ast_channel *chan, int vol, const char *tonelist, int interruptible) |
void | ast_playtones_stop (struct ast_channel *chan) |
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_ic706 (int m, int d, int *defmode) |
static int | check_freq_kenwood (int m, int d, int *defmode) |
static int | check_freq_rbi (int m, int d, int *defmode) |
static char | check_tx_freq (struct rpt *myrpt) |
static int | civ_cmd (struct rpt *myrpt, unsigned char *cmd, int cmdlen) |
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) |
static int | connect_link (struct rpt *myrpt, char *node, int mode, int perma) |
static int | decimals2int (char *fraction) |
static long | diskavail (struct rpt *myrpt) |
static void | do_dtmf_local (struct rpt *myrpt, char c) |
static void | do_dtmf_phone (struct rpt *myrpt, struct rpt_link *mylink, char c) |
static void | do_scheduler (struct rpt *myrpt) |
static void | donodelog (struct rpt *myrpt, char *str) |
static char * | eatwhite (char *s) |
static int | finddelim (char *str, char *strp[], int limit) |
static char | func_xlat (struct rpt *myrpt, char c, struct rpt_xlat *xlat) |
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_macro (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) |
static int | ic706_pltocode (char *str) |
static int | kenwood_pltocode (char *str) |
static int | load_module (void) |
static void | load_rpt_vars (int n, int init) |
static void | local_dtmf_helper (struct rpt *myrpt, char c) |
static int | matchkeyword (char *string, char **param, char *keywords[]) |
static void | mdc1200_notify (struct rpt *myrpt, char *fromnode, unsigned int unit) |
static int | mem2vfo_ic706 (struct rpt *myrpt) |
static int | multimode_bump_freq (struct rpt *myrpt, int interval) |
static int | multimode_bump_freq_ft897 (struct rpt *myrpt, int interval) |
static int | multimode_bump_freq_ic706 (struct rpt *myrpt, int interval) |
static int | multimode_capable (struct rpt *myrpt) |
static int | myatoi (char *str) |
static int | mycompar (const void *a, const void *b) |
static char * | node_lookup (struct rpt *myrpt, char *digitbuf) |
static int | openserial (char *fname) |
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 void | queue_id (struct rpt *myrpt) |
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 | reload (void) |
static int | retreive_memory (struct rpt *myrpt, char *memory) |
static int | retrieve_astcfgint (struct rpt *myrpt, char *category, char *name, int min, int max, int defl) |
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_do_dump (int fd, int argc, char *argv[]) |
static int | rpt_do_fun (int fd, int argc, char *argv[]) |
static int | rpt_do_lstats (int fd, int argc, char *argv[]) |
static int | rpt_do_nodes (int fd, int argc, char *argv[]) |
static int | rpt_do_reload (int fd, int argc, char *argv[]) |
static int | rpt_do_restart (int fd, int argc, char *argv[]) |
static int | rpt_do_stats (int fd, int argc, char *argv[]) |
static int | rpt_exec (struct ast_channel *chan, void *data) |
static void | rpt_localtime (time_t *t, struct tm *lt) |
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 int | select_mem_ic706 (struct rpt *myrpt, int slot) |
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 | sendkenwood (struct rpt *myrpt, char *txstr, char *rxstr) |
static int | sendrxkenwood (struct rpt *myrpt, char *txstr, char *rxstr, char *cmpstr) |
static int | serial_remote_io (struct rpt *myrpt, unsigned char *txbuf, int txbytes, unsigned 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_ctcss_mode_ic706 (struct rpt *myrpt, char txplon, char rxplon) |
static int | set_freq_ft897 (struct rpt *myrpt, char *newfreq) |
static int | set_freq_ic706 (struct rpt *myrpt, char *newfreq) |
static int | set_ft897 (struct rpt *myrpt) |
static int | set_ic706 (struct rpt *myrpt) |
static int | set_mode_ft897 (struct rpt *myrpt, char newmode) |
static int | set_mode_ic706 (struct rpt *myrpt, char newmode) |
static int | set_offset_ft897 (struct rpt *myrpt, char offset) |
static int | set_offset_ic706 (struct rpt *myrpt, char offset) |
static int | setkenwood (struct rpt *myrpt) |
static int | setrbi (struct rpt *myrpt) |
static int | setrbi_check (struct rpt *myrpt) |
static int | setrem (struct rpt *myrpt) |
static int | simple_command_ft897 (struct rpt *myrpt, char command) |
static int | simple_command_ic706 (struct rpt *myrpt, char command, char subcommand) |
static char * | skipchars (char *string, char *charlist) |
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) |
static int | telem_any (struct rpt *myrpt, struct ast_channel *chan, char *entry) |
static int | telem_lookup (struct rpt *myrpt, struct ast_channel *chan, char *node, char *name) |
static int | unload_module (void) |
static int | vfo_ic706 (struct rpt *myrpt) |
static void | wait_interval (struct rpt *myrpt, int type, struct ast_channel *chan) |
Variables | |
static char * | app = "Rpt" |
static struct ast_cli_entry | cli_debug |
static struct ast_cli_entry | cli_dump |
static struct ast_cli_entry | cli_fun |
static struct ast_cli_entry | cli_lstats |
static struct ast_cli_entry | cli_nodes |
static struct ast_cli_entry | cli_reload |
static struct ast_cli_entry | cli_restart |
static struct ast_cli_entry | cli_stats |
static int | debug = 0 |
static char | debug_usage [] |
static char * | descrip |
char * | discstr = "!!DISCONNECT!!" |
static char | dump_lstats [] |
static char | dump_nodes [] |
static char | dump_stats [] |
static char | dump_usage [] |
static char | fun_usage [] |
static struct function_table_tag | function_table [] |
int | max_chan_stat [] = {22000,1000,22000,100,22000,2000,22000} |
static int | nrpts = 0 |
static char | reload_usage [] |
static char | remdtmfstr [] = "0123456789*#ABCD" |
static char * | remote_rig_ft897 = "ft897" |
static char * | remote_rig_ic706 = "ic706" |
static char * | remote_rig_kenwood = "kenwood" |
static char * | remote_rig_rbi = "rbi" |
static char | restart_usage [] |
static pthread_t | rpt_master_thread |
static struct rpt | rpt_vars [MAXRPTS] |
static time_t | starttime = 0 |
static char * | synopsis = "Radio Repeater/Remote Base Control System" |
static char * | tdesc = "Radio Repeater / Remote Base version 0.73 09/04/2007" |
static struct telem_defaults | tele_defs [] |
Repeater / Remote Functions: "Simple" Mode: * - autopatch access, # - autopatch hangup Normal mode: See the function list in rpt.conf (autopatchup, autopatchdn) autopatchup can optionally take comma delimited setting=value pairs:
context=string : Override default context with "string" dialtime=ms : Specify the max number of milliseconds between phone number digits (1000 milliseconds = 1 second) farenddisconnect=1 : Automatically disconnect when called party hangs up noct=1 : Don't send repeater courtesy tone during autopatch calls quiet=1 : Don't send dial tone, or connect messages. Do not send patch down message when called party hangs up
Example: 123=autopatchup,dialtime=20000,noct=1,farenddisconnect=1
To send an asterisk (*) while dialing or talking on phone, use the autopatch acess code.
status cmds:
1 - Force ID 2 - Give Time of Day 3 - Give software Version
cop (control operator) cmds:
1 - System warm boot 2 - System enable 3 - System disable 4 - Test Tone On/Off 5 - Dump System Variables on Console (debug) 6 - PTT (phone mode only) 7 - Time out timer enable 8 - Time out timer disable 9 - Autopatch enable 10 - Autopatch disable 11 - Link enable 12 - Link disable 13 - Query System State 14 - Change System State 15 - Scheduler Enable 16 - Scheduler Disable 17 - User functions (time, id, etc) enable 18 - User functions (time, id, etc) disable 19 - Select alternate hang timer 20 - Select standard hang timer
ilink cmds:
1 - Disconnect specified link 2 - Connect specified link -- monitor only 3 - Connect specified link -- tranceive 4 - Enter command mode on specified link 5 - System status 6 - Disconnect all links 11 - Disconnect a previously permanently connected link 12 - Permanently connect specified link -- monitor only 13 - Permanently connect specified link -- tranceive 15 - Full system status (all nodes) 16 - Reconnect links disconnected with "disconnect all links" 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
remote cmds:
1 - Recall Memory MM (*000-*099) (Gets memory from rpt.conf) 2 - Set VFO MMMMM*KKK*O (Mhz digits, Khz digits, Offset) 3 - Set Rx PL Tone HHH*D* 4 - Set Tx PL Tone HHH*D* (Not currently implemented with DHE RBI-1) 5 - Link Status (long) 6 - Set operating mode M (FM, USB, LSB, AM, etc) 100 - RX PL off (Default) 101 - RX PL On 102 - TX PL Off (Default) 103 - TX PL On 104 - Low Power 105 - Med Power 106 - Hi Power 107 - Bump Down 20 Hz 108 - Bump Down 100 Hz 109 - Bump Down 500 Hz 110 - Bump Up 20 Hz 111 - Bump Up 100 Hz 112 - Bump Up 500 Hz 113 - Scan Down Slow 114 - Scan Down Medium 115 - Scan Down Fast 116 - Scan Up Slow 117 - Scan Up Medium 118 - Scan Up Fast 119 - Transmit allowing auto-tune 140 - Link Status (brief) 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
'duplex' modes: (defaults to duplex=2)
0 - Only remote links key Tx and no main repeat audio. 1 - Everything other then main Rx keys Tx, no main repeat audio. 2 - Normal mode 3 - Normal except no main repeat audio. 4 - Normal except no main repeat audio during autopatch only
Definition in file app_rpt.c.
#define AUTHLOGOUTTIME 25000 |
#define AUTHTELLTIME 7000 |
#define AUTHTXTIME 1000 |
#define DEFAULT_CIV_ADDR 0x58 |
#define DEFAULT_IOBASE 0x378 |
#define DEFAULT_MONITOR_MIN_DISK_BLOCKS 10000 |
#define DEFAULT_REMOTE_INACT_TIMEOUT (15 * 60) |
#define DEFAULT_REMOTE_TIMEOUT (60 * 60) |
#define DEFAULT_REMOTE_TIMEOUT_WARNING (3 * 60) |
#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ 30 |
#define DELIMCHR ',' |
#define DTMF_LOCAL_STARTTIME 500 |
#define DTMF_LOCAL_TIME 250 |
#define DTMF_TIMEOUT 3 |
#define ENDCHAR '#' |
#define EXTNODEFILE "/var/lib/asterisk/rpt_extnodes" |
#define EXTNODES "extnodes" |
#define FUNCCHAR '*' |
#define FUNCTIONS "functions" |
#define HANGTIME 5000 |
#define IC706_PL_MEMORY_OFFSET 50 |
#define IDTIME 300000 |
#define KENWOOD_RETRIES 5 |
#define LINKLISTSHORTTIME 200 |
#define MACRO "macro" |
#define MACROPTIME 500 |
#define MACROTIME 100 |
Definition at line 160 of file app_rpt.c.
Referenced by do_scheduler(), function_macro(), rpt(), rpt_do_fun(), and rpt_exec().
#define MAX_RETRIES 5 |
Definition at line 174 of file app_rpt.c.
Referenced by connect_link(), function_ilink(), and rpt_exec().
#define MAX_RETRIES_PERM 1000000000 |
#define MAX_STAT_LINKS 32 |
#define MAX_SYSSTATES 10 |
#define MAXDTMF 32 |
Definition at line 155 of file app_rpt.c.
Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and local_dtmf_helper().
#define MAXLINKLIST 512 |
Definition at line 157 of file app_rpt.c.
Referenced by __mklinklist(), connect_link(), function_ilink(), rpt(), rpt_do_nodes(), and rpt_tele_thread().
#define MAXMACRO 2048 |
Definition at line 156 of file app_rpt.c.
Referenced by do_scheduler(), function_macro(), rpt(), rpt_do_fun(), and rpt_exec().
#define MAXNODESTR 300 |
Definition at line 214 of file app_rpt.c.
Referenced by connect_link(), function_ilink(), and rpt_exec().
#define MAXPATCHCONTEXT 100 |
Definition at line 216 of file app_rpt.c.
Referenced by function_autopatchup(), and local_dtmf_helper().
#define MAXPEERSTR 31 |
#define MAXREMSTR 15 |
Definition at line 184 of file app_rpt.c.
Referenced by check_tx_freq(), function_remote(), multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), rpt_do_lstats(), rpt_tele_thread(), service_scan(), set_ctcss_freq_ft897(), set_freq_ft897(), set_freq_ic706(), setkenwood(), setrbi(), setrbi_check(), split_ctcss_freq(), and split_freq().
#define MAXXLAT 20 |
#define MAXXLATTIME 3 |
#define MEMORY "memory" |
#define MONITOR_DISK_BLOCKS_PER_MINUTE 38 |
#define MORSE "morse" |
#define MSWAIT 200 |
#define NODES "nodes" |
#define NRPTSTAT 7 |
#define POLITEID 30000 |
#define QUOTECHR 34 |
#define REDUNDANT_TX_TIME 2000 |
#define REM_SCANTIME 100 |
#define rpt_mutex_lock | ( | x | ) | ast_mutex_lock(x) |
Definition at line 871 of file app_rpt.c.
Referenced by attempt_reconnect(), connect_link(), do_dtmf_local(), function_autopatchdn(), function_autopatchup(), function_ilink(), function_macro(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rpt_exec(), rpt_tele_thread(), and rpt_telemetry().
#define rpt_mutex_unlock | ( | x | ) | ast_mutex_unlock(x) |
Definition at line 872 of file app_rpt.c.
Referenced by attempt_reconnect(), connect_link(), do_dtmf_local(), function_autopatchdn(), function_autopatchup(), function_ilink(), function_macro(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rpt_exec(), rpt_tele_thread(), and rpt_telemetry().
#define START_DELAY 2 |
#define TELEMETRY "telemetry" |
#define TELEPARAMSIZE 256 |
#define TOTIME 180000 |
anonymous enum |
anonymous enum |
Definition at line 233 of file app_rpt.c.
00233 {ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO, 00234 CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME, 00235 STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH, 00236 TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY, FULLSTATUS, 00237 MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS, 00238 REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE, 00239 TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX};
anonymous enum |
anonymous enum |
anonymous enum |
Definition at line 246 of file app_rpt.c.
00246 {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY};
anonymous enum |
Definition at line 248 of file app_rpt.c.
00248 {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE};
anonymous enum |
Definition at line 250 of file app_rpt.c.
00250 {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM, DLY_COMP, DLY_LINKUNKEY};
anonymous enum |
Definition at line 252 of file app_rpt.c.
00252 {REM_MODE_FM,REM_MODE_USB,REM_MODE_LSB,REM_MODE_AM};
anonymous enum |
HF_SCAN_OFF | |
HF_SCAN_DOWN_SLOW | |
HF_SCAN_DOWN_QUICK | |
HF_SCAN_DOWN_FAST | |
HF_SCAN_UP_SLOW | |
HF_SCAN_UP_QUICK | |
HF_SCAN_UP_FAST |
Definition at line 254 of file app_rpt.c.
00254 {HF_SCAN_OFF,HF_SCAN_DOWN_SLOW,HF_SCAN_DOWN_QUICK, 00255 HF_SCAN_DOWN_FAST,HF_SCAN_UP_SLOW,HF_SCAN_UP_QUICK,HF_SCAN_UP_FAST};
anonymous enum |
static void __kickshort | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 1397 of file app_rpt.c.
References LINKLISTSHORTTIME, rpt_link::linklisttimer, rpt::links, rpt_link::name, and rpt_link::next.
Referenced by connect_link(), rpt(), and rpt_exec().
01398 { 01399 struct rpt_link *l; 01400 01401 for(l = myrpt->links.next; l != &myrpt->links; l = l->next) 01402 { 01403 /* if is not a real link, ignore it */ 01404 if (l->name[0] == '0') continue; 01405 l->linklisttimer = LINKLISTSHORTTIME; 01406 } 01407 return; 01408 }
Definition at line 1348 of file app_rpt.c.
References rpt_link::linklist, rpt::links, MAXLINKLIST, rpt_link::mode, rpt_link::name, rpt_link::next, and rpt_link::thisconnected.
Referenced by connect_link(), rpt(), rpt_do_nodes(), and rpt_tele_thread().
01349 { 01350 struct rpt_link *l; 01351 char mode; 01352 int i,spos; 01353 01354 buf[0] = 0; /* clear output buffer */ 01355 /* go thru all links */ 01356 for(l = myrpt->links.next; l != &myrpt->links; l = l->next) 01357 { 01358 /* if is not a real link, ignore it */ 01359 if (l->name[0] == '0') continue; 01360 /* dont count our stuff */ 01361 if (l == mylink) continue; 01362 if (mylink && (!strcmp(l->name,mylink->name))) continue; 01363 /* figure out mode to report */ 01364 mode = 'T'; /* use Tranceive by default */ 01365 if (!l->mode) mode = 'R'; /* indicate RX for our mode */ 01366 if (!l->thisconnected) mode = 'C'; /* indicate connecting */ 01367 spos = strlen(buf); /* current buf size (b4 we add our stuff) */ 01368 if (spos) 01369 { 01370 strcat(buf,","); 01371 spos++; 01372 } 01373 /* add nodes into buffer */ 01374 if (l->linklist[0]) 01375 { 01376 snprintf(buf + spos,MAXLINKLIST - spos, 01377 "%c%s,%s",mode,l->name,l->linklist); 01378 } 01379 else /* if no nodes, add this node into buffer */ 01380 { 01381 snprintf(buf + spos,MAXLINKLIST - spos, 01382 "%c%s",mode,l->name); 01383 } 01384 /* if we are in tranceive mode, let all modes stand */ 01385 if (mode == 'T') continue; 01386 /* downgrade everyone on this node if appropriate */ 01387 for(i = spos; buf[i]; i++) 01388 { 01389 if (buf[i] == 'T') buf[i] = mode; 01390 if ((buf[i] == 'R') && (mode == 'C')) buf[i] = mode; 01391 } 01392 } 01393 return; 01394 }
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Radio Repeater/Remote Base Application" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | nodelookuplock | ) |
AST_MUTEX_DEFINE_STATIC | ( | nodeloglock | ) |
int ast_playtones_start | ( | struct ast_channel * | chan, | |
int | vol, | |||
const char * | tonelist, | |||
int | interruptible | |||
) |
Definition at line 212 of file indications.c.
References ast_activate_generator(), ast_log(), ast_realloc, ast_strdupa, playtones_item::duration, playtones_item::fac1, playtones_item::fac2, free, playtones_item::init_v2_1, playtones_item::init_v2_2, playtones_item::init_v3_1, playtones_item::init_v3_2, playtones_def::interruptible, playtones_def::items, LOG_WARNING, playtones_item::modulate, playtones_def::nitems, playtones_def::reppos, s, strsep(), and playtones_def::vol.
Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dialtone_indicate(), do_dtmf_local(), handle_playtones(), play_dialtone(), playtone(), read_exec(), and send_digit_to_chan().
00213 { 00214 char *s, *data = ast_strdupa(playlst); /* cute */ 00215 struct playtones_def d = { vol, -1, 0, 1, NULL}; 00216 char *stringp; 00217 char *separator; 00218 00219 if (vol < 1) 00220 d.vol = 7219; /* Default to -8db */ 00221 00222 d.interruptible = interruptible; 00223 00224 stringp=data; 00225 /* the stringp/data is not null here */ 00226 /* check if the data is separated with '|' or with ',' by default */ 00227 if (strchr(stringp,'|')) 00228 separator = "|"; 00229 else 00230 separator = ","; 00231 s = strsep(&stringp,separator); 00232 while (s && *s) { 00233 int freq1, freq2, time, modulate=0, midinote=0; 00234 00235 if (s[0]=='!') 00236 s++; 00237 else if (d.reppos == -1) 00238 d.reppos = d.nitems; 00239 if (sscanf(s, "%d+%d/%d", &freq1, &freq2, &time) == 3) { 00240 /* f1+f2/time format */ 00241 } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) { 00242 /* f1+f2 format */ 00243 time = 0; 00244 } else if (sscanf(s, "%d*%d/%d", &freq1, &freq2, &time) == 3) { 00245 /* f1*f2/time format */ 00246 modulate = 1; 00247 } else if (sscanf(s, "%d*%d", &freq1, &freq2) == 2) { 00248 /* f1*f2 format */ 00249 time = 0; 00250 modulate = 1; 00251 } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) { 00252 /* f1/time format */ 00253 freq2 = 0; 00254 } else if (sscanf(s, "%d", &freq1) == 1) { 00255 /* f1 format */ 00256 freq2 = 0; 00257 time = 0; 00258 } else if (sscanf(s, "M%d+M%d/%d", &freq1, &freq2, &time) == 3) { 00259 /* Mf1+Mf2/time format */ 00260 midinote = 1; 00261 } else if (sscanf(s, "M%d+M%d", &freq1, &freq2) == 2) { 00262 /* Mf1+Mf2 format */ 00263 time = 0; 00264 midinote = 1; 00265 } else if (sscanf(s, "M%d*M%d/%d", &freq1, &freq2, &time) == 3) { 00266 /* Mf1*Mf2/time format */ 00267 modulate = 1; 00268 midinote = 1; 00269 } else if (sscanf(s, "M%d*M%d", &freq1, &freq2) == 2) { 00270 /* Mf1*Mf2 format */ 00271 time = 0; 00272 modulate = 1; 00273 midinote = 1; 00274 } else if (sscanf(s, "M%d/%d", &freq1, &time) == 2) { 00275 /* Mf1/time format */ 00276 freq2 = -1; 00277 midinote = 1; 00278 } else if (sscanf(s, "M%d", &freq1) == 1) { 00279 /* Mf1 format */ 00280 freq2 = -1; 00281 time = 0; 00282 midinote = 1; 00283 } else { 00284 ast_log(LOG_WARNING,"%s: tone component '%s' of '%s' is no good\n",chan->name,s,playlst); 00285 return -1; 00286 } 00287 00288 if (midinote) { 00289 /* midi notes must be between 0 and 127 */ 00290 if ((freq1 >= 0) && (freq1 <= 127)) 00291 freq1 = midi_tohz[freq1]; 00292 else 00293 freq1 = 0; 00294 00295 if ((freq2 >= 0) && (freq2 <= 127)) 00296 freq2 = midi_tohz[freq2]; 00297 else 00298 freq2 = 0; 00299 } 00300 00301 if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) { 00302 return -1; 00303 } 00304 d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0; 00305 d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * d.vol; 00306 d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * d.vol; 00307 00308 d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0; 00309 d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * d.vol; 00310 d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * d.vol; 00311 d.items[d.nitems].duration = time; 00312 d.items[d.nitems].modulate = modulate; 00313 d.nitems++; 00314 00315 s = strsep(&stringp,separator); 00316 } 00317 00318 if (ast_activate_generator(chan, &playtones, &d)) { 00319 free(d.items); 00320 return -1; 00321 } 00322 return 0; 00323 }
void ast_playtones_stop | ( | struct ast_channel * | chan | ) |
Stop the tones from playing
Definition at line 325 of file indications.c.
References ast_deactivate_generator().
Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_end(), disa_exec(), handle_stopplaytones(), playtone(), read_exec(), and stop_indicate().
00326 { 00327 ast_deactivate_generator(chan); 00328 }
Definition at line 8408 of file app_rpt.c.
References ast_call(), AST_FORMAT_SLINEAR, ast_log(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_verbose(), free, rpt::links, rpt::lock, LOG_NOTICE, rpt::name, rpt_link::name, rpt_link::next, node_lookup(), option_verbose, rpt_mutex_lock, rpt_mutex_unlock, s, strdup, strsep(), and VERBOSE_PREFIX_3.
Referenced by rpt().
08409 { 08410 char *val, *s, *s1, *s2, *tele; 08411 char tmp[300], deststr[300] = ""; 08412 08413 val = node_lookup(myrpt,l->name); 08414 if (!val) 08415 { 08416 fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name); 08417 return -1; 08418 } 08419 08420 rpt_mutex_lock(&myrpt->lock); 08421 /* remove from queue */ 08422 remque((struct qelem *) l); 08423 rpt_mutex_unlock(&myrpt->lock); 08424 strncpy(tmp,val,sizeof(tmp) - 1); 08425 s = tmp; 08426 s1 = strsep(&s,","); 08427 s2 = strsep(&s,","); 08428 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 08429 tele = strchr(deststr, '/'); 08430 if (!tele) { 08431 fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr); 08432 return -1; 08433 } 08434 *tele++ = 0; 08435 l->elaptime = 0; 08436 l->connecttime = 0; 08437 l->thisconnected = 0; 08438 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 08439 if (l->chan){ 08440 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 08441 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 08442 l->chan->whentohangup = 0; 08443 l->chan->appl = "Apprpt"; 08444 l->chan->data = "(Remote Rx)"; 08445 if (option_verbose > 2) 08446 ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n", 08447 deststr, tele, l->chan->name); 08448 if(l->chan->cid.cid_num) 08449 free(l->chan->cid.cid_num); 08450 l->chan->cid.cid_num = strdup(myrpt->name); 08451 ast_call(l->chan,tele,999); 08452 08453 } 08454 else 08455 { 08456 if (option_verbose > 2) 08457 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 08458 deststr,tele,l->chan->name); 08459 return -1; 08460 } 08461 rpt_mutex_lock(&myrpt->lock); 08462 /* put back in queue */ 08463 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 08464 rpt_mutex_unlock(&myrpt->lock); 08465 ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name); 08466 return 0; 08467 }
static int check_freq | ( | struct rpt * | myrpt, | |
int | m, | |||
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 7407 of file app_rpt.c.
References check_freq_ft897(), check_freq_ic706(), check_freq_kenwood(), check_freq_rbi(), and rpt::remote.
Referenced by function_remote().
07408 { 07409 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07410 return check_freq_ft897(m, d, defmode); 07411 else if(!strcmp(myrpt->remote, remote_rig_ic706)) 07412 return check_freq_ic706(m, d, defmode); 07413 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 07414 return check_freq_rbi(m, d, defmode); 07415 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) 07416 return check_freq_kenwood(m, d, defmode); 07417 else 07418 return -1; 07419 }
static int check_freq_ft897 | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6422 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().
06423 { 06424 int dflmd = REM_MODE_FM; 06425 06426 if(m == 1){ /* 160 meters */ 06427 dflmd = REM_MODE_LSB; 06428 if(d < 80000) 06429 return -1; 06430 } 06431 else if(m == 3){ /* 80 meters */ 06432 dflmd = REM_MODE_LSB; 06433 if(d < 50000) 06434 return -1; 06435 } 06436 else if(m == 7){ /* 40 meters */ 06437 dflmd = REM_MODE_LSB; 06438 if(d > 30000) 06439 return -1; 06440 } 06441 else if(m == 14){ /* 20 meters */ 06442 dflmd = REM_MODE_USB; 06443 if(d > 35000) 06444 return -1; 06445 } 06446 else if(m == 18){ /* 17 meters */ 06447 dflmd = REM_MODE_USB; 06448 if((d < 6800) || (d > 16800)) 06449 return -1; 06450 } 06451 else if(m == 21){ /* 15 meters */ 06452 dflmd = REM_MODE_USB; 06453 if((d < 20000) || (d > 45000)) 06454 return -1; 06455 } 06456 else if(m == 24){ /* 12 meters */ 06457 dflmd = REM_MODE_USB; 06458 if((d < 89000) || (d > 99000)) 06459 return -1; 06460 } 06461 else if(m == 28){ /* 10 meters */ 06462 dflmd = REM_MODE_USB; 06463 } 06464 else if(m == 29){ 06465 if(d >= 51000) 06466 dflmd = REM_MODE_FM; 06467 else 06468 dflmd = REM_MODE_USB; 06469 if(d > 70000) 06470 return -1; 06471 } 06472 else if(m == 50){ /* 6 meters */ 06473 if(d >= 30000) 06474 dflmd = REM_MODE_FM; 06475 else 06476 dflmd = REM_MODE_USB; 06477 06478 } 06479 else if((m >= 51) && ( m < 54)){ 06480 dflmd = REM_MODE_FM; 06481 } 06482 else if(m == 144){ /* 2 meters */ 06483 if(d >= 30000) 06484 dflmd = REM_MODE_FM; 06485 else 06486 dflmd = REM_MODE_USB; 06487 } 06488 else if((m >= 145) && (m < 148)){ 06489 dflmd = REM_MODE_FM; 06490 } 06491 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06492 if(m < 438) 06493 dflmd = REM_MODE_USB; 06494 else 06495 dflmd = REM_MODE_FM; 06496 ; 06497 } 06498 else 06499 return -1; 06500 06501 if(defmode) 06502 *defmode = dflmd; 06503 06504 return 0; 06505 }
static int check_freq_ic706 | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6793 of file app_rpt.c.
References REM_MODE_FM, REM_MODE_LSB, and REM_MODE_USB.
Referenced by check_freq(), and multimode_bump_freq_ic706().
06794 { 06795 int dflmd = REM_MODE_FM; 06796 06797 if(m == 1){ /* 160 meters */ 06798 dflmd = REM_MODE_LSB; 06799 if(d < 80000) 06800 return -1; 06801 } 06802 else if(m == 3){ /* 80 meters */ 06803 dflmd = REM_MODE_LSB; 06804 if(d < 50000) 06805 return -1; 06806 } 06807 else if(m == 7){ /* 40 meters */ 06808 dflmd = REM_MODE_LSB; 06809 if(d > 30000) 06810 return -1; 06811 } 06812 else if(m == 14){ /* 20 meters */ 06813 dflmd = REM_MODE_USB; 06814 if(d > 35000) 06815 return -1; 06816 } 06817 else if(m == 18){ /* 17 meters */ 06818 dflmd = REM_MODE_USB; 06819 if((d < 6800) || (d > 16800)) 06820 return -1; 06821 } 06822 else if(m == 21){ /* 15 meters */ 06823 dflmd = REM_MODE_USB; 06824 if((d < 20000) || (d > 45000)) 06825 return -1; 06826 } 06827 else if(m == 24){ /* 12 meters */ 06828 dflmd = REM_MODE_USB; 06829 if((d < 89000) || (d > 99000)) 06830 return -1; 06831 } 06832 else if(m == 28){ /* 10 meters */ 06833 dflmd = REM_MODE_USB; 06834 } 06835 else if(m == 29){ 06836 if(d >= 51000) 06837 dflmd = REM_MODE_FM; 06838 else 06839 dflmd = REM_MODE_USB; 06840 if(d > 70000) 06841 return -1; 06842 } 06843 else if(m == 50){ /* 6 meters */ 06844 if(d >= 30000) 06845 dflmd = REM_MODE_FM; 06846 else 06847 dflmd = REM_MODE_USB; 06848 06849 } 06850 else if((m >= 51) && ( m < 54)){ 06851 dflmd = REM_MODE_FM; 06852 } 06853 else if(m == 144){ /* 2 meters */ 06854 if(d >= 30000) 06855 dflmd = REM_MODE_FM; 06856 else 06857 dflmd = REM_MODE_USB; 06858 } 06859 else if((m >= 145) && (m < 148)){ 06860 dflmd = REM_MODE_FM; 06861 } 06862 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06863 if(m < 438) 06864 dflmd = REM_MODE_USB; 06865 else 06866 dflmd = REM_MODE_FM; 06867 ; 06868 } 06869 else 06870 return -1; 06871 06872 if(defmode) 06873 *defmode = dflmd; 06874 06875 return 0; 06876 }
static int check_freq_kenwood | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6284 of file app_rpt.c.
References REM_MODE_FM.
Referenced by check_freq().
06285 { 06286 int dflmd = REM_MODE_FM; 06287 06288 if (m == 144){ /* 2 meters */ 06289 if(d < 10100) 06290 return -1; 06291 } 06292 else if((m >= 145) && (m < 148)){ 06293 ; 06294 } 06295 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06296 ; 06297 } 06298 else 06299 return -1; 06300 06301 if(defmode) 06302 *defmode = dflmd; 06303 06304 06305 return 0; 06306 }
static int check_freq_rbi | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6312 of file app_rpt.c.
References REM_MODE_FM.
Referenced by check_freq().
06313 { 06314 int dflmd = REM_MODE_FM; 06315 06316 if(m == 50){ /* 6 meters */ 06317 if(d < 10100) 06318 return -1; 06319 } 06320 else if((m >= 51) && ( m < 54)){ 06321 ; 06322 } 06323 else if(m == 144){ /* 2 meters */ 06324 if(d < 10100) 06325 return -1; 06326 } 06327 else if((m >= 145) && (m < 148)){ 06328 ; 06329 } 06330 else if((m >= 222) && (m < 225)){ /* 1.25 meters */ 06331 ; 06332 } 06333 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06334 ; 06335 } 06336 else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */ 06337 ; 06338 } 06339 else 06340 return -1; 06341 06342 if(defmode) 06343 *defmode = dflmd; 06344 06345 06346 return 0; 06347 }
static char check_tx_freq | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7425 of file app_rpt.c.
References ast_log(), ast_variable_browse(), rpt::cfg, decimals2int(), eatwhite(), finddelim(), rpt::freq, LOG_NOTICE, LOG_WARNING, rpt::loginlevel, rpt::loginuser, MAXREMSTR, ast_variable::name, ast_variable::next, rpt::p, s, split_freq(), rpt::txlimitsstanzaname, and ast_variable::value.
Referenced by rpt_exec().
07426 { 07427 int i; 07428 int radio_mhz, radio_decimals, ulimit_mhz, ulimit_decimals, llimit_mhz, llimit_decimals; 07429 char radio_mhz_char[MAXREMSTR]; 07430 char radio_decimals_char[MAXREMSTR]; 07431 char limit_mhz_char[MAXREMSTR]; 07432 char limit_decimals_char[MAXREMSTR]; 07433 char limits[256]; 07434 char *limit_ranges[40]; 07435 struct ast_variable *limitlist; 07436 07437 07438 /* Must have user logged in and tx_limits defined */ 07439 07440 if(!myrpt->p.txlimitsstanzaname || !myrpt->loginuser[0] || !myrpt->loginlevel[0]){ 07441 if(debug > 3){ 07442 ast_log(LOG_NOTICE, "No tx band table defined, or no user logged in\n"); 07443 } 07444 return 1; /* Assume it's ok otherwise */ 07445 } 07446 07447 /* Retrieve the band table for the loginlevel */ 07448 limitlist = ast_variable_browse(myrpt->cfg, myrpt->p.txlimitsstanzaname); 07449 07450 if(!limitlist){ 07451 ast_log(LOG_WARNING, "No entries in %s band table stanza\n", myrpt->p.txlimitsstanzaname); 07452 return 0; 07453 } 07454 07455 split_freq(radio_mhz_char, radio_decimals_char, myrpt->freq); 07456 radio_mhz = atoi(radio_mhz_char); 07457 radio_decimals = decimals2int(radio_decimals_char); 07458 07459 07460 if(debug > 3){ 07461 ast_log(LOG_NOTICE, "Login User = %s, login level = %s\n", myrpt->loginuser, myrpt->loginlevel); 07462 } 07463 07464 /* Find our entry */ 07465 07466 for(;limitlist; limitlist=limitlist->next){ 07467 if(!strcmp(limitlist->name, myrpt->loginlevel)) 07468 break; 07469 } 07470 07471 if(!limitlist){ 07472 ast_log(LOG_WARNING, "Can't find %s entry in band table stanza %s\n", myrpt->loginlevel, myrpt->p.txlimitsstanzaname); 07473 return 0; 07474 } 07475 07476 if(debug > 3){ 07477 ast_log(LOG_NOTICE, "Auth %s = %s\n", limitlist->name, limitlist->value); 07478 } 07479 07480 /* Parse the limits */ 07481 07482 strncpy(limits, limitlist->value, 256); 07483 limits[255] = 0; 07484 finddelim(limits, limit_ranges, 40); 07485 for(i = 0; i < 40 && limit_ranges[i] ; i++){ 07486 char range[40]; 07487 char *r,*s; 07488 strncpy(range, limit_ranges[i], 40); 07489 range[39] = 0; 07490 if(debug > 3){ 07491 ast_log(LOG_NOTICE, "Checking to see if %s is within limits of %s\n", myrpt->freq, range); 07492 } 07493 07494 r = strchr(range, '-'); 07495 if(!r){ 07496 ast_log(LOG_WARNING, "Malformed range in %s tx band table entry\n", limitlist->name); 07497 return 0; 07498 } 07499 *r++ = 0; 07500 s = eatwhite(range); 07501 r = eatwhite(r); 07502 split_freq(limit_mhz_char, limit_decimals_char, s); 07503 llimit_mhz = atoi(limit_mhz_char); 07504 llimit_decimals = decimals2int(limit_decimals_char); 07505 split_freq(limit_mhz_char, limit_decimals_char, r); 07506 ulimit_mhz = atoi(limit_mhz_char); 07507 ulimit_decimals = decimals2int(limit_decimals_char); 07508 07509 if((radio_mhz >= llimit_mhz) && (radio_mhz <= ulimit_mhz)){ 07510 if(radio_mhz == llimit_mhz){ /* CASE 1: TX freq is in llimit mhz portion of band */ 07511 if(radio_decimals >= llimit_decimals){ /* Cannot be below llimit decimals */ 07512 if(llimit_mhz == ulimit_mhz){ /* If bandwidth < 1Mhz, check ulimit decimals */ 07513 if(radio_decimals <= ulimit_decimals){ 07514 return 1; 07515 } 07516 else{ 07517 if(debug > 3) 07518 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 1\n"); 07519 return 0; 07520 } 07521 } 07522 else{ 07523 return 1; 07524 } 07525 } 07526 else{ /* Is below llimit decimals */ 07527 if(debug > 3) 07528 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 2\n"); 07529 return 0; 07530 } 07531 } 07532 else if(radio_mhz == ulimit_mhz){ /* CASE 2: TX freq not in llimit mhz portion of band */ 07533 if(radio_decimals <= ulimit_decimals){ 07534 return 1; 07535 } 07536 else{ /* Is above ulimit decimals */ 07537 if(debug > 3) 07538 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 3\n"); 07539 return 0; 07540 } 07541 } 07542 else /* CASE 3: TX freq within a multi-Mhz band and ok */ 07543 return 1; 07544 } 07545 } 07546 if(debug > 3) /* No match found in TX band table */ 07547 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 4\n"); 07548 return 0; 07549 }
static int civ_cmd | ( | struct rpt * | myrpt, | |
unsigned char * | cmd, | |||
int | cmdlen | |||
) | [static] |
Definition at line 5960 of file app_rpt.c.
References serial_remote_io().
Referenced by mem2vfo_ic706(), select_mem_ic706(), set_ctcss_mode_ic706(), set_freq_ic706(), simple_command_ic706(), and vfo_ic706().
05961 { 05962 unsigned char rxbuf[100]; 05963 int i,rv ; 05964 05965 rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0); 05966 if (rv == -1) return(-1); 05967 if (rv != (cmdlen + 6)) return(1); 05968 for(i = 0; i < 6; i++) 05969 if (rxbuf[i] != cmd[i]) return(1); 05970 if (rxbuf[cmdlen] != 0xfe) return(1); 05971 if (rxbuf[cmdlen + 1] != 0xfe) return(1); 05972 if (rxbuf[cmdlen + 4] != 0xfb) return(1); 05973 if (rxbuf[cmdlen + 5] != 0xfd) return(1); 05974 return(0); 05975 }
static int closerem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7395 of file app_rpt.c.
References closerem_ft897(), and rpt::remote.
Referenced by rpt_exec().
07396 { 07397 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07398 return closerem_ft897(myrpt); 07399 else 07400 return 0; 07401 }
static int closerem_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6733 of file app_rpt.c.
References simple_command_ft897().
Referenced by closerem().
06734 { 06735 simple_command_ft897(myrpt, 0x88); /* PTT off */ 06736 return 0; 06737 }
static int collect_function_digits | ( | struct rpt * | myrpt, | |
char * | digits, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5230 of file app_rpt.c.
References ast_variable_browse(), rpt::cfg, DC_ERROR, DC_INDETERMINATE, rpt::dphone_functions, rpt::dphone_longestfunc, rpt::functions, rpt::link_functions, rpt::link_longestfunc, rpt::longestfunc, ast_variable::name, ast_variable::next, rpt::p, 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 local_dtmf_helper().
05232 { 05233 int i; 05234 char *stringp,*action,*param,*functiondigits; 05235 char function_table_name[30] = ""; 05236 char workstring[200]; 05237 05238 struct ast_variable *vp; 05239 05240 if(debug) 05241 printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source); 05242 05243 if (command_source == SOURCE_DPHONE) { 05244 if (!myrpt->p.dphone_functions) return DC_INDETERMINATE; 05245 strncpy(function_table_name, myrpt->p.dphone_functions, sizeof(function_table_name) - 1); 05246 } 05247 else if (command_source == SOURCE_PHONE) { 05248 if (!myrpt->p.phone_functions) return DC_INDETERMINATE; 05249 strncpy(function_table_name, myrpt->p.phone_functions, sizeof(function_table_name) - 1); 05250 } 05251 else if (command_source == SOURCE_LNK) 05252 strncpy(function_table_name, myrpt->p.link_functions, sizeof(function_table_name) - 1); 05253 else 05254 strncpy(function_table_name, myrpt->p.functions, sizeof(function_table_name) - 1); 05255 vp = ast_variable_browse(myrpt->cfg, function_table_name); 05256 while(vp) { 05257 if(!strncasecmp(vp->name, digits, strlen(vp->name))) 05258 break; 05259 vp = vp->next; 05260 } 05261 if(!vp) { 05262 int n; 05263 05264 n = myrpt->longestfunc; 05265 if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc; 05266 else 05267 if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc; 05268 else 05269 if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc; 05270 05271 if(strlen(digits) >= n) 05272 return DC_ERROR; 05273 else 05274 return DC_INDETERMINATE; 05275 } 05276 /* Found a match, retrieve value part and parse */ 05277 strncpy(workstring, vp->value, sizeof(workstring) - 1 ); 05278 stringp = workstring; 05279 action = strsep(&stringp, ","); 05280 param = stringp; 05281 if(debug) 05282 printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)"); 05283 /* Look up the action */ 05284 for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){ 05285 if(!strncasecmp(action, function_table[i].action, strlen(action))) 05286 break; 05287 } 05288 if(debug) 05289 printf("@@@@ table index i = %d\n",i); 05290 if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){ 05291 /* Error, action not in table */ 05292 return DC_ERROR; 05293 } 05294 if(function_table[i].function == NULL){ 05295 /* Error, function undefined */ 05296 if(debug) 05297 printf("@@@@ NULL for action: %s\n",action); 05298 return DC_ERROR; 05299 } 05300 functiondigits = digits + strlen(vp->name); 05301 return (*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink); 05302 }
static int connect_link | ( | struct rpt * | myrpt, | |
char * | node, | |||
int | mode, | |||
int | perma | |||
) | [static] |
Definition at line 4470 of file app_rpt.c.
References __kickshort(), __mklinklist(), rpt::archivedir, ast_call(), AST_CDR_FLAG_POST_DISABLED, AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_request(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_true(), rpt_link::chan, rpt::conf, rpt_link::disced, donodelog(), finddelim(), free, rpt::lastlinknode, rpt::links, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::longestnode, malloc, MAX_RETRIES, rpt_link::max_retries, MAX_RETRIES_PERM, MAXLINKLIST, MAXNODESTR, rpt_link::mode, rpt::name, rpt_link::name, rpt_link::next, node_lookup(), rpt::p, rpt_link::reconnects, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, s, strdup, and strsep().
Referenced by function_ilink().
04471 { 04472 char *val, *s, *s1, *s2, *tele; 04473 char lstr[MAXLINKLIST],*strs[MAXLINKLIST]; 04474 char tmp[300], deststr[300] = "",modechange = 0; 04475 struct rpt_link *l; 04476 int reconnects = 0; 04477 int i,n; 04478 ZT_CONFINFO ci; /* conference info */ 04479 04480 val = node_lookup(myrpt,node); 04481 if (!val){ 04482 if(strlen(node) >= myrpt->longestnode) 04483 return -1; /* No such node */ 04484 return 1; /* No match yet */ 04485 } 04486 if(debug > 3){ 04487 ast_log(LOG_NOTICE,"Connect attempt to node %s\n", node); 04488 ast_log(LOG_NOTICE,"Mode: %s\n",(mode)?"Transceive":"Monitor"); 04489 ast_log(LOG_NOTICE,"Connection type: %s\n",(perma)?"Permalink":"Normal"); 04490 } 04491 04492 strncpy(tmp,val,sizeof(tmp) - 1); 04493 s = tmp; 04494 s1 = strsep(&s,","); 04495 s2 = strsep(&s,","); 04496 rpt_mutex_lock(&myrpt->lock); 04497 l = myrpt->links.next; 04498 /* try to find this one in queue */ 04499 while(l != &myrpt->links){ 04500 if (l->name[0] == '0') 04501 { 04502 l = l->next; 04503 continue; 04504 } 04505 /* if found matching string */ 04506 if (!strcmp(l->name, node)) 04507 break; 04508 l = l->next; 04509 } 04510 /* if found */ 04511 if (l != &myrpt->links){ 04512 /* if already in this mode, just ignore */ 04513 if ((l->mode) || (!l->chan)) { 04514 rpt_mutex_unlock(&myrpt->lock); 04515 return 2; /* Already linked */ 04516 } 04517 reconnects = l->reconnects; 04518 rpt_mutex_unlock(&myrpt->lock); 04519 if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV); 04520 l->retries = l->max_retries + 1; 04521 l->disced = 2; 04522 modechange = 1; 04523 } else 04524 { 04525 __mklinklist(myrpt,NULL,lstr); 04526 rpt_mutex_unlock(&myrpt->lock); 04527 n = finddelim(lstr,strs,MAXLINKLIST); 04528 for(i = 0; i < n; i++) 04529 { 04530 if ((*strs[i] < '0') || 04531 (*strs[i] > '9')) strs[i]++; 04532 if (!strcmp(strs[i],node)) 04533 { 04534 return 2; /* Already linked */ 04535 } 04536 } 04537 } 04538 strncpy(myrpt->lastlinknode,node,MAXNODESTR - 1); 04539 /* establish call */ 04540 l = malloc(sizeof(struct rpt_link)); 04541 if (!l) 04542 { 04543 ast_log(LOG_WARNING, "Unable to malloc\n"); 04544 return -1; 04545 } 04546 /* zero the silly thing */ 04547 memset((char *)l,0,sizeof(struct rpt_link)); 04548 l->mode = mode; 04549 l->outbound = 1; 04550 l->thisconnected = 0; 04551 strncpy(l->name, node, MAXNODESTR - 1); 04552 l->isremote = (s && ast_true(s)); 04553 if (modechange) l->connected = 1; 04554 l->hasconnected = l->perma = perma; 04555 #ifdef ALLOW_LOCAL_CHANNELS 04556 if ((strncasecmp(s1,"iax2/", 5) == 0) || (strncasecmp(s1, "local/", 6) == 0)) 04557 strncpy(deststr, s1, sizeof(deststr)); 04558 else 04559 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 04560 #else 04561 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 04562 #endif 04563 tele = strchr(deststr, '/'); 04564 if (!tele){ 04565 ast_log(LOG_WARNING,"link3:Dial number (%s) must be in format tech/number\n",deststr); 04566 free(l); 04567 return -1; 04568 } 04569 *tele++ = 0; 04570 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 04571 if (l->chan){ 04572 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 04573 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 04574 #ifdef AST_CDR_FLAG_POST_DISABLED 04575 ast_set_flag(l->chan->cdr,AST_CDR_FLAG_POST_DISABLED); 04576 #endif 04577 l->chan->whentohangup = 0; 04578 l->chan->appl = "Apprpt"; 04579 l->chan->data = "(Remote Rx)"; 04580 if (debug > 3) 04581 ast_log(LOG_NOTICE, "rpt (remote) initiating call to %s/%s on %s\n", 04582 deststr, tele, l->chan->name); 04583 if(l->chan->cid.cid_num) 04584 free(l->chan->cid.cid_num); 04585 l->chan->cid.cid_num = strdup(myrpt->name); 04586 ast_call(l->chan,tele,999); 04587 } 04588 else { 04589 if(debug > 3) 04590 ast_log(LOG_NOTICE, "Unable to place call to %s/%s on %s\n", 04591 deststr,tele,l->chan->name); 04592 if (myrpt->p.archivedir) 04593 { 04594 char str[100]; 04595 sprintf(str,"LINKFAIL,%s",l->name); 04596 donodelog(myrpt,str); 04597 } 04598 free(l); 04599 return -1; 04600 } 04601 /* allocate a pseudo-channel thru asterisk */ 04602 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04603 if (!l->pchan){ 04604 ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n"); 04605 ast_hangup(l->chan); 04606 free(l); 04607 return -1; 04608 } 04609 ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR); 04610 ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR); 04611 #ifdef AST_CDR_FLAG_POST_DISABLED 04612 ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED); 04613 #endif 04614 /* make a conference for the tx */ 04615 ci.chan = 0; 04616 ci.confno = myrpt->conf; 04617 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 04618 /* first put the channel on the conference in proper mode */ 04619 if (ioctl(l->pchan->fds[0], ZT_SETCONF, &ci) == -1) 04620 { 04621 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04622 ast_hangup(l->chan); 04623 ast_hangup(l->pchan); 04624 free(l); 04625 return -1; 04626 } 04627 rpt_mutex_lock(&myrpt->lock); 04628 l->reconnects = reconnects; 04629 /* insert at end of queue */ 04630 l->max_retries = MAX_RETRIES; 04631 if (perma) 04632 l->max_retries = MAX_RETRIES_PERM; 04633 if (l->isremote) l->retries = l->max_retries + 1; 04634 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 04635 __kickshort(myrpt); 04636 rpt_mutex_unlock(&myrpt->lock); 04637 return 0; 04638 }
static int decimals2int | ( | char * | fraction | ) | [static] |
Definition at line 6353 of file app_rpt.c.
Referenced by check_tx_freq().
06354 { 06355 int i; 06356 char len = strlen(fraction); 06357 int multiplier = 100000; 06358 int res = 0; 06359 06360 if(!len) 06361 return 0; 06362 for( i = 0 ; i < len ; i++, multiplier /= 10) 06363 res += (fraction[i] - '0') * multiplier; 06364 return res; 06365 }
static long diskavail | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 1025 of file app_rpt.c.
References rpt::archivedir, ast_log(), LOG_WARNING, rpt::name, and rpt::p.
Referenced by rpt(), and rpt_exec().
01026 { 01027 struct statfs statfsbuf; 01028 01029 if (!myrpt->p.archivedir) return(0); 01030 if (statfs(myrpt->p.archivedir,&statfsbuf) == -1) 01031 { 01032 ast_log(LOG_WARNING,"Cannot get filesystem size for %s node %s\n", 01033 myrpt->p.archivedir,myrpt->name); 01034 return(-1); 01035 } 01036 return(statfsbuf.f_bavail); 01037 }
static void do_dtmf_local | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 1090 of file app_rpt.c.
References ast_log(), ast_playtones_start(), DTMF_LOCAL_STARTTIME, rpt::dtmf_local_str, DTMF_LOCAL_TIME, rpt::dtmf_local_timer, rpt::lock, LOG_DEBUG, rpt_mutex_lock, rpt_mutex_unlock, and rpt::txchannel.
Referenced by function_ilink(), function_remote(), handle_link_data(), handle_remote_dtmf_digit(), rpt(), and rpt_exec().
01091 { 01092 int i; 01093 char digit; 01094 static const char* dtmf_tones[] = { 01095 "!941+1336/200,!0/200", /* 0 */ 01096 "!697+1209/200,!0/200", /* 1 */ 01097 "!697+1336/200,!0/200", /* 2 */ 01098 "!697+1477/200,!0/200", /* 3 */ 01099 "!770+1209/200,!0/200", /* 4 */ 01100 "!770+1336/200,!0/200", /* 5 */ 01101 "!770+1477/200,!0/200", /* 6 */ 01102 "!852+1209/200,!0/200", /* 7 */ 01103 "!852+1336/200,!0/200", /* 8 */ 01104 "!852+1477/200,!0/200", /* 9 */ 01105 "!697+1633/200,!0/200", /* A */ 01106 "!770+1633/200,!0/200", /* B */ 01107 "!852+1633/200,!0/200", /* C */ 01108 "!941+1633/200,!0/200", /* D */ 01109 "!941+1209/200,!0/200", /* * */ 01110 "!941+1477/200,!0/200" }; /* # */ 01111 01112 01113 if (c) 01114 { 01115 snprintf(myrpt->dtmf_local_str + strlen(myrpt->dtmf_local_str),sizeof(myrpt->dtmf_local_str) - 1,"%c",c); 01116 if (!myrpt->dtmf_local_timer) 01117 myrpt->dtmf_local_timer = DTMF_LOCAL_STARTTIME; 01118 } 01119 /* if at timeout */ 01120 if (myrpt->dtmf_local_timer == 1) 01121 { 01122 /* if anything in the string */ 01123 if (myrpt->dtmf_local_str[0]) 01124 { 01125 digit = myrpt->dtmf_local_str[0]; 01126 myrpt->dtmf_local_str[0] = 0; 01127 for(i = 1; myrpt->dtmf_local_str[i]; i++) 01128 { 01129 myrpt->dtmf_local_str[i - 1] = 01130 myrpt->dtmf_local_str[i]; 01131 } 01132 myrpt->dtmf_local_str[i - 1] = 0; 01133 myrpt->dtmf_local_timer = DTMF_LOCAL_TIME; 01134 rpt_mutex_unlock(&myrpt->lock); 01135 if (digit >= '0' && digit <='9') 01136 ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'0'], 0); 01137 else if (digit >= 'A' && digit <= 'D') 01138 ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'A'+10], 0); 01139 else if (digit == '*') 01140 ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[14], 0); 01141 else if (digit == '#') 01142 ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[15], 0); 01143 else { 01144 /* not handled */ 01145 ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, myrpt->txchannel->name); 01146 } 01147 rpt_mutex_lock(&myrpt->lock); 01148 } 01149 else 01150 { 01151 myrpt->dtmf_local_timer = 0; 01152 } 01153 } 01154 }
Definition at line 1039 of file app_rpt.c.
References ast_senddigit(), rpt_link::chan, rpt::links, rpt_link::next, and rpt_link::phonemode.
Referenced by handle_link_data(), and local_dtmf_helper().
01040 { 01041 struct rpt_link *l; 01042 01043 l = myrpt->links.next; 01044 /* go thru all the links */ 01045 while(l != &myrpt->links) 01046 { 01047 if (!l->phonemode) 01048 { 01049 l = l->next; 01050 continue; 01051 } 01052 /* dont send to self */ 01053 if (mylink && (l == mylink)) 01054 { 01055 l = l->next; 01056 continue; 01057 } 01058 if (l->chan) ast_senddigit(l->chan,c); 01059 l = l->next; 01060 } 01061 return; 01062 }
static void do_scheduler | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 8643 of file app_rpt.c.
References ast_log(), ast_variable_browse(), ast_variable_retrieve(), rpt::cfg, rpt::curtv, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, LOG_NOTICE, LOG_WARNING, rpt::macro, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, ast_variable::name, ast_variable::next, rpt::p, rpt::remote, rpt_localtime(), rpt::s, sysstate::schedulerdisable, rpt::skedstanzaname, rpt::sysstate_cur, and ast_variable::value.
Referenced by rpt().
08644 { 08645 int i,res; 08646 struct tm tmnow; 08647 struct ast_variable *skedlist; 08648 char *strs[5],*vp,*val,value[100]; 08649 08650 memcpy(&myrpt->lasttv, &myrpt->curtv, sizeof(struct timeval)); 08651 08652 if( (res = gettimeofday(&myrpt->curtv, NULL)) < 0) 08653 ast_log(LOG_NOTICE, "Scheduler gettime of day returned: %s\n", strerror(res)); 08654 08655 /* Try to get close to a 1 second resolution */ 08656 08657 if(myrpt->lasttv.tv_sec == myrpt->curtv.tv_sec) 08658 return; 08659 08660 rpt_localtime(&myrpt->curtv.tv_sec, &tmnow); 08661 08662 /* If midnight, then reset all daily statistics */ 08663 08664 if((tmnow.tm_hour == 0)&&(tmnow.tm_min == 0)&&(tmnow.tm_sec == 0)){ 08665 myrpt->dailykeyups = 0; 08666 myrpt->dailytxtime = 0; 08667 myrpt->dailykerchunks = 0; 08668 myrpt->dailyexecdcommands = 0; 08669 } 08670 08671 if(tmnow.tm_sec != 0) 08672 return; 08673 08674 /* Code below only executes once per minute */ 08675 08676 08677 /* Don't schedule if remote */ 08678 08679 if (myrpt->remote) 08680 return; 08681 08682 /* Don't schedule if disabled */ 08683 08684 if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable){ 08685 if(debug > 6) 08686 ast_log(LOG_NOTICE, "Scheduler disabled\n"); 08687 return; 08688 } 08689 08690 if(!myrpt->p.skedstanzaname){ /* No stanza means we do nothing */ 08691 if(debug > 6) 08692 ast_log(LOG_NOTICE,"No stanza for scheduler in rpt.conf\n"); 08693 return; 08694 } 08695 08696 /* get pointer to linked list of scheduler entries */ 08697 skedlist = ast_variable_browse(myrpt->cfg, myrpt->p.skedstanzaname); 08698 08699 if(debug > 6){ 08700 ast_log(LOG_NOTICE, "Time now: %02d:%02d %02d %02d %02d\n", 08701 tmnow.tm_hour,tmnow.tm_min,tmnow.tm_mday,tmnow.tm_mon + 1, tmnow.tm_wday); 08702 } 08703 /* walk the list */ 08704 for(; skedlist; skedlist = skedlist->next){ 08705 if(debug > 6) 08706 ast_log(LOG_NOTICE, "Scheduler entry %s = %s being considered\n",skedlist->name, skedlist->value); 08707 strncpy(value,skedlist->value,99); 08708 value[99] = 0; 08709 /* point to the substrings for minute, hour, dom, month, and dow */ 08710 for( i = 0, vp = value ; i < 5; i++){ 08711 if(!*vp) 08712 break; 08713 while((*vp == ' ') || (*vp == 0x09)) /* get rid of any leading white space */ 08714 vp++; 08715 strs[i] = vp; /* save pointer to beginning of substring */ 08716 while((*vp != ' ') && (*vp != 0x09) && (*vp != 0)) /* skip over substring */ 08717 vp++; 08718 if(*vp) 08719 *vp++ = 0; /* mark end of substring */ 08720 } 08721 if(debug > 6) 08722 ast_log(LOG_NOTICE, "i = %d, min = %s, hour = %s, mday=%s, mon=%s, wday=%s\n",i, 08723 strs[0], strs[1], strs[2], strs[3], strs[4]); 08724 if(i == 5){ 08725 if((*strs[0] != '*')&&(atoi(strs[0]) != tmnow.tm_min)) 08726 continue; 08727 if((*strs[1] != '*')&&(atoi(strs[1]) != tmnow.tm_hour)) 08728 continue; 08729 if((*strs[2] != '*')&&(atoi(strs[2]) != tmnow.tm_mday)) 08730 continue; 08731 if((*strs[3] != '*')&&(atoi(strs[3]) != tmnow.tm_mon + 1)) 08732 continue; 08733 if(atoi(strs[4]) == 7) 08734 strs[4] = "0"; 08735 if((*strs[4] != '*')&&(atoi(strs[4]) != tmnow.tm_wday)) 08736 continue; 08737 if(debug) 08738 ast_log(LOG_NOTICE, "Executing scheduler entry %s = %s\n", skedlist->name, skedlist->value); 08739 if(atoi(skedlist->name) == 0) 08740 return; /* Zero is reserved for the startup macro */ 08741 val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, skedlist->name); 08742 if (!val){ 08743 ast_log(LOG_WARNING,"Scheduler could not find macro %s\n",skedlist->name); 08744 return; /* Macro not found */ 08745 } 08746 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)){ 08747 ast_log(LOG_WARNING, "Scheduler could not execute macro %s: Macro buffer full\n", 08748 skedlist->name); 08749 return; /* Macro buffer full */ 08750 } 08751 myrpt->macrotimer = MACROTIME; 08752 strncat(myrpt->macrobuf,val,MAXMACRO - 1); 08753 } 08754 else{ 08755 ast_log(LOG_WARNING,"Malformed scheduler entry in rpt.conf: %s = %s\n", 08756 skedlist->name, skedlist->value); 08757 } 08758 } 08759 08760 }
static void donodelog | ( | struct rpt * | myrpt, | |
char * | str | |||
) | [static] |
Definition at line 1065 of file app_rpt.c.
References nodelog::archivedir, rpt::archivedir, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, malloc, rpt::name, rpt::p, nodelog::prev, nodelog::str, and nodelog::timestamp.
Referenced by connect_link(), function_remote(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_data(), handle_remote_phone_dtmf(), local_dtmf_helper(), rpt(), rpt_exec(), and setrem().
01066 { 01067 struct nodelog *nodep; 01068 char datestr[100]; 01069 01070 if (!myrpt->p.archivedir) return; 01071 nodep = (struct nodelog *)malloc(sizeof(struct nodelog)); 01072 if (nodep == NULL) 01073 { 01074 ast_log(LOG_ERROR,"Cannot get memory for node log"); 01075 return; 01076 } 01077 time(&nodep->timestamp); 01078 strncpy(nodep->archivedir,myrpt->p.archivedir, 01079 sizeof(nodep->archivedir) - 1); 01080 strftime(datestr,sizeof(datestr) - 1,"%Y%m%d%H%M%S", 01081 localtime(&nodep->timestamp)); 01082 snprintf(nodep->str,sizeof(nodep->str) - 1,"%s %s,%s\n", 01083 myrpt->name,datestr,str); 01084 ast_mutex_lock(&nodeloglock); 01085 insque((struct qelem *) nodep, (struct qelem *) nodelog.prev); 01086 ast_mutex_unlock(&nodeloglock); 01087 }
static char* eatwhite | ( | char * | s | ) | [static] |
static int finddelim | ( | char * | str, | |
char * | strp[], | |||
int | limit | |||
) | [static] |
Definition at line 1308 of file app_rpt.c.
References DELIMCHR, and QUOTECHR.
Referenced by check_tx_freq(), connect_link(), function_autopatchup(), function_ilink(), load_rpt_vars(), rpt_do_nodes(), and rpt_tele_thread().
01309 { 01310 int i,l,inquo; 01311 01312 inquo = 0; 01313 i = 0; 01314 strp[i++] = str; 01315 if (!*str) 01316 { 01317 strp[0] = 0; 01318 return(0); 01319 } 01320 for(l = 0; *str && (l < limit) ; str++) 01321 { 01322 if (*str == QUOTECHR) 01323 { 01324 if (inquo) 01325 { 01326 *str = 0; 01327 inquo = 0; 01328 } 01329 else 01330 { 01331 strp[i - 1] = str + 1; 01332 inquo = 1; 01333 } 01334 } 01335 if ((*str == DELIMCHR) && (!inquo)) 01336 { 01337 *str = 0; 01338 l++; 01339 strp[i++] = str + 1; 01340 } 01341 } 01342 strp[i] = 0; 01343 return(i); 01344 01345 }
Definition at line 1243 of file app_rpt.c.
References rpt::endchar, rpt_xlat::endcharseq, rpt_xlat::endindex, rpt::funcchar, rpt_xlat::funccharseq, rpt_xlat::funcindex, rpt_xlat::lastone, MAXXLATTIME, rpt::p, and rpt_xlat::passchars.
Referenced by handle_link_data(), handle_remote_data(), and rpt().
01244 { 01245 time_t now; 01246 int gotone; 01247 01248 time(&now); 01249 gotone = 0; 01250 /* if too much time, reset the skate machine */ 01251 if ((now - xlat->lastone) > MAXXLATTIME) 01252 { 01253 xlat->funcindex = xlat->endindex = 0; 01254 } 01255 if (xlat->funccharseq[0] && (c == xlat->funccharseq[xlat->funcindex++])) 01256 { 01257 time(&xlat->lastone); 01258 gotone = 1; 01259 if (!xlat->funccharseq[xlat->funcindex]) 01260 { 01261 xlat->funcindex = xlat->endindex = 0; 01262 return(myrpt->p.funcchar); 01263 } 01264 } else xlat->funcindex = 0; 01265 if (xlat->endcharseq[0] && (c == xlat->endcharseq[xlat->endindex++])) 01266 { 01267 time(&xlat->lastone); 01268 gotone = 1; 01269 if (!xlat->endcharseq[xlat->endindex]) 01270 { 01271 xlat->funcindex = xlat->endindex = 0; 01272 return(myrpt->p.endchar); 01273 } 01274 } else xlat->endindex = 0; 01275 /* if in middle of decode seq, send nothing back */ 01276 if (gotone) return(0); 01277 /* if no pass chars specified, return em all */ 01278 if (!xlat->passchars[0]) return(c); 01279 /* if a "pass char", pass it */ 01280 if (strchr(xlat->passchars,c)) return(c); 01281 return(0); 01282 }
static int function_autopatchdn | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5001 of file app_rpt.c.
References sysstate::autopatchdisable, rpt::callmode, DC_COMPLETE, DC_ERROR, rpt::lock, rpt::p, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::s, rpt::sysstate_cur, TERM, and sysstate::txdisable.
05002 { 05003 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 05004 return DC_ERROR; 05005 05006 if(debug) 05007 printf("@@@@ Autopatch down\n"); 05008 05009 rpt_mutex_lock(&myrpt->lock); 05010 05011 if (!myrpt->callmode){ 05012 rpt_mutex_unlock(&myrpt->lock); 05013 return DC_COMPLETE; 05014 } 05015 05016 myrpt->callmode = 0; 05017 rpt_mutex_unlock(&myrpt->lock); 05018 rpt_telemetry(myrpt, TERM, NULL); 05019 return DC_COMPLETE; 05020 }
static int function_autopatchup | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 4904 of file app_rpt.c.
References ast_log(), ast_pthread_create, ast_strdupa, sysstate::autopatchdisable, rpt::callmode, rpt::cidx, DC_COMPLETE, DC_ERROR, rpt::endchar, rpt::exten, finddelim(), rpt::lock, LOG_ERROR, matchkeyword(), MAXPATCHCONTEXT, rpt::mydtmf, rpt::ourcontext, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchnoct, rpt::patchquiet, rpt_call(), rpt::rpt_call_thread, rpt_mutex_lock, rpt_mutex_unlock, rpt::s, skipchars(), rpt::sysstate_cur, and sysstate::txdisable.
04905 { 04906 pthread_attr_t attr; 04907 int i, index, paramlength; 04908 char *lparam; 04909 char *value = NULL; 04910 char *paramlist[20]; 04911 04912 static char *keywords[] = { 04913 "context", 04914 "dialtime", 04915 "farenddisconnect", 04916 "noct", 04917 "quiet", 04918 NULL 04919 }; 04920 04921 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 04922 return DC_ERROR; 04923 04924 if(debug) 04925 printf("@@@@ Autopatch up\n"); 04926 04927 if(!myrpt->callmode){ 04928 /* Set defaults */ 04929 myrpt->patchnoct = 0; 04930 myrpt->patchdialtime = 0; 04931 myrpt->patchfarenddisconnect = 0; 04932 myrpt->patchquiet = 0; 04933 strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT); 04934 04935 if(param){ 04936 /* Process parameter list */ 04937 lparam = ast_strdupa(param); 04938 if(!lparam){ 04939 ast_log(LOG_ERROR,"App_rpt out of memory on line %d\n",__LINE__); 04940 return DC_ERROR; 04941 } 04942 paramlength = finddelim(lparam, paramlist, 20); 04943 for(i = 0; i < paramlength; i++){ 04944 index = matchkeyword(paramlist[i], &value, keywords); 04945 if(value) 04946 value = skipchars(value, "= "); 04947 switch(index){ 04948 04949 case 1: /* context */ 04950 strncpy(myrpt->patchcontext, value, MAXPATCHCONTEXT - 1) ; 04951 break; 04952 04953 case 2: /* dialtime */ 04954 myrpt->patchdialtime = atoi(value); 04955 break; 04956 04957 case 3: /* farenddisconnect */ 04958 myrpt->patchfarenddisconnect = atoi(value); 04959 break; 04960 04961 case 4: /* noct */ 04962 myrpt->patchnoct = atoi(value); 04963 break; 04964 04965 case 5: /* quiet */ 04966 myrpt->patchquiet = atoi(value); 04967 break; 04968 04969 default: 04970 break; 04971 } 04972 } 04973 } 04974 } 04975 04976 rpt_mutex_lock(&myrpt->lock); 04977 04978 /* if on call, force * into current audio stream */ 04979 04980 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){ 04981 myrpt->mydtmf = myrpt->p.endchar; 04982 } 04983 if (myrpt->callmode){ 04984 rpt_mutex_unlock(&myrpt->lock); 04985 return DC_COMPLETE; 04986 } 04987 myrpt->callmode = 1; 04988 myrpt->cidx = 0; 04989 myrpt->exten[myrpt->cidx] = 0; 04990 rpt_mutex_unlock(&myrpt->lock); 04991 pthread_attr_init(&attr); 04992 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04993 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt); 04994 return DC_COMPLETE; 04995 }
static int function_cop | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5102 of file app_rpt.c.
References sysstate::alternatetail, ARB_ALPHA, sysstate::autopatchdisable, DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, rpt::disgorgetime, sysstate::linkfundisable, myatoi(), rpt::p, rpt_telemetry(), rpt::s, sysstate::schedulerdisable, SOURCE_PHONE, rpt::stopgen, rpt::sysstate_cur, TEST_TONE, sysstate::totdisable, sysstate::txdisable, and sysstate::userfundisable.
05103 { 05104 char string[16]; 05105 05106 if(!param) 05107 return DC_ERROR; 05108 05109 switch(myatoi(param)){ 05110 case 1: /* System reset */ 05111 system("killall -9 asterisk"); 05112 return DC_COMPLETE; 05113 05114 case 2: 05115 myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 0; 05116 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA"); 05117 return DC_COMPLETE; 05118 05119 case 3: 05120 myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 1; 05121 return DC_COMPLETE; 05122 05123 case 4: /* test tone on */ 05124 if (myrpt->stopgen < 0) 05125 { 05126 myrpt->stopgen = 1; 05127 } 05128 else 05129 { 05130 myrpt->stopgen = 0; 05131 rpt_telemetry(myrpt, TEST_TONE, NULL); 05132 } 05133 return DC_COMPLETE; 05134 05135 case 5: /* Disgorge variables to log for debug purposes */ 05136 myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 05137 return DC_COMPLETE; 05138 05139 case 6: /* Simulate COR being activated (phone only) */ 05140 if (command_source != SOURCE_PHONE) return DC_INDETERMINATE; 05141 return DC_DOKEY; 05142 05143 05144 case 7: /* Time out timer enable */ 05145 myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 0; 05146 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTENA"); 05147 return DC_COMPLETE; 05148 05149 case 8: /* Time out timer disable */ 05150 myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 1; 05151 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTDIS"); 05152 return DC_COMPLETE; 05153 05154 case 9: /* Autopatch enable */ 05155 myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 0; 05156 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APENA"); 05157 return DC_COMPLETE; 05158 05159 case 10: /* Autopatch disable */ 05160 myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 1; 05161 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APDIS"); 05162 return DC_COMPLETE; 05163 05164 case 11: /* Link Enable */ 05165 myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 0; 05166 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKENA"); 05167 return DC_COMPLETE; 05168 05169 case 12: /* Link Disable */ 05170 myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 1; 05171 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKDIS"); 05172 return DC_COMPLETE; 05173 05174 case 13: /* Query System State */ 05175 string[0] = string[1] = 'S'; 05176 string[2] = myrpt->p.sysstate_cur + '0'; 05177 string[3] = '\0'; 05178 rpt_telemetry(myrpt, ARB_ALPHA, (void *) string); 05179 return DC_COMPLETE; 05180 05181 case 14: /* Change System State */ 05182 if(strlen(digitbuf) == 0) 05183 break; 05184 if((digitbuf[0] < '0') || (digitbuf[0] > '9')) 05185 return DC_ERROR; 05186 myrpt->p.sysstate_cur = digitbuf[0] - '0'; 05187 string[0] = string[1] = 'S'; 05188 string[2] = myrpt->p.sysstate_cur + '0'; 05189 string[3] = '\0'; 05190 rpt_telemetry(myrpt, ARB_ALPHA, (void *) string); 05191 return DC_COMPLETE; 05192 05193 case 15: /* Scheduler Enable */ 05194 myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 0; 05195 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKENA"); 05196 return DC_COMPLETE; 05197 05198 case 16: /* Scheduler Disable */ 05199 myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 1; 05200 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKDIS"); 05201 return DC_COMPLETE; 05202 05203 case 17: /* User functions Enable */ 05204 myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 0; 05205 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFENA"); 05206 return DC_COMPLETE; 05207 05208 case 18: /* User Functions Disable */ 05209 myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 1; 05210 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFDIS"); 05211 return DC_COMPLETE; 05212 05213 case 19: /* Alternate Tail Enable */ 05214 myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 1; 05215 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATENA"); 05216 return DC_COMPLETE; 05217 05218 case 20: /* Alternate Tail Disable */ 05219 myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 0; 05220 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATDIS"); 05221 return DC_COMPLETE; 05222 } 05223 return DC_INDETERMINATE; 05224 }
static int function_ilink | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 4646 of file app_rpt.c.
References AST_FRAME_TEXT, ast_log(), ast_safe_sleep(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt_link::chan, rpt::cmdnode, COMPLETE, connect_link(), CONNFAIL, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt_link::disced, do_dtmf_local(), finddelim(), ast_frame::frametype, FULLSTATUS, rpt::lastlinknode, LASTNODEKEY, sysstate::linkfundisable, rpt::links, rpt::lock, LOG_NOTICE, rpt::longestnode, ast_frame::mallocd, MAX_RETRIES, rpt_link::max_retries, MAXLINKLIST, MAXNODESTR, mdc1200_notify(), rpt_link::mode, myatoi(), rpt::name, rpt_link::name, rpt_link::next, node_lookup(), ast_frame::offset, rpt::p, rpt_link::perma, rpt::propagate_dtmf, rpt::propagate_phonedtmf, REMALREADY, REMGO, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::s, s, ast_frame::samples, rpt::savednodes, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, SOURCE_RPT, STATUS, strsep(), ast_frame::subclass, rpt::sysstate_cur, and sysstate::txdisable.
04647 { 04648 04649 char *val, *s, *s1, *s2; 04650 char tmp[300]; 04651 char digitbuf[MAXNODESTR],*strs[MAXLINKLIST]; 04652 char mode,perma; 04653 struct rpt_link *l; 04654 int i,r; 04655 04656 if(!param) 04657 return DC_ERROR; 04658 04659 04660 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable ) 04661 return DC_ERROR; 04662 04663 strncpy(digitbuf,digits,MAXNODESTR - 1); 04664 04665 if(debug > 6) 04666 printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 04667 04668 switch(myatoi(param)){ 04669 case 11: /* Perm Link off */ 04670 case 1: /* Link off */ 04671 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04672 strcpy(digitbuf,myrpt->lastlinknode); 04673 val = node_lookup(myrpt,digitbuf); 04674 if (!val){ 04675 if(strlen(digitbuf) >= myrpt->longestnode) 04676 return DC_ERROR; 04677 break; 04678 } 04679 strncpy(tmp,val,sizeof(tmp) - 1); 04680 s = tmp; 04681 s1 = strsep(&s,","); 04682 s2 = strsep(&s,","); 04683 rpt_mutex_lock(&myrpt->lock); 04684 l = myrpt->links.next; 04685 /* try to find this one in queue */ 04686 while(l != &myrpt->links){ 04687 if (l->name[0] == '0') 04688 { 04689 l = l->next; 04690 continue; 04691 } 04692 /* if found matching string */ 04693 if (!strcmp(l->name, digitbuf)) 04694 break; 04695 l = l->next; 04696 } 04697 if (l != &myrpt->links){ /* if found */ 04698 struct ast_frame wf; 04699 04700 /* must use perm command on perm link */ 04701 if ((myatoi(param) < 10) && 04702 (l->max_retries > MAX_RETRIES)) 04703 { 04704 rpt_mutex_unlock(&myrpt->lock); 04705 return DC_COMPLETE; 04706 } 04707 strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1); 04708 l->retries = l->max_retries + 1; 04709 l->disced = 1; 04710 rpt_mutex_unlock(&myrpt->lock); 04711 wf.frametype = AST_FRAME_TEXT; 04712 wf.subclass = 0; 04713 wf.offset = 0; 04714 wf.mallocd = 0; 04715 wf.datalen = strlen(discstr) + 1; 04716 wf.samples = 0; 04717 wf.data = discstr; 04718 if (l->chan) 04719 { 04720 ast_write(l->chan,&wf); 04721 if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR; 04722 ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 04723 } 04724 rpt_telemetry(myrpt, COMPLETE, NULL); 04725 return DC_COMPLETE; 04726 } 04727 rpt_mutex_unlock(&myrpt->lock); 04728 return DC_COMPLETE; 04729 case 2: /* Link Monitor */ 04730 case 3: /* Link transceive */ 04731 case 12: /* Link Monitor permanent */ 04732 case 13: /* Link transceive permanent */ 04733 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04734 strcpy(digitbuf,myrpt->lastlinknode); 04735 /* Attempt connection */ 04736 perma = (atoi(param) > 10) ? 1 : 0; 04737 mode = (atoi(param) & 1) ? 1 : 0; 04738 r = connect_link(myrpt, digitbuf, mode, perma); 04739 switch(r){ 04740 case 0: 04741 rpt_telemetry(myrpt, COMPLETE, NULL); 04742 return DC_COMPLETE; 04743 04744 case 1: 04745 break; 04746 04747 case 2: 04748 rpt_telemetry(myrpt, REMALREADY, NULL); 04749 return DC_COMPLETE; 04750 04751 default: 04752 rpt_telemetry(myrpt, CONNFAIL, NULL); 04753 return DC_COMPLETE; 04754 } 04755 break; 04756 04757 case 4: /* Enter Command Mode */ 04758 04759 /* if doesnt allow link cmd, or no links active, return */ 04760 if (((command_source != SOURCE_RPT) && 04761 (command_source != SOURCE_PHONE) && 04762 (command_source != SOURCE_DPHONE)) || 04763 (myrpt->links.next == &myrpt->links)) 04764 return DC_COMPLETE; 04765 04766 /* if already in cmd mode, or selected self, fughetabahtit */ 04767 if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){ 04768 04769 rpt_telemetry(myrpt, REMALREADY, NULL); 04770 return DC_COMPLETE; 04771 } 04772 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04773 strcpy(digitbuf,myrpt->lastlinknode); 04774 /* node must at least exist in list */ 04775 val = node_lookup(myrpt,digitbuf); 04776 if (!val){ 04777 if(strlen(digitbuf) >= myrpt->longestnode) 04778 return DC_ERROR; 04779 break; 04780 04781 } 04782 rpt_mutex_lock(&myrpt->lock); 04783 strcpy(myrpt->lastlinknode,digitbuf); 04784 strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1); 04785 rpt_mutex_unlock(&myrpt->lock); 04786 rpt_telemetry(myrpt, REMGO, NULL); 04787 return DC_COMPLETE; 04788 04789 case 5: /* Status */ 04790 rpt_telemetry(myrpt, STATUS, NULL); 04791 return DC_COMPLETE; 04792 04793 case 15: /* Full Status */ 04794 rpt_telemetry(myrpt, FULLSTATUS, NULL); 04795 return DC_COMPLETE; 04796 04797 04798 case 6: /* All Links Off, including permalinks */ 04799 rpt_mutex_lock(&myrpt->lock); 04800 myrpt->savednodes[0] = 0; 04801 l = myrpt->links.next; 04802 /* loop through all links */ 04803 while(l != &myrpt->links){ 04804 struct ast_frame wf; 04805 if (l->name[0] == '0') /* Skip any IAXRPT monitoring */ 04806 { 04807 l = l->next; 04808 continue; 04809 } 04810 /* Make a string of disconnected nodes for possible restoration */ 04811 sprintf(tmp,"%c%c%s",(l->mode) ? 'X' : 'M',(l->perma) ? 'P':'T',l->name); 04812 if(strlen(tmp) + strlen(myrpt->savednodes) + 1 < MAXNODESTR){ 04813 if(myrpt->savednodes[0]) 04814 strcat(myrpt->savednodes, ","); 04815 strcat(myrpt->savednodes, tmp); 04816 } 04817 l->retries = l->max_retries + 1; 04818 l->disced = 2; /* Silently disconnect */ 04819 rpt_mutex_unlock(&myrpt->lock); 04820 /* ast_log(LOG_NOTICE,"dumping link %s\n",l->name); */ 04821 04822 wf.frametype = AST_FRAME_TEXT; 04823 wf.subclass = 0; 04824 wf.offset = 0; 04825 wf.mallocd = 0; 04826 wf.datalen = strlen(discstr) + 1; 04827 wf.samples = 0; 04828 wf.data = discstr; 04829 if (l->chan) 04830 { 04831 ast_write(l->chan,&wf); 04832 ast_safe_sleep(l->chan,250); /* It's dead already, why check the return value? */ 04833 ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 04834 } 04835 rpt_mutex_lock(&myrpt->lock); 04836 l = l->next; 04837 } 04838 rpt_mutex_unlock(&myrpt->lock); 04839 if(debug > 3) 04840 ast_log(LOG_NOTICE,"Nodes disconnected: %s\n",myrpt->savednodes); 04841 rpt_telemetry(myrpt, COMPLETE, NULL); 04842 return DC_COMPLETE; 04843 04844 case 7: /* Identify last node which keyed us up */ 04845 rpt_telemetry(myrpt, LASTNODEKEY, NULL); 04846 break; 04847 04848 04849 #ifdef _MDC_DECODE_H_ 04850 case 8: 04851 myrpt->lastunit = 0xd00d; 04852 mdc1200_notify(myrpt,NULL,myrpt->lastunit); 04853 mdc1200_send(myrpt,myrpt->lastunit); 04854 break; 04855 #endif 04856 04857 case 16: /* Restore links disconnected with "disconnect all links" command */ 04858 strcpy(tmp, myrpt->savednodes); /* Make a copy */ 04859 finddelim(tmp, strs, MAXLINKLIST); /* convert into substrings */ 04860 for(i = 0; tmp[0] && strs[i] != NULL && i < MAXLINKLIST; i++){ 04861 s1 = strs[i]; 04862 mode = (s1[0] == 'X') ? 1 : 0; 04863 perma = (s1[1] == 'P') ? 1 : 0; 04864 connect_link(myrpt, s1 + 2, mode, perma); /* Try to reconnect */ 04865 } 04866 rpt_telemetry(myrpt, COMPLETE, NULL); 04867 break; 04868 04869 case 200: 04870 case 201: 04871 case 202: 04872 case 203: 04873 case 204: 04874 case 205: 04875 case 206: 04876 case 207: 04877 case 208: 04878 case 209: 04879 case 210: 04880 case 211: 04881 case 212: 04882 case 213: 04883 case 214: 04884 case 215: 04885 if (((myrpt->p.propagate_dtmf) && 04886 (command_source == SOURCE_LNK)) || 04887 ((myrpt->p.propagate_phonedtmf) && 04888 ((command_source == SOURCE_PHONE) || 04889 (command_source == SOURCE_DPHONE)))) 04890 do_dtmf_local(myrpt, 04891 remdtmfstr[myatoi(param) - 200]); 04892 default: 04893 return DC_ERROR; 04894 04895 } 04896 04897 return DC_INDETERMINATE; 04898 }
static int function_macro | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5057 of file app_rpt.c.
References ast_variable_retrieve(), rpt::cfg, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt::lock, rpt::macro, MACRO_BUSY, rpt::macro_longest, MACRO_NOTFOUND, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, rpt::p, rpt::remote, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), and rpt::startupmacro.
05058 { 05059 05060 char *val; 05061 int i; 05062 if (myrpt->remote) 05063 return DC_ERROR; 05064 05065 if(debug) 05066 printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 05067 05068 if(strlen(digitbuf) < 1) /* needs 1 digit */ 05069 return DC_INDETERMINATE; 05070 05071 for(i = 0 ; i < digitbuf[i] ; i++) { 05072 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 05073 return DC_ERROR; 05074 } 05075 05076 if (*digitbuf == '0') val = myrpt->p.startupmacro; 05077 else val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, digitbuf); 05078 /* param was 1 for local buf */ 05079 if (!val){ 05080 if (strlen(digitbuf) < myrpt->macro_longest) 05081 return DC_INDETERMINATE; 05082 rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL); 05083 return DC_COMPLETE; 05084 } 05085 rpt_mutex_lock(&myrpt->lock); 05086 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)) 05087 { 05088 rpt_mutex_unlock(&myrpt->lock); 05089 rpt_telemetry(myrpt, MACRO_BUSY, NULL); 05090 return DC_ERROR; 05091 } 05092 myrpt->macrotimer = MACROTIME; 05093 strncat(myrpt->macrobuf,val,MAXMACRO - 1); 05094 rpt_mutex_unlock(&myrpt->lock); 05095 return DC_COMPLETE; 05096 }
static int function_remote | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 7752 of file app_rpt.c.
References rpt::archivedir, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_mutex_lock(), ast_mutex_unlock(), rpt::authlevel, check_freq(), DC_COMPLETE, DC_COMPLETEQUIET, DC_ERROR, DC_INDETERMINATE, do_dtmf_local(), donodelog(), free, 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, INVFREQ, rpt::lock, rpt::loginlevel, rpt::loginuser, MAXREMSTR, MEMNOTFOUND, multimode_bump_freq(), multimode_capable(), myatoi(), rpt::offset, offset, rpt::p, rpt::powerlevel, REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, REM_PLUS, REM_SCANTIME, REM_SIMPLEX, REMLOGIN, REMLONGSTATUS, REMMODE, rpt::remmode, rpt::remote, rpt::remotetx, REMSHORTSTATUS, REMXXX, retreive_memory(), rpt_telemetry(), rpt::rxpl, rpt::rxplon, s, rpt::scantimer, setrem(), SOURCE_LNK, SOURCE_RPT, split_freq(), strdup, strsep(), TUNE, rpt::tunerequest, rpt::txchannel, rpt::txpl, and rpt::txplon.
07753 { 07754 char *s,*s1,*s2; 07755 int i,j,p,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode; 07756 char multimode = 0; 07757 char oc,*cp,*cp1,*cp2; 07758 char tmp[20], freq[20] = "", savestr[20] = ""; 07759 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07760 07761 if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK)) 07762 return DC_ERROR; 07763 07764 p = myatoi(param); 07765 07766 if ((p != 99) && (p != 5) && (p != 140) && myrpt->p.authlevel && 07767 (!myrpt->loginlevel[0])) return DC_ERROR; 07768 multimode = multimode_capable(myrpt); 07769 07770 switch(p){ 07771 07772 case 1: /* retrieve memory */ 07773 if(strlen(digitbuf) < 2) /* needs 2 digits */ 07774 break; 07775 07776 for(i = 0 ; i < 2 ; i++){ 07777 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07778 return DC_ERROR; 07779 } 07780 07781 r = retreive_memory(myrpt, digitbuf); 07782 if (r < 0){ 07783 rpt_telemetry(myrpt,MEMNOTFOUND,NULL); 07784 return DC_COMPLETE; 07785 } 07786 if (r > 0){ 07787 return DC_ERROR; 07788 } 07789 if (setrem(myrpt) == -1) return DC_ERROR; 07790 return DC_COMPLETE; 07791 07792 case 2: /* set freq and offset */ 07793 07794 07795 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */ 07796 if(digitbuf[i] == '*'){ 07797 j++; 07798 continue; 07799 } 07800 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07801 goto invalid_freq; 07802 else{ 07803 if(j == 0) 07804 l++; /* # of digits before first * */ 07805 if(j == 1) 07806 k++; /* # of digits after first * */ 07807 } 07808 } 07809 07810 i = strlen(digitbuf) - 1; 07811 if(multimode){ 07812 if((j > 2) || (l > 3) || (k > 6)) 07813 goto invalid_freq; /* &^@#! */ 07814 } 07815 else{ 07816 if((j > 2) || (l > 4) || (k > 3)) 07817 goto invalid_freq; /* &^@#! */ 07818 } 07819 07820 /* Wait for M+*K+* */ 07821 07822 if(j < 2) 07823 break; /* Not yet */ 07824 07825 /* We have a frequency */ 07826 07827 strncpy(tmp, digitbuf ,sizeof(tmp) - 1); 07828 07829 s = tmp; 07830 s1 = strsep(&s, "*"); /* Pick off MHz */ 07831 s2 = strsep(&s,"*"); /* Pick off KHz and Hz */ 07832 ls2 = strlen(s2); 07833 07834 switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */ 07835 case 1: 07836 ht = 0; 07837 k = 100 * atoi(s2); 07838 break; 07839 07840 case 2: 07841 ht = 0; 07842 k = 10 * atoi(s2); 07843 break; 07844 07845 case 3: 07846 if(!multimode){ 07847 if((s2[2] != '0')&&(s2[2] != '5')) 07848 goto invalid_freq; 07849 } 07850 ht = 0; 07851 k = atoi(s2); 07852 break; 07853 case 4: 07854 k = atoi(s2)/10; 07855 ht = 10 * (atoi(s2+(ls2-1))); 07856 break; 07857 07858 case 5: 07859 k = atoi(s2)/100; 07860 ht = (atoi(s2+(ls2-2))); 07861 break; 07862 07863 default: 07864 goto invalid_freq; 07865 } 07866 07867 /* Check frequency for validity and establish a default mode */ 07868 07869 snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht); 07870 07871 if(debug) 07872 printf("New frequency: %s\n", freq); 07873 07874 split_freq(mhz, decimals, freq); 07875 m = atoi(mhz); 07876 d = atoi(decimals); 07877 07878 if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */ 07879 goto invalid_freq; 07880 07881 07882 if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */ 07883 break; /* Not yet */ 07884 07885 07886 offset = REM_SIMPLEX; /* Assume simplex */ 07887 07888 if(defmode == REM_MODE_FM){ 07889 oc = *s; /* Pick off offset */ 07890 07891 if (oc){ 07892 switch(oc){ 07893 case '1': 07894 offset = REM_MINUS; 07895 break; 07896 07897 case '2': 07898 offset = REM_SIMPLEX; 07899 break; 07900 07901 case '3': 07902 offset = REM_PLUS; 07903 break; 07904 07905 default: 07906 goto invalid_freq; 07907 } 07908 } 07909 } 07910 offsave = myrpt->offset; 07911 modesave = myrpt->remmode; 07912 strncpy(savestr, myrpt->freq, sizeof(savestr) - 1); 07913 strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1); 07914 myrpt->offset = offset; 07915 myrpt->remmode = defmode; 07916 07917 if (setrem(myrpt) == -1){ 07918 myrpt->offset = offsave; 07919 myrpt->remmode = modesave; 07920 strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1); 07921 goto invalid_freq; 07922 } 07923 07924 return DC_COMPLETE; 07925 07926 invalid_freq: 07927 rpt_telemetry(myrpt,INVFREQ,NULL); 07928 return DC_ERROR; 07929 07930 case 3: /* set rx PL tone */ 07931 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 07932 if(digitbuf[i] == '*'){ 07933 j++; 07934 continue; 07935 } 07936 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07937 return DC_ERROR; 07938 else{ 07939 if(j) 07940 l++; 07941 else 07942 k++; 07943 } 07944 } 07945 if((j > 1) || (k > 3) || (l > 1)) 07946 return DC_ERROR; /* &$@^! */ 07947 i = strlen(digitbuf) - 1; 07948 if((j != 1) || (k < 2)|| (l != 1)) 07949 break; /* Not yet */ 07950 if(debug) 07951 printf("PL digits entered %s\n", digitbuf); 07952 07953 strncpy(tmp, digitbuf, sizeof(tmp) - 1); 07954 /* see if we have at least 1 */ 07955 s = strchr(tmp,'*'); 07956 if(s) 07957 *s = '.'; 07958 strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1); 07959 strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1); 07960 if(!strcmp(myrpt->remote, remote_rig_rbi)) 07961 { 07962 strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1); 07963 } 07964 if (setrem(myrpt) == -1){ 07965 strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1); 07966 return DC_ERROR; 07967 } 07968 07969 07970 return DC_COMPLETE; 07971 07972 case 4: /* set tx PL tone */ 07973 /* cant set tx tone on RBI (rx tone does both) */ 07974 if(!strcmp(myrpt->remote, remote_rig_rbi)) 07975 return DC_ERROR; 07976 if(!strcmp(myrpt->remote, remote_rig_ic706)) 07977 return DC_ERROR; 07978 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 07979 if(digitbuf[i] == '*'){ 07980 j++; 07981 continue; 07982 } 07983 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07984 return DC_ERROR; 07985 else{ 07986 if(j) 07987 l++; 07988 else 07989 k++; 07990 } 07991 } 07992 if((j > 1) || (k > 3) || (l > 1)) 07993 return DC_ERROR; /* &$@^! */ 07994 i = strlen(digitbuf) - 1; 07995 if((j != 1) || (k < 2)|| (l != 1)) 07996 break; /* Not yet */ 07997 if(debug) 07998 printf("PL digits entered %s\n", digitbuf); 07999 08000 strncpy(tmp, digitbuf, sizeof(tmp) - 1); 08001 /* see if we have at least 1 */ 08002 s = strchr(tmp,'*'); 08003 if(s) 08004 *s = '.'; 08005 strncpy(savestr, myrpt->txpl, sizeof(savestr) - 1); 08006 strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1); 08007 08008 if (setrem(myrpt) == -1){ 08009 strncpy(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1); 08010 return DC_ERROR; 08011 } 08012 08013 08014 return DC_COMPLETE; 08015 08016 08017 case 6: /* MODE (FM,USB,LSB,AM) */ 08018 if(strlen(digitbuf) < 1) 08019 break; 08020 08021 if(!multimode) 08022 return DC_ERROR; /* Multimode radios only */ 08023 08024 switch(*digitbuf){ 08025 case '1': 08026 split_freq(mhz, decimals, myrpt->freq); 08027 m=atoi(mhz); 08028 if(m < 29) /* No FM allowed below 29MHz! */ 08029 return DC_ERROR; 08030 myrpt->remmode = REM_MODE_FM; 08031 08032 rpt_telemetry(myrpt,REMMODE,NULL); 08033 break; 08034 08035 case '2': 08036 myrpt->remmode = REM_MODE_USB; 08037 rpt_telemetry(myrpt,REMMODE,NULL); 08038 break; 08039 08040 case '3': 08041 myrpt->remmode = REM_MODE_LSB; 08042 rpt_telemetry(myrpt,REMMODE,NULL); 08043 break; 08044 08045 case '4': 08046 myrpt->remmode = REM_MODE_AM; 08047 rpt_telemetry(myrpt,REMMODE,NULL); 08048 break; 08049 08050 default: 08051 return DC_ERROR; 08052 } 08053 08054 if(setrem(myrpt)) 08055 return DC_ERROR; 08056 return DC_COMPLETEQUIET; 08057 case 99: 08058 /* cant log in when logged in */ 08059 if (myrpt->loginlevel[0]) 08060 return DC_ERROR; 08061 *myrpt->loginuser = 0; 08062 myrpt->loginlevel[0] = 0; 08063 cp = strdup(param); 08064 cp1 = strchr(cp,','); 08065 ast_mutex_lock(&myrpt->lock); 08066 if (cp1) 08067 { 08068 *cp1 = 0; 08069 cp2 = strchr(cp1 + 1,','); 08070 if (cp2) 08071 { 08072 *cp2 = 0; 08073 strncpy(myrpt->loginlevel,cp2 + 1, 08074 sizeof(myrpt->loginlevel) - 1); 08075 } 08076 strncpy(myrpt->loginuser,cp1 + 1,sizeof(myrpt->loginuser)); 08077 ast_mutex_unlock(&myrpt->lock); 08078 if (myrpt->p.archivedir) 08079 { 08080 char str[100]; 08081 08082 sprintf(str,"LOGIN,%s,%s", 08083 myrpt->loginuser,myrpt->loginlevel); 08084 donodelog(myrpt,str); 08085 } 08086 if (debug) 08087 printf("loginuser %s level %s\n",myrpt->loginuser,myrpt->loginlevel); 08088 rpt_telemetry(myrpt,REMLOGIN,NULL); 08089 } 08090 free(cp); 08091 return DC_COMPLETEQUIET; 08092 case 100: /* RX PL Off */ 08093 myrpt->rxplon = 0; 08094 setrem(myrpt); 08095 rpt_telemetry(myrpt,REMXXX,(void *)p); 08096 return DC_COMPLETEQUIET; 08097 case 101: /* RX PL On */ 08098 myrpt->rxplon = 1; 08099 setrem(myrpt); 08100 rpt_telemetry(myrpt,REMXXX,(void *)p); 08101 return DC_COMPLETEQUIET; 08102 case 102: /* TX PL Off */ 08103 myrpt->txplon = 0; 08104 setrem(myrpt); 08105 rpt_telemetry(myrpt,REMXXX,(void *)p); 08106 return DC_COMPLETEQUIET; 08107 case 103: /* TX PL On */ 08108 myrpt->txplon = 1; 08109 setrem(myrpt); 08110 rpt_telemetry(myrpt,REMXXX,(void *)p); 08111 return DC_COMPLETEQUIET; 08112 case 104: /* Low Power */ 08113 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08114 return DC_ERROR; 08115 myrpt->powerlevel = REM_LOWPWR; 08116 setrem(myrpt); 08117 rpt_telemetry(myrpt,REMXXX,(void *)p); 08118 return DC_COMPLETEQUIET; 08119 case 105: /* Medium Power */ 08120 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08121 return DC_ERROR; 08122 myrpt->powerlevel = REM_MEDPWR; 08123 setrem(myrpt); 08124 rpt_telemetry(myrpt,REMXXX,(void *)p); 08125 return DC_COMPLETEQUIET; 08126 case 106: /* Hi Power */ 08127 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08128 return DC_ERROR; 08129 myrpt->powerlevel = REM_HIPWR; 08130 setrem(myrpt); 08131 rpt_telemetry(myrpt,REMXXX,(void *)p); 08132 return DC_COMPLETEQUIET; 08133 case 107: /* Bump down 20Hz */ 08134 multimode_bump_freq(myrpt, -20); 08135 return DC_COMPLETE; 08136 case 108: /* Bump down 100Hz */ 08137 multimode_bump_freq(myrpt, -100); 08138 return DC_COMPLETE; 08139 case 109: /* Bump down 500Hz */ 08140 multimode_bump_freq(myrpt, -500); 08141 return DC_COMPLETE; 08142 case 110: /* Bump up 20Hz */ 08143 multimode_bump_freq(myrpt, 20); 08144 return DC_COMPLETE; 08145 case 111: /* Bump up 100Hz */ 08146 multimode_bump_freq(myrpt, 100); 08147 return DC_COMPLETE; 08148 case 112: /* Bump up 500Hz */ 08149 multimode_bump_freq(myrpt, 500); 08150 return DC_COMPLETE; 08151 case 113: /* Scan down slow */ 08152 myrpt->scantimer = REM_SCANTIME; 08153 myrpt->hfscanmode = HF_SCAN_DOWN_SLOW; 08154 rpt_telemetry(myrpt,REMXXX,(void *)p); 08155 return DC_COMPLETEQUIET; 08156 case 114: /* Scan down quick */ 08157 myrpt->scantimer = REM_SCANTIME; 08158 myrpt->hfscanmode = HF_SCAN_DOWN_QUICK; 08159 rpt_telemetry(myrpt,REMXXX,(void *)p); 08160 return DC_COMPLETEQUIET; 08161 case 115: /* Scan down fast */ 08162 myrpt->scantimer = REM_SCANTIME; 08163 myrpt->hfscanmode = HF_SCAN_DOWN_FAST; 08164 rpt_telemetry(myrpt,REMXXX,(void *)p); 08165 return DC_COMPLETEQUIET; 08166 case 116: /* Scan up slow */ 08167 myrpt->scantimer = REM_SCANTIME; 08168 myrpt->hfscanmode = HF_SCAN_UP_SLOW; 08169 rpt_telemetry(myrpt,REMXXX,(void *)p); 08170 return DC_COMPLETEQUIET; 08171 case 117: /* Scan up quick */ 08172 myrpt->scantimer = REM_SCANTIME; 08173 myrpt->hfscanmode = HF_SCAN_UP_QUICK; 08174 rpt_telemetry(myrpt,REMXXX,(void *)p); 08175 return DC_COMPLETEQUIET; 08176 case 118: /* Scan up fast */ 08177 myrpt->scantimer = REM_SCANTIME; 08178 myrpt->hfscanmode = HF_SCAN_UP_FAST; 08179 rpt_telemetry(myrpt,REMXXX,(void *)p); 08180 return DC_COMPLETEQUIET; 08181 case 119: /* Tune Request */ 08182 /* if not currently going, and valid to do */ 08183 if((!myrpt->tunerequest) && 08184 ((!strcmp(myrpt->remote, remote_rig_ft897) || 08185 !strcmp(myrpt->remote, remote_rig_ic706)) )) { 08186 myrpt->remotetx = 0; 08187 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 08188 myrpt->tunerequest = 1; 08189 rpt_telemetry(myrpt,TUNE,NULL); 08190 return DC_COMPLETEQUIET; 08191 } 08192 return DC_ERROR; 08193 case 5: /* Long Status */ 08194 rpt_telemetry(myrpt,REMLONGSTATUS,NULL); 08195 return DC_COMPLETEQUIET; 08196 case 140: /* Short Status */ 08197 rpt_telemetry(myrpt,REMSHORTSTATUS,NULL); 08198 return DC_COMPLETEQUIET; 08199 case 200: 08200 case 201: 08201 case 202: 08202 case 203: 08203 case 204: 08204 case 205: 08205 case 206: 08206 case 207: 08207 case 208: 08208 case 209: 08209 case 210: 08210 case 211: 08211 case 212: 08212 case 213: 08213 case 214: 08214 case 215: 08215 do_dtmf_local(myrpt,remdtmfstr[p - 200]); 08216 return DC_COMPLETEQUIET; 08217 default: 08218 break; 08219 } 08220 return DC_INDETERMINATE; 08221 }
static int function_status | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5026 of file app_rpt.c.
References DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, ID1, myatoi(), rpt::p, rpt_telemetry(), rpt::s, STATS_TIME, STATS_VERSION, rpt::sysstate_cur, sysstate::txdisable, and sysstate::userfundisable.
05027 { 05028 05029 if (!param) 05030 return DC_ERROR; 05031 05032 if ((myrpt->p.s[myrpt->p.sysstate_cur].txdisable) || (myrpt->p.s[myrpt->p.sysstate_cur].userfundisable)) 05033 return DC_ERROR; 05034 05035 if(debug) 05036 printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 05037 05038 switch(myatoi(param)){ 05039 case 1: /* System ID */ 05040 rpt_telemetry(myrpt, ID1, NULL); 05041 return DC_COMPLETE; 05042 case 2: /* System Time */ 05043 rpt_telemetry(myrpt, STATS_TIME, NULL); 05044 return DC_COMPLETE; 05045 case 3: /* app_rpt.c version */ 05046 rpt_telemetry(myrpt, STATS_VERSION, NULL); 05047 default: 05048 return DC_ERROR; 05049 } 05050 return DC_INDETERMINATE; 05051 }
static int get_wait_interval | ( | struct rpt * | myrpt, | |
int | type | |||
) | [static] |
Definition at line 2823 of file app_rpt.c.
References ast_log(), ast_strdupa, ast_variable_retrieve(), rpt::cfg, DLY_CALLTERM, DLY_COMP, DLY_ID, DLY_LINKUNKEY, DLY_TELEM, DLY_UNKEY, LOG_WARNING, rpt::name, and retrieve_astcfgint().
Referenced by rpt_tele_thread(), and wait_interval().
02824 { 02825 int interval; 02826 char *wait_times; 02827 char *wait_times_save; 02828 02829 wait_times_save = NULL; 02830 wait_times = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "wait_times"); 02831 02832 if(wait_times){ 02833 wait_times_save = ast_strdupa(wait_times); 02834 if(!wait_times_save){ 02835 ast_log(LOG_WARNING, "Out of memory in wait_interval()\n"); 02836 wait_times = NULL; 02837 } 02838 } 02839 02840 switch(type){ 02841 case DLY_TELEM: 02842 if(wait_times) 02843 interval = retrieve_astcfgint(myrpt,wait_times_save, "telemwait", 500, 5000, 1000); 02844 else 02845 interval = 1000; 02846 break; 02847 02848 case DLY_ID: 02849 if(wait_times) 02850 interval = retrieve_astcfgint(myrpt,wait_times_save, "idwait",250,5000,500); 02851 else 02852 interval = 500; 02853 break; 02854 02855 case DLY_UNKEY: 02856 if(wait_times) 02857 interval = retrieve_astcfgint(myrpt,wait_times_save, "unkeywait",500,5000,1000); 02858 else 02859 interval = 1000; 02860 break; 02861 02862 case DLY_LINKUNKEY: 02863 if(wait_times) 02864 interval = retrieve_astcfgint(myrpt,wait_times_save, "linkunkeywait",500,5000,1000); 02865 else 02866 interval = 1000; 02867 break; 02868 02869 case DLY_CALLTERM: 02870 if(wait_times) 02871 interval = retrieve_astcfgint(myrpt,wait_times_save, "calltermwait",500,5000,1500); 02872 else 02873 interval = 1500; 02874 break; 02875 02876 case DLY_COMP: 02877 if(wait_times) 02878 interval = retrieve_astcfgint(myrpt,wait_times_save, "compwait",500,5000,200); 02879 else 02880 interval = 200; 02881 break; 02882 02883 default: 02884 return 0; 02885 } 02886 return interval; 02887 }
Definition at line 5305 of file app_rpt.c.
References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_TEXT, ast_log(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt::callmode, rpt_link::chan, rpt::cidx, collect_function_digits(), rpt::dailyexecdcommands, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_COMPLETEQUIET, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt_link::disced, do_dtmf_local(), do_dtmf_phone(), donodelog(), rpt::endchar, rpt::exten, ast_frame::frametype, func_xlat(), rpt::funcchar, rpt::lastdtmfcommand, rpt_link::linklist, rpt_link::linklistreceived, rpt::links, rpt::lock, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, rpt_link::max_retries, MAXDTMF, mdc1200_notify(), rpt::mydtmf, rpt_link::name, rpt::name, rpt_link::next, ast_frame::offset, rpt::outxlat, rpt::p, rpt::patchcontext, rpt::patchquiet, rpt::pchannel, PROC, rpt::propagate_dtmf, rpt::propagate_phonedtmf, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), ast_frame::samples, seq, SOURCE_LNK, rpt::stopgen, ast_frame::subclass, and rpt::totalexecdcommands.
Referenced by rpt().
05307 { 05308 char tmp[512],cmd[300] = "",dest[300],src[300],c; 05309 int seq, res; 05310 struct rpt_link *l; 05311 struct ast_frame wf; 05312 05313 wf.frametype = AST_FRAME_TEXT; 05314 wf.subclass = 0; 05315 wf.offset = 0; 05316 wf.mallocd = 0; 05317 wf.datalen = strlen(str) + 1; 05318 wf.samples = 0; 05319 /* put string in our buffer */ 05320 strncpy(tmp,str,sizeof(tmp) - 1); 05321 05322 if (!strcmp(tmp,discstr)) 05323 { 05324 mylink->disced = 1; 05325 mylink->retries = mylink->max_retries + 1; 05326 ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV); 05327 return; 05328 } 05329 if (tmp[0] == 'L') 05330 { 05331 rpt_mutex_lock(&myrpt->lock); 05332 strcpy(mylink->linklist,tmp + 2); 05333 time(&mylink->linklistreceived); 05334 rpt_mutex_unlock(&myrpt->lock); 05335 if (debug > 6) ast_log(LOG_NOTICE,"@@@@ node %s recieved node list %s from node %s\n", 05336 myrpt->name,tmp,mylink->name); 05337 return; 05338 } 05339 if (tmp[0] == 'I') 05340 { 05341 if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3) 05342 { 05343 ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str); 05344 return; 05345 } 05346 mdc1200_notify(myrpt,src,seq); 05347 strcpy(dest,"*"); 05348 } 05349 else 05350 { 05351 if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5) 05352 { 05353 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 05354 return; 05355 } 05356 if (strcmp(cmd,"D")) 05357 { 05358 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 05359 return; 05360 } 05361 } 05362 if (dest[0] == '0') 05363 { 05364 strcpy(dest,myrpt->name); 05365 } 05366 05367 /* if not for me, redistribute to all links */ 05368 if (strcmp(dest,myrpt->name)) 05369 { 05370 l = myrpt->links.next; 05371 /* see if this is one in list */ 05372 while(l != &myrpt->links) 05373 { 05374 if (l->name[0] == '0') 05375 { 05376 l = l->next; 05377 continue; 05378 } 05379 /* dont send back from where it came */ 05380 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 05381 { 05382 l = l->next; 05383 continue; 05384 } 05385 /* if it is, send it and we're done */ 05386 if (!strcmp(l->name,dest)) 05387 { 05388 /* send, but not to src */ 05389 if (strcmp(l->name,src)) { 05390 wf.data = str; 05391 if (l->chan) ast_write(l->chan,&wf); 05392 } 05393 return; 05394 } 05395 l = l->next; 05396 } 05397 l = myrpt->links.next; 05398 /* otherwise, send it to all of em */ 05399 while(l != &myrpt->links) 05400 { 05401 if (l->name[0] == '0') 05402 { 05403 l = l->next; 05404 continue; 05405 } 05406 /* dont send back from where it came */ 05407 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 05408 { 05409 l = l->next; 05410 continue; 05411 } 05412 /* send, but not to src */ 05413 if (strcmp(l->name,src)) { 05414 wf.data = str; 05415 if (l->chan) ast_write(l->chan,&wf); 05416 } 05417 l = l->next; 05418 } 05419 return; 05420 } 05421 if (myrpt->p.archivedir) 05422 { 05423 char str[100]; 05424 05425 sprintf(str,"DTMF,%s,%c",mylink->name,c); 05426 donodelog(myrpt,str); 05427 } 05428 c = func_xlat(myrpt,c,&myrpt->p.outxlat); 05429 if (!c) return; 05430 rpt_mutex_lock(&myrpt->lock); 05431 if (c == myrpt->p.endchar) myrpt->stopgen = 1; 05432 if (myrpt->callmode == 1) 05433 { 05434 myrpt->exten[myrpt->cidx++] = c; 05435 myrpt->exten[myrpt->cidx] = 0; 05436 /* if this exists */ 05437 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05438 { 05439 myrpt->callmode = 2; 05440 if(!myrpt->patchquiet){ 05441 rpt_mutex_unlock(&myrpt->lock); 05442 rpt_telemetry(myrpt,PROC,NULL); 05443 rpt_mutex_lock(&myrpt->lock); 05444 } 05445 } 05446 /* if can continue, do so */ 05447 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05448 { 05449 /* call has failed, inform user */ 05450 myrpt->callmode = 4; 05451 } 05452 } 05453 if (c == myrpt->p.funcchar) 05454 { 05455 myrpt->rem_dtmfidx = 0; 05456 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05457 time(&myrpt->rem_dtmf_time); 05458 rpt_mutex_unlock(&myrpt->lock); 05459 return; 05460 } 05461 else if (myrpt->rem_dtmfidx < 0) 05462 { 05463 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 05464 { 05465 myrpt->mydtmf = c; 05466 } 05467 if (myrpt->p.propagate_dtmf) do_dtmf_local(myrpt,c); 05468 if (myrpt->p.propagate_phonedtmf) do_dtmf_phone(myrpt,mylink,c); 05469 rpt_mutex_unlock(&myrpt->lock); 05470 return; 05471 } 05472 else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0)) 05473 { 05474 time(&myrpt->rem_dtmf_time); 05475 if (myrpt->rem_dtmfidx < MAXDTMF) 05476 { 05477 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 05478 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05479 05480 rpt_mutex_unlock(&myrpt->lock); 05481 strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1); 05482 res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink); 05483 rpt_mutex_lock(&myrpt->lock); 05484 05485 switch(res){ 05486 05487 case DC_INDETERMINATE: 05488 break; 05489 05490 case DC_REQ_FLUSH: 05491 myrpt->rem_dtmfidx = 0; 05492 myrpt->rem_dtmfbuf[0] = 0; 05493 break; 05494 05495 05496 case DC_COMPLETE: 05497 case DC_COMPLETEQUIET: 05498 myrpt->totalexecdcommands++; 05499 myrpt->dailyexecdcommands++; 05500 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 05501 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 05502 myrpt->rem_dtmfbuf[0] = 0; 05503 myrpt->rem_dtmfidx = -1; 05504 myrpt->rem_dtmf_time = 0; 05505 break; 05506 05507 case DC_ERROR: 05508 default: 05509 myrpt->rem_dtmfbuf[0] = 0; 05510 myrpt->rem_dtmfidx = -1; 05511 myrpt->rem_dtmf_time = 0; 05512 break; 05513 } 05514 } 05515 05516 } 05517 rpt_mutex_unlock(&myrpt->lock); 05518 return; 05519 }
static void handle_link_phone_dtmf | ( | struct rpt * | myrpt, | |
struct rpt_link * | mylink, | |||
char | c | |||
) | [static] |
Definition at line 5521 of file app_rpt.c.
References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), rpt::callmode, rpt::cidx, rpt::cmdnode, collect_function_digits(), COMPLETE, rpt::dailyexecdcommands, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, donodelog(), rpt::dtmfbuf, rpt::dtmfidx, rpt::endchar, rpt::exten, rpt::funcchar, rpt::lastdtmfcommand, rpt_link::lastrx, rpt::lock, MAXDTMF, rpt::mydtmf, rpt_link::name, rpt::p, rpt::patchcontext, rpt::patchquiet, rpt::pchannel, rpt_link::phonemode, PROC, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), send_link_dtmf(), SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, rpt::stopgen, and rpt::totalexecdcommands.
Referenced by rpt().
05523 { 05524 05525 char cmd[300]; 05526 int res; 05527 05528 if (myrpt->p.archivedir) 05529 { 05530 char str[100]; 05531 05532 sprintf(str,"DTMF(P),%s,%c",mylink->name,c); 05533 donodelog(myrpt,str); 05534 } 05535 rpt_mutex_lock(&myrpt->lock); 05536 if (c == myrpt->p.endchar) 05537 { 05538 if (mylink->lastrx) 05539 { 05540 mylink->lastrx = 0; 05541 rpt_mutex_unlock(&myrpt->lock); 05542 return; 05543 } 05544 myrpt->stopgen = 1; 05545 if (myrpt->cmdnode[0]) 05546 { 05547 myrpt->cmdnode[0] = 0; 05548 myrpt->dtmfidx = -1; 05549 myrpt->dtmfbuf[0] = 0; 05550 rpt_mutex_unlock(&myrpt->lock); 05551 rpt_telemetry(myrpt,COMPLETE,NULL); 05552 return; 05553 } 05554 } 05555 if (myrpt->cmdnode[0]) 05556 { 05557 rpt_mutex_unlock(&myrpt->lock); 05558 send_link_dtmf(myrpt,c); 05559 return; 05560 } 05561 if (myrpt->callmode == 1) 05562 { 05563 myrpt->exten[myrpt->cidx++] = c; 05564 myrpt->exten[myrpt->cidx] = 0; 05565 /* if this exists */ 05566 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05567 { 05568 myrpt->callmode = 2; 05569 if(!myrpt->patchquiet){ 05570 rpt_mutex_unlock(&myrpt->lock); 05571 rpt_telemetry(myrpt,PROC,NULL); 05572 rpt_mutex_lock(&myrpt->lock); 05573 } 05574 } 05575 /* if can continue, do so */ 05576 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05577 { 05578 /* call has failed, inform user */ 05579 myrpt->callmode = 4; 05580 } 05581 } 05582 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 05583 { 05584 myrpt->mydtmf = c; 05585 } 05586 if (c == myrpt->p.funcchar) 05587 { 05588 myrpt->rem_dtmfidx = 0; 05589 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05590 time(&myrpt->rem_dtmf_time); 05591 rpt_mutex_unlock(&myrpt->lock); 05592 return; 05593 } 05594 else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0)) 05595 { 05596 time(&myrpt->rem_dtmf_time); 05597 if (myrpt->rem_dtmfidx < MAXDTMF) 05598 { 05599 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 05600 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05601 05602 rpt_mutex_unlock(&myrpt->lock); 05603 strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1); 05604 switch(mylink->phonemode) 05605 { 05606 case 1: 05607 res = collect_function_digits(myrpt, cmd, 05608 SOURCE_PHONE, mylink); 05609 break; 05610 case 2: 05611 res = collect_function_digits(myrpt, cmd, 05612 SOURCE_DPHONE,mylink); 05613 break; 05614 default: 05615 res = collect_function_digits(myrpt, cmd, 05616 SOURCE_LNK, mylink); 05617 break; 05618 } 05619 05620 rpt_mutex_lock(&myrpt->lock); 05621 05622 switch(res){ 05623 05624 case DC_INDETERMINATE: 05625 break; 05626 05627 case DC_DOKEY: 05628 mylink->lastrx = 1; 05629 break; 05630 05631 case DC_REQ_FLUSH: 05632 myrpt->rem_dtmfidx = 0; 05633 myrpt->rem_dtmfbuf[0] = 0; 05634 break; 05635 05636 05637 case DC_COMPLETE: 05638 case DC_COMPLETEQUIET: 05639 myrpt->totalexecdcommands++; 05640 myrpt->dailyexecdcommands++; 05641 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 05642 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 05643 myrpt->rem_dtmfbuf[0] = 0; 05644 myrpt->rem_dtmfidx = -1; 05645 myrpt->rem_dtmf_time = 0; 05646 break; 05647 05648 case DC_ERROR: 05649 default: 05650 myrpt->rem_dtmfbuf[0] = 0; 05651 myrpt->rem_dtmfidx = -1; 05652 myrpt->rem_dtmf_time = 0; 05653 break; 05654 } 05655 } 05656 05657 } 05658 rpt_mutex_unlock(&myrpt->lock); 05659 return; 05660 }
static int handle_remote_data | ( | struct rpt * | myrpt, | |
char * | str | |||
) | [static] |
Definition at line 8334 of file app_rpt.c.
References rpt::archivedir, ast_log(), COMPLETE, donodelog(), func_xlat(), handle_remote_dtmf_digit(), LOG_WARNING, mdc1200_notify(), rpt::name, rpt::outxlat, rpt::p, rpt_telemetry(), and seq.
Referenced by rpt_exec().
08335 { 08336 char tmp[300],cmd[300],dest[300],src[300],c; 08337 int seq,res; 08338 08339 /* put string in our buffer */ 08340 strncpy(tmp,str,sizeof(tmp) - 1); 08341 if (!strcmp(tmp,discstr)) return 0; 08342 08343 #ifndef DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES 08344 if (tmp[0] == 'I') 08345 { 08346 if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3) 08347 { 08348 ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str); 08349 return 0; 08350 } 08351 mdc1200_notify(myrpt,src,seq); 08352 return 0; 08353 } 08354 #endif 08355 if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5) 08356 { 08357 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 08358 return 0; 08359 } 08360 if (strcmp(cmd,"D")) 08361 { 08362 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 08363 return 0; 08364 } 08365 /* if not for me, ignore */ 08366 if (strcmp(dest,myrpt->name)) return 0; 08367 if (myrpt->p.archivedir) 08368 { 08369 char str[100]; 08370 08371 sprintf(str,"DTMF,%c",c); 08372 donodelog(myrpt,str); 08373 } 08374 c = func_xlat(myrpt,c,&myrpt->p.outxlat); 08375 if (!c) return(0); 08376 res = handle_remote_dtmf_digit(myrpt,c, NULL, 0); 08377 if (res != 1) 08378 return res; 08379 rpt_telemetry(myrpt,COMPLETE,NULL); 08380 return 0; 08381 }
static int handle_remote_dtmf_digit | ( | struct rpt * | myrpt, | |
char | c, | |||
char * | keyed, | |||
int | phonemode | |||
) | [static] |
Definition at line 8224 of file app_rpt.c.
References collect_function_digits(), rpt::dailyexecdcommands, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, do_dtmf_local(), rpt::dtmf_time_rem, DTMF_TIMEOUT, rpt::dtmfbuf, rpt::dtmfidx, rpt::funcchar, rpt::hfscanmode, rpt::last_activity_time, rpt::lastdtmfcommand, rpt::lock, MAXDTMF, rpt::p, rpt::propagate_dtmf, rpt_mutex_lock, rpt_mutex_unlock, SOURCE_DPHONE, SOURCE_PHONE, SOURCE_RMT, stop_scan(), and rpt::totalexecdcommands.
Referenced by handle_remote_data(), handle_remote_phone_dtmf(), and rpt_exec().
08225 { 08226 time_t now; 08227 int ret,res = 0,src; 08228 08229 time(&myrpt->last_activity_time); 08230 /* Stop scan mode if in scan mode */ 08231 if(myrpt->hfscanmode){ 08232 stop_scan(myrpt); 08233 return 0; 08234 } 08235 08236 time(&now); 08237 /* if timed-out */ 08238 if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now) 08239 { 08240 myrpt->dtmfidx = -1; 08241 myrpt->dtmfbuf[0] = 0; 08242 myrpt->dtmf_time_rem = 0; 08243 } 08244 /* if decode not active */ 08245 if (myrpt->dtmfidx == -1) 08246 { 08247 /* if not lead-in digit, dont worry */ 08248 if (c != myrpt->p.funcchar) 08249 { 08250 if (!myrpt->p.propagate_dtmf) 08251 { 08252 rpt_mutex_lock(&myrpt->lock); 08253 do_dtmf_local(myrpt,c); 08254 rpt_mutex_unlock(&myrpt->lock); 08255 } 08256 return 0; 08257 } 08258 myrpt->dtmfidx = 0; 08259 myrpt->dtmfbuf[0] = 0; 08260 myrpt->dtmf_time_rem = now; 08261 return 0; 08262 } 08263 /* if too many in buffer, start over */ 08264 if (myrpt->dtmfidx >= MAXDTMF) 08265 { 08266 myrpt->dtmfidx = 0; 08267 myrpt->dtmfbuf[0] = 0; 08268 myrpt->dtmf_time_rem = now; 08269 } 08270 if (c == myrpt->p.funcchar) 08271 { 08272 /* if star at beginning, or 2 together, erase buffer */ 08273 if ((myrpt->dtmfidx < 1) || 08274 (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->p.funcchar)) 08275 { 08276 myrpt->dtmfidx = 0; 08277 myrpt->dtmfbuf[0] = 0; 08278 myrpt->dtmf_time_rem = now; 08279 return 0; 08280 } 08281 } 08282 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 08283 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08284 myrpt->dtmf_time_rem = now; 08285 08286 08287 src = SOURCE_RMT; 08288 if (phonemode > 1) src = SOURCE_DPHONE; 08289 else if (phonemode) src = SOURCE_PHONE; 08290 ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL); 08291 08292 switch(ret){ 08293 08294 case DC_INDETERMINATE: 08295 res = 0; 08296 break; 08297 08298 case DC_DOKEY: 08299 if (keyed) *keyed = 1; 08300 res = 0; 08301 break; 08302 08303 case DC_REQ_FLUSH: 08304 myrpt->dtmfidx = 0; 08305 myrpt->dtmfbuf[0] = 0; 08306 res = 0; 08307 break; 08308 08309 08310 case DC_COMPLETE: 08311 res = 1; 08312 case DC_COMPLETEQUIET: 08313 myrpt->totalexecdcommands++; 08314 myrpt->dailyexecdcommands++; 08315 strncpy(myrpt->lastdtmfcommand, myrpt->dtmfbuf, MAXDTMF-1); 08316 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 08317 myrpt->dtmfbuf[0] = 0; 08318 myrpt->dtmfidx = -1; 08319 myrpt->dtmf_time_rem = 0; 08320 break; 08321 08322 case DC_ERROR: 08323 default: 08324 myrpt->dtmfbuf[0] = 0; 08325 myrpt->dtmfidx = -1; 08326 myrpt->dtmf_time_rem = 0; 08327 res = 0; 08328 break; 08329 } 08330 08331 return res; 08332 }
static int handle_remote_phone_dtmf | ( | struct rpt * | myrpt, | |
char | c, | |||
char * | keyed, | |||
int | phonemode | |||
) | [static] |
Definition at line 8383 of file app_rpt.c.
References rpt::archivedir, COMPLETE, DC_INDETERMINATE, donodelog(), rpt::endchar, handle_remote_dtmf_digit(), rpt::p, and rpt_telemetry().
Referenced by rpt_exec().
08384 { 08385 int res; 08386 08387 08388 if (keyed && *keyed && (c == myrpt->p.endchar)) 08389 { 08390 *keyed = 0; 08391 return DC_INDETERMINATE; 08392 } 08393 08394 if (myrpt->p.archivedir) 08395 { 08396 char str[100]; 08397 08398 sprintf(str,"DTMF(P),%c",c); 08399 donodelog(myrpt,str); 08400 } 08401 res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode); 08402 if (res != 1) 08403 return res; 08404 rpt_telemetry(myrpt,COMPLETE,NULL); 08405 return 0; 08406 }
static int ic706_pltocode | ( | char * | str | ) | [static] |
Definition at line 6879 of file app_rpt.c.
References s.
Referenced by set_ic706().
06880 { 06881 int i; 06882 char *s; 06883 06884 s = strchr(str,'.'); 06885 i = 0; 06886 if (s) i = atoi(s + 1); 06887 i += atoi(str) * 10; 06888 switch(i) 06889 { 06890 case 670: 06891 return 0; 06892 case 693: 06893 return 1; 06894 case 719: 06895 return 2; 06896 case 744: 06897 return 3; 06898 case 770: 06899 return 4; 06900 case 797: 06901 return 5; 06902 case 825: 06903 return 6; 06904 case 854: 06905 return 7; 06906 case 885: 06907 return 8; 06908 case 915: 06909 return 9; 06910 case 948: 06911 return 10; 06912 case 974: 06913 return 11; 06914 case 1000: 06915 return 12; 06916 case 1035: 06917 return 13; 06918 case 1072: 06919 return 14; 06920 case 1109: 06921 return 15; 06922 case 1148: 06923 return 16; 06924 case 1188: 06925 return 17; 06926 case 1230: 06927 return 18; 06928 case 1273: 06929 return 19; 06930 case 1318: 06931 return 20; 06932 case 1365: 06933 return 21; 06934 case 1413: 06935 return 22; 06936 case 1462: 06937 return 23; 06938 case 1514: 06939 return 24; 06940 case 1567: 06941 return 25; 06942 case 1598: 06943 return 26; 06944 case 1622: 06945 return 27; 06946 case 1655: 06947 return 28; 06948 case 1679: 06949 return 29; 06950 case 1713: 06951 return 30; 06952 case 1738: 06953 return 31; 06954 case 1773: 06955 return 32; 06956 case 1799: 06957 return 33; 06958 case 1835: 06959 return 34; 06960 case 1862: 06961 return 35; 06962 case 1899: 06963 return 36; 06964 case 1928: 06965 return 37; 06966 case 1966: 06967 return 38; 06968 case 1995: 06969 return 39; 06970 case 2035: 06971 return 40; 06972 case 2065: 06973 return 41; 06974 case 2107: 06975 return 42; 06976 case 2181: 06977 return 43; 06978 case 2257: 06979 return 44; 06980 case 2291: 06981 return 45; 06982 case 2336: 06983 return 46; 06984 case 2418: 06985 return 47; 06986 case 2503: 06987 return 48; 06988 case 2541: 06989 return 49; 06990 } 06991 return -1; 06992 }
static int kenwood_pltocode | ( | char * | str | ) | [static] |
Definition at line 5992 of file app_rpt.c.
References s.
Referenced by setkenwood().
05993 { 05994 int i; 05995 char *s; 05996 05997 s = strchr(str,'.'); 05998 i = 0; 05999 if (s) i = atoi(s + 1); 06000 i += atoi(str) * 10; 06001 switch(i) 06002 { 06003 case 670: 06004 return 1; 06005 case 719: 06006 return 3; 06007 case 744: 06008 return 4; 06009 case 770: 06010 return 5; 06011 case 797: 06012 return 6; 06013 case 825: 06014 return 7; 06015 case 854: 06016 return 8; 06017 case 885: 06018 return 9; 06019 case 915: 06020 return 10; 06021 case 948: 06022 return 11; 06023 case 974: 06024 return 12; 06025 case 1000: 06026 return 13; 06027 case 1035: 06028 return 14; 06029 case 1072: 06030 return 15; 06031 case 1109: 06032 return 16; 06033 case 1148: 06034 return 17; 06035 case 1188: 06036 return 18; 06037 case 1230: 06038 return 19; 06039 case 1273: 06040 return 20; 06041 case 1318: 06042 return 21; 06043 case 1365: 06044 return 22; 06045 case 1413: 06046 return 23; 06047 case 1462: 06048 return 24; 06049 case 1514: 06050 return 25; 06051 case 1567: 06052 return 26; 06053 case 1622: 06054 return 27; 06055 case 1679: 06056 return 28; 06057 case 1738: 06058 return 29; 06059 case 1799: 06060 return 30; 06061 case 1862: 06062 return 31; 06063 case 1928: 06064 return 32; 06065 case 2035: 06066 return 33; 06067 case 2107: 06068 return 34; 06069 case 2181: 06070 return 35; 06071 case 2257: 06072 return 36; 06073 case 2336: 06074 return 37; 06075 case 2418: 06076 return 38; 06077 case 2503: 06078 return 39; 06079 } 06080 return -1; 06081 }
static int load_module | ( | void | ) | [static] |
Definition at line 11875 of file app_rpt.c.
References ast_cli_register(), ast_pthread_create, ast_register_application(), rpt_exec(), and rpt_master().
11877 { 11878 ast_pthread_create(&rpt_master_thread,NULL,rpt_master,NULL); 11879 11880 /* Register cli extensions */ 11881 ast_cli_register(&cli_debug); 11882 ast_cli_register(&cli_dump); 11883 ast_cli_register(&cli_stats); 11884 ast_cli_register(&cli_lstats); 11885 ast_cli_register(&cli_nodes); 11886 ast_cli_register(&cli_reload); 11887 ast_cli_register(&cli_restart); 11888 ast_cli_register(&cli_fun); 11889 11890 return ast_register_application(app, rpt_exec, synopsis, descrip); 11891 }
static void load_rpt_vars | ( | int | n, | |
int | init | |||
) | [static] |
Definition at line 1622 of file app_rpt.c.
References rpt::acctcode, sysstate::alternatetail, rpt::althangtime, rpt::archivedir, ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), rpt::authlevel, sysstate::autopatchdisable, rpt::cfg, rpt::civaddr, rpt::csstanzaname, DEFAULT_CIV_ADDR, DEFAULT_IOBASE, DEFAULT_MONITOR_MIN_DISK_BLOCKS, DEFAULT_REMOTE_INACT_TIMEOUT, DEFAULT_REMOTE_TIMEOUT, DEFAULT_REMOTE_TIMEOUT_WARNING, DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ, desc, rpt::dphone_functions, rpt::dphone_longestfunc, rpt::duplex, ENDCHAR, rpt::endchar, rpt_xlat::endcharseq, rpt::extnodefile, EXTNODEFILE, rpt::extnodes, EXTNODES, finddelim(), FUNCCHAR, rpt::funcchar, rpt_xlat::funccharseq, rpt::functions, FUNCTIONS, HANGTIME, rpt::hangtime, rpt::ident, IDTIME, rpt::idtime, rpt::inxlat, rpt::iobase, rpt::ioport, rpt::link_functions, rpt::link_longestfunc, sysstate::linkfundisable, rpt::linktolink, lock, LOG_NOTICE, LOG_WARNING, rpt::longestfunc, rpt::longestnode, rpt::macro, MACRO, rpt::macro_longest, MAX_SYSSTATES, MAXXLAT, rpt::memory, MEMORY, rpt::monminblocks, ast_variable::name, rpt::name, name, ast_variable::next, rpt_tele::next, rpt::nobusyout, rpt::nodes, NODES, rpt::notelemtx, option_verbose, rpt::ourcallerid, rpt::ourcontext, rpt::outxlat, rpt::p, rpt_xlat::passchars, rpt::phone_functions, rpt::phone_longestfunc, POLITEID, rpt::politeid, rpt_tele::prev, rpt::propagate_dtmf, rpt::propagate_phonedtmf, rpt::remoteinacttimeout, rpt::remotetimeout, rpt::remotetimeoutwarning, rpt::remotetimeoutwarningfreq, retrieve_astcfgint(), rpt::rpt_thread, rpt_vars, rpt::s, sysstate::schedulerdisable, rpt::simple, rpt::skedstanzaname, rpt::startupmacro, rpt::tailmessagemax, rpt::tailmessagen, rpt::tailmessages, rpt::tailmessagetime, rpt::tailsquashedtime, rpt::tele, rpt::tonezone, sysstate::totdisable, TOTIME, rpt::totime, sysstate::txdisable, rpt::txlimitsstanzaname, sysstate::userfundisable, ast_variable::value, and VERBOSE_PREFIX_3.
Referenced by rpt(), rpt_exec(), and rpt_master().
01623 { 01624 char *this,*val; 01625 int i,j,longestnode; 01626 struct ast_variable *vp; 01627 struct ast_config *cfg; 01628 char *strs[100]; 01629 char s1[256]; 01630 static char *cs_keywords[] = {"rptena","rptdis","apena","apdis","lnkena","lnkdis","totena","totdis","skena","skdis", 01631 "ufena","ufdis","atena","atdis",NULL}; 01632 01633 if (option_verbose > 2) 01634 ast_verbose(VERBOSE_PREFIX_3 "%s config for repeater %s\n", 01635 (init) ? "Loading initial" : "Re-Loading",rpt_vars[n].name); 01636 ast_mutex_lock(&rpt_vars[n].lock); 01637 if (rpt_vars[n].cfg) ast_config_destroy(rpt_vars[n].cfg); 01638 cfg = ast_config_load("rpt.conf"); 01639 if (!cfg) { 01640 ast_mutex_unlock(&rpt_vars[n].lock); 01641 ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); 01642 pthread_exit(NULL); 01643 } 01644 rpt_vars[n].cfg = cfg; 01645 this = rpt_vars[n].name; 01646 memset(&rpt_vars[n].p,0,sizeof(rpt_vars[n].p)); 01647 if (init) 01648 { 01649 char *cp; 01650 int savearea = (char *)&rpt_vars[n].p - (char *)&rpt_vars[n]; 01651 01652 cp = (char *) &rpt_vars[n].p; 01653 memset(cp + sizeof(rpt_vars[n].p),0, 01654 sizeof(rpt_vars[n]) - (sizeof(rpt_vars[n].p) + savearea)); 01655 rpt_vars[n].tele.next = &rpt_vars[n].tele; 01656 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 01657 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 01658 rpt_vars[n].tailmessagen = 0; 01659 } 01660 #ifdef __RPT_NOTCH 01661 /* zot out filters stuff */ 01662 memset(&rpt_vars[n].filters,0,sizeof(rpt_vars[n].filters)); 01663 #endif 01664 val = (char *) ast_variable_retrieve(cfg,this,"context"); 01665 if (val) rpt_vars[n].p.ourcontext = val; 01666 else rpt_vars[n].p.ourcontext = this; 01667 val = (char *) ast_variable_retrieve(cfg,this,"callerid"); 01668 if (val) rpt_vars[n].p.ourcallerid = val; 01669 val = (char *) ast_variable_retrieve(cfg,this,"accountcode"); 01670 if (val) rpt_vars[n].p.acctcode = val; 01671 val = (char *) ast_variable_retrieve(cfg,this,"idrecording"); 01672 if (val) rpt_vars[n].p.ident = val; 01673 val = (char *) ast_variable_retrieve(cfg,this,"hangtime"); 01674 if (val) rpt_vars[n].p.hangtime = atoi(val); 01675 else rpt_vars[n].p.hangtime = HANGTIME; 01676 val = (char *) ast_variable_retrieve(cfg,this,"althangtime"); 01677 if (val) rpt_vars[n].p.althangtime = atoi(val); 01678 else rpt_vars[n].p.althangtime = HANGTIME; 01679 val = (char *) ast_variable_retrieve(cfg,this,"totime"); 01680 if (val) rpt_vars[n].p.totime = atoi(val); 01681 else rpt_vars[n].p.totime = TOTIME; 01682 rpt_vars[n].p.tailmessagetime = retrieve_astcfgint(&rpt_vars[n],this, "tailmessagetime", 0, 2400000, 0); 01683 rpt_vars[n].p.tailsquashedtime = retrieve_astcfgint(&rpt_vars[n],this, "tailsquashedtime", 0, 2400000, 0); 01684 rpt_vars[n].p.duplex = retrieve_astcfgint(&rpt_vars[n],this,"duplex",0,4,2); 01685 rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", -60000, 2400000, IDTIME); /* Enforce a min max including zero */ 01686 rpt_vars[n].p.politeid = retrieve_astcfgint(&rpt_vars[n],this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */ 01687 val = (char *) ast_variable_retrieve(cfg,this,"tonezone"); 01688 if (val) rpt_vars[n].p.tonezone = val; 01689 rpt_vars[n].p.tailmessages[0] = 0; 01690 rpt_vars[n].p.tailmessagemax = 0; 01691 val = (char *) ast_variable_retrieve(cfg,this,"tailmessagelist"); 01692 if (val) rpt_vars[n].p.tailmessagemax = finddelim(val, rpt_vars[n].p.tailmessages, 500); 01693 val = (char *) ast_variable_retrieve(cfg,this,"memory"); 01694 if (!val) val = MEMORY; 01695 rpt_vars[n].p.memory = val; 01696 val = (char *) ast_variable_retrieve(cfg,this,"macro"); 01697 if (!val) val = MACRO; 01698 rpt_vars[n].p.macro = val; 01699 val = (char *) ast_variable_retrieve(cfg,this,"startup_macro"); 01700 if (val) rpt_vars[n].p.startupmacro = val; 01701 val = (char *) ast_variable_retrieve(cfg,this,"iobase"); 01702 /* do not use atoi() here, we need to be able to have 01703 the input specified in hex or decimal so we use 01704 sscanf with a %i */ 01705 if ((!val) || (sscanf(val,"%i",&rpt_vars[n].p.iobase) != 1)) 01706 rpt_vars[n].p.iobase = DEFAULT_IOBASE; 01707 val = (char *) ast_variable_retrieve(cfg,this,"ioport"); 01708 rpt_vars[n].p.ioport = val; 01709 val = (char *) ast_variable_retrieve(cfg,this,"functions"); 01710 if (!val) 01711 { 01712 val = FUNCTIONS; 01713 rpt_vars[n].p.simple = 1; 01714 } 01715 rpt_vars[n].p.functions = val; 01716 val = (char *) ast_variable_retrieve(cfg,this,"link_functions"); 01717 if (val) rpt_vars[n].p.link_functions = val; 01718 else 01719 rpt_vars[n].p.link_functions = rpt_vars[n].p.functions; 01720 val = (char *) ast_variable_retrieve(cfg,this,"phone_functions"); 01721 if (val) rpt_vars[n].p.phone_functions = val; 01722 val = (char *) ast_variable_retrieve(cfg,this,"dphone_functions"); 01723 if (val) rpt_vars[n].p.dphone_functions = val; 01724 val = (char *) ast_variable_retrieve(cfg,this,"funcchar"); 01725 if (!val) rpt_vars[n].p.funcchar = FUNCCHAR; else 01726 rpt_vars[n].p.funcchar = *val; 01727 val = (char *) ast_variable_retrieve(cfg,this,"endchar"); 01728 if (!val) rpt_vars[n].p.endchar = ENDCHAR; else 01729 rpt_vars[n].p.endchar = *val; 01730 val = (char *) ast_variable_retrieve(cfg,this,"nobusyout"); 01731 if (val) rpt_vars[n].p.nobusyout = ast_true(val); 01732 val = (char *) ast_variable_retrieve(cfg,this,"notelemtx"); 01733 if (val) rpt_vars[n].p.notelemtx = ast_true(val); 01734 val = (char *) ast_variable_retrieve(cfg,this,"propagate_dtmf"); 01735 if (val) rpt_vars[n].p.propagate_dtmf = ast_true(val); 01736 val = (char *) ast_variable_retrieve(cfg,this,"propagate_phonedtmf"); 01737 if (val) rpt_vars[n].p.propagate_phonedtmf = ast_true(val); 01738 val = (char *) ast_variable_retrieve(cfg,this,"linktolink"); 01739 if (val) rpt_vars[n].p.linktolink = ast_true(val); 01740 val = (char *) ast_variable_retrieve(cfg,this,"nodes"); 01741 if (!val) val = NODES; 01742 rpt_vars[n].p.nodes = val; 01743 val = (char *) ast_variable_retrieve(cfg,this,"extnodes"); 01744 if (!val) val = EXTNODES; 01745 rpt_vars[n].p.extnodes = val; 01746 val = (char *) ast_variable_retrieve(cfg,this,"extnodefile"); 01747 if (!val) val = EXTNODEFILE; 01748 rpt_vars[n].p.extnodefile = val; 01749 val = (char *) ast_variable_retrieve(cfg,this,"archivedir"); 01750 if (val) rpt_vars[n].p.archivedir = val; 01751 val = (char *) ast_variable_retrieve(cfg,this,"authlevel"); 01752 if (val) rpt_vars[n].p.authlevel = atoi(val); 01753 else rpt_vars[n].p.authlevel = 0; 01754 val = (char *) ast_variable_retrieve(cfg,this,"monminblocks"); 01755 if (val) rpt_vars[n].p.monminblocks = atol(val); 01756 else rpt_vars[n].p.monminblocks = DEFAULT_MONITOR_MIN_DISK_BLOCKS; 01757 val = (char *) ast_variable_retrieve(cfg,this,"remote_inact_timeout"); 01758 if (val) rpt_vars[n].p.remoteinacttimeout = atoi(val); 01759 else rpt_vars[n].p.remoteinacttimeout = DEFAULT_REMOTE_INACT_TIMEOUT; 01760 val = (char *) ast_variable_retrieve(cfg,this,"civaddr"); 01761 if (val) rpt_vars[n].p.civaddr = atoi(val); 01762 else rpt_vars[n].p.civaddr = DEFAULT_CIV_ADDR; 01763 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout"); 01764 if (val) rpt_vars[n].p.remotetimeout = atoi(val); 01765 else rpt_vars[n].p.remotetimeout = DEFAULT_REMOTE_TIMEOUT; 01766 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning"); 01767 if (val) rpt_vars[n].p.remotetimeoutwarning = atoi(val); 01768 else rpt_vars[n].p.remotetimeoutwarning = DEFAULT_REMOTE_TIMEOUT_WARNING; 01769 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning_freq"); 01770 if (val) rpt_vars[n].p.remotetimeoutwarningfreq = atoi(val); 01771 else rpt_vars[n].p.remotetimeoutwarningfreq = DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ; 01772 #ifdef __RPT_NOTCH 01773 val = (char *) ast_variable_retrieve(cfg,this,"rxnotch"); 01774 if (val) { 01775 i = finddelim(val,strs,MAXFILTERS * 2); 01776 i &= ~1; /* force an even number, rounded down */ 01777 if (i >= 2) for(j = 0; j < i; j += 2) 01778 { 01779 rpt_mknotch(atof(strs[j]),atof(strs[j + 1]), 01780 &rpt_vars[n].filters[j >> 1].gain, 01781 &rpt_vars[n].filters[j >> 1].const0, 01782 &rpt_vars[n].filters[j >> 1].const1, 01783 &rpt_vars[n].filters[j >> 1].const2); 01784 sprintf(rpt_vars[n].filters[j >> 1].desc,"%s Hz, BW = %s", 01785 strs[j],strs[j + 1]); 01786 } 01787 01788 } 01789 #endif 01790 val = (char *) ast_variable_retrieve(cfg,this,"inxlat"); 01791 if (val) { 01792 memset(&rpt_vars[n].p.inxlat,0,sizeof(struct rpt_xlat)); 01793 i = finddelim(val,strs,3); 01794 if (i) strncpy(rpt_vars[n].p.inxlat.funccharseq,strs[0],MAXXLAT - 1); 01795 if (i > 1) strncpy(rpt_vars[n].p.inxlat.endcharseq,strs[1],MAXXLAT - 1); 01796 if (i > 2) strncpy(rpt_vars[n].p.inxlat.passchars,strs[2],MAXXLAT - 1); 01797 } 01798 val = (char *) ast_variable_retrieve(cfg,this,"outxlat"); 01799 if (val) { 01800 memset(&rpt_vars[n].p.outxlat,0,sizeof(struct rpt_xlat)); 01801 i = finddelim(val,strs,3); 01802 if (i) strncpy(rpt_vars[n].p.outxlat.funccharseq,strs[0],MAXXLAT - 1); 01803 if (i > 1) strncpy(rpt_vars[n].p.outxlat.endcharseq,strs[1],MAXXLAT - 1); 01804 if (i > 2) strncpy(rpt_vars[n].p.outxlat.passchars,strs[2],MAXXLAT - 1); 01805 } 01806 /* retreive the stanza name for the control states if there is one */ 01807 val = (char *) ast_variable_retrieve(cfg,this,"controlstates"); 01808 rpt_vars[n].p.csstanzaname = val; 01809 01810 /* retreive the stanza name for the scheduler if there is one */ 01811 val = (char *) ast_variable_retrieve(cfg,this,"scheduler"); 01812 rpt_vars[n].p.skedstanzaname = val; 01813 01814 /* retreive the stanza name for the txlimits */ 01815 val = (char *) ast_variable_retrieve(cfg,this,"txlimits"); 01816 rpt_vars[n].p.txlimitsstanzaname = val; 01817 01818 longestnode = 0; 01819 01820 vp = ast_variable_browse(cfg, rpt_vars[n].p.nodes); 01821 01822 while(vp){ 01823 j = strlen(vp->name); 01824 if (j > longestnode) 01825 longestnode = j; 01826 vp = vp->next; 01827 } 01828 01829 rpt_vars[n].longestnode = longestnode; 01830 01831 /* 01832 * For this repeater, Determine the length of the longest function 01833 */ 01834 rpt_vars[n].longestfunc = 0; 01835 vp = ast_variable_browse(cfg, rpt_vars[n].p.functions); 01836 while(vp){ 01837 j = strlen(vp->name); 01838 if (j > rpt_vars[n].longestfunc) 01839 rpt_vars[n].longestfunc = j; 01840 vp = vp->next; 01841 } 01842 /* 01843 * For this repeater, Determine the length of the longest function 01844 */ 01845 rpt_vars[n].link_longestfunc = 0; 01846 vp = ast_variable_browse(cfg, rpt_vars[n].p.link_functions); 01847 while(vp){ 01848 j = strlen(vp->name); 01849 if (j > rpt_vars[n].link_longestfunc) 01850 rpt_vars[n].link_longestfunc = j; 01851 vp = vp->next; 01852 } 01853 rpt_vars[n].phone_longestfunc = 0; 01854 if (rpt_vars[n].p.phone_functions) 01855 { 01856 vp = ast_variable_browse(cfg, rpt_vars[n].p.phone_functions); 01857 while(vp){ 01858 j = strlen(vp->name); 01859 if (j > rpt_vars[n].phone_longestfunc) 01860 rpt_vars[n].phone_longestfunc = j; 01861 vp = vp->next; 01862 } 01863 } 01864 rpt_vars[n].dphone_longestfunc = 0; 01865 if (rpt_vars[n].p.dphone_functions) 01866 { 01867 vp = ast_variable_browse(cfg, rpt_vars[n].p.dphone_functions); 01868 while(vp){ 01869 j = strlen(vp->name); 01870 if (j > rpt_vars[n].dphone_longestfunc) 01871 rpt_vars[n].dphone_longestfunc = j; 01872 vp = vp->next; 01873 } 01874 } 01875 rpt_vars[n].macro_longest = 1; 01876 vp = ast_variable_browse(cfg, rpt_vars[n].p.macro); 01877 while(vp){ 01878 j = strlen(vp->name); 01879 if (j > rpt_vars[n].macro_longest) 01880 rpt_vars[n].macro_longest = j; 01881 vp = vp->next; 01882 } 01883 01884 /* Browse for control states */ 01885 if(rpt_vars[n].p.csstanzaname) 01886 vp = ast_variable_browse(cfg, rpt_vars[n].p.csstanzaname); 01887 else 01888 vp = NULL; 01889 for( i = 0 ; vp && (i < MAX_SYSSTATES) ; i++){ /* Iterate over the number of control state lines in the stanza */ 01890 int k,nukw,statenum; 01891 statenum=atoi(vp->name); 01892 strncpy(s1, vp->value, 255); 01893 s1[255] = 0; 01894 nukw = finddelim(s1,strs,32); 01895 01896 for (k = 0 ; k < nukw ; k++){ /* for each user specified keyword */ 01897 for(j = 0 ; cs_keywords[j] != NULL ; j++){ /* try to match to one in our internal table */ 01898 if(!strcmp(strs[k],cs_keywords[j])){ 01899 switch(j){ 01900 case 0: /* rptena */ 01901 rpt_vars[n].p.s[statenum].txdisable = 0; 01902 break; 01903 case 1: /* rptdis */ 01904 rpt_vars[n].p.s[statenum].txdisable = 1; 01905 break; 01906 01907 case 2: /* apena */ 01908 rpt_vars[n].p.s[statenum].autopatchdisable = 0; 01909 break; 01910 01911 case 3: /* apdis */ 01912 rpt_vars[n].p.s[statenum].autopatchdisable = 1; 01913 break; 01914 01915 case 4: /* lnkena */ 01916 rpt_vars[n].p.s[statenum].linkfundisable = 0; 01917 break; 01918 01919 case 5: /* lnkdis */ 01920 rpt_vars[n].p.s[statenum].linkfundisable = 1; 01921 break; 01922 01923 case 6: /* totena */ 01924 rpt_vars[n].p.s[statenum].totdisable = 0; 01925 break; 01926 01927 case 7: /* totdis */ 01928 rpt_vars[n].p.s[statenum].totdisable = 1; 01929 break; 01930 01931 case 8: /* skena */ 01932 rpt_vars[n].p.s[statenum].schedulerdisable = 0; 01933 break; 01934 01935 case 9: /* skdis */ 01936 rpt_vars[n].p.s[statenum].schedulerdisable = 1; 01937 break; 01938 01939 case 10: /* ufena */ 01940 rpt_vars[n].p.s[statenum].userfundisable = 0; 01941 break; 01942 01943 case 11: /* ufdis */ 01944 rpt_vars[n].p.s[statenum].userfundisable = 1; 01945 break; 01946 01947 case 12: /* atena */ 01948 rpt_vars[n].p.s[statenum].alternatetail = 1; 01949 break; 01950 01951 case 13: /* atdis */ 01952 rpt_vars[n].p.s[statenum].alternatetail = 0; 01953 break; 01954 01955 default: 01956 ast_log(LOG_WARNING, 01957 "Unhandled control state keyword %s", cs_keywords[i]); 01958 break; 01959 } 01960 } 01961 } 01962 } 01963 vp = vp->next; 01964 } 01965 ast_mutex_unlock(&rpt_vars[n].lock); 01966 }
static void local_dtmf_helper | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 8470 of file app_rpt.c.
References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), ast_pthread_create, rpt::callmode, rpt::cidx, rpt::cmdnode, collect_function_digits(), COMPLETE, rpt::dailyexecdcommands, DC_COMPLETE, DC_COMPLETEQUIET, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, do_dtmf_phone(), donodelog(), rpt::dtmf_time, rpt::dtmfbuf, rpt::dtmfidx, rpt::endchar, rpt::exten, rpt::funcchar, rpt::lastdtmfcommand, rpt::lock, MAXDTMF, MAXPATCHCONTEXT, rpt::mydtmf, rpt::ourcontext, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchnoct, rpt::patchquiet, rpt::pchannel, PROC, rpt::propagate_phonedtmf, rpt_call(), rpt::rpt_call_thread, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), send_link_dtmf(), rpt::simple, SOURCE_RPT, rpt::stopgen, TERM, and rpt::totalexecdcommands.
Referenced by rpt().
08471 { 08472 int res; 08473 pthread_attr_t attr; 08474 char cmd[MAXDTMF+1] = ""; 08475 08476 if (myrpt->p.archivedir) 08477 { 08478 char str[100]; 08479 08480 sprintf(str,"DTMF,MAIN,%c",c); 08481 donodelog(myrpt,str); 08482 } 08483 if (c == myrpt->p.endchar) 08484 { 08485 /* if in simple mode, kill autopatch */ 08486 if (myrpt->p.simple && myrpt->callmode) 08487 { 08488 rpt_mutex_lock(&myrpt->lock); 08489 myrpt->callmode = 0; 08490 rpt_mutex_unlock(&myrpt->lock); 08491 rpt_telemetry(myrpt,TERM,NULL); 08492 return; 08493 } 08494 rpt_mutex_lock(&myrpt->lock); 08495 myrpt->stopgen = 1; 08496 if (myrpt->cmdnode[0]) 08497 { 08498 myrpt->cmdnode[0] = 0; 08499 myrpt->dtmfidx = -1; 08500 myrpt->dtmfbuf[0] = 0; 08501 rpt_mutex_unlock(&myrpt->lock); 08502 rpt_telemetry(myrpt,COMPLETE,NULL); 08503 } 08504 else 08505 { 08506 rpt_mutex_unlock(&myrpt->lock); 08507 if (myrpt->p.propagate_phonedtmf) 08508 do_dtmf_phone(myrpt,NULL,c); 08509 } 08510 return; 08511 } 08512 rpt_mutex_lock(&myrpt->lock); 08513 if (myrpt->cmdnode[0]) 08514 { 08515 rpt_mutex_unlock(&myrpt->lock); 08516 send_link_dtmf(myrpt,c); 08517 return; 08518 } 08519 if (!myrpt->p.simple) 08520 { 08521 if (c == myrpt->p.funcchar) 08522 { 08523 myrpt->dtmfidx = 0; 08524 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08525 rpt_mutex_unlock(&myrpt->lock); 08526 time(&myrpt->dtmf_time); 08527 return; 08528 } 08529 else if ((c != myrpt->p.endchar) && (myrpt->dtmfidx >= 0)) 08530 { 08531 time(&myrpt->dtmf_time); 08532 08533 if (myrpt->dtmfidx < MAXDTMF) 08534 { 08535 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 08536 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08537 08538 strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1); 08539 08540 rpt_mutex_unlock(&myrpt->lock); 08541 res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL); 08542 rpt_mutex_lock(&myrpt->lock); 08543 switch(res){ 08544 case DC_INDETERMINATE: 08545 break; 08546 case DC_REQ_FLUSH: 08547 myrpt->dtmfidx = 0; 08548 myrpt->dtmfbuf[0] = 0; 08549 break; 08550 case DC_COMPLETE: 08551 case DC_COMPLETEQUIET: 08552 myrpt->totalexecdcommands++; 08553 myrpt->dailyexecdcommands++; 08554 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 08555 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 08556 myrpt->dtmfbuf[0] = 0; 08557 myrpt->dtmfidx = -1; 08558 myrpt->dtmf_time = 0; 08559 break; 08560 08561 case DC_ERROR: 08562 default: 08563 myrpt->dtmfbuf[0] = 0; 08564 myrpt->dtmfidx = -1; 08565 myrpt->dtmf_time = 0; 08566 break; 08567 } 08568 if(res != DC_INDETERMINATE) { 08569 rpt_mutex_unlock(&myrpt->lock); 08570 return; 08571 } 08572 } 08573 } 08574 } 08575 else /* if simple */ 08576 { 08577 if ((!myrpt->callmode) && (c == myrpt->p.funcchar)) 08578 { 08579 myrpt->callmode = 1; 08580 myrpt->patchnoct = 0; 08581 myrpt->patchquiet = 0; 08582 myrpt->patchfarenddisconnect = 0; 08583 myrpt->patchdialtime = 0; 08584 strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT); 08585 myrpt->cidx = 0; 08586 myrpt->exten[myrpt->cidx] = 0; 08587 rpt_mutex_unlock(&myrpt->lock); 08588 pthread_attr_init(&attr); 08589 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08590 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt); 08591 return; 08592 } 08593 } 08594 if (myrpt->callmode == 1) 08595 { 08596 myrpt->exten[myrpt->cidx++] = c; 08597 myrpt->exten[myrpt->cidx] = 0; 08598 /* if this exists */ 08599 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 08600 { 08601 myrpt->callmode = 2; 08602 rpt_mutex_unlock(&myrpt->lock); 08603 if(!myrpt->patchquiet) 08604 rpt_telemetry(myrpt,PROC,NULL); 08605 return; 08606 } 08607 /* if can continue, do so */ 08608 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 08609 { 08610 /* call has failed, inform user */ 08611 myrpt->callmode = 4; 08612 } 08613 rpt_mutex_unlock(&myrpt->lock); 08614 return; 08615 } 08616 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 08617 { 08618 myrpt->mydtmf = c; 08619 } 08620 rpt_mutex_unlock(&myrpt->lock); 08621 if ((myrpt->dtmfidx < 0) && myrpt->p.propagate_phonedtmf) 08622 do_dtmf_phone(myrpt,NULL,c); 08623 return; 08624 }
static int matchkeyword | ( | char * | string, | |
char ** | param, | |||
char * | keywords[] | |||
) | [static] |
Definition at line 1478 of file app_rpt.c.
Referenced by function_autopatchup().
01479 { 01480 int i,ls; 01481 for( i = 0 ; keywords[i] ; i++){ 01482 ls = strlen(keywords[i]); 01483 if(!ls){ 01484 *param = NULL; 01485 return 0; 01486 } 01487 if(!strncmp(string, keywords[i], ls)){ 01488 if(param) 01489 *param = string + ls; 01490 return i + 1; 01491 } 01492 } 01493 param = NULL; 01494 return 0; 01495 }
static void mdc1200_notify | ( | struct rpt * | myrpt, | |
char * | fromnode, | |||
unsigned int | unit | |||
) | [static] |
Definition at line 1192 of file app_rpt.c.
References ast_verbose(), and rpt::name.
Referenced by function_ilink(), handle_link_data(), handle_remote_data(), and rpt().
01193 { 01194 if (!fromnode) 01195 { 01196 ast_verbose("Got MDC-1200 ID %04X from local system (%s)\n", 01197 unit,myrpt->name); 01198 } 01199 else 01200 { 01201 ast_verbose("Got MDC-1200 ID %04X from node %s (%s)\n", 01202 unit,fromnode,myrpt->name); 01203 } 01204 }
static int mem2vfo_ic706 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7193 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07194 { 07195 unsigned char cmdstr[10]; 07196 07197 cmdstr[0] = cmdstr[1] = 0xfe; 07198 cmdstr[2] = myrpt->p.civaddr; 07199 cmdstr[3] = 0xe0; 07200 cmdstr[4] = 0x0a; 07201 cmdstr[5] = 0xfd; 07202 07203 return(civ_cmd(myrpt,cmdstr,6)); 07204 }
static int multimode_bump_freq | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 7556 of file app_rpt.c.
References multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), and rpt::remote.
Referenced by function_remote(), and service_scan().
07557 { 07558 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07559 return multimode_bump_freq_ft897(myrpt, interval); 07560 else if(!strcmp(myrpt->remote, remote_rig_ic706)) 07561 return multimode_bump_freq_ic706(myrpt, interval); 07562 else 07563 return -1; 07564 }
static int multimode_bump_freq_ft897 | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 6745 of file app_rpt.c.
References check_freq_ft897(), rpt::freq, MAXREMSTR, set_freq_ft897(), and split_freq().
Referenced by multimode_bump_freq().
06746 { 06747 int m,d; 06748 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 06749 06750 if(debug) 06751 printf("Before bump: %s\n", myrpt->freq); 06752 06753 if(split_freq(mhz, decimals, myrpt->freq)) 06754 return -1; 06755 06756 m = atoi(mhz); 06757 d = atoi(decimals); 06758 06759 d += (interval / 10); /* 10Hz resolution */ 06760 if(d < 0){ 06761 m--; 06762 d += 100000; 06763 } 06764 else if(d >= 100000){ 06765 m++; 06766 d -= 100000; 06767 } 06768 06769 if(check_freq_ft897(m, d, NULL)){ 06770 if(debug) 06771 printf("Bump freq invalid\n"); 06772 return -1; 06773 } 06774 06775 snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d); 06776 06777 if(debug) 06778 printf("After bump: %s\n", myrpt->freq); 06779 06780 return set_freq_ft897(myrpt, myrpt->freq); 06781 }
static int multimode_bump_freq_ic706 | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 7289 of file app_rpt.c.
References check_freq_ic706(), rpt::civaddr, rpt::freq, MAXREMSTR, rpt::p, serial_remote_io(), and split_freq().
Referenced by multimode_bump_freq().
07290 { 07291 int m,d; 07292 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07293 unsigned char cmdstr[20]; 07294 07295 if(debug) 07296 printf("Before bump: %s\n", myrpt->freq); 07297 07298 if(split_freq(mhz, decimals, myrpt->freq)) 07299 return -1; 07300 07301 m = atoi(mhz); 07302 d = atoi(decimals); 07303 07304 d += (interval / 10); /* 10Hz resolution */ 07305 if(d < 0){ 07306 m--; 07307 d += 100000; 07308 } 07309 else if(d >= 100000){ 07310 m++; 07311 d -= 100000; 07312 } 07313 07314 if(check_freq_ic706(m, d, NULL)){ 07315 if(debug) 07316 printf("Bump freq invalid\n"); 07317 return -1; 07318 } 07319 07320 snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d); 07321 07322 if(debug) 07323 printf("After bump: %s\n", myrpt->freq); 07324 07325 /* The ic-706 likes packed BCD frequencies */ 07326 07327 cmdstr[0] = cmdstr[1] = 0xfe; 07328 cmdstr[2] = myrpt->p.civaddr; 07329 cmdstr[3] = 0xe0; 07330 cmdstr[4] = 0; 07331 cmdstr[5] = ((d % 10) << 4); 07332 cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10); 07333 cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000); 07334 cmdstr[8] = (((m % 100)/10) << 4) + (m % 10); 07335 cmdstr[9] = (m / 100); 07336 cmdstr[10] = 0xfd; 07337 07338 return(serial_remote_io(myrpt,cmdstr,11,NULL,0,0)); 07339 }
static int multimode_capable | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 880 of file app_rpt.c.
References rpt::remote.
Referenced by function_remote(), and rpt_tele_thread().
00881 { 00882 if(!strcmp(myrpt->remote, remote_rig_ft897)) 00883 return 1; 00884 if(!strcmp(myrpt->remote, remote_rig_ic706)) 00885 return 1; 00886 return 0; 00887 }
static int myatoi | ( | char * | str | ) | [static] |
Definition at line 1520 of file app_rpt.c.
Referenced by function_cop(), function_ilink(), function_remote(), function_status(), retrieve_astcfgint(), and rpt_do_debug().
01521 { 01522 int ret; 01523 01524 if (str == NULL) return -1; 01525 /* leave this %i alone, non-base-10 input is useful here */ 01526 if (sscanf(str,"%i",&ret) != 1) return -1; 01527 return ret; 01528 }
static int mycompar | ( | const void * | a, | |
const void * | b | |||
) | [static] |
Definition at line 1530 of file app_rpt.c.
Referenced by rpt_do_nodes(), and rpt_tele_thread().
01531 { 01532 char **x = (char **) a; 01533 char **y = (char **) b; 01534 int xoff,yoff; 01535 01536 if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0; 01537 if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0; 01538 return(strcmp((*x) + xoff,(*y) + yoff)); 01539 }
static char* node_lookup | ( | struct rpt * | myrpt, | |
char * | digitbuf | |||
) | [static] |
Definition at line 1410 of file app_rpt.c.
References ast_config_destroy(), ast_config_load(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), ast_variable_retrieve(), rpt::cfg, rpt::extnodefile, rpt::extnodes, last, rpt::longestnode, ast_variable::name, ast_variable::next, rpt::nodes, and rpt::p.
Referenced by attempt_reconnect(), connect_link(), function_ilink(), and rpt_exec().
01411 { 01412 01413 char *val; 01414 int longestnode,j; 01415 struct stat mystat; 01416 static time_t last = 0; 01417 static struct ast_config *ourcfg = NULL; 01418 struct ast_variable *vp; 01419 01420 /* try to look it up locally first */ 01421 val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf); 01422 if (val) return(val); 01423 ast_mutex_lock(&nodelookuplock); 01424 /* if file does not exist */ 01425 if (stat(myrpt->p.extnodefile,&mystat) == -1) 01426 { 01427 if (ourcfg) ast_config_destroy(ourcfg); 01428 ourcfg = NULL; 01429 ast_mutex_unlock(&nodelookuplock); 01430 return(NULL); 01431 } 01432 /* if we need to reload */ 01433 if (mystat.st_mtime > last) 01434 { 01435 if (ourcfg) ast_config_destroy(ourcfg); 01436 ourcfg = ast_config_load(myrpt->p.extnodefile); 01437 /* if file not there, just bail */ 01438 if (!ourcfg) 01439 { 01440 ast_mutex_unlock(&nodelookuplock); 01441 return(NULL); 01442 } 01443 /* reset "last" time */ 01444 last = mystat.st_mtime; 01445 01446 /* determine longest node length again */ 01447 longestnode = 0; 01448 vp = ast_variable_browse(myrpt->cfg, myrpt->p.nodes); 01449 while(vp){ 01450 j = strlen(vp->name); 01451 if (j > longestnode) 01452 longestnode = j; 01453 vp = vp->next; 01454 } 01455 01456 vp = ast_variable_browse(ourcfg, myrpt->p.extnodes); 01457 while(vp){ 01458 j = strlen(vp->name); 01459 if (j > longestnode) 01460 longestnode = j; 01461 vp = vp->next; 01462 } 01463 01464 myrpt->longestnode = longestnode; 01465 } 01466 val = NULL; 01467 if (ourcfg) 01468 val = (char *) ast_variable_retrieve(ourcfg, myrpt->p.extnodes, digitbuf); 01469 ast_mutex_unlock(&nodelookuplock); 01470 return(val); 01471 }
static int openserial | ( | char * | fname | ) | [static] |
Definition at line 1156 of file app_rpt.c.
References ast_log(), ECHO, errno, LOG_WARNING, and MAX.
Referenced by rpt_exec().
01157 { 01158 struct termios mode; 01159 int fd; 01160 01161 fd = open(fname,O_RDWR); 01162 if (fd == -1) 01163 { 01164 ast_log(LOG_WARNING,"Cannot open serial port %s\n",fname); 01165 return -1; 01166 } 01167 memset(&mode, 0, sizeof(mode)); 01168 if (tcgetattr(fd, &mode)) { 01169 ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", fname, strerror(errno)); 01170 return -1; 01171 } 01172 #ifndef SOLARIS 01173 cfmakeraw(&mode); 01174 #else 01175 mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP 01176 |INLCR|IGNCR|ICRNL|IXON); 01177 mode.c_oflag &= ~OPOST; 01178 mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 01179 mode.c_cflag &= ~(CSIZE|PARENB|CRTSCTS); 01180 mode.c_cflag |= CS8; 01181 mode.c_cc[TIME] = 3; 01182 mode.c_cc[MAX] = 1; 01183 #endif 01184 01185 cfsetispeed(&mode, B9600); 01186 cfsetospeed(&mode, B9600); 01187 if (tcsetattr(fd, TCSANOW, &mode)) 01188 ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", fname, strerror(errno)); 01189 return(fd); 01190 }
static int play_silence | ( | struct ast_channel * | chan, | |
int | duration | |||
) | [static] |
Definition at line 2462 of file app_rpt.c.
References play_tone_pair().
Referenced by send_morse().
02463 { 02464 return play_tone_pair(chan, 0, 0, duration, 0); 02465 }
static int play_tone | ( | struct ast_channel * | chan, | |
int | freq, | |||
int | duration, | |||
int | amplitude | |||
) | [static] |
Definition at line 2457 of file app_rpt.c.
References play_tone_pair().
Referenced by rpt_tele_thread(), and send_morse().
02458 { 02459 return play_tone_pair(chan, freq, 0, duration, amplitude); 02460 }
static int play_tone_pair | ( | struct ast_channel * | chan, | |
int | f1, | |||
int | f2, | |||
int | duration, | |||
int | amplitude | |||
) | [static] |
Definition at line 2443 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().
02444 { 02445 int res; 02446 02447 if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude))) 02448 return res; 02449 02450 while(chan->generatordata) { 02451 if (ast_safe_sleep(chan,1)) return -1; 02452 } 02453 02454 return 0; 02455 }
static void queue_id | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 8629 of file app_rpt.c.
References ID, rpt::idtime, rpt::idtimer, rpt::lock, rpt::mustid, rpt::p, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), and rpt::tailid.
Referenced by rpt().
08630 { 08631 if(myrpt->p.idtime){ /* ID time must be non-zero */ 08632 myrpt->mustid = myrpt->tailid = 0; 08633 myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */ 08634 rpt_mutex_unlock(&myrpt->lock); 08635 rpt_telemetry(myrpt,ID,NULL); 08636 rpt_mutex_lock(&myrpt->lock); 08637 } 08638 }
static int rbi_mhztoband | ( | char * | str | ) | [static] |
Definition at line 5693 of file app_rpt.c.
Referenced by setrbi(), and setrbi_check().
05694 { 05695 int i; 05696 05697 i = atoi(str) / 10; /* get the 10's of mhz */ 05698 switch(i) 05699 { 05700 case 2: 05701 return 10; 05702 case 5: 05703 return 11; 05704 case 14: 05705 return 2; 05706 case 22: 05707 return 3; 05708 case 44: 05709 return 4; 05710 case 124: 05711 return 0; 05712 case 125: 05713 return 1; 05714 case 126: 05715 return 8; 05716 case 127: 05717 return 5; 05718 case 128: 05719 return 6; 05720 case 129: 05721 return 7; 05722 default: 05723 break; 05724 } 05725 return -1; 05726 }
static void rbi_out | ( | struct rpt * | myrpt, | |
unsigned char * | data | |||
) | [static] |
Definition at line 5852 of file app_rpt.c.
References ast_log(), ast_channel::fds, LOG_WARNING, rbi_out_parallel(), and rpt::zaprxchannel.
Referenced by setrbi().
05853 { 05854 struct zt_radio_param r; 05855 05856 memset(&r,0,sizeof(struct zt_radio_param)); 05857 r.radpar = ZT_RADPAR_REMMODE; 05858 r.data = ZT_RADPAR_REM_RBI1; 05859 /* if setparam ioctl fails, its probably not a pciradio card */ 05860 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1) 05861 { 05862 rbi_out_parallel(myrpt,data); 05863 return; 05864 } 05865 r.radpar = ZT_RADPAR_REMCOMMAND; 05866 memcpy(&r.data,data,5); 05867 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1) 05868 { 05869 ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->zaprxchannel->name); 05870 return; 05871 } 05872 }
static void rbi_out_parallel | ( | struct rpt * | myrpt, | |
unsigned char * | data | |||
) | [static] |
Definition at line 5824 of file app_rpt.c.
References rpt::iobase, and rpt::p.
Referenced by rbi_out().
05825 { 05826 #ifdef __i386__ 05827 int i,j; 05828 unsigned char od,d; 05829 static volatile long long delayvar; 05830 05831 for(i = 0 ; i < 5 ; i++){ 05832 od = *data++; 05833 for(j = 0 ; j < 8 ; j++){ 05834 d = od & 1; 05835 outb(d,myrpt->p.iobase); 05836 /* >= 15 us */ 05837 for(delayvar = 1; delayvar < 15000; delayvar++); 05838 od >>= 1; 05839 outb(d | 2,myrpt->p.iobase); 05840 /* >= 30 us */ 05841 for(delayvar = 1; delayvar < 30000; delayvar++); 05842 outb(d,myrpt->p.iobase); 05843 /* >= 10 us */ 05844 for(delayvar = 1; delayvar < 10000; delayvar++); 05845 } 05846 } 05847 /* >= 50 us */ 05848 for(delayvar = 1; delayvar < 50000; delayvar++); 05849 #endif 05850 }
static int rbi_pltocode | ( | char * | str | ) | [static] |
Definition at line 5729 of file app_rpt.c.
References s.
Referenced by setrbi(), and setrbi_check().
05730 { 05731 int i; 05732 char *s; 05733 05734 s = strchr(str,'.'); 05735 i = 0; 05736 if (s) i = atoi(s + 1); 05737 i += atoi(str) * 10; 05738 switch(i) 05739 { 05740 case 670: 05741 return 0; 05742 case 719: 05743 return 1; 05744 case 744: 05745 return 2; 05746 case 770: 05747 return 3; 05748 case 797: 05749 return 4; 05750 case 825: 05751 return 5; 05752 case 854: 05753 return 6; 05754 case 885: 05755 return 7; 05756 case 915: 05757 return 8; 05758 case 948: 05759 return 9; 05760 case 974: 05761 return 10; 05762 case 1000: 05763 return 11; 05764 case 1035: 05765 return 12; 05766 case 1072: 05767 return 13; 05768 case 1109: 05769 return 14; 05770 case 1148: 05771 return 15; 05772 case 1188: 05773 return 16; 05774 case 1230: 05775 return 17; 05776 case 1273: 05777 return 18; 05778 case 1318: 05779 return 19; 05780 case 1365: 05781 return 20; 05782 case 1413: 05783 return 21; 05784 case 1462: 05785 return 22; 05786 case 1514: 05787 return 23; 05788 case 1567: 05789 return 24; 05790 case 1622: 05791 return 25; 05792 case 1679: 05793 return 26; 05794 case 1738: 05795 return 27; 05796 case 1799: 05797 return 28; 05798 case 1862: 05799 return 29; 05800 case 1928: 05801 return 30; 05802 case 2035: 05803 return 31; 05804 case 2107: 05805 return 32; 05806 case 2181: 05807 return 33; 05808 case 2257: 05809 return 34; 05810 case 2336: 05811 return 35; 05812 case 2418: 05813 return 36; 05814 case 2503: 05815 return 37; 05816 } 05817 return -1; 05818 }
static int reload | ( | void | ) | [static] |
static int retreive_memory | ( | struct rpt * | myrpt, | |
char * | memory | |||
) | [static] |
Definition at line 7653 of file app_rpt.c.
References ast_variable_retrieve(), rpt::cfg, rpt::freq, rpt::memory, rpt::offset, rpt::p, 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::remmode, rpt::rxpl, rpt::rxplon, s, rpt::txpl, and rpt::txplon.
Referenced by function_remote(), and rpt_master().
07654 { 07655 char tmp[30], *s, *s1, *val; 07656 07657 val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.memory, memory); 07658 if (!val){ 07659 return -1; 07660 } 07661 strncpy(tmp,val,sizeof(tmp) - 1); 07662 tmp[sizeof(tmp)-1] = 0; 07663 07664 s = strchr(tmp,','); 07665 if (!s) 07666 return 1; 07667 *s++ = 0; 07668 s1 = strchr(s,','); 07669 if (!s1) 07670 return 1; 07671 *s1++ = 0; 07672 strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1); 07673 strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1); 07674 strncpy(myrpt->txpl, s, sizeof(myrpt->rxpl) - 1); 07675 myrpt->remmode = REM_MODE_FM; 07676 myrpt->offset = REM_SIMPLEX; 07677 myrpt->powerlevel = REM_MEDPWR; 07678 myrpt->txplon = myrpt->rxplon = 0; 07679 while(*s1){ 07680 switch(*s1++){ 07681 case 'A': 07682 case 'a': 07683 strcpy(myrpt->rxpl, "100.0"); 07684 strcpy(myrpt->txpl, "100.0"); 07685 myrpt->remmode = REM_MODE_AM; 07686 break; 07687 case 'B': 07688 case 'b': 07689 strcpy(myrpt->rxpl, "100.0"); 07690 strcpy(myrpt->txpl, "100.0"); 07691 myrpt->remmode = REM_MODE_LSB; 07692 break; 07693 case 'F': 07694 myrpt->remmode = REM_MODE_FM; 07695 break; 07696 case 'L': 07697 case 'l': 07698 myrpt->powerlevel = REM_LOWPWR; 07699 break; 07700 case 'H': 07701 case 'h': 07702 myrpt->powerlevel = REM_HIPWR; 07703 break; 07704 07705 case 'M': 07706 case 'm': 07707 myrpt->powerlevel = REM_MEDPWR; 07708 break; 07709 07710 case '-': 07711 myrpt->offset = REM_MINUS; 07712 break; 07713 07714 case '+': 07715 myrpt->offset = REM_PLUS; 07716 break; 07717 07718 case 'S': 07719 case 's': 07720 myrpt->offset = REM_SIMPLEX; 07721 break; 07722 07723 case 'T': 07724 case 't': 07725 myrpt->txplon = 1; 07726 break; 07727 07728 case 'R': 07729 case 'r': 07730 myrpt->rxplon = 1; 07731 break; 07732 07733 case 'U': 07734 case 'u': 07735 strcpy(myrpt->rxpl, "100.0"); 07736 strcpy(myrpt->txpl, "100.0"); 07737 myrpt->remmode = REM_MODE_USB; 07738 break; 07739 default: 07740 return 1; 07741 } 07742 } 07743 return 0; 07744 }
static int retrieve_astcfgint | ( | struct rpt * | myrpt, | |
char * | category, | |||
char * | name, | |||
int | min, | |||
int | max, | |||
int | defl | |||
) | [static] |
Definition at line 1595 of file app_rpt.c.
References ast_variable_retrieve(), rpt::cfg, myatoi(), and var.
Referenced by get_wait_interval(), load_rpt_vars(), and telem_any().
01596 { 01597 char *var; 01598 int ret; 01599 char include_zero = 0; 01600 01601 if(min < 0){ /* If min is negative, this means include 0 as a valid entry */ 01602 min = -min; 01603 include_zero = 1; 01604 } 01605 01606 var = (char *) ast_variable_retrieve(myrpt->cfg, category, name); 01607 if(var){ 01608 ret = myatoi(var); 01609 if(include_zero && !ret) 01610 return 0; 01611 if(ret < min) 01612 ret = min; 01613 if(ret > max) 01614 ret = max; 01615 } 01616 else 01617 ret = defl; 01618 return ret; 01619 }
static void* rpt | ( | void * | this | ) | [static] |
Definition at line 8763 of file app_rpt.c.
References __kickshort(), __mklinklist(), ast_channel::_state, sysstate::alternatetail, rpt::althangtime, ast_channel::appl, rpt::archivedir, ast_call(), AST_CDR_FLAG_POST_DISABLED, ast_channel_setoption(), ast_check_hangup(), ast_closestream(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_FORMAT_SLINEAR, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frdup(), ast_frfree, ast_hangup(), ast_indicate(), ast_log(), AST_OPTION_RELAXDTMF, AST_OPTION_TONE_VERIFY, AST_PTHREADT_STOP, ast_read(), ast_request(), ast_set_flag, 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(), ast_writefile(), ast_writestream(), attempt_reconnect(), rpt::callmode, ast_channel::cdr, rpt::cfg, rpt_link::chan, rpt_tele::chan, rpt::cmdnode, rpt::conf, CONNECTED, rpt_link::connected, rpt_link::connecttime, CONNFAIL, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, ast_frame::data, ast_channel::data, ast_frame::datalen, DISC_TIME, rpt_link::disced, rpt_link::disctime, rpt::disgorgetime, diskavail(), do_dtmf_local(), do_scheduler(), donodelog(), rpt::dtmf_local_timer, rpt::dtmf_time, DTMF_TIMEOUT, rpt::dtmfbuf, rpt_link::dtmfed, rpt::dtmfidx, rpt::duplex, rpt_link::elaptime, rpt::exten, rpt::exttx, ast_channel::fds, ast_frame::frametype, free, func_xlat(), handle_link_data(), handle_link_phone_dtmf(), rpt::hangtime, rpt_link::hasconnected, ID, IDTALKOVER, rpt::idtime, rpt::idtimer, rpt::inxlat, rpt_link::isremote, rpt::keyed, rpt_link::killme, rpt::lastdtmfcommand, rpt_link::lastf1, rpt::lastf1, rpt_link::lastf2, rpt::lastf2, rpt::lastnodewhichkeyedusup, rpt_link::lastrx, rpt_link::lastrx1, rpt_link::lasttx, LINKLISTTIME, rpt_link::linklisttimer, rpt::links, rpt::linktolink, LINKUNKEY, load_rpt_vars(), local_dtmf_helper(), rpt::localtx, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macrobuf, MACROPTIME, MACROTIME, rpt::macrotimer, ast_frame::mallocd, rpt_link::max_retries, MAXCONNECTTIME, MAXLINKLIST, MAXMACRO, mdc1200_notify(), rpt_link::mode, rpt_tele::mode, rpt::monchannel, rpt::monminblocks, rpt::monstream, MSWAIT, rpt::mustid, rpt_link::name, rpt::name, rpt_link::next, rpt_tele::next, rpt::notelemtx, ast_frame::offset, option_verbose, rpt_link::outbound, rpt::p, rpt_link::pchan, rpt::pchannel, rpt_link::phonemode, rpt::politeid, rpt_link::prev, queue_id(), rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, REMDISC, rpt_link::rerxtimer, rpt::rerxtimer, rpt_link::retries, RETRY_TIMER_MS, rpt_link::retrytimer, rpt_link::retxtimer, rpt::retxtimer, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, rpt::rxchannel, s, rpt::s, ast_frame::samples, rpt::scram, rpt::skedtimer, START_DELAY, rpt::startupmacro, ast_frame::subclass, rpt::sysstate_cur, rpt::tailevent, rpt::tailid, rpt::tailmessages, rpt::tailmessagetime, TAILMSG, rpt::tailtimer, rpt::tele, rpt_link::thisconnected, TIMEOUT, rpt::timeouts, rpt::tmsgtimer, rpt::tonotify, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, sysstate::totdisable, rpt::totime, rpt::totimer, rpt::tounkeyed, rpt::txchanname, rpt::txchannel, rpt::txconf, sysstate::txdisable, rpt::txpchannel, UNKEY, VERBOSE_PREFIX_3, ast_channel::whentohangup, rpt::zaprxchannel, and rpt::zaptxchannel.
08764 { 08765 struct rpt *myrpt = (struct rpt *)this; 08766 char *tele,*idtalkover,c; 08767 int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,othertelemqueued; 08768 int tailmessagequeued,ctqueued,dtmfed; 08769 struct ast_channel *who; 08770 ZT_CONFINFO ci; /* conference info */ 08771 time_t t; 08772 struct rpt_link *l,*m; 08773 struct rpt_tele *telem; 08774 char tmpstr[300],lstr[MAXLINKLIST]; 08775 08776 08777 if (myrpt->p.archivedir) mkdir(myrpt->p.archivedir,0600); 08778 sprintf(tmpstr,"%s/%s",myrpt->p.archivedir,myrpt->name); 08779 mkdir(tmpstr,0600); 08780 rpt_mutex_lock(&myrpt->lock); 08781 08782 telem = myrpt->tele.next; 08783 while(telem != &myrpt->tele) 08784 { 08785 ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV); 08786 telem = telem->next; 08787 } 08788 rpt_mutex_unlock(&myrpt->lock); 08789 /* find our index, and load the vars initially */ 08790 for(i = 0; i < nrpts; i++) 08791 { 08792 if (&rpt_vars[i] == myrpt) 08793 { 08794 load_rpt_vars(i,0); 08795 break; 08796 } 08797 } 08798 rpt_mutex_lock(&myrpt->lock); 08799 strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1); 08800 tele = strchr(tmpstr,'/'); 08801 if (!tele) 08802 { 08803 fprintf(stderr,"rpt:Rxchannel Dial number (%s) must be in format tech/number\n",myrpt->rxchanname); 08804 rpt_mutex_unlock(&myrpt->lock); 08805 myrpt->rpt_thread = AST_PTHREADT_STOP; 08806 pthread_exit(NULL); 08807 } 08808 *tele++ = 0; 08809 myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 08810 myrpt->zaprxchannel = NULL; 08811 if (!strcasecmp(tmpstr,"Zap")) 08812 myrpt->zaprxchannel = myrpt->rxchannel; 08813 if (myrpt->rxchannel) 08814 { 08815 if (myrpt->rxchannel->_state == AST_STATE_BUSY) 08816 { 08817 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 08818 rpt_mutex_unlock(&myrpt->lock); 08819 ast_hangup(myrpt->rxchannel); 08820 myrpt->rpt_thread = AST_PTHREADT_STOP; 08821 pthread_exit(NULL); 08822 } 08823 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 08824 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 08825 #ifdef AST_CDR_FLAG_POST_DISABLED 08826 ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08827 #endif 08828 myrpt->rxchannel->whentohangup = 0; 08829 myrpt->rxchannel->appl = "Apprpt"; 08830 myrpt->rxchannel->data = "(Repeater Rx)"; 08831 if (option_verbose > 2) 08832 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 08833 tmpstr,tele,myrpt->rxchannel->name); 08834 ast_call(myrpt->rxchannel,tele,999); 08835 if (myrpt->rxchannel->_state != AST_STATE_UP) 08836 { 08837 rpt_mutex_unlock(&myrpt->lock); 08838 ast_hangup(myrpt->rxchannel); 08839 myrpt->rpt_thread = AST_PTHREADT_STOP; 08840 pthread_exit(NULL); 08841 } 08842 } 08843 else 08844 { 08845 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 08846 rpt_mutex_unlock(&myrpt->lock); 08847 myrpt->rpt_thread = AST_PTHREADT_STOP; 08848 pthread_exit(NULL); 08849 } 08850 myrpt->zaptxchannel = NULL; 08851 if (myrpt->txchanname) 08852 { 08853 strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1); 08854 tele = strchr(tmpstr,'/'); 08855 if (!tele) 08856 { 08857 fprintf(stderr,"rpt:Txchannel Dial number (%s) must be in format tech/number\n",myrpt->txchanname); 08858 rpt_mutex_unlock(&myrpt->lock); 08859 ast_hangup(myrpt->rxchannel); 08860 myrpt->rpt_thread = AST_PTHREADT_STOP; 08861 pthread_exit(NULL); 08862 } 08863 *tele++ = 0; 08864 myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 08865 if (!strcasecmp(tmpstr,"Zap")) 08866 myrpt->zaptxchannel = myrpt->txchannel; 08867 if (myrpt->txchannel) 08868 { 08869 if (myrpt->txchannel->_state == AST_STATE_BUSY) 08870 { 08871 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 08872 rpt_mutex_unlock(&myrpt->lock); 08873 ast_hangup(myrpt->txchannel); 08874 ast_hangup(myrpt->rxchannel); 08875 myrpt->rpt_thread = AST_PTHREADT_STOP; 08876 pthread_exit(NULL); 08877 } 08878 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 08879 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 08880 #ifdef AST_CDR_FLAG_POST_DISABLED 08881 ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08882 #endif 08883 myrpt->txchannel->whentohangup = 0; 08884 myrpt->txchannel->appl = "Apprpt"; 08885 myrpt->txchannel->data = "(Repeater Tx)"; 08886 if (option_verbose > 2) 08887 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 08888 tmpstr,tele,myrpt->txchannel->name); 08889 ast_call(myrpt->txchannel,tele,999); 08890 if (myrpt->rxchannel->_state != AST_STATE_UP) 08891 { 08892 rpt_mutex_unlock(&myrpt->lock); 08893 ast_hangup(myrpt->rxchannel); 08894 ast_hangup(myrpt->txchannel); 08895 myrpt->rpt_thread = AST_PTHREADT_STOP; 08896 pthread_exit(NULL); 08897 } 08898 } 08899 else 08900 { 08901 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 08902 rpt_mutex_unlock(&myrpt->lock); 08903 ast_hangup(myrpt->rxchannel); 08904 myrpt->rpt_thread = AST_PTHREADT_STOP; 08905 pthread_exit(NULL); 08906 } 08907 } 08908 else 08909 { 08910 myrpt->txchannel = myrpt->rxchannel; 08911 } 08912 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 08913 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 08914 /* allocate a pseudo-channel thru asterisk */ 08915 myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08916 if (!myrpt->pchannel) 08917 { 08918 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08919 rpt_mutex_unlock(&myrpt->lock); 08920 if (myrpt->txchannel != myrpt->rxchannel) 08921 ast_hangup(myrpt->txchannel); 08922 ast_hangup(myrpt->rxchannel); 08923 myrpt->rpt_thread = AST_PTHREADT_STOP; 08924 pthread_exit(NULL); 08925 } 08926 #ifdef AST_CDR_FLAG_POST_DISABLED 08927 ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08928 #endif 08929 if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel; 08930 if (!myrpt->zaptxchannel) 08931 { 08932 /* allocate a pseudo-channel thru asterisk */ 08933 myrpt->zaptxchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08934 if (!myrpt->zaptxchannel) 08935 { 08936 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08937 rpt_mutex_unlock(&myrpt->lock); 08938 if (myrpt->txchannel != myrpt->rxchannel) 08939 ast_hangup(myrpt->txchannel); 08940 ast_hangup(myrpt->rxchannel); 08941 myrpt->rpt_thread = AST_PTHREADT_STOP; 08942 pthread_exit(NULL); 08943 } 08944 ast_set_read_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR); 08945 ast_set_write_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR); 08946 #ifdef AST_CDR_FLAG_POST_DISABLED 08947 ast_set_flag(myrpt->zaptxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08948 #endif 08949 } 08950 /* allocate a pseudo-channel thru asterisk */ 08951 myrpt->monchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08952 if (!myrpt->monchannel) 08953 { 08954 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08955 rpt_mutex_unlock(&myrpt->lock); 08956 if (myrpt->txchannel != myrpt->rxchannel) 08957 ast_hangup(myrpt->txchannel); 08958 ast_hangup(myrpt->rxchannel); 08959 myrpt->rpt_thread = AST_PTHREADT_STOP; 08960 pthread_exit(NULL); 08961 } 08962 ast_set_read_format(myrpt->monchannel,AST_FORMAT_SLINEAR); 08963 ast_set_write_format(myrpt->monchannel,AST_FORMAT_SLINEAR); 08964 #ifdef AST_CDR_FLAG_POST_DISABLED 08965 ast_set_flag(myrpt->monchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08966 #endif 08967 /* make a conference for the tx */ 08968 ci.chan = 0; 08969 ci.confno = -1; /* make a new conf */ 08970 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER; 08971 /* first put the channel on the conference in proper mode */ 08972 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_SETCONF,&ci) == -1) 08973 { 08974 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 08975 rpt_mutex_unlock(&myrpt->lock); 08976 ast_hangup(myrpt->pchannel); 08977 ast_hangup(myrpt->monchannel); 08978 if (myrpt->txchannel != myrpt->rxchannel) 08979 ast_hangup(myrpt->txchannel); 08980 ast_hangup(myrpt->rxchannel); 08981 myrpt->rpt_thread = AST_PTHREADT_STOP; 08982 pthread_exit(NULL); 08983 } 08984 /* save tx conference number */ 08985 myrpt->txconf = ci.confno; 08986 /* make a conference for the pseudo */ 08987 ci.chan = 0; 08988 ci.confno = -1; /* make a new conf */ 08989 ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON : 08990 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 08991 /* first put the channel on the conference in announce mode */ 08992 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 08993 { 08994 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 08995 rpt_mutex_unlock(&myrpt->lock); 08996 ast_hangup(myrpt->pchannel); 08997 ast_hangup(myrpt->monchannel); 08998 if (myrpt->txchannel != myrpt->rxchannel) 08999 ast_hangup(myrpt->txchannel); 09000 ast_hangup(myrpt->rxchannel); 09001 myrpt->rpt_thread = AST_PTHREADT_STOP; 09002 pthread_exit(NULL); 09003 } 09004 /* save pseudo channel conference number */ 09005 myrpt->conf = ci.confno; 09006 /* make a conference for the pseudo */ 09007 ci.chan = 0; 09008 if ((strstr(myrpt->txchannel->name,"pseudo") == NULL) && 09009 (myrpt->zaptxchannel == myrpt->txchannel)) 09010 { 09011 /* get tx channel's port number */ 09012 if (ioctl(myrpt->txchannel->fds[0],ZT_CHANNO,&ci.confno) == -1) 09013 { 09014 ast_log(LOG_WARNING, "Unable to set tx channel's chan number\n"); 09015 rpt_mutex_unlock(&myrpt->lock); 09016 ast_hangup(myrpt->pchannel); 09017 ast_hangup(myrpt->monchannel); 09018 if (myrpt->txchannel != myrpt->rxchannel) 09019 ast_hangup(myrpt->txchannel); 09020 ast_hangup(myrpt->rxchannel); 09021 myrpt->rpt_thread = AST_PTHREADT_STOP; 09022 pthread_exit(NULL); 09023 } 09024 ci.confmode = ZT_CONF_MONITORTX; 09025 } 09026 else 09027 { 09028 ci.confno = myrpt->txconf; 09029 ci.confmode = ZT_CONF_CONFANNMON; 09030 } 09031 /* first put the channel on the conference in announce mode */ 09032 if (ioctl(myrpt->monchannel->fds[0],ZT_SETCONF,&ci) == -1) 09033 { 09034 ast_log(LOG_WARNING, "Unable to set conference mode for monitor\n"); 09035 rpt_mutex_unlock(&myrpt->lock); 09036 ast_hangup(myrpt->pchannel); 09037 ast_hangup(myrpt->monchannel); 09038 if (myrpt->txchannel != myrpt->rxchannel) 09039 ast_hangup(myrpt->txchannel); 09040 ast_hangup(myrpt->rxchannel); 09041 myrpt->rpt_thread = AST_PTHREADT_STOP; 09042 pthread_exit(NULL); 09043 } 09044 /* allocate a pseudo-channel thru asterisk */ 09045 myrpt->txpchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 09046 if (!myrpt->txpchannel) 09047 { 09048 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 09049 rpt_mutex_unlock(&myrpt->lock); 09050 ast_hangup(myrpt->pchannel); 09051 ast_hangup(myrpt->monchannel); 09052 if (myrpt->txchannel != myrpt->rxchannel) 09053 ast_hangup(myrpt->txchannel); 09054 ast_hangup(myrpt->rxchannel); 09055 myrpt->rpt_thread = AST_PTHREADT_STOP; 09056 pthread_exit(NULL); 09057 } 09058 #ifdef AST_CDR_FLAG_POST_DISABLED 09059 ast_set_flag(myrpt->txpchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 09060 #endif 09061 /* make a conference for the tx */ 09062 ci.chan = 0; 09063 ci.confno = myrpt->txconf; 09064 ci.confmode = ZT_CONF_CONF | ZT_CONF_TALKER ; 09065 /* first put the channel on the conference in proper mode */ 09066 if (ioctl(myrpt->txpchannel->fds[0],ZT_SETCONF,&ci) == -1) 09067 { 09068 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 09069 rpt_mutex_unlock(&myrpt->lock); 09070 ast_hangup(myrpt->txpchannel); 09071 ast_hangup(myrpt->monchannel); 09072 if (myrpt->txchannel != myrpt->rxchannel) 09073 ast_hangup(myrpt->txchannel); 09074 ast_hangup(myrpt->rxchannel); 09075 myrpt->rpt_thread = AST_PTHREADT_STOP; 09076 pthread_exit(NULL); 09077 } 09078 /* Now, the idea here is to copy from the physical rx channel buffer 09079 into the pseudo tx buffer, and from the pseudo rx buffer into the 09080 tx channel buffer */ 09081 myrpt->links.next = &myrpt->links; 09082 myrpt->links.prev = &myrpt->links; 09083 myrpt->tailtimer = 0; 09084 myrpt->totimer = 0; 09085 myrpt->tmsgtimer = myrpt->p.tailmessagetime; 09086 myrpt->idtimer = myrpt->p.politeid; 09087 myrpt->mustid = myrpt->tailid = 0; 09088 myrpt->callmode = 0; 09089 myrpt->tounkeyed = 0; 09090 myrpt->tonotify = 0; 09091 myrpt->retxtimer = 0; 09092 myrpt->rerxtimer = 0; 09093 myrpt->skedtimer = 0; 09094 myrpt->tailevent = 0; 09095 lasttx = 0; 09096 myrpt->keyed = 0; 09097 idtalkover = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "idtalkover"); 09098 myrpt->dtmfidx = -1; 09099 myrpt->dtmfbuf[0] = 0; 09100 myrpt->rem_dtmfidx = -1; 09101 myrpt->rem_dtmfbuf[0] = 0; 09102 myrpt->dtmf_time = 0; 09103 myrpt->rem_dtmf_time = 0; 09104 myrpt->disgorgetime = 0; 09105 myrpt->lastnodewhichkeyedusup[0] = '\0'; 09106 myrpt->dailytxtime = 0; 09107 myrpt->totaltxtime = 0; 09108 myrpt->dailykeyups = 0; 09109 myrpt->totalkeyups = 0; 09110 myrpt->dailykerchunks = 0; 09111 myrpt->totalkerchunks = 0; 09112 myrpt->dailyexecdcommands = 0; 09113 myrpt->totalexecdcommands = 0; 09114 myrpt->timeouts = 0; 09115 myrpt->exten[0] = '\0'; 09116 myrpt->lastdtmfcommand[0] = '\0'; 09117 if (myrpt->p.startupmacro) 09118 { 09119 snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro); 09120 } 09121 rpt_mutex_unlock(&myrpt->lock); 09122 val = 1; 09123 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0); 09124 val = 1; 09125 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0); 09126 if (myrpt->p.archivedir) donodelog(myrpt,"STARTUP"); 09127 dtmfed = 0; 09128 while (ms >= 0) 09129 { 09130 struct ast_frame *f,*f1,*f2; 09131 struct ast_channel *cs[300],*cs1[300]; 09132 int totx=0,elap=0,n,x,toexit=0; 09133 09134 /* DEBUG Dump */ 09135 if((myrpt->disgorgetime) && (time(NULL) >= myrpt->disgorgetime)){ 09136 struct rpt_link *zl; 09137 struct rpt_tele *zt; 09138 09139 myrpt->disgorgetime = 0; 09140 ast_log(LOG_NOTICE,"********** Variable Dump Start (app_rpt) **********\n"); 09141 ast_log(LOG_NOTICE,"totx = %d\n",totx); 09142 ast_log(LOG_NOTICE,"remrx = %d\n",remrx); 09143 ast_log(LOG_NOTICE,"lasttx = %d\n",lasttx); 09144 ast_log(LOG_NOTICE,"elap = %d\n",elap); 09145 ast_log(LOG_NOTICE,"toexit = %d\n",toexit); 09146 09147 ast_log(LOG_NOTICE,"myrpt->keyed = %d\n",myrpt->keyed); 09148 ast_log(LOG_NOTICE,"myrpt->localtx = %d\n",myrpt->localtx); 09149 ast_log(LOG_NOTICE,"myrpt->callmode = %d\n",myrpt->callmode); 09150 ast_log(LOG_NOTICE,"myrpt->mustid = %d\n",myrpt->mustid); 09151 ast_log(LOG_NOTICE,"myrpt->tounkeyed = %d\n",myrpt->tounkeyed); 09152 ast_log(LOG_NOTICE,"myrpt->tonotify = %d\n",myrpt->tonotify); 09153 ast_log(LOG_NOTICE,"myrpt->retxtimer = %ld\n",myrpt->retxtimer); 09154 ast_log(LOG_NOTICE,"myrpt->totimer = %d\n",myrpt->totimer); 09155 ast_log(LOG_NOTICE,"myrpt->tailtimer = %d\n",myrpt->tailtimer); 09156 ast_log(LOG_NOTICE,"myrpt->tailevent = %d\n",myrpt->tailevent); 09157 09158 zl = myrpt->links.next; 09159 while(zl != &myrpt->links){ 09160 ast_log(LOG_NOTICE,"*** Link Name: %s ***\n",zl->name); 09161 ast_log(LOG_NOTICE," link->lasttx %d\n",zl->lasttx); 09162 ast_log(LOG_NOTICE," link->lastrx %d\n",zl->lastrx); 09163 ast_log(LOG_NOTICE," link->connected %d\n",zl->connected); 09164 ast_log(LOG_NOTICE," link->hasconnected %d\n",zl->hasconnected); 09165 ast_log(LOG_NOTICE," link->outbound %d\n",zl->outbound); 09166 ast_log(LOG_NOTICE," link->disced %d\n",zl->disced); 09167 ast_log(LOG_NOTICE," link->killme %d\n",zl->killme); 09168 ast_log(LOG_NOTICE," link->disctime %ld\n",zl->disctime); 09169 ast_log(LOG_NOTICE," link->retrytimer %ld\n",zl->retrytimer); 09170 ast_log(LOG_NOTICE," link->retries = %d\n",zl->retries); 09171 ast_log(LOG_NOTICE," link->reconnects = %d\n",zl->reconnects); 09172 zl = zl->next; 09173 } 09174 09175 zt = myrpt->tele.next; 09176 if(zt != &myrpt->tele) 09177 ast_log(LOG_NOTICE,"*** Telemetry Queue ***\n"); 09178 while(zt != &myrpt->tele){ 09179 ast_log(LOG_NOTICE," Telemetry mode: %d\n",zt->mode); 09180 zt = zt->next; 09181 } 09182 ast_log(LOG_NOTICE,"******* Variable Dump End (app_rpt) *******\n"); 09183 09184 } 09185 09186 09187 if (myrpt->reload) 09188 { 09189 struct rpt_tele *telem; 09190 09191 rpt_mutex_lock(&myrpt->lock); 09192 telem = myrpt->tele.next; 09193 while(telem != &myrpt->tele) 09194 { 09195 ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV); 09196 telem = telem->next; 09197 } 09198 myrpt->reload = 0; 09199 rpt_mutex_unlock(&myrpt->lock); 09200 usleep(10000); 09201 /* find our index, and load the vars */ 09202 for(i = 0; i < nrpts; i++) 09203 { 09204 if (&rpt_vars[i] == myrpt) 09205 { 09206 load_rpt_vars(i,0); 09207 break; 09208 } 09209 } 09210 } 09211 09212 rpt_mutex_lock(&myrpt->lock); 09213 if (ast_check_hangup(myrpt->rxchannel)) break; 09214 if (ast_check_hangup(myrpt->txchannel)) break; 09215 if (ast_check_hangup(myrpt->pchannel)) break; 09216 if (ast_check_hangup(myrpt->monchannel)) break; 09217 if (ast_check_hangup(myrpt->txpchannel)) break; 09218 if (myrpt->zaptxchannel && ast_check_hangup(myrpt->zaptxchannel)) break; 09219 09220 /* Set local tx with keyed */ 09221 myrpt->localtx = myrpt->keyed; 09222 /* If someone's connected, and they're transmitting from their end to us, set remrx true */ 09223 l = myrpt->links.next; 09224 remrx = 0; 09225 while(l != &myrpt->links) 09226 { 09227 if (l->lastrx){ 09228 remrx = 1; 09229 if(l->name[0] != '0') /* Ignore '0' nodes */ 09230 strcpy(myrpt->lastnodewhichkeyedusup, l->name); /* Note the node which is doing the key up */ 09231 } 09232 l = l->next; 09233 } 09234 /* Create a "must_id" flag for the cleanup ID */ 09235 if(myrpt->p.idtime) /* ID time must be non-zero */ 09236 myrpt->mustid |= (myrpt->idtimer) && (myrpt->keyed || remrx) ; 09237 /* Build a fresh totx from myrpt->keyed and autopatch activated */ 09238 totx = myrpt->callmode; 09239 /* If full duplex, add local tx to totx */ 09240 if (myrpt->p.duplex > 1) 09241 { 09242 totx = totx || myrpt->localtx; 09243 } 09244 /* Traverse the telemetry list to see what's queued */ 09245 identqueued = 0; 09246 othertelemqueued = 0; 09247 tailmessagequeued = 0; 09248 ctqueued = 0; 09249 telem = myrpt->tele.next; 09250 while(telem != &myrpt->tele) 09251 { 09252 if((telem->mode == ID) || (telem->mode == IDTALKOVER)){ 09253 identqueued = 1; /* Identification telemetry */ 09254 } 09255 else if(telem->mode == TAILMSG) 09256 { 09257 tailmessagequeued = 1; /* Tail message telemetry */ 09258 } 09259 else 09260 { 09261 if ((telem->mode != UNKEY) && (telem->mode != LINKUNKEY)) 09262 othertelemqueued = 1; /* Other telemetry */ 09263 else 09264 ctqueued = 1; /* Courtesy tone telemetry */ 09265 } 09266 telem = telem->next; 09267 } 09268 09269 /* Add in any "other" telemetry, unless specified otherwise */ 09270 if (!myrpt->p.notelemtx) totx = totx || othertelemqueued; 09271 /* Update external (to links) transmitter PTT state with everything but ID, CT, and tailmessage telemetry */ 09272 myrpt->exttx = totx; 09273 totx = totx || myrpt->dtmf_local_timer; 09274 /* If half or 3/4 duplex, add localtx to external link tx */ 09275 if (myrpt->p.duplex < 2) myrpt->exttx = myrpt->exttx || myrpt->localtx; 09276 /* Add in ID telemetry to local transmitter */ 09277 totx = totx || remrx; 09278 /* If 3/4 or full duplex, add in ident and CT telemetry */ 09279 if (myrpt->p.duplex > 0) 09280 totx = totx || identqueued || ctqueued; 09281 /* If full duplex, add local dtmf stuff active */ 09282 if (myrpt->p.duplex > 1) 09283 { 09284 totx = totx || (myrpt->dtmfidx > -1) || 09285 myrpt->cmdnode[0]; 09286 } 09287 /* Reset time out timer variables if there is no activity */ 09288 if (!totx) 09289 { 09290 myrpt->totimer = myrpt->p.totime; 09291 myrpt->tounkeyed = 0; 09292 myrpt->tonotify = 0; 09293 } 09294 else{ 09295 myrpt->tailtimer = myrpt->p.s[myrpt->p.sysstate_cur].alternatetail ? 09296 myrpt->p.althangtime : /* Initialize tail timer */ 09297 myrpt->p.hangtime; 09298 } 09299 /* Disable the local transmitter if we are timed out */ 09300 totx = totx && myrpt->totimer; 09301 /* if timed-out and not said already, say it */ 09302 if ((!myrpt->totimer) && (!myrpt->tonotify)) 09303 { 09304 myrpt->tonotify = 1; 09305 myrpt->timeouts++; 09306 rpt_mutex_unlock(&myrpt->lock); 09307 rpt_telemetry(myrpt,TIMEOUT,NULL); 09308 rpt_mutex_lock(&myrpt->lock); 09309 } 09310 09311 /* If unkey and re-key, reset time out timer */ 09312 if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!myrpt->keyed)) 09313 { 09314 myrpt->tounkeyed = 1; 09315 } 09316 if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->keyed) 09317 { 09318 myrpt->totimer = myrpt->p.totime; 09319 myrpt->tounkeyed = 0; 09320 myrpt->tonotify = 0; 09321 rpt_mutex_unlock(&myrpt->lock); 09322 continue; 09323 } 09324 /* if timed-out and in circuit busy after call */ 09325 if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4)) 09326 { 09327 myrpt->callmode = 0; 09328 } 09329 /* get rid of tail if timed out */ 09330 if (!myrpt->totimer) myrpt->tailtimer = 0; 09331 /* if not timed-out, add in tail */ 09332 if (myrpt->totimer) totx = totx || myrpt->tailtimer; 09333 /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */ 09334 /* If tail message, kill the message if someone keys up over it */ 09335 if ((myrpt->keyed || remrx) && ((identqueued && idtalkover) || (tailmessagequeued))) { 09336 int hasid = 0,hastalkover = 0; 09337 09338 telem = myrpt->tele.next; 09339 while(telem != &myrpt->tele){ 09340 if(telem->mode == ID){ 09341 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 09342 hasid = 1; 09343 } 09344 if(telem->mode == TAILMSG){ 09345 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 09346 } 09347 if (telem->mode == IDTALKOVER) hastalkover = 1; 09348 telem = telem->next; 09349 } 09350 rpt_mutex_unlock(&myrpt->lock); 09351 if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */ 09352 rpt_mutex_lock(&myrpt->lock); 09353 } 09354 /* Try to be polite */ 09355 /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/ 09356 /* If within 30 seconds of the time to ID, try do it in the tail */ 09357 /* else if at ID time limit, do it right over the top of them */ 09358 /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */ 09359 if(myrpt->mustid && (!myrpt->idtimer)) 09360 queue_id(myrpt); 09361 09362 if ((myrpt->p.idtime && totx && (!myrpt->exttx) && 09363 (myrpt->idtimer <= myrpt->p.politeid) && myrpt->tailtimer)) /* ID time must be non-zero */ 09364 { 09365 myrpt->tailid = 1; 09366 } 09367 09368 /* If tail timer expires, then check for tail messages */ 09369 09370 if(myrpt->tailevent){ 09371 myrpt->tailevent = 0; 09372 if(myrpt->tailid){ 09373 totx = 1; 09374 queue_id(myrpt); 09375 } 09376 else if ((myrpt->p.tailmessages[0]) && 09377 (myrpt->p.tailmessagetime) && (myrpt->tmsgtimer == 0)){ 09378 totx = 1; 09379 myrpt->tmsgtimer = myrpt->p.tailmessagetime; 09380 rpt_mutex_unlock(&myrpt->lock); 09381 rpt_telemetry(myrpt, TAILMSG, NULL); 09382 rpt_mutex_lock(&myrpt->lock); 09383 } 09384 } 09385 09386 /* Main TX control */ 09387 09388 /* let telemetry transmit anyway (regardless of timeout) */ 09389 if (myrpt->p.duplex > 0) totx = totx || (myrpt->tele.next != &myrpt->tele); 09390 if (totx && (!lasttx)) 09391 { 09392 char mydate[100],myfname[100]; 09393 time_t myt; 09394 09395 if (myrpt->monstream) ast_closestream(myrpt->monstream); 09396 if (myrpt->p.archivedir) 09397 { 09398 long blocksleft; 09399 09400 time(&myt); 09401 strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S", 09402 localtime(&myt)); 09403 sprintf(myfname,"%s/%s/%s",myrpt->p.archivedir, 09404 myrpt->name,mydate); 09405 myrpt->monstream = ast_writefile(myfname,"wav49", 09406 "app_rpt Air Archive",O_CREAT | O_APPEND,0,0600); 09407 if (myrpt->p.monminblocks) 09408 { 09409 blocksleft = diskavail(myrpt); 09410 if (blocksleft >= myrpt->p.monminblocks) 09411 donodelog(myrpt,"TXKEY,MAIN"); 09412 } else donodelog(myrpt,"TXKEY,MAIN"); 09413 } 09414 lasttx = 1; 09415 myrpt->dailykeyups++; 09416 myrpt->totalkeyups++; 09417 rpt_mutex_unlock(&myrpt->lock); 09418 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 09419 rpt_mutex_lock(&myrpt->lock); 09420 } 09421 totx = totx && !myrpt->p.s[myrpt->p.sysstate_cur].txdisable; 09422 if ((!totx) && lasttx) 09423 { 09424 if (myrpt->monstream) ast_closestream(myrpt->monstream); 09425 myrpt->monstream = NULL; 09426 09427 lasttx = 0; 09428 rpt_mutex_unlock(&myrpt->lock); 09429 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 09430 rpt_mutex_lock(&myrpt->lock); 09431 donodelog(myrpt,"TXUNKEY,MAIN"); 09432 } 09433 time(&t); 09434 /* if DTMF timeout */ 09435 if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((myrpt->dtmf_time + DTMF_TIMEOUT) < t)) 09436 { 09437 myrpt->dtmfidx = -1; 09438 myrpt->dtmfbuf[0] = 0; 09439 } 09440 /* if remote DTMF timeout */ 09441 if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t)) 09442 { 09443 myrpt->rem_dtmfidx = -1; 09444 myrpt->rem_dtmfbuf[0] = 0; 09445 } 09446 09447 /* Reconnect */ 09448 09449 l = myrpt->links.next; 09450 while(l != &myrpt->links) 09451 { 09452 if (l->killme) 09453 { 09454 /* remove from queue */ 09455 remque((struct qelem *) l); 09456 if (!strcmp(myrpt->cmdnode,l->name)) 09457 myrpt->cmdnode[0] = 0; 09458 rpt_mutex_unlock(&myrpt->lock); 09459 /* hang-up on call to device */ 09460 if (l->chan) ast_hangup(l->chan); 09461 ast_hangup(l->pchan); 09462 free(l); 09463 rpt_mutex_lock(&myrpt->lock); 09464 /* re-start link traversal */ 09465 l = myrpt->links.next; 09466 continue; 09467 } 09468 l = l->next; 09469 } 09470 n = 0; 09471 cs[n++] = myrpt->rxchannel; 09472 cs[n++] = myrpt->pchannel; 09473 cs[n++] = myrpt->monchannel; 09474 cs[n++] = myrpt->txpchannel; 09475 if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel; 09476 if (myrpt->zaptxchannel != myrpt->txchannel) 09477 cs[n++] = myrpt->zaptxchannel; 09478 l = myrpt->links.next; 09479 while(l != &myrpt->links) 09480 { 09481 if ((!l->killme) && (!l->disctime) && l->chan) 09482 { 09483 cs[n++] = l->chan; 09484 cs[n++] = l->pchan; 09485 } 09486 l = l->next; 09487 } 09488 rpt_mutex_unlock(&myrpt->lock); 09489 ms = MSWAIT; 09490 for(x = 0; x < n; x++) 09491 { 09492 int s = -(-x - myrpt->scram - 1) % n; 09493 cs1[x] = cs[s]; 09494 } 09495 myrpt->scram++; 09496 who = ast_waitfor_n(cs1,n,&ms); 09497 if (who == NULL) ms = 0; 09498 elap = MSWAIT - ms; 09499 rpt_mutex_lock(&myrpt->lock); 09500 l = myrpt->links.next; 09501 while(l != &myrpt->links) 09502 { 09503 if (l->linklisttimer) 09504 { 09505 l->linklisttimer -= elap; 09506 if (l->linklisttimer < 0) l->linklisttimer = 0; 09507 } 09508 if ((!l->linklisttimer) && (l->name[0] != '0') && (!l->isremote)) 09509 { 09510 struct ast_frame lf; 09511 09512 memset(&lf,0,sizeof(lf)); 09513 lf.frametype = AST_FRAME_TEXT; 09514 lf.subclass = 0; 09515 lf.offset = 0; 09516 lf.mallocd = 0; 09517 lf.samples = 0; 09518 l->linklisttimer = LINKLISTTIME; 09519 strcpy(lstr,"L "); 09520 __mklinklist(myrpt,l,lstr + 2); 09521 if (l->chan) 09522 { 09523 lf.datalen = strlen(lstr) + 1; 09524 lf.data = lstr; 09525 ast_write(l->chan,&lf); 09526 if (debug > 6) ast_log(LOG_NOTICE, 09527 "@@@@ node %s sent node string %s to node %s\n", 09528 myrpt->name,lstr,l->name); 09529 } 09530 } 09531 #ifndef OLDKEY 09532 if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME) 09533 { 09534 l->retxtimer = 0; 09535 if (l->chan && l->phonemode == 0) 09536 { 09537 if (l->lasttx) 09538 ast_indicate(l->chan,AST_CONTROL_RADIO_KEY); 09539 else 09540 ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 09541 } 09542 } 09543 if ((l->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 5)) 09544 { 09545 if (debug == 7) printf("@@@@ rx un-key\n"); 09546 l->lastrx = 0; 09547 l->rerxtimer = 0; 09548 if(myrpt->p.duplex) 09549 rpt_telemetry(myrpt,LINKUNKEY,l); 09550 if (myrpt->p.archivedir) 09551 { 09552 char str[100]; 09553 09554 l->lastrx1 = 0; 09555 sprintf(str,"RXUNKEY(T),%s",l->name); 09556 donodelog(myrpt,str); 09557 } 09558 } 09559 #endif 09560 if (l->disctime) /* Disconnect timer active on a channel ? */ 09561 { 09562 l->disctime -= elap; 09563 if (l->disctime <= 0) /* Disconnect timer expired on inbound channel ? */ 09564 l->disctime = 0; /* Yep */ 09565 } 09566 09567 if (l->retrytimer) 09568 { 09569 l->retrytimer -= elap; 09570 if (l->retrytimer < 0) l->retrytimer = 0; 09571 } 09572 09573 /* Tally connect time */ 09574 l->connecttime += elap; 09575 09576 /* ignore non-timing channels */ 09577 if (l->elaptime < 0) 09578 { 09579 l = l->next; 09580 continue; 09581 } 09582 l->elaptime += elap; 09583 /* if connection has taken too long */ 09584 if ((l->elaptime > MAXCONNECTTIME) && 09585 ((!l->chan) || (l->chan->_state != AST_STATE_UP))) 09586 { 09587 l->elaptime = 0; 09588 rpt_mutex_unlock(&myrpt->lock); 09589 if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 09590 rpt_mutex_lock(&myrpt->lock); 09591 break; 09592 } 09593 if ((!l->chan) && (!l->retrytimer) && l->outbound && 09594 (l->retries++ < l->max_retries) && (l->hasconnected)) 09595 { 09596 if (l->chan) ast_hangup(l->chan); 09597 l->chan = 0; 09598 rpt_mutex_unlock(&myrpt->lock); 09599 if ((l->name[0] != '0') && (!l->isremote)) 09600 { 09601 if (attempt_reconnect(myrpt,l) == -1) 09602 { 09603 l->retrytimer = RETRY_TIMER_MS; 09604 } 09605 } 09606 else 09607 { 09608 l->retrytimer = l->max_retries + 1; 09609 } 09610 09611 rpt_mutex_lock(&myrpt->lock); 09612 break; 09613 } 09614 if ((!l->chan) && (!l->retrytimer) && l->outbound && 09615 (l->retries >= l->max_retries)) 09616 { 09617 /* remove from queue */ 09618 remque((struct qelem *) l); 09619 if (!strcmp(myrpt->cmdnode,l->name)) 09620 myrpt->cmdnode[0] = 0; 09621 rpt_mutex_unlock(&myrpt->lock); 09622 if (l->name[0] != '0') 09623 { 09624 if (!l->hasconnected) 09625 rpt_telemetry(myrpt,CONNFAIL,l); 09626 else rpt_telemetry(myrpt,REMDISC,l); 09627 } 09628 if (myrpt->p.archivedir) 09629 { 09630 char str[100]; 09631 09632 if (!l->hasconnected) 09633 sprintf(str,"LINKFAIL,%s",l->name); 09634 else 09635 sprintf(str,"LINKDISC,%s",l->name); 09636 donodelog(myrpt,str); 09637 } 09638 /* hang-up on call to device */ 09639 ast_hangup(l->pchan); 09640 free(l); 09641 rpt_mutex_lock(&myrpt->lock); 09642 break; 09643 } 09644 if ((!l->chan) && (!l->disctime) && (!l->outbound)) 09645 { 09646 /* remove from queue */ 09647 remque((struct qelem *) l); 09648 if (!strcmp(myrpt->cmdnode,l->name)) 09649 myrpt->cmdnode[0] = 0; 09650 rpt_mutex_unlock(&myrpt->lock); 09651 if (l->name[0] != '0') 09652 { 09653 rpt_telemetry(myrpt,REMDISC,l); 09654 } 09655 if (myrpt->p.archivedir) 09656 { 09657 char str[100]; 09658 09659 sprintf(str,"LINKDISC,%s",l->name); 09660 donodelog(myrpt,str); 09661 } 09662 /* hang-up on call to device */ 09663 ast_hangup(l->pchan); 09664 free(l); 09665 rpt_mutex_lock(&myrpt->lock); 09666 break; 09667 } 09668 l = l->next; 09669 } 09670 if(totx){ 09671 myrpt->dailytxtime += elap; 09672 myrpt->totaltxtime += elap; 09673 } 09674 i = myrpt->tailtimer; 09675 if (myrpt->tailtimer) myrpt->tailtimer -= elap; 09676 if (myrpt->tailtimer < 0) myrpt->tailtimer = 0; 09677 if((i) && (myrpt->tailtimer == 0)) 09678 myrpt->tailevent = 1; 09679 if ((!myrpt->p.s[myrpt->p.sysstate_cur].totdisable) && myrpt->totimer) myrpt->totimer -= elap; 09680 if (myrpt->totimer < 0) myrpt->totimer = 0; 09681 if (myrpt->idtimer) myrpt->idtimer -= elap; 09682 if (myrpt->idtimer < 0) myrpt->idtimer = 0; 09683 if (myrpt->tmsgtimer) myrpt->tmsgtimer -= elap; 09684 if (myrpt->tmsgtimer < 0) myrpt->tmsgtimer = 0; 09685 /* do macro timers */ 09686 if (myrpt->macrotimer) myrpt->macrotimer -= elap; 09687 if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; 09688 /* do local dtmf timer */ 09689 if (myrpt->dtmf_local_timer) 09690 { 09691 if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap; 09692 if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1; 09693 } 09694 do_dtmf_local(myrpt,0); 09695 /* Execute scheduler appx. every 2 tenths of a second */ 09696 if (myrpt->skedtimer <= 0){ 09697 myrpt->skedtimer = 200; 09698 do_scheduler(myrpt); 09699 } 09700 else 09701 myrpt->skedtimer -=elap; 09702 if (!ms) 09703 { 09704 rpt_mutex_unlock(&myrpt->lock); 09705 continue; 09706 } 09707 c = myrpt->macrobuf[0]; 09708 time(&t); 09709 if (c && (!myrpt->macrotimer) && 09710 starttime && (t > (starttime + START_DELAY))) 09711 { 09712 myrpt->macrotimer = MACROTIME; 09713 memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1); 09714 if ((c == 'p') || (c == 'P')) 09715 myrpt->macrotimer = MACROPTIME; 09716 rpt_mutex_unlock(&myrpt->lock); 09717 if (myrpt->p.archivedir) 09718 { 09719 char str[100]; 09720 09721 sprintf(str,"DTMF(M),MAIN,%c",c); 09722 donodelog(myrpt,str); 09723 } 09724 local_dtmf_helper(myrpt,c); 09725 } else rpt_mutex_unlock(&myrpt->lock); 09726 if (who == myrpt->rxchannel) /* if it was a read from rx */ 09727 { 09728 int ismuted; 09729 09730 f = ast_read(myrpt->rxchannel); 09731 if (!f) 09732 { 09733 if (debug) printf("@@@@ rpt:Hung Up\n"); 09734 break; 09735 } 09736 if (f->frametype == AST_FRAME_VOICE) 09737 { 09738 #ifdef _MDC_DECODE_H_ 09739 unsigned char ubuf[2560]; 09740 short *sp; 09741 int n; 09742 #endif 09743 09744 if ((!myrpt->localtx) && (!myrpt->p.linktolink)) { 09745 memset(f->data,0,f->datalen); 09746 } 09747 09748 #ifdef _MDC_DECODE_H_ 09749 sp = (short *) f->data; 09750 /* convert block to unsigned char */ 09751 for(n = 0; n < f->datalen / 2; n++) 09752 { 09753 ubuf[n] = (*sp++ >> 8) + 128; 09754 } 09755 n = mdc_decoder_process_samples(myrpt->mdc,ubuf,f->datalen / 2); 09756 if (n == 1) 09757 { 09758 unsigned char op,arg; 09759 unsigned short unitID; 09760 09761 mdc_decoder_get_packet(myrpt->mdc,&op,&arg,&unitID); 09762 if (debug > 2) 09763 { 09764 ast_log(LOG_NOTICE,"Got (single-length) packet:\n"); 09765 ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n", 09766 op & 255,arg & 255,unitID); 09767 } 09768 if ((op == 1) && (arg == 0)) 09769 { 09770 myrpt->lastunit = unitID; 09771 mdc1200_notify(myrpt,NULL,myrpt->lastunit); 09772 mdc1200_send(myrpt,myrpt->lastunit); 09773 } 09774 } 09775 if ((debug > 2) && (i == 2)) 09776 { 09777 unsigned char op,arg,ex1,ex2,ex3,ex4; 09778 unsigned short unitID; 09779 09780 mdc_decoder_get_double_packet(myrpt->mdc,&op,&arg,&unitID, 09781 &ex1,&ex2,&ex3,&ex4); 09782 ast_log(LOG_NOTICE,"Got (double-length) packet:\n"); 09783 ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n", 09784 op & 255,arg & 255,unitID); 09785 ast_log(LOG_NOTICE,"ex1: %02x, ex2: %02x, ex3: %02x, ex4: %02x\n", 09786 ex1 & 255, ex2 & 255, ex3 & 255, ex4 & 255); 09787 } 09788 #endif 09789 #ifdef __RPT_NOTCH 09790 /* apply inbound filters, if any */ 09791 rpt_filter(myrpt,f->data,f->datalen / 2); 09792 #endif 09793 if (ioctl(myrpt->zaprxchannel->fds[0], ZT_GETCONFMUTE, &ismuted) == -1) 09794 { 09795 ismuted = 0; 09796 } 09797 if (dtmfed) ismuted = 1; 09798 dtmfed = 0; 09799 if (ismuted) 09800 { 09801 memset(f->data,0,f->datalen); 09802 if (myrpt->lastf1) 09803 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09804 if (myrpt->lastf2) 09805 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09806 } 09807 if (f) f2 = ast_frdup(f); 09808 else f2 = NULL; 09809 f1 = myrpt->lastf2; 09810 myrpt->lastf2 = myrpt->lastf1; 09811 myrpt->lastf1 = f2; 09812 if (ismuted) 09813 { 09814 if (myrpt->lastf1) 09815 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09816 if (myrpt->lastf2) 09817 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09818 } 09819 if (f1) 09820 { 09821 ast_write(myrpt->pchannel,f1); 09822 ast_frfree(f1); 09823 } 09824 } 09825 #ifndef OLD_ASTERISK 09826 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 09827 { 09828 if (myrpt->lastf1) 09829 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09830 if (myrpt->lastf2) 09831 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09832 dtmfed = 1; 09833 } 09834 #endif 09835 else if (f->frametype == AST_FRAME_DTMF) 09836 { 09837 c = (char) f->subclass; /* get DTMF char */ 09838 ast_frfree(f); 09839 if (myrpt->lastf1) 09840 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09841 if (myrpt->lastf2) 09842 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09843 dtmfed = 1; 09844 if (!myrpt->keyed) continue; 09845 c = func_xlat(myrpt,c,&myrpt->p.inxlat); 09846 if (c) local_dtmf_helper(myrpt,c); 09847 continue; 09848 } 09849 else if (f->frametype == AST_FRAME_CONTROL) 09850 { 09851 if (f->subclass == AST_CONTROL_HANGUP) 09852 { 09853 if (debug) printf("@@@@ rpt:Hung Up\n"); 09854 ast_frfree(f); 09855 break; 09856 } 09857 /* if RX key */ 09858 if (f->subclass == AST_CONTROL_RADIO_KEY) 09859 { 09860 if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink)) 09861 { 09862 if (debug == 7) printf("@@@@ rx key\n"); 09863 myrpt->keyed = 1; 09864 } 09865 if (myrpt->p.archivedir) 09866 { 09867 donodelog(myrpt,"RXKEY,MAIN"); 09868 } 09869 } 09870 /* if RX un-key */ 09871 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 09872 { 09873 if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink)) 09874 { 09875 if (debug == 7) printf("@@@@ rx un-key\n"); 09876 if(myrpt->p.duplex && myrpt->keyed) { 09877 rpt_telemetry(myrpt,UNKEY,NULL); 09878 } 09879 } 09880 myrpt->keyed = 0; 09881 if (myrpt->p.archivedir) 09882 { 09883 donodelog(myrpt,"RXUNKEY,MAIN"); 09884 } 09885 } 09886 } 09887 ast_frfree(f); 09888 continue; 09889 } 09890 if (who == myrpt->pchannel) /* if it was a read from pseudo */ 09891 { 09892 f = ast_read(myrpt->pchannel); 09893 if (!f) 09894 { 09895 if (debug) printf("@@@@ rpt:Hung Up\n"); 09896 break; 09897 } 09898 if (f->frametype == AST_FRAME_VOICE) 09899 { 09900 ast_write(myrpt->txpchannel,f); 09901 } 09902 if (f->frametype == AST_FRAME_CONTROL) 09903 { 09904 if (f->subclass == AST_CONTROL_HANGUP) 09905 { 09906 if (debug) printf("@@@@ rpt:Hung Up\n"); 09907 ast_frfree(f); 09908 break; 09909 } 09910 } 09911 ast_frfree(f); 09912 continue; 09913 } 09914 if (who == myrpt->txchannel) /* if it was a read from tx */ 09915 { 09916 f = ast_read(myrpt->txchannel); 09917 if (!f) 09918 { 09919 if (debug) printf("@@@@ rpt:Hung Up\n"); 09920 break; 09921 } 09922 if (f->frametype == AST_FRAME_CONTROL) 09923 { 09924 if (f->subclass == AST_CONTROL_HANGUP) 09925 { 09926 if (debug) printf("@@@@ rpt:Hung Up\n"); 09927 ast_frfree(f); 09928 break; 09929 } 09930 } 09931 ast_frfree(f); 09932 continue; 09933 } 09934 if (who == myrpt->zaptxchannel) /* if it was a read from pseudo-tx */ 09935 { 09936 f = ast_read(myrpt->zaptxchannel); 09937 if (!f) 09938 { 09939 if (debug) printf("@@@@ rpt:Hung Up\n"); 09940 break; 09941 } 09942 if (f->frametype == AST_FRAME_VOICE) 09943 { 09944 ast_write(myrpt->txchannel,f); 09945 } 09946 if (f->frametype == AST_FRAME_CONTROL) 09947 { 09948 if (f->subclass == AST_CONTROL_HANGUP) 09949 { 09950 if (debug) printf("@@@@ rpt:Hung Up\n"); 09951 ast_frfree(f); 09952 break; 09953 } 09954 } 09955 ast_frfree(f); 09956 continue; 09957 } 09958 toexit = 0; 09959 rpt_mutex_lock(&myrpt->lock); 09960 l = myrpt->links.next; 09961 while(l != &myrpt->links) 09962 { 09963 if (l->disctime) 09964 { 09965 l = l->next; 09966 continue; 09967 } 09968 if (who == l->chan) /* if it was a read from rx */ 09969 { 09970 int remnomute; 09971 09972 remrx = 0; 09973 /* see if any other links are receiving */ 09974 m = myrpt->links.next; 09975 while(m != &myrpt->links) 09976 { 09977 /* if not us, count it */ 09978 if ((m != l) && (m->lastrx)) remrx = 1; 09979 m = m->next; 09980 } 09981 rpt_mutex_unlock(&myrpt->lock); 09982 remnomute = myrpt->localtx && 09983 (!(myrpt->cmdnode[0] || 09984 (myrpt->dtmfidx > -1))); 09985 totx = (((l->isremote) ? (remnomute) : 09986 myrpt->exttx) || remrx) && l->mode; 09987 if (l->phonemode == 0 && l->chan && (l->lasttx != totx)) 09988 { 09989 if (totx) 09990 { 09991 ast_indicate(l->chan,AST_CONTROL_RADIO_KEY); 09992 } 09993 else 09994 { 09995 ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 09996 } 09997 if (myrpt->p.archivedir) 09998 { 09999 char str[100]; 10000 10001 if (totx) 10002 sprintf(str,"TXKEY,%s",l->name); 10003 else 10004 sprintf(str,"TXUNKEY,%s",l->name); 10005 donodelog(myrpt,str); 10006 } 10007 } 10008 l->lasttx = totx; 10009 f = ast_read(l->chan); 10010 if (!f) 10011 { 10012 rpt_mutex_lock(&myrpt->lock); 10013 __kickshort(myrpt); 10014 rpt_mutex_unlock(&myrpt->lock); 10015 if ((!l->disced) && (!l->outbound)) 10016 { 10017 if ((l->name[0] == '0') || l->isremote) 10018 l->disctime = 1; 10019 else 10020 l->disctime = DISC_TIME; 10021 rpt_mutex_lock(&myrpt->lock); 10022 ast_hangup(l->chan); 10023 l->chan = 0; 10024 break; 10025 } 10026 10027 if (l->retrytimer) 10028 { 10029 ast_hangup(l->chan); 10030 l->chan = 0; 10031 rpt_mutex_lock(&myrpt->lock); 10032 break; 10033 } 10034 if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected)) 10035 { 10036 rpt_mutex_lock(&myrpt->lock); 10037 if (l->chan) ast_hangup(l->chan); 10038 l->chan = 0; 10039 l->hasconnected = 1; 10040 l->retrytimer = RETRY_TIMER_MS; 10041 l->elaptime = 0; 10042 l->connecttime = 0; 10043 l->thisconnected = 0; 10044 break; 10045 } 10046 rpt_mutex_lock(&myrpt->lock); 10047 /* remove from queue */ 10048 remque((struct qelem *) l); 10049 if (!strcmp(myrpt->cmdnode,l->name)) 10050 myrpt->cmdnode[0] = 0; 10051 __kickshort(myrpt); 10052 rpt_mutex_unlock(&myrpt->lock); 10053 if (!l->hasconnected) 10054 rpt_telemetry(myrpt,CONNFAIL,l); 10055 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 10056 if (myrpt->p.archivedir) 10057 { 10058 char str[100]; 10059 10060 if (!l->hasconnected) 10061 sprintf(str,"LINKFAIL,%s",l->name); 10062 else 10063 sprintf(str,"LINKDISC,%s",l->name); 10064 donodelog(myrpt,str); 10065 } 10066 if (l->lastf1) ast_frfree(l->lastf1); 10067 l->lastf1 = NULL; 10068 if (l->lastf2) ast_frfree(l->lastf2); 10069 l->lastf2 = NULL; 10070 /* hang-up on call to device */ 10071 ast_hangup(l->chan); 10072 ast_hangup(l->pchan); 10073 free(l); 10074 rpt_mutex_lock(&myrpt->lock); 10075 break; 10076 } 10077 if (f->frametype == AST_FRAME_VOICE) 10078 { 10079 int ismuted; 10080 10081 if (l->phonemode) 10082 { 10083 if (ioctl(l->chan->fds[0], ZT_GETCONFMUTE, &ismuted) == -1) 10084 { 10085 ismuted = 0; 10086 } 10087 /* if not receiving, zero-out audio */ 10088 ismuted |= (!l->lastrx); 10089 if (l->dtmfed && l->phonemode) ismuted = 1; 10090 l->dtmfed = 0; 10091 if (ismuted) 10092 { 10093 memset(f->data,0,f->datalen); 10094 if (l->lastf1) 10095 memset(l->lastf1->data,0,l->lastf1->datalen); 10096 if (l->lastf2) 10097 memset(l->lastf2->data,0,l->lastf2->datalen); 10098 } 10099 if (f) f2 = ast_frdup(f); 10100 else f2 = NULL; 10101 f1 = l->lastf2; 10102 l->lastf2 = l->lastf1; 10103 l->lastf1 = f2; 10104 if (ismuted) 10105 { 10106 if (l->lastf1) 10107 memset(l->lastf1->data,0,l->lastf1->datalen); 10108 if (l->lastf2) 10109 memset(l->lastf2->data,0,l->lastf2->datalen); 10110 } 10111 if (f1) 10112 { 10113 ast_write(l->pchan,f1); 10114 ast_frfree(f1); 10115 } 10116 } 10117 else 10118 { 10119 if (!l->lastrx) 10120 memset(f->data,0,f->datalen); 10121 ast_write(l->pchan,f); 10122 } 10123 } 10124 #ifndef OLD_ASTERISK 10125 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 10126 { 10127 if (l->lastf1) 10128 memset(l->lastf1->data,0,l->lastf1->datalen); 10129 if (l->lastf2) 10130 memset(l->lastf2->data,0,l->lastf2->datalen); 10131 l->dtmfed = 1; 10132 } 10133 #endif 10134 10135 if (f->frametype == AST_FRAME_TEXT) 10136 { 10137 handle_link_data(myrpt,l,f->data); 10138 } 10139 if (f->frametype == AST_FRAME_DTMF) 10140 { 10141 if (l->lastf1) 10142 memset(l->lastf1->data,0,l->lastf1->datalen); 10143 if (l->lastf2) 10144 memset(l->lastf2->data,0,l->lastf2->datalen); 10145 l->dtmfed = 1; 10146 handle_link_phone_dtmf(myrpt,l,f->subclass); 10147 } 10148 if (f->frametype == AST_FRAME_CONTROL) 10149 { 10150 if (f->subclass == AST_CONTROL_ANSWER) 10151 { 10152 char lconnected = l->connected; 10153 10154 __kickshort(myrpt); 10155 l->connected = 1; 10156 l->hasconnected = 1; 10157 l->thisconnected = 1; 10158 l->elaptime = -1; 10159 if (!l->isremote) l->retries = 0; 10160 if (!lconnected) 10161 { 10162 rpt_telemetry(myrpt,CONNECTED,l); 10163 if (myrpt->p.archivedir) 10164 { 10165 char str[100]; 10166 10167 if (l->mode) 10168 sprintf(str,"LINKTRX,%s",l->name); 10169 else 10170 sprintf(str,"LINKMONITOR,%s",l->name); 10171 donodelog(myrpt,str); 10172 } 10173 } 10174 else 10175 l->reconnects++; 10176 } 10177 /* if RX key */ 10178 if (f->subclass == AST_CONTROL_RADIO_KEY) 10179 { 10180 if (debug == 7 ) printf("@@@@ rx key\n"); 10181 l->lastrx = 1; 10182 l->rerxtimer = 0; 10183 if (myrpt->p.archivedir && (!l->lastrx1)) 10184 { 10185 char str[100]; 10186 10187 l->lastrx1 = 1; 10188 sprintf(str,"RXKEY,%s",l->name); 10189 donodelog(myrpt,str); 10190 } 10191 } 10192 /* if RX un-key */ 10193 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 10194 { 10195 if (debug == 7) printf("@@@@ rx un-key\n"); 10196 l->lastrx = 0; 10197 l->rerxtimer = 0; 10198 if(myrpt->p.duplex) 10199 rpt_telemetry(myrpt,LINKUNKEY,l); 10200 if (myrpt->p.archivedir && (l->lastrx1)) 10201 { 10202 char str[100]; 10203 10204 l->lastrx1 = 0; 10205 sprintf(str,"RXUNKEY,%s",l->name); 10206 donodelog(myrpt,str); 10207 } 10208 } 10209 if (f->subclass == AST_CONTROL_HANGUP) 10210 { 10211 ast_frfree(f); 10212 rpt_mutex_lock(&myrpt->lock); 10213 __kickshort(myrpt); 10214 rpt_mutex_unlock(&myrpt->lock); 10215 if ((!l->outbound) && (!l->disced)) 10216 { 10217 if ((l->name[0] == '0') || l->isremote) 10218 l->disctime = 1; 10219 else 10220 l->disctime = DISC_TIME; 10221 rpt_mutex_lock(&myrpt->lock); 10222 ast_hangup(l->chan); 10223 l->chan = 0; 10224 break; 10225 } 10226 if (l->retrytimer) 10227 { 10228 if (l->chan) ast_hangup(l->chan); 10229 l->chan = 0; 10230 rpt_mutex_lock(&myrpt->lock); 10231 break; 10232 } 10233 if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected)) 10234 { 10235 rpt_mutex_lock(&myrpt->lock); 10236 if (l->chan) ast_hangup(l->chan); 10237 l->chan = 0; 10238 l->hasconnected = 1; 10239 l->elaptime = 0; 10240 l->retrytimer = RETRY_TIMER_MS; 10241 l->connecttime = 0; 10242 l->thisconnected = 0; 10243 break; 10244 } 10245 rpt_mutex_lock(&myrpt->lock); 10246 /* remove from queue */ 10247 remque((struct qelem *) l); 10248 if (!strcmp(myrpt->cmdnode,l->name)) 10249 myrpt->cmdnode[0] = 0; 10250 __kickshort(myrpt); 10251 rpt_mutex_unlock(&myrpt->lock); 10252 if (!l->hasconnected) 10253 rpt_telemetry(myrpt,CONNFAIL,l); 10254 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 10255 if (myrpt->p.archivedir) 10256 { 10257 char str[100]; 10258 10259 if (!l->hasconnected) 10260 sprintf(str,"LINKFAIL,%s",l->name); 10261 else 10262 sprintf(str,"LINKDISC,%s",l->name); 10263 donodelog(myrpt,str); 10264 } 10265 if (l->lastf1) ast_frfree(l->lastf1); 10266 l->lastf1 = NULL; 10267 if (l->lastf2) ast_frfree(l->lastf2); 10268 l->lastf2 = NULL; 10269 /* hang-up on call to device */ 10270 ast_hangup(l->chan); 10271 ast_hangup(l->pchan); 10272 free(l); 10273 rpt_mutex_lock(&myrpt->lock); 10274 break; 10275 } 10276 } 10277 ast_frfree(f); 10278 rpt_mutex_lock(&myrpt->lock); 10279 break; 10280 } 10281 if (who == l->pchan) 10282 { 10283 rpt_mutex_unlock(&myrpt->lock); 10284 f = ast_read(l->pchan); 10285 if (!f) 10286 { 10287 if (debug) printf("@@@@ rpt:Hung Up\n"); 10288 toexit = 1; 10289 rpt_mutex_lock(&myrpt->lock); 10290 break; 10291 } 10292 if (f->frametype == AST_FRAME_VOICE) 10293 { 10294 if (l->chan) ast_write(l->chan,f); 10295 } 10296 if (f->frametype == AST_FRAME_CONTROL) 10297 { 10298 if (f->subclass == AST_CONTROL_HANGUP) 10299 { 10300 if (debug) printf("@@@@ rpt:Hung Up\n"); 10301 ast_frfree(f); 10302 toexit = 1; 10303 rpt_mutex_lock(&myrpt->lock); 10304 break; 10305 } 10306 } 10307 ast_frfree(f); 10308 rpt_mutex_lock(&myrpt->lock); 10309 break; 10310 } 10311 l = l->next; 10312 } 10313 rpt_mutex_unlock(&myrpt->lock); 10314 if (toexit) break; 10315 if (who == myrpt->monchannel) 10316 { 10317 f = ast_read(myrpt->monchannel); 10318 if (!f) 10319 { 10320 if (debug) printf("@@@@ rpt:Hung Up\n"); 10321 break; 10322 } 10323 if (f->frametype == AST_FRAME_VOICE) 10324 { 10325 if (myrpt->monstream) 10326 ast_writestream(myrpt->monstream,f); 10327 } 10328 if (f->frametype == AST_FRAME_CONTROL) 10329 { 10330 if (f->subclass == AST_CONTROL_HANGUP) 10331 { 10332 if (debug) printf("@@@@ rpt:Hung Up\n"); 10333 ast_frfree(f); 10334 break; 10335 } 10336 } 10337 ast_frfree(f); 10338 continue; 10339 } 10340 if (who == myrpt->txpchannel) /* if it was a read from remote tx */ 10341 { 10342 f = ast_read(myrpt->txpchannel); 10343 if (!f) 10344 { 10345 if (debug) printf("@@@@ rpt:Hung Up\n"); 10346 break; 10347 } 10348 if (f->frametype == AST_FRAME_CONTROL) 10349 { 10350 if (f->subclass == AST_CONTROL_HANGUP) 10351 { 10352 if (debug) printf("@@@@ rpt:Hung Up\n"); 10353 ast_frfree(f); 10354 break; 10355 } 10356 } 10357 ast_frfree(f); 10358 continue; 10359 } 10360 } 10361 usleep(100000); 10362 ast_hangup(myrpt->pchannel); 10363 ast_hangup(myrpt->monchannel); 10364 ast_hangup(myrpt->txpchannel); 10365 if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel); 10366 if (myrpt->zaptxchannel != myrpt->txchannel) ast_hangup(myrpt->zaptxchannel); 10367 if (myrpt->lastf1) ast_frfree(myrpt->lastf1); 10368 myrpt->lastf1 = NULL; 10369 if (myrpt->lastf2) ast_frfree(myrpt->lastf2); 10370 myrpt->lastf2 = NULL; 10371 ast_hangup(myrpt->rxchannel); 10372 rpt_mutex_lock(&myrpt->lock); 10373 l = myrpt->links.next; 10374 while(l != &myrpt->links) 10375 { 10376 struct rpt_link *ll = l; 10377 /* remove from queue */ 10378 remque((struct qelem *) l); 10379 /* hang-up on call to device */ 10380 if (l->chan) ast_hangup(l->chan); 10381 ast_hangup(l->pchan); 10382 l = l->next; 10383 free(ll); 10384 } 10385 rpt_mutex_unlock(&myrpt->lock); 10386 if (debug) printf("@@@@ rpt:Hung up channel\n"); 10387 myrpt->rpt_thread = AST_PTHREADT_STOP; 10388 pthread_exit(NULL); 10389 return NULL; 10390 }
static void* rpt_call | ( | void * | this | ) | [static] |
Definition at line 4166 of file app_rpt.c.
References rpt::acctcode, ast_callerid_parse(), AST_CDR_FLAG_POST_DISABLED, ast_cdr_setaccount(), ast_channel_undefer_dtmf(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, ast_hangup(), ast_log(), ast_pbx_start(), ast_queue_frame(), ast_request(), ast_safe_sleep(), ast_senddigit(), ast_set_flag, ast_softhangup(), AST_SOFTHANGUP_DEV, rpt::callmode, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, rpt::cidx, rpt::conf, ast_channel::context, rpt::duplex, rpt::exten, ast_channel::exten, ast_channel::fds, free, rpt::lock, LOG_WARNING, MSWAIT, rpt::mydtmf, name, rpt::ourcallerid, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchquiet, ast_channel::pbx, rpt::pchannel, ast_channel::priority, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), strdup, ast_frame::subclass, TERM, and rpt::tonezone.
Referenced by function_autopatchup(), and local_dtmf_helper().
04167 { 04168 ZT_CONFINFO ci; /* conference info */ 04169 struct rpt *myrpt = (struct rpt *)this; 04170 int res; 04171 int stopped,congstarted,dialtimer,lastcidx,aborted; 04172 struct ast_channel *mychannel,*genchannel; 04173 04174 04175 myrpt->mydtmf = 0; 04176 /* allocate a pseudo-channel thru asterisk */ 04177 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04178 if (!mychannel) 04179 { 04180 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 04181 pthread_exit(NULL); 04182 } 04183 #ifdef AST_CDR_FLAG_POST_DISABLED 04184 ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED); 04185 #endif 04186 ci.chan = 0; 04187 ci.confno = myrpt->conf; /* use the pseudo conference */ 04188 ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER 04189 | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 04190 /* first put the channel on the conference */ 04191 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 04192 { 04193 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04194 ast_hangup(mychannel); 04195 myrpt->callmode = 0; 04196 pthread_exit(NULL); 04197 } 04198 /* allocate a pseudo-channel thru asterisk */ 04199 genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04200 if (!genchannel) 04201 { 04202 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 04203 ast_hangup(mychannel); 04204 pthread_exit(NULL); 04205 } 04206 #ifdef AST_CDR_FLAG_POST_DISABLED 04207 ast_set_flag(genchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 04208 #endif 04209 ci.chan = 0; 04210 ci.confno = myrpt->conf; 04211 ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER 04212 | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 04213 /* first put the channel on the conference */ 04214 if (ioctl(genchannel->fds[0],ZT_SETCONF,&ci) == -1) 04215 { 04216 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04217 ast_hangup(mychannel); 04218 ast_hangup(genchannel); 04219 myrpt->callmode = 0; 04220 pthread_exit(NULL); 04221 } 04222 if (myrpt->p.tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->p.tonezone) == -1)) 04223 { 04224 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone); 04225 ast_hangup(mychannel); 04226 ast_hangup(genchannel); 04227 myrpt->callmode = 0; 04228 pthread_exit(NULL); 04229 } 04230 if (myrpt->p.tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->p.tonezone) == -1)) 04231 { 04232 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone); 04233 ast_hangup(mychannel); 04234 ast_hangup(genchannel); 04235 myrpt->callmode = 0; 04236 pthread_exit(NULL); 04237 } 04238 /* start dialtone if patchquiet is 0. Special patch modes don't send dial tone */ 04239 if ((!myrpt->patchquiet) && (tone_zone_play_tone(mychannel->fds[0],ZT_TONE_DIALTONE) < 0)) 04240 { 04241 ast_log(LOG_WARNING, "Cannot start dialtone\n"); 04242 ast_hangup(mychannel); 04243 ast_hangup(genchannel); 04244 myrpt->callmode = 0; 04245 pthread_exit(NULL); 04246 } 04247 stopped = 0; 04248 congstarted = 0; 04249 dialtimer = 0; 04250 lastcidx = 0; 04251 aborted = 0; 04252 04253 04254 while ((myrpt->callmode == 1) || (myrpt->callmode == 4)) 04255 { 04256 04257 if((myrpt->patchdialtime)&&(myrpt->callmode == 1)&&(myrpt->cidx != lastcidx)){ 04258 dialtimer = 0; 04259 lastcidx = myrpt->cidx; 04260 } 04261 04262 if((myrpt->patchdialtime)&&(dialtimer >= myrpt->patchdialtime)){ 04263 rpt_mutex_lock(&myrpt->lock); 04264 aborted = 1; 04265 myrpt->callmode = 0; 04266 rpt_mutex_unlock(&myrpt->lock); 04267 break; 04268 } 04269 04270 if ((!myrpt->patchquiet) && (!stopped) && (myrpt->callmode == 1) && (myrpt->cidx > 0)) 04271 { 04272 stopped = 1; 04273 /* stop dial tone */ 04274 tone_zone_play_tone(mychannel->fds[0],-1); 04275 } 04276 if (myrpt->callmode == 4) 04277 { 04278 if(!congstarted){ 04279 congstarted = 1; 04280 /* start congestion tone */ 04281 tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION); 04282 } 04283 } 04284 res = ast_safe_sleep(mychannel, MSWAIT); 04285 if (res < 0) 04286 { 04287 ast_hangup(mychannel); 04288 ast_hangup(genchannel); 04289 rpt_mutex_lock(&myrpt->lock); 04290 myrpt->callmode = 0; 04291 rpt_mutex_unlock(&myrpt->lock); 04292 pthread_exit(NULL); 04293 } 04294 dialtimer += MSWAIT; 04295 } 04296 /* stop any tone generation */ 04297 tone_zone_play_tone(mychannel->fds[0],-1); 04298 /* end if done */ 04299 if (!myrpt->callmode) 04300 { 04301 ast_hangup(mychannel); 04302 ast_hangup(genchannel); 04303 rpt_mutex_lock(&myrpt->lock); 04304 myrpt->callmode = 0; 04305 rpt_mutex_unlock(&myrpt->lock); 04306 if((!myrpt->patchquiet) && aborted) 04307 rpt_telemetry(myrpt, TERM, NULL); 04308 pthread_exit(NULL); 04309 } 04310 04311 if (myrpt->p.ourcallerid && *myrpt->p.ourcallerid){ 04312 char *name, *loc, *instr; 04313 instr = strdup(myrpt->p.ourcallerid); 04314 if(instr){ 04315 ast_callerid_parse(instr, &name, &loc); 04316 if(loc){ 04317 if(mychannel->cid.cid_num) 04318 free(mychannel->cid.cid_num); 04319 mychannel->cid.cid_num = strdup(loc); 04320 } 04321 if(name){ 04322 if(mychannel->cid.cid_name) 04323 free(mychannel->cid.cid_name); 04324 mychannel->cid.cid_name = strdup(name); 04325 } 04326 free(instr); 04327 } 04328 } 04329 04330 ast_copy_string(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1); 04331 ast_copy_string(mychannel->context, myrpt->patchcontext, sizeof(mychannel->context) - 1); 04332 04333 if (myrpt->p.acctcode) 04334 ast_cdr_setaccount(mychannel,myrpt->p.acctcode); 04335 mychannel->priority = 1; 04336 ast_channel_undefer_dtmf(mychannel); 04337 if (ast_pbx_start(mychannel) < 0) 04338 { 04339 ast_log(LOG_WARNING, "Unable to start PBX!!\n"); 04340 ast_hangup(mychannel); 04341 ast_hangup(genchannel); 04342 rpt_mutex_lock(&myrpt->lock); 04343 myrpt->callmode = 0; 04344 rpt_mutex_unlock(&myrpt->lock); 04345 pthread_exit(NULL); 04346 } 04347 usleep(10000); 04348 rpt_mutex_lock(&myrpt->lock); 04349 myrpt->callmode = 3; 04350 /* set appropriate conference for the pseudo */ 04351 ci.chan = 0; 04352 ci.confno = myrpt->conf; 04353 ci.confmode = (myrpt->p.duplex == 2) ? ZT_CONF_CONFANNMON : 04354 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 04355 /* first put the channel on the conference in announce mode */ 04356 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 04357 { 04358 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04359 ast_hangup(mychannel); 04360 ast_hangup(genchannel); 04361 myrpt->callmode = 0; 04362 pthread_exit(NULL); 04363 } 04364 while(myrpt->callmode) 04365 { 04366 if ((!mychannel->pbx) && (myrpt->callmode != 4)) 04367 { 04368 if(myrpt->patchfarenddisconnect){ /* If patch is setup for far end disconnect */ 04369 myrpt->callmode = 0; 04370 if(!myrpt->patchquiet){ 04371 rpt_mutex_unlock(&myrpt->lock); 04372 rpt_telemetry(myrpt, TERM, NULL); 04373 rpt_mutex_lock(&myrpt->lock); 04374 } 04375 } 04376 else{ /* Send congestion until patch is downed by command */ 04377 myrpt->callmode = 4; 04378 rpt_mutex_unlock(&myrpt->lock); 04379 /* start congestion tone */ 04380 tone_zone_play_tone(genchannel->fds[0],ZT_TONE_CONGESTION); 04381 rpt_mutex_lock(&myrpt->lock); 04382 } 04383 } 04384 if (myrpt->mydtmf) 04385 { 04386 struct ast_frame wf = {AST_FRAME_DTMF, } ; 04387 wf.subclass = myrpt->mydtmf; 04388 rpt_mutex_unlock(&myrpt->lock); 04389 ast_queue_frame(mychannel,&wf); 04390 ast_senddigit(genchannel,myrpt->mydtmf); 04391 rpt_mutex_lock(&myrpt->lock); 04392 myrpt->mydtmf = 0; 04393 } 04394 rpt_mutex_unlock(&myrpt->lock); 04395 usleep(MSWAIT * 1000); 04396 rpt_mutex_lock(&myrpt->lock); 04397 } 04398 rpt_mutex_unlock(&myrpt->lock); 04399 tone_zone_play_tone(genchannel->fds[0],-1); 04400 if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV); 04401 ast_hangup(genchannel); 04402 rpt_mutex_lock(&myrpt->lock); 04403 myrpt->callmode = 0; 04404 rpt_mutex_unlock(&myrpt->lock); 04405 /* set appropriate conference for the pseudo */ 04406 ci.chan = 0; 04407 ci.confno = myrpt->conf; 04408 ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON : 04409 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 04410 /* first put the channel on the conference in announce mode */ 04411 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 04412 { 04413 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04414 } 04415 pthread_exit(NULL); 04416 }
static int rpt_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1972 of file app_rpt.c.
References ast_cli(), myatoi(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01973 { 01974 int newlevel; 01975 01976 if (argc != 4) 01977 return RESULT_SHOWUSAGE; 01978 newlevel = myatoi(argv[3]); 01979 if((newlevel < 0) || (newlevel > 7)) 01980 return RESULT_SHOWUSAGE; 01981 if(newlevel) 01982 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel); 01983 else 01984 ast_cli(fd, "app_rpt Debugging disabled\n"); 01985 01986 debug = newlevel; 01987 return RESULT_SUCCESS; 01988 }
static int rpt_do_dump | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1994 of file app_rpt.c.
References ast_cli(), rpt::disgorgetime, name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and rpt_vars.
01995 { 01996 int i; 01997 01998 if (argc != 3) 01999 return RESULT_SHOWUSAGE; 02000 02001 for(i = 0; i < nrpts; i++) 02002 { 02003 if (!strcmp(argv[2],rpt_vars[i].name)) 02004 { 02005 rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 02006 ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]); 02007 return RESULT_SUCCESS; 02008 } 02009 } 02010 return RESULT_FAILURE; 02011 }
static int rpt_do_fun | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2414 of file app_rpt.c.
References ast_cli(), busy, rpt::lock, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, name, RESULT_FAILURE, RESULT_SHOWUSAGE, rpt_mutex_lock, rpt_mutex_unlock, and rpt_vars.
02415 { 02416 int i,busy=0; 02417 02418 if (argc != 4) return RESULT_SHOWUSAGE; 02419 02420 for(i = 0; i < nrpts; i++){ 02421 if(!strcmp(argv[2], rpt_vars[i].name)){ 02422 struct rpt *myrpt = &rpt_vars[i]; 02423 rpt_mutex_lock(&myrpt->lock); 02424 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(argv[3])){ 02425 rpt_mutex_unlock(&myrpt->lock); 02426 busy=1; 02427 } 02428 if(!busy){ 02429 myrpt->macrotimer = MACROTIME; 02430 strncat(myrpt->macrobuf,argv[3],MAXMACRO - 1); 02431 } 02432 rpt_mutex_unlock(&myrpt->lock); 02433 } 02434 } 02435 if(busy){ 02436 ast_cli(fd, "Function decoder busy"); 02437 } 02438 return RESULT_FAILURE; 02439 }
static int rpt_do_lstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2242 of file app_rpt.c.
References ast_cli(), ast_log(), rpt_link::chan, rpt_link::chan_stat, rpt_lstat::chan_stat, rpt_link::connecttime, rpt_lstat::connecttime, free, rpt::links, rpt::lock, LOG_ERROR, malloc, MAXPEERSTR, MAXREMSTR, rpt_link::mode, rpt_lstat::mode, rpt_lstat::name, rpt_link::name, name, rpt_link::next, rpt_lstat::next, NRPTSTAT, rpt_link::outbound, rpt_lstat::outbound, pbx_substitute_variables_helper(), rpt_lstat::peer, rpt_lstat::prev, rpt_link::reconnects, rpt_lstat::reconnects, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, s, rpt_link::thisconnected, and rpt_lstat::thisconnected.
02243 { 02244 int i,j; 02245 char *connstate; 02246 struct rpt *myrpt; 02247 struct rpt_link *l; 02248 struct rpt_lstat *s,*t; 02249 struct rpt_lstat s_head; 02250 if(argc != 3) 02251 return RESULT_SHOWUSAGE; 02252 02253 s = NULL; 02254 s_head.next = &s_head; 02255 s_head.prev = &s_head; 02256 02257 for(i = 0; i < nrpts; i++) 02258 { 02259 if (!strcmp(argv[2],rpt_vars[i].name)){ 02260 /* Make a copy of all stat variables while locked */ 02261 myrpt = &rpt_vars[i]; 02262 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02263 /* Traverse the list of connected nodes */ 02264 j = 0; 02265 l = myrpt->links.next; 02266 while(l && (l != &myrpt->links)){ 02267 if (l->name[0] == '0'){ /* Skip '0' nodes */ 02268 l = l->next; 02269 continue; 02270 } 02271 if((s = (struct rpt_lstat *) malloc(sizeof(struct rpt_lstat))) == NULL){ 02272 ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n"); 02273 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02274 return RESULT_FAILURE; 02275 } 02276 memset(s, 0, sizeof(struct rpt_lstat)); 02277 strncpy(s->name, l->name, MAXREMSTR - 1); 02278 if (l->chan) pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1); 02279 else strcpy(s->peer,"(none)"); 02280 s->mode = l->mode; 02281 s->outbound = l->outbound; 02282 s->reconnects = l->reconnects; 02283 s->connecttime = l->connecttime; 02284 s->thisconnected = l->thisconnected; 02285 memcpy(s->chan_stat,l->chan_stat,NRPTSTAT * sizeof(struct rpt_chan_stat)); 02286 insque((struct qelem *) s, (struct qelem *) s_head.next); 02287 memset(l->chan_stat,0,NRPTSTAT * sizeof(struct rpt_chan_stat)); 02288 l = l->next; 02289 } 02290 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02291 ast_cli(fd, "NODE PEER RECONNECTS DIRECTION CONNECT TIME CONNECT STATE\n"); 02292 ast_cli(fd, "---- ---- ---------- --------- ------------ -------------\n"); 02293 02294 for(s = s_head.next; s != &s_head; s = s->next){ 02295 int hours, minutes, seconds; 02296 long long connecttime = s->connecttime; 02297 char conntime[21]; 02298 hours = (int) connecttime/3600000; 02299 connecttime %= 3600000; 02300 minutes = (int) connecttime/60000; 02301 connecttime %= 60000; 02302 seconds = (int) connecttime/1000; 02303 connecttime %= 1000; 02304 snprintf(conntime, 20, "%02d:%02d:%02d.%d", 02305 hours, minutes, seconds, (int) connecttime); 02306 conntime[20] = 0; 02307 if(s->thisconnected) 02308 connstate = "ESTABLISHED"; 02309 else 02310 connstate = "CONNECTING"; 02311 ast_cli(fd, "%-10s%-20s%-12d%-11s%-20s%-20s\n", 02312 s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime, connstate); 02313 } 02314 /* destroy our local link queue */ 02315 s = s_head.next; 02316 while(s != &s_head){ 02317 t = s; 02318 s = s->next; 02319 remque((struct qelem *)t); 02320 free(t); 02321 } 02322 return RESULT_SUCCESS; 02323 } 02324 } 02325 return RESULT_FAILURE; 02326 }
static int rpt_do_nodes | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2332 of file app_rpt.c.
References __mklinklist(), ast_cli(), finddelim(), rpt::lock, MAXLINKLIST, mycompar(), name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, and rpt_vars.
02333 { 02334 int i,j; 02335 char ns; 02336 char lbuf[MAXLINKLIST],*strs[MAXLINKLIST]; 02337 struct rpt *myrpt; 02338 if(argc != 3) 02339 return RESULT_SHOWUSAGE; 02340 02341 for(i = 0; i < nrpts; i++) 02342 { 02343 if (!strcmp(argv[2],rpt_vars[i].name)){ 02344 /* Make a copy of all stat variables while locked */ 02345 myrpt = &rpt_vars[i]; 02346 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02347 __mklinklist(myrpt,NULL,lbuf); 02348 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02349 /* parse em */ 02350 ns = finddelim(lbuf,strs,MAXLINKLIST); 02351 /* sort em */ 02352 if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar); 02353 ast_cli(fd,"\n"); 02354 ast_cli(fd, "************************* CONNECTED NODES *************************\n\n"); 02355 for(j = 0 ;; j++){ 02356 if(!strs[j]){ 02357 if(!j){ 02358 ast_cli(fd,"<NONE>"); 02359 } 02360 break; 02361 } 02362 ast_cli(fd, "%s", strs[j]); 02363 if(j % 8 == 7){ 02364 ast_cli(fd, "\n"); 02365 } 02366 else{ 02367 if(strs[j + 1]) 02368 ast_cli(fd, ", "); 02369 } 02370 } 02371 ast_cli(fd,"\n\n"); 02372 return RESULT_SUCCESS; 02373 } 02374 } 02375 return RESULT_FAILURE; 02376 }
static int rpt_do_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2382 of file app_rpt.c.
References reload(), RESULT_FAILURE, RESULT_SHOWUSAGE, and rpt_vars.
02383 { 02384 int n; 02385 02386 if (argc > 2) return RESULT_SHOWUSAGE; 02387 02388 for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1; 02389 02390 return RESULT_FAILURE; 02391 }
static int rpt_do_restart | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2397 of file app_rpt.c.
References ast_softhangup(), AST_SOFTHANGUP_DEV, RESULT_FAILURE, RESULT_SHOWUSAGE, rpt_vars, and rpt::rxchannel.
02398 { 02399 int i; 02400 02401 if (argc > 2) return RESULT_SHOWUSAGE; 02402 for(i = 0; i < nrpts; i++) 02403 { 02404 if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV); 02405 } 02406 return RESULT_FAILURE; 02407 }
static int rpt_do_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2017 of file app_rpt.c.
References sysstate::alternatetail, ast_cli(), ast_strdupa, sysstate::autopatchdisable, rpt::callmode, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, rpt::exten, rpt::keyed, rpt::lastdtmfcommand, rpt::lastnodewhichkeyedusup, sysstate::linkfundisable, rpt::links, rpt::lock, MAX_STAT_LINKS, rpt::mustid, rpt::name, rpt_link::name, name, rpt_link::next, rpt::p, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, rpt::s, sysstate::schedulerdisable, rpt::sysstate_cur, rpt::tailid, rpt::timeouts, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, sysstate::totdisable, rpt::totime, rpt::totimer, sysstate::txdisable, and sysstate::userfundisable.
02018 { 02019 int i,j; 02020 int dailytxtime, dailykerchunks; 02021 int totalkerchunks, dailykeyups, totalkeyups, timeouts; 02022 int totalexecdcommands, dailyexecdcommands, hours, minutes, seconds; 02023 long long totaltxtime; 02024 struct rpt_link *l; 02025 char *listoflinks[MAX_STAT_LINKS]; 02026 char *lastnodewhichkeyedusup, *lastdtmfcommand; 02027 char *tot_state, *ider_state, *patch_state; 02028 char *reverse_patch_state, *sys_ena, *tot_ena, *link_ena, *patch_ena; 02029 char *sch_ena, *input_signal, *called_number, *user_funs, *tail_type; 02030 struct rpt *myrpt; 02031 02032 static char *not_applicable = "N/A"; 02033 02034 if(argc != 3) 02035 return RESULT_SHOWUSAGE; 02036 02037 for(i = 0 ; i < MAX_STAT_LINKS; i++) 02038 listoflinks[i] = NULL; 02039 02040 tot_state = ider_state = 02041 patch_state = reverse_patch_state = 02042 input_signal = called_number = 02043 lastdtmfcommand = not_applicable; 02044 02045 for(i = 0; i < nrpts; i++) 02046 { 02047 if (!strcmp(argv[2],rpt_vars[i].name)){ 02048 /* Make a copy of all stat variables while locked */ 02049 myrpt = &rpt_vars[i]; 02050 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02051 02052 dailytxtime = myrpt->dailytxtime; 02053 totaltxtime = myrpt->totaltxtime; 02054 dailykeyups = myrpt->dailykeyups; 02055 totalkeyups = myrpt->totalkeyups; 02056 dailykerchunks = myrpt->dailykerchunks; 02057 totalkerchunks = myrpt->totalkerchunks; 02058 dailyexecdcommands = myrpt->dailyexecdcommands; 02059 totalexecdcommands = myrpt->totalexecdcommands; 02060 timeouts = myrpt->timeouts; 02061 02062 /* Traverse the list of connected nodes */ 02063 reverse_patch_state = "DOWN"; 02064 j = 0; 02065 l = myrpt->links.next; 02066 while(l && (l != &myrpt->links)){ 02067 if (l->name[0] == '0'){ /* Skip '0' nodes */ 02068 reverse_patch_state = "UP"; 02069 l = l->next; 02070 continue; 02071 } 02072 listoflinks[j] = ast_strdupa(l->name); 02073 if(listoflinks[j]) 02074 j++; 02075 l = l->next; 02076 } 02077 02078 lastnodewhichkeyedusup = ast_strdupa(myrpt->lastnodewhichkeyedusup); 02079 if((!lastnodewhichkeyedusup) || (!strlen(lastnodewhichkeyedusup))) 02080 lastnodewhichkeyedusup = not_applicable; 02081 02082 if(myrpt->keyed) 02083 input_signal = "YES"; 02084 else 02085 input_signal = "NO"; 02086 02087 if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable) 02088 sys_ena = "DISABLED"; 02089 else 02090 sys_ena = "ENABLED"; 02091 02092 if(myrpt->p.s[myrpt->p.sysstate_cur].totdisable) 02093 tot_ena = "DISABLED"; 02094 else 02095 tot_ena = "ENABLED"; 02096 02097 if(myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable) 02098 link_ena = "DISABLED"; 02099 else 02100 link_ena = "ENABLED"; 02101 02102 if(myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 02103 patch_ena = "DISABLED"; 02104 else 02105 patch_ena = "ENABLED"; 02106 02107 if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable) 02108 sch_ena = "DISABLED"; 02109 else 02110 sch_ena = "ENABLED"; 02111 02112 if(myrpt->p.s[myrpt->p.sysstate_cur].userfundisable) 02113 user_funs = "DISABLED"; 02114 else 02115 user_funs = "ENABLED"; 02116 02117 if(myrpt->p.s[myrpt->p.sysstate_cur].alternatetail) 02118 tail_type = "ALTERNATE"; 02119 else 02120 tail_type = "STANDARD"; 02121 02122 if(!myrpt->totimer) 02123 tot_state = "TIMED OUT!"; 02124 else if(myrpt->totimer != myrpt->p.totime) 02125 tot_state = "ARMED"; 02126 else 02127 tot_state = "RESET"; 02128 02129 if(myrpt->tailid) 02130 ider_state = "QUEUED IN TAIL"; 02131 else if(myrpt->mustid) 02132 ider_state = "QUEUED FOR CLEANUP"; 02133 else 02134 ider_state = "CLEAN"; 02135 02136 switch(myrpt->callmode){ 02137 case 1: 02138 patch_state = "DIALING"; 02139 break; 02140 case 2: 02141 patch_state = "CONNECTING"; 02142 break; 02143 case 3: 02144 patch_state = "UP"; 02145 break; 02146 02147 case 4: 02148 patch_state = "CALL FAILED"; 02149 break; 02150 02151 default: 02152 patch_state = "DOWN"; 02153 } 02154 02155 if(strlen(myrpt->exten)){ 02156 called_number = ast_strdupa(myrpt->exten); 02157 if(!called_number) 02158 called_number = not_applicable; 02159 } 02160 02161 if(strlen(myrpt->lastdtmfcommand)){ 02162 lastdtmfcommand = ast_strdupa(myrpt->lastdtmfcommand); 02163 if(!lastdtmfcommand) 02164 lastdtmfcommand = not_applicable; 02165 } 02166 02167 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02168 02169 ast_cli(fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name); 02170 ast_cli(fd, "Selected system state............................: %d\n", myrpt->p.sysstate_cur); 02171 ast_cli(fd, "Signal on input..................................: %s\n", input_signal); 02172 ast_cli(fd, "System...........................................: %s\n", sys_ena); 02173 ast_cli(fd, "Scheduler........................................: %s\n", sch_ena); 02174 ast_cli(fd, "Tail Time........................................: %s\n", tail_type); 02175 ast_cli(fd, "Time out timer...................................: %s\n", tot_ena); 02176 ast_cli(fd, "Time out timer state.............................: %s\n", tot_state); 02177 ast_cli(fd, "Time outs since system initialization............: %d\n", timeouts); 02178 ast_cli(fd, "Identifier state.................................: %s\n", ider_state); 02179 ast_cli(fd, "Kerchunks today..................................: %d\n", dailykerchunks); 02180 ast_cli(fd, "Kerchunks since system initialization............: %d\n", totalkerchunks); 02181 ast_cli(fd, "Keyups today.....................................: %d\n", dailykeyups); 02182 ast_cli(fd, "Keyups since system initialization...............: %d\n", totalkeyups); 02183 ast_cli(fd, "DTMF commands today..............................: %d\n", dailyexecdcommands); 02184 ast_cli(fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands); 02185 ast_cli(fd, "Last DTMF command executed.......................: %s\n", lastdtmfcommand); 02186 hours = dailytxtime/3600000; 02187 dailytxtime %= 3600000; 02188 minutes = dailytxtime/60000; 02189 dailytxtime %= 60000; 02190 seconds = dailytxtime/1000; 02191 dailytxtime %= 1000; 02192 02193 ast_cli(fd, "TX time today ...................................: %02d:%02d:%02d.%d\n", 02194 hours, minutes, seconds, dailytxtime); 02195 02196 hours = (int) totaltxtime/3600000; 02197 totaltxtime %= 3600000; 02198 minutes = (int) totaltxtime/60000; 02199 totaltxtime %= 60000; 02200 seconds = (int) totaltxtime/1000; 02201 totaltxtime %= 1000; 02202 02203 ast_cli(fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n", 02204 hours, minutes, seconds, (int) totaltxtime); 02205 ast_cli(fd, "Nodes currently connected to us..................: "); 02206 for(j = 0 ;; j++){ 02207 if(!listoflinks[j]){ 02208 if(!j){ 02209 ast_cli(fd,"<NONE>"); 02210 } 02211 break; 02212 } 02213 ast_cli(fd, "%s", listoflinks[j]); 02214 if(j % 4 == 3){ 02215 ast_cli(fd, "\n"); 02216 ast_cli(fd, " : "); 02217 } 02218 else{ 02219 if(listoflinks[j + 1]) 02220 ast_cli(fd, ", "); 02221 } 02222 } 02223 ast_cli(fd,"\n"); 02224 02225 ast_cli(fd, "Last node which transmitted to us................: %s\n", lastnodewhichkeyedusup); 02226 ast_cli(fd, "Autopatch........................................: %s\n", patch_ena); 02227 ast_cli(fd, "Autopatch state..................................: %s\n", patch_state); 02228 ast_cli(fd, "Autopatch called number..........................: %s\n", called_number); 02229 ast_cli(fd, "Reverse patch/IAXRPT connected...................: %s\n", reverse_patch_state); 02230 ast_cli(fd, "User linking commands............................: %s\n", link_ena); 02231 ast_cli(fd, "User functions...................................: %s\n\n", user_funs); 02232 return RESULT_SUCCESS; 02233 } 02234 } 02235 return RESULT_FAILURE; 02236 }
static int rpt_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 10560 of file app_rpt.c.
References __kickshort(), ast_channel::_state, ACT_TIMEOUT_WARNING, ahp, ast_channel::appl, rpt::archivedir, ast_answer(), ast_call(), ast_callerid_parse(), AST_CDR_FLAG_POST_DISABLED, ast_channel_setoption(), ast_check_hangup(), ast_cli_command(), AST_CONTROL_BUSY, AST_CONTROL_HANGUP, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_exists_extension(), AST_FORMAT_SLINEAR, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frdup(), ast_frfree, ast_gethostbyname(), ast_hangup(), ast_indicate(), ast_inet_ntoa(), ast_log(), ast_masq_park_call(), AST_OPTION_TONE_VERIFY, AST_PBX_KEEPALIVE, ast_read(), ast_request(), ast_safe_sleep(), ast_say_character_str(), ast_set_callerid(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_shrink_phone_number(), AST_STATE_UP, ast_strlen_zero(), ast_verbose(), ast_waitfor_n(), ast_write(), rpt::authlevel, AUTHLOGOUTTIME, AUTHTELLTIME, rpt::authtelltimer, rpt::authtimer, AUTHTXTIME, rpt::callmode, ast_channel::cdr, check_tx_freq(), ast_channel::cid, ast_callerid::cid_num, closerem(), rpt::conf, ast_channel::context, context, ast_frame::data, ast_channel::data, ast_frame::datalen, rpt_link::disced, diskavail(), do_dtmf_local(), donodelog(), rpt::dtmf_local_timer, rpt::dtmf_time_rem, rpt::dtmfbuf, rpt::dtmfidx, ast_channel::exten, exten, ast_channel::fds, ast_frame::frametype, free, handle_remote_data(), handle_remote_dtmf_digit(), handle_remote_phone_dtmf(), rpt::hfscanmode, rpt::hfscanstatus, hp, rpt::iobase, rpt::iofd, rpt::ioport, rpt_link::killme, rpt::last_activity_time, rpt::lastf1, rpt::lastf2, rpt::links, load_rpt_vars(), rpt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, rpt::loginlevel, LOGINREQ, rpt::loginuser, rpt::macrobuf, MACROPTIME, MACROTIME, rpt::macrotimer, malloc, MAX_RETRIES, rpt_link::max_retries, MAXMACRO, MAXNODESTR, rpt_tele::mode, MONITOR_DISK_BLOCKS_PER_MINUTE, rpt::monminblocks, MSWAIT, rpt_link::name, rpt::name, name, rpt_tele::next, rpt_link::next, rpt::nobusyout, node_lookup(), openserial(), option_verbose, rpt::p, pbx_substitute_variables_helper(), rpt::pchannel, rpt_tele::prev, ast_channel::priority, rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, REM_MODE_FM, REM_SCANTIME, rpt::remmode, rpt::remote, rpt::remoteinacttimeout, rpt::remoteon, rpt::remoterx, rpt::remotetimeout, rpt::remotetimeoutwarning, rpt::remotetimeoutwarningfreq, rpt::remotetx, rpt::remtxfreqok, rpt::rerxtimer, rpt_link::retries, rpt::retxtimer, REV_PATCH, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt_vars, rpt::rxchanname, rpt::rxchannel, s, rpt::s, sayfile(), SCAN, rpt::scantimer, setrem(), SETREMOTE, START_DELAY, rpt::start_time, rpt::startupmacro, strsep(), ast_frame::subclass, rpt::sysstate_cur, rpt::tele, TIMEOUT_WARNING, TUNE, rpt::tunerequest, rpt::txchanname, rpt::txchannel, rpt::txconf, sysstate::txdisable, UNAUTHTX, VERBOSE_PREFIX_3, ast_channel::whentohangup, rpt::zaprxchannel, and rpt::zaptxchannel.
Referenced by load_module().
10561 { 10562 int res=-1,i,rem_totx,rem_rx,remkeyed,n,phone_mode = 0; 10563 int iskenwood_pci4,authtold,authreq,setting,notremming,reming; 10564 int ismuted,dtmfed; 10565 #ifdef OLD_ASTERISK 10566 struct localuser *u; 10567 #endif 10568 char tmp[256], keyed = 0,keyed1 = 0; 10569 char *options,*stringp,*tele,c; 10570 struct rpt *myrpt; 10571 struct ast_frame *f,*f1,*f2; 10572 struct ast_channel *who; 10573 struct ast_channel *cs[20]; 10574 struct rpt_link *l; 10575 ZT_CONFINFO ci; /* conference info */ 10576 ZT_PARAMS par; 10577 int ms,elap,nullfd; 10578 time_t t,last_timeout_warning; 10579 struct zt_radio_param z; 10580 struct rpt_tele *telem; 10581 10582 nullfd = open("/dev/null",O_RDWR); 10583 if (ast_strlen_zero(data)) { 10584 ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n"); 10585 return -1; 10586 } 10587 10588 strncpy(tmp, (char *)data, sizeof(tmp)-1); 10589 time(&t); 10590 /* if time has externally shifted negative, screw it */ 10591 if (t < starttime) t = starttime + START_DELAY; 10592 if ((!starttime) || (t < (starttime + START_DELAY))) 10593 { 10594 ast_log(LOG_NOTICE,"Node %s rejecting call: too soon!\n",tmp); 10595 ast_safe_sleep(chan,3000); 10596 return -1; 10597 } 10598 stringp=tmp; 10599 strsep(&stringp, "|"); 10600 options = stringp; 10601 myrpt = NULL; 10602 /* see if we can find our specified one */ 10603 for(i = 0; i < nrpts; i++) 10604 { 10605 /* if name matches, assign it and exit loop */ 10606 if (!strcmp(tmp,rpt_vars[i].name)) 10607 { 10608 myrpt = &rpt_vars[i]; 10609 break; 10610 } 10611 } 10612 if (myrpt == NULL) 10613 { 10614 ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp); 10615 return -1; 10616 } 10617 10618 if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable){ /* Do not allow incoming connections if disabled */ 10619 ast_log(LOG_NOTICE, "Connect attempt to node %s with tx disabled", myrpt->name); 10620 return -1; 10621 } 10622 10623 /* if not phone access, must be an IAX connection */ 10624 if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R'))) 10625 { 10626 int val; 10627 10628 phone_mode = 1; 10629 if (*options == 'D') phone_mode = 2; 10630 ast_set_callerid(chan,"0","app_rpt user","0"); 10631 val = 1; 10632 ast_channel_setoption(chan,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0); 10633 } 10634 else 10635 { 10636 #ifdef ALLOW_LOCAL_CHANNELS 10637 /* Check to insure the connection is IAX2 or Local*/ 10638 if ( (strncmp(chan->name,"IAX2",4)) && (strncmp(chan->name,"Local",5)) ) { 10639 ast_log(LOG_WARNING, "We only accept links via IAX2 or Local!!\n"); 10640 return -1; 10641 } 10642 #else 10643 if (strncmp(chan->name,"IAX2",4)) 10644 { 10645 ast_log(LOG_WARNING, "We only accept links via IAX2!!\n"); 10646 return -1; 10647 } 10648 #endif 10649 } 10650 if (options && (*options == 'R')) 10651 { 10652 10653 /* Parts of this section taken from app_parkandannounce */ 10654 char *return_context; 10655 int l, m, lot, timeout = 0; 10656 char tmp[256],*template; 10657 char *working, *context, *exten, *priority; 10658 char *s,*orig_s; 10659 10660 10661 rpt_mutex_lock(&myrpt->lock); 10662 m = myrpt->callmode; 10663 rpt_mutex_unlock(&myrpt->lock); 10664 10665 if ((!myrpt->p.nobusyout) && m) 10666 { 10667 if (chan->_state != AST_STATE_UP) 10668 { 10669 ast_indicate(chan,AST_CONTROL_BUSY); 10670 } 10671 while(ast_safe_sleep(chan,10000) != -1); 10672 return -1; 10673 } 10674 10675 if (chan->_state != AST_STATE_UP) 10676 { 10677 ast_answer(chan); 10678 } 10679 10680 l=strlen(options)+2; 10681 orig_s=malloc(l); 10682 if(!orig_s) { 10683 ast_log(LOG_WARNING, "Out of memory\n"); 10684 return -1; 10685 } 10686 s=orig_s; 10687 strncpy(s,options,l); 10688 10689 template=strsep(&s,"|"); 10690 if(!template) { 10691 ast_log(LOG_WARNING, "An announce template must be defined\n"); 10692 free(orig_s); 10693 return -1; 10694 } 10695 10696 if(s) { 10697 timeout = atoi(strsep(&s, "|")); 10698 timeout *= 1000; 10699 } 10700 10701 return_context = s; 10702 10703 if(return_context != NULL) { 10704 /* set the return context. Code borrowed from the Goto builtin */ 10705 10706 working = return_context; 10707 context = strsep(&working, "|"); 10708 exten = strsep(&working, "|"); 10709 if(!exten) { 10710 /* Only a priority in this one */ 10711 priority = context; 10712 exten = NULL; 10713 context = NULL; 10714 } else { 10715 priority = strsep(&working, "|"); 10716 if(!priority) { 10717 /* Only an extension and priority in this one */ 10718 priority = exten; 10719 exten = context; 10720 context = NULL; 10721 } 10722 } 10723 if(atoi(priority) < 0) { 10724 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority); 10725 free(orig_s); 10726 return -1; 10727 } 10728 /* At this point we have a priority and maybe an extension and a context */ 10729 chan->priority = atoi(priority); 10730 #ifdef OLD_ASTERISK 10731 if(exten && strcasecmp(exten, "BYEXTENSION")) 10732 #else 10733 if(exten) 10734 #endif 10735 strncpy(chan->exten, exten, sizeof(chan->exten)-1); 10736 if(context) 10737 strncpy(chan->context, context, sizeof(chan->context)-1); 10738 } else { /* increment the priority by default*/ 10739 chan->priority++; 10740 } 10741 10742 if(option_verbose > 2) { 10743 ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num); 10744 if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 10745 ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n"); 10746 } 10747 } 10748 10749 /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout 10750 before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */ 10751 10752 ast_masq_park_call(chan, NULL, timeout, &lot); 10753 10754 if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context); 10755 10756 snprintf(tmp,sizeof(tmp) - 1,"%d,%s",lot,template + 1); 10757 10758 rpt_telemetry(myrpt,REV_PATCH,tmp); 10759 10760 free(orig_s); 10761 10762 return 0; 10763 10764 } 10765 10766 if (!options) 10767 { 10768 struct ast_hostent ahp; 10769 struct hostent *hp; 10770 struct in_addr ia; 10771 char hisip[100],nodeip[100],*val, *s, *s1, *s2, *b,*b1; 10772 10773 /* look at callerid to see what node this comes from */ 10774 if (!chan->cid.cid_num) /* if doesn't have caller id */ 10775 { 10776 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 10777 return -1; 10778 } 10779 10780 /* get his IP from IAX2 module */ 10781 memset(hisip,0,sizeof(hisip)); 10782 #ifdef ALLOW_LOCAL_CHANNELS 10783 /* set IP address if this is a local connection*/ 10784 if (strncmp(chan->name,"Local",5)==0) { 10785 strcpy(hisip,"127.0.0.1"); 10786 } else { 10787 pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1); 10788 } 10789 #else 10790 pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1); 10791 #endif 10792 10793 if (!hisip[0]) 10794 { 10795 ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n"); 10796 return -1; 10797 } 10798 10799 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 10800 ast_shrink_phone_number(b1); 10801 if (!strcmp(myrpt->name,b1)) 10802 { 10803 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 10804 return -1; 10805 } 10806 10807 if (*b1 < '1') 10808 { 10809 ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1); 10810 return -1; 10811 } 10812 10813 10814 /* look for his reported node string */ 10815 val = node_lookup(myrpt,b1); 10816 if (!val) 10817 { 10818 ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1); 10819 return -1; 10820 } 10821 strncpy(tmp,val,sizeof(tmp) - 1); 10822 s = tmp; 10823 s1 = strsep(&s,","); 10824 s2 = strsep(&s,","); 10825 if (!s2) 10826 { 10827 ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1); 10828 return -1; 10829 } 10830 if (strcmp(s2,"NONE")) { 10831 hp = ast_gethostbyname(s2, &ahp); 10832 if (!hp) 10833 { 10834 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2); 10835 return -1; 10836 } 10837 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 10838 #ifdef OLD_ASTERISK 10839 ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia); 10840 #else 10841 strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1); 10842 #endif 10843 if (strcmp(hisip,nodeip)) 10844 { 10845 char *s3 = strchr(s1,'@'); 10846 if (s3) s1 = s3 + 1; 10847 s3 = strchr(s1,'/'); 10848 if (s3) *s3 = 0; 10849 hp = ast_gethostbyname(s1, &ahp); 10850 if (!hp) 10851 { 10852 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1); 10853 return -1; 10854 } 10855 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 10856 #ifdef OLD_ASTERISK 10857 ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia); 10858 #else 10859 strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1); 10860 #endif 10861 if (strcmp(hisip,nodeip)) 10862 { 10863 ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip); 10864 return -1; 10865 } 10866 } 10867 } 10868 } 10869 10870 /* if is not a remote */ 10871 if (!myrpt->remote) 10872 { 10873 10874 char *b,*b1; 10875 int reconnects = 0; 10876 10877 /* look at callerid to see what node this comes from */ 10878 if (!chan->cid.cid_num) /* if doesn't have caller id */ 10879 { 10880 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 10881 return -1; 10882 } 10883 10884 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 10885 ast_shrink_phone_number(b1); 10886 if (!strcmp(myrpt->name,b1)) 10887 { 10888 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 10889 return -1; 10890 } 10891 rpt_mutex_lock(&myrpt->lock); 10892 l = myrpt->links.next; 10893 /* try to find this one in queue */ 10894 while(l != &myrpt->links) 10895 { 10896 if (l->name[0] == '0') 10897 { 10898 l = l->next; 10899 continue; 10900 } 10901 /* if found matching string */ 10902 if (!strcmp(l->name,b1)) break; 10903 l = l->next; 10904 } 10905 /* if found */ 10906 if (l != &myrpt->links) 10907 { 10908 l->killme = 1; 10909 l->retries = l->max_retries + 1; 10910 l->disced = 2; 10911 reconnects = l->reconnects; 10912 reconnects++; 10913 rpt_mutex_unlock(&myrpt->lock); 10914 usleep(500000); 10915 } else 10916 rpt_mutex_unlock(&myrpt->lock); 10917 /* establish call in tranceive mode */ 10918 l = malloc(sizeof(struct rpt_link)); 10919 if (!l) 10920 { 10921 ast_log(LOG_WARNING, "Unable to malloc\n"); 10922 pthread_exit(NULL); 10923 } 10924 /* zero the silly thing */ 10925 memset((char *)l,0,sizeof(struct rpt_link)); 10926 l->mode = 1; 10927 strncpy(l->name,b1,MAXNODESTR - 1); 10928 l->isremote = 0; 10929 l->chan = chan; 10930 l->connected = 1; 10931 l->thisconnected = 1; 10932 l->hasconnected = 1; 10933 l->reconnects = reconnects; 10934 l->phonemode = phone_mode; 10935 l->lastf1 = NULL; 10936 l->lastf2 = NULL; 10937 l->dtmfed = 0; 10938 ast_set_read_format(l->chan,AST_FORMAT_SLINEAR); 10939 ast_set_write_format(l->chan,AST_FORMAT_SLINEAR); 10940 /* allocate a pseudo-channel thru asterisk */ 10941 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 10942 if (!l->pchan) 10943 { 10944 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 10945 pthread_exit(NULL); 10946 } 10947 ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR); 10948 ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR); 10949 #ifdef AST_CDR_FLAG_POST_DISABLED 10950 ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED); 10951 #endif 10952 /* make a conference for the tx */ 10953 ci.chan = 0; 10954 ci.confno = myrpt->conf; 10955 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 10956 /* first put the channel on the conference in proper mode */ 10957 if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1) 10958 { 10959 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 10960 pthread_exit(NULL); 10961 } 10962 rpt_mutex_lock(&myrpt->lock); 10963 if (phone_mode > 1) l->lastrx = 1; 10964 l->max_retries = MAX_RETRIES; 10965 /* insert at end of queue */ 10966 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 10967 __kickshort(myrpt); 10968 rpt_mutex_unlock(&myrpt->lock); 10969 if (chan->_state != AST_STATE_UP) { 10970 ast_answer(chan); 10971 } 10972 if (myrpt->p.archivedir) 10973 { 10974 char str[100]; 10975 10976 if (l->phonemode) 10977 sprintf(str,"LINK(P),%s",l->name); 10978 else 10979 sprintf(str,"LINK,%s",l->name); 10980 donodelog(myrpt,str); 10981 } 10982 return AST_PBX_KEEPALIVE; 10983 } 10984 /* well, then it is a remote */ 10985 rpt_mutex_lock(&myrpt->lock); 10986 /* if remote, error if anyone else already linked */ 10987 if (myrpt->remoteon) 10988 { 10989 rpt_mutex_unlock(&myrpt->lock); 10990 usleep(500000); 10991 if (myrpt->remoteon) 10992 { 10993 ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp); 10994 return -1; 10995 } 10996 rpt_mutex_lock(&myrpt->lock); 10997 } 10998 if ((!strcmp(myrpt->remote, remote_rig_rbi)) && 10999 (ioperm(myrpt->p.iobase,1,1) == -1)) 11000 { 11001 rpt_mutex_unlock(&myrpt->lock); 11002 ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase); 11003 return -1; 11004 } 11005 myrpt->remoteon = 1; 11006 #ifdef OLD_ASTERISK 11007 LOCAL_USER_ADD(u); 11008 #endif 11009 rpt_mutex_unlock(&myrpt->lock); 11010 /* find our index, and load the vars initially */ 11011 for(i = 0; i < nrpts; i++) 11012 { 11013 if (&rpt_vars[i] == myrpt) 11014 { 11015 load_rpt_vars(i,0); 11016 break; 11017 } 11018 } 11019 rpt_mutex_lock(&myrpt->lock); 11020 tele = strchr(myrpt->rxchanname,'/'); 11021 if (!tele) 11022 { 11023 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 11024 rpt_mutex_unlock(&myrpt->lock); 11025 pthread_exit(NULL); 11026 } 11027 *tele++ = 0; 11028 myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL); 11029 myrpt->zaprxchannel = NULL; 11030 if (!strcasecmp(myrpt->rxchanname,"Zap")) 11031 myrpt->zaprxchannel = myrpt->rxchannel; 11032 if (myrpt->rxchannel) 11033 { 11034 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 11035 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 11036 #ifdef AST_CDR_FLAG_POST_DISABLED 11037 ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11038 #endif 11039 myrpt->rxchannel->whentohangup = 0; 11040 myrpt->rxchannel->appl = "Apprpt"; 11041 myrpt->rxchannel->data = "(Link Rx)"; 11042 if (option_verbose > 2) 11043 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 11044 myrpt->rxchanname,tele,myrpt->rxchannel->name); 11045 rpt_mutex_unlock(&myrpt->lock); 11046 ast_call(myrpt->rxchannel,tele,999); 11047 rpt_mutex_lock(&myrpt->lock); 11048 } 11049 else 11050 { 11051 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 11052 rpt_mutex_unlock(&myrpt->lock); 11053 pthread_exit(NULL); 11054 } 11055 *--tele = '/'; 11056 myrpt->zaptxchannel = NULL; 11057 if (myrpt->txchanname) 11058 { 11059 tele = strchr(myrpt->txchanname,'/'); 11060 if (!tele) 11061 { 11062 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 11063 rpt_mutex_unlock(&myrpt->lock); 11064 ast_hangup(myrpt->rxchannel); 11065 pthread_exit(NULL); 11066 } 11067 *tele++ = 0; 11068 myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL); 11069 if (!strcasecmp(myrpt->txchanname,"Zap")) 11070 myrpt->zaptxchannel = myrpt->txchannel; 11071 if (myrpt->txchannel) 11072 { 11073 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 11074 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 11075 #ifdef AST_CDR_FLAG_POST_DISABLED 11076 ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11077 #endif 11078 myrpt->txchannel->whentohangup = 0; 11079 myrpt->txchannel->appl = "Apprpt"; 11080 myrpt->txchannel->data = "(Link Tx)"; 11081 if (option_verbose > 2) 11082 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 11083 myrpt->txchanname,tele,myrpt->txchannel->name); 11084 rpt_mutex_unlock(&myrpt->lock); 11085 ast_call(myrpt->txchannel,tele,999); 11086 rpt_mutex_lock(&myrpt->lock); 11087 } 11088 else 11089 { 11090 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 11091 rpt_mutex_unlock(&myrpt->lock); 11092 ast_hangup(myrpt->rxchannel); 11093 pthread_exit(NULL); 11094 } 11095 *--tele = '/'; 11096 } 11097 else 11098 { 11099 myrpt->txchannel = myrpt->rxchannel; 11100 } 11101 /* allocate a pseudo-channel thru asterisk */ 11102 myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 11103 if (!myrpt->pchannel) 11104 { 11105 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 11106 rpt_mutex_unlock(&myrpt->lock); 11107 if (myrpt->txchannel != myrpt->rxchannel) 11108 ast_hangup(myrpt->txchannel); 11109 ast_hangup(myrpt->rxchannel); 11110 pthread_exit(NULL); 11111 } 11112 ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR); 11113 ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR); 11114 #ifdef AST_CDR_FLAG_POST_DISABLED 11115 ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11116 #endif 11117 if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel; 11118 if (!myrpt->zaptxchannel) myrpt->zaptxchannel = myrpt->pchannel; 11119 /* make a conference for the pseudo */ 11120 ci.chan = 0; 11121 ci.confno = -1; /* make a new conf */ 11122 ci.confmode = ZT_CONF_CONFANNMON ; 11123 /* first put the channel on the conference in announce/monitor mode */ 11124 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 11125 { 11126 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 11127 rpt_mutex_unlock(&myrpt->lock); 11128 ast_hangup(myrpt->pchannel); 11129 if (myrpt->txchannel != myrpt->rxchannel) 11130 ast_hangup(myrpt->txchannel); 11131 ast_hangup(myrpt->rxchannel); 11132 pthread_exit(NULL); 11133 } 11134 /* save pseudo channel conference number */ 11135 myrpt->conf = myrpt->txconf = ci.confno; 11136 /* if serial io port, open it */ 11137 myrpt->iofd = -1; 11138 if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt->p.ioport)) == -1)) 11139 { 11140 rpt_mutex_unlock(&myrpt->lock); 11141 ast_hangup(myrpt->pchannel); 11142 if (myrpt->txchannel != myrpt->rxchannel) 11143 ast_hangup(myrpt->txchannel); 11144 ast_hangup(myrpt->rxchannel); 11145 pthread_exit(NULL); 11146 } 11147 iskenwood_pci4 = 0; 11148 memset(&z,0,sizeof(z)); 11149 if ((myrpt->iofd < 1) && (myrpt->txchannel == myrpt->zaptxchannel)) 11150 { 11151 z.radpar = ZT_RADPAR_REMMODE; 11152 z.data = ZT_RADPAR_REM_NONE; 11153 res = ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z); 11154 /* if PCIRADIO and kenwood selected */ 11155 if ((!res) && (!strcmp(myrpt->remote,remote_rig_kenwood))) 11156 { 11157 z.radpar = ZT_RADPAR_UIOMODE; 11158 z.data = 1; 11159 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11160 { 11161 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11162 return -1; 11163 } 11164 z.radpar = ZT_RADPAR_UIODATA; 11165 z.data = 3; 11166 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11167 { 11168 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11169 return -1; 11170 } 11171 i = ZT_OFFHOOK; 11172 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i) == -1) 11173 { 11174 ast_log(LOG_ERROR,"Cannot set hook\n"); 11175 return -1; 11176 } 11177 iskenwood_pci4 = 1; 11178 } 11179 } 11180 if (myrpt->txchannel == myrpt->zaptxchannel) 11181 { 11182 i = ZT_ONHOOK; 11183 ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i); 11184 /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */ 11185 if ((myrpt->iofd < 1) && (!res) && 11186 (!strcmp(myrpt->remote,remote_rig_ft897) || 11187 (!strcmp(myrpt->remote,remote_rig_ic706)))) 11188 { 11189 z.radpar = ZT_RADPAR_UIOMODE; 11190 z.data = 1; 11191 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11192 { 11193 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11194 return -1; 11195 } 11196 z.radpar = ZT_RADPAR_UIODATA; 11197 z.data = 3; 11198 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11199 { 11200 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11201 return -1; 11202 } 11203 } 11204 } 11205 myrpt->remoterx = 0; 11206 myrpt->remotetx = 0; 11207 myrpt->retxtimer = 0; 11208 myrpt->rerxtimer = 0; 11209 myrpt->remoteon = 1; 11210 myrpt->dtmfidx = -1; 11211 myrpt->dtmfbuf[0] = 0; 11212 myrpt->dtmf_time_rem = 0; 11213 myrpt->hfscanmode = 0; 11214 myrpt->hfscanstatus = 0; 11215 if (myrpt->p.startupmacro) 11216 { 11217 snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro); 11218 } 11219 time(&myrpt->start_time); 11220 myrpt->last_activity_time = myrpt->start_time; 11221 last_timeout_warning = 0; 11222 myrpt->reload = 0; 11223 myrpt->tele.next = &myrpt->tele; 11224 myrpt->tele.prev = &myrpt->tele; 11225 rpt_mutex_unlock(&myrpt->lock); 11226 ast_set_write_format(chan, AST_FORMAT_SLINEAR); 11227 ast_set_read_format(chan, AST_FORMAT_SLINEAR); 11228 rem_rx = 0; 11229 remkeyed = 0; 11230 /* if we are on 2w loop and are a remote, turn EC on */ 11231 if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel)) 11232 { 11233 i = 128; 11234 ioctl(myrpt->zaprxchannel->fds[0],ZT_ECHOCANCEL,&i); 11235 } 11236 if (chan->_state != AST_STATE_UP) { 11237 ast_answer(chan); 11238 } 11239 11240 if (myrpt->rxchannel == myrpt->zaprxchannel) 11241 { 11242 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_GET_PARAMS,&par) != -1) 11243 { 11244 if (par.rxisoffhook) 11245 { 11246 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11247 myrpt->remoterx = 1; 11248 remkeyed = 1; 11249 } 11250 } 11251 } 11252 if (myrpt->p.archivedir) 11253 { 11254 char mycmd[100],mydate[100],*b,*b1; 11255 time_t myt; 11256 long blocksleft; 11257 11258 11259 mkdir(myrpt->p.archivedir,0600); 11260 sprintf(mycmd,"%s/%s",myrpt->p.archivedir,myrpt->name); 11261 mkdir(mycmd,0600); 11262 time(&myt); 11263 strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S", 11264 localtime(&myt)); 11265 sprintf(mycmd,"mixmonitor start %s %s/%s/%s.wav49 a",chan->name, 11266 myrpt->p.archivedir,myrpt->name,mydate); 11267 if (myrpt->p.monminblocks) 11268 { 11269 blocksleft = diskavail(myrpt); 11270 if (myrpt->p.remotetimeout) 11271 { 11272 blocksleft -= (myrpt->p.remotetimeout * 11273 MONITOR_DISK_BLOCKS_PER_MINUTE) / 60; 11274 } 11275 if (blocksleft >= myrpt->p.monminblocks) 11276 ast_cli_command(nullfd,mycmd); 11277 } else ast_cli_command(nullfd,mycmd); 11278 /* look at callerid to see what node this comes from */ 11279 if (!chan->cid.cid_num) /* if doesn't have caller id */ 11280 { 11281 b1 = "0"; 11282 } else { 11283 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 11284 ast_shrink_phone_number(b1); 11285 } 11286 sprintf(mycmd,"CONNECT,%s",b1); 11287 donodelog(myrpt,mycmd); 11288 } 11289 myrpt->loginuser[0] = 0; 11290 myrpt->loginlevel[0] = 0; 11291 myrpt->authtelltimer = 0; 11292 myrpt->authtimer = 0; 11293 authtold = 0; 11294 authreq = 0; 11295 if (myrpt->p.authlevel > 1) authreq = 1; 11296 setrem(myrpt); 11297 n = 0; 11298 dtmfed = 0; 11299 cs[n++] = chan; 11300 cs[n++] = myrpt->rxchannel; 11301 cs[n++] = myrpt->pchannel; 11302 if (myrpt->rxchannel != myrpt->txchannel) 11303 cs[n++] = myrpt->txchannel; 11304 /* start un-locked */ 11305 for(;;) 11306 { 11307 if (ast_check_hangup(chan)) break; 11308 if (ast_check_hangup(myrpt->rxchannel)) break; 11309 notremming = 0; 11310 setting = 0; 11311 reming = 0; 11312 telem = myrpt->tele.next; 11313 while(telem != &myrpt->tele) 11314 { 11315 if (telem->mode == SETREMOTE) setting = 1; 11316 if ((telem->mode == SETREMOTE) || 11317 (telem->mode == SCAN) || 11318 (telem->mode == TUNE)) reming = 1; 11319 else notremming = 1; 11320 telem = telem->next; 11321 } 11322 if (myrpt->reload) 11323 { 11324 myrpt->reload = 0; 11325 /* find our index, and load the vars */ 11326 for(i = 0; i < nrpts; i++) 11327 { 11328 if (&rpt_vars[i] == myrpt) 11329 { 11330 load_rpt_vars(i,0); 11331 break; 11332 } 11333 } 11334 } 11335 time(&t); 11336 if (myrpt->p.remotetimeout) 11337 { 11338 time_t r; 11339 11340 r = (t - myrpt->start_time); 11341 if (r >= myrpt->p.remotetimeout) 11342 { 11343 sayfile(chan,"rpt/node"); 11344 ast_say_character_str(chan,myrpt->name,NULL,chan->language); 11345 sayfile(chan,"rpt/timeout"); 11346 ast_safe_sleep(chan,1000); 11347 break; 11348 } 11349 if ((myrpt->p.remotetimeoutwarning) && 11350 (r >= (myrpt->p.remotetimeout - 11351 myrpt->p.remotetimeoutwarning)) && 11352 (r <= (myrpt->p.remotetimeout - 11353 myrpt->p.remotetimeoutwarningfreq))) 11354 { 11355 if (myrpt->p.remotetimeoutwarningfreq) 11356 { 11357 if ((t - last_timeout_warning) >= 11358 myrpt->p.remotetimeoutwarningfreq) 11359 { 11360 time(&last_timeout_warning); 11361 rpt_telemetry(myrpt,TIMEOUT_WARNING,0); 11362 } 11363 } 11364 else 11365 { 11366 if (!last_timeout_warning) 11367 { 11368 time(&last_timeout_warning); 11369 rpt_telemetry(myrpt,TIMEOUT_WARNING,0); 11370 } 11371 } 11372 } 11373 } 11374 if (myrpt->p.remoteinacttimeout && myrpt->last_activity_time) 11375 { 11376 time_t r; 11377 11378 r = (t - myrpt->last_activity_time); 11379 if (r >= myrpt->p.remoteinacttimeout) 11380 { 11381 sayfile(chan,"rpt/node"); 11382 ast_say_character_str(chan,myrpt->name,NULL,chan->language); 11383 sayfile(chan,"rpt/timeout"); 11384 ast_safe_sleep(chan,1000); 11385 break; 11386 } 11387 if ((myrpt->p.remotetimeoutwarning) && 11388 (r >= (myrpt->p.remoteinacttimeout - 11389 myrpt->p.remotetimeoutwarning)) && 11390 (r <= (myrpt->p.remoteinacttimeout - 11391 myrpt->p.remotetimeoutwarningfreq))) 11392 { 11393 if (myrpt->p.remotetimeoutwarningfreq) 11394 { 11395 if ((t - last_timeout_warning) >= 11396 myrpt->p.remotetimeoutwarningfreq) 11397 { 11398 time(&last_timeout_warning); 11399 rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0); 11400 } 11401 } 11402 else 11403 { 11404 if (!last_timeout_warning) 11405 { 11406 time(&last_timeout_warning); 11407 rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0); 11408 } 11409 } 11410 } 11411 } 11412 ms = MSWAIT; 11413 who = ast_waitfor_n(cs,n,&ms); 11414 if (who == NULL) ms = 0; 11415 elap = MSWAIT - ms; 11416 if (myrpt->macrotimer) myrpt->macrotimer -= elap; 11417 if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; 11418 if (!ms) continue; 11419 /* do local dtmf timer */ 11420 if (myrpt->dtmf_local_timer) 11421 { 11422 if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap; 11423 if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1; 11424 } 11425 rpt_mutex_lock(&myrpt->lock); 11426 do_dtmf_local(myrpt,0); 11427 rpt_mutex_unlock(&myrpt->lock); 11428 rem_totx = myrpt->dtmf_local_timer && (!phone_mode); 11429 rem_totx |= keyed && (!myrpt->tunerequest); 11430 rem_rx = (remkeyed && (!setting)) || (myrpt->tele.next != &myrpt->tele); 11431 if(!strcmp(myrpt->remote, remote_rig_ic706)) 11432 rem_totx |= myrpt->tunerequest; 11433 if (keyed && (!keyed1)) 11434 { 11435 keyed1 = 1; 11436 } 11437 11438 if (!keyed && (keyed1)) 11439 { 11440 time_t myt; 11441 11442 keyed1 = 0; 11443 time(&myt); 11444 /* if login necessary, and not too soon */ 11445 if ((myrpt->p.authlevel) && 11446 (!myrpt->loginlevel[0]) && 11447 (myt > (t + 3))) 11448 { 11449 authreq = 1; 11450 authtold = 0; 11451 myrpt->authtelltimer = AUTHTELLTIME - AUTHTXTIME; 11452 } 11453 } 11454 11455 11456 if (rem_rx && (!myrpt->remoterx)) 11457 { 11458 myrpt->remoterx = 1; 11459 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11460 } 11461 if ((!rem_rx) && (myrpt->remoterx)) 11462 { 11463 myrpt->remoterx = 0; 11464 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 11465 } 11466 /* if auth requested, and not authed yet */ 11467 if (authreq && (!myrpt->loginlevel[0])) 11468 { 11469 if ((!authtold) && ((myrpt->authtelltimer += elap) 11470 >= AUTHTELLTIME)) 11471 { 11472 authtold = 1; 11473 rpt_telemetry(myrpt,LOGINREQ,NULL); 11474 } 11475 if ((myrpt->authtimer += elap) >= AUTHLOGOUTTIME) 11476 { 11477 break; /* if not logged in, hang up after a time */ 11478 } 11479 } 11480 #ifndef OLDKEY 11481 if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME) 11482 { 11483 myrpt->retxtimer = 0; 11484 if ((myrpt->remoterx) && (!myrpt->remotetx)) 11485 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11486 else 11487 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 11488 } 11489 11490 if ((myrpt->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 2)) 11491 { 11492 keyed = 0; 11493 myrpt->rerxtimer = 0; 11494 } 11495 #endif 11496 if (rem_totx && (!myrpt->remotetx)) 11497 { 11498 /* if not authed, and needed, dont transmit */ 11499 if ((!myrpt->p.authlevel) || myrpt->loginlevel[0]) 11500 { 11501 myrpt->remotetx = 1; 11502 if((myrpt->remtxfreqok = check_tx_freq(myrpt))) 11503 { 11504 time(&myrpt->last_activity_time); 11505 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11506 { 11507 z.radpar = ZT_RADPAR_UIODATA; 11508 z.data = 1; 11509 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11510 { 11511 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11512 return -1; 11513 } 11514 } 11515 else 11516 { 11517 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 11518 } 11519 if (myrpt->p.archivedir) donodelog(myrpt,"TXKEY"); 11520 } 11521 } 11522 } 11523 if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */ 11524 { 11525 myrpt->remotetx = 0; 11526 if(!myrpt->remtxfreqok){ 11527 rpt_telemetry(myrpt,UNAUTHTX,NULL); 11528 } 11529 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11530 { 11531 z.radpar = ZT_RADPAR_UIODATA; 11532 z.data = 3; 11533 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11534 { 11535 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11536 return -1; 11537 } 11538 } 11539 else 11540 { 11541 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 11542 } 11543 if (myrpt->p.archivedir) donodelog(myrpt,"TXUNKEY"); 11544 } 11545 if (myrpt->hfscanmode){ 11546 myrpt->scantimer -= elap; 11547 if(myrpt->scantimer <= 0){ 11548 if (!reming) 11549 { 11550 myrpt->scantimer = REM_SCANTIME; 11551 rpt_telemetry(myrpt,SCAN,0); 11552 } else myrpt->scantimer = 1; 11553 } 11554 } 11555 rpt_mutex_lock(&myrpt->lock); 11556 c = myrpt->macrobuf[0]; 11557 if (c && (!myrpt->macrotimer)) 11558 { 11559 myrpt->macrotimer = MACROTIME; 11560 memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1); 11561 if ((c == 'p') || (c == 'P')) 11562 myrpt->macrotimer = MACROPTIME; 11563 rpt_mutex_unlock(&myrpt->lock); 11564 if (myrpt->p.archivedir) 11565 { 11566 char str[100]; 11567 sprintf(str,"DTMF(M),%c",c); 11568 donodelog(myrpt,str); 11569 } 11570 if (handle_remote_dtmf_digit(myrpt,c,&keyed,0) == -1) break; 11571 continue; 11572 } else rpt_mutex_unlock(&myrpt->lock); 11573 if (who == chan) /* if it was a read from incomming */ 11574 { 11575 f = ast_read(chan); 11576 if (!f) 11577 { 11578 if (debug) printf("@@@@ link:Hung Up\n"); 11579 break; 11580 } 11581 if (f->frametype == AST_FRAME_VOICE) 11582 { 11583 if (ioctl(chan->fds[0], ZT_GETCONFMUTE, &ismuted) == -1) 11584 { 11585 ismuted = 0; 11586 } 11587 /* if not transmitting, zero-out audio */ 11588 ismuted |= (!myrpt->remotetx); 11589 if (dtmfed && phone_mode) ismuted = 1; 11590 dtmfed = 0; 11591 if (ismuted) 11592 { 11593 memset(f->data,0,f->datalen); 11594 if (myrpt->lastf1) 11595 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11596 if (myrpt->lastf2) 11597 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11598 } 11599 if (f) f2 = ast_frdup(f); 11600 else f2 = NULL; 11601 f1 = myrpt->lastf2; 11602 myrpt->lastf2 = myrpt->lastf1; 11603 myrpt->lastf1 = f2; 11604 if (ismuted) 11605 { 11606 if (myrpt->lastf1) 11607 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11608 if (myrpt->lastf2) 11609 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11610 } 11611 if (f1) 11612 { 11613 if (phone_mode) 11614 ast_write(myrpt->txchannel,f1); 11615 else 11616 ast_write(myrpt->txchannel,f); 11617 ast_frfree(f1); 11618 } 11619 } 11620 #ifndef OLD_ASTERISK 11621 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 11622 { 11623 if (myrpt->lastf1) 11624 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11625 if (myrpt->lastf2) 11626 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11627 dtmfed = 1; 11628 } 11629 #endif 11630 if (f->frametype == AST_FRAME_DTMF) 11631 { 11632 if (myrpt->lastf1) 11633 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11634 if (myrpt->lastf2) 11635 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11636 dtmfed = 1; 11637 if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1) 11638 { 11639 if (debug) printf("@@@@ rpt:Hung Up\n"); 11640 ast_frfree(f); 11641 break; 11642 } 11643 } 11644 if (f->frametype == AST_FRAME_TEXT) 11645 { 11646 if (handle_remote_data(myrpt,f->data) == -1) 11647 { 11648 if (debug) printf("@@@@ rpt:Hung Up\n"); 11649 ast_frfree(f); 11650 break; 11651 } 11652 } 11653 if (f->frametype == AST_FRAME_CONTROL) 11654 { 11655 if (f->subclass == AST_CONTROL_HANGUP) 11656 { 11657 if (debug) printf("@@@@ rpt:Hung Up\n"); 11658 ast_frfree(f); 11659 break; 11660 } 11661 /* if RX key */ 11662 if (f->subclass == AST_CONTROL_RADIO_KEY) 11663 { 11664 if (debug == 7) printf("@@@@ rx key\n"); 11665 keyed = 1; 11666 myrpt->rerxtimer = 0; 11667 } 11668 /* if RX un-key */ 11669 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 11670 { 11671 myrpt->rerxtimer = 0; 11672 if (debug == 7) printf("@@@@ rx un-key\n"); 11673 keyed = 0; 11674 } 11675 } 11676 ast_frfree(f); 11677 continue; 11678 } 11679 if (who == myrpt->rxchannel) /* if it was a read from radio */ 11680 { 11681 f = ast_read(myrpt->rxchannel); 11682 if (!f) 11683 { 11684 if (debug) printf("@@@@ link:Hung Up\n"); 11685 break; 11686 } 11687 if (f->frametype == AST_FRAME_VOICE) 11688 { 11689 int myreming = 0; 11690 11691 if(!strcmp(myrpt->remote, remote_rig_kenwood)) 11692 myreming = reming; 11693 11694 if (myreming || (!remkeyed) || 11695 ((myrpt->remote) && (myrpt->remotetx)) || 11696 ((myrpt->remmode != REM_MODE_FM) && 11697 notremming)) 11698 memset(f->data,0,f->datalen); 11699 ast_write(myrpt->pchannel,f); 11700 } 11701 else if (f->frametype == AST_FRAME_CONTROL) 11702 { 11703 if (f->subclass == AST_CONTROL_HANGUP) 11704 { 11705 if (debug) printf("@@@@ rpt:Hung Up\n"); 11706 ast_frfree(f); 11707 break; 11708 } 11709 /* if RX key */ 11710 if (f->subclass == AST_CONTROL_RADIO_KEY) 11711 { 11712 if (debug == 7) printf("@@@@ remote rx key\n"); 11713 if (!myrpt->remotetx) 11714 { 11715 remkeyed = 1; 11716 } 11717 } 11718 /* if RX un-key */ 11719 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 11720 { 11721 if (debug == 7) printf("@@@@ remote rx un-key\n"); 11722 if (!myrpt->remotetx) 11723 { 11724 remkeyed = 0; 11725 } 11726 } 11727 } 11728 ast_frfree(f); 11729 continue; 11730 } 11731 if (who == myrpt->pchannel) /* if is remote mix output */ 11732 { 11733 f = ast_read(myrpt->pchannel); 11734 if (!f) 11735 { 11736 if (debug) printf("@@@@ link:Hung Up\n"); 11737 break; 11738 } 11739 if (f->frametype == AST_FRAME_VOICE) 11740 { 11741 ast_write(chan,f); 11742 } 11743 if (f->frametype == AST_FRAME_CONTROL) 11744 { 11745 if (f->subclass == AST_CONTROL_HANGUP) 11746 { 11747 if (debug) printf("@@@@ rpt:Hung Up\n"); 11748 ast_frfree(f); 11749 break; 11750 } 11751 } 11752 ast_frfree(f); 11753 continue; 11754 } 11755 if ((myrpt->rxchannel != myrpt->txchannel) && 11756 (who == myrpt->txchannel)) /* do this cuz you have to */ 11757 { 11758 f = ast_read(myrpt->txchannel); 11759 if (!f) 11760 { 11761 if (debug) printf("@@@@ link:Hung Up\n"); 11762 break; 11763 } 11764 if (f->frametype == AST_FRAME_CONTROL) 11765 { 11766 if (f->subclass == AST_CONTROL_HANGUP) 11767 { 11768 if (debug) printf("@@@@ rpt:Hung Up\n"); 11769 ast_frfree(f); 11770 break; 11771 } 11772 } 11773 ast_frfree(f); 11774 continue; 11775 } 11776 } 11777 if (myrpt->p.archivedir) 11778 { 11779 char mycmd[100],*b,*b1; 11780 11781 /* look at callerid to see what node this comes from */ 11782 if (!chan->cid.cid_num) /* if doesn't have caller id */ 11783 { 11784 b1 = "0"; 11785 } else { 11786 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 11787 ast_shrink_phone_number(b1); 11788 } 11789 sprintf(mycmd,"DISCONNECT,%s",b1); 11790 donodelog(myrpt,mycmd); 11791 } 11792 /* wait for telem to be done */ 11793 while(myrpt->tele.next != &myrpt->tele) usleep(100000); 11794 sprintf(tmp,"mixmonitor stop %s",chan->name); 11795 ast_cli_command(nullfd,tmp); 11796 close(nullfd); 11797 rpt_mutex_lock(&myrpt->lock); 11798 myrpt->hfscanmode = 0; 11799 myrpt->hfscanstatus = 0; 11800 myrpt->remoteon = 0; 11801 rpt_mutex_unlock(&myrpt->lock); 11802 if (myrpt->lastf1) ast_frfree(myrpt->lastf1); 11803 myrpt->lastf1 = NULL; 11804 if (myrpt->lastf2) ast_frfree(myrpt->lastf2); 11805 myrpt->lastf2 = NULL; 11806 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11807 { 11808 z.radpar = ZT_RADPAR_UIOMODE; 11809 z.data = 3; 11810 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11811 { 11812 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11813 return -1; 11814 } 11815 z.radpar = ZT_RADPAR_UIODATA; 11816 z.data = 3; 11817 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11818 { 11819 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11820 return -1; 11821 } 11822 i = ZT_OFFHOOK; 11823 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i) == -1) 11824 { 11825 ast_log(LOG_ERROR,"Cannot set hook\n"); 11826 return -1; 11827 } 11828 } 11829 if (myrpt->iofd) close(myrpt->iofd); 11830 myrpt->iofd = -1; 11831 ast_hangup(myrpt->pchannel); 11832 if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel); 11833 ast_hangup(myrpt->rxchannel); 11834 closerem(myrpt); 11835 #ifdef OLD_ASTERISK 11836 LOCAL_USER_REMOVE(u); 11837 #endif 11838 return res; 11839 }
static void rpt_localtime | ( | time_t * | t, | |
struct tm * | lt | |||
) | [static] |
Definition at line 1584 of file app_rpt.c.
References ast_localtime(), and localtime_r.
Referenced by do_scheduler(), and rpt_tele_thread().
01585 { 01586 #ifdef OLD_ASTERISK 01587 localtime_r(t, lt); 01588 #else 01589 ast_localtime(t, lt, NULL); 01590 #endif 01591 }
static void* rpt_master | ( | void * | ignore | ) | [static] |
Definition at line 10393 of file app_rpt.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_test_flag, ast_variable_retrieve(), rpt::cfg, free, rpt::ident, rpt::lastthreadrestarttime, load_rpt_vars(), lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, name, rpt::name, nodelog::next, rpt_tele::next, rpt::offset, rpt::powerlevel, rpt_tele::prev, REM_MEDPWR, REM_MODE_FM, REM_SIMPLEX, rpt::remmode, rpt::remote, retreive_memory(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, space, strdup, rpt::tailmessagen, rpt::tele, rpt::threadrestarts, and rpt::txchanname.
Referenced by load_module().
10394 { 10395 int i,n; 10396 pthread_attr_t attr; 10397 struct ast_config *cfg; 10398 char *this,*val; 10399 10400 /* init nodelog queue */ 10401 nodelog.next = nodelog.prev = &nodelog; 10402 /* go thru all the specified repeaters */ 10403 this = NULL; 10404 n = 0; 10405 /* wait until asterisk starts */ 10406 while(!ast_test_flag(&ast_options,AST_OPT_FLAG_FULLY_BOOTED)) 10407 usleep(250000); 10408 rpt_vars[n].cfg = ast_config_load("rpt.conf"); 10409 cfg = rpt_vars[n].cfg; 10410 if (!cfg) { 10411 ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); 10412 pthread_exit(NULL); 10413 } 10414 while((this = ast_category_browse(cfg,this)) != NULL) 10415 { 10416 for(i = 0 ; i < strlen(this) ; i++){ 10417 if((this[i] < '0') || (this[i] > '9')) 10418 break; 10419 } 10420 if(i != strlen(this)) continue; /* Not a node defn */ 10421 memset(&rpt_vars[n],0,sizeof(rpt_vars[n])); 10422 rpt_vars[n].name = strdup(this); 10423 val = (char *) ast_variable_retrieve(cfg,this,"rxchannel"); 10424 if (val) rpt_vars[n].rxchanname = strdup(val); 10425 val = (char *) ast_variable_retrieve(cfg,this,"txchannel"); 10426 if (val) rpt_vars[n].txchanname = strdup(val); 10427 val = (char *) ast_variable_retrieve(cfg,this,"remote"); 10428 if (val) rpt_vars[n].remote = strdup(val); 10429 ast_mutex_init(&rpt_vars[n].lock); 10430 ast_mutex_init(&rpt_vars[n].remlock); 10431 rpt_vars[n].tele.next = &rpt_vars[n].tele; 10432 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 10433 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 10434 rpt_vars[n].tailmessagen = 0; 10435 #ifdef _MDC_DECODE_H_ 10436 rpt_vars[n].mdc = mdc_decoder_new(8000); 10437 #endif 10438 n++; 10439 } 10440 nrpts = n; 10441 ast_config_destroy(cfg); 10442 10443 /* start em all */ 10444 for(i = 0; i < n; i++) 10445 { 10446 load_rpt_vars(i,1); 10447 10448 /* if is a remote, dont start one for it */ 10449 if (rpt_vars[i].remote) 10450 { 10451 if(retreive_memory(&rpt_vars[i],"init")){ /* Try to retreive initial memory channel */ 10452 strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1); 10453 strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1); 10454 10455 strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1); 10456 rpt_vars[i].remmode = REM_MODE_FM; 10457 rpt_vars[i].offset = REM_SIMPLEX; 10458 rpt_vars[i].powerlevel = REM_MEDPWR; 10459 } 10460 continue; 10461 } 10462 if (!rpt_vars[i].p.ident) 10463 { 10464 ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name); 10465 ast_config_destroy(cfg); 10466 pthread_exit(NULL); 10467 } 10468 pthread_attr_init(&attr); 10469 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10470 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 10471 } 10472 usleep(500000); 10473 time(&starttime); 10474 for(;;) 10475 { 10476 /* Now monitor each thread, and restart it if necessary */ 10477 for(i = 0; i < n; i++) 10478 { 10479 int rv; 10480 if (rpt_vars[i].remote) continue; 10481 if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP) 10482 rv = -1; 10483 else 10484 rv = pthread_kill(rpt_vars[i].rpt_thread,0); 10485 if (rv) 10486 { 10487 if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15) 10488 { 10489 if(rpt_vars[i].threadrestarts >= 5) 10490 { 10491 ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n"); 10492 exit(1); /* Stuck in a restart loop, kill Asterisk and start over */ 10493 } 10494 else 10495 { 10496 ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name); 10497 rpt_vars[i].threadrestarts++; 10498 } 10499 } 10500 else 10501 rpt_vars[i].threadrestarts = 0; 10502 10503 rpt_vars[i].lastthreadrestarttime = time(NULL); 10504 pthread_attr_init(&attr); 10505 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10506 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 10507 ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name); 10508 } 10509 10510 } 10511 for(;;) 10512 { 10513 struct nodelog *nodep; 10514 char *space,datestr[100],fname[300]; 10515 int fd; 10516 10517 ast_mutex_lock(&nodeloglock); 10518 nodep = nodelog.next; 10519 if(nodep == &nodelog) /* if nothing in queue */ 10520 { 10521 ast_mutex_unlock(&nodeloglock); 10522 break; 10523 } 10524 remque((struct qelem *)nodep); 10525 ast_mutex_unlock(&nodeloglock); 10526 space = strchr(nodep->str,' '); 10527 if (!space) 10528 { 10529 free(nodep); 10530 continue; 10531 } 10532 *space = 0; 10533 strftime(datestr,sizeof(datestr) - 1,"%Y%m%d", 10534 localtime(&nodep->timestamp)); 10535 sprintf(fname,"%s/%s/%s.txt",nodep->archivedir, 10536 nodep->str,datestr); 10537 fd = open(fname,O_WRONLY | O_CREAT | O_APPEND,0600); 10538 if (fd == -1) 10539 { 10540 ast_log(LOG_ERROR,"Cannot open node log file %s for write",space + 1); 10541 free(nodep); 10542 continue; 10543 } 10544 if (write(fd,space + 1,strlen(space + 1)) != 10545 strlen(space + 1)) 10546 { 10547 ast_log(LOG_ERROR,"Cannot write node log file %s for write",space + 1); 10548 free(nodep); 10549 continue; 10550 } 10551 close(fd); 10552 free(nodep); 10553 } 10554 usleep(2000000); 10555 } 10556 ast_config_destroy(cfg); 10557 pthread_exit(NULL); 10558 }
static void* rpt_tele_thread | ( | void * | this | ) | [static] |
Definition at line 2910 of file app_rpt.c.
References __mklinklist(), ACT_TIMEOUT_WARNING, ARB_ALPHA, AST_CDR_FLAG_POST_DISABLED, AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_safe_sleep(), ast_say_character_str(), ast_say_digits(), ast_say_number(), ast_say_time, ast_set_flag, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_tonepair_start(), ast_variable_retrieve(), ast_waitstream(), ast_channel::cdr, rpt_tele::chan, COMPLETE, CONNECTED, CONNFAIL, DLY_CALLTERM, DLY_COMP, DLY_ID, DLY_LINKUNKEY, DLY_TELEM, DLY_UNKEY, ast_channel::fds, finddelim(), free, FULLSTATUS, ast_channel::generatordata, get_wait_interval(), rpt_link::hasconnected, ID, ID1, IDTALKOVER, INVFREQ, rpt_link::isremote, LASTNODEKEY, LINKUNKEY, rpt_link::linkunkeytocttimer, LOG_ERROR, LOG_NOTICE, LOG_WARNING, LOGINREQ, MACRO_BUSY, MACRO_NOTFOUND, malloc, MAXLINKLIST, MAXREMSTR, MEMNOTFOUND, rpt_link::mode, rpt_tele::mode, multimode_capable(), mycompar(), rpt_tele::mylink, rpt_link::name, rpt_link::next, rpt_tele::next, rpt_tele::param, play_tone(), rpt_link::prev, PROC, REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, REM_PLUS, REM_SIMPLEX, REMALREADY, REMDISC, REMGO, REMLOGIN, REMLONGSTATUS, REMMODE, REMNOTFOUND, REMSHORTSTATUS, REMXXX, REV_PATCH, rpt_tele::rpt, rpt_localtime(), rpt_mutex_lock, rpt_mutex_unlock, s, saycharstr(), sayfile(), saynum(), SCAN, SCANSTAT, service_scan(), set_ft897(), set_ic706(), set_mode_ft897(), set_mode_ic706(), setkenwood(), setrbi(), SETREMOTE, simple_command_ft897(), split_freq(), STATS_TIME, STATS_VERSION, STATUS, strsep(), rpt_tele::submode, TAILMSG, telem_any(), telem_lookup(), TERM, TEST_TONE, rpt_link::thisconnected, TIMEOUT, TIMEOUT_WARNING, TUNE, UNAUTHTX, UNKEY, and wait_interval().
Referenced by rpt_telemetry().
02911 { 02912 ZT_CONFINFO ci; /* conference info */ 02913 int res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x; 02914 struct rpt_tele *mytele = (struct rpt_tele *)this; 02915 struct rpt_tele *tlist; 02916 struct rpt *myrpt; 02917 struct rpt_link *l,*l1,linkbase; 02918 struct ast_channel *mychannel; 02919 int vmajor, vminor, m; 02920 char *p,*ct,*ct_copy,*ident, *nodename,*cp; 02921 time_t t; 02922 struct tm localtm; 02923 char lbuf[MAXLINKLIST],*strs[MAXLINKLIST]; 02924 int i,ns,rbimode; 02925 char mhz[MAXREMSTR]; 02926 char decimals[MAXREMSTR]; 02927 struct zt_params par; 02928 02929 02930 /* get a pointer to myrpt */ 02931 myrpt = mytele->rpt; 02932 02933 /* Snag copies of a few key myrpt variables */ 02934 rpt_mutex_lock(&myrpt->lock); 02935 nodename = ast_strdupa(myrpt->name); 02936 if (myrpt->p.ident) ident = ast_strdupa(myrpt->p.ident); 02937 else ident = ""; 02938 rpt_mutex_unlock(&myrpt->lock); 02939 02940 /* allocate a pseudo-channel thru asterisk */ 02941 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 02942 if (!mychannel) 02943 { 02944 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 02945 rpt_mutex_lock(&myrpt->lock); 02946 remque((struct qelem *)mytele); 02947 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02948 rpt_mutex_unlock(&myrpt->lock); 02949 free(mytele); 02950 pthread_exit(NULL); 02951 } 02952 #ifdef AST_CDR_FLAG_POST_DISABLED 02953 ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED); 02954 #endif 02955 rpt_mutex_lock(&myrpt->lock); 02956 mytele->chan = mychannel; 02957 rpt_mutex_unlock(&myrpt->lock); 02958 /* make a conference for the tx */ 02959 ci.chan = 0; 02960 /* If there's an ID queued, or tail message queued, */ 02961 /* only connect the ID audio to the local tx conference so */ 02962 /* linked systems can't hear it */ 02963 ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) || 02964 (mytele->mode == TAILMSG) || (mytele->mode == LINKUNKEY)) || (mytele->mode == TIMEOUT) ? 02965 myrpt->txconf : myrpt->conf); 02966 ci.confmode = ZT_CONF_CONFANN; 02967 /* first put the channel on the conference in announce mode */ 02968 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 02969 { 02970 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02971 rpt_mutex_lock(&myrpt->lock); 02972 remque((struct qelem *)mytele); 02973 rpt_mutex_unlock(&myrpt->lock); 02974 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02975 free(mytele); 02976 ast_hangup(mychannel); 02977 pthread_exit(NULL); 02978 } 02979 ast_stopstream(mychannel); 02980 switch(mytele->mode) 02981 { 02982 case ID: 02983 case ID1: 02984 /* wait a bit */ 02985 wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel); 02986 res = telem_any(myrpt,mychannel, ident); 02987 imdone=1; 02988 break; 02989 02990 case TAILMSG: 02991 res = ast_streamfile(mychannel, myrpt->p.tailmessages[myrpt->tailmessagen], mychannel->language); 02992 break; 02993 02994 case IDTALKOVER: 02995 p = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "idtalkover"); 02996 if(p) 02997 res = telem_any(myrpt,mychannel, p); 02998 imdone=1; 02999 break; 03000 03001 case PROC: 03002 /* wait a little bit longer */ 03003 wait_interval(myrpt, DLY_TELEM, mychannel); 03004 res = telem_lookup(myrpt, mychannel, myrpt->name, "patchup"); 03005 if(res < 0){ /* Then default message */ 03006 res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language); 03007 } 03008 break; 03009 case TERM: 03010 /* wait a little bit longer */ 03011 wait_interval(myrpt, DLY_CALLTERM, mychannel); 03012 res = telem_lookup(myrpt, mychannel, myrpt->name, "patchdown"); 03013 if(res < 0){ /* Then default message */ 03014 res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language); 03015 } 03016 break; 03017 case COMPLETE: 03018 /* wait a little bit */ 03019 wait_interval(myrpt, DLY_TELEM, mychannel); 03020 res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03021 break; 03022 case MACRO_NOTFOUND: 03023 /* wait a little bit */ 03024 wait_interval(myrpt, DLY_TELEM, mychannel); 03025 res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language); 03026 break; 03027 case MACRO_BUSY: 03028 /* wait a little bit */ 03029 wait_interval(myrpt, DLY_TELEM, mychannel); 03030 res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language); 03031 break; 03032 case UNKEY: 03033 if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */ 03034 imdone = 1; 03035 break; 03036 } 03037 03038 /* 03039 * Reset the Unkey to CT timer 03040 */ 03041 03042 x = get_wait_interval(myrpt, DLY_UNKEY); 03043 rpt_mutex_lock(&myrpt->lock); 03044 myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */ 03045 rpt_mutex_unlock(&myrpt->lock); 03046 03047 /* 03048 * If there's one already queued, don't do another 03049 */ 03050 03051 tlist = myrpt->tele.next; 03052 unkeys_queued = 0; 03053 if (tlist != &myrpt->tele) 03054 { 03055 rpt_mutex_lock(&myrpt->lock); 03056 while(tlist != &myrpt->tele){ 03057 if (tlist->mode == UNKEY) unkeys_queued++; 03058 tlist = tlist->next; 03059 } 03060 rpt_mutex_unlock(&myrpt->lock); 03061 } 03062 if( unkeys_queued > 1){ 03063 imdone = 1; 03064 break; 03065 } 03066 03067 /* Wait for the telemetry timer to expire */ 03068 /* Periodically check the timer since it can be re-initialized above */ 03069 while(myrpt->unkeytocttimer) 03070 { 03071 int ctint; 03072 if(myrpt->unkeytocttimer > 100) 03073 ctint = 100; 03074 else 03075 ctint = myrpt->unkeytocttimer; 03076 ast_safe_sleep(mychannel, ctint); 03077 rpt_mutex_lock(&myrpt->lock); 03078 if(myrpt->unkeytocttimer < ctint) 03079 myrpt->unkeytocttimer = 0; 03080 else 03081 myrpt->unkeytocttimer -= ctint; 03082 rpt_mutex_unlock(&myrpt->lock); 03083 } 03084 03085 /* 03086 * Now, the carrier on the rptr rx should be gone. 03087 * If it re-appeared, then forget about sending the CT 03088 */ 03089 if(myrpt->keyed){ 03090 imdone = 1; 03091 break; 03092 } 03093 03094 rpt_mutex_lock(&myrpt->lock); /* Update the kerchunk counters */ 03095 myrpt->dailykerchunks++; 03096 myrpt->totalkerchunks++; 03097 rpt_mutex_unlock(&myrpt->lock); 03098 03099 haslink = 0; 03100 hastx = 0; 03101 hasremote = 0; 03102 l = myrpt->links.next; 03103 if (l != &myrpt->links) 03104 { 03105 rpt_mutex_lock(&myrpt->lock); 03106 while(l != &myrpt->links) 03107 { 03108 if (l->name[0] == '0') 03109 { 03110 l = l->next; 03111 continue; 03112 } 03113 haslink = 1; 03114 if (l->mode) { 03115 hastx++; 03116 if (l->isremote) hasremote++; 03117 } 03118 l = l->next; 03119 } 03120 rpt_mutex_unlock(&myrpt->lock); 03121 } 03122 if (haslink) 03123 { 03124 03125 res = telem_lookup(myrpt,mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx"); 03126 if(res) 03127 ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name); 03128 03129 03130 /* if in remote cmd mode, indicate it */ 03131 if (myrpt->cmdnode[0]) 03132 { 03133 ast_safe_sleep(mychannel,200); 03134 res = telem_lookup(myrpt,mychannel, myrpt->name, "cmdmode"); 03135 if(res) 03136 ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name); 03137 ast_stopstream(mychannel); 03138 } 03139 } 03140 else if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */ 03141 ct_copy = ast_strdupa(ct); 03142 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03143 if(res) 03144 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03145 } 03146 if (hasremote && (!myrpt->cmdnode[0])) 03147 { 03148 /* set for all to hear */ 03149 ci.chan = 0; 03150 ci.confno = myrpt->conf; 03151 ci.confmode = ZT_CONF_CONFANN; 03152 /* first put the channel on the conference in announce mode */ 03153 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 03154 { 03155 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 03156 rpt_mutex_lock(&myrpt->lock); 03157 remque((struct qelem *)mytele); 03158 rpt_mutex_unlock(&myrpt->lock); 03159 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03160 free(mytele); 03161 ast_hangup(mychannel); 03162 pthread_exit(NULL); 03163 } 03164 if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */ 03165 ast_safe_sleep(mychannel,200); 03166 ct_copy = ast_strdupa(ct); 03167 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03168 if(res) 03169 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03170 } 03171 } 03172 #if defined(_MDC_DECODE_H_) && defined(MDC_SAY_WHEN_DOING_CT) 03173 if (myrpt->lastunit) 03174 { 03175 char mystr[10]; 03176 03177 ast_safe_sleep(mychannel,200); 03178 /* set for all to hear */ 03179 ci.chan = 0; 03180 ci.confno = myrpt->txconf; 03181 ci.confmode = ZT_CONF_CONFANN; 03182 /* first put the channel on the conference in announce mode */ 03183 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 03184 { 03185 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 03186 rpt_mutex_lock(&myrpt->lock); 03187 remque((struct qelem *)mytele); 03188 rpt_mutex_unlock(&myrpt->lock); 03189 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03190 free(mytele); 03191 ast_hangup(mychannel); 03192 pthread_exit(NULL); 03193 } 03194 sprintf(mystr,"%04x",myrpt->lastunit); 03195 myrpt->lastunit = 0; 03196 ast_say_character_str(mychannel,mystr,NULL,mychannel->language); 03197 break; 03198 } 03199 #endif 03200 imdone = 1; 03201 break; 03202 case LINKUNKEY: 03203 if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */ 03204 imdone = 1; 03205 break; 03206 } 03207 03208 /* 03209 * Reset the Unkey to CT timer 03210 */ 03211 03212 x = get_wait_interval(myrpt, DLY_LINKUNKEY); 03213 mytele->mylink.linkunkeytocttimer = x; /* Must be protected as it is changed below */ 03214 03215 /* 03216 * If there's one already queued, don't do another 03217 */ 03218 03219 tlist = myrpt->tele.next; 03220 unkeys_queued = 0; 03221 if (tlist != &myrpt->tele) 03222 { 03223 rpt_mutex_lock(&myrpt->lock); 03224 while(tlist != &myrpt->tele){ 03225 if (tlist->mode == LINKUNKEY) unkeys_queued++; 03226 tlist = tlist->next; 03227 } 03228 rpt_mutex_unlock(&myrpt->lock); 03229 } 03230 if( unkeys_queued > 1){ 03231 imdone = 1; 03232 break; 03233 } 03234 03235 /* Wait for the telemetry timer to expire */ 03236 /* Periodically check the timer since it can be re-initialized above */ 03237 while(mytele->mylink.linkunkeytocttimer) 03238 { 03239 int ctint; 03240 if(mytele->mylink.linkunkeytocttimer > 100) 03241 ctint = 100; 03242 else 03243 ctint = mytele->mylink.linkunkeytocttimer; 03244 ast_safe_sleep(mychannel, ctint); 03245 rpt_mutex_lock(&myrpt->lock); 03246 if(mytele->mylink.linkunkeytocttimer < ctint) 03247 mytele->mylink.linkunkeytocttimer = 0; 03248 else 03249 mytele->mylink.linkunkeytocttimer -= ctint; 03250 rpt_mutex_unlock(&myrpt->lock); 03251 } 03252 03253 if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "linkunkeyct"))){ /* Unlinked Courtesy Tone */ 03254 ct_copy = ast_strdupa(ct); 03255 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03256 if(res) 03257 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03258 } 03259 imdone = 1; 03260 break; 03261 case REMDISC: 03262 /* wait a little bit */ 03263 wait_interval(myrpt, DLY_TELEM, mychannel); 03264 l = myrpt->links.next; 03265 haslink = 0; 03266 /* dont report if a link for this one still on system */ 03267 if (l != &myrpt->links) 03268 { 03269 rpt_mutex_lock(&myrpt->lock); 03270 while(l != &myrpt->links) 03271 { 03272 if (l->name[0] == '0') 03273 { 03274 l = l->next; 03275 continue; 03276 } 03277 if (!strcmp(l->name,mytele->mylink.name)) 03278 { 03279 haslink = 1; 03280 break; 03281 } 03282 l = l->next; 03283 } 03284 rpt_mutex_unlock(&myrpt->lock); 03285 } 03286 if (haslink) 03287 { 03288 imdone = 1; 03289 break; 03290 } 03291 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03292 if (!res) 03293 res = ast_waitstream(mychannel, ""); 03294 else 03295 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03296 ast_stopstream(mychannel); 03297 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03298 res = ast_streamfile(mychannel, ((mytele->mylink.hasconnected) ? 03299 "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language); 03300 break; 03301 case REMALREADY: 03302 /* wait a little bit */ 03303 wait_interval(myrpt, DLY_TELEM, mychannel); 03304 res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language); 03305 break; 03306 case REMNOTFOUND: 03307 /* wait a little bit */ 03308 wait_interval(myrpt, DLY_TELEM, mychannel); 03309 res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language); 03310 break; 03311 case REMGO: 03312 /* wait a little bit */ 03313 wait_interval(myrpt, DLY_TELEM, mychannel); 03314 res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language); 03315 break; 03316 case CONNECTED: 03317 /* wait a little bit */ 03318 wait_interval(myrpt, DLY_TELEM, mychannel); 03319 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03320 if (!res) 03321 res = ast_waitstream(mychannel, ""); 03322 else 03323 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03324 ast_stopstream(mychannel); 03325 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03326 res = ast_streamfile(mychannel, "rpt/connected", mychannel->language); 03327 if (!res) 03328 res = ast_waitstream(mychannel, ""); 03329 else 03330 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03331 ast_stopstream(mychannel); 03332 res = ast_streamfile(mychannel, "digits/2", mychannel->language); 03333 if (!res) 03334 res = ast_waitstream(mychannel, ""); 03335 else 03336 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03337 ast_stopstream(mychannel); 03338 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03339 if (!res) 03340 res = ast_waitstream(mychannel, ""); 03341 else 03342 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03343 ast_stopstream(mychannel); 03344 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03345 imdone = 1; 03346 break; 03347 case CONNFAIL: 03348 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03349 if (!res) 03350 res = ast_waitstream(mychannel, ""); 03351 else 03352 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03353 ast_stopstream(mychannel); 03354 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03355 res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language); 03356 break; 03357 case MEMNOTFOUND: 03358 /* wait a little bit */ 03359 wait_interval(myrpt, DLY_TELEM, mychannel); 03360 res = ast_streamfile(mychannel, "rpt/memory_notfound", mychannel->language); 03361 break; 03362 case SETREMOTE: 03363 ast_mutex_lock(&myrpt->remlock); 03364 res = 0; 03365 if(!strcmp(myrpt->remote, remote_rig_ft897)) 03366 { 03367 res = set_ft897(myrpt); 03368 } 03369 if(!strcmp(myrpt->remote, remote_rig_ic706)) 03370 { 03371 res = set_ic706(myrpt); 03372 } 03373 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 03374 { 03375 if (ioperm(myrpt->p.iobase,1,1) == -1) 03376 { 03377 rpt_mutex_unlock(&myrpt->lock); 03378 ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase); 03379 res = -1; 03380 } 03381 else res = setrbi(myrpt); 03382 } 03383 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) 03384 { 03385 res = setkenwood(myrpt); 03386 if (ast_safe_sleep(mychannel,200) == -1) 03387 { 03388 ast_mutex_unlock(&myrpt->remlock); 03389 res = -1; 03390 break; 03391 } 03392 i = ZT_FLUSH_EVENT; 03393 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_FLUSH,&i) == -1) 03394 { 03395 ast_mutex_unlock(&myrpt->remlock); 03396 ast_log(LOG_ERROR,"Cant flush events"); 03397 res = -1; 03398 break; 03399 } 03400 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_GET_PARAMS,&par) == -1) 03401 { 03402 ast_mutex_unlock(&myrpt->remlock); 03403 ast_log(LOG_ERROR,"Cant get params"); 03404 res = -1; 03405 break; 03406 } 03407 myrpt->remoterx = 03408 (par.rxisoffhook || (myrpt->tele.next != &myrpt->tele)); 03409 } 03410 ast_mutex_unlock(&myrpt->remlock); 03411 if (!res) 03412 { 03413 imdone = 1; 03414 break; 03415 } 03416 /* fall thru to invalid freq */ 03417 case INVFREQ: 03418 /* wait a little bit */ 03419 wait_interval(myrpt, DLY_TELEM, mychannel); 03420 res = ast_streamfile(mychannel, "rpt/invalid-freq", mychannel->language); 03421 break; 03422 case REMMODE: 03423 cp = 0; 03424 wait_interval(myrpt, DLY_TELEM, mychannel); 03425 switch(myrpt->remmode) 03426 { 03427 case REM_MODE_FM: 03428 saycharstr(mychannel,"FM"); 03429 break; 03430 case REM_MODE_USB: 03431 saycharstr(mychannel,"USB"); 03432 break; 03433 case REM_MODE_LSB: 03434 saycharstr(mychannel,"LSB"); 03435 break; 03436 case REM_MODE_AM: 03437 saycharstr(mychannel,"AM"); 03438 break; 03439 } 03440 wait_interval(myrpt, DLY_COMP, mychannel); 03441 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03442 break; 03443 case LOGINREQ: 03444 wait_interval(myrpt, DLY_TELEM, mychannel); 03445 sayfile(mychannel,"rpt/login"); 03446 saycharstr(mychannel,myrpt->name); 03447 break; 03448 case REMLOGIN: 03449 wait_interval(myrpt, DLY_TELEM, mychannel); 03450 saycharstr(mychannel,myrpt->loginuser); 03451 sayfile(mychannel,"rpt/node"); 03452 saycharstr(mychannel,myrpt->name); 03453 wait_interval(myrpt, DLY_COMP, mychannel); 03454 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03455 break; 03456 case REMXXX: 03457 wait_interval(myrpt, DLY_TELEM, mychannel); 03458 res = 0; 03459 switch(mytele->submode) 03460 { 03461 case 100: /* RX PL Off */ 03462 sayfile(mychannel, "rpt/rxpl"); 03463 sayfile(mychannel, "rpt/off"); 03464 break; 03465 case 101: /* RX PL On */ 03466 sayfile(mychannel, "rpt/rxpl"); 03467 sayfile(mychannel, "rpt/on"); 03468 break; 03469 case 102: /* TX PL Off */ 03470 sayfile(mychannel, "rpt/txpl"); 03471 sayfile(mychannel, "rpt/off"); 03472 break; 03473 case 103: /* TX PL On */ 03474 sayfile(mychannel, "rpt/txpl"); 03475 sayfile(mychannel, "rpt/on"); 03476 break; 03477 case 104: /* Low Power */ 03478 sayfile(mychannel, "rpt/lopwr"); 03479 break; 03480 case 105: /* Medium Power */ 03481 sayfile(mychannel, "rpt/medpwr"); 03482 break; 03483 case 106: /* Hi Power */ 03484 sayfile(mychannel, "rpt/hipwr"); 03485 break; 03486 case 113: /* Scan down slow */ 03487 sayfile(mychannel,"rpt/down"); 03488 sayfile(mychannel, "rpt/slow"); 03489 break; 03490 case 114: /* Scan down quick */ 03491 sayfile(mychannel,"rpt/down"); 03492 sayfile(mychannel, "rpt/quick"); 03493 break; 03494 case 115: /* Scan down fast */ 03495 sayfile(mychannel,"rpt/down"); 03496 sayfile(mychannel, "rpt/fast"); 03497 break; 03498 case 116: /* Scan up slow */ 03499 sayfile(mychannel,"rpt/up"); 03500 sayfile(mychannel, "rpt/slow"); 03501 break; 03502 case 117: /* Scan up quick */ 03503 sayfile(mychannel,"rpt/up"); 03504 sayfile(mychannel, "rpt/quick"); 03505 break; 03506 case 118: /* Scan up fast */ 03507 sayfile(mychannel,"rpt/up"); 03508 sayfile(mychannel, "rpt/fast"); 03509 break; 03510 default: 03511 res = -1; 03512 } 03513 wait_interval(myrpt, DLY_COMP, mychannel); 03514 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03515 break; 03516 case SCAN: 03517 ast_mutex_lock(&myrpt->remlock); 03518 if (myrpt->hfscanstop) 03519 { 03520 myrpt->hfscanstatus = 0; 03521 myrpt->hfscanmode = 0; 03522 myrpt->hfscanstop = 0; 03523 mytele->mode = SCANSTAT; 03524 ast_mutex_unlock(&myrpt->remlock); 03525 if (ast_safe_sleep(mychannel,1000) == -1) break; 03526 sayfile(mychannel, "rpt/stop"); 03527 imdone = 1; 03528 break; 03529 } 03530 if (myrpt->hfscanstatus > -2) service_scan(myrpt); 03531 i = myrpt->hfscanstatus; 03532 myrpt->hfscanstatus = 0; 03533 if (i) mytele->mode = SCANSTAT; 03534 ast_mutex_unlock(&myrpt->remlock); 03535 if (i < 0) sayfile(mychannel, "rpt/stop"); 03536 else if (i > 0) saynum(mychannel,i); 03537 imdone = 1; 03538 break; 03539 case TUNE: 03540 ast_mutex_lock(&myrpt->remlock); 03541 if (!strcmp(myrpt->remote,remote_rig_ic706)) 03542 { 03543 set_mode_ic706(myrpt, REM_MODE_AM); 03544 if(play_tone(mychannel, 800, 6000, 8192) == -1) break; 03545 ast_safe_sleep(mychannel,500); 03546 set_mode_ic706(myrpt, myrpt->remmode); 03547 myrpt->tunerequest = 0; 03548 ast_mutex_unlock(&myrpt->remlock); 03549 imdone = 1; 03550 break; 03551 } 03552 set_mode_ft897(myrpt, REM_MODE_AM); 03553 simple_command_ft897(myrpt, 8); 03554 if(play_tone(mychannel, 800, 6000, 8192) == -1) break; 03555 simple_command_ft897(myrpt, 0x88); 03556 ast_safe_sleep(mychannel,500); 03557 set_mode_ft897(myrpt, myrpt->remmode); 03558 myrpt->tunerequest = 0; 03559 ast_mutex_unlock(&myrpt->remlock); 03560 imdone = 1; 03561 break; 03562 case REMSHORTSTATUS: 03563 case REMLONGSTATUS: 03564 wait_interval(myrpt, DLY_TELEM, mychannel); 03565 res = sayfile(mychannel,"rpt/node"); 03566 if(!res) 03567 res = saycharstr(mychannel, myrpt->name); 03568 if(!res) 03569 res = sayfile(mychannel,"rpt/frequency"); 03570 if(!res) 03571 res = split_freq(mhz, decimals, myrpt->freq); 03572 if (!multimode_capable(myrpt)) decimals[3] = 0; 03573 if(!res){ 03574 m = atoi(mhz); 03575 if(m < 100) 03576 res = saynum(mychannel, m); 03577 else 03578 res = saycharstr(mychannel, mhz); 03579 } 03580 if(!res) 03581 res = sayfile(mychannel, "letters/dot"); 03582 if(!res) 03583 res = saycharstr(mychannel, decimals); 03584 03585 if(res) break; 03586 if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */ 03587 switch(myrpt->offset){ 03588 03589 case REM_MINUS: 03590 res = sayfile(mychannel,"rpt/minus"); 03591 break; 03592 03593 case REM_SIMPLEX: 03594 res = sayfile(mychannel,"rpt/simplex"); 03595 break; 03596 03597 case REM_PLUS: 03598 res = sayfile(mychannel,"rpt/plus"); 03599 break; 03600 03601 default: 03602 break; 03603 } 03604 } 03605 else{ /* Must be USB, LSB, or AM */ 03606 switch(myrpt->remmode){ 03607 03608 case REM_MODE_USB: 03609 res = saycharstr(mychannel, "USB"); 03610 break; 03611 03612 case REM_MODE_LSB: 03613 res = saycharstr(mychannel, "LSB"); 03614 break; 03615 03616 case REM_MODE_AM: 03617 res = saycharstr(mychannel, "AM"); 03618 break; 03619 03620 03621 default: 03622 break; 03623 } 03624 } 03625 03626 if (res == -1) break; 03627 03628 if(mytele->mode == REMSHORTSTATUS){ /* Short status? */ 03629 wait_interval(myrpt, DLY_COMP, mychannel); 03630 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03631 break; 03632 } 03633 03634 if (strcmp(myrpt->remote,remote_rig_ic706)) 03635 { 03636 switch(myrpt->powerlevel){ 03637 03638 case REM_LOWPWR: 03639 res = sayfile(mychannel,"rpt/lopwr") ; 03640 break; 03641 case REM_MEDPWR: 03642 res = sayfile(mychannel,"rpt/medpwr"); 03643 break; 03644 case REM_HIPWR: 03645 res = sayfile(mychannel,"rpt/hipwr"); 03646 break; 03647 } 03648 } 03649 03650 rbimode = ((!strncmp(myrpt->remote,remote_rig_rbi,3)) 03651 || (!strncmp(myrpt->remote,remote_rig_ic706,3))); 03652 if (res || (sayfile(mychannel,"rpt/rxpl") == -1)) break; 03653 if (rbimode && (sayfile(mychannel,"rpt/txpl") == -1)) break; 03654 if ((sayfile(mychannel,"rpt/frequency") == -1) || 03655 (saycharstr(mychannel,myrpt->rxpl) == -1)) break; 03656 if ((!rbimode) && ((sayfile(mychannel,"rpt/txpl") == -1) || 03657 (sayfile(mychannel,"rpt/frequency") == -1) || 03658 (saycharstr(mychannel,myrpt->txpl) == -1))) break; 03659 if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */ 03660 if ((sayfile(mychannel,"rpt/rxpl") == -1) || 03661 (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1) || 03662 (sayfile(mychannel,"rpt/txpl") == -1) || 03663 (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1)) 03664 { 03665 break; 03666 } 03667 } 03668 wait_interval(myrpt, DLY_COMP, mychannel); 03669 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03670 break; 03671 case STATUS: 03672 /* wait a little bit */ 03673 wait_interval(myrpt, DLY_TELEM, mychannel); 03674 hastx = 0; 03675 linkbase.next = &linkbase; 03676 linkbase.prev = &linkbase; 03677 rpt_mutex_lock(&myrpt->lock); 03678 /* make our own list of links */ 03679 l = myrpt->links.next; 03680 while(l != &myrpt->links) 03681 { 03682 if (l->name[0] == '0') 03683 { 03684 l = l->next; 03685 continue; 03686 } 03687 l1 = malloc(sizeof(struct rpt_link)); 03688 if (!l1) 03689 { 03690 ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name); 03691 remque((struct qelem *)mytele); 03692 rpt_mutex_unlock(&myrpt->lock); 03693 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03694 free(mytele); 03695 ast_hangup(mychannel); 03696 pthread_exit(NULL); 03697 } 03698 memcpy(l1,l,sizeof(struct rpt_link)); 03699 l1->next = l1->prev = NULL; 03700 insque((struct qelem *)l1,(struct qelem *)linkbase.next); 03701 l = l->next; 03702 } 03703 rpt_mutex_unlock(&myrpt->lock); 03704 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03705 if (!res) 03706 res = ast_waitstream(mychannel, ""); 03707 else 03708 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03709 ast_stopstream(mychannel); 03710 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03711 if (!res) 03712 res = ast_waitstream(mychannel, ""); 03713 else 03714 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03715 ast_stopstream(mychannel); 03716 if (myrpt->callmode) 03717 { 03718 hastx = 1; 03719 res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language); 03720 if (!res) 03721 res = ast_waitstream(mychannel, ""); 03722 else 03723 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03724 ast_stopstream(mychannel); 03725 } 03726 l = linkbase.next; 03727 while(l != &linkbase) 03728 { 03729 char *s; 03730 03731 hastx = 1; 03732 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03733 if (!res) 03734 res = ast_waitstream(mychannel, ""); 03735 else 03736 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03737 ast_stopstream(mychannel); 03738 ast_say_character_str(mychannel,l->name,NULL,mychannel->language); 03739 if (!res) 03740 res = ast_waitstream(mychannel, ""); 03741 else 03742 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03743 ast_stopstream(mychannel); 03744 s = "rpt/tranceive"; 03745 if (!l->mode) s = "rpt/monitor"; 03746 if (!l->thisconnected) s = "rpt/connecting"; 03747 res = ast_streamfile(mychannel, s, mychannel->language); 03748 if (!res) 03749 res = ast_waitstream(mychannel, ""); 03750 else 03751 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03752 ast_stopstream(mychannel); 03753 l = l->next; 03754 } 03755 if (!hastx) 03756 { 03757 res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language); 03758 if (!res) 03759 res = ast_waitstream(mychannel, ""); 03760 else 03761 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03762 ast_stopstream(mychannel); 03763 } 03764 /* destroy our local link queue */ 03765 l = linkbase.next; 03766 while(l != &linkbase) 03767 { 03768 l1 = l; 03769 l = l->next; 03770 remque((struct qelem *)l1); 03771 free(l1); 03772 } 03773 imdone = 1; 03774 break; 03775 case FULLSTATUS: 03776 rpt_mutex_lock(&myrpt->lock); 03777 /* get all the nodes */ 03778 __mklinklist(myrpt,NULL,lbuf); 03779 rpt_mutex_unlock(&myrpt->lock); 03780 /* parse em */ 03781 ns = finddelim(lbuf,strs,MAXLINKLIST); 03782 /* sort em */ 03783 if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar); 03784 /* wait a little bit */ 03785 wait_interval(myrpt, DLY_TELEM, mychannel); 03786 hastx = 0; 03787 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03788 if (!res) 03789 res = ast_waitstream(mychannel, ""); 03790 else 03791 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03792 ast_stopstream(mychannel); 03793 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03794 if (!res) 03795 res = ast_waitstream(mychannel, ""); 03796 else 03797 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03798 ast_stopstream(mychannel); 03799 if (myrpt->callmode) 03800 { 03801 hastx = 1; 03802 res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language); 03803 if (!res) 03804 res = ast_waitstream(mychannel, ""); 03805 else 03806 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03807 ast_stopstream(mychannel); 03808 } 03809 /* go thru all the nodes in list */ 03810 for(i = 0; i < ns; i++) 03811 { 03812 char *s,mode = 'T'; 03813 03814 /* if a mode spec at first, handle it */ 03815 if ((*strs[i] < '0') || (*strs[i] > '9')) 03816 { 03817 mode = *strs[i]; 03818 strs[i]++; 03819 } 03820 03821 hastx = 1; 03822 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03823 if (!res) 03824 res = ast_waitstream(mychannel, ""); 03825 else 03826 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03827 ast_stopstream(mychannel); 03828 ast_say_character_str(mychannel,strs[i],NULL,mychannel->language); 03829 if (!res) 03830 res = ast_waitstream(mychannel, ""); 03831 else 03832 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03833 ast_stopstream(mychannel); 03834 s = "rpt/tranceive"; 03835 if (mode == 'R') s = "rpt/monitor"; 03836 if (mode == 'C') s = "rpt/connecting"; 03837 res = ast_streamfile(mychannel, s, mychannel->language); 03838 if (!res) 03839 res = ast_waitstream(mychannel, ""); 03840 else 03841 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03842 ast_stopstream(mychannel); 03843 } 03844 if (!hastx) 03845 { 03846 res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language); 03847 if (!res) 03848 res = ast_waitstream(mychannel, ""); 03849 else 03850 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03851 ast_stopstream(mychannel); 03852 } 03853 imdone = 1; 03854 break; 03855 03856 case LASTNODEKEY: /* Identify last node which keyed us up */ 03857 rpt_mutex_lock(&myrpt->lock); 03858 if(myrpt->lastnodewhichkeyedusup) 03859 p = ast_strdupa(myrpt->lastnodewhichkeyedusup); /* Make a local copy of the node name */ 03860 else 03861 p = NULL; 03862 rpt_mutex_unlock(&myrpt->lock); 03863 if(!p){ 03864 imdone = 1; /* no node previously keyed us up, or the node which did has been disconnected */ 03865 break; 03866 } 03867 wait_interval(myrpt, DLY_TELEM, mychannel); 03868 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03869 if (!res) 03870 res = ast_waitstream(mychannel, ""); 03871 else 03872 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03873 ast_stopstream(mychannel); 03874 ast_say_character_str(mychannel, p, NULL, mychannel->language); 03875 if (!res) 03876 res = ast_waitstream(mychannel, ""); 03877 else 03878 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03879 ast_stopstream(mychannel); 03880 imdone = 1; 03881 break; 03882 03883 case UNAUTHTX: /* Say unauthorized transmit frequency */ 03884 wait_interval(myrpt, DLY_TELEM, mychannel); 03885 res = ast_streamfile(mychannel, "rpt/unauthtx", mychannel->language); 03886 if (!res) 03887 res = ast_waitstream(mychannel, ""); 03888 else 03889 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03890 ast_stopstream(mychannel); 03891 imdone = 1; 03892 break; 03893 03894 03895 case TIMEOUT: 03896 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03897 if (!res) 03898 res = ast_waitstream(mychannel, ""); 03899 else 03900 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03901 ast_stopstream(mychannel); 03902 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03903 res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language); 03904 break; 03905 03906 case TIMEOUT_WARNING: 03907 time(&t); 03908 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03909 if (!res) 03910 res = ast_waitstream(mychannel, ""); 03911 else 03912 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03913 ast_stopstream(mychannel); 03914 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03915 res = ast_streamfile(mychannel, "rpt/timeout-warning", mychannel->language); 03916 if (!res) 03917 res = ast_waitstream(mychannel, ""); 03918 else 03919 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03920 ast_stopstream(mychannel); 03921 if(!res) /* Say number of seconds */ 03922 ast_say_number(mychannel, myrpt->p.remotetimeout - 03923 (t - myrpt->last_activity_time), 03924 "", mychannel->language, (char *) NULL); 03925 if (!res) 03926 res = ast_waitstream(mychannel, ""); 03927 ast_stopstream(mychannel); 03928 res = ast_streamfile(mychannel, "queue-seconds", mychannel->language); 03929 break; 03930 03931 case ACT_TIMEOUT_WARNING: 03932 time(&t); 03933 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03934 if (!res) 03935 res = ast_waitstream(mychannel, ""); 03936 else 03937 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03938 ast_stopstream(mychannel); 03939 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03940 res = ast_streamfile(mychannel, "rpt/act-timeout-warning", mychannel->language); 03941 if (!res) 03942 res = ast_waitstream(mychannel, ""); 03943 else 03944 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03945 ast_stopstream(mychannel); 03946 if(!res) /* Say number of seconds */ 03947 ast_say_number(mychannel, myrpt->p.remoteinacttimeout - 03948 (t - myrpt->last_activity_time), 03949 "", mychannel->language, (char *) NULL); 03950 if (!res) 03951 res = ast_waitstream(mychannel, ""); 03952 ast_stopstream(mychannel); 03953 res = ast_streamfile(mychannel, "queue-seconds", mychannel->language); 03954 break; 03955 03956 case STATS_TIME: 03957 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 03958 t = time(NULL); 03959 rpt_localtime(&t, &localtm); 03960 /* Say the phase of the day is before the time */ 03961 if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12)) 03962 p = "rpt/goodmorning"; 03963 else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18)) 03964 p = "rpt/goodafternoon"; 03965 else 03966 p = "rpt/goodevening"; 03967 if (sayfile(mychannel,p) == -1) 03968 { 03969 imdone = 1; 03970 break; 03971 } 03972 /* Say the time is ... */ 03973 if (sayfile(mychannel,"rpt/thetimeis") == -1) 03974 { 03975 imdone = 1; 03976 break; 03977 } 03978 /* Say the time */ 03979 res = ast_say_time(mychannel, t, "", mychannel->language); 03980 if (!res) 03981 res = ast_waitstream(mychannel, ""); 03982 ast_stopstream(mychannel); 03983 imdone = 1; 03984 break; 03985 case STATS_VERSION: 03986 p = strstr(tdesc, "version"); 03987 if(!p) 03988 break; 03989 if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2) 03990 break; 03991 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 03992 /* Say "version" */ 03993 if (sayfile(mychannel,"rpt/version") == -1) 03994 { 03995 imdone = 1; 03996 break; 03997 } 03998 if(!res) /* Say "X" */ 03999 ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL); 04000 if (!res) 04001 res = ast_waitstream(mychannel, ""); 04002 ast_stopstream(mychannel); 04003 if (saycharstr(mychannel,".") == -1) 04004 { 04005 imdone = 1; 04006 break; 04007 } 04008 if(!res) /* Say "Y" */ 04009 ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL); 04010 if (!res){ 04011 res = ast_waitstream(mychannel, ""); 04012 ast_stopstream(mychannel); 04013 } 04014 else 04015 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 04016 imdone = 1; 04017 break; 04018 case ARB_ALPHA: 04019 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 04020 if(mytele->param) 04021 saycharstr(mychannel, mytele->param); 04022 imdone = 1; 04023 break; 04024 case REV_PATCH: 04025 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 04026 if(mytele->param) { 04027 04028 /* Parts of this section taken from app_parkandannounce */ 04029 char *tpl_working, *tpl_current; 04030 char *tmp[100], *myparm; 04031 int looptemp=0,i=0, dres = 0; 04032 04033 04034 tpl_working = strdupa(mytele->param); 04035 myparm = strsep(&tpl_working,","); 04036 tpl_current=strsep(&tpl_working, ":"); 04037 04038 while(tpl_current && looptemp < sizeof(tmp)) { 04039 tmp[looptemp]=tpl_current; 04040 looptemp++; 04041 tpl_current=strsep(&tpl_working,":"); 04042 } 04043 04044 for(i=0; i<looptemp; i++) { 04045 if(!strcmp(tmp[i], "PARKED")) { 04046 ast_say_digits(mychannel, atoi(myparm), "", mychannel->language); 04047 } else if(!strcmp(tmp[i], "NODE")) { 04048 ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language); 04049 } else { 04050 dres = ast_streamfile(mychannel, tmp[i], mychannel->language); 04051 if(!dres) { 04052 dres = ast_waitstream(mychannel, ""); 04053 } else { 04054 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name); 04055 dres = 0; 04056 } 04057 } 04058 } 04059 } 04060 imdone = 1; 04061 break; 04062 case TEST_TONE: 04063 imdone = 1; 04064 if (myrpt->stopgen) break; 04065 myrpt->stopgen = -1; 04066 if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0))) 04067 { 04068 myrpt->stopgen = 0; 04069 break; 04070 } 04071 while(mychannel->generatordata && (myrpt->stopgen <= 0)) { 04072 if (ast_safe_sleep(mychannel,1)) break; 04073 imdone = 1; 04074 } 04075 myrpt->stopgen = 0; 04076 break; 04077 default: 04078 break; 04079 } 04080 if (!imdone) 04081 { 04082 if (!res) 04083 res = ast_waitstream(mychannel, ""); 04084 else { 04085 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 04086 res = 0; 04087 } 04088 } 04089 ast_stopstream(mychannel); 04090 rpt_mutex_lock(&myrpt->lock); 04091 if (mytele->mode == TAILMSG) 04092 { 04093 if (!res) 04094 { 04095 myrpt->tailmessagen++; 04096 if(myrpt->tailmessagen >= myrpt->p.tailmessagemax) myrpt->tailmessagen = 0; 04097 } 04098 else 04099 { 04100 myrpt->tmsgtimer = myrpt->p.tailsquashedtime; 04101 } 04102 } 04103 remque((struct qelem *)mytele); 04104 rpt_mutex_unlock(&myrpt->lock); 04105 free(mytele); 04106 ast_hangup(mychannel); 04107 #ifdef APP_RPT_LOCK_DEBUG 04108 { 04109 struct lockthread *t; 04110 04111 sleep(5); 04112 ast_mutex_lock(&locklock); 04113 t = get_lockthread(pthread_self()); 04114 if (t) memset(t,0,sizeof(struct lockthread)); 04115 ast_mutex_unlock(&locklock); 04116 } 04117 #endif 04118 pthread_exit(NULL); 04119 }
static void rpt_telemetry | ( | struct rpt * | myrpt, | |
int | mode, | |||
void * | data | |||
) | [static] |
Definition at line 4121 of file app_rpt.c.
References ARB_ALPHA, ast_log(), ast_pthread_create, CONNECTED, CONNFAIL, LINKUNKEY, rpt::lock, LOG_WARNING, malloc, rpt_tele::next, REMDISC, REMXXX, REV_PATCH, rpt_mutex_lock, rpt_mutex_unlock, rpt_tele_thread(), rpt::tele, and TELEPARAMSIZE.
Referenced by function_autopatchdn(), function_cop(), function_ilink(), function_macro(), function_remote(), function_status(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_data(), handle_remote_phone_dtmf(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_exec(), setrem(), and stop_scan().
04122 { 04123 struct rpt_tele *tele; 04124 struct rpt_link *mylink = (struct rpt_link *) data; 04125 int res; 04126 pthread_attr_t attr; 04127 04128 tele = malloc(sizeof(struct rpt_tele)); 04129 if (!tele) 04130 { 04131 ast_log(LOG_WARNING, "Unable to allocate memory\n"); 04132 pthread_exit(NULL); 04133 return; 04134 } 04135 /* zero it out */ 04136 memset((char *)tele,0,sizeof(struct rpt_tele)); 04137 tele->rpt = myrpt; 04138 tele->mode = mode; 04139 rpt_mutex_lock(&myrpt->lock); 04140 if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED) || 04141 (mode == LINKUNKEY)){ 04142 memset(&tele->mylink,0,sizeof(struct rpt_link)); 04143 if (mylink){ 04144 memcpy(&tele->mylink,mylink,sizeof(struct rpt_link)); 04145 } 04146 } 04147 else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) { 04148 strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1); 04149 tele->param[TELEPARAMSIZE - 1] = 0; 04150 } 04151 if (mode == REMXXX) tele->submode = (int) data; 04152 insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next); 04153 rpt_mutex_unlock(&myrpt->lock); 04154 pthread_attr_init(&attr); 04155 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04156 res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele); 04157 if(res < 0){ 04158 rpt_mutex_lock(&myrpt->lock); 04159 remque((struct qlem *) tele); /* We don't like stuck transmitters, remove it from the queue */ 04160 rpt_mutex_unlock(&myrpt->lock); 04161 ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res)); 04162 } 04163 return; 04164 }
static int saycharstr | ( | struct ast_channel * | mychannel, | |
char * | str | |||
) | [static] |
Definition at line 2694 of file app_rpt.c.
References ast_log(), ast_say_character_str(), ast_stopstream(), ast_waitstream(), and LOG_WARNING.
Referenced by rpt_tele_thread().
02695 { 02696 int res; 02697 02698 res = ast_say_character_str(mychannel,str,NULL,mychannel->language); 02699 if (!res) 02700 res = ast_waitstream(mychannel, ""); 02701 else 02702 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02703 ast_stopstream(mychannel); 02704 return res; 02705 }
static int sayfile | ( | struct ast_channel * | mychannel, | |
char * | fname | |||
) | [static] |
Definition at line 2681 of file app_rpt.c.
References ast_log(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and LOG_WARNING.
Referenced by rpt_exec(), rpt_tele_thread(), and telem_any().
02682 { 02683 int res; 02684 02685 res = ast_streamfile(mychannel, fname, mychannel->language); 02686 if (!res) 02687 res = ast_waitstream(mychannel, ""); 02688 else 02689 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02690 ast_stopstream(mychannel); 02691 return res; 02692 }
static int saynum | ( | struct ast_channel * | mychannel, | |
int | num | |||
) | [static] |
Definition at line 2707 of file app_rpt.c.
References ast_log(), ast_say_number(), ast_stopstream(), ast_waitstream(), and LOG_WARNING.
Referenced by rpt_tele_thread().
02708 { 02709 int res; 02710 res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL); 02711 if(!res) 02712 res = ast_waitstream(mychannel, ""); 02713 else 02714 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02715 ast_stopstream(mychannel); 02716 return res; 02717 }
static int select_mem_ic706 | ( | struct rpt * | myrpt, | |
int | slot | |||
) | [static] |
Definition at line 7206 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07207 { 07208 unsigned char cmdstr[10]; 07209 07210 cmdstr[0] = cmdstr[1] = 0xfe; 07211 cmdstr[2] = myrpt->p.civaddr; 07212 cmdstr[3] = 0xe0; 07213 cmdstr[4] = 8; 07214 cmdstr[5] = 0; 07215 cmdstr[6] = ((slot / 10) << 4) + (slot % 10); 07216 cmdstr[7] = 0xfd; 07217 07218 return(civ_cmd(myrpt,cmdstr,8)); 07219 }
static void send_link_dtmf | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 4418 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, and ast_frame::subclass.
Referenced by handle_link_phone_dtmf(), and local_dtmf_helper().
04419 { 04420 char str[300]; 04421 struct ast_frame wf; 04422 struct rpt_link *l; 04423 04424 snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c); 04425 wf.frametype = AST_FRAME_TEXT; 04426 wf.subclass = 0; 04427 wf.offset = 0; 04428 wf.mallocd = 0; 04429 wf.datalen = strlen(str) + 1; 04430 wf.samples = 0; 04431 l = myrpt->links.next; 04432 /* first, see if our dude is there */ 04433 while(l != &myrpt->links) 04434 { 04435 if (l->name[0] == '0') 04436 { 04437 l = l->next; 04438 continue; 04439 } 04440 /* if we found it, write it and were done */ 04441 if (!strcmp(l->name,myrpt->cmdnode)) 04442 { 04443 wf.data = str; 04444 if (l->chan) ast_write(l->chan,&wf); 04445 return; 04446 } 04447 l = l->next; 04448 } 04449 l = myrpt->links.next; 04450 /* if not, give it to everyone */ 04451 while(l != &myrpt->links) 04452 { 04453 wf.data = str; 04454 if (l->chan) ast_write(l->chan,&wf); 04455 l = l->next; 04456 } 04457 return; 04458 }
static int send_morse | ( | struct ast_channel * | chan, | |
char * | string, | |||
int | speed, | |||
int | freq, | |||
int | amplitude | |||
) | [static] |
Definition at line 2468 of file app_rpt.c.
References ast_safe_sleep(), ast_stopstream(), ast_waitstream(), morse_bits::ddcomb, ast_channel::fds, morse_bits::len, play_silence(), and play_tone().
Referenced by telem_any().
02469 { 02470 02471 static struct morse_bits mbits[] = { 02472 {0, 0}, /* SPACE */ 02473 {0, 0}, 02474 {6, 18},/* " */ 02475 {0, 0}, 02476 {7, 72},/* $ */ 02477 {0, 0}, 02478 {0, 0}, 02479 {6, 30},/* ' */ 02480 {5, 13},/* ( */ 02481 {6, 29},/* ) */ 02482 {0, 0}, 02483 {5, 10},/* + */ 02484 {6, 51},/* , */ 02485 {6, 33},/* - */ 02486 {6, 42},/* . */ 02487 {5, 9}, /* / */ 02488 {5, 31},/* 0 */ 02489 {5, 30},/* 1 */ 02490 {5, 28},/* 2 */ 02491 {5, 24},/* 3 */ 02492 {5, 16},/* 4 */ 02493 {5, 0}, /* 5 */ 02494 {5, 1}, /* 6 */ 02495 {5, 3}, /* 7 */ 02496 {5, 7}, /* 8 */ 02497 {5, 15},/* 9 */ 02498 {6, 7}, /* : */ 02499 {6, 21},/* ; */ 02500 {0, 0}, 02501 {5, 33},/* = */ 02502 {0, 0}, 02503 {6, 12},/* ? */ 02504 {0, 0}, 02505 {2, 2}, /* A */ 02506 {4, 1}, /* B */ 02507 {4, 5}, /* C */ 02508 {3, 1}, /* D */ 02509 {1, 0}, /* E */ 02510 {4, 4}, /* F */ 02511 {3, 3}, /* G */ 02512 {4, 0}, /* H */ 02513 {2, 0}, /* I */ 02514 {4, 14},/* J */ 02515 {3, 5}, /* K */ 02516 {4, 2}, /* L */ 02517 {2, 3}, /* M */ 02518 {2, 1}, /* N */ 02519 {3, 7}, /* O */ 02520 {4, 6}, /* P */ 02521 {4, 11},/* Q */ 02522 {3, 2}, /* R */ 02523 {3, 0}, /* S */ 02524 {1, 1}, /* T */ 02525 {3, 4}, /* U */ 02526 {4, 8}, /* V */ 02527 {3, 6}, /* W */ 02528 {4, 9}, /* X */ 02529 {4, 13},/* Y */ 02530 {4, 3} /* Z */ 02531 }; 02532 02533 02534 int dottime; 02535 int dashtime; 02536 int intralettertime; 02537 int interlettertime; 02538 int interwordtime; 02539 int len, ddcomb; 02540 int res; 02541 int c; 02542 int i; 02543 int flags; 02544 02545 res = 0; 02546 02547 /* Approximate the dot time from the speed arg. */ 02548 02549 dottime = 900/speed; 02550 02551 /* Establish timing releationships */ 02552 02553 dashtime = 3 * dottime; 02554 intralettertime = dottime; 02555 interlettertime = dottime * 4 ; 02556 interwordtime = dottime * 7; 02557 02558 for(;(*string) && (!res); string++){ 02559 02560 c = *string; 02561 02562 /* Convert lower case to upper case */ 02563 02564 if((c >= 'a') && (c <= 'z')) 02565 c -= 0x20; 02566 02567 /* Can't deal with any char code greater than Z, skip it */ 02568 02569 if(c > 'Z') 02570 continue; 02571 02572 /* If space char, wait the inter word time */ 02573 02574 if(c == ' '){ 02575 if(!res) 02576 res = play_silence(chan, interwordtime); 02577 continue; 02578 } 02579 02580 /* Subtract out control char offset to match our table */ 02581 02582 c -= 0x20; 02583 02584 /* Get the character data */ 02585 02586 len = mbits[c].len; 02587 ddcomb = mbits[c].ddcomb; 02588 02589 /* Send the character */ 02590 02591 for(; len ; len--){ 02592 if(!res) 02593 res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude); 02594 if(!res) 02595 res = play_silence(chan, intralettertime); 02596 ddcomb >>= 1; 02597 } 02598 02599 /* Wait the interletter time */ 02600 02601 if(!res) 02602 res = play_silence(chan, interlettertime - intralettertime); 02603 } 02604 02605 /* Wait for all the frames to be sent */ 02606 02607 if (!res) 02608 res = ast_waitstream(chan, ""); 02609 ast_stopstream(chan); 02610 02611 /* 02612 * Wait for the zaptel driver to physically write the tone blocks to the hardware 02613 */ 02614 02615 for(i = 0; i < 20 ; i++){ 02616 flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT; 02617 res = ioctl(chan->fds[0], ZT_IOMUX, &flags); 02618 if(flags & ZT_IOMUX_WRITEEMPTY) 02619 break; 02620 if( ast_safe_sleep(chan, 50)){ 02621 res = -1; 02622 break; 02623 } 02624 } 02625 02626 02627 return res; 02628 }
static int send_tone_telemetry | ( | struct ast_channel * | chan, | |
char * | tonestring | |||
) | [static] |
Definition at line 2630 of file app_rpt.c.
References ast_safe_sleep(), ast_stopstream(), ast_strdupa, ast_waitstream(), ast_channel::fds, play_tone_pair(), and strsep().
Referenced by telem_any().
02631 { 02632 char *stringp; 02633 char *tonesubset; 02634 int f1,f2; 02635 int duration; 02636 int amplitude; 02637 int res; 02638 int i; 02639 int flags; 02640 02641 res = 0; 02642 02643 stringp = ast_strdupa(tonestring); 02644 02645 for(;tonestring;){ 02646 tonesubset = strsep(&stringp,")"); 02647 if(!tonesubset) 02648 break; 02649 if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &litude) != 4) 02650 break; 02651 res = play_tone_pair(chan, f1, f2, duration, amplitude); 02652 if(res) 02653 break; 02654 } 02655 if(!res) 02656 res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */ 02657 02658 if (!res) 02659 res = ast_waitstream(chan, ""); 02660 ast_stopstream(chan); 02661 02662 /* 02663 * Wait for the zaptel driver to physically write the tone blocks to the hardware 02664 */ 02665 02666 for(i = 0; i < 20 ; i++){ 02667 flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT; 02668 res = ioctl(chan->fds[0], ZT_IOMUX, &flags); 02669 if(flags & ZT_IOMUX_WRITEEMPTY) 02670 break; 02671 if( ast_safe_sleep(chan, 50)){ 02672 res = -1; 02673 break; 02674 } 02675 } 02676 02677 return res; 02678 02679 }
static int sendkenwood | ( | struct rpt * | myrpt, | |
char * | txstr, | |||
char * | rxstr | |||
) | [static] |
Definition at line 5977 of file app_rpt.c.
References serial_remote_io().
Referenced by sendrxkenwood().
05978 { 05979 int i; 05980 05981 if (debug) printf("Send to kenwood: %s\n",txstr); 05982 i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr), 05983 (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3); 05984 if (i < 0) return -1; 05985 if ((i > 0) && (rxstr[i - 1] == '\r')) 05986 rxstr[i-- - 1] = 0; 05987 if (debug) printf("Got from kenwood: %s\n",rxstr); 05988 return(i); 05989 }
static int sendrxkenwood | ( | struct rpt * | myrpt, | |
char * | txstr, | |||
char * | rxstr, | |||
char * | cmpstr | |||
) | [static] |
Definition at line 6083 of file app_rpt.c.
References KENWOOD_RETRIES, and sendkenwood().
Referenced by setkenwood().
06085 { 06086 int i,j; 06087 06088 for(i = 0;i < KENWOOD_RETRIES;i++) 06089 { 06090 j = sendkenwood(myrpt,txstr,rxstr); 06091 if (j < 0) return(j); 06092 if (j == 0) continue; 06093 if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0); 06094 } 06095 return(-1); 06096 }
static int serial_remote_io | ( | struct rpt * | myrpt, | |
unsigned char * | txbuf, | |||
int | txbytes, | |||
unsigned char * | rxbuf, | |||
int | rxmaxbytes, | |||
int | asciiflag | |||
) | [static] |
Definition at line 5874 of file app_rpt.c.
References ast_channel::fds, rpt::iofd, rpt::rxchannel, and rpt::zaprxchannel.
Referenced by civ_cmd(), multimode_bump_freq_ic706(), sendkenwood(), set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), and simple_command_ft897().
05876 { 05877 int i,j,index,oldmode,olddata; 05878 struct zt_radio_param prm; 05879 char c; 05880 05881 if(debug){ 05882 printf("String output was: "); 05883 for(i = 0; i < txbytes; i++) 05884 printf("%02X ", (unsigned char ) txbuf[i]); 05885 printf("\n"); 05886 } 05887 if (myrpt->iofd > 0) /* if to do out a serial port */ 05888 { 05889 if (rxmaxbytes && rxbuf) tcflush(myrpt->iofd,TCIFLUSH); 05890 if (write(myrpt->iofd,txbuf,txbytes) != txbytes) return -1; 05891 if ((!rxmaxbytes) || (rxbuf == NULL)) return(0); 05892 memset(rxbuf,0,rxmaxbytes); 05893 for(i = 0; i < rxmaxbytes; i++) 05894 { 05895 j = read(myrpt->iofd,&c,1); 05896 if (j < 1) return(i); 05897 rxbuf[i] = c; 05898 if (asciiflag & 1) 05899 { 05900 rxbuf[i + 1] = 0; 05901 if (c == '\r') break; 05902 } 05903 } 05904 if(debug){ 05905 printf("String returned was: "); 05906 for(j = 0; j < i; j++) 05907 printf("%02X ", (unsigned char ) rxbuf[j]); 05908 printf("\n"); 05909 } 05910 return(i); 05911 } 05912 05913 /* if not a zap channel, cant use pciradio stuff */ 05914 if (myrpt->rxchannel != myrpt->zaprxchannel) return -1; 05915 05916 prm.radpar = ZT_RADPAR_UIOMODE; 05917 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1; 05918 oldmode = prm.data; 05919 prm.radpar = ZT_RADPAR_UIODATA; 05920 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1; 05921 olddata = prm.data; 05922 prm.radpar = ZT_RADPAR_REMMODE; 05923 if (asciiflag & 1) prm.data = ZT_RADPAR_REM_SERIAL_ASCII; 05924 else prm.data = ZT_RADPAR_REM_SERIAL; 05925 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05926 if (asciiflag & 2) 05927 { 05928 i = ZT_ONHOOK; 05929 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1; 05930 usleep(100000); 05931 } 05932 prm.radpar = ZT_RADPAR_REMCOMMAND; 05933 prm.data = rxmaxbytes; 05934 memcpy(prm.buf,txbuf,txbytes); 05935 prm.index = txbytes; 05936 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05937 if (rxbuf) 05938 { 05939 *rxbuf = 0; 05940 memcpy(rxbuf,prm.buf,prm.index); 05941 } 05942 index = prm.index; 05943 prm.radpar = ZT_RADPAR_REMMODE; 05944 prm.data = ZT_RADPAR_REM_NONE; 05945 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05946 if (asciiflag & 2) 05947 { 05948 i = ZT_OFFHOOK; 05949 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1; 05950 } 05951 prm.radpar = ZT_RADPAR_UIOMODE; 05952 prm.data = oldmode; 05953 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05954 prm.radpar = ZT_RADPAR_UIODATA; 05955 prm.data = olddata; 05956 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05957 return(index); 05958 }
static int service_scan | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7582 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(), and split_freq().
Referenced by rpt_tele_thread().
07583 { 07584 int res, interval; 07585 char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0; 07586 07587 switch(myrpt->hfscanmode){ 07588 07589 case HF_SCAN_DOWN_SLOW: 07590 interval = -10; /* 100Hz /sec */ 07591 break; 07592 07593 case HF_SCAN_DOWN_QUICK: 07594 interval = -50; /* 500Hz /sec */ 07595 break; 07596 07597 case HF_SCAN_DOWN_FAST: 07598 interval = -200; /* 2KHz /sec */ 07599 break; 07600 07601 case HF_SCAN_UP_SLOW: 07602 interval = 10; /* 100Hz /sec */ 07603 break; 07604 07605 case HF_SCAN_UP_QUICK: 07606 interval = 50; /* 500 Hz/sec */ 07607 break; 07608 07609 case HF_SCAN_UP_FAST: 07610 interval = 200; /* 2KHz /sec */ 07611 break; 07612 07613 default: 07614 myrpt->hfscanmode = 0; /* Huh? */ 07615 return -1; 07616 } 07617 07618 res = split_freq(mhz, decimals, myrpt->freq); 07619 07620 if(!res){ 07621 k100 =decimals[0]; 07622 k10 = decimals[1]; 07623 res = multimode_bump_freq(myrpt, interval); 07624 } 07625 07626 if(!res) 07627 res = split_freq(mhz, decimals, myrpt->freq); 07628 07629 07630 if(res){ 07631 myrpt->hfscanmode = 0; 07632 myrpt->hfscanstatus = -2; 07633 return -1; 07634 } 07635 07636 /* Announce 10KHz boundaries */ 07637 if(k10 != decimals[1]){ 07638 int myhund = (interval < 0) ? k100 : decimals[0]; 07639 int myten = (interval < 0) ? k10 : decimals[1]; 07640 myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10; 07641 } else myrpt->hfscanstatus = 0; 07642 return res; 07643 07644 }
static int set_ctcss_freq_ft897 | ( | struct rpt * | myrpt, | |
char * | txtone, | |||
char * | rxtone | |||
) | [static] |
Definition at line 6642 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_ctcss_freq().
Referenced by set_ft897().
06643 { 06644 unsigned char cmdstr[5]; 06645 char hertz[MAXREMSTR],decimal[MAXREMSTR]; 06646 int h,d; 06647 06648 memset(cmdstr, 0, 5); 06649 06650 if(split_ctcss_freq(hertz, decimal, txtone)) 06651 return -1; 06652 06653 h = atoi(hertz); 06654 d = atoi(decimal); 06655 06656 cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10; 06657 cmdstr[1] = ((h % 10) << 4) + (d % 10); 06658 06659 if(rxtone){ 06660 06661 if(split_ctcss_freq(hertz, decimal, rxtone)) 06662 return -1; 06663 06664 h = atoi(hertz); 06665 d = atoi(decimal); 06666 06667 cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10; 06668 cmdstr[3] = ((h % 10) << 4) + (d % 10); 06669 } 06670 cmdstr[4] = 0x0B; 06671 06672 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06673 }
static int set_ctcss_mode_ft897 | ( | struct rpt * | myrpt, | |
char | txplon, | |||
char | rxplon | |||
) | [static] |
Definition at line 6619 of file app_rpt.c.
References serial_remote_io().
Referenced by set_ft897().
06620 { 06621 unsigned char cmdstr[5]; 06622 06623 memset(cmdstr, 0, 5); 06624 06625 if(rxplon && txplon) 06626 cmdstr[0] = 0x2A; /* Encode and Decode */ 06627 else if (!rxplon && txplon) 06628 cmdstr[0] = 0x4A; /* Encode only */ 06629 else if (rxplon && !txplon) 06630 cmdstr[0] = 0x3A; /* Encode only */ 06631 else 06632 cmdstr[0] = 0x8A; /* OFF */ 06633 06634 cmdstr[4] = 0x0A; 06635 06636 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06637 }
static int set_ctcss_mode_ic706 | ( | struct rpt * | myrpt, | |
char | txplon, | |||
char | rxplon | |||
) | [static] |
Definition at line 7104 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07105 { 07106 unsigned char cmdstr[10]; 07107 int rv; 07108 07109 cmdstr[0] = cmdstr[1] = 0xfe; 07110 cmdstr[2] = myrpt->p.civaddr; 07111 cmdstr[3] = 0xe0; 07112 cmdstr[4] = 0x16; 07113 cmdstr[5] = 0x42; 07114 cmdstr[6] = (txplon != 0); 07115 cmdstr[7] = 0xfd; 07116 07117 rv = civ_cmd(myrpt,cmdstr,8); 07118 if (rv) return(-1); 07119 07120 cmdstr[0] = cmdstr[1] = 0xfe; 07121 cmdstr[2] = myrpt->p.civaddr; 07122 cmdstr[3] = 0xe0; 07123 cmdstr[4] = 0x16; 07124 cmdstr[5] = 0x43; 07125 cmdstr[6] = (rxplon != 0); 07126 cmdstr[7] = 0xfd; 07127 07128 return(civ_cmd(myrpt,cmdstr,8)); 07129 }
static int set_freq_ft897 | ( | struct rpt * | myrpt, | |
char * | newfreq | |||
) | [static] |
Definition at line 6511 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_freq().
Referenced by multimode_bump_freq_ft897(), and set_ft897().
06512 { 06513 unsigned char cmdstr[5]; 06514 int fd,m,d; 06515 char mhz[MAXREMSTR]; 06516 char decimals[MAXREMSTR]; 06517 06518 fd = 0; 06519 if(debug) 06520 printf("New frequency: %s\n",newfreq); 06521 06522 if(split_freq(mhz, decimals, newfreq)) 06523 return -1; 06524 06525 m = atoi(mhz); 06526 d = atoi(decimals); 06527 06528 /* The FT-897 likes packed BCD frequencies */ 06529 06530 cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10); /* 100MHz 10Mhz */ 06531 cmdstr[1] = ((m % 10) << 4) + (d / 10000); /* 1MHz 100KHz */ 06532 cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100); /* 10KHz 1KHz */ 06533 cmdstr[3] = (((d % 100)/10) << 4) + (d % 10); /* 100Hz 10Hz */ 06534 cmdstr[4] = 0x01; /* command */ 06535 06536 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06537 06538 }
static int set_freq_ic706 | ( | struct rpt * | myrpt, | |
char * | newfreq | |||
) | [static] |
Definition at line 7014 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, MAXREMSTR, rpt::p, and split_freq().
Referenced by set_ic706().
07015 { 07016 unsigned char cmdstr[20]; 07017 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07018 int fd,m,d; 07019 07020 fd = 0; 07021 if(debug) 07022 printf("New frequency: %s\n",newfreq); 07023 07024 if(split_freq(mhz, decimals, newfreq)) 07025 return -1; 07026 07027 m = atoi(mhz); 07028 d = atoi(decimals); 07029 07030 /* The ic-706 likes packed BCD frequencies */ 07031 07032 cmdstr[0] = cmdstr[1] = 0xfe; 07033 cmdstr[2] = myrpt->p.civaddr; 07034 cmdstr[3] = 0xe0; 07035 cmdstr[4] = 5; 07036 cmdstr[5] = ((d % 10) << 4); 07037 cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10); 07038 cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000); 07039 cmdstr[8] = (((m % 100)/10) << 4) + (m % 10); 07040 cmdstr[9] = (m / 100); 07041 cmdstr[10] = 0xfd; 07042 07043 return(civ_cmd(myrpt,cmdstr,11)); 07044 }
static int set_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6677 of file app_rpt.c.
References rpt::freq, rpt::offset, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, rpt::remmode, rpt::rxpl, rpt::rxplon, set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), simple_command_ft897(), rpt::txpl, and rpt::txplon.
Referenced by rpt_tele_thread().
06678 { 06679 int res; 06680 06681 if(debug) 06682 printf("@@@@ lock on\n"); 06683 06684 res = simple_command_ft897(myrpt, 0x00); /* LOCK on */ 06685 06686 if(debug) 06687 printf("@@@@ ptt off\n"); 06688 06689 if(!res) 06690 res = simple_command_ft897(myrpt, 0x88); /* PTT off */ 06691 06692 if(debug) 06693 printf("Modulation mode\n"); 06694 06695 if(!res) 06696 res = set_mode_ft897(myrpt, myrpt->remmode); /* Modulation mode */ 06697 06698 if(debug) 06699 printf("Split off\n"); 06700 06701 if(!res) 06702 simple_command_ft897(myrpt, 0x82); /* Split off */ 06703 06704 if(debug) 06705 printf("Frequency\n"); 06706 06707 if(!res) 06708 res = set_freq_ft897(myrpt, myrpt->freq); /* Frequency */ 06709 if((myrpt->remmode == REM_MODE_FM)){ 06710 if(debug) 06711 printf("Offset\n"); 06712 if(!res) 06713 res = set_offset_ft897(myrpt, myrpt->offset); /* Offset if FM */ 06714 if((!res)&&(myrpt->rxplon || myrpt->txplon)){ 06715 if(debug) 06716 printf("CTCSS tone freqs.\n"); 06717 res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */ 06718 } 06719 if(!res){ 06720 if(debug) 06721 printf("CTCSS mode\n"); 06722 res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */ 06723 } 06724 } 06725 if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){ 06726 if(debug) 06727 printf("Clarifier off\n"); 06728 simple_command_ft897(myrpt, 0x85); /* Clarifier off if LSB or USB */ 06729 } 06730 return res; 06731 }
static int set_ic706 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7221 of file app_rpt.c.
References rpt::freq, IC706_PL_MEMORY_OFFSET, ic706_pltocode(), mem2vfo_ic706(), rpt::offset, REM_MODE_FM, rpt::remmode, rpt::rxpl, rpt::rxplon, select_mem_ic706(), set_ctcss_mode_ic706(), set_freq_ic706(), set_mode_ic706(), set_offset_ic706(), simple_command_ic706(), rpt::txplon, and vfo_ic706().
Referenced by rpt_tele_thread().
07222 { 07223 int res = 0,i; 07224 07225 if(debug) 07226 printf("Set to VFO A\n"); 07227 07228 if (!res) 07229 res = simple_command_ic706(myrpt,7,0); 07230 07231 07232 if((myrpt->remmode == REM_MODE_FM)) 07233 { 07234 i = ic706_pltocode(myrpt->rxpl); 07235 if (i == -1) return -1; 07236 if(debug) 07237 printf("Select memory number\n"); 07238 if (!res) 07239 res = select_mem_ic706(myrpt,i + IC706_PL_MEMORY_OFFSET); 07240 if(debug) 07241 printf("Transfer memory to VFO\n"); 07242 if (!res) 07243 res = mem2vfo_ic706(myrpt); 07244 } 07245 07246 if(debug) 07247 printf("Set to VFO\n"); 07248 07249 if (!res) 07250 res = vfo_ic706(myrpt); 07251 07252 if(debug) 07253 printf("Modulation mode\n"); 07254 07255 if (!res) 07256 res = set_mode_ic706(myrpt, myrpt->remmode); /* Modulation mode */ 07257 07258 if(debug) 07259 printf("Split off\n"); 07260 07261 if(!res) 07262 simple_command_ic706(myrpt, 0x82,0); /* Split off */ 07263 07264 if(debug) 07265 printf("Frequency\n"); 07266 07267 if(!res) 07268 res = set_freq_ic706(myrpt, myrpt->freq); /* Frequency */ 07269 if((myrpt->remmode == REM_MODE_FM)){ 07270 if(debug) 07271 printf("Offset\n"); 07272 if(!res) 07273 res = set_offset_ic706(myrpt, myrpt->offset); /* Offset if FM */ 07274 if(!res){ 07275 if(debug) 07276 printf("CTCSS mode\n"); 07277 res = set_ctcss_mode_ic706(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */ 07278 } 07279 } 07280 return res; 07281 }
static int set_mode_ft897 | ( | struct rpt * | myrpt, | |
char | newmode | |||
) | [static] |
Definition at line 6586 of file app_rpt.c.
References REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, and serial_remote_io().
Referenced by rpt_tele_thread(), and set_ft897().
06587 { 06588 unsigned char cmdstr[5]; 06589 06590 memset(cmdstr, 0, 5); 06591 06592 switch(newmode){ 06593 case REM_MODE_FM: 06594 cmdstr[0] = 0x08; 06595 break; 06596 06597 case REM_MODE_USB: 06598 cmdstr[0] = 0x01; 06599 break; 06600 06601 case REM_MODE_LSB: 06602 cmdstr[0] = 0x00; 06603 break; 06604 06605 case REM_MODE_AM: 06606 cmdstr[0] = 0x04; 06607 break; 06608 06609 default: 06610 return -1; 06611 } 06612 cmdstr[4] = 0x07; 06613 06614 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06615 }
static int set_mode_ic706 | ( | struct rpt * | myrpt, | |
char | newmode | |||
) | [static] |
Definition at line 7075 of file app_rpt.c.
References REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, and simple_command_ic706().
Referenced by rpt_tele_thread(), and set_ic706().
07076 { 07077 unsigned char c; 07078 07079 switch(newmode){ 07080 case REM_MODE_FM: 07081 c = 5; 07082 break; 07083 07084 case REM_MODE_USB: 07085 c = 1; 07086 break; 07087 07088 case REM_MODE_LSB: 07089 c = 0; 07090 break; 07091 07092 case REM_MODE_AM: 07093 c = 2; 07094 break; 07095 07096 default: 07097 return -1; 07098 } 07099 return simple_command_ic706(myrpt,6,c); 07100 }
static int set_offset_ft897 | ( | struct rpt * | myrpt, | |
char | offset | |||
) | [static] |
Definition at line 6556 of file app_rpt.c.
References REM_MINUS, REM_PLUS, REM_SIMPLEX, and serial_remote_io().
Referenced by set_ft897().
06557 { 06558 unsigned char cmdstr[5]; 06559 06560 memset(cmdstr, 0, 5); 06561 06562 switch(offset){ 06563 case REM_SIMPLEX: 06564 cmdstr[0] = 0x89; 06565 break; 06566 06567 case REM_MINUS: 06568 cmdstr[0] = 0x09; 06569 break; 06570 06571 case REM_PLUS: 06572 cmdstr[0] = 0x49; 06573 break; 06574 06575 default: 06576 return -1; 06577 } 06578 06579 cmdstr[4] = 0x09; 06580 06581 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06582 }
static int set_offset_ic706 | ( | struct rpt * | myrpt, | |
char | offset | |||
) | [static] |
Definition at line 7048 of file app_rpt.c.
References REM_MINUS, REM_PLUS, REM_SIMPLEX, and simple_command_ic706().
Referenced by set_ic706().
07049 { 07050 unsigned char c; 07051 07052 switch(offset){ 07053 case REM_SIMPLEX: 07054 c = 0x10; 07055 break; 07056 07057 case REM_MINUS: 07058 c = 0x11; 07059 break; 07060 07061 case REM_PLUS: 07062 c = 0x12; 07063 break; 07064 07065 default: 07066 return -1; 07067 } 07068 07069 return simple_command_ic706(myrpt,0x0f,c); 07070 07071 }
static int setkenwood | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6098 of file app_rpt.c.
References rpt::freq, kenwood_pltocode(), MAXREMSTR, rpt::offset, offset, rpt::powerlevel, rpt::rxpl, rpt::rxplon, sendrxkenwood(), split_freq(), rpt::txpl, and rpt::txplon.
Referenced by rpt_tele_thread().
06099 { 06100 char rxstr[RAD_SERIAL_BUFLEN],txstr[RAD_SERIAL_BUFLEN],freq[20]; 06101 char mhz[MAXREMSTR],offset[20],band,decimals[MAXREMSTR],band1,band2; 06102 06103 int offsets[] = {0,2,1}; 06104 int powers[] = {2,1,0}; 06105 06106 if (sendrxkenwood(myrpt,"VMC 0,0\r",rxstr,"VMC") < 0) return -1; 06107 split_freq(mhz, decimals, myrpt->freq); 06108 if (atoi(mhz) > 400) 06109 { 06110 band = '6'; 06111 band1 = '1'; 06112 band2 = '5'; 06113 strcpy(offset,"005000000"); 06114 } 06115 else 06116 { 06117 band = '2'; 06118 band1 = '0'; 06119 band2 = '2'; 06120 strcpy(offset,"000600000"); 06121 } 06122 strcpy(freq,"000000"); 06123 strncpy(freq,decimals,strlen(decimals)); 06124 sprintf(txstr,"VW %c,%05d%s,0,%d,0,%d,%d,,%02d,,%02d,%s\r", 06125 band,atoi(mhz),freq,offsets[(int)myrpt->offset], 06126 (myrpt->txplon != 0),(myrpt->rxplon != 0), 06127 kenwood_pltocode(myrpt->txpl),kenwood_pltocode(myrpt->rxpl), 06128 offset); 06129 if (sendrxkenwood(myrpt,txstr,rxstr,"VW") < 0) return -1; 06130 sprintf(txstr,"RBN %c\r",band2); 06131 if (sendrxkenwood(myrpt,txstr,rxstr,"RBN") < 0) return -1; 06132 sprintf(txstr,"PC %c,%d\r",band1,powers[(int)myrpt->powerlevel]); 06133 if (sendrxkenwood(myrpt,txstr,rxstr,"PC") < 0) return -1; 06134 return 0; 06135 }
static int setrbi | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6137 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::rxpl, rpt::rxplon, s, setrbi_check(), and rpt::txplon.
Referenced by rpt_tele_thread().
06138 { 06139 char tmp[MAXREMSTR] = "",*s; 06140 unsigned char rbicmd[5]; 06141 int band,txoffset = 0,txpower = 0,rxpl; 06142 06143 /* must be a remote system */ 06144 if (!myrpt->remote) return(0); 06145 /* must have rbi hardware */ 06146 if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0); 06147 if (setrbi_check(myrpt) == -1) return(-1); 06148 strncpy(tmp, myrpt->freq, sizeof(tmp) - 1); 06149 s = strchr(tmp,'.'); 06150 /* if no decimal, is invalid */ 06151 06152 if (s == NULL){ 06153 if(debug) 06154 printf("@@@@ Frequency needs a decimal\n"); 06155 return -1; 06156 } 06157 06158 *s++ = 0; 06159 if (strlen(tmp) < 2){ 06160 if(debug) 06161 printf("@@@@ Bad MHz digits: %s\n", tmp); 06162 return -1; 06163 } 06164 06165 if (strlen(s) < 3){ 06166 if(debug) 06167 printf("@@@@ Bad KHz digits: %s\n", s); 06168 return -1; 06169 } 06170 06171 if ((s[2] != '0') && (s[2] != '5')){ 06172 if(debug) 06173 printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]); 06174 return -1; 06175 } 06176 06177 band = rbi_mhztoband(tmp); 06178 if (band == -1){ 06179 if(debug) 06180 printf("@@@@ Bad Band: %s\n", tmp); 06181 return -1; 06182 } 06183 06184 rxpl = rbi_pltocode(myrpt->rxpl); 06185 06186 if (rxpl == -1){ 06187 if(debug) 06188 printf("@@@@ Bad TX PL: %s\n", myrpt->rxpl); 06189 return -1; 06190 } 06191 06192 06193 switch(myrpt->offset) 06194 { 06195 case REM_MINUS: 06196 txoffset = 0; 06197 break; 06198 case REM_PLUS: 06199 txoffset = 0x10; 06200 break; 06201 case REM_SIMPLEX: 06202 txoffset = 0x20; 06203 break; 06204 } 06205 switch(myrpt->powerlevel) 06206 { 06207 case REM_LOWPWR: 06208 txpower = 0; 06209 break; 06210 case REM_MEDPWR: 06211 txpower = 0x20; 06212 break; 06213 case REM_HIPWR: 06214 txpower = 0x10; 06215 break; 06216 } 06217 rbicmd[0] = 0; 06218 rbicmd[1] = band | txpower | 0xc0; 06219 rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80; 06220 if (s[2] == '5') rbicmd[2] |= 0x40; 06221 rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0'); 06222 rbicmd[4] = rxpl; 06223 if (myrpt->txplon) rbicmd[4] |= 0x40; 06224 if (myrpt->rxplon) rbicmd[4] |= 0x80; 06225 rbi_out(myrpt,rbicmd); 06226 return 0; 06227 }
static int setrbi_check | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6229 of file app_rpt.c.
References rpt::freq, MAXREMSTR, rbi_mhztoband(), rbi_pltocode(), rpt::remote, s, and rpt::txpl.
Referenced by setrbi(), and setrem().
06230 { 06231 char tmp[MAXREMSTR] = "",*s; 06232 int band,txpl; 06233 06234 /* must be a remote system */ 06235 if (!myrpt->remote) return(0); 06236 /* must have rbi hardware */ 06237 if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0); 06238 strncpy(tmp, myrpt->freq, sizeof(tmp) - 1); 06239 s = strchr(tmp,'.'); 06240 /* if no decimal, is invalid */ 06241 06242 if (s == NULL){ 06243 if(debug) 06244 printf("@@@@ Frequency needs a decimal\n"); 06245 return -1; 06246 } 06247 06248 *s++ = 0; 06249 if (strlen(tmp) < 2){ 06250 if(debug) 06251 printf("@@@@ Bad MHz digits: %s\n", tmp); 06252 return -1; 06253 } 06254 06255 if (strlen(s) < 3){ 06256 if(debug) 06257 printf("@@@@ Bad KHz digits: %s\n", s); 06258 return -1; 06259 } 06260 06261 if ((s[2] != '0') && (s[2] != '5')){ 06262 if(debug) 06263 printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]); 06264 return -1; 06265 } 06266 06267 band = rbi_mhztoband(tmp); 06268 if (band == -1){ 06269 if(debug) 06270 printf("@@@@ Bad Band: %s\n", tmp); 06271 return -1; 06272 } 06273 06274 txpl = rbi_pltocode(myrpt->txpl); 06275 06276 if (txpl == -1){ 06277 if(debug) 06278 printf("@@@@ Bad TX PL: %s\n", myrpt->txpl); 06279 return -1; 06280 } 06281 return 0; 06282 }
static int setrem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7347 of file app_rpt.c.
References rpt::archivedir, ast_log(), donodelog(), rpt::freq, LOG_ERROR, modes, rpt::name, rpt::offset, rpt::p, rpt::powerlevel, rpt::remmode, rpt::remote, rpt_telemetry(), rpt::rxpl, rpt::rxplon, setrbi_check(), SETREMOTE, rpt::txpl, and rpt::txplon.
Referenced by function_remote(), and rpt_exec().
07348 { 07349 char str[300]; 07350 char *offsets[] = {"MINUS","SIMPLEX","PLUS"}; 07351 char *powerlevels[] = {"LOW","MEDIUM","HIGH"}; 07352 char *modes[] = {"FM","USB","LSB","AM"}; 07353 int res = -1; 07354 07355 if (myrpt->p.archivedir) 07356 { 07357 sprintf(str,"FREQ,%s,%s,%s,%s,%s,%s,%d,%d",myrpt->freq, 07358 modes[(int)myrpt->remmode], 07359 myrpt->txpl,myrpt->rxpl,offsets[(int)myrpt->offset], 07360 powerlevels[(int)myrpt->powerlevel],myrpt->txplon, 07361 myrpt->rxplon); 07362 donodelog(myrpt,str); 07363 } 07364 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07365 { 07366 rpt_telemetry(myrpt,SETREMOTE,NULL); 07367 res = 0; 07368 } 07369 if(!strcmp(myrpt->remote, remote_rig_ic706)) 07370 { 07371 rpt_telemetry(myrpt,SETREMOTE,NULL); 07372 res = 0; 07373 } 07374 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 07375 { 07376 res = setrbi_check(myrpt); 07377 if (!res) 07378 { 07379 rpt_telemetry(myrpt,SETREMOTE,NULL); 07380 res = 0; 07381 } 07382 } 07383 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) { 07384 rpt_telemetry(myrpt,SETREMOTE,NULL); 07385 res = 0; 07386 } 07387 else 07388 res = 0; 07389 07390 if (res < 0) ast_log(LOG_ERROR,"Unable to send remote command on node %s\n",myrpt->name); 07391 07392 return res; 07393 }
static int simple_command_ft897 | ( | struct rpt * | myrpt, | |
char | command | |||
) | [static] |
Definition at line 6542 of file app_rpt.c.
References serial_remote_io().
Referenced by closerem_ft897(), rpt_tele_thread(), and set_ft897().
06543 { 06544 unsigned char cmdstr[5]; 06545 06546 memset(cmdstr, 0, 5); 06547 06548 cmdstr[4] = command; 06549 06550 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06551 06552 }
static int simple_command_ic706 | ( | struct rpt * | myrpt, | |
char | command, | |||
char | subcommand | |||
) | [static] |
Definition at line 6996 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706(), set_mode_ic706(), and set_offset_ic706().
06997 { 06998 unsigned char cmdstr[10]; 06999 07000 cmdstr[0] = cmdstr[1] = 0xfe; 07001 cmdstr[2] = myrpt->p.civaddr; 07002 cmdstr[3] = 0xe0; 07003 cmdstr[4] = command; 07004 cmdstr[5] = subcommand; 07005 cmdstr[6] = 0xfd; 07006 07007 return(civ_cmd(myrpt,cmdstr,7)); 07008 }
static char* skipchars | ( | char * | string, | |
char * | charlist | |||
) | [static] |
Definition at line 1502 of file app_rpt.c.
Referenced by function_autopatchup().
01503 { 01504 int i; 01505 while(*string){ 01506 for(i = 0; charlist[i] ; i++){ 01507 if(*string == charlist[i]){ 01508 string++; 01509 break; 01510 } 01511 } 01512 if(!charlist[i]) 01513 return string; 01514 } 01515 return string; 01516 }
static int split_ctcss_freq | ( | char * | hertz, | |
char * | decimal, | |||
char * | freq | |||
) | [static] |
Definition at line 6395 of file app_rpt.c.
References MAXREMSTR.
Referenced by set_ctcss_freq_ft897().
06396 { 06397 char freq_copy[MAXREMSTR]; 06398 char *decp; 06399 06400 decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.'); 06401 if(decp){ 06402 *decp++ = 0; 06403 strncpy(hertz, freq_copy, MAXREMSTR); 06404 strncpy(decimal, decp, strlen(decp)); 06405 decimal[strlen(decp)] = '\0'; 06406 return 0; 06407 } 06408 else 06409 return -1; 06410 }
static int split_freq | ( | char * | mhz, | |
char * | decimals, | |||
char * | freq | |||
) | [static] |
Definition at line 6372 of file app_rpt.c.
References MAXREMSTR.
Referenced by check_tx_freq(), function_remote(), multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), rpt_tele_thread(), service_scan(), set_freq_ft897(), set_freq_ic706(), and setkenwood().
06373 { 06374 char freq_copy[MAXREMSTR]; 06375 char *decp; 06376 06377 decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.'); 06378 if(decp){ 06379 *decp++ = 0; 06380 strncpy(mhz, freq_copy, MAXREMSTR); 06381 strcpy(decimals, "00000"); 06382 strncpy(decimals, decp, strlen(decp)); 06383 decimals[5] = 0; 06384 return 0; 06385 } 06386 else 06387 return -1; 06388 06389 }
static void stop_scan | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7571 of file app_rpt.c.
References rpt::hfscanstop, rpt_telemetry(), and SCAN.
Referenced by handle_remote_dtmf_digit().
07572 { 07573 myrpt->hfscanstop = 1; 07574 rpt_telemetry(myrpt,SCAN,0); 07575 }
static int telem_any | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
char * | entry | |||
) | [static] |
Definition at line 2720 of file app_rpt.c.
References MORSE, retrieve_astcfgint(), sayfile(), send_morse(), and send_tone_telemetry().
Referenced by rpt_tele_thread(), and telem_lookup().
02721 { 02722 int res; 02723 char c; 02724 02725 static int morsespeed; 02726 static int morsefreq; 02727 static int morseampl; 02728 static int morseidfreq = 0; 02729 static int morseidampl; 02730 static char mcat[] = MORSE; 02731 02732 res = 0; 02733 02734 if(!morseidfreq){ /* Get the morse parameters if not already loaded */ 02735 morsespeed = retrieve_astcfgint(myrpt, mcat, "speed", 5, 20, 20); 02736 morsefreq = retrieve_astcfgint(myrpt, mcat, "frequency", 300, 3000, 800); 02737 morseampl = retrieve_astcfgint(myrpt, mcat, "amplitude", 200, 8192, 4096); 02738 morseidampl = retrieve_astcfgint(myrpt, mcat, "idamplitude", 200, 8192, 2048); 02739 morseidfreq = retrieve_astcfgint(myrpt, mcat, "idfrequency", 300, 3000, 330); 02740 } 02741 02742 /* Is it a file, or a tone sequence? */ 02743 02744 if(entry[0] == '|'){ 02745 c = entry[1]; 02746 if((c >= 'a')&&(c <= 'z')) 02747 c -= 0x20; 02748 02749 switch(c){ 02750 case 'I': /* Morse ID */ 02751 res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl); 02752 break; 02753 02754 case 'M': /* Morse Message */ 02755 res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl); 02756 break; 02757 02758 case 'T': /* Tone sequence */ 02759 res = send_tone_telemetry(chan, entry + 2); 02760 break; 02761 default: 02762 res = -1; 02763 } 02764 } 02765 else 02766 res = sayfile(chan, entry); /* File */ 02767 return res; 02768 }
static int telem_lookup | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
char * | node, | |||
char * | name | |||
) | [static] |
Definition at line 2776 of file app_rpt.c.
References ast_log(), ast_strdupa, ast_variable_retrieve(), rpt::cfg, LOG_WARNING, telem_any(), and TELEMETRY.
Referenced by rpt_tele_thread().
02777 { 02778 02779 int res; 02780 int i; 02781 char *entry; 02782 char *telemetry; 02783 char *telemetry_save; 02784 02785 res = 0; 02786 telemetry_save = NULL; 02787 entry = NULL; 02788 02789 /* Retrieve the section name for telemetry from the node section */ 02790 telemetry = (char *) ast_variable_retrieve(myrpt->cfg, node, TELEMETRY); 02791 if(telemetry ){ 02792 telemetry_save = ast_strdupa(telemetry); 02793 if(!telemetry_save){ 02794 ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n"); 02795 return res; 02796 } 02797 entry = (char *) ast_variable_retrieve(myrpt->cfg, telemetry_save, name); 02798 } 02799 02800 /* Try to look up the telemetry name */ 02801 02802 if(!entry){ 02803 /* Telemetry name wasn't found in the config file, use the default */ 02804 for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){ 02805 if(!strcasecmp(tele_defs[i].name, name)) 02806 entry = tele_defs[i].value; 02807 } 02808 } 02809 if(entry){ 02810 if(strlen(entry)) 02811 telem_any(myrpt,chan, entry); 02812 } 02813 else{ 02814 res = -1; 02815 } 02816 return res; 02817 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11844 of file app_rpt.c.
References ast_cli_unregister(), ast_mutex_destroy(), ast_unregister_application(), lock, name, rpt::nodes, and rpt_vars.
11846 { 11847 int i; 11848 11849 #ifdef OLD_ASTERISK 11850 STANDARD_HANGUP_LOCALUSERS; 11851 #endif 11852 for(i = 0; i < nrpts; i++) { 11853 if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue; 11854 ast_mutex_destroy(&rpt_vars[i].lock); 11855 ast_mutex_destroy(&rpt_vars[i].remlock); 11856 } 11857 i = ast_unregister_application(app); 11858 11859 /* Unregister cli extensions */ 11860 ast_cli_unregister(&cli_debug); 11861 ast_cli_unregister(&cli_dump); 11862 ast_cli_unregister(&cli_stats); 11863 ast_cli_unregister(&cli_lstats); 11864 ast_cli_unregister(&cli_nodes); 11865 ast_cli_unregister(&cli_reload); 11866 ast_cli_unregister(&cli_restart); 11867 ast_cli_unregister(&cli_fun); 11868 11869 return i; 11870 }
static int vfo_ic706 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7180 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07181 { 07182 unsigned char cmdstr[10]; 07183 07184 cmdstr[0] = cmdstr[1] = 0xfe; 07185 cmdstr[2] = myrpt->p.civaddr; 07186 cmdstr[3] = 0xe0; 07187 cmdstr[4] = 7; 07188 cmdstr[5] = 0xfd; 07189 07190 return(civ_cmd(myrpt,cmdstr,6)); 07191 }
static void wait_interval | ( | struct rpt * | myrpt, | |
int | type, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 2895 of file app_rpt.c.
References ast_log(), ast_safe_sleep(), get_wait_interval(), and LOG_NOTICE.
Referenced by rpt_tele_thread().
02896 { 02897 int interval; 02898 interval = get_wait_interval(myrpt, type); 02899 if(debug) 02900 ast_log(LOG_NOTICE," Delay interval = %d\n", interval); 02901 if(interval) 02902 ast_safe_sleep(chan,interval); 02903 if(debug) 02904 ast_log(LOG_NOTICE,"Delay complete\n"); 02905 return; 02906 }
struct ast_cli_entry cli_debug [static] |
Initial value:
{ { "rpt", "debug", "level" }, rpt_do_debug, "Enable app_rpt debugging", debug_usage }
struct ast_cli_entry cli_dump [static] |
Initial value:
{ { "rpt", "dump" }, rpt_do_dump, "Dump app_rpt structs for debugging", dump_usage }
struct ast_cli_entry cli_fun [static] |
Initial value:
{ { "rpt", "fun" }, rpt_do_fun, "Execute a DTMF function", fun_usage }
struct ast_cli_entry cli_lstats [static] |
Initial value:
{ { "rpt", "lstats" }, rpt_do_lstats, "Dump link statistics", dump_lstats }
struct ast_cli_entry cli_nodes [static] |
Initial value:
{ { "rpt", "nodes" }, rpt_do_nodes, "Dump node list", dump_nodes }
struct ast_cli_entry cli_reload [static] |
Initial value:
{ { "rpt", "reload" }, rpt_do_reload, "Reload app_rpt config", reload_usage }
struct ast_cli_entry cli_restart [static] |
Initial value:
{ { "rpt", "restart" }, rpt_do_restart, "Restart app_rpt", restart_usage }
struct ast_cli_entry cli_stats [static] |
Initial value:
{ { "rpt", "stats" }, rpt_do_stats, "Dump node statistics", dump_stats }
int debug = 0 [static] |
Definition at line 354 of file app_rpt.c.
Referenced by add_sdp(), add_t38_sdp(), aji_load_config(), check_user_full(), dladdr(), dlclose(), dlsymIntern(), error(), findFile(), get_mach_header_from_NSModule(), getSearchPath(), handle_request(), insertStatus(), loadModule(), lookupStatus(), process_sdp(), promoteLocalToGlobal(), reference(), search_linked_libs(), set_destination(), and sip_sendtext().
char debug_usage[] [static] |
char dump_lstats[] [static] |
char dump_nodes[] [static] |
char dump_stats[] [static] |
char dump_usage[] [static] |
char fun_usage[] [static] |
struct function_table_tag function_table[] [static] |
int max_chan_stat[] = {22000,1000,22000,100,22000,2000,22000} |
char reload_usage[] [static] |
char remdtmfstr[] = "0123456789*#ABCD" [static] |
char* remote_rig_ft897 = "ft897" [static] |
char* remote_rig_ic706 = "ic706" [static] |
char* remote_rig_kenwood = "kenwood" [static] |
char* remote_rig_rbi = "rbi" [static] |
char restart_usage[] [static] |
pthread_t rpt_master_thread [static] |
Referenced by load_rpt_vars(), reload(), rpt(), rpt_do_dump(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_reload(), rpt_do_restart(), rpt_do_stats(), rpt_exec(), rpt_master(), and unload_module().
time_t starttime = 0 [static] |
char* synopsis = "Radio Repeater/Remote Base Control System" [static] |
char* tdesc = "Radio Repeater / Remote Base version 0.73 09/04/2007" [static] |
struct telem_defaults tele_defs[] [static] |