#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 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 MACROTIME 100 |
Definition at line 160 of file app_rpt.c.
Referenced by do_scheduler(), function_macro(), rpt(), and rpt_do_fun().
#define MAX_RETRIES 5 |
#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(), and rpt_do_fun().
#define MAXNODESTR 300 |
#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 MORSE "morse" |
#define MSWAIT 200 |
#define NODES "nodes" |
#define NRPTSTAT 7 |
#define POLITEID 30000 |
#define QUOTECHR 34 |
#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_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_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 |
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(), and rpt().
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, 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 8404 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().
08405 { 08406 char *val, *s, *s1, *s2, *tele; 08407 char tmp[300], deststr[300] = ""; 08408 08409 val = node_lookup(myrpt,l->name); 08410 if (!val) 08411 { 08412 fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name); 08413 return -1; 08414 } 08415 08416 rpt_mutex_lock(&myrpt->lock); 08417 /* remove from queue */ 08418 remque((struct qelem *) l); 08419 rpt_mutex_unlock(&myrpt->lock); 08420 strncpy(tmp,val,sizeof(tmp) - 1); 08421 s = tmp; 08422 s1 = strsep(&s,","); 08423 s2 = strsep(&s,","); 08424 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 08425 tele = strchr(deststr, '/'); 08426 if (!tele) { 08427 fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr); 08428 return -1; 08429 } 08430 *tele++ = 0; 08431 l->elaptime = 0; 08432 l->connecttime = 0; 08433 l->thisconnected = 0; 08434 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 08435 if (l->chan){ 08436 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 08437 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 08438 l->chan->whentohangup = 0; 08439 l->chan->appl = "Apprpt"; 08440 l->chan->data = "(Remote Rx)"; 08441 if (option_verbose > 2) 08442 ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n", 08443 deststr, tele, l->chan->name); 08444 if(l->chan->cid.cid_num) 08445 free(l->chan->cid.cid_num); 08446 l->chan->cid.cid_num = strdup(myrpt->name); 08447 ast_call(l->chan,tele,999); 08448 08449 } 08450 else 08451 { 08452 if (option_verbose > 2) 08453 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 08454 deststr,tele,l->chan->name); 08455 return -1; 08456 } 08457 rpt_mutex_lock(&myrpt->lock); 08458 /* put back in queue */ 08459 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 08460 rpt_mutex_unlock(&myrpt->lock); 08461 ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name); 08462 return 0; 08463 }
static int check_freq | ( | struct rpt * | myrpt, | |
int | m, | |||
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 7403 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().
07404 { 07405 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07406 return check_freq_ft897(m, d, defmode); 07407 else if(!strcmp(myrpt->remote, remote_rig_ic706)) 07408 return check_freq_ic706(m, d, defmode); 07409 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 07410 return check_freq_rbi(m, d, defmode); 07411 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) 07412 return check_freq_kenwood(m, d, defmode); 07413 else 07414 return -1; 07415 }
static int check_freq_ft897 | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6418 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().
06419 { 06420 int dflmd = REM_MODE_FM; 06421 06422 if(m == 1){ /* 160 meters */ 06423 dflmd = REM_MODE_LSB; 06424 if(d < 80000) 06425 return -1; 06426 } 06427 else if(m == 3){ /* 80 meters */ 06428 dflmd = REM_MODE_LSB; 06429 if(d < 50000) 06430 return -1; 06431 } 06432 else if(m == 7){ /* 40 meters */ 06433 dflmd = REM_MODE_LSB; 06434 if(d > 30000) 06435 return -1; 06436 } 06437 else if(m == 14){ /* 20 meters */ 06438 dflmd = REM_MODE_USB; 06439 if(d > 35000) 06440 return -1; 06441 } 06442 else if(m == 18){ /* 17 meters */ 06443 dflmd = REM_MODE_USB; 06444 if((d < 6800) || (d > 16800)) 06445 return -1; 06446 } 06447 else if(m == 21){ /* 15 meters */ 06448 dflmd = REM_MODE_USB; 06449 if((d < 20000) || (d > 45000)) 06450 return -1; 06451 } 06452 else if(m == 24){ /* 12 meters */ 06453 dflmd = REM_MODE_USB; 06454 if((d < 89000) || (d > 99000)) 06455 return -1; 06456 } 06457 else if(m == 28){ /* 10 meters */ 06458 dflmd = REM_MODE_USB; 06459 } 06460 else if(m == 29){ 06461 if(d >= 51000) 06462 dflmd = REM_MODE_FM; 06463 else 06464 dflmd = REM_MODE_USB; 06465 if(d > 70000) 06466 return -1; 06467 } 06468 else if(m == 50){ /* 6 meters */ 06469 if(d >= 30000) 06470 dflmd = REM_MODE_FM; 06471 else 06472 dflmd = REM_MODE_USB; 06473 06474 } 06475 else if((m >= 51) && ( m < 54)){ 06476 dflmd = REM_MODE_FM; 06477 } 06478 else if(m == 144){ /* 2 meters */ 06479 if(d >= 30000) 06480 dflmd = REM_MODE_FM; 06481 else 06482 dflmd = REM_MODE_USB; 06483 } 06484 else if((m >= 145) && (m < 148)){ 06485 dflmd = REM_MODE_FM; 06486 } 06487 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06488 if(m < 438) 06489 dflmd = REM_MODE_USB; 06490 else 06491 dflmd = REM_MODE_FM; 06492 ; 06493 } 06494 else 06495 return -1; 06496 06497 if(defmode) 06498 *defmode = dflmd; 06499 06500 return 0; 06501 }
static int check_freq_ic706 | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6789 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().
06790 { 06791 int dflmd = REM_MODE_FM; 06792 06793 if(m == 1){ /* 160 meters */ 06794 dflmd = REM_MODE_LSB; 06795 if(d < 80000) 06796 return -1; 06797 } 06798 else if(m == 3){ /* 80 meters */ 06799 dflmd = REM_MODE_LSB; 06800 if(d < 50000) 06801 return -1; 06802 } 06803 else if(m == 7){ /* 40 meters */ 06804 dflmd = REM_MODE_LSB; 06805 if(d > 30000) 06806 return -1; 06807 } 06808 else if(m == 14){ /* 20 meters */ 06809 dflmd = REM_MODE_USB; 06810 if(d > 35000) 06811 return -1; 06812 } 06813 else if(m == 18){ /* 17 meters */ 06814 dflmd = REM_MODE_USB; 06815 if((d < 6800) || (d > 16800)) 06816 return -1; 06817 } 06818 else if(m == 21){ /* 15 meters */ 06819 dflmd = REM_MODE_USB; 06820 if((d < 20000) || (d > 45000)) 06821 return -1; 06822 } 06823 else if(m == 24){ /* 12 meters */ 06824 dflmd = REM_MODE_USB; 06825 if((d < 89000) || (d > 99000)) 06826 return -1; 06827 } 06828 else if(m == 28){ /* 10 meters */ 06829 dflmd = REM_MODE_USB; 06830 } 06831 else if(m == 29){ 06832 if(d >= 51000) 06833 dflmd = REM_MODE_FM; 06834 else 06835 dflmd = REM_MODE_USB; 06836 if(d > 70000) 06837 return -1; 06838 } 06839 else if(m == 50){ /* 6 meters */ 06840 if(d >= 30000) 06841 dflmd = REM_MODE_FM; 06842 else 06843 dflmd = REM_MODE_USB; 06844 06845 } 06846 else if((m >= 51) && ( m < 54)){ 06847 dflmd = REM_MODE_FM; 06848 } 06849 else if(m == 144){ /* 2 meters */ 06850 if(d >= 30000) 06851 dflmd = REM_MODE_FM; 06852 else 06853 dflmd = REM_MODE_USB; 06854 } 06855 else if((m >= 145) && (m < 148)){ 06856 dflmd = REM_MODE_FM; 06857 } 06858 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06859 if(m < 438) 06860 dflmd = REM_MODE_USB; 06861 else 06862 dflmd = REM_MODE_FM; 06863 ; 06864 } 06865 else 06866 return -1; 06867 06868 if(defmode) 06869 *defmode = dflmd; 06870 06871 return 0; 06872 }
static int check_freq_kenwood | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6280 of file app_rpt.c.
References REM_MODE_FM.
Referenced by check_freq().
06281 { 06282 int dflmd = REM_MODE_FM; 06283 06284 if (m == 144){ /* 2 meters */ 06285 if(d < 10100) 06286 return -1; 06287 } 06288 else if((m >= 145) && (m < 148)){ 06289 ; 06290 } 06291 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06292 ; 06293 } 06294 else 06295 return -1; 06296 06297 if(defmode) 06298 *defmode = dflmd; 06299 06300 06301 return 0; 06302 }
static int check_freq_rbi | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6308 of file app_rpt.c.
References REM_MODE_FM.
Referenced by check_freq().
06309 { 06310 int dflmd = REM_MODE_FM; 06311 06312 if(m == 50){ /* 6 meters */ 06313 if(d < 10100) 06314 return -1; 06315 } 06316 else if((m >= 51) && ( m < 54)){ 06317 ; 06318 } 06319 else if(m == 144){ /* 2 meters */ 06320 if(d < 10100) 06321 return -1; 06322 } 06323 else if((m >= 145) && (m < 148)){ 06324 ; 06325 } 06326 else if((m >= 222) && (m < 225)){ /* 1.25 meters */ 06327 ; 06328 } 06329 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06330 ; 06331 } 06332 else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */ 06333 ; 06334 } 06335 else 06336 return -1; 06337 06338 if(defmode) 06339 *defmode = dflmd; 06340 06341 06342 return 0; 06343 }
static char check_tx_freq | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7421 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.
07422 { 07423 int i; 07424 int radio_mhz, radio_decimals, ulimit_mhz, ulimit_decimals, llimit_mhz, llimit_decimals; 07425 char radio_mhz_char[MAXREMSTR]; 07426 char radio_decimals_char[MAXREMSTR]; 07427 char limit_mhz_char[MAXREMSTR]; 07428 char limit_decimals_char[MAXREMSTR]; 07429 char limits[256]; 07430 char *limit_ranges[40]; 07431 struct ast_variable *limitlist; 07432 07433 07434 /* Must have user logged in and tx_limits defined */ 07435 07436 if(!myrpt->p.txlimitsstanzaname || !myrpt->loginuser[0] || !myrpt->loginlevel[0]){ 07437 if(debug > 3){ 07438 ast_log(LOG_NOTICE, "No tx band table defined, or no user logged in\n"); 07439 } 07440 return 1; /* Assume it's ok otherwise */ 07441 } 07442 07443 /* Retrieve the band table for the loginlevel */ 07444 limitlist = ast_variable_browse(myrpt->cfg, myrpt->p.txlimitsstanzaname); 07445 07446 if(!limitlist){ 07447 ast_log(LOG_WARNING, "No entries in %s band table stanza\n", myrpt->p.txlimitsstanzaname); 07448 return 0; 07449 } 07450 07451 split_freq(radio_mhz_char, radio_decimals_char, myrpt->freq); 07452 radio_mhz = atoi(radio_mhz_char); 07453 radio_decimals = decimals2int(radio_decimals_char); 07454 07455 07456 if(debug > 3){ 07457 ast_log(LOG_NOTICE, "Login User = %s, login level = %s\n", myrpt->loginuser, myrpt->loginlevel); 07458 } 07459 07460 /* Find our entry */ 07461 07462 for(;limitlist; limitlist=limitlist->next){ 07463 if(!strcmp(limitlist->name, myrpt->loginlevel)) 07464 break; 07465 } 07466 07467 if(!limitlist){ 07468 ast_log(LOG_WARNING, "Can't find %s entry in band table stanza %s\n", myrpt->loginlevel, myrpt->p.txlimitsstanzaname); 07469 return 0; 07470 } 07471 07472 if(debug > 3){ 07473 ast_log(LOG_NOTICE, "Auth %s = %s\n", limitlist->name, limitlist->value); 07474 } 07475 07476 /* Parse the limits */ 07477 07478 strncpy(limits, limitlist->value, 256); 07479 limits[255] = 0; 07480 finddelim(limits, limit_ranges, 40); 07481 for(i = 0; i < 40 && limit_ranges[i] ; i++){ 07482 char range[40]; 07483 char *r,*s; 07484 strncpy(range, limit_ranges[i], 40); 07485 range[39] = 0; 07486 if(debug > 3){ 07487 ast_log(LOG_NOTICE, "Checking to see if %s is within limits of %s\n", myrpt->freq, range); 07488 } 07489 07490 r = strchr(range, '-'); 07491 if(!r){ 07492 ast_log(LOG_WARNING, "Malformed range in %s tx band table entry\n", limitlist->name); 07493 return 0; 07494 } 07495 *r++ = 0; 07496 s = eatwhite(range); 07497 r = eatwhite(r); 07498 split_freq(limit_mhz_char, limit_decimals_char, s); 07499 llimit_mhz = atoi(limit_mhz_char); 07500 llimit_decimals = decimals2int(limit_decimals_char); 07501 split_freq(limit_mhz_char, limit_decimals_char, r); 07502 ulimit_mhz = atoi(limit_mhz_char); 07503 ulimit_decimals = decimals2int(limit_decimals_char); 07504 07505 if((radio_mhz >= llimit_mhz) && (radio_mhz <= ulimit_mhz)){ 07506 if(radio_mhz == llimit_mhz){ /* CASE 1: TX freq is in llimit mhz portion of band */ 07507 if(radio_decimals >= llimit_decimals){ /* Cannot be below llimit decimals */ 07508 if(llimit_mhz == ulimit_mhz){ /* If bandwidth < 1Mhz, check ulimit decimals */ 07509 if(radio_decimals <= ulimit_decimals){ 07510 return 1; 07511 } 07512 else{ 07513 if(debug > 3) 07514 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 1\n"); 07515 return 0; 07516 } 07517 } 07518 else{ 07519 return 1; 07520 } 07521 } 07522 else{ /* Is below llimit decimals */ 07523 if(debug > 3) 07524 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 2\n"); 07525 return 0; 07526 } 07527 } 07528 else if(radio_mhz == ulimit_mhz){ /* CASE 2: TX freq not in llimit mhz portion of band */ 07529 if(radio_decimals <= ulimit_decimals){ 07530 return 1; 07531 } 07532 else{ /* Is above ulimit decimals */ 07533 if(debug > 3) 07534 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 3\n"); 07535 return 0; 07536 } 07537 } 07538 else /* CASE 3: TX freq within a multi-Mhz band and ok */ 07539 return 1; 07540 } 07541 } 07542 if(debug > 3) /* No match found in TX band table */ 07543 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 4\n"); 07544 return 0; 07545 }
static int civ_cmd | ( | struct rpt * | myrpt, | |
unsigned char * | cmd, | |||
int | cmdlen | |||
) | [static] |
Definition at line 5956 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().
05957 { 05958 unsigned char rxbuf[100]; 05959 int i,rv ; 05960 05961 rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0); 05962 if (rv == -1) return(-1); 05963 if (rv != (cmdlen + 6)) return(1); 05964 for(i = 0; i < 6; i++) 05965 if (rxbuf[i] != cmd[i]) return(1); 05966 if (rxbuf[cmdlen] != 0xfe) return(1); 05967 if (rxbuf[cmdlen + 1] != 0xfe) return(1); 05968 if (rxbuf[cmdlen + 4] != 0xfb) return(1); 05969 if (rxbuf[cmdlen + 5] != 0xfd) return(1); 05970 return(0); 05971 }
static int closerem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7391 of file app_rpt.c.
References closerem_ft897(), and rpt::remote.
07392 { 07393 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07394 return closerem_ft897(myrpt); 07395 else 07396 return 0; 07397 }
static int closerem_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6729 of file app_rpt.c.
References simple_command_ft897().
Referenced by closerem().
06730 { 06731 simple_command_ft897(myrpt, 0x88); /* PTT off */ 06732 return 0; 06733 }
static int collect_function_digits | ( | struct rpt * | myrpt, | |
char * | digits, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5226 of file app_rpt.c.
References ast_variable_browse(), rpt::cfg, DC_ERROR, DC_INDETERMINATE, rpt::dphone_functions, rpt::dphone_longestfunc, function_table, 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().
05228 { 05229 int i; 05230 char *stringp,*action,*param,*functiondigits; 05231 char function_table_name[30] = ""; 05232 char workstring[200]; 05233 05234 struct ast_variable *vp; 05235 05236 if(debug) 05237 printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source); 05238 05239 if (command_source == SOURCE_DPHONE) { 05240 if (!myrpt->p.dphone_functions) return DC_INDETERMINATE; 05241 strncpy(function_table_name, myrpt->p.dphone_functions, sizeof(function_table_name) - 1); 05242 } 05243 else if (command_source == SOURCE_PHONE) { 05244 if (!myrpt->p.phone_functions) return DC_INDETERMINATE; 05245 strncpy(function_table_name, myrpt->p.phone_functions, sizeof(function_table_name) - 1); 05246 } 05247 else if (command_source == SOURCE_LNK) 05248 strncpy(function_table_name, myrpt->p.link_functions, sizeof(function_table_name) - 1); 05249 else 05250 strncpy(function_table_name, myrpt->p.functions, sizeof(function_table_name) - 1); 05251 vp = ast_variable_browse(myrpt->cfg, function_table_name); 05252 while(vp) { 05253 if(!strncasecmp(vp->name, digits, strlen(vp->name))) 05254 break; 05255 vp = vp->next; 05256 } 05257 if(!vp) { 05258 int n; 05259 05260 n = myrpt->longestfunc; 05261 if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc; 05262 else 05263 if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc; 05264 else 05265 if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc; 05266 05267 if(strlen(digits) >= n) 05268 return DC_ERROR; 05269 else 05270 return DC_INDETERMINATE; 05271 } 05272 /* Found a match, retrieve value part and parse */ 05273 strncpy(workstring, vp->value, sizeof(workstring) - 1 ); 05274 stringp = workstring; 05275 action = strsep(&stringp, ","); 05276 param = stringp; 05277 if(debug) 05278 printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)"); 05279 /* Look up the action */ 05280 for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){ 05281 if(!strncasecmp(action, function_table[i].action, strlen(action))) 05282 break; 05283 } 05284 if(debug) 05285 printf("@@@@ table index i = %d\n",i); 05286 if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){ 05287 /* Error, action not in table */ 05288 return DC_ERROR; 05289 } 05290 if(function_table[i].function == NULL){ 05291 /* Error, function undefined */ 05292 if(debug) 05293 printf("@@@@ NULL for action: %s\n",action); 05294 return DC_ERROR; 05295 } 05296 functiondigits = digits + strlen(vp->name); 05297 return (*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink); 05298 }
static int connect_link | ( | struct rpt * | myrpt, | |
char * | node, | |||
int | mode, | |||
int | perma | |||
) | [static] |
Definition at line 4466 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().
04467 { 04468 char *val, *s, *s1, *s2, *tele; 04469 char lstr[MAXLINKLIST],*strs[MAXLINKLIST]; 04470 char tmp[300], deststr[300] = "",modechange = 0; 04471 struct rpt_link *l; 04472 int reconnects = 0; 04473 int i,n; 04474 ZT_CONFINFO ci; /* conference info */ 04475 04476 val = node_lookup(myrpt,node); 04477 if (!val){ 04478 if(strlen(node) >= myrpt->longestnode) 04479 return -1; /* No such node */ 04480 return 1; /* No match yet */ 04481 } 04482 if(debug > 3){ 04483 ast_log(LOG_NOTICE,"Connect attempt to node %s\n", node); 04484 ast_log(LOG_NOTICE,"Mode: %s\n",(mode)?"Transceive":"Monitor"); 04485 ast_log(LOG_NOTICE,"Connection type: %s\n",(perma)?"Permalink":"Normal"); 04486 } 04487 04488 strncpy(tmp,val,sizeof(tmp) - 1); 04489 s = tmp; 04490 s1 = strsep(&s,","); 04491 s2 = strsep(&s,","); 04492 rpt_mutex_lock(&myrpt->lock); 04493 l = myrpt->links.next; 04494 /* try to find this one in queue */ 04495 while(l != &myrpt->links){ 04496 if (l->name[0] == '0') 04497 { 04498 l = l->next; 04499 continue; 04500 } 04501 /* if found matching string */ 04502 if (!strcmp(l->name, node)) 04503 break; 04504 l = l->next; 04505 } 04506 /* if found */ 04507 if (l != &myrpt->links){ 04508 /* if already in this mode, just ignore */ 04509 if ((l->mode) || (!l->chan)) { 04510 rpt_mutex_unlock(&myrpt->lock); 04511 return 2; /* Already linked */ 04512 } 04513 reconnects = l->reconnects; 04514 rpt_mutex_unlock(&myrpt->lock); 04515 if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV); 04516 l->retries = l->max_retries + 1; 04517 l->disced = 2; 04518 modechange = 1; 04519 } else 04520 { 04521 __mklinklist(myrpt,NULL,lstr); 04522 rpt_mutex_unlock(&myrpt->lock); 04523 n = finddelim(lstr,strs,MAXLINKLIST); 04524 for(i = 0; i < n; i++) 04525 { 04526 if ((*strs[i] < '0') || 04527 (*strs[i] > '9')) strs[i]++; 04528 if (!strcmp(strs[i],node)) 04529 { 04530 return 2; /* Already linked */ 04531 } 04532 } 04533 } 04534 strncpy(myrpt->lastlinknode,node,MAXNODESTR - 1); 04535 /* establish call */ 04536 l = malloc(sizeof(struct rpt_link)); 04537 if (!l) 04538 { 04539 ast_log(LOG_WARNING, "Unable to malloc\n"); 04540 return -1; 04541 } 04542 /* zero the silly thing */ 04543 memset((char *)l,0,sizeof(struct rpt_link)); 04544 l->mode = mode; 04545 l->outbound = 1; 04546 l->thisconnected = 0; 04547 strncpy(l->name, node, MAXNODESTR - 1); 04548 l->isremote = (s && ast_true(s)); 04549 if (modechange) l->connected = 1; 04550 l->hasconnected = l->perma = perma; 04551 #ifdef ALLOW_LOCAL_CHANNELS 04552 if ((strncasecmp(s1,"iax2/", 5) == 0) || (strncasecmp(s1, "local/", 6) == 0)) 04553 strncpy(deststr, s1, sizeof(deststr)); 04554 else 04555 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 04556 #else 04557 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 04558 #endif 04559 tele = strchr(deststr, '/'); 04560 if (!tele){ 04561 ast_log(LOG_WARNING,"link3:Dial number (%s) must be in format tech/number\n",deststr); 04562 free(l); 04563 return -1; 04564 } 04565 *tele++ = 0; 04566 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 04567 if (l->chan){ 04568 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 04569 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 04570 #ifdef AST_CDR_FLAG_POST_DISABLED 04571 ast_set_flag(l->chan->cdr,AST_CDR_FLAG_POST_DISABLED); 04572 #endif 04573 l->chan->whentohangup = 0; 04574 l->chan->appl = "Apprpt"; 04575 l->chan->data = "(Remote Rx)"; 04576 if (debug > 3) 04577 ast_log(LOG_NOTICE, "rpt (remote) initiating call to %s/%s on %s\n", 04578 deststr, tele, l->chan->name); 04579 if(l->chan->cid.cid_num) 04580 free(l->chan->cid.cid_num); 04581 l->chan->cid.cid_num = strdup(myrpt->name); 04582 ast_call(l->chan,tele,999); 04583 } 04584 else { 04585 if(debug > 3) 04586 ast_log(LOG_NOTICE, "Unable to place call to %s/%s on %s\n", 04587 deststr,tele,l->chan->name); 04588 if (myrpt->p.archivedir) 04589 { 04590 char str[100]; 04591 sprintf(str,"LINKFAIL,%s",l->name); 04592 donodelog(myrpt,str); 04593 } 04594 free(l); 04595 return -1; 04596 } 04597 /* allocate a pseudo-channel thru asterisk */ 04598 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04599 if (!l->pchan){ 04600 ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n"); 04601 ast_hangup(l->chan); 04602 free(l); 04603 return -1; 04604 } 04605 ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR); 04606 ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR); 04607 #ifdef AST_CDR_FLAG_POST_DISABLED 04608 ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED); 04609 #endif 04610 /* make a conference for the tx */ 04611 ci.chan = 0; 04612 ci.confno = myrpt->conf; 04613 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 04614 /* first put the channel on the conference in proper mode */ 04615 if (ioctl(l->pchan->fds[0], ZT_SETCONF, &ci) == -1) 04616 { 04617 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04618 ast_hangup(l->chan); 04619 ast_hangup(l->pchan); 04620 free(l); 04621 return -1; 04622 } 04623 rpt_mutex_lock(&myrpt->lock); 04624 l->reconnects = reconnects; 04625 /* insert at end of queue */ 04626 l->max_retries = MAX_RETRIES; 04627 if (perma) 04628 l->max_retries = MAX_RETRIES_PERM; 04629 if (l->isremote) l->retries = l->max_retries + 1; 04630 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 04631 __kickshort(myrpt); 04632 rpt_mutex_unlock(&myrpt->lock); 04633 return 0; 04634 }
static int decimals2int | ( | char * | fraction | ) | [static] |
Definition at line 6349 of file app_rpt.c.
Referenced by check_tx_freq().
06350 { 06351 int i; 06352 char len = strlen(fraction); 06353 int multiplier = 100000; 06354 int res = 0; 06355 06356 if(!len) 06357 return 0; 06358 for( i = 0 ; i < len ; i++, multiplier /= 10) 06359 res += (fraction[i] - '0') * multiplier; 06360 return res; 06361 }
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().
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(), and rpt().
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 8639 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, rpt::skedstanzaname, rpt::sysstate_cur, and ast_variable::value.
Referenced by rpt().
08640 { 08641 int i,res; 08642 struct tm tmnow; 08643 struct ast_variable *skedlist; 08644 char *strs[5],*vp,*val,value[100]; 08645 08646 memcpy(&myrpt->lasttv, &myrpt->curtv, sizeof(struct timeval)); 08647 08648 if( (res = gettimeofday(&myrpt->curtv, NULL)) < 0) 08649 ast_log(LOG_NOTICE, "Scheduler gettime of day returned: %s\n", strerror(res)); 08650 08651 /* Try to get close to a 1 second resolution */ 08652 08653 if(myrpt->lasttv.tv_sec == myrpt->curtv.tv_sec) 08654 return; 08655 08656 rpt_localtime(&myrpt->curtv.tv_sec, &tmnow); 08657 08658 /* If midnight, then reset all daily statistics */ 08659 08660 if((tmnow.tm_hour == 0)&&(tmnow.tm_min == 0)&&(tmnow.tm_sec == 0)){ 08661 myrpt->dailykeyups = 0; 08662 myrpt->dailytxtime = 0; 08663 myrpt->dailykerchunks = 0; 08664 myrpt->dailyexecdcommands = 0; 08665 } 08666 08667 if(tmnow.tm_sec != 0) 08668 return; 08669 08670 /* Code below only executes once per minute */ 08671 08672 08673 /* Don't schedule if remote */ 08674 08675 if (myrpt->remote) 08676 return; 08677 08678 /* Don't schedule if disabled */ 08679 08680 if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable){ 08681 if(debug > 6) 08682 ast_log(LOG_NOTICE, "Scheduler disabled\n"); 08683 return; 08684 } 08685 08686 if(!myrpt->p.skedstanzaname){ /* No stanza means we do nothing */ 08687 if(debug > 6) 08688 ast_log(LOG_NOTICE,"No stanza for scheduler in rpt.conf\n"); 08689 return; 08690 } 08691 08692 /* get pointer to linked list of scheduler entries */ 08693 skedlist = ast_variable_browse(myrpt->cfg, myrpt->p.skedstanzaname); 08694 08695 if(debug > 6){ 08696 ast_log(LOG_NOTICE, "Time now: %02d:%02d %02d %02d %02d\n", 08697 tmnow.tm_hour,tmnow.tm_min,tmnow.tm_mday,tmnow.tm_mon + 1, tmnow.tm_wday); 08698 } 08699 /* walk the list */ 08700 for(; skedlist; skedlist = skedlist->next){ 08701 if(debug > 6) 08702 ast_log(LOG_NOTICE, "Scheduler entry %s = %s being considered\n",skedlist->name, skedlist->value); 08703 strncpy(value,skedlist->value,99); 08704 value[99] = 0; 08705 /* point to the substrings for minute, hour, dom, month, and dow */ 08706 for( i = 0, vp = value ; i < 5; i++){ 08707 if(!*vp) 08708 break; 08709 while((*vp == ' ') || (*vp == 0x09)) /* get rid of any leading white space */ 08710 vp++; 08711 strs[i] = vp; /* save pointer to beginning of substring */ 08712 while((*vp != ' ') && (*vp != 0x09) && (*vp != 0)) /* skip over substring */ 08713 vp++; 08714 if(*vp) 08715 *vp++ = 0; /* mark end of substring */ 08716 } 08717 if(debug > 6) 08718 ast_log(LOG_NOTICE, "i = %d, min = %s, hour = %s, mday=%s, mon=%s, wday=%s\n",i, 08719 strs[0], strs[1], strs[2], strs[3], strs[4]); 08720 if(i == 5){ 08721 if((*strs[0] != '*')&&(atoi(strs[0]) != tmnow.tm_min)) 08722 continue; 08723 if((*strs[1] != '*')&&(atoi(strs[1]) != tmnow.tm_hour)) 08724 continue; 08725 if((*strs[2] != '*')&&(atoi(strs[2]) != tmnow.tm_mday)) 08726 continue; 08727 if((*strs[3] != '*')&&(atoi(strs[3]) != tmnow.tm_mon + 1)) 08728 continue; 08729 if(atoi(strs[4]) == 7) 08730 strs[4] = "0"; 08731 if((*strs[4] != '*')&&(atoi(strs[4]) != tmnow.tm_wday)) 08732 continue; 08733 if(debug) 08734 ast_log(LOG_NOTICE, "Executing scheduler entry %s = %s\n", skedlist->name, skedlist->value); 08735 if(atoi(skedlist->name) == 0) 08736 return; /* Zero is reserved for the startup macro */ 08737 val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, skedlist->name); 08738 if (!val){ 08739 ast_log(LOG_WARNING,"Scheduler could not find macro %s\n",skedlist->name); 08740 return; /* Macro not found */ 08741 } 08742 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)){ 08743 ast_log(LOG_WARNING, "Scheduler could not execute macro %s: Macro buffer full\n", 08744 skedlist->name); 08745 return; /* Macro buffer full */ 08746 } 08747 myrpt->macrotimer = MACROTIME; 08748 strncat(myrpt->macrobuf,val,MAXMACRO - strlen(myrpt->macrobuf) - 1); 08749 } 08750 else{ 08751 ast_log(LOG_WARNING,"Malformed scheduler entry in rpt.conf: %s = %s\n", 08752 skedlist->name, skedlist->value); 08753 } 08754 } 08755 08756 }
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(), 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 4997 of file app_rpt.c.
References rpt::callmode, DC_COMPLETE, DC_ERROR, rpt::lock, rpt::p, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::s, rpt::sysstate_cur, and TERM.
04998 { 04999 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 05000 return DC_ERROR; 05001 05002 if(debug) 05003 printf("@@@@ Autopatch down\n"); 05004 05005 rpt_mutex_lock(&myrpt->lock); 05006 05007 if (!myrpt->callmode){ 05008 rpt_mutex_unlock(&myrpt->lock); 05009 return DC_COMPLETE; 05010 } 05011 05012 myrpt->callmode = 0; 05013 rpt_mutex_unlock(&myrpt->lock); 05014 rpt_telemetry(myrpt, TERM, NULL); 05015 return DC_COMPLETE; 05016 }
static int function_autopatchup | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 4900 of file app_rpt.c.
References ast_log(), ast_pthread_create, ast_strdupa, 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(), and rpt::sysstate_cur.
04901 { 04902 pthread_attr_t attr; 04903 int i, index, paramlength; 04904 char *lparam; 04905 char *value = NULL; 04906 char *paramlist[20]; 04907 04908 static char *keywords[] = { 04909 "context", 04910 "dialtime", 04911 "farenddisconnect", 04912 "noct", 04913 "quiet", 04914 NULL 04915 }; 04916 04917 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 04918 return DC_ERROR; 04919 04920 if(debug) 04921 printf("@@@@ Autopatch up\n"); 04922 04923 if(!myrpt->callmode){ 04924 /* Set defaults */ 04925 myrpt->patchnoct = 0; 04926 myrpt->patchdialtime = 0; 04927 myrpt->patchfarenddisconnect = 0; 04928 myrpt->patchquiet = 0; 04929 strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT); 04930 04931 if(param){ 04932 /* Process parameter list */ 04933 lparam = ast_strdupa(param); 04934 if(!lparam){ 04935 ast_log(LOG_ERROR,"App_rpt out of memory on line %d\n",__LINE__); 04936 return DC_ERROR; 04937 } 04938 paramlength = finddelim(lparam, paramlist, 20); 04939 for(i = 0; i < paramlength; i++){ 04940 index = matchkeyword(paramlist[i], &value, keywords); 04941 if(value) 04942 value = skipchars(value, "= "); 04943 switch(index){ 04944 04945 case 1: /* context */ 04946 strncpy(myrpt->patchcontext, value, MAXPATCHCONTEXT - 1) ; 04947 break; 04948 04949 case 2: /* dialtime */ 04950 myrpt->patchdialtime = atoi(value); 04951 break; 04952 04953 case 3: /* farenddisconnect */ 04954 myrpt->patchfarenddisconnect = atoi(value); 04955 break; 04956 04957 case 4: /* noct */ 04958 myrpt->patchnoct = atoi(value); 04959 break; 04960 04961 case 5: /* quiet */ 04962 myrpt->patchquiet = atoi(value); 04963 break; 04964 04965 default: 04966 break; 04967 } 04968 } 04969 } 04970 } 04971 04972 rpt_mutex_lock(&myrpt->lock); 04973 04974 /* if on call, force * into current audio stream */ 04975 04976 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){ 04977 myrpt->mydtmf = myrpt->p.endchar; 04978 } 04979 if (myrpt->callmode){ 04980 rpt_mutex_unlock(&myrpt->lock); 04981 return DC_COMPLETE; 04982 } 04983 myrpt->callmode = 1; 04984 myrpt->cidx = 0; 04985 myrpt->exten[myrpt->cidx] = 0; 04986 rpt_mutex_unlock(&myrpt->lock); 04987 pthread_attr_init(&attr); 04988 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04989 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt); 04990 return DC_COMPLETE; 04991 }
static int function_cop | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5098 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.
05099 { 05100 char string[16]; 05101 05102 if(!param) 05103 return DC_ERROR; 05104 05105 switch(myatoi(param)){ 05106 case 1: /* System reset */ 05107 system("killall -9 asterisk"); 05108 return DC_COMPLETE; 05109 05110 case 2: 05111 myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 0; 05112 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA"); 05113 return DC_COMPLETE; 05114 05115 case 3: 05116 myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 1; 05117 return DC_COMPLETE; 05118 05119 case 4: /* test tone on */ 05120 if (myrpt->stopgen < 0) 05121 { 05122 myrpt->stopgen = 1; 05123 } 05124 else 05125 { 05126 myrpt->stopgen = 0; 05127 rpt_telemetry(myrpt, TEST_TONE, NULL); 05128 } 05129 return DC_COMPLETE; 05130 05131 case 5: /* Disgorge variables to log for debug purposes */ 05132 myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 05133 return DC_COMPLETE; 05134 05135 case 6: /* Simulate COR being activated (phone only) */ 05136 if (command_source != SOURCE_PHONE) return DC_INDETERMINATE; 05137 return DC_DOKEY; 05138 05139 05140 case 7: /* Time out timer enable */ 05141 myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 0; 05142 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTENA"); 05143 return DC_COMPLETE; 05144 05145 case 8: /* Time out timer disable */ 05146 myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 1; 05147 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTDIS"); 05148 return DC_COMPLETE; 05149 05150 case 9: /* Autopatch enable */ 05151 myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 0; 05152 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APENA"); 05153 return DC_COMPLETE; 05154 05155 case 10: /* Autopatch disable */ 05156 myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 1; 05157 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APDIS"); 05158 return DC_COMPLETE; 05159 05160 case 11: /* Link Enable */ 05161 myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 0; 05162 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKENA"); 05163 return DC_COMPLETE; 05164 05165 case 12: /* Link Disable */ 05166 myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 1; 05167 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKDIS"); 05168 return DC_COMPLETE; 05169 05170 case 13: /* Query System State */ 05171 string[0] = string[1] = 'S'; 05172 string[2] = myrpt->p.sysstate_cur + '0'; 05173 string[3] = '\0'; 05174 rpt_telemetry(myrpt, ARB_ALPHA, (void *) string); 05175 return DC_COMPLETE; 05176 05177 case 14: /* Change System State */ 05178 if(strlen(digitbuf) == 0) 05179 break; 05180 if((digitbuf[0] < '0') || (digitbuf[0] > '9')) 05181 return DC_ERROR; 05182 myrpt->p.sysstate_cur = digitbuf[0] - '0'; 05183 string[0] = string[1] = 'S'; 05184 string[2] = myrpt->p.sysstate_cur + '0'; 05185 string[3] = '\0'; 05186 rpt_telemetry(myrpt, ARB_ALPHA, (void *) string); 05187 return DC_COMPLETE; 05188 05189 case 15: /* Scheduler Enable */ 05190 myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 0; 05191 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKENA"); 05192 return DC_COMPLETE; 05193 05194 case 16: /* Scheduler Disable */ 05195 myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 1; 05196 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKDIS"); 05197 return DC_COMPLETE; 05198 05199 case 17: /* User functions Enable */ 05200 myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 0; 05201 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFENA"); 05202 return DC_COMPLETE; 05203 05204 case 18: /* User Functions Disable */ 05205 myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 1; 05206 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFDIS"); 05207 return DC_COMPLETE; 05208 05209 case 19: /* Alternate Tail Enable */ 05210 myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 1; 05211 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATENA"); 05212 return DC_COMPLETE; 05213 05214 case 20: /* Alternate Tail Disable */ 05215 myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 0; 05216 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATDIS"); 05217 return DC_COMPLETE; 05218 } 05219 return DC_INDETERMINATE; 05220 }
static int function_ilink | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 4642 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, 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, and rpt::sysstate_cur.
04643 { 04644 04645 char *val, *s, *s1, *s2; 04646 char tmp[300]; 04647 char digitbuf[MAXNODESTR],*strs[MAXLINKLIST]; 04648 char mode,perma; 04649 struct rpt_link *l; 04650 int i,r; 04651 04652 if(!param) 04653 return DC_ERROR; 04654 04655 04656 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable ) 04657 return DC_ERROR; 04658 04659 strncpy(digitbuf,digits,MAXNODESTR - 1); 04660 04661 if(debug > 6) 04662 printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 04663 04664 switch(myatoi(param)){ 04665 case 11: /* Perm Link off */ 04666 case 1: /* Link off */ 04667 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04668 strcpy(digitbuf,myrpt->lastlinknode); 04669 val = node_lookup(myrpt,digitbuf); 04670 if (!val){ 04671 if(strlen(digitbuf) >= myrpt->longestnode) 04672 return DC_ERROR; 04673 break; 04674 } 04675 strncpy(tmp,val,sizeof(tmp) - 1); 04676 s = tmp; 04677 s1 = strsep(&s,","); 04678 s2 = strsep(&s,","); 04679 rpt_mutex_lock(&myrpt->lock); 04680 l = myrpt->links.next; 04681 /* try to find this one in queue */ 04682 while(l != &myrpt->links){ 04683 if (l->name[0] == '0') 04684 { 04685 l = l->next; 04686 continue; 04687 } 04688 /* if found matching string */ 04689 if (!strcmp(l->name, digitbuf)) 04690 break; 04691 l = l->next; 04692 } 04693 if (l != &myrpt->links){ /* if found */ 04694 struct ast_frame wf; 04695 04696 /* must use perm command on perm link */ 04697 if ((myatoi(param) < 10) && 04698 (l->max_retries > MAX_RETRIES)) 04699 { 04700 rpt_mutex_unlock(&myrpt->lock); 04701 return DC_COMPLETE; 04702 } 04703 strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1); 04704 l->retries = l->max_retries + 1; 04705 l->disced = 1; 04706 rpt_mutex_unlock(&myrpt->lock); 04707 wf.frametype = AST_FRAME_TEXT; 04708 wf.subclass = 0; 04709 wf.offset = 0; 04710 wf.mallocd = 0; 04711 wf.datalen = strlen(discstr) + 1; 04712 wf.samples = 0; 04713 wf.data = discstr; 04714 if (l->chan) 04715 { 04716 ast_write(l->chan,&wf); 04717 if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR; 04718 ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 04719 } 04720 rpt_telemetry(myrpt, COMPLETE, NULL); 04721 return DC_COMPLETE; 04722 } 04723 rpt_mutex_unlock(&myrpt->lock); 04724 return DC_COMPLETE; 04725 case 2: /* Link Monitor */ 04726 case 3: /* Link transceive */ 04727 case 12: /* Link Monitor permanent */ 04728 case 13: /* Link transceive permanent */ 04729 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04730 strcpy(digitbuf,myrpt->lastlinknode); 04731 /* Attempt connection */ 04732 perma = (atoi(param) > 10) ? 1 : 0; 04733 mode = (atoi(param) & 1) ? 1 : 0; 04734 r = connect_link(myrpt, digitbuf, mode, perma); 04735 switch(r){ 04736 case 0: 04737 rpt_telemetry(myrpt, COMPLETE, NULL); 04738 return DC_COMPLETE; 04739 04740 case 1: 04741 break; 04742 04743 case 2: 04744 rpt_telemetry(myrpt, REMALREADY, NULL); 04745 return DC_COMPLETE; 04746 04747 default: 04748 rpt_telemetry(myrpt, CONNFAIL, NULL); 04749 return DC_COMPLETE; 04750 } 04751 break; 04752 04753 case 4: /* Enter Command Mode */ 04754 04755 /* if doesnt allow link cmd, or no links active, return */ 04756 if (((command_source != SOURCE_RPT) && 04757 (command_source != SOURCE_PHONE) && 04758 (command_source != SOURCE_DPHONE)) || 04759 (myrpt->links.next == &myrpt->links)) 04760 return DC_COMPLETE; 04761 04762 /* if already in cmd mode, or selected self, fughetabahtit */ 04763 if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){ 04764 04765 rpt_telemetry(myrpt, REMALREADY, NULL); 04766 return DC_COMPLETE; 04767 } 04768 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04769 strcpy(digitbuf,myrpt->lastlinknode); 04770 /* node must at least exist in list */ 04771 val = node_lookup(myrpt,digitbuf); 04772 if (!val){ 04773 if(strlen(digitbuf) >= myrpt->longestnode) 04774 return DC_ERROR; 04775 break; 04776 04777 } 04778 rpt_mutex_lock(&myrpt->lock); 04779 strcpy(myrpt->lastlinknode,digitbuf); 04780 strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1); 04781 rpt_mutex_unlock(&myrpt->lock); 04782 rpt_telemetry(myrpt, REMGO, NULL); 04783 return DC_COMPLETE; 04784 04785 case 5: /* Status */ 04786 rpt_telemetry(myrpt, STATUS, NULL); 04787 return DC_COMPLETE; 04788 04789 case 15: /* Full Status */ 04790 rpt_telemetry(myrpt, FULLSTATUS, NULL); 04791 return DC_COMPLETE; 04792 04793 04794 case 6: /* All Links Off, including permalinks */ 04795 rpt_mutex_lock(&myrpt->lock); 04796 myrpt->savednodes[0] = 0; 04797 l = myrpt->links.next; 04798 /* loop through all links */ 04799 while(l != &myrpt->links){ 04800 struct ast_frame wf; 04801 if (l->name[0] == '0') /* Skip any IAXRPT monitoring */ 04802 { 04803 l = l->next; 04804 continue; 04805 } 04806 /* Make a string of disconnected nodes for possible restoration */ 04807 sprintf(tmp,"%c%c%s",(l->mode) ? 'X' : 'M',(l->perma) ? 'P':'T',l->name); 04808 if(strlen(tmp) + strlen(myrpt->savednodes) + 1 < MAXNODESTR){ 04809 if(myrpt->savednodes[0]) 04810 strcat(myrpt->savednodes, ","); 04811 strcat(myrpt->savednodes, tmp); 04812 } 04813 l->retries = l->max_retries + 1; 04814 l->disced = 2; /* Silently disconnect */ 04815 rpt_mutex_unlock(&myrpt->lock); 04816 /* ast_log(LOG_NOTICE,"dumping link %s\n",l->name); */ 04817 04818 wf.frametype = AST_FRAME_TEXT; 04819 wf.subclass = 0; 04820 wf.offset = 0; 04821 wf.mallocd = 0; 04822 wf.datalen = strlen(discstr) + 1; 04823 wf.samples = 0; 04824 wf.data = discstr; 04825 if (l->chan) 04826 { 04827 ast_write(l->chan,&wf); 04828 ast_safe_sleep(l->chan,250); /* It's dead already, why check the return value? */ 04829 ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 04830 } 04831 rpt_mutex_lock(&myrpt->lock); 04832 l = l->next; 04833 } 04834 rpt_mutex_unlock(&myrpt->lock); 04835 if(debug > 3) 04836 ast_log(LOG_NOTICE,"Nodes disconnected: %s\n",myrpt->savednodes); 04837 rpt_telemetry(myrpt, COMPLETE, NULL); 04838 return DC_COMPLETE; 04839 04840 case 7: /* Identify last node which keyed us up */ 04841 rpt_telemetry(myrpt, LASTNODEKEY, NULL); 04842 break; 04843 04844 04845 #ifdef _MDC_DECODE_H_ 04846 case 8: 04847 myrpt->lastunit = 0xd00d; 04848 mdc1200_notify(myrpt,NULL,myrpt->lastunit); 04849 mdc1200_send(myrpt,myrpt->lastunit); 04850 break; 04851 #endif 04852 04853 case 16: /* Restore links disconnected with "disconnect all links" command */ 04854 strcpy(tmp, myrpt->savednodes); /* Make a copy */ 04855 finddelim(tmp, strs, MAXLINKLIST); /* convert into substrings */ 04856 for(i = 0; tmp[0] && strs[i] != NULL && i < MAXLINKLIST; i++){ 04857 s1 = strs[i]; 04858 mode = (s1[0] == 'X') ? 1 : 0; 04859 perma = (s1[1] == 'P') ? 1 : 0; 04860 connect_link(myrpt, s1 + 2, mode, perma); /* Try to reconnect */ 04861 } 04862 rpt_telemetry(myrpt, COMPLETE, NULL); 04863 break; 04864 04865 case 200: 04866 case 201: 04867 case 202: 04868 case 203: 04869 case 204: 04870 case 205: 04871 case 206: 04872 case 207: 04873 case 208: 04874 case 209: 04875 case 210: 04876 case 211: 04877 case 212: 04878 case 213: 04879 case 214: 04880 case 215: 04881 if (((myrpt->p.propagate_dtmf) && 04882 (command_source == SOURCE_LNK)) || 04883 ((myrpt->p.propagate_phonedtmf) && 04884 ((command_source == SOURCE_PHONE) || 04885 (command_source == SOURCE_DPHONE)))) 04886 do_dtmf_local(myrpt, 04887 remdtmfstr[myatoi(param) - 200]); 04888 default: 04889 return DC_ERROR; 04890 04891 } 04892 04893 return DC_INDETERMINATE; 04894 }
static int function_macro | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5053 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.
05054 { 05055 05056 char *val; 05057 int i; 05058 if (myrpt->remote) 05059 return DC_ERROR; 05060 05061 if(debug) 05062 printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 05063 05064 if(strlen(digitbuf) < 1) /* needs 1 digit */ 05065 return DC_INDETERMINATE; 05066 05067 for(i = 0 ; i < digitbuf[i] ; i++) { 05068 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 05069 return DC_ERROR; 05070 } 05071 05072 if (*digitbuf == '0') val = myrpt->p.startupmacro; 05073 else val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, digitbuf); 05074 /* param was 1 for local buf */ 05075 if (!val){ 05076 if (strlen(digitbuf) < myrpt->macro_longest) 05077 return DC_INDETERMINATE; 05078 rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL); 05079 return DC_COMPLETE; 05080 } 05081 rpt_mutex_lock(&myrpt->lock); 05082 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)) 05083 { 05084 rpt_mutex_unlock(&myrpt->lock); 05085 rpt_telemetry(myrpt, MACRO_BUSY, NULL); 05086 return DC_ERROR; 05087 } 05088 myrpt->macrotimer = MACROTIME; 05089 strncat(myrpt->macrobuf, val, MAXMACRO - strlen(myrpt->macrobuf) - 1); 05090 rpt_mutex_unlock(&myrpt->lock); 05091 return DC_COMPLETE; 05092 }
static int function_remote | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 7748 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.
07749 { 07750 char *s,*s1,*s2; 07751 int i,j,p,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode; 07752 char multimode = 0; 07753 char oc,*cp,*cp1,*cp2; 07754 char tmp[20], freq[20] = "", savestr[20] = ""; 07755 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07756 07757 if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK)) 07758 return DC_ERROR; 07759 07760 p = myatoi(param); 07761 07762 if ((p != 99) && (p != 5) && (p != 140) && myrpt->p.authlevel && 07763 (!myrpt->loginlevel[0])) return DC_ERROR; 07764 multimode = multimode_capable(myrpt); 07765 07766 switch(p){ 07767 07768 case 1: /* retrieve memory */ 07769 if(strlen(digitbuf) < 2) /* needs 2 digits */ 07770 break; 07771 07772 for(i = 0 ; i < 2 ; i++){ 07773 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07774 return DC_ERROR; 07775 } 07776 07777 r = retreive_memory(myrpt, digitbuf); 07778 if (r < 0){ 07779 rpt_telemetry(myrpt,MEMNOTFOUND,NULL); 07780 return DC_COMPLETE; 07781 } 07782 if (r > 0){ 07783 return DC_ERROR; 07784 } 07785 if (setrem(myrpt) == -1) return DC_ERROR; 07786 return DC_COMPLETE; 07787 07788 case 2: /* set freq and offset */ 07789 07790 07791 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */ 07792 if(digitbuf[i] == '*'){ 07793 j++; 07794 continue; 07795 } 07796 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07797 goto invalid_freq; 07798 else{ 07799 if(j == 0) 07800 l++; /* # of digits before first * */ 07801 if(j == 1) 07802 k++; /* # of digits after first * */ 07803 } 07804 } 07805 07806 i = strlen(digitbuf) - 1; 07807 if(multimode){ 07808 if((j > 2) || (l > 3) || (k > 6)) 07809 goto invalid_freq; /* &^@#! */ 07810 } 07811 else{ 07812 if((j > 2) || (l > 4) || (k > 3)) 07813 goto invalid_freq; /* &^@#! */ 07814 } 07815 07816 /* Wait for M+*K+* */ 07817 07818 if(j < 2) 07819 break; /* Not yet */ 07820 07821 /* We have a frequency */ 07822 07823 strncpy(tmp, digitbuf ,sizeof(tmp) - 1); 07824 07825 s = tmp; 07826 s1 = strsep(&s, "*"); /* Pick off MHz */ 07827 s2 = strsep(&s,"*"); /* Pick off KHz and Hz */ 07828 ls2 = strlen(s2); 07829 07830 switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */ 07831 case 1: 07832 ht = 0; 07833 k = 100 * atoi(s2); 07834 break; 07835 07836 case 2: 07837 ht = 0; 07838 k = 10 * atoi(s2); 07839 break; 07840 07841 case 3: 07842 if(!multimode){ 07843 if((s2[2] != '0')&&(s2[2] != '5')) 07844 goto invalid_freq; 07845 } 07846 ht = 0; 07847 k = atoi(s2); 07848 break; 07849 case 4: 07850 k = atoi(s2)/10; 07851 ht = 10 * (atoi(s2+(ls2-1))); 07852 break; 07853 07854 case 5: 07855 k = atoi(s2)/100; 07856 ht = (atoi(s2+(ls2-2))); 07857 break; 07858 07859 default: 07860 goto invalid_freq; 07861 } 07862 07863 /* Check frequency for validity and establish a default mode */ 07864 07865 snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht); 07866 07867 if(debug) 07868 printf("New frequency: %s\n", freq); 07869 07870 split_freq(mhz, decimals, freq); 07871 m = atoi(mhz); 07872 d = atoi(decimals); 07873 07874 if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */ 07875 goto invalid_freq; 07876 07877 07878 if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */ 07879 break; /* Not yet */ 07880 07881 07882 offset = REM_SIMPLEX; /* Assume simplex */ 07883 07884 if(defmode == REM_MODE_FM){ 07885 oc = *s; /* Pick off offset */ 07886 07887 if (oc){ 07888 switch(oc){ 07889 case '1': 07890 offset = REM_MINUS; 07891 break; 07892 07893 case '2': 07894 offset = REM_SIMPLEX; 07895 break; 07896 07897 case '3': 07898 offset = REM_PLUS; 07899 break; 07900 07901 default: 07902 goto invalid_freq; 07903 } 07904 } 07905 } 07906 offsave = myrpt->offset; 07907 modesave = myrpt->remmode; 07908 strncpy(savestr, myrpt->freq, sizeof(savestr) - 1); 07909 strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1); 07910 myrpt->offset = offset; 07911 myrpt->remmode = defmode; 07912 07913 if (setrem(myrpt) == -1){ 07914 myrpt->offset = offsave; 07915 myrpt->remmode = modesave; 07916 strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1); 07917 goto invalid_freq; 07918 } 07919 07920 return DC_COMPLETE; 07921 07922 invalid_freq: 07923 rpt_telemetry(myrpt,INVFREQ,NULL); 07924 return DC_ERROR; 07925 07926 case 3: /* set rx PL tone */ 07927 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 07928 if(digitbuf[i] == '*'){ 07929 j++; 07930 continue; 07931 } 07932 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07933 return DC_ERROR; 07934 else{ 07935 if(j) 07936 l++; 07937 else 07938 k++; 07939 } 07940 } 07941 if((j > 1) || (k > 3) || (l > 1)) 07942 return DC_ERROR; /* &$@^! */ 07943 i = strlen(digitbuf) - 1; 07944 if((j != 1) || (k < 2)|| (l != 1)) 07945 break; /* Not yet */ 07946 if(debug) 07947 printf("PL digits entered %s\n", digitbuf); 07948 07949 strncpy(tmp, digitbuf, sizeof(tmp) - 1); 07950 /* see if we have at least 1 */ 07951 s = strchr(tmp,'*'); 07952 if(s) 07953 *s = '.'; 07954 strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1); 07955 strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1); 07956 if(!strcmp(myrpt->remote, remote_rig_rbi)) 07957 { 07958 strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1); 07959 } 07960 if (setrem(myrpt) == -1){ 07961 strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1); 07962 return DC_ERROR; 07963 } 07964 07965 07966 return DC_COMPLETE; 07967 07968 case 4: /* set tx PL tone */ 07969 /* cant set tx tone on RBI (rx tone does both) */ 07970 if(!strcmp(myrpt->remote, remote_rig_rbi)) 07971 return DC_ERROR; 07972 if(!strcmp(myrpt->remote, remote_rig_ic706)) 07973 return DC_ERROR; 07974 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 07975 if(digitbuf[i] == '*'){ 07976 j++; 07977 continue; 07978 } 07979 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07980 return DC_ERROR; 07981 else{ 07982 if(j) 07983 l++; 07984 else 07985 k++; 07986 } 07987 } 07988 if((j > 1) || (k > 3) || (l > 1)) 07989 return DC_ERROR; /* &$@^! */ 07990 i = strlen(digitbuf) - 1; 07991 if((j != 1) || (k < 2)|| (l != 1)) 07992 break; /* Not yet */ 07993 if(debug) 07994 printf("PL digits entered %s\n", digitbuf); 07995 07996 strncpy(tmp, digitbuf, sizeof(tmp) - 1); 07997 /* see if we have at least 1 */ 07998 s = strchr(tmp,'*'); 07999 if(s) 08000 *s = '.'; 08001 strncpy(savestr, myrpt->txpl, sizeof(savestr) - 1); 08002 strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1); 08003 08004 if (setrem(myrpt) == -1){ 08005 strncpy(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1); 08006 return DC_ERROR; 08007 } 08008 08009 08010 return DC_COMPLETE; 08011 08012 08013 case 6: /* MODE (FM,USB,LSB,AM) */ 08014 if(strlen(digitbuf) < 1) 08015 break; 08016 08017 if(!multimode) 08018 return DC_ERROR; /* Multimode radios only */ 08019 08020 switch(*digitbuf){ 08021 case '1': 08022 split_freq(mhz, decimals, myrpt->freq); 08023 m=atoi(mhz); 08024 if(m < 29) /* No FM allowed below 29MHz! */ 08025 return DC_ERROR; 08026 myrpt->remmode = REM_MODE_FM; 08027 08028 rpt_telemetry(myrpt,REMMODE,NULL); 08029 break; 08030 08031 case '2': 08032 myrpt->remmode = REM_MODE_USB; 08033 rpt_telemetry(myrpt,REMMODE,NULL); 08034 break; 08035 08036 case '3': 08037 myrpt->remmode = REM_MODE_LSB; 08038 rpt_telemetry(myrpt,REMMODE,NULL); 08039 break; 08040 08041 case '4': 08042 myrpt->remmode = REM_MODE_AM; 08043 rpt_telemetry(myrpt,REMMODE,NULL); 08044 break; 08045 08046 default: 08047 return DC_ERROR; 08048 } 08049 08050 if(setrem(myrpt)) 08051 return DC_ERROR; 08052 return DC_COMPLETEQUIET; 08053 case 99: 08054 /* cant log in when logged in */ 08055 if (myrpt->loginlevel[0]) 08056 return DC_ERROR; 08057 *myrpt->loginuser = 0; 08058 myrpt->loginlevel[0] = 0; 08059 cp = strdup(param); 08060 cp1 = strchr(cp,','); 08061 ast_mutex_lock(&myrpt->lock); 08062 if (cp1) 08063 { 08064 *cp1 = 0; 08065 cp2 = strchr(cp1 + 1,','); 08066 if (cp2) 08067 { 08068 *cp2 = 0; 08069 strncpy(myrpt->loginlevel,cp2 + 1, 08070 sizeof(myrpt->loginlevel) - 1); 08071 } 08072 strncpy(myrpt->loginuser,cp1 + 1,sizeof(myrpt->loginuser)); 08073 ast_mutex_unlock(&myrpt->lock); 08074 if (myrpt->p.archivedir) 08075 { 08076 char str[100]; 08077 08078 sprintf(str,"LOGIN,%s,%s", 08079 myrpt->loginuser,myrpt->loginlevel); 08080 donodelog(myrpt,str); 08081 } 08082 if (debug) 08083 printf("loginuser %s level %s\n",myrpt->loginuser,myrpt->loginlevel); 08084 rpt_telemetry(myrpt,REMLOGIN,NULL); 08085 } 08086 free(cp); 08087 return DC_COMPLETEQUIET; 08088 case 100: /* RX PL Off */ 08089 myrpt->rxplon = 0; 08090 setrem(myrpt); 08091 rpt_telemetry(myrpt,REMXXX,(void *)p); 08092 return DC_COMPLETEQUIET; 08093 case 101: /* RX PL On */ 08094 myrpt->rxplon = 1; 08095 setrem(myrpt); 08096 rpt_telemetry(myrpt,REMXXX,(void *)p); 08097 return DC_COMPLETEQUIET; 08098 case 102: /* TX PL Off */ 08099 myrpt->txplon = 0; 08100 setrem(myrpt); 08101 rpt_telemetry(myrpt,REMXXX,(void *)p); 08102 return DC_COMPLETEQUIET; 08103 case 103: /* TX PL On */ 08104 myrpt->txplon = 1; 08105 setrem(myrpt); 08106 rpt_telemetry(myrpt,REMXXX,(void *)p); 08107 return DC_COMPLETEQUIET; 08108 case 104: /* Low Power */ 08109 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08110 return DC_ERROR; 08111 myrpt->powerlevel = REM_LOWPWR; 08112 setrem(myrpt); 08113 rpt_telemetry(myrpt,REMXXX,(void *)p); 08114 return DC_COMPLETEQUIET; 08115 case 105: /* Medium Power */ 08116 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08117 return DC_ERROR; 08118 myrpt->powerlevel = REM_MEDPWR; 08119 setrem(myrpt); 08120 rpt_telemetry(myrpt,REMXXX,(void *)p); 08121 return DC_COMPLETEQUIET; 08122 case 106: /* Hi Power */ 08123 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08124 return DC_ERROR; 08125 myrpt->powerlevel = REM_HIPWR; 08126 setrem(myrpt); 08127 rpt_telemetry(myrpt,REMXXX,(void *)p); 08128 return DC_COMPLETEQUIET; 08129 case 107: /* Bump down 20Hz */ 08130 multimode_bump_freq(myrpt, -20); 08131 return DC_COMPLETE; 08132 case 108: /* Bump down 100Hz */ 08133 multimode_bump_freq(myrpt, -100); 08134 return DC_COMPLETE; 08135 case 109: /* Bump down 500Hz */ 08136 multimode_bump_freq(myrpt, -500); 08137 return DC_COMPLETE; 08138 case 110: /* Bump up 20Hz */ 08139 multimode_bump_freq(myrpt, 20); 08140 return DC_COMPLETE; 08141 case 111: /* Bump up 100Hz */ 08142 multimode_bump_freq(myrpt, 100); 08143 return DC_COMPLETE; 08144 case 112: /* Bump up 500Hz */ 08145 multimode_bump_freq(myrpt, 500); 08146 return DC_COMPLETE; 08147 case 113: /* Scan down slow */ 08148 myrpt->scantimer = REM_SCANTIME; 08149 myrpt->hfscanmode = HF_SCAN_DOWN_SLOW; 08150 rpt_telemetry(myrpt,REMXXX,(void *)p); 08151 return DC_COMPLETEQUIET; 08152 case 114: /* Scan down quick */ 08153 myrpt->scantimer = REM_SCANTIME; 08154 myrpt->hfscanmode = HF_SCAN_DOWN_QUICK; 08155 rpt_telemetry(myrpt,REMXXX,(void *)p); 08156 return DC_COMPLETEQUIET; 08157 case 115: /* Scan down fast */ 08158 myrpt->scantimer = REM_SCANTIME; 08159 myrpt->hfscanmode = HF_SCAN_DOWN_FAST; 08160 rpt_telemetry(myrpt,REMXXX,(void *)p); 08161 return DC_COMPLETEQUIET; 08162 case 116: /* Scan up slow */ 08163 myrpt->scantimer = REM_SCANTIME; 08164 myrpt->hfscanmode = HF_SCAN_UP_SLOW; 08165 rpt_telemetry(myrpt,REMXXX,(void *)p); 08166 return DC_COMPLETEQUIET; 08167 case 117: /* Scan up quick */ 08168 myrpt->scantimer = REM_SCANTIME; 08169 myrpt->hfscanmode = HF_SCAN_UP_QUICK; 08170 rpt_telemetry(myrpt,REMXXX,(void *)p); 08171 return DC_COMPLETEQUIET; 08172 case 118: /* Scan up fast */ 08173 myrpt->scantimer = REM_SCANTIME; 08174 myrpt->hfscanmode = HF_SCAN_UP_FAST; 08175 rpt_telemetry(myrpt,REMXXX,(void *)p); 08176 return DC_COMPLETEQUIET; 08177 case 119: /* Tune Request */ 08178 /* if not currently going, and valid to do */ 08179 if((!myrpt->tunerequest) && 08180 ((!strcmp(myrpt->remote, remote_rig_ft897) || 08181 !strcmp(myrpt->remote, remote_rig_ic706)) )) { 08182 myrpt->remotetx = 0; 08183 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 08184 myrpt->tunerequest = 1; 08185 rpt_telemetry(myrpt,TUNE,NULL); 08186 return DC_COMPLETEQUIET; 08187 } 08188 return DC_ERROR; 08189 case 5: /* Long Status */ 08190 rpt_telemetry(myrpt,REMLONGSTATUS,NULL); 08191 return DC_COMPLETEQUIET; 08192 case 140: /* Short Status */ 08193 rpt_telemetry(myrpt,REMSHORTSTATUS,NULL); 08194 return DC_COMPLETEQUIET; 08195 case 200: 08196 case 201: 08197 case 202: 08198 case 203: 08199 case 204: 08200 case 205: 08201 case 206: 08202 case 207: 08203 case 208: 08204 case 209: 08205 case 210: 08206 case 211: 08207 case 212: 08208 case 213: 08209 case 214: 08210 case 215: 08211 do_dtmf_local(myrpt,remdtmfstr[p - 200]); 08212 return DC_COMPLETEQUIET; 08213 default: 08214 break; 08215 } 08216 return DC_INDETERMINATE; 08217 }
static int function_status | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5022 of file app_rpt.c.
References DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, ID1, myatoi(), rpt::p, rpt_telemetry(), rpt::s, STATS_TIME, STATS_VERSION, and rpt::sysstate_cur.
05023 { 05024 05025 if (!param) 05026 return DC_ERROR; 05027 05028 if ((myrpt->p.s[myrpt->p.sysstate_cur].txdisable) || (myrpt->p.s[myrpt->p.sysstate_cur].userfundisable)) 05029 return DC_ERROR; 05030 05031 if(debug) 05032 printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 05033 05034 switch(myatoi(param)){ 05035 case 1: /* System ID */ 05036 rpt_telemetry(myrpt, ID1, NULL); 05037 return DC_COMPLETE; 05038 case 2: /* System Time */ 05039 rpt_telemetry(myrpt, STATS_TIME, NULL); 05040 return DC_COMPLETE; 05041 case 3: /* app_rpt.c version */ 05042 rpt_telemetry(myrpt, STATS_VERSION, NULL); 05043 default: 05044 return DC_ERROR; 05045 } 05046 return DC_INDETERMINATE; 05047 }
static int get_wait_interval | ( | struct rpt * | myrpt, | |
int | type | |||
) | [static] |
Definition at line 2819 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().
02820 { 02821 int interval; 02822 char *wait_times; 02823 char *wait_times_save; 02824 02825 wait_times_save = NULL; 02826 wait_times = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "wait_times"); 02827 02828 if(wait_times){ 02829 wait_times_save = ast_strdupa(wait_times); 02830 if(!wait_times_save){ 02831 ast_log(LOG_WARNING, "Out of memory in wait_interval()\n"); 02832 wait_times = NULL; 02833 } 02834 } 02835 02836 switch(type){ 02837 case DLY_TELEM: 02838 if(wait_times) 02839 interval = retrieve_astcfgint(myrpt,wait_times_save, "telemwait", 500, 5000, 1000); 02840 else 02841 interval = 1000; 02842 break; 02843 02844 case DLY_ID: 02845 if(wait_times) 02846 interval = retrieve_astcfgint(myrpt,wait_times_save, "idwait",250,5000,500); 02847 else 02848 interval = 500; 02849 break; 02850 02851 case DLY_UNKEY: 02852 if(wait_times) 02853 interval = retrieve_astcfgint(myrpt,wait_times_save, "unkeywait",500,5000,1000); 02854 else 02855 interval = 1000; 02856 break; 02857 02858 case DLY_LINKUNKEY: 02859 if(wait_times) 02860 interval = retrieve_astcfgint(myrpt,wait_times_save, "linkunkeywait",500,5000,1000); 02861 else 02862 interval = 1000; 02863 break; 02864 02865 case DLY_CALLTERM: 02866 if(wait_times) 02867 interval = retrieve_astcfgint(myrpt,wait_times_save, "calltermwait",500,5000,1500); 02868 else 02869 interval = 1500; 02870 break; 02871 02872 case DLY_COMP: 02873 if(wait_times) 02874 interval = retrieve_astcfgint(myrpt,wait_times_save, "compwait",500,5000,200); 02875 else 02876 interval = 200; 02877 break; 02878 02879 default: 02880 return 0; 02881 } 02882 return interval; 02883 }
Definition at line 5301 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().
05303 { 05304 char tmp[512],cmd[300] = "",dest[300],src[300],c; 05305 int seq, res; 05306 struct rpt_link *l; 05307 struct ast_frame wf; 05308 05309 wf.frametype = AST_FRAME_TEXT; 05310 wf.subclass = 0; 05311 wf.offset = 0; 05312 wf.mallocd = 0; 05313 wf.datalen = strlen(str) + 1; 05314 wf.samples = 0; 05315 /* put string in our buffer */ 05316 strncpy(tmp,str,sizeof(tmp) - 1); 05317 05318 if (!strcmp(tmp,discstr)) 05319 { 05320 mylink->disced = 1; 05321 mylink->retries = mylink->max_retries + 1; 05322 ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV); 05323 return; 05324 } 05325 if (tmp[0] == 'L') 05326 { 05327 rpt_mutex_lock(&myrpt->lock); 05328 strcpy(mylink->linklist,tmp + 2); 05329 time(&mylink->linklistreceived); 05330 rpt_mutex_unlock(&myrpt->lock); 05331 if (debug > 6) ast_log(LOG_NOTICE,"@@@@ node %s recieved node list %s from node %s\n", 05332 myrpt->name,tmp,mylink->name); 05333 return; 05334 } 05335 if (tmp[0] == 'I') 05336 { 05337 if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3) 05338 { 05339 ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str); 05340 return; 05341 } 05342 mdc1200_notify(myrpt,src,seq); 05343 strcpy(dest,"*"); 05344 } 05345 else 05346 { 05347 if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5) 05348 { 05349 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 05350 return; 05351 } 05352 if (strcmp(cmd,"D")) 05353 { 05354 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 05355 return; 05356 } 05357 } 05358 if (dest[0] == '0') 05359 { 05360 strcpy(dest,myrpt->name); 05361 } 05362 05363 /* if not for me, redistribute to all links */ 05364 if (strcmp(dest,myrpt->name)) 05365 { 05366 l = myrpt->links.next; 05367 /* see if this is one in list */ 05368 while(l != &myrpt->links) 05369 { 05370 if (l->name[0] == '0') 05371 { 05372 l = l->next; 05373 continue; 05374 } 05375 /* dont send back from where it came */ 05376 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 05377 { 05378 l = l->next; 05379 continue; 05380 } 05381 /* if it is, send it and we're done */ 05382 if (!strcmp(l->name,dest)) 05383 { 05384 /* send, but not to src */ 05385 if (strcmp(l->name,src)) { 05386 wf.data = str; 05387 if (l->chan) ast_write(l->chan,&wf); 05388 } 05389 return; 05390 } 05391 l = l->next; 05392 } 05393 l = myrpt->links.next; 05394 /* otherwise, send it to all of em */ 05395 while(l != &myrpt->links) 05396 { 05397 if (l->name[0] == '0') 05398 { 05399 l = l->next; 05400 continue; 05401 } 05402 /* dont send back from where it came */ 05403 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 05404 { 05405 l = l->next; 05406 continue; 05407 } 05408 /* send, but not to src */ 05409 if (strcmp(l->name,src)) { 05410 wf.data = str; 05411 if (l->chan) ast_write(l->chan,&wf); 05412 } 05413 l = l->next; 05414 } 05415 return; 05416 } 05417 if (myrpt->p.archivedir) 05418 { 05419 char str[100]; 05420 05421 sprintf(str,"DTMF,%s,%c",mylink->name,c); 05422 donodelog(myrpt,str); 05423 } 05424 c = func_xlat(myrpt,c,&myrpt->p.outxlat); 05425 if (!c) return; 05426 rpt_mutex_lock(&myrpt->lock); 05427 if (c == myrpt->p.endchar) myrpt->stopgen = 1; 05428 if (myrpt->callmode == 1) 05429 { 05430 myrpt->exten[myrpt->cidx++] = c; 05431 myrpt->exten[myrpt->cidx] = 0; 05432 /* if this exists */ 05433 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05434 { 05435 myrpt->callmode = 2; 05436 if(!myrpt->patchquiet){ 05437 rpt_mutex_unlock(&myrpt->lock); 05438 rpt_telemetry(myrpt,PROC,NULL); 05439 rpt_mutex_lock(&myrpt->lock); 05440 } 05441 } 05442 /* if can continue, do so */ 05443 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05444 { 05445 /* call has failed, inform user */ 05446 myrpt->callmode = 4; 05447 } 05448 } 05449 if (c == myrpt->p.funcchar) 05450 { 05451 myrpt->rem_dtmfidx = 0; 05452 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05453 time(&myrpt->rem_dtmf_time); 05454 rpt_mutex_unlock(&myrpt->lock); 05455 return; 05456 } 05457 else if (myrpt->rem_dtmfidx < 0) 05458 { 05459 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 05460 { 05461 myrpt->mydtmf = c; 05462 } 05463 if (myrpt->p.propagate_dtmf) do_dtmf_local(myrpt,c); 05464 if (myrpt->p.propagate_phonedtmf) do_dtmf_phone(myrpt,mylink,c); 05465 rpt_mutex_unlock(&myrpt->lock); 05466 return; 05467 } 05468 else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0)) 05469 { 05470 time(&myrpt->rem_dtmf_time); 05471 if (myrpt->rem_dtmfidx < MAXDTMF) 05472 { 05473 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 05474 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05475 05476 rpt_mutex_unlock(&myrpt->lock); 05477 strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1); 05478 res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink); 05479 rpt_mutex_lock(&myrpt->lock); 05480 05481 switch(res){ 05482 05483 case DC_INDETERMINATE: 05484 break; 05485 05486 case DC_REQ_FLUSH: 05487 myrpt->rem_dtmfidx = 0; 05488 myrpt->rem_dtmfbuf[0] = 0; 05489 break; 05490 05491 05492 case DC_COMPLETE: 05493 case DC_COMPLETEQUIET: 05494 myrpt->totalexecdcommands++; 05495 myrpt->dailyexecdcommands++; 05496 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 05497 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 05498 myrpt->rem_dtmfbuf[0] = 0; 05499 myrpt->rem_dtmfidx = -1; 05500 myrpt->rem_dtmf_time = 0; 05501 break; 05502 05503 case DC_ERROR: 05504 default: 05505 myrpt->rem_dtmfbuf[0] = 0; 05506 myrpt->rem_dtmfidx = -1; 05507 myrpt->rem_dtmf_time = 0; 05508 break; 05509 } 05510 } 05511 05512 } 05513 rpt_mutex_unlock(&myrpt->lock); 05514 return; 05515 }
static void handle_link_phone_dtmf | ( | struct rpt * | myrpt, | |
struct rpt_link * | mylink, | |||
char | c | |||
) | [static] |
Definition at line 5517 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().
05519 { 05520 05521 char cmd[300]; 05522 int res; 05523 05524 if (myrpt->p.archivedir) 05525 { 05526 char str[100]; 05527 05528 sprintf(str,"DTMF(P),%s,%c",mylink->name,c); 05529 donodelog(myrpt,str); 05530 } 05531 rpt_mutex_lock(&myrpt->lock); 05532 if (c == myrpt->p.endchar) 05533 { 05534 if (mylink->lastrx) 05535 { 05536 mylink->lastrx = 0; 05537 rpt_mutex_unlock(&myrpt->lock); 05538 return; 05539 } 05540 myrpt->stopgen = 1; 05541 if (myrpt->cmdnode[0]) 05542 { 05543 myrpt->cmdnode[0] = 0; 05544 myrpt->dtmfidx = -1; 05545 myrpt->dtmfbuf[0] = 0; 05546 rpt_mutex_unlock(&myrpt->lock); 05547 rpt_telemetry(myrpt,COMPLETE,NULL); 05548 return; 05549 } 05550 } 05551 if (myrpt->cmdnode[0]) 05552 { 05553 rpt_mutex_unlock(&myrpt->lock); 05554 send_link_dtmf(myrpt,c); 05555 return; 05556 } 05557 if (myrpt->callmode == 1) 05558 { 05559 myrpt->exten[myrpt->cidx++] = c; 05560 myrpt->exten[myrpt->cidx] = 0; 05561 /* if this exists */ 05562 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05563 { 05564 myrpt->callmode = 2; 05565 if(!myrpt->patchquiet){ 05566 rpt_mutex_unlock(&myrpt->lock); 05567 rpt_telemetry(myrpt,PROC,NULL); 05568 rpt_mutex_lock(&myrpt->lock); 05569 } 05570 } 05571 /* if can continue, do so */ 05572 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05573 { 05574 /* call has failed, inform user */ 05575 myrpt->callmode = 4; 05576 } 05577 } 05578 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 05579 { 05580 myrpt->mydtmf = c; 05581 } 05582 if (c == myrpt->p.funcchar) 05583 { 05584 myrpt->rem_dtmfidx = 0; 05585 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05586 time(&myrpt->rem_dtmf_time); 05587 rpt_mutex_unlock(&myrpt->lock); 05588 return; 05589 } 05590 else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0)) 05591 { 05592 time(&myrpt->rem_dtmf_time); 05593 if (myrpt->rem_dtmfidx < MAXDTMF) 05594 { 05595 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 05596 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05597 05598 rpt_mutex_unlock(&myrpt->lock); 05599 strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1); 05600 switch(mylink->phonemode) 05601 { 05602 case 1: 05603 res = collect_function_digits(myrpt, cmd, 05604 SOURCE_PHONE, mylink); 05605 break; 05606 case 2: 05607 res = collect_function_digits(myrpt, cmd, 05608 SOURCE_DPHONE,mylink); 05609 break; 05610 default: 05611 res = collect_function_digits(myrpt, cmd, 05612 SOURCE_LNK, mylink); 05613 break; 05614 } 05615 05616 rpt_mutex_lock(&myrpt->lock); 05617 05618 switch(res){ 05619 05620 case DC_INDETERMINATE: 05621 break; 05622 05623 case DC_DOKEY: 05624 mylink->lastrx = 1; 05625 break; 05626 05627 case DC_REQ_FLUSH: 05628 myrpt->rem_dtmfidx = 0; 05629 myrpt->rem_dtmfbuf[0] = 0; 05630 break; 05631 05632 05633 case DC_COMPLETE: 05634 case DC_COMPLETEQUIET: 05635 myrpt->totalexecdcommands++; 05636 myrpt->dailyexecdcommands++; 05637 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 05638 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 05639 myrpt->rem_dtmfbuf[0] = 0; 05640 myrpt->rem_dtmfidx = -1; 05641 myrpt->rem_dtmf_time = 0; 05642 break; 05643 05644 case DC_ERROR: 05645 default: 05646 myrpt->rem_dtmfbuf[0] = 0; 05647 myrpt->rem_dtmfidx = -1; 05648 myrpt->rem_dtmf_time = 0; 05649 break; 05650 } 05651 } 05652 05653 } 05654 rpt_mutex_unlock(&myrpt->lock); 05655 return; 05656 }
static int handle_remote_data | ( | struct rpt * | myrpt, | |
char * | str | |||
) | [static] |
Definition at line 8330 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.
08331 { 08332 char tmp[300],cmd[300],dest[300],src[300],c; 08333 int seq,res; 08334 08335 /* put string in our buffer */ 08336 strncpy(tmp,str,sizeof(tmp) - 1); 08337 if (!strcmp(tmp,discstr)) return 0; 08338 08339 #ifndef DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES 08340 if (tmp[0] == 'I') 08341 { 08342 if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3) 08343 { 08344 ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str); 08345 return 0; 08346 } 08347 mdc1200_notify(myrpt,src,seq); 08348 return 0; 08349 } 08350 #endif 08351 if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5) 08352 { 08353 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 08354 return 0; 08355 } 08356 if (strcmp(cmd,"D")) 08357 { 08358 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 08359 return 0; 08360 } 08361 /* if not for me, ignore */ 08362 if (strcmp(dest,myrpt->name)) return 0; 08363 if (myrpt->p.archivedir) 08364 { 08365 char str[100]; 08366 08367 sprintf(str,"DTMF,%c",c); 08368 donodelog(myrpt,str); 08369 } 08370 c = func_xlat(myrpt,c,&myrpt->p.outxlat); 08371 if (!c) return(0); 08372 res = handle_remote_dtmf_digit(myrpt,c, NULL, 0); 08373 if (res != 1) 08374 return res; 08375 rpt_telemetry(myrpt,COMPLETE,NULL); 08376 return 0; 08377 }
static int handle_remote_dtmf_digit | ( | struct rpt * | myrpt, | |
char | c, | |||
char * | keyed, | |||
int | phonemode | |||
) | [static] |
Definition at line 8220 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(), and handle_remote_phone_dtmf().
08221 { 08222 time_t now; 08223 int ret,res = 0,src; 08224 08225 time(&myrpt->last_activity_time); 08226 /* Stop scan mode if in scan mode */ 08227 if(myrpt->hfscanmode){ 08228 stop_scan(myrpt); 08229 return 0; 08230 } 08231 08232 time(&now); 08233 /* if timed-out */ 08234 if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now) 08235 { 08236 myrpt->dtmfidx = -1; 08237 myrpt->dtmfbuf[0] = 0; 08238 myrpt->dtmf_time_rem = 0; 08239 } 08240 /* if decode not active */ 08241 if (myrpt->dtmfidx == -1) 08242 { 08243 /* if not lead-in digit, dont worry */ 08244 if (c != myrpt->p.funcchar) 08245 { 08246 if (!myrpt->p.propagate_dtmf) 08247 { 08248 rpt_mutex_lock(&myrpt->lock); 08249 do_dtmf_local(myrpt,c); 08250 rpt_mutex_unlock(&myrpt->lock); 08251 } 08252 return 0; 08253 } 08254 myrpt->dtmfidx = 0; 08255 myrpt->dtmfbuf[0] = 0; 08256 myrpt->dtmf_time_rem = now; 08257 return 0; 08258 } 08259 /* if too many in buffer, start over */ 08260 if (myrpt->dtmfidx >= MAXDTMF) 08261 { 08262 myrpt->dtmfidx = 0; 08263 myrpt->dtmfbuf[0] = 0; 08264 myrpt->dtmf_time_rem = now; 08265 } 08266 if (c == myrpt->p.funcchar) 08267 { 08268 /* if star at beginning, or 2 together, erase buffer */ 08269 if ((myrpt->dtmfidx < 1) || 08270 (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->p.funcchar)) 08271 { 08272 myrpt->dtmfidx = 0; 08273 myrpt->dtmfbuf[0] = 0; 08274 myrpt->dtmf_time_rem = now; 08275 return 0; 08276 } 08277 } 08278 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 08279 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08280 myrpt->dtmf_time_rem = now; 08281 08282 08283 src = SOURCE_RMT; 08284 if (phonemode > 1) src = SOURCE_DPHONE; 08285 else if (phonemode) src = SOURCE_PHONE; 08286 ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL); 08287 08288 switch(ret){ 08289 08290 case DC_INDETERMINATE: 08291 res = 0; 08292 break; 08293 08294 case DC_DOKEY: 08295 if (keyed) *keyed = 1; 08296 res = 0; 08297 break; 08298 08299 case DC_REQ_FLUSH: 08300 myrpt->dtmfidx = 0; 08301 myrpt->dtmfbuf[0] = 0; 08302 res = 0; 08303 break; 08304 08305 08306 case DC_COMPLETE: 08307 res = 1; 08308 case DC_COMPLETEQUIET: 08309 myrpt->totalexecdcommands++; 08310 myrpt->dailyexecdcommands++; 08311 strncpy(myrpt->lastdtmfcommand, myrpt->dtmfbuf, MAXDTMF-1); 08312 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 08313 myrpt->dtmfbuf[0] = 0; 08314 myrpt->dtmfidx = -1; 08315 myrpt->dtmf_time_rem = 0; 08316 break; 08317 08318 case DC_ERROR: 08319 default: 08320 myrpt->dtmfbuf[0] = 0; 08321 myrpt->dtmfidx = -1; 08322 myrpt->dtmf_time_rem = 0; 08323 res = 0; 08324 break; 08325 } 08326 08327 return res; 08328 }
static int handle_remote_phone_dtmf | ( | struct rpt * | myrpt, | |
char | c, | |||
char * | keyed, | |||
int | phonemode | |||
) | [static] |
Definition at line 8379 of file app_rpt.c.
References rpt::archivedir, COMPLETE, DC_INDETERMINATE, donodelog(), rpt::endchar, handle_remote_dtmf_digit(), rpt::p, and rpt_telemetry().
08380 { 08381 int res; 08382 08383 08384 if (keyed && *keyed && (c == myrpt->p.endchar)) 08385 { 08386 *keyed = 0; 08387 return DC_INDETERMINATE; 08388 } 08389 08390 if (myrpt->p.archivedir) 08391 { 08392 char str[100]; 08393 08394 sprintf(str,"DTMF(P),%c",c); 08395 donodelog(myrpt,str); 08396 } 08397 res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode); 08398 if (res != 1) 08399 return res; 08400 rpt_telemetry(myrpt,COMPLETE,NULL); 08401 return 0; 08402 }
static int ic706_pltocode | ( | char * | str | ) | [static] |
Definition at line 6875 of file app_rpt.c.
References s.
Referenced by set_ic706().
06876 { 06877 int i; 06878 char *s; 06879 06880 s = strchr(str,'.'); 06881 i = 0; 06882 if (s) i = atoi(s + 1); 06883 i += atoi(str) * 10; 06884 switch(i) 06885 { 06886 case 670: 06887 return 0; 06888 case 693: 06889 return 1; 06890 case 719: 06891 return 2; 06892 case 744: 06893 return 3; 06894 case 770: 06895 return 4; 06896 case 797: 06897 return 5; 06898 case 825: 06899 return 6; 06900 case 854: 06901 return 7; 06902 case 885: 06903 return 8; 06904 case 915: 06905 return 9; 06906 case 948: 06907 return 10; 06908 case 974: 06909 return 11; 06910 case 1000: 06911 return 12; 06912 case 1035: 06913 return 13; 06914 case 1072: 06915 return 14; 06916 case 1109: 06917 return 15; 06918 case 1148: 06919 return 16; 06920 case 1188: 06921 return 17; 06922 case 1230: 06923 return 18; 06924 case 1273: 06925 return 19; 06926 case 1318: 06927 return 20; 06928 case 1365: 06929 return 21; 06930 case 1413: 06931 return 22; 06932 case 1462: 06933 return 23; 06934 case 1514: 06935 return 24; 06936 case 1567: 06937 return 25; 06938 case 1598: 06939 return 26; 06940 case 1622: 06941 return 27; 06942 case 1655: 06943 return 28; 06944 case 1679: 06945 return 29; 06946 case 1713: 06947 return 30; 06948 case 1738: 06949 return 31; 06950 case 1773: 06951 return 32; 06952 case 1799: 06953 return 33; 06954 case 1835: 06955 return 34; 06956 case 1862: 06957 return 35; 06958 case 1899: 06959 return 36; 06960 case 1928: 06961 return 37; 06962 case 1966: 06963 return 38; 06964 case 1995: 06965 return 39; 06966 case 2035: 06967 return 40; 06968 case 2065: 06969 return 41; 06970 case 2107: 06971 return 42; 06972 case 2181: 06973 return 43; 06974 case 2257: 06975 return 44; 06976 case 2291: 06977 return 45; 06978 case 2336: 06979 return 46; 06980 case 2418: 06981 return 47; 06982 case 2503: 06983 return 48; 06984 case 2541: 06985 return 49; 06986 } 06987 return -1; 06988 }
static int kenwood_pltocode | ( | char * | str | ) | [static] |
Definition at line 5988 of file app_rpt.c.
References s.
Referenced by setkenwood().
05989 { 05990 int i; 05991 char *s; 05992 05993 s = strchr(str,'.'); 05994 i = 0; 05995 if (s) i = atoi(s + 1); 05996 i += atoi(str) * 10; 05997 switch(i) 05998 { 05999 case 670: 06000 return 1; 06001 case 719: 06002 return 3; 06003 case 744: 06004 return 4; 06005 case 770: 06006 return 5; 06007 case 797: 06008 return 6; 06009 case 825: 06010 return 7; 06011 case 854: 06012 return 8; 06013 case 885: 06014 return 9; 06015 case 915: 06016 return 10; 06017 case 948: 06018 return 11; 06019 case 974: 06020 return 12; 06021 case 1000: 06022 return 13; 06023 case 1035: 06024 return 14; 06025 case 1072: 06026 return 15; 06027 case 1109: 06028 return 16; 06029 case 1148: 06030 return 17; 06031 case 1188: 06032 return 18; 06033 case 1230: 06034 return 19; 06035 case 1273: 06036 return 20; 06037 case 1318: 06038 return 21; 06039 case 1365: 06040 return 22; 06041 case 1413: 06042 return 23; 06043 case 1462: 06044 return 24; 06045 case 1514: 06046 return 25; 06047 case 1567: 06048 return 26; 06049 case 1622: 06050 return 27; 06051 case 1679: 06052 return 28; 06053 case 1738: 06054 return 29; 06055 case 1799: 06056 return 30; 06057 case 1862: 06058 return 31; 06059 case 1928: 06060 return 32; 06061 case 2035: 06062 return 33; 06063 case 2107: 06064 return 34; 06065 case 2181: 06066 return 35; 06067 case 2257: 06068 return 36; 06069 case 2336: 06070 return 37; 06071 case 2418: 06072 return 38; 06073 case 2503: 06074 return 39; 06075 } 06076 return -1; 06077 }
static int load_module | ( | void | ) | [static] |
Definition at line 11871 of file app_rpt.c.
References ast_cli_register(), ast_pthread_create, ast_register_application(), cli_debug, cli_dump, cli_fun, cli_lstats, cli_nodes, cli_reload, cli_restart, cli_stats, rpt_exec(), and rpt_master().
11873 { 11874 ast_pthread_create(&rpt_master_thread,NULL,rpt_master,NULL); 11875 11876 /* Register cli extensions */ 11877 ast_cli_register(&cli_debug); 11878 ast_cli_register(&cli_dump); 11879 ast_cli_register(&cli_stats); 11880 ast_cli_register(&cli_lstats); 11881 ast_cli_register(&cli_nodes); 11882 ast_cli_register(&cli_reload); 11883 ast_cli_register(&cli_restart); 11884 ast_cli_register(&cli_fun); 11885 11886 return ast_register_application(app, rpt_exec, synopsis, descrip); 11887 }
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::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::propagate_dtmf, rpt::propagate_phonedtmf, rpt::remoteinacttimeout, rpt::remotetimeout, rpt::remotetimeoutwarning, rpt::remotetimeoutwarningfreq, retrieve_astcfgint(), rpt_vars, rpt::s, sysstate::schedulerdisable, rpt::simple, rpt::skedstanzaname, rpt::startupmacro, rpt::tailmessagemax, rpt::tailmessages, rpt::tailmessagetime, rpt::tailsquashedtime, rpt::tonezone, sysstate::totdisable, TOTIME, rpt::totime, sysstate::txdisable, rpt::txlimitsstanzaname, typeof(), sysstate::userfundisable, ast_variable::value, and VERBOSE_PREFIX_3.
Referenced by rpt(), 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 /* clear all the fields in the structure after 'p' */ 01650 memset(&rpt_vars[n].p + sizeof(rpt_vars[0].p), 0, sizeof(rpt_vars[0]) - sizeof(rpt_vars[0].p) - offsetof(typeof(rpt_vars[0]), p)); 01651 rpt_vars[n].tele.next = &rpt_vars[n].tele; 01652 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 01653 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 01654 rpt_vars[n].tailmessagen = 0; 01655 } 01656 #ifdef __RPT_NOTCH 01657 /* zot out filters stuff */ 01658 memset(&rpt_vars[n].filters,0,sizeof(rpt_vars[n].filters)); 01659 #endif 01660 val = (char *) ast_variable_retrieve(cfg,this,"context"); 01661 if (val) rpt_vars[n].p.ourcontext = val; 01662 else rpt_vars[n].p.ourcontext = this; 01663 val = (char *) ast_variable_retrieve(cfg,this,"callerid"); 01664 if (val) rpt_vars[n].p.ourcallerid = val; 01665 val = (char *) ast_variable_retrieve(cfg,this,"accountcode"); 01666 if (val) rpt_vars[n].p.acctcode = val; 01667 val = (char *) ast_variable_retrieve(cfg,this,"idrecording"); 01668 if (val) rpt_vars[n].p.ident = val; 01669 val = (char *) ast_variable_retrieve(cfg,this,"hangtime"); 01670 if (val) rpt_vars[n].p.hangtime = atoi(val); 01671 else rpt_vars[n].p.hangtime = HANGTIME; 01672 val = (char *) ast_variable_retrieve(cfg,this,"althangtime"); 01673 if (val) rpt_vars[n].p.althangtime = atoi(val); 01674 else rpt_vars[n].p.althangtime = HANGTIME; 01675 val = (char *) ast_variable_retrieve(cfg,this,"totime"); 01676 if (val) rpt_vars[n].p.totime = atoi(val); 01677 else rpt_vars[n].p.totime = TOTIME; 01678 rpt_vars[n].p.tailmessagetime = retrieve_astcfgint(&rpt_vars[n],this, "tailmessagetime", 0, 2400000, 0); 01679 rpt_vars[n].p.tailsquashedtime = retrieve_astcfgint(&rpt_vars[n],this, "tailsquashedtime", 0, 2400000, 0); 01680 rpt_vars[n].p.duplex = retrieve_astcfgint(&rpt_vars[n],this,"duplex",0,4,2); 01681 rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", -60000, 2400000, IDTIME); /* Enforce a min max including zero */ 01682 rpt_vars[n].p.politeid = retrieve_astcfgint(&rpt_vars[n],this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */ 01683 val = (char *) ast_variable_retrieve(cfg,this,"tonezone"); 01684 if (val) rpt_vars[n].p.tonezone = val; 01685 rpt_vars[n].p.tailmessages[0] = 0; 01686 rpt_vars[n].p.tailmessagemax = 0; 01687 val = (char *) ast_variable_retrieve(cfg,this,"tailmessagelist"); 01688 if (val) rpt_vars[n].p.tailmessagemax = finddelim(val, rpt_vars[n].p.tailmessages, 500); 01689 val = (char *) ast_variable_retrieve(cfg,this,"memory"); 01690 if (!val) val = MEMORY; 01691 rpt_vars[n].p.memory = val; 01692 val = (char *) ast_variable_retrieve(cfg,this,"macro"); 01693 if (!val) val = MACRO; 01694 rpt_vars[n].p.macro = val; 01695 val = (char *) ast_variable_retrieve(cfg,this,"startup_macro"); 01696 if (val) rpt_vars[n].p.startupmacro = val; 01697 val = (char *) ast_variable_retrieve(cfg,this,"iobase"); 01698 /* do not use atoi() here, we need to be able to have 01699 the input specified in hex or decimal so we use 01700 sscanf with a %i */ 01701 if ((!val) || (sscanf(val,"%i",&rpt_vars[n].p.iobase) != 1)) 01702 rpt_vars[n].p.iobase = DEFAULT_IOBASE; 01703 val = (char *) ast_variable_retrieve(cfg,this,"ioport"); 01704 rpt_vars[n].p.ioport = val; 01705 val = (char *) ast_variable_retrieve(cfg,this,"functions"); 01706 if (!val) 01707 { 01708 val = FUNCTIONS; 01709 rpt_vars[n].p.simple = 1; 01710 } 01711 rpt_vars[n].p.functions = val; 01712 val = (char *) ast_variable_retrieve(cfg,this,"link_functions"); 01713 if (val) rpt_vars[n].p.link_functions = val; 01714 else 01715 rpt_vars[n].p.link_functions = rpt_vars[n].p.functions; 01716 val = (char *) ast_variable_retrieve(cfg,this,"phone_functions"); 01717 if (val) rpt_vars[n].p.phone_functions = val; 01718 val = (char *) ast_variable_retrieve(cfg,this,"dphone_functions"); 01719 if (val) rpt_vars[n].p.dphone_functions = val; 01720 val = (char *) ast_variable_retrieve(cfg,this,"funcchar"); 01721 if (!val) rpt_vars[n].p.funcchar = FUNCCHAR; else 01722 rpt_vars[n].p.funcchar = *val; 01723 val = (char *) ast_variable_retrieve(cfg,this,"endchar"); 01724 if (!val) rpt_vars[n].p.endchar = ENDCHAR; else 01725 rpt_vars[n].p.endchar = *val; 01726 val = (char *) ast_variable_retrieve(cfg,this,"nobusyout"); 01727 if (val) rpt_vars[n].p.nobusyout = ast_true(val); 01728 val = (char *) ast_variable_retrieve(cfg,this,"notelemtx"); 01729 if (val) rpt_vars[n].p.notelemtx = ast_true(val); 01730 val = (char *) ast_variable_retrieve(cfg,this,"propagate_dtmf"); 01731 if (val) rpt_vars[n].p.propagate_dtmf = ast_true(val); 01732 val = (char *) ast_variable_retrieve(cfg,this,"propagate_phonedtmf"); 01733 if (val) rpt_vars[n].p.propagate_phonedtmf = ast_true(val); 01734 val = (char *) ast_variable_retrieve(cfg,this,"linktolink"); 01735 if (val) rpt_vars[n].p.linktolink = ast_true(val); 01736 val = (char *) ast_variable_retrieve(cfg,this,"nodes"); 01737 if (!val) val = NODES; 01738 rpt_vars[n].p.nodes = val; 01739 val = (char *) ast_variable_retrieve(cfg,this,"extnodes"); 01740 if (!val) val = EXTNODES; 01741 rpt_vars[n].p.extnodes = val; 01742 val = (char *) ast_variable_retrieve(cfg,this,"extnodefile"); 01743 if (!val) val = EXTNODEFILE; 01744 rpt_vars[n].p.extnodefile = val; 01745 val = (char *) ast_variable_retrieve(cfg,this,"archivedir"); 01746 if (val) rpt_vars[n].p.archivedir = val; 01747 val = (char *) ast_variable_retrieve(cfg,this,"authlevel"); 01748 if (val) rpt_vars[n].p.authlevel = atoi(val); 01749 else rpt_vars[n].p.authlevel = 0; 01750 val = (char *) ast_variable_retrieve(cfg,this,"monminblocks"); 01751 if (val) rpt_vars[n].p.monminblocks = atol(val); 01752 else rpt_vars[n].p.monminblocks = DEFAULT_MONITOR_MIN_DISK_BLOCKS; 01753 val = (char *) ast_variable_retrieve(cfg,this,"remote_inact_timeout"); 01754 if (val) rpt_vars[n].p.remoteinacttimeout = atoi(val); 01755 else rpt_vars[n].p.remoteinacttimeout = DEFAULT_REMOTE_INACT_TIMEOUT; 01756 val = (char *) ast_variable_retrieve(cfg,this,"civaddr"); 01757 if (val) rpt_vars[n].p.civaddr = atoi(val); 01758 else rpt_vars[n].p.civaddr = DEFAULT_CIV_ADDR; 01759 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout"); 01760 if (val) rpt_vars[n].p.remotetimeout = atoi(val); 01761 else rpt_vars[n].p.remotetimeout = DEFAULT_REMOTE_TIMEOUT; 01762 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning"); 01763 if (val) rpt_vars[n].p.remotetimeoutwarning = atoi(val); 01764 else rpt_vars[n].p.remotetimeoutwarning = DEFAULT_REMOTE_TIMEOUT_WARNING; 01765 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning_freq"); 01766 if (val) rpt_vars[n].p.remotetimeoutwarningfreq = atoi(val); 01767 else rpt_vars[n].p.remotetimeoutwarningfreq = DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ; 01768 #ifdef __RPT_NOTCH 01769 val = (char *) ast_variable_retrieve(cfg,this,"rxnotch"); 01770 if (val) { 01771 i = finddelim(val,strs,MAXFILTERS * 2); 01772 i &= ~1; /* force an even number, rounded down */ 01773 if (i >= 2) for(j = 0; j < i; j += 2) 01774 { 01775 rpt_mknotch(atof(strs[j]),atof(strs[j + 1]), 01776 &rpt_vars[n].filters[j >> 1].gain, 01777 &rpt_vars[n].filters[j >> 1].const0, 01778 &rpt_vars[n].filters[j >> 1].const1, 01779 &rpt_vars[n].filters[j >> 1].const2); 01780 sprintf(rpt_vars[n].filters[j >> 1].desc,"%s Hz, BW = %s", 01781 strs[j],strs[j + 1]); 01782 } 01783 01784 } 01785 #endif 01786 val = (char *) ast_variable_retrieve(cfg,this,"inxlat"); 01787 if (val) { 01788 memset(&rpt_vars[n].p.inxlat,0,sizeof(struct rpt_xlat)); 01789 i = finddelim(val,strs,3); 01790 if (i) strncpy(rpt_vars[n].p.inxlat.funccharseq,strs[0],MAXXLAT - 1); 01791 if (i > 1) strncpy(rpt_vars[n].p.inxlat.endcharseq,strs[1],MAXXLAT - 1); 01792 if (i > 2) strncpy(rpt_vars[n].p.inxlat.passchars,strs[2],MAXXLAT - 1); 01793 } 01794 val = (char *) ast_variable_retrieve(cfg,this,"outxlat"); 01795 if (val) { 01796 memset(&rpt_vars[n].p.outxlat,0,sizeof(struct rpt_xlat)); 01797 i = finddelim(val,strs,3); 01798 if (i) strncpy(rpt_vars[n].p.outxlat.funccharseq,strs[0],MAXXLAT - 1); 01799 if (i > 1) strncpy(rpt_vars[n].p.outxlat.endcharseq,strs[1],MAXXLAT - 1); 01800 if (i > 2) strncpy(rpt_vars[n].p.outxlat.passchars,strs[2],MAXXLAT - 1); 01801 } 01802 /* retreive the stanza name for the control states if there is one */ 01803 val = (char *) ast_variable_retrieve(cfg,this,"controlstates"); 01804 rpt_vars[n].p.csstanzaname = val; 01805 01806 /* retreive the stanza name for the scheduler if there is one */ 01807 val = (char *) ast_variable_retrieve(cfg,this,"scheduler"); 01808 rpt_vars[n].p.skedstanzaname = val; 01809 01810 /* retreive the stanza name for the txlimits */ 01811 val = (char *) ast_variable_retrieve(cfg,this,"txlimits"); 01812 rpt_vars[n].p.txlimitsstanzaname = val; 01813 01814 longestnode = 0; 01815 01816 vp = ast_variable_browse(cfg, rpt_vars[n].p.nodes); 01817 01818 while(vp){ 01819 j = strlen(vp->name); 01820 if (j > longestnode) 01821 longestnode = j; 01822 vp = vp->next; 01823 } 01824 01825 rpt_vars[n].longestnode = longestnode; 01826 01827 /* 01828 * For this repeater, Determine the length of the longest function 01829 */ 01830 rpt_vars[n].longestfunc = 0; 01831 vp = ast_variable_browse(cfg, rpt_vars[n].p.functions); 01832 while(vp){ 01833 j = strlen(vp->name); 01834 if (j > rpt_vars[n].longestfunc) 01835 rpt_vars[n].longestfunc = j; 01836 vp = vp->next; 01837 } 01838 /* 01839 * For this repeater, Determine the length of the longest function 01840 */ 01841 rpt_vars[n].link_longestfunc = 0; 01842 vp = ast_variable_browse(cfg, rpt_vars[n].p.link_functions); 01843 while(vp){ 01844 j = strlen(vp->name); 01845 if (j > rpt_vars[n].link_longestfunc) 01846 rpt_vars[n].link_longestfunc = j; 01847 vp = vp->next; 01848 } 01849 rpt_vars[n].phone_longestfunc = 0; 01850 if (rpt_vars[n].p.phone_functions) 01851 { 01852 vp = ast_variable_browse(cfg, rpt_vars[n].p.phone_functions); 01853 while(vp){ 01854 j = strlen(vp->name); 01855 if (j > rpt_vars[n].phone_longestfunc) 01856 rpt_vars[n].phone_longestfunc = j; 01857 vp = vp->next; 01858 } 01859 } 01860 rpt_vars[n].dphone_longestfunc = 0; 01861 if (rpt_vars[n].p.dphone_functions) 01862 { 01863 vp = ast_variable_browse(cfg, rpt_vars[n].p.dphone_functions); 01864 while(vp){ 01865 j = strlen(vp->name); 01866 if (j > rpt_vars[n].dphone_longestfunc) 01867 rpt_vars[n].dphone_longestfunc = j; 01868 vp = vp->next; 01869 } 01870 } 01871 rpt_vars[n].macro_longest = 1; 01872 vp = ast_variable_browse(cfg, rpt_vars[n].p.macro); 01873 while(vp){ 01874 j = strlen(vp->name); 01875 if (j > rpt_vars[n].macro_longest) 01876 rpt_vars[n].macro_longest = j; 01877 vp = vp->next; 01878 } 01879 01880 /* Browse for control states */ 01881 if(rpt_vars[n].p.csstanzaname) 01882 vp = ast_variable_browse(cfg, rpt_vars[n].p.csstanzaname); 01883 else 01884 vp = NULL; 01885 for( i = 0 ; vp && (i < MAX_SYSSTATES) ; i++){ /* Iterate over the number of control state lines in the stanza */ 01886 int k,nukw,statenum; 01887 statenum=atoi(vp->name); 01888 strncpy(s1, vp->value, 255); 01889 s1[255] = 0; 01890 nukw = finddelim(s1,strs,32); 01891 01892 for (k = 0 ; k < nukw ; k++){ /* for each user specified keyword */ 01893 for(j = 0 ; cs_keywords[j] != NULL ; j++){ /* try to match to one in our internal table */ 01894 if(!strcmp(strs[k],cs_keywords[j])){ 01895 switch(j){ 01896 case 0: /* rptena */ 01897 rpt_vars[n].p.s[statenum].txdisable = 0; 01898 break; 01899 case 1: /* rptdis */ 01900 rpt_vars[n].p.s[statenum].txdisable = 1; 01901 break; 01902 01903 case 2: /* apena */ 01904 rpt_vars[n].p.s[statenum].autopatchdisable = 0; 01905 break; 01906 01907 case 3: /* apdis */ 01908 rpt_vars[n].p.s[statenum].autopatchdisable = 1; 01909 break; 01910 01911 case 4: /* lnkena */ 01912 rpt_vars[n].p.s[statenum].linkfundisable = 0; 01913 break; 01914 01915 case 5: /* lnkdis */ 01916 rpt_vars[n].p.s[statenum].linkfundisable = 1; 01917 break; 01918 01919 case 6: /* totena */ 01920 rpt_vars[n].p.s[statenum].totdisable = 0; 01921 break; 01922 01923 case 7: /* totdis */ 01924 rpt_vars[n].p.s[statenum].totdisable = 1; 01925 break; 01926 01927 case 8: /* skena */ 01928 rpt_vars[n].p.s[statenum].schedulerdisable = 0; 01929 break; 01930 01931 case 9: /* skdis */ 01932 rpt_vars[n].p.s[statenum].schedulerdisable = 1; 01933 break; 01934 01935 case 10: /* ufena */ 01936 rpt_vars[n].p.s[statenum].userfundisable = 0; 01937 break; 01938 01939 case 11: /* ufdis */ 01940 rpt_vars[n].p.s[statenum].userfundisable = 1; 01941 break; 01942 01943 case 12: /* atena */ 01944 rpt_vars[n].p.s[statenum].alternatetail = 1; 01945 break; 01946 01947 case 13: /* atdis */ 01948 rpt_vars[n].p.s[statenum].alternatetail = 0; 01949 break; 01950 01951 default: 01952 ast_log(LOG_WARNING, 01953 "Unhandled control state keyword %s", cs_keywords[i]); 01954 break; 01955 } 01956 } 01957 } 01958 } 01959 vp = vp->next; 01960 } 01961 ast_mutex_unlock(&rpt_vars[n].lock); 01962 }
static void local_dtmf_helper | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 8466 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().
08467 { 08468 int res; 08469 pthread_attr_t attr; 08470 char cmd[MAXDTMF+1] = ""; 08471 08472 if (myrpt->p.archivedir) 08473 { 08474 char str[100]; 08475 08476 sprintf(str,"DTMF,MAIN,%c",c); 08477 donodelog(myrpt,str); 08478 } 08479 if (c == myrpt->p.endchar) 08480 { 08481 /* if in simple mode, kill autopatch */ 08482 if (myrpt->p.simple && myrpt->callmode) 08483 { 08484 rpt_mutex_lock(&myrpt->lock); 08485 myrpt->callmode = 0; 08486 rpt_mutex_unlock(&myrpt->lock); 08487 rpt_telemetry(myrpt,TERM,NULL); 08488 return; 08489 } 08490 rpt_mutex_lock(&myrpt->lock); 08491 myrpt->stopgen = 1; 08492 if (myrpt->cmdnode[0]) 08493 { 08494 myrpt->cmdnode[0] = 0; 08495 myrpt->dtmfidx = -1; 08496 myrpt->dtmfbuf[0] = 0; 08497 rpt_mutex_unlock(&myrpt->lock); 08498 rpt_telemetry(myrpt,COMPLETE,NULL); 08499 } 08500 else 08501 { 08502 rpt_mutex_unlock(&myrpt->lock); 08503 if (myrpt->p.propagate_phonedtmf) 08504 do_dtmf_phone(myrpt,NULL,c); 08505 } 08506 return; 08507 } 08508 rpt_mutex_lock(&myrpt->lock); 08509 if (myrpt->cmdnode[0]) 08510 { 08511 rpt_mutex_unlock(&myrpt->lock); 08512 send_link_dtmf(myrpt,c); 08513 return; 08514 } 08515 if (!myrpt->p.simple) 08516 { 08517 if (c == myrpt->p.funcchar) 08518 { 08519 myrpt->dtmfidx = 0; 08520 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08521 rpt_mutex_unlock(&myrpt->lock); 08522 time(&myrpt->dtmf_time); 08523 return; 08524 } 08525 else if ((c != myrpt->p.endchar) && (myrpt->dtmfidx >= 0)) 08526 { 08527 time(&myrpt->dtmf_time); 08528 08529 if (myrpt->dtmfidx < MAXDTMF) 08530 { 08531 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 08532 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08533 08534 strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1); 08535 08536 rpt_mutex_unlock(&myrpt->lock); 08537 res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL); 08538 rpt_mutex_lock(&myrpt->lock); 08539 switch(res){ 08540 case DC_INDETERMINATE: 08541 break; 08542 case DC_REQ_FLUSH: 08543 myrpt->dtmfidx = 0; 08544 myrpt->dtmfbuf[0] = 0; 08545 break; 08546 case DC_COMPLETE: 08547 case DC_COMPLETEQUIET: 08548 myrpt->totalexecdcommands++; 08549 myrpt->dailyexecdcommands++; 08550 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 08551 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 08552 myrpt->dtmfbuf[0] = 0; 08553 myrpt->dtmfidx = -1; 08554 myrpt->dtmf_time = 0; 08555 break; 08556 08557 case DC_ERROR: 08558 default: 08559 myrpt->dtmfbuf[0] = 0; 08560 myrpt->dtmfidx = -1; 08561 myrpt->dtmf_time = 0; 08562 break; 08563 } 08564 if(res != DC_INDETERMINATE) { 08565 rpt_mutex_unlock(&myrpt->lock); 08566 return; 08567 } 08568 } 08569 } 08570 } 08571 else /* if simple */ 08572 { 08573 if ((!myrpt->callmode) && (c == myrpt->p.funcchar)) 08574 { 08575 myrpt->callmode = 1; 08576 myrpt->patchnoct = 0; 08577 myrpt->patchquiet = 0; 08578 myrpt->patchfarenddisconnect = 0; 08579 myrpt->patchdialtime = 0; 08580 strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT); 08581 myrpt->cidx = 0; 08582 myrpt->exten[myrpt->cidx] = 0; 08583 rpt_mutex_unlock(&myrpt->lock); 08584 pthread_attr_init(&attr); 08585 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08586 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt); 08587 return; 08588 } 08589 } 08590 if (myrpt->callmode == 1) 08591 { 08592 myrpt->exten[myrpt->cidx++] = c; 08593 myrpt->exten[myrpt->cidx] = 0; 08594 /* if this exists */ 08595 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 08596 { 08597 myrpt->callmode = 2; 08598 rpt_mutex_unlock(&myrpt->lock); 08599 if(!myrpt->patchquiet) 08600 rpt_telemetry(myrpt,PROC,NULL); 08601 return; 08602 } 08603 /* if can continue, do so */ 08604 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 08605 { 08606 /* call has failed, inform user */ 08607 myrpt->callmode = 4; 08608 } 08609 rpt_mutex_unlock(&myrpt->lock); 08610 return; 08611 } 08612 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 08613 { 08614 myrpt->mydtmf = c; 08615 } 08616 rpt_mutex_unlock(&myrpt->lock); 08617 if ((myrpt->dtmfidx < 0) && myrpt->p.propagate_phonedtmf) 08618 do_dtmf_phone(myrpt,NULL,c); 08619 return; 08620 }
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 7189 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07190 { 07191 unsigned char cmdstr[10]; 07192 07193 cmdstr[0] = cmdstr[1] = 0xfe; 07194 cmdstr[2] = myrpt->p.civaddr; 07195 cmdstr[3] = 0xe0; 07196 cmdstr[4] = 0x0a; 07197 cmdstr[5] = 0xfd; 07198 07199 return(civ_cmd(myrpt,cmdstr,6)); 07200 }
static int multimode_bump_freq | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 7552 of file app_rpt.c.
References multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), and rpt::remote.
Referenced by function_remote(), and service_scan().
07553 { 07554 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07555 return multimode_bump_freq_ft897(myrpt, interval); 07556 else if(!strcmp(myrpt->remote, remote_rig_ic706)) 07557 return multimode_bump_freq_ic706(myrpt, interval); 07558 else 07559 return -1; 07560 }
static int multimode_bump_freq_ft897 | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 6741 of file app_rpt.c.
References check_freq_ft897(), rpt::freq, MAXREMSTR, set_freq_ft897(), and split_freq().
Referenced by multimode_bump_freq().
06742 { 06743 int m,d; 06744 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 06745 06746 if(debug) 06747 printf("Before bump: %s\n", myrpt->freq); 06748 06749 if(split_freq(mhz, decimals, myrpt->freq)) 06750 return -1; 06751 06752 m = atoi(mhz); 06753 d = atoi(decimals); 06754 06755 d += (interval / 10); /* 10Hz resolution */ 06756 if(d < 0){ 06757 m--; 06758 d += 100000; 06759 } 06760 else if(d >= 100000){ 06761 m++; 06762 d -= 100000; 06763 } 06764 06765 if(check_freq_ft897(m, d, NULL)){ 06766 if(debug) 06767 printf("Bump freq invalid\n"); 06768 return -1; 06769 } 06770 06771 snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d); 06772 06773 if(debug) 06774 printf("After bump: %s\n", myrpt->freq); 06775 06776 return set_freq_ft897(myrpt, myrpt->freq); 06777 }
static int multimode_bump_freq_ic706 | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 7285 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().
07286 { 07287 int m,d; 07288 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07289 unsigned char cmdstr[20]; 07290 07291 if(debug) 07292 printf("Before bump: %s\n", myrpt->freq); 07293 07294 if(split_freq(mhz, decimals, myrpt->freq)) 07295 return -1; 07296 07297 m = atoi(mhz); 07298 d = atoi(decimals); 07299 07300 d += (interval / 10); /* 10Hz resolution */ 07301 if(d < 0){ 07302 m--; 07303 d += 100000; 07304 } 07305 else if(d >= 100000){ 07306 m++; 07307 d -= 100000; 07308 } 07309 07310 if(check_freq_ic706(m, d, NULL)){ 07311 if(debug) 07312 printf("Bump freq invalid\n"); 07313 return -1; 07314 } 07315 07316 snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d); 07317 07318 if(debug) 07319 printf("After bump: %s\n", myrpt->freq); 07320 07321 /* The ic-706 likes packed BCD frequencies */ 07322 07323 cmdstr[0] = cmdstr[1] = 0xfe; 07324 cmdstr[2] = myrpt->p.civaddr; 07325 cmdstr[3] = 0xe0; 07326 cmdstr[4] = 0; 07327 cmdstr[5] = ((d % 10) << 4); 07328 cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10); 07329 cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000); 07330 cmdstr[8] = (((m % 100)/10) << 4) + (m % 10); 07331 cmdstr[9] = (m / 100); 07332 cmdstr[10] = 0xfd; 07333 07334 return(serial_remote_io(myrpt,cmdstr,11,NULL,0,0)); 07335 }
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, rpt::p, and val.
Referenced by attempt_reconnect(), connect_link(), and function_ilink().
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.
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 2458 of file app_rpt.c.
References play_tone_pair().
Referenced by send_morse().
02459 { 02460 return play_tone_pair(chan, 0, 0, duration, 0); 02461 }
static int play_tone | ( | struct ast_channel * | chan, | |
int | freq, | |||
int | duration, | |||
int | amplitude | |||
) | [static] |
Definition at line 2453 of file app_rpt.c.
References play_tone_pair().
Referenced by rpt_tele_thread(), and send_morse().
02454 { 02455 return play_tone_pair(chan, freq, 0, duration, amplitude); 02456 }
static int play_tone_pair | ( | struct ast_channel * | chan, | |
int | f1, | |||
int | f2, | |||
int | duration, | |||
int | amplitude | |||
) | [static] |
Definition at line 2439 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().
02440 { 02441 int res; 02442 02443 if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude))) 02444 return res; 02445 02446 while(chan->generatordata) { 02447 if (ast_safe_sleep(chan,1)) return -1; 02448 } 02449 02450 return 0; 02451 }
static void queue_id | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 8625 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().
08626 { 08627 if(myrpt->p.idtime){ /* ID time must be non-zero */ 08628 myrpt->mustid = myrpt->tailid = 0; 08629 myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */ 08630 rpt_mutex_unlock(&myrpt->lock); 08631 rpt_telemetry(myrpt,ID,NULL); 08632 rpt_mutex_lock(&myrpt->lock); 08633 } 08634 }
static int rbi_mhztoband | ( | char * | str | ) | [static] |
Definition at line 5689 of file app_rpt.c.
Referenced by setrbi(), and setrbi_check().
05690 { 05691 int i; 05692 05693 i = atoi(str) / 10; /* get the 10's of mhz */ 05694 switch(i) 05695 { 05696 case 2: 05697 return 10; 05698 case 5: 05699 return 11; 05700 case 14: 05701 return 2; 05702 case 22: 05703 return 3; 05704 case 44: 05705 return 4; 05706 case 124: 05707 return 0; 05708 case 125: 05709 return 1; 05710 case 126: 05711 return 8; 05712 case 127: 05713 return 5; 05714 case 128: 05715 return 6; 05716 case 129: 05717 return 7; 05718 default: 05719 break; 05720 } 05721 return -1; 05722 }
static void rbi_out | ( | struct rpt * | myrpt, | |
unsigned char * | data | |||
) | [static] |
Definition at line 5848 of file app_rpt.c.
References ast_log(), ast_channel::fds, LOG_WARNING, rbi_out_parallel(), and rpt::zaprxchannel.
Referenced by setrbi().
05849 { 05850 struct zt_radio_param r; 05851 05852 memset(&r,0,sizeof(struct zt_radio_param)); 05853 r.radpar = ZT_RADPAR_REMMODE; 05854 r.data = ZT_RADPAR_REM_RBI1; 05855 /* if setparam ioctl fails, its probably not a pciradio card */ 05856 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1) 05857 { 05858 rbi_out_parallel(myrpt,data); 05859 return; 05860 } 05861 r.radpar = ZT_RADPAR_REMCOMMAND; 05862 memcpy(&r.data,data,5); 05863 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1) 05864 { 05865 ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->zaprxchannel->name); 05866 return; 05867 } 05868 }
static void rbi_out_parallel | ( | struct rpt * | myrpt, | |
unsigned char * | data | |||
) | [static] |
Definition at line 5820 of file app_rpt.c.
References rpt::iobase, and rpt::p.
Referenced by rbi_out().
05821 { 05822 #ifdef __i386__ 05823 int i,j; 05824 unsigned char od,d; 05825 static volatile long long delayvar; 05826 05827 for(i = 0 ; i < 5 ; i++){ 05828 od = *data++; 05829 for(j = 0 ; j < 8 ; j++){ 05830 d = od & 1; 05831 outb(d,myrpt->p.iobase); 05832 /* >= 15 us */ 05833 for(delayvar = 1; delayvar < 15000; delayvar++); 05834 od >>= 1; 05835 outb(d | 2,myrpt->p.iobase); 05836 /* >= 30 us */ 05837 for(delayvar = 1; delayvar < 30000; delayvar++); 05838 outb(d,myrpt->p.iobase); 05839 /* >= 10 us */ 05840 for(delayvar = 1; delayvar < 10000; delayvar++); 05841 } 05842 } 05843 /* >= 50 us */ 05844 for(delayvar = 1; delayvar < 50000; delayvar++); 05845 #endif 05846 }
static int rbi_pltocode | ( | char * | str | ) | [static] |
Definition at line 5725 of file app_rpt.c.
References s.
Referenced by setrbi(), and setrbi_check().
05726 { 05727 int i; 05728 char *s; 05729 05730 s = strchr(str,'.'); 05731 i = 0; 05732 if (s) i = atoi(s + 1); 05733 i += atoi(str) * 10; 05734 switch(i) 05735 { 05736 case 670: 05737 return 0; 05738 case 719: 05739 return 1; 05740 case 744: 05741 return 2; 05742 case 770: 05743 return 3; 05744 case 797: 05745 return 4; 05746 case 825: 05747 return 5; 05748 case 854: 05749 return 6; 05750 case 885: 05751 return 7; 05752 case 915: 05753 return 8; 05754 case 948: 05755 return 9; 05756 case 974: 05757 return 10; 05758 case 1000: 05759 return 11; 05760 case 1035: 05761 return 12; 05762 case 1072: 05763 return 13; 05764 case 1109: 05765 return 14; 05766 case 1148: 05767 return 15; 05768 case 1188: 05769 return 16; 05770 case 1230: 05771 return 17; 05772 case 1273: 05773 return 18; 05774 case 1318: 05775 return 19; 05776 case 1365: 05777 return 20; 05778 case 1413: 05779 return 21; 05780 case 1462: 05781 return 22; 05782 case 1514: 05783 return 23; 05784 case 1567: 05785 return 24; 05786 case 1622: 05787 return 25; 05788 case 1679: 05789 return 26; 05790 case 1738: 05791 return 27; 05792 case 1799: 05793 return 28; 05794 case 1862: 05795 return 29; 05796 case 1928: 05797 return 30; 05798 case 2035: 05799 return 31; 05800 case 2107: 05801 return 32; 05802 case 2181: 05803 return 33; 05804 case 2257: 05805 return 34; 05806 case 2336: 05807 return 35; 05808 case 2418: 05809 return 36; 05810 case 2503: 05811 return 37; 05812 } 05813 return -1; 05814 }
static int reload | ( | void | ) | [static] |
static int retreive_memory | ( | struct rpt * | myrpt, | |
char * | memory | |||
) | [static] |
Definition at line 7649 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().
07650 { 07651 char tmp[30], *s, *s1, *val; 07652 07653 val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.memory, memory); 07654 if (!val){ 07655 return -1; 07656 } 07657 strncpy(tmp,val,sizeof(tmp) - 1); 07658 tmp[sizeof(tmp)-1] = 0; 07659 07660 s = strchr(tmp,','); 07661 if (!s) 07662 return 1; 07663 *s++ = 0; 07664 s1 = strchr(s,','); 07665 if (!s1) 07666 return 1; 07667 *s1++ = 0; 07668 strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1); 07669 strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1); 07670 strncpy(myrpt->txpl, s, sizeof(myrpt->rxpl) - 1); 07671 myrpt->remmode = REM_MODE_FM; 07672 myrpt->offset = REM_SIMPLEX; 07673 myrpt->powerlevel = REM_MEDPWR; 07674 myrpt->txplon = myrpt->rxplon = 0; 07675 while(*s1){ 07676 switch(*s1++){ 07677 case 'A': 07678 case 'a': 07679 strcpy(myrpt->rxpl, "100.0"); 07680 strcpy(myrpt->txpl, "100.0"); 07681 myrpt->remmode = REM_MODE_AM; 07682 break; 07683 case 'B': 07684 case 'b': 07685 strcpy(myrpt->rxpl, "100.0"); 07686 strcpy(myrpt->txpl, "100.0"); 07687 myrpt->remmode = REM_MODE_LSB; 07688 break; 07689 case 'F': 07690 myrpt->remmode = REM_MODE_FM; 07691 break; 07692 case 'L': 07693 case 'l': 07694 myrpt->powerlevel = REM_LOWPWR; 07695 break; 07696 case 'H': 07697 case 'h': 07698 myrpt->powerlevel = REM_HIPWR; 07699 break; 07700 07701 case 'M': 07702 case 'm': 07703 myrpt->powerlevel = REM_MEDPWR; 07704 break; 07705 07706 case '-': 07707 myrpt->offset = REM_MINUS; 07708 break; 07709 07710 case '+': 07711 myrpt->offset = REM_PLUS; 07712 break; 07713 07714 case 'S': 07715 case 's': 07716 myrpt->offset = REM_SIMPLEX; 07717 break; 07718 07719 case 'T': 07720 case 't': 07721 myrpt->txplon = 1; 07722 break; 07723 07724 case 'R': 07725 case 'r': 07726 myrpt->rxplon = 1; 07727 break; 07728 07729 case 'U': 07730 case 'u': 07731 strcpy(myrpt->rxpl, "100.0"); 07732 strcpy(myrpt->txpl, "100.0"); 07733 myrpt->remmode = REM_MODE_USB; 07734 break; 07735 default: 07736 return 1; 07737 } 07738 } 07739 return 0; 07740 }
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 8759 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, f, ast_channel::fds, 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, 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, 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, rpt::scram, rpt::skedtimer, START_DELAY, rpt::startupmacro, rpt::sysstate_cur, t, 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, 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.
08760 { 08761 struct rpt *myrpt = (struct rpt *)this; 08762 char *tele,*idtalkover,c; 08763 int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,othertelemqueued; 08764 int tailmessagequeued,ctqueued,dtmfed; 08765 struct ast_channel *who; 08766 ZT_CONFINFO ci; /* conference info */ 08767 time_t t; 08768 struct rpt_link *l,*m; 08769 struct rpt_tele *telem; 08770 char tmpstr[300],lstr[MAXLINKLIST]; 08771 08772 08773 if (myrpt->p.archivedir) mkdir(myrpt->p.archivedir,0600); 08774 sprintf(tmpstr,"%s/%s",myrpt->p.archivedir,myrpt->name); 08775 mkdir(tmpstr,0600); 08776 rpt_mutex_lock(&myrpt->lock); 08777 08778 telem = myrpt->tele.next; 08779 while(telem != &myrpt->tele) 08780 { 08781 ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV); 08782 telem = telem->next; 08783 } 08784 rpt_mutex_unlock(&myrpt->lock); 08785 /* find our index, and load the vars initially */ 08786 for(i = 0; i < nrpts; i++) 08787 { 08788 if (&rpt_vars[i] == myrpt) 08789 { 08790 load_rpt_vars(i,0); 08791 break; 08792 } 08793 } 08794 rpt_mutex_lock(&myrpt->lock); 08795 strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1); 08796 tele = strchr(tmpstr,'/'); 08797 if (!tele) 08798 { 08799 fprintf(stderr,"rpt:Rxchannel Dial number (%s) must be in format tech/number\n",myrpt->rxchanname); 08800 rpt_mutex_unlock(&myrpt->lock); 08801 myrpt->rpt_thread = AST_PTHREADT_STOP; 08802 pthread_exit(NULL); 08803 } 08804 *tele++ = 0; 08805 myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 08806 myrpt->zaprxchannel = NULL; 08807 if (!strcasecmp(tmpstr,"Zap")) 08808 myrpt->zaprxchannel = myrpt->rxchannel; 08809 if (myrpt->rxchannel) 08810 { 08811 if (myrpt->rxchannel->_state == AST_STATE_BUSY) 08812 { 08813 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 08814 rpt_mutex_unlock(&myrpt->lock); 08815 ast_hangup(myrpt->rxchannel); 08816 myrpt->rpt_thread = AST_PTHREADT_STOP; 08817 pthread_exit(NULL); 08818 } 08819 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 08820 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 08821 #ifdef AST_CDR_FLAG_POST_DISABLED 08822 ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08823 #endif 08824 myrpt->rxchannel->whentohangup = 0; 08825 myrpt->rxchannel->appl = "Apprpt"; 08826 myrpt->rxchannel->data = "(Repeater Rx)"; 08827 if (option_verbose > 2) 08828 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 08829 tmpstr,tele,myrpt->rxchannel->name); 08830 ast_call(myrpt->rxchannel,tele,999); 08831 if (myrpt->rxchannel->_state != AST_STATE_UP) 08832 { 08833 rpt_mutex_unlock(&myrpt->lock); 08834 ast_hangup(myrpt->rxchannel); 08835 myrpt->rpt_thread = AST_PTHREADT_STOP; 08836 pthread_exit(NULL); 08837 } 08838 } 08839 else 08840 { 08841 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 08842 rpt_mutex_unlock(&myrpt->lock); 08843 myrpt->rpt_thread = AST_PTHREADT_STOP; 08844 pthread_exit(NULL); 08845 } 08846 myrpt->zaptxchannel = NULL; 08847 if (myrpt->txchanname) 08848 { 08849 strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1); 08850 tele = strchr(tmpstr,'/'); 08851 if (!tele) 08852 { 08853 fprintf(stderr,"rpt:Txchannel Dial number (%s) must be in format tech/number\n",myrpt->txchanname); 08854 rpt_mutex_unlock(&myrpt->lock); 08855 ast_hangup(myrpt->rxchannel); 08856 myrpt->rpt_thread = AST_PTHREADT_STOP; 08857 pthread_exit(NULL); 08858 } 08859 *tele++ = 0; 08860 myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 08861 if (!strcasecmp(tmpstr,"Zap")) 08862 myrpt->zaptxchannel = myrpt->txchannel; 08863 if (myrpt->txchannel) 08864 { 08865 if (myrpt->txchannel->_state == AST_STATE_BUSY) 08866 { 08867 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 08868 rpt_mutex_unlock(&myrpt->lock); 08869 ast_hangup(myrpt->txchannel); 08870 ast_hangup(myrpt->rxchannel); 08871 myrpt->rpt_thread = AST_PTHREADT_STOP; 08872 pthread_exit(NULL); 08873 } 08874 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 08875 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 08876 #ifdef AST_CDR_FLAG_POST_DISABLED 08877 ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08878 #endif 08879 myrpt->txchannel->whentohangup = 0; 08880 myrpt->txchannel->appl = "Apprpt"; 08881 myrpt->txchannel->data = "(Repeater Tx)"; 08882 if (option_verbose > 2) 08883 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 08884 tmpstr,tele,myrpt->txchannel->name); 08885 ast_call(myrpt->txchannel,tele,999); 08886 if (myrpt->rxchannel->_state != AST_STATE_UP) 08887 { 08888 rpt_mutex_unlock(&myrpt->lock); 08889 ast_hangup(myrpt->rxchannel); 08890 ast_hangup(myrpt->txchannel); 08891 myrpt->rpt_thread = AST_PTHREADT_STOP; 08892 pthread_exit(NULL); 08893 } 08894 } 08895 else 08896 { 08897 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 08898 rpt_mutex_unlock(&myrpt->lock); 08899 ast_hangup(myrpt->rxchannel); 08900 myrpt->rpt_thread = AST_PTHREADT_STOP; 08901 pthread_exit(NULL); 08902 } 08903 } 08904 else 08905 { 08906 myrpt->txchannel = myrpt->rxchannel; 08907 } 08908 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 08909 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 08910 /* allocate a pseudo-channel thru asterisk */ 08911 myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08912 if (!myrpt->pchannel) 08913 { 08914 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08915 rpt_mutex_unlock(&myrpt->lock); 08916 if (myrpt->txchannel != myrpt->rxchannel) 08917 ast_hangup(myrpt->txchannel); 08918 ast_hangup(myrpt->rxchannel); 08919 myrpt->rpt_thread = AST_PTHREADT_STOP; 08920 pthread_exit(NULL); 08921 } 08922 #ifdef AST_CDR_FLAG_POST_DISABLED 08923 ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08924 #endif 08925 if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel; 08926 if (!myrpt->zaptxchannel) 08927 { 08928 /* allocate a pseudo-channel thru asterisk */ 08929 myrpt->zaptxchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08930 if (!myrpt->zaptxchannel) 08931 { 08932 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08933 rpt_mutex_unlock(&myrpt->lock); 08934 if (myrpt->txchannel != myrpt->rxchannel) 08935 ast_hangup(myrpt->txchannel); 08936 ast_hangup(myrpt->rxchannel); 08937 myrpt->rpt_thread = AST_PTHREADT_STOP; 08938 pthread_exit(NULL); 08939 } 08940 ast_set_read_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR); 08941 ast_set_write_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR); 08942 #ifdef AST_CDR_FLAG_POST_DISABLED 08943 ast_set_flag(myrpt->zaptxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08944 #endif 08945 } 08946 /* allocate a pseudo-channel thru asterisk */ 08947 myrpt->monchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08948 if (!myrpt->monchannel) 08949 { 08950 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08951 rpt_mutex_unlock(&myrpt->lock); 08952 if (myrpt->txchannel != myrpt->rxchannel) 08953 ast_hangup(myrpt->txchannel); 08954 ast_hangup(myrpt->rxchannel); 08955 myrpt->rpt_thread = AST_PTHREADT_STOP; 08956 pthread_exit(NULL); 08957 } 08958 ast_set_read_format(myrpt->monchannel,AST_FORMAT_SLINEAR); 08959 ast_set_write_format(myrpt->monchannel,AST_FORMAT_SLINEAR); 08960 #ifdef AST_CDR_FLAG_POST_DISABLED 08961 ast_set_flag(myrpt->monchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08962 #endif 08963 /* make a conference for the tx */ 08964 ci.chan = 0; 08965 ci.confno = -1; /* make a new conf */ 08966 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER; 08967 /* first put the channel on the conference in proper mode */ 08968 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_SETCONF,&ci) == -1) 08969 { 08970 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 08971 rpt_mutex_unlock(&myrpt->lock); 08972 ast_hangup(myrpt->pchannel); 08973 ast_hangup(myrpt->monchannel); 08974 if (myrpt->txchannel != myrpt->rxchannel) 08975 ast_hangup(myrpt->txchannel); 08976 ast_hangup(myrpt->rxchannel); 08977 myrpt->rpt_thread = AST_PTHREADT_STOP; 08978 pthread_exit(NULL); 08979 } 08980 /* save tx conference number */ 08981 myrpt->txconf = ci.confno; 08982 /* make a conference for the pseudo */ 08983 ci.chan = 0; 08984 ci.confno = -1; /* make a new conf */ 08985 ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON : 08986 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 08987 /* first put the channel on the conference in announce mode */ 08988 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 08989 { 08990 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 08991 rpt_mutex_unlock(&myrpt->lock); 08992 ast_hangup(myrpt->pchannel); 08993 ast_hangup(myrpt->monchannel); 08994 if (myrpt->txchannel != myrpt->rxchannel) 08995 ast_hangup(myrpt->txchannel); 08996 ast_hangup(myrpt->rxchannel); 08997 myrpt->rpt_thread = AST_PTHREADT_STOP; 08998 pthread_exit(NULL); 08999 } 09000 /* save pseudo channel conference number */ 09001 myrpt->conf = ci.confno; 09002 /* make a conference for the pseudo */ 09003 ci.chan = 0; 09004 if ((strstr(myrpt->txchannel->name,"pseudo") == NULL) && 09005 (myrpt->zaptxchannel == myrpt->txchannel)) 09006 { 09007 /* get tx channel's port number */ 09008 if (ioctl(myrpt->txchannel->fds[0],ZT_CHANNO,&ci.confno) == -1) 09009 { 09010 ast_log(LOG_WARNING, "Unable to set tx channel's chan number\n"); 09011 rpt_mutex_unlock(&myrpt->lock); 09012 ast_hangup(myrpt->pchannel); 09013 ast_hangup(myrpt->monchannel); 09014 if (myrpt->txchannel != myrpt->rxchannel) 09015 ast_hangup(myrpt->txchannel); 09016 ast_hangup(myrpt->rxchannel); 09017 myrpt->rpt_thread = AST_PTHREADT_STOP; 09018 pthread_exit(NULL); 09019 } 09020 ci.confmode = ZT_CONF_MONITORTX; 09021 } 09022 else 09023 { 09024 ci.confno = myrpt->txconf; 09025 ci.confmode = ZT_CONF_CONFANNMON; 09026 } 09027 /* first put the channel on the conference in announce mode */ 09028 if (ioctl(myrpt->monchannel->fds[0],ZT_SETCONF,&ci) == -1) 09029 { 09030 ast_log(LOG_WARNING, "Unable to set conference mode for monitor\n"); 09031 rpt_mutex_unlock(&myrpt->lock); 09032 ast_hangup(myrpt->pchannel); 09033 ast_hangup(myrpt->monchannel); 09034 if (myrpt->txchannel != myrpt->rxchannel) 09035 ast_hangup(myrpt->txchannel); 09036 ast_hangup(myrpt->rxchannel); 09037 myrpt->rpt_thread = AST_PTHREADT_STOP; 09038 pthread_exit(NULL); 09039 } 09040 /* allocate a pseudo-channel thru asterisk */ 09041 myrpt->txpchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 09042 if (!myrpt->txpchannel) 09043 { 09044 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 09045 rpt_mutex_unlock(&myrpt->lock); 09046 ast_hangup(myrpt->pchannel); 09047 ast_hangup(myrpt->monchannel); 09048 if (myrpt->txchannel != myrpt->rxchannel) 09049 ast_hangup(myrpt->txchannel); 09050 ast_hangup(myrpt->rxchannel); 09051 myrpt->rpt_thread = AST_PTHREADT_STOP; 09052 pthread_exit(NULL); 09053 } 09054 #ifdef AST_CDR_FLAG_POST_DISABLED 09055 ast_set_flag(myrpt->txpchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 09056 #endif 09057 /* make a conference for the tx */ 09058 ci.chan = 0; 09059 ci.confno = myrpt->txconf; 09060 ci.confmode = ZT_CONF_CONF | ZT_CONF_TALKER ; 09061 /* first put the channel on the conference in proper mode */ 09062 if (ioctl(myrpt->txpchannel->fds[0],ZT_SETCONF,&ci) == -1) 09063 { 09064 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 09065 rpt_mutex_unlock(&myrpt->lock); 09066 ast_hangup(myrpt->txpchannel); 09067 ast_hangup(myrpt->monchannel); 09068 if (myrpt->txchannel != myrpt->rxchannel) 09069 ast_hangup(myrpt->txchannel); 09070 ast_hangup(myrpt->rxchannel); 09071 myrpt->rpt_thread = AST_PTHREADT_STOP; 09072 pthread_exit(NULL); 09073 } 09074 /* Now, the idea here is to copy from the physical rx channel buffer 09075 into the pseudo tx buffer, and from the pseudo rx buffer into the 09076 tx channel buffer */ 09077 myrpt->links.next = &myrpt->links; 09078 myrpt->links.prev = &myrpt->links; 09079 myrpt->tailtimer = 0; 09080 myrpt->totimer = 0; 09081 myrpt->tmsgtimer = myrpt->p.tailmessagetime; 09082 myrpt->idtimer = myrpt->p.politeid; 09083 myrpt->mustid = myrpt->tailid = 0; 09084 myrpt->callmode = 0; 09085 myrpt->tounkeyed = 0; 09086 myrpt->tonotify = 0; 09087 myrpt->retxtimer = 0; 09088 myrpt->rerxtimer = 0; 09089 myrpt->skedtimer = 0; 09090 myrpt->tailevent = 0; 09091 lasttx = 0; 09092 myrpt->keyed = 0; 09093 idtalkover = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "idtalkover"); 09094 myrpt->dtmfidx = -1; 09095 myrpt->dtmfbuf[0] = 0; 09096 myrpt->rem_dtmfidx = -1; 09097 myrpt->rem_dtmfbuf[0] = 0; 09098 myrpt->dtmf_time = 0; 09099 myrpt->rem_dtmf_time = 0; 09100 myrpt->disgorgetime = 0; 09101 myrpt->lastnodewhichkeyedusup[0] = '\0'; 09102 myrpt->dailytxtime = 0; 09103 myrpt->totaltxtime = 0; 09104 myrpt->dailykeyups = 0; 09105 myrpt->totalkeyups = 0; 09106 myrpt->dailykerchunks = 0; 09107 myrpt->totalkerchunks = 0; 09108 myrpt->dailyexecdcommands = 0; 09109 myrpt->totalexecdcommands = 0; 09110 myrpt->timeouts = 0; 09111 myrpt->exten[0] = '\0'; 09112 myrpt->lastdtmfcommand[0] = '\0'; 09113 if (myrpt->p.startupmacro) 09114 { 09115 snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro); 09116 } 09117 rpt_mutex_unlock(&myrpt->lock); 09118 val = 1; 09119 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0); 09120 val = 1; 09121 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0); 09122 if (myrpt->p.archivedir) donodelog(myrpt,"STARTUP"); 09123 dtmfed = 0; 09124 while (ms >= 0) 09125 { 09126 struct ast_frame *f,*f1,*f2; 09127 struct ast_channel *cs[300],*cs1[300]; 09128 int totx=0,elap=0,n,x,toexit=0; 09129 09130 /* DEBUG Dump */ 09131 if((myrpt->disgorgetime) && (time(NULL) >= myrpt->disgorgetime)){ 09132 struct rpt_link *zl; 09133 struct rpt_tele *zt; 09134 09135 myrpt->disgorgetime = 0; 09136 ast_log(LOG_NOTICE,"********** Variable Dump Start (app_rpt) **********\n"); 09137 ast_log(LOG_NOTICE,"totx = %d\n",totx); 09138 ast_log(LOG_NOTICE,"remrx = %d\n",remrx); 09139 ast_log(LOG_NOTICE,"lasttx = %d\n",lasttx); 09140 ast_log(LOG_NOTICE,"elap = %d\n",elap); 09141 ast_log(LOG_NOTICE,"toexit = %d\n",toexit); 09142 09143 ast_log(LOG_NOTICE,"myrpt->keyed = %d\n",myrpt->keyed); 09144 ast_log(LOG_NOTICE,"myrpt->localtx = %d\n",myrpt->localtx); 09145 ast_log(LOG_NOTICE,"myrpt->callmode = %d\n",myrpt->callmode); 09146 ast_log(LOG_NOTICE,"myrpt->mustid = %d\n",myrpt->mustid); 09147 ast_log(LOG_NOTICE,"myrpt->tounkeyed = %d\n",myrpt->tounkeyed); 09148 ast_log(LOG_NOTICE,"myrpt->tonotify = %d\n",myrpt->tonotify); 09149 ast_log(LOG_NOTICE,"myrpt->retxtimer = %ld\n",myrpt->retxtimer); 09150 ast_log(LOG_NOTICE,"myrpt->totimer = %d\n",myrpt->totimer); 09151 ast_log(LOG_NOTICE,"myrpt->tailtimer = %d\n",myrpt->tailtimer); 09152 ast_log(LOG_NOTICE,"myrpt->tailevent = %d\n",myrpt->tailevent); 09153 09154 zl = myrpt->links.next; 09155 while(zl != &myrpt->links){ 09156 ast_log(LOG_NOTICE,"*** Link Name: %s ***\n",zl->name); 09157 ast_log(LOG_NOTICE," link->lasttx %d\n",zl->lasttx); 09158 ast_log(LOG_NOTICE," link->lastrx %d\n",zl->lastrx); 09159 ast_log(LOG_NOTICE," link->connected %d\n",zl->connected); 09160 ast_log(LOG_NOTICE," link->hasconnected %d\n",zl->hasconnected); 09161 ast_log(LOG_NOTICE," link->outbound %d\n",zl->outbound); 09162 ast_log(LOG_NOTICE," link->disced %d\n",zl->disced); 09163 ast_log(LOG_NOTICE," link->killme %d\n",zl->killme); 09164 ast_log(LOG_NOTICE," link->disctime %ld\n",zl->disctime); 09165 ast_log(LOG_NOTICE," link->retrytimer %ld\n",zl->retrytimer); 09166 ast_log(LOG_NOTICE," link->retries = %d\n",zl->retries); 09167 ast_log(LOG_NOTICE," link->reconnects = %d\n",zl->reconnects); 09168 zl = zl->next; 09169 } 09170 09171 zt = myrpt->tele.next; 09172 if(zt != &myrpt->tele) 09173 ast_log(LOG_NOTICE,"*** Telemetry Queue ***\n"); 09174 while(zt != &myrpt->tele){ 09175 ast_log(LOG_NOTICE," Telemetry mode: %d\n",zt->mode); 09176 zt = zt->next; 09177 } 09178 ast_log(LOG_NOTICE,"******* Variable Dump End (app_rpt) *******\n"); 09179 09180 } 09181 09182 09183 if (myrpt->reload) 09184 { 09185 struct rpt_tele *telem; 09186 09187 rpt_mutex_lock(&myrpt->lock); 09188 telem = myrpt->tele.next; 09189 while(telem != &myrpt->tele) 09190 { 09191 ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV); 09192 telem = telem->next; 09193 } 09194 myrpt->reload = 0; 09195 rpt_mutex_unlock(&myrpt->lock); 09196 usleep(10000); 09197 /* find our index, and load the vars */ 09198 for(i = 0; i < nrpts; i++) 09199 { 09200 if (&rpt_vars[i] == myrpt) 09201 { 09202 load_rpt_vars(i,0); 09203 break; 09204 } 09205 } 09206 } 09207 09208 rpt_mutex_lock(&myrpt->lock); 09209 if (ast_check_hangup(myrpt->rxchannel)) break; 09210 if (ast_check_hangup(myrpt->txchannel)) break; 09211 if (ast_check_hangup(myrpt->pchannel)) break; 09212 if (ast_check_hangup(myrpt->monchannel)) break; 09213 if (ast_check_hangup(myrpt->txpchannel)) break; 09214 if (myrpt->zaptxchannel && ast_check_hangup(myrpt->zaptxchannel)) break; 09215 09216 /* Set local tx with keyed */ 09217 myrpt->localtx = myrpt->keyed; 09218 /* If someone's connected, and they're transmitting from their end to us, set remrx true */ 09219 l = myrpt->links.next; 09220 remrx = 0; 09221 while(l != &myrpt->links) 09222 { 09223 if (l->lastrx){ 09224 remrx = 1; 09225 if(l->name[0] != '0') /* Ignore '0' nodes */ 09226 strcpy(myrpt->lastnodewhichkeyedusup, l->name); /* Note the node which is doing the key up */ 09227 } 09228 l = l->next; 09229 } 09230 /* Create a "must_id" flag for the cleanup ID */ 09231 if(myrpt->p.idtime) /* ID time must be non-zero */ 09232 myrpt->mustid |= (myrpt->idtimer) && (myrpt->keyed || remrx) ; 09233 /* Build a fresh totx from myrpt->keyed and autopatch activated */ 09234 totx = myrpt->callmode; 09235 /* If full duplex, add local tx to totx */ 09236 if (myrpt->p.duplex > 1) 09237 { 09238 totx = totx || myrpt->localtx; 09239 } 09240 /* Traverse the telemetry list to see what's queued */ 09241 identqueued = 0; 09242 othertelemqueued = 0; 09243 tailmessagequeued = 0; 09244 ctqueued = 0; 09245 telem = myrpt->tele.next; 09246 while(telem != &myrpt->tele) 09247 { 09248 if((telem->mode == ID) || (telem->mode == IDTALKOVER)){ 09249 identqueued = 1; /* Identification telemetry */ 09250 } 09251 else if(telem->mode == TAILMSG) 09252 { 09253 tailmessagequeued = 1; /* Tail message telemetry */ 09254 } 09255 else 09256 { 09257 if ((telem->mode != UNKEY) && (telem->mode != LINKUNKEY)) 09258 othertelemqueued = 1; /* Other telemetry */ 09259 else 09260 ctqueued = 1; /* Courtesy tone telemetry */ 09261 } 09262 telem = telem->next; 09263 } 09264 09265 /* Add in any "other" telemetry, unless specified otherwise */ 09266 if (!myrpt->p.notelemtx) totx = totx || othertelemqueued; 09267 /* Update external (to links) transmitter PTT state with everything but ID, CT, and tailmessage telemetry */ 09268 myrpt->exttx = totx; 09269 totx = totx || myrpt->dtmf_local_timer; 09270 /* If half or 3/4 duplex, add localtx to external link tx */ 09271 if (myrpt->p.duplex < 2) myrpt->exttx = myrpt->exttx || myrpt->localtx; 09272 /* Add in ID telemetry to local transmitter */ 09273 totx = totx || remrx; 09274 /* If 3/4 or full duplex, add in ident and CT telemetry */ 09275 if (myrpt->p.duplex > 0) 09276 totx = totx || identqueued || ctqueued; 09277 /* If full duplex, add local dtmf stuff active */ 09278 if (myrpt->p.duplex > 1) 09279 { 09280 totx = totx || (myrpt->dtmfidx > -1) || 09281 myrpt->cmdnode[0]; 09282 } 09283 /* Reset time out timer variables if there is no activity */ 09284 if (!totx) 09285 { 09286 myrpt->totimer = myrpt->p.totime; 09287 myrpt->tounkeyed = 0; 09288 myrpt->tonotify = 0; 09289 } 09290 else{ 09291 myrpt->tailtimer = myrpt->p.s[myrpt->p.sysstate_cur].alternatetail ? 09292 myrpt->p.althangtime : /* Initialize tail timer */ 09293 myrpt->p.hangtime; 09294 } 09295 /* Disable the local transmitter if we are timed out */ 09296 totx = totx && myrpt->totimer; 09297 /* if timed-out and not said already, say it */ 09298 if ((!myrpt->totimer) && (!myrpt->tonotify)) 09299 { 09300 myrpt->tonotify = 1; 09301 myrpt->timeouts++; 09302 rpt_mutex_unlock(&myrpt->lock); 09303 rpt_telemetry(myrpt,TIMEOUT,NULL); 09304 rpt_mutex_lock(&myrpt->lock); 09305 } 09306 09307 /* If unkey and re-key, reset time out timer */ 09308 if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!myrpt->keyed)) 09309 { 09310 myrpt->tounkeyed = 1; 09311 } 09312 if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->keyed) 09313 { 09314 myrpt->totimer = myrpt->p.totime; 09315 myrpt->tounkeyed = 0; 09316 myrpt->tonotify = 0; 09317 rpt_mutex_unlock(&myrpt->lock); 09318 continue; 09319 } 09320 /* if timed-out and in circuit busy after call */ 09321 if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4)) 09322 { 09323 myrpt->callmode = 0; 09324 } 09325 /* get rid of tail if timed out */ 09326 if (!myrpt->totimer) myrpt->tailtimer = 0; 09327 /* if not timed-out, add in tail */ 09328 if (myrpt->totimer) totx = totx || myrpt->tailtimer; 09329 /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */ 09330 /* If tail message, kill the message if someone keys up over it */ 09331 if ((myrpt->keyed || remrx) && ((identqueued && idtalkover) || (tailmessagequeued))) { 09332 int hasid = 0,hastalkover = 0; 09333 09334 telem = myrpt->tele.next; 09335 while(telem != &myrpt->tele){ 09336 if(telem->mode == ID){ 09337 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 09338 hasid = 1; 09339 } 09340 if(telem->mode == TAILMSG){ 09341 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 09342 } 09343 if (telem->mode == IDTALKOVER) hastalkover = 1; 09344 telem = telem->next; 09345 } 09346 rpt_mutex_unlock(&myrpt->lock); 09347 if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */ 09348 rpt_mutex_lock(&myrpt->lock); 09349 } 09350 /* Try to be polite */ 09351 /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/ 09352 /* If within 30 seconds of the time to ID, try do it in the tail */ 09353 /* else if at ID time limit, do it right over the top of them */ 09354 /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */ 09355 if(myrpt->mustid && (!myrpt->idtimer)) 09356 queue_id(myrpt); 09357 09358 if ((myrpt->p.idtime && totx && (!myrpt->exttx) && 09359 (myrpt->idtimer <= myrpt->p.politeid) && myrpt->tailtimer)) /* ID time must be non-zero */ 09360 { 09361 myrpt->tailid = 1; 09362 } 09363 09364 /* If tail timer expires, then check for tail messages */ 09365 09366 if(myrpt->tailevent){ 09367 myrpt->tailevent = 0; 09368 if(myrpt->tailid){ 09369 totx = 1; 09370 queue_id(myrpt); 09371 } 09372 else if ((myrpt->p.tailmessages[0]) && 09373 (myrpt->p.tailmessagetime) && (myrpt->tmsgtimer == 0)){ 09374 totx = 1; 09375 myrpt->tmsgtimer = myrpt->p.tailmessagetime; 09376 rpt_mutex_unlock(&myrpt->lock); 09377 rpt_telemetry(myrpt, TAILMSG, NULL); 09378 rpt_mutex_lock(&myrpt->lock); 09379 } 09380 } 09381 09382 /* Main TX control */ 09383 09384 /* let telemetry transmit anyway (regardless of timeout) */ 09385 if (myrpt->p.duplex > 0) totx = totx || (myrpt->tele.next != &myrpt->tele); 09386 if (totx && (!lasttx)) 09387 { 09388 char mydate[100],myfname[100]; 09389 time_t myt; 09390 09391 if (myrpt->monstream) ast_closestream(myrpt->monstream); 09392 if (myrpt->p.archivedir) 09393 { 09394 long blocksleft; 09395 09396 time(&myt); 09397 strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S", 09398 localtime(&myt)); 09399 sprintf(myfname,"%s/%s/%s",myrpt->p.archivedir, 09400 myrpt->name,mydate); 09401 myrpt->monstream = ast_writefile(myfname,"wav49", 09402 "app_rpt Air Archive",O_CREAT | O_APPEND,0,0600); 09403 if (myrpt->p.monminblocks) 09404 { 09405 blocksleft = diskavail(myrpt); 09406 if (blocksleft >= myrpt->p.monminblocks) 09407 donodelog(myrpt,"TXKEY,MAIN"); 09408 } else donodelog(myrpt,"TXKEY,MAIN"); 09409 } 09410 lasttx = 1; 09411 myrpt->dailykeyups++; 09412 myrpt->totalkeyups++; 09413 rpt_mutex_unlock(&myrpt->lock); 09414 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 09415 rpt_mutex_lock(&myrpt->lock); 09416 } 09417 totx = totx && !myrpt->p.s[myrpt->p.sysstate_cur].txdisable; 09418 if ((!totx) && lasttx) 09419 { 09420 if (myrpt->monstream) ast_closestream(myrpt->monstream); 09421 myrpt->monstream = NULL; 09422 09423 lasttx = 0; 09424 rpt_mutex_unlock(&myrpt->lock); 09425 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 09426 rpt_mutex_lock(&myrpt->lock); 09427 donodelog(myrpt,"TXUNKEY,MAIN"); 09428 } 09429 time(&t); 09430 /* if DTMF timeout */ 09431 if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((myrpt->dtmf_time + DTMF_TIMEOUT) < t)) 09432 { 09433 myrpt->dtmfidx = -1; 09434 myrpt->dtmfbuf[0] = 0; 09435 } 09436 /* if remote DTMF timeout */ 09437 if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t)) 09438 { 09439 myrpt->rem_dtmfidx = -1; 09440 myrpt->rem_dtmfbuf[0] = 0; 09441 } 09442 09443 /* Reconnect */ 09444 09445 l = myrpt->links.next; 09446 while(l != &myrpt->links) 09447 { 09448 if (l->killme) 09449 { 09450 /* remove from queue */ 09451 remque((struct qelem *) l); 09452 if (!strcmp(myrpt->cmdnode,l->name)) 09453 myrpt->cmdnode[0] = 0; 09454 rpt_mutex_unlock(&myrpt->lock); 09455 /* hang-up on call to device */ 09456 if (l->chan) ast_hangup(l->chan); 09457 ast_hangup(l->pchan); 09458 free(l); 09459 rpt_mutex_lock(&myrpt->lock); 09460 /* re-start link traversal */ 09461 l = myrpt->links.next; 09462 continue; 09463 } 09464 l = l->next; 09465 } 09466 n = 0; 09467 cs[n++] = myrpt->rxchannel; 09468 cs[n++] = myrpt->pchannel; 09469 cs[n++] = myrpt->monchannel; 09470 cs[n++] = myrpt->txpchannel; 09471 if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel; 09472 if (myrpt->zaptxchannel != myrpt->txchannel) 09473 cs[n++] = myrpt->zaptxchannel; 09474 l = myrpt->links.next; 09475 while(l != &myrpt->links) 09476 { 09477 if ((!l->killme) && (!l->disctime) && l->chan) 09478 { 09479 cs[n++] = l->chan; 09480 cs[n++] = l->pchan; 09481 } 09482 l = l->next; 09483 } 09484 rpt_mutex_unlock(&myrpt->lock); 09485 ms = MSWAIT; 09486 for(x = 0; x < n; x++) 09487 { 09488 int s = -(-x - myrpt->scram - 1) % n; 09489 cs1[x] = cs[s]; 09490 } 09491 myrpt->scram++; 09492 who = ast_waitfor_n(cs1,n,&ms); 09493 if (who == NULL) ms = 0; 09494 elap = MSWAIT - ms; 09495 rpt_mutex_lock(&myrpt->lock); 09496 l = myrpt->links.next; 09497 while(l != &myrpt->links) 09498 { 09499 if (l->linklisttimer) 09500 { 09501 l->linklisttimer -= elap; 09502 if (l->linklisttimer < 0) l->linklisttimer = 0; 09503 } 09504 if ((!l->linklisttimer) && (l->name[0] != '0') && (!l->isremote)) 09505 { 09506 struct ast_frame lf; 09507 09508 memset(&lf,0,sizeof(lf)); 09509 lf.frametype = AST_FRAME_TEXT; 09510 lf.subclass = 0; 09511 lf.offset = 0; 09512 lf.mallocd = 0; 09513 lf.samples = 0; 09514 l->linklisttimer = LINKLISTTIME; 09515 strcpy(lstr,"L "); 09516 __mklinklist(myrpt,l,lstr + 2); 09517 if (l->chan) 09518 { 09519 lf.datalen = strlen(lstr) + 1; 09520 lf.data = lstr; 09521 ast_write(l->chan,&lf); 09522 if (debug > 6) ast_log(LOG_NOTICE, 09523 "@@@@ node %s sent node string %s to node %s\n", 09524 myrpt->name,lstr,l->name); 09525 } 09526 } 09527 #ifndef OLDKEY 09528 if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME) 09529 { 09530 l->retxtimer = 0; 09531 if (l->chan && l->phonemode == 0) 09532 { 09533 if (l->lasttx) 09534 ast_indicate(l->chan,AST_CONTROL_RADIO_KEY); 09535 else 09536 ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 09537 } 09538 } 09539 if ((l->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 5)) 09540 { 09541 if (debug == 7) printf("@@@@ rx un-key\n"); 09542 l->lastrx = 0; 09543 l->rerxtimer = 0; 09544 if(myrpt->p.duplex) 09545 rpt_telemetry(myrpt,LINKUNKEY,l); 09546 if (myrpt->p.archivedir) 09547 { 09548 char str[100]; 09549 09550 l->lastrx1 = 0; 09551 sprintf(str,"RXUNKEY(T),%s",l->name); 09552 donodelog(myrpt,str); 09553 } 09554 } 09555 #endif 09556 if (l->disctime) /* Disconnect timer active on a channel ? */ 09557 { 09558 l->disctime -= elap; 09559 if (l->disctime <= 0) /* Disconnect timer expired on inbound channel ? */ 09560 l->disctime = 0; /* Yep */ 09561 } 09562 09563 if (l->retrytimer) 09564 { 09565 l->retrytimer -= elap; 09566 if (l->retrytimer < 0) l->retrytimer = 0; 09567 } 09568 09569 /* Tally connect time */ 09570 l->connecttime += elap; 09571 09572 /* ignore non-timing channels */ 09573 if (l->elaptime < 0) 09574 { 09575 l = l->next; 09576 continue; 09577 } 09578 l->elaptime += elap; 09579 /* if connection has taken too long */ 09580 if ((l->elaptime > MAXCONNECTTIME) && 09581 ((!l->chan) || (l->chan->_state != AST_STATE_UP))) 09582 { 09583 l->elaptime = 0; 09584 rpt_mutex_unlock(&myrpt->lock); 09585 if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 09586 rpt_mutex_lock(&myrpt->lock); 09587 break; 09588 } 09589 if ((!l->chan) && (!l->retrytimer) && l->outbound && 09590 (l->retries++ < l->max_retries) && (l->hasconnected)) 09591 { 09592 if (l->chan) ast_hangup(l->chan); 09593 l->chan = 0; 09594 rpt_mutex_unlock(&myrpt->lock); 09595 if ((l->name[0] != '0') && (!l->isremote)) 09596 { 09597 if (attempt_reconnect(myrpt,l) == -1) 09598 { 09599 l->retrytimer = RETRY_TIMER_MS; 09600 } 09601 } 09602 else 09603 { 09604 l->retrytimer = l->max_retries + 1; 09605 } 09606 09607 rpt_mutex_lock(&myrpt->lock); 09608 break; 09609 } 09610 if ((!l->chan) && (!l->retrytimer) && l->outbound && 09611 (l->retries >= l->max_retries)) 09612 { 09613 /* remove from queue */ 09614 remque((struct qelem *) l); 09615 if (!strcmp(myrpt->cmdnode,l->name)) 09616 myrpt->cmdnode[0] = 0; 09617 rpt_mutex_unlock(&myrpt->lock); 09618 if (l->name[0] != '0') 09619 { 09620 if (!l->hasconnected) 09621 rpt_telemetry(myrpt,CONNFAIL,l); 09622 else rpt_telemetry(myrpt,REMDISC,l); 09623 } 09624 if (myrpt->p.archivedir) 09625 { 09626 char str[100]; 09627 09628 if (!l->hasconnected) 09629 sprintf(str,"LINKFAIL,%s",l->name); 09630 else 09631 sprintf(str,"LINKDISC,%s",l->name); 09632 donodelog(myrpt,str); 09633 } 09634 /* hang-up on call to device */ 09635 ast_hangup(l->pchan); 09636 free(l); 09637 rpt_mutex_lock(&myrpt->lock); 09638 break; 09639 } 09640 if ((!l->chan) && (!l->disctime) && (!l->outbound)) 09641 { 09642 /* remove from queue */ 09643 remque((struct qelem *) l); 09644 if (!strcmp(myrpt->cmdnode,l->name)) 09645 myrpt->cmdnode[0] = 0; 09646 rpt_mutex_unlock(&myrpt->lock); 09647 if (l->name[0] != '0') 09648 { 09649 rpt_telemetry(myrpt,REMDISC,l); 09650 } 09651 if (myrpt->p.archivedir) 09652 { 09653 char str[100]; 09654 09655 sprintf(str,"LINKDISC,%s",l->name); 09656 donodelog(myrpt,str); 09657 } 09658 /* hang-up on call to device */ 09659 ast_hangup(l->pchan); 09660 free(l); 09661 rpt_mutex_lock(&myrpt->lock); 09662 break; 09663 } 09664 l = l->next; 09665 } 09666 if(totx){ 09667 myrpt->dailytxtime += elap; 09668 myrpt->totaltxtime += elap; 09669 } 09670 i = myrpt->tailtimer; 09671 if (myrpt->tailtimer) myrpt->tailtimer -= elap; 09672 if (myrpt->tailtimer < 0) myrpt->tailtimer = 0; 09673 if((i) && (myrpt->tailtimer == 0)) 09674 myrpt->tailevent = 1; 09675 if ((!myrpt->p.s[myrpt->p.sysstate_cur].totdisable) && myrpt->totimer) myrpt->totimer -= elap; 09676 if (myrpt->totimer < 0) myrpt->totimer = 0; 09677 if (myrpt->idtimer) myrpt->idtimer -= elap; 09678 if (myrpt->idtimer < 0) myrpt->idtimer = 0; 09679 if (myrpt->tmsgtimer) myrpt->tmsgtimer -= elap; 09680 if (myrpt->tmsgtimer < 0) myrpt->tmsgtimer = 0; 09681 /* do macro timers */ 09682 if (myrpt->macrotimer) myrpt->macrotimer -= elap; 09683 if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; 09684 /* do local dtmf timer */ 09685 if (myrpt->dtmf_local_timer) 09686 { 09687 if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap; 09688 if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1; 09689 } 09690 do_dtmf_local(myrpt,0); 09691 /* Execute scheduler appx. every 2 tenths of a second */ 09692 if (myrpt->skedtimer <= 0){ 09693 myrpt->skedtimer = 200; 09694 do_scheduler(myrpt); 09695 } 09696 else 09697 myrpt->skedtimer -=elap; 09698 if (!ms) 09699 { 09700 rpt_mutex_unlock(&myrpt->lock); 09701 continue; 09702 } 09703 c = myrpt->macrobuf[0]; 09704 time(&t); 09705 if (c && (!myrpt->macrotimer) && 09706 starttime && (t > (starttime + START_DELAY))) 09707 { 09708 myrpt->macrotimer = MACROTIME; 09709 memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1); 09710 if ((c == 'p') || (c == 'P')) 09711 myrpt->macrotimer = MACROPTIME; 09712 rpt_mutex_unlock(&myrpt->lock); 09713 if (myrpt->p.archivedir) 09714 { 09715 char str[100]; 09716 09717 sprintf(str,"DTMF(M),MAIN,%c",c); 09718 donodelog(myrpt,str); 09719 } 09720 local_dtmf_helper(myrpt,c); 09721 } else rpt_mutex_unlock(&myrpt->lock); 09722 if (who == myrpt->rxchannel) /* if it was a read from rx */ 09723 { 09724 int ismuted; 09725 09726 f = ast_read(myrpt->rxchannel); 09727 if (!f) 09728 { 09729 if (debug) printf("@@@@ rpt:Hung Up\n"); 09730 break; 09731 } 09732 if (f->frametype == AST_FRAME_VOICE) 09733 { 09734 #ifdef _MDC_DECODE_H_ 09735 unsigned char ubuf[2560]; 09736 short *sp; 09737 int n; 09738 #endif 09739 09740 if ((!myrpt->localtx) && (!myrpt->p.linktolink)) { 09741 memset(f->data,0,f->datalen); 09742 } 09743 09744 #ifdef _MDC_DECODE_H_ 09745 sp = (short *) f->data; 09746 /* convert block to unsigned char */ 09747 for(n = 0; n < f->datalen / 2; n++) 09748 { 09749 ubuf[n] = (*sp++ >> 8) + 128; 09750 } 09751 n = mdc_decoder_process_samples(myrpt->mdc,ubuf,f->datalen / 2); 09752 if (n == 1) 09753 { 09754 unsigned char op,arg; 09755 unsigned short unitID; 09756 09757 mdc_decoder_get_packet(myrpt->mdc,&op,&arg,&unitID); 09758 if (debug > 2) 09759 { 09760 ast_log(LOG_NOTICE,"Got (single-length) packet:\n"); 09761 ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n", 09762 op & 255,arg & 255,unitID); 09763 } 09764 if ((op == 1) && (arg == 0)) 09765 { 09766 myrpt->lastunit = unitID; 09767 mdc1200_notify(myrpt,NULL,myrpt->lastunit); 09768 mdc1200_send(myrpt,myrpt->lastunit); 09769 } 09770 } 09771 if ((debug > 2) && (i == 2)) 09772 { 09773 unsigned char op,arg,ex1,ex2,ex3,ex4; 09774 unsigned short unitID; 09775 09776 mdc_decoder_get_double_packet(myrpt->mdc,&op,&arg,&unitID, 09777 &ex1,&ex2,&ex3,&ex4); 09778 ast_log(LOG_NOTICE,"Got (double-length) packet:\n"); 09779 ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n", 09780 op & 255,arg & 255,unitID); 09781 ast_log(LOG_NOTICE,"ex1: %02x, ex2: %02x, ex3: %02x, ex4: %02x\n", 09782 ex1 & 255, ex2 & 255, ex3 & 255, ex4 & 255); 09783 } 09784 #endif 09785 #ifdef __RPT_NOTCH 09786 /* apply inbound filters, if any */ 09787 rpt_filter(myrpt,f->data,f->datalen / 2); 09788 #endif 09789 if (ioctl(myrpt->zaprxchannel->fds[0], ZT_GETCONFMUTE, &ismuted) == -1) 09790 { 09791 ismuted = 0; 09792 } 09793 if (dtmfed) ismuted = 1; 09794 dtmfed = 0; 09795 if (ismuted) 09796 { 09797 memset(f->data,0,f->datalen); 09798 if (myrpt->lastf1) 09799 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09800 if (myrpt->lastf2) 09801 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09802 } 09803 if (f) f2 = ast_frdup(f); 09804 else f2 = NULL; 09805 f1 = myrpt->lastf2; 09806 myrpt->lastf2 = myrpt->lastf1; 09807 myrpt->lastf1 = f2; 09808 if (ismuted) 09809 { 09810 if (myrpt->lastf1) 09811 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09812 if (myrpt->lastf2) 09813 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09814 } 09815 if (f1) 09816 { 09817 ast_write(myrpt->pchannel,f1); 09818 ast_frfree(f1); 09819 } 09820 } 09821 #ifndef OLD_ASTERISK 09822 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 09823 { 09824 if (myrpt->lastf1) 09825 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09826 if (myrpt->lastf2) 09827 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09828 dtmfed = 1; 09829 } 09830 #endif 09831 else if (f->frametype == AST_FRAME_DTMF) 09832 { 09833 c = (char) f->subclass; /* get DTMF char */ 09834 ast_frfree(f); 09835 if (myrpt->lastf1) 09836 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09837 if (myrpt->lastf2) 09838 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09839 dtmfed = 1; 09840 if (!myrpt->keyed) continue; 09841 c = func_xlat(myrpt,c,&myrpt->p.inxlat); 09842 if (c) local_dtmf_helper(myrpt,c); 09843 continue; 09844 } 09845 else if (f->frametype == AST_FRAME_CONTROL) 09846 { 09847 if (f->subclass == AST_CONTROL_HANGUP) 09848 { 09849 if (debug) printf("@@@@ rpt:Hung Up\n"); 09850 ast_frfree(f); 09851 break; 09852 } 09853 /* if RX key */ 09854 if (f->subclass == AST_CONTROL_RADIO_KEY) 09855 { 09856 if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink)) 09857 { 09858 if (debug == 7) printf("@@@@ rx key\n"); 09859 myrpt->keyed = 1; 09860 } 09861 if (myrpt->p.archivedir) 09862 { 09863 donodelog(myrpt,"RXKEY,MAIN"); 09864 } 09865 } 09866 /* if RX un-key */ 09867 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 09868 { 09869 if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink)) 09870 { 09871 if (debug == 7) printf("@@@@ rx un-key\n"); 09872 if(myrpt->p.duplex && myrpt->keyed) { 09873 rpt_telemetry(myrpt,UNKEY,NULL); 09874 } 09875 } 09876 myrpt->keyed = 0; 09877 if (myrpt->p.archivedir) 09878 { 09879 donodelog(myrpt,"RXUNKEY,MAIN"); 09880 } 09881 } 09882 } 09883 ast_frfree(f); 09884 continue; 09885 } 09886 if (who == myrpt->pchannel) /* if it was a read from pseudo */ 09887 { 09888 f = ast_read(myrpt->pchannel); 09889 if (!f) 09890 { 09891 if (debug) printf("@@@@ rpt:Hung Up\n"); 09892 break; 09893 } 09894 if (f->frametype == AST_FRAME_VOICE) 09895 { 09896 ast_write(myrpt->txpchannel,f); 09897 } 09898 if (f->frametype == AST_FRAME_CONTROL) 09899 { 09900 if (f->subclass == AST_CONTROL_HANGUP) 09901 { 09902 if (debug) printf("@@@@ rpt:Hung Up\n"); 09903 ast_frfree(f); 09904 break; 09905 } 09906 } 09907 ast_frfree(f); 09908 continue; 09909 } 09910 if (who == myrpt->txchannel) /* if it was a read from tx */ 09911 { 09912 f = ast_read(myrpt->txchannel); 09913 if (!f) 09914 { 09915 if (debug) printf("@@@@ rpt:Hung Up\n"); 09916 break; 09917 } 09918 if (f->frametype == AST_FRAME_CONTROL) 09919 { 09920 if (f->subclass == AST_CONTROL_HANGUP) 09921 { 09922 if (debug) printf("@@@@ rpt:Hung Up\n"); 09923 ast_frfree(f); 09924 break; 09925 } 09926 } 09927 ast_frfree(f); 09928 continue; 09929 } 09930 if (who == myrpt->zaptxchannel) /* if it was a read from pseudo-tx */ 09931 { 09932 f = ast_read(myrpt->zaptxchannel); 09933 if (!f) 09934 { 09935 if (debug) printf("@@@@ rpt:Hung Up\n"); 09936 break; 09937 } 09938 if (f->frametype == AST_FRAME_VOICE) 09939 { 09940 ast_write(myrpt->txchannel,f); 09941 } 09942 if (f->frametype == AST_FRAME_CONTROL) 09943 { 09944 if (f->subclass == AST_CONTROL_HANGUP) 09945 { 09946 if (debug) printf("@@@@ rpt:Hung Up\n"); 09947 ast_frfree(f); 09948 break; 09949 } 09950 } 09951 ast_frfree(f); 09952 continue; 09953 } 09954 toexit = 0; 09955 rpt_mutex_lock(&myrpt->lock); 09956 l = myrpt->links.next; 09957 while(l != &myrpt->links) 09958 { 09959 if (l->disctime) 09960 { 09961 l = l->next; 09962 continue; 09963 } 09964 if (who == l->chan) /* if it was a read from rx */ 09965 { 09966 int remnomute; 09967 09968 remrx = 0; 09969 /* see if any other links are receiving */ 09970 m = myrpt->links.next; 09971 while(m != &myrpt->links) 09972 { 09973 /* if not us, count it */ 09974 if ((m != l) && (m->lastrx)) remrx = 1; 09975 m = m->next; 09976 } 09977 rpt_mutex_unlock(&myrpt->lock); 09978 remnomute = myrpt->localtx && 09979 (!(myrpt->cmdnode[0] || 09980 (myrpt->dtmfidx > -1))); 09981 totx = (((l->isremote) ? (remnomute) : 09982 myrpt->exttx) || remrx) && l->mode; 09983 if (l->phonemode == 0 && l->chan && (l->lasttx != totx)) 09984 { 09985 if (totx) 09986 { 09987 ast_indicate(l->chan,AST_CONTROL_RADIO_KEY); 09988 } 09989 else 09990 { 09991 ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 09992 } 09993 if (myrpt->p.archivedir) 09994 { 09995 char str[100]; 09996 09997 if (totx) 09998 sprintf(str,"TXKEY,%s",l->name); 09999 else 10000 sprintf(str,"TXUNKEY,%s",l->name); 10001 donodelog(myrpt,str); 10002 } 10003 } 10004 l->lasttx = totx; 10005 f = ast_read(l->chan); 10006 if (!f) 10007 { 10008 rpt_mutex_lock(&myrpt->lock); 10009 __kickshort(myrpt); 10010 rpt_mutex_unlock(&myrpt->lock); 10011 if ((!l->disced) && (!l->outbound)) 10012 { 10013 if ((l->name[0] == '0') || l->isremote) 10014 l->disctime = 1; 10015 else 10016 l->disctime = DISC_TIME; 10017 rpt_mutex_lock(&myrpt->lock); 10018 ast_hangup(l->chan); 10019 l->chan = 0; 10020 break; 10021 } 10022 10023 if (l->retrytimer) 10024 { 10025 ast_hangup(l->chan); 10026 l->chan = 0; 10027 rpt_mutex_lock(&myrpt->lock); 10028 break; 10029 } 10030 if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected)) 10031 { 10032 rpt_mutex_lock(&myrpt->lock); 10033 if (l->chan) ast_hangup(l->chan); 10034 l->chan = 0; 10035 l->hasconnected = 1; 10036 l->retrytimer = RETRY_TIMER_MS; 10037 l->elaptime = 0; 10038 l->connecttime = 0; 10039 l->thisconnected = 0; 10040 break; 10041 } 10042 rpt_mutex_lock(&myrpt->lock); 10043 /* remove from queue */ 10044 remque((struct qelem *) l); 10045 if (!strcmp(myrpt->cmdnode,l->name)) 10046 myrpt->cmdnode[0] = 0; 10047 __kickshort(myrpt); 10048 rpt_mutex_unlock(&myrpt->lock); 10049 if (!l->hasconnected) 10050 rpt_telemetry(myrpt,CONNFAIL,l); 10051 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 10052 if (myrpt->p.archivedir) 10053 { 10054 char str[100]; 10055 10056 if (!l->hasconnected) 10057 sprintf(str,"LINKFAIL,%s",l->name); 10058 else 10059 sprintf(str,"LINKDISC,%s",l->name); 10060 donodelog(myrpt,str); 10061 } 10062 if (l->lastf1) ast_frfree(l->lastf1); 10063 l->lastf1 = NULL; 10064 if (l->lastf2) ast_frfree(l->lastf2); 10065 l->lastf2 = NULL; 10066 /* hang-up on call to device */ 10067 ast_hangup(l->chan); 10068 ast_hangup(l->pchan); 10069 free(l); 10070 rpt_mutex_lock(&myrpt->lock); 10071 break; 10072 } 10073 if (f->frametype == AST_FRAME_VOICE) 10074 { 10075 int ismuted; 10076 10077 if (l->phonemode) 10078 { 10079 if (ioctl(l->chan->fds[0], ZT_GETCONFMUTE, &ismuted) == -1) 10080 { 10081 ismuted = 0; 10082 } 10083 /* if not receiving, zero-out audio */ 10084 ismuted |= (!l->lastrx); 10085 if (l->dtmfed && l->phonemode) ismuted = 1; 10086 l->dtmfed = 0; 10087 if (ismuted) 10088 { 10089 memset(f->data,0,f->datalen); 10090 if (l->lastf1) 10091 memset(l->lastf1->data,0,l->lastf1->datalen); 10092 if (l->lastf2) 10093 memset(l->lastf2->data,0,l->lastf2->datalen); 10094 } 10095 if (f) f2 = ast_frdup(f); 10096 else f2 = NULL; 10097 f1 = l->lastf2; 10098 l->lastf2 = l->lastf1; 10099 l->lastf1 = f2; 10100 if (ismuted) 10101 { 10102 if (l->lastf1) 10103 memset(l->lastf1->data,0,l->lastf1->datalen); 10104 if (l->lastf2) 10105 memset(l->lastf2->data,0,l->lastf2->datalen); 10106 } 10107 if (f1) 10108 { 10109 ast_write(l->pchan,f1); 10110 ast_frfree(f1); 10111 } 10112 } 10113 else 10114 { 10115 if (!l->lastrx) 10116 memset(f->data,0,f->datalen); 10117 ast_write(l->pchan,f); 10118 } 10119 } 10120 #ifndef OLD_ASTERISK 10121 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 10122 { 10123 if (l->lastf1) 10124 memset(l->lastf1->data,0,l->lastf1->datalen); 10125 if (l->lastf2) 10126 memset(l->lastf2->data,0,l->lastf2->datalen); 10127 l->dtmfed = 1; 10128 } 10129 #endif 10130 10131 if (f->frametype == AST_FRAME_TEXT) 10132 { 10133 handle_link_data(myrpt,l,f->data); 10134 } 10135 if (f->frametype == AST_FRAME_DTMF) 10136 { 10137 if (l->lastf1) 10138 memset(l->lastf1->data,0,l->lastf1->datalen); 10139 if (l->lastf2) 10140 memset(l->lastf2->data,0,l->lastf2->datalen); 10141 l->dtmfed = 1; 10142 handle_link_phone_dtmf(myrpt,l,f->subclass); 10143 } 10144 if (f->frametype == AST_FRAME_CONTROL) 10145 { 10146 if (f->subclass == AST_CONTROL_ANSWER) 10147 { 10148 char lconnected = l->connected; 10149 10150 __kickshort(myrpt); 10151 l->connected = 1; 10152 l->hasconnected = 1; 10153 l->thisconnected = 1; 10154 l->elaptime = -1; 10155 if (!l->isremote) l->retries = 0; 10156 if (!lconnected) 10157 { 10158 rpt_telemetry(myrpt,CONNECTED,l); 10159 if (myrpt->p.archivedir) 10160 { 10161 char str[100]; 10162 10163 if (l->mode) 10164 sprintf(str,"LINKTRX,%s",l->name); 10165 else 10166 sprintf(str,"LINKMONITOR,%s",l->name); 10167 donodelog(myrpt,str); 10168 } 10169 } 10170 else 10171 l->reconnects++; 10172 } 10173 /* if RX key */ 10174 if (f->subclass == AST_CONTROL_RADIO_KEY) 10175 { 10176 if (debug == 7 ) printf("@@@@ rx key\n"); 10177 l->lastrx = 1; 10178 l->rerxtimer = 0; 10179 if (myrpt->p.archivedir && (!l->lastrx1)) 10180 { 10181 char str[100]; 10182 10183 l->lastrx1 = 1; 10184 sprintf(str,"RXKEY,%s",l->name); 10185 donodelog(myrpt,str); 10186 } 10187 } 10188 /* if RX un-key */ 10189 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 10190 { 10191 if (debug == 7) printf("@@@@ rx un-key\n"); 10192 l->lastrx = 0; 10193 l->rerxtimer = 0; 10194 if(myrpt->p.duplex) 10195 rpt_telemetry(myrpt,LINKUNKEY,l); 10196 if (myrpt->p.archivedir && (l->lastrx1)) 10197 { 10198 char str[100]; 10199 10200 l->lastrx1 = 0; 10201 sprintf(str,"RXUNKEY,%s",l->name); 10202 donodelog(myrpt,str); 10203 } 10204 } 10205 if (f->subclass == AST_CONTROL_HANGUP) 10206 { 10207 ast_frfree(f); 10208 rpt_mutex_lock(&myrpt->lock); 10209 __kickshort(myrpt); 10210 rpt_mutex_unlock(&myrpt->lock); 10211 if ((!l->outbound) && (!l->disced)) 10212 { 10213 if ((l->name[0] == '0') || l->isremote) 10214 l->disctime = 1; 10215 else 10216 l->disctime = DISC_TIME; 10217 rpt_mutex_lock(&myrpt->lock); 10218 ast_hangup(l->chan); 10219 l->chan = 0; 10220 break; 10221 } 10222 if (l->retrytimer) 10223 { 10224 if (l->chan) ast_hangup(l->chan); 10225 l->chan = 0; 10226 rpt_mutex_lock(&myrpt->lock); 10227 break; 10228 } 10229 if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected)) 10230 { 10231 rpt_mutex_lock(&myrpt->lock); 10232 if (l->chan) ast_hangup(l->chan); 10233 l->chan = 0; 10234 l->hasconnected = 1; 10235 l->elaptime = 0; 10236 l->retrytimer = RETRY_TIMER_MS; 10237 l->connecttime = 0; 10238 l->thisconnected = 0; 10239 break; 10240 } 10241 rpt_mutex_lock(&myrpt->lock); 10242 /* remove from queue */ 10243 remque((struct qelem *) l); 10244 if (!strcmp(myrpt->cmdnode,l->name)) 10245 myrpt->cmdnode[0] = 0; 10246 __kickshort(myrpt); 10247 rpt_mutex_unlock(&myrpt->lock); 10248 if (!l->hasconnected) 10249 rpt_telemetry(myrpt,CONNFAIL,l); 10250 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 10251 if (myrpt->p.archivedir) 10252 { 10253 char str[100]; 10254 10255 if (!l->hasconnected) 10256 sprintf(str,"LINKFAIL,%s",l->name); 10257 else 10258 sprintf(str,"LINKDISC,%s",l->name); 10259 donodelog(myrpt,str); 10260 } 10261 if (l->lastf1) ast_frfree(l->lastf1); 10262 l->lastf1 = NULL; 10263 if (l->lastf2) ast_frfree(l->lastf2); 10264 l->lastf2 = NULL; 10265 /* hang-up on call to device */ 10266 ast_hangup(l->chan); 10267 ast_hangup(l->pchan); 10268 free(l); 10269 rpt_mutex_lock(&myrpt->lock); 10270 break; 10271 } 10272 } 10273 ast_frfree(f); 10274 rpt_mutex_lock(&myrpt->lock); 10275 break; 10276 } 10277 if (who == l->pchan) 10278 { 10279 rpt_mutex_unlock(&myrpt->lock); 10280 f = ast_read(l->pchan); 10281 if (!f) 10282 { 10283 if (debug) printf("@@@@ rpt:Hung Up\n"); 10284 toexit = 1; 10285 rpt_mutex_lock(&myrpt->lock); 10286 break; 10287 } 10288 if (f->frametype == AST_FRAME_VOICE) 10289 { 10290 if (l->chan) ast_write(l->chan,f); 10291 } 10292 if (f->frametype == AST_FRAME_CONTROL) 10293 { 10294 if (f->subclass == AST_CONTROL_HANGUP) 10295 { 10296 if (debug) printf("@@@@ rpt:Hung Up\n"); 10297 ast_frfree(f); 10298 toexit = 1; 10299 rpt_mutex_lock(&myrpt->lock); 10300 break; 10301 } 10302 } 10303 ast_frfree(f); 10304 rpt_mutex_lock(&myrpt->lock); 10305 break; 10306 } 10307 l = l->next; 10308 } 10309 rpt_mutex_unlock(&myrpt->lock); 10310 if (toexit) break; 10311 if (who == myrpt->monchannel) 10312 { 10313 f = ast_read(myrpt->monchannel); 10314 if (!f) 10315 { 10316 if (debug) printf("@@@@ rpt:Hung Up\n"); 10317 break; 10318 } 10319 if (f->frametype == AST_FRAME_VOICE) 10320 { 10321 if (myrpt->monstream) 10322 ast_writestream(myrpt->monstream,f); 10323 } 10324 if (f->frametype == AST_FRAME_CONTROL) 10325 { 10326 if (f->subclass == AST_CONTROL_HANGUP) 10327 { 10328 if (debug) printf("@@@@ rpt:Hung Up\n"); 10329 ast_frfree(f); 10330 break; 10331 } 10332 } 10333 ast_frfree(f); 10334 continue; 10335 } 10336 if (who == myrpt->txpchannel) /* if it was a read from remote tx */ 10337 { 10338 f = ast_read(myrpt->txpchannel); 10339 if (!f) 10340 { 10341 if (debug) printf("@@@@ rpt:Hung Up\n"); 10342 break; 10343 } 10344 if (f->frametype == AST_FRAME_CONTROL) 10345 { 10346 if (f->subclass == AST_CONTROL_HANGUP) 10347 { 10348 if (debug) printf("@@@@ rpt:Hung Up\n"); 10349 ast_frfree(f); 10350 break; 10351 } 10352 } 10353 ast_frfree(f); 10354 continue; 10355 } 10356 } 10357 usleep(100000); 10358 ast_hangup(myrpt->pchannel); 10359 ast_hangup(myrpt->monchannel); 10360 ast_hangup(myrpt->txpchannel); 10361 if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel); 10362 if (myrpt->zaptxchannel != myrpt->txchannel) ast_hangup(myrpt->zaptxchannel); 10363 if (myrpt->lastf1) ast_frfree(myrpt->lastf1); 10364 myrpt->lastf1 = NULL; 10365 if (myrpt->lastf2) ast_frfree(myrpt->lastf2); 10366 myrpt->lastf2 = NULL; 10367 ast_hangup(myrpt->rxchannel); 10368 rpt_mutex_lock(&myrpt->lock); 10369 l = myrpt->links.next; 10370 while(l != &myrpt->links) 10371 { 10372 struct rpt_link *ll = l; 10373 /* remove from queue */ 10374 remque((struct qelem *) l); 10375 /* hang-up on call to device */ 10376 if (l->chan) ast_hangup(l->chan); 10377 ast_hangup(l->pchan); 10378 l = l->next; 10379 free(ll); 10380 } 10381 rpt_mutex_unlock(&myrpt->lock); 10382 if (debug) printf("@@@@ rpt:Hung up channel\n"); 10383 myrpt->rpt_thread = AST_PTHREADT_STOP; 10384 pthread_exit(NULL); 10385 return NULL; 10386 }
static void* rpt_call | ( | void * | this | ) | [static] |
Definition at line 4162 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().
04163 { 04164 ZT_CONFINFO ci; /* conference info */ 04165 struct rpt *myrpt = (struct rpt *)this; 04166 int res; 04167 int stopped,congstarted,dialtimer,lastcidx,aborted; 04168 struct ast_channel *mychannel,*genchannel; 04169 04170 04171 myrpt->mydtmf = 0; 04172 /* allocate a pseudo-channel thru asterisk */ 04173 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04174 if (!mychannel) 04175 { 04176 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 04177 pthread_exit(NULL); 04178 } 04179 #ifdef AST_CDR_FLAG_POST_DISABLED 04180 ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED); 04181 #endif 04182 ci.chan = 0; 04183 ci.confno = myrpt->conf; /* use the pseudo conference */ 04184 ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER 04185 | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 04186 /* first put the channel on the conference */ 04187 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 04188 { 04189 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04190 ast_hangup(mychannel); 04191 myrpt->callmode = 0; 04192 pthread_exit(NULL); 04193 } 04194 /* allocate a pseudo-channel thru asterisk */ 04195 genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04196 if (!genchannel) 04197 { 04198 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 04199 ast_hangup(mychannel); 04200 pthread_exit(NULL); 04201 } 04202 #ifdef AST_CDR_FLAG_POST_DISABLED 04203 ast_set_flag(genchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 04204 #endif 04205 ci.chan = 0; 04206 ci.confno = myrpt->conf; 04207 ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER 04208 | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 04209 /* first put the channel on the conference */ 04210 if (ioctl(genchannel->fds[0],ZT_SETCONF,&ci) == -1) 04211 { 04212 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04213 ast_hangup(mychannel); 04214 ast_hangup(genchannel); 04215 myrpt->callmode = 0; 04216 pthread_exit(NULL); 04217 } 04218 if (myrpt->p.tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->p.tonezone) == -1)) 04219 { 04220 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone); 04221 ast_hangup(mychannel); 04222 ast_hangup(genchannel); 04223 myrpt->callmode = 0; 04224 pthread_exit(NULL); 04225 } 04226 if (myrpt->p.tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->p.tonezone) == -1)) 04227 { 04228 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone); 04229 ast_hangup(mychannel); 04230 ast_hangup(genchannel); 04231 myrpt->callmode = 0; 04232 pthread_exit(NULL); 04233 } 04234 /* start dialtone if patchquiet is 0. Special patch modes don't send dial tone */ 04235 if ((!myrpt->patchquiet) && (tone_zone_play_tone(mychannel->fds[0],ZT_TONE_DIALTONE) < 0)) 04236 { 04237 ast_log(LOG_WARNING, "Cannot start dialtone\n"); 04238 ast_hangup(mychannel); 04239 ast_hangup(genchannel); 04240 myrpt->callmode = 0; 04241 pthread_exit(NULL); 04242 } 04243 stopped = 0; 04244 congstarted = 0; 04245 dialtimer = 0; 04246 lastcidx = 0; 04247 aborted = 0; 04248 04249 04250 while ((myrpt->callmode == 1) || (myrpt->callmode == 4)) 04251 { 04252 04253 if((myrpt->patchdialtime)&&(myrpt->callmode == 1)&&(myrpt->cidx != lastcidx)){ 04254 dialtimer = 0; 04255 lastcidx = myrpt->cidx; 04256 } 04257 04258 if((myrpt->patchdialtime)&&(dialtimer >= myrpt->patchdialtime)){ 04259 rpt_mutex_lock(&myrpt->lock); 04260 aborted = 1; 04261 myrpt->callmode = 0; 04262 rpt_mutex_unlock(&myrpt->lock); 04263 break; 04264 } 04265 04266 if ((!myrpt->patchquiet) && (!stopped) && (myrpt->callmode == 1) && (myrpt->cidx > 0)) 04267 { 04268 stopped = 1; 04269 /* stop dial tone */ 04270 tone_zone_play_tone(mychannel->fds[0],-1); 04271 } 04272 if (myrpt->callmode == 4) 04273 { 04274 if(!congstarted){ 04275 congstarted = 1; 04276 /* start congestion tone */ 04277 tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION); 04278 } 04279 } 04280 res = ast_safe_sleep(mychannel, MSWAIT); 04281 if (res < 0) 04282 { 04283 ast_hangup(mychannel); 04284 ast_hangup(genchannel); 04285 rpt_mutex_lock(&myrpt->lock); 04286 myrpt->callmode = 0; 04287 rpt_mutex_unlock(&myrpt->lock); 04288 pthread_exit(NULL); 04289 } 04290 dialtimer += MSWAIT; 04291 } 04292 /* stop any tone generation */ 04293 tone_zone_play_tone(mychannel->fds[0],-1); 04294 /* end if done */ 04295 if (!myrpt->callmode) 04296 { 04297 ast_hangup(mychannel); 04298 ast_hangup(genchannel); 04299 rpt_mutex_lock(&myrpt->lock); 04300 myrpt->callmode = 0; 04301 rpt_mutex_unlock(&myrpt->lock); 04302 if((!myrpt->patchquiet) && aborted) 04303 rpt_telemetry(myrpt, TERM, NULL); 04304 pthread_exit(NULL); 04305 } 04306 04307 if (myrpt->p.ourcallerid && *myrpt->p.ourcallerid){ 04308 char *name, *loc, *instr; 04309 instr = strdup(myrpt->p.ourcallerid); 04310 if(instr){ 04311 ast_callerid_parse(instr, &name, &loc); 04312 if(loc){ 04313 if(mychannel->cid.cid_num) 04314 free(mychannel->cid.cid_num); 04315 mychannel->cid.cid_num = strdup(loc); 04316 } 04317 if(name){ 04318 if(mychannel->cid.cid_name) 04319 free(mychannel->cid.cid_name); 04320 mychannel->cid.cid_name = strdup(name); 04321 } 04322 free(instr); 04323 } 04324 } 04325 04326 ast_copy_string(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1); 04327 ast_copy_string(mychannel->context, myrpt->patchcontext, sizeof(mychannel->context) - 1); 04328 04329 if (myrpt->p.acctcode) 04330 ast_cdr_setaccount(mychannel,myrpt->p.acctcode); 04331 mychannel->priority = 1; 04332 ast_channel_undefer_dtmf(mychannel); 04333 if (ast_pbx_start(mychannel) < 0) 04334 { 04335 ast_log(LOG_WARNING, "Unable to start PBX!!\n"); 04336 ast_hangup(mychannel); 04337 ast_hangup(genchannel); 04338 rpt_mutex_lock(&myrpt->lock); 04339 myrpt->callmode = 0; 04340 rpt_mutex_unlock(&myrpt->lock); 04341 pthread_exit(NULL); 04342 } 04343 usleep(10000); 04344 rpt_mutex_lock(&myrpt->lock); 04345 myrpt->callmode = 3; 04346 /* set appropriate conference for the pseudo */ 04347 ci.chan = 0; 04348 ci.confno = myrpt->conf; 04349 ci.confmode = (myrpt->p.duplex == 2) ? ZT_CONF_CONFANNMON : 04350 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 04351 /* first put the channel on the conference in announce mode */ 04352 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 04353 { 04354 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04355 ast_hangup(mychannel); 04356 ast_hangup(genchannel); 04357 myrpt->callmode = 0; 04358 pthread_exit(NULL); 04359 } 04360 while(myrpt->callmode) 04361 { 04362 if ((!mychannel->pbx) && (myrpt->callmode != 4)) 04363 { 04364 if(myrpt->patchfarenddisconnect){ /* If patch is setup for far end disconnect */ 04365 myrpt->callmode = 0; 04366 if(!myrpt->patchquiet){ 04367 rpt_mutex_unlock(&myrpt->lock); 04368 rpt_telemetry(myrpt, TERM, NULL); 04369 rpt_mutex_lock(&myrpt->lock); 04370 } 04371 } 04372 else{ /* Send congestion until patch is downed by command */ 04373 myrpt->callmode = 4; 04374 rpt_mutex_unlock(&myrpt->lock); 04375 /* start congestion tone */ 04376 tone_zone_play_tone(genchannel->fds[0],ZT_TONE_CONGESTION); 04377 rpt_mutex_lock(&myrpt->lock); 04378 } 04379 } 04380 if (myrpt->mydtmf) 04381 { 04382 struct ast_frame wf = {AST_FRAME_DTMF, } ; 04383 wf.subclass = myrpt->mydtmf; 04384 rpt_mutex_unlock(&myrpt->lock); 04385 ast_queue_frame(mychannel,&wf); 04386 ast_senddigit(genchannel,myrpt->mydtmf); 04387 rpt_mutex_lock(&myrpt->lock); 04388 myrpt->mydtmf = 0; 04389 } 04390 rpt_mutex_unlock(&myrpt->lock); 04391 usleep(MSWAIT * 1000); 04392 rpt_mutex_lock(&myrpt->lock); 04393 } 04394 rpt_mutex_unlock(&myrpt->lock); 04395 tone_zone_play_tone(genchannel->fds[0],-1); 04396 if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV); 04397 ast_hangup(genchannel); 04398 rpt_mutex_lock(&myrpt->lock); 04399 myrpt->callmode = 0; 04400 rpt_mutex_unlock(&myrpt->lock); 04401 /* set appropriate conference for the pseudo */ 04402 ci.chan = 0; 04403 ci.confno = myrpt->conf; 04404 ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON : 04405 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 04406 /* first put the channel on the conference in announce mode */ 04407 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 04408 { 04409 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04410 } 04411 pthread_exit(NULL); 04412 }
static int rpt_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1968 of file app_rpt.c.
References ast_cli(), myatoi(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01969 { 01970 int newlevel; 01971 01972 if (argc != 4) 01973 return RESULT_SHOWUSAGE; 01974 newlevel = myatoi(argv[3]); 01975 if((newlevel < 0) || (newlevel > 7)) 01976 return RESULT_SHOWUSAGE; 01977 if(newlevel) 01978 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel); 01979 else 01980 ast_cli(fd, "app_rpt Debugging disabled\n"); 01981 01982 debug = newlevel; 01983 return RESULT_SUCCESS; 01984 }
static int rpt_do_dump | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1990 of file app_rpt.c.
References ast_cli(), name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and rpt_vars.
01991 { 01992 int i; 01993 01994 if (argc != 3) 01995 return RESULT_SHOWUSAGE; 01996 01997 for(i = 0; i < nrpts; i++) 01998 { 01999 if (!strcmp(argv[2],rpt_vars[i].name)) 02000 { 02001 rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 02002 ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]); 02003 return RESULT_SUCCESS; 02004 } 02005 } 02006 return RESULT_FAILURE; 02007 }
static int rpt_do_fun | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2410 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.
02411 { 02412 int i,busy=0; 02413 02414 if (argc != 4) return RESULT_SHOWUSAGE; 02415 02416 for(i = 0; i < nrpts; i++){ 02417 if(!strcmp(argv[2], rpt_vars[i].name)){ 02418 struct rpt *myrpt = &rpt_vars[i]; 02419 rpt_mutex_lock(&myrpt->lock); 02420 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(argv[3])){ 02421 rpt_mutex_unlock(&myrpt->lock); 02422 busy=1; 02423 } 02424 if(!busy){ 02425 myrpt->macrotimer = MACROTIME; 02426 strncat(myrpt->macrobuf, argv[3], MAXMACRO - strlen(myrpt->macrobuf) - 1); 02427 } 02428 rpt_mutex_unlock(&myrpt->lock); 02429 } 02430 } 02431 if(busy){ 02432 ast_cli(fd, "Function decoder busy"); 02433 } 02434 return RESULT_FAILURE; 02435 }
static int rpt_do_lstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2238 of file app_rpt.c.
References ast_cli(), ast_log(), rpt_link::chan, rpt_link::chan_stat, rpt_lstat::connecttime, rpt_link::connecttime, free, rpt::links, rpt::lock, LOG_ERROR, malloc, MAXPEERSTR, MAXREMSTR, rpt_link::mode, rpt_link::name, name, rpt_link::next, rpt_lstat::next, NRPTSTAT, rpt_link::outbound, pbx_substitute_variables_helper(), rpt_lstat::prev, rpt_link::reconnects, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, s, t, and rpt_link::thisconnected.
02239 { 02240 int i,j; 02241 char *connstate; 02242 struct rpt *myrpt; 02243 struct rpt_link *l; 02244 struct rpt_lstat *s,*t; 02245 struct rpt_lstat s_head; 02246 if(argc != 3) 02247 return RESULT_SHOWUSAGE; 02248 02249 s = NULL; 02250 s_head.next = &s_head; 02251 s_head.prev = &s_head; 02252 02253 for(i = 0; i < nrpts; i++) 02254 { 02255 if (!strcmp(argv[2],rpt_vars[i].name)){ 02256 /* Make a copy of all stat variables while locked */ 02257 myrpt = &rpt_vars[i]; 02258 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02259 /* Traverse the list of connected nodes */ 02260 j = 0; 02261 l = myrpt->links.next; 02262 while(l && (l != &myrpt->links)){ 02263 if (l->name[0] == '0'){ /* Skip '0' nodes */ 02264 l = l->next; 02265 continue; 02266 } 02267 if((s = (struct rpt_lstat *) malloc(sizeof(struct rpt_lstat))) == NULL){ 02268 ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n"); 02269 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02270 return RESULT_FAILURE; 02271 } 02272 memset(s, 0, sizeof(struct rpt_lstat)); 02273 strncpy(s->name, l->name, MAXREMSTR - 1); 02274 if (l->chan) pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1); 02275 else strcpy(s->peer,"(none)"); 02276 s->mode = l->mode; 02277 s->outbound = l->outbound; 02278 s->reconnects = l->reconnects; 02279 s->connecttime = l->connecttime; 02280 s->thisconnected = l->thisconnected; 02281 memcpy(s->chan_stat,l->chan_stat,NRPTSTAT * sizeof(struct rpt_chan_stat)); 02282 insque((struct qelem *) s, (struct qelem *) s_head.next); 02283 memset(l->chan_stat,0,NRPTSTAT * sizeof(struct rpt_chan_stat)); 02284 l = l->next; 02285 } 02286 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02287 ast_cli(fd, "NODE PEER RECONNECTS DIRECTION CONNECT TIME CONNECT STATE\n"); 02288 ast_cli(fd, "---- ---- ---------- --------- ------------ -------------\n"); 02289 02290 for(s = s_head.next; s != &s_head; s = s->next){ 02291 int hours, minutes, seconds; 02292 long long connecttime = s->connecttime; 02293 char conntime[21]; 02294 hours = (int) connecttime/3600000; 02295 connecttime %= 3600000; 02296 minutes = (int) connecttime/60000; 02297 connecttime %= 60000; 02298 seconds = (int) connecttime/1000; 02299 connecttime %= 1000; 02300 snprintf(conntime, 20, "%02d:%02d:%02d.%d", 02301 hours, minutes, seconds, (int) connecttime); 02302 conntime[20] = 0; 02303 if(s->thisconnected) 02304 connstate = "ESTABLISHED"; 02305 else 02306 connstate = "CONNECTING"; 02307 ast_cli(fd, "%-10s%-20s%-12d%-11s%-20s%-20s\n", 02308 s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime, connstate); 02309 } 02310 /* destroy our local link queue */ 02311 s = s_head.next; 02312 while(s != &s_head){ 02313 t = s; 02314 s = s->next; 02315 remque((struct qelem *)t); 02316 free(t); 02317 } 02318 return RESULT_SUCCESS; 02319 } 02320 } 02321 return RESULT_FAILURE; 02322 }
static int rpt_do_nodes | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2328 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.
02329 { 02330 int i,j; 02331 char ns; 02332 char lbuf[MAXLINKLIST],*strs[MAXLINKLIST]; 02333 struct rpt *myrpt; 02334 if(argc != 3) 02335 return RESULT_SHOWUSAGE; 02336 02337 for(i = 0; i < nrpts; i++) 02338 { 02339 if (!strcmp(argv[2],rpt_vars[i].name)){ 02340 /* Make a copy of all stat variables while locked */ 02341 myrpt = &rpt_vars[i]; 02342 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02343 __mklinklist(myrpt,NULL,lbuf); 02344 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02345 /* parse em */ 02346 ns = finddelim(lbuf,strs,MAXLINKLIST); 02347 /* sort em */ 02348 if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar); 02349 ast_cli(fd,"\n"); 02350 ast_cli(fd, "************************* CONNECTED NODES *************************\n\n"); 02351 for(j = 0 ;; j++){ 02352 if(!strs[j]){ 02353 if(!j){ 02354 ast_cli(fd,"<NONE>"); 02355 } 02356 break; 02357 } 02358 ast_cli(fd, "%s", strs[j]); 02359 if(j % 8 == 7){ 02360 ast_cli(fd, "\n"); 02361 } 02362 else{ 02363 if(strs[j + 1]) 02364 ast_cli(fd, ", "); 02365 } 02366 } 02367 ast_cli(fd,"\n\n"); 02368 return RESULT_SUCCESS; 02369 } 02370 } 02371 return RESULT_FAILURE; 02372 }
static int rpt_do_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2378 of file app_rpt.c.
References reload(), RESULT_FAILURE, RESULT_SHOWUSAGE, and rpt_vars.
02379 { 02380 int n; 02381 02382 if (argc > 2) return RESULT_SHOWUSAGE; 02383 02384 for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1; 02385 02386 return RESULT_FAILURE; 02387 }
static int rpt_do_restart | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2393 of file app_rpt.c.
References ast_softhangup(), AST_SOFTHANGUP_DEV, RESULT_FAILURE, RESULT_SHOWUSAGE, rpt_vars, and rpt::rxchannel.
02394 { 02395 int i; 02396 02397 if (argc > 2) return RESULT_SHOWUSAGE; 02398 for(i = 0; i < nrpts; i++) 02399 { 02400 if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV); 02401 } 02402 return RESULT_FAILURE; 02403 }
static int rpt_do_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2013 of file app_rpt.c.
References ast_cli(), ast_strdupa, rpt::callmode, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, rpt::exten, rpt::keyed, rpt::lastdtmfcommand, rpt::lastnodewhichkeyedusup, 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, rpt::sysstate_cur, rpt::tailid, rpt::timeouts, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, rpt::totime, and rpt::totimer.
02014 { 02015 int i,j; 02016 int dailytxtime, dailykerchunks; 02017 int totalkerchunks, dailykeyups, totalkeyups, timeouts; 02018 int totalexecdcommands, dailyexecdcommands, hours, minutes, seconds; 02019 long long totaltxtime; 02020 struct rpt_link *l; 02021 char *listoflinks[MAX_STAT_LINKS]; 02022 char *lastnodewhichkeyedusup, *lastdtmfcommand; 02023 char *tot_state, *ider_state, *patch_state; 02024 char *reverse_patch_state, *sys_ena, *tot_ena, *link_ena, *patch_ena; 02025 char *sch_ena, *input_signal, *called_number, *user_funs, *tail_type; 02026 struct rpt *myrpt; 02027 02028 static char *not_applicable = "N/A"; 02029 02030 if(argc != 3) 02031 return RESULT_SHOWUSAGE; 02032 02033 for(i = 0 ; i < MAX_STAT_LINKS; i++) 02034 listoflinks[i] = NULL; 02035 02036 tot_state = ider_state = 02037 patch_state = reverse_patch_state = 02038 input_signal = called_number = 02039 lastdtmfcommand = not_applicable; 02040 02041 for(i = 0; i < nrpts; i++) 02042 { 02043 if (!strcmp(argv[2],rpt_vars[i].name)){ 02044 /* Make a copy of all stat variables while locked */ 02045 myrpt = &rpt_vars[i]; 02046 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02047 02048 dailytxtime = myrpt->dailytxtime; 02049 totaltxtime = myrpt->totaltxtime; 02050 dailykeyups = myrpt->dailykeyups; 02051 totalkeyups = myrpt->totalkeyups; 02052 dailykerchunks = myrpt->dailykerchunks; 02053 totalkerchunks = myrpt->totalkerchunks; 02054 dailyexecdcommands = myrpt->dailyexecdcommands; 02055 totalexecdcommands = myrpt->totalexecdcommands; 02056 timeouts = myrpt->timeouts; 02057 02058 /* Traverse the list of connected nodes */ 02059 reverse_patch_state = "DOWN"; 02060 j = 0; 02061 l = myrpt->links.next; 02062 while(l && (l != &myrpt->links)){ 02063 if (l->name[0] == '0'){ /* Skip '0' nodes */ 02064 reverse_patch_state = "UP"; 02065 l = l->next; 02066 continue; 02067 } 02068 listoflinks[j] = ast_strdupa(l->name); 02069 if(listoflinks[j]) 02070 j++; 02071 l = l->next; 02072 } 02073 02074 lastnodewhichkeyedusup = ast_strdupa(myrpt->lastnodewhichkeyedusup); 02075 if((!lastnodewhichkeyedusup) || (!strlen(lastnodewhichkeyedusup))) 02076 lastnodewhichkeyedusup = not_applicable; 02077 02078 if(myrpt->keyed) 02079 input_signal = "YES"; 02080 else 02081 input_signal = "NO"; 02082 02083 if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable) 02084 sys_ena = "DISABLED"; 02085 else 02086 sys_ena = "ENABLED"; 02087 02088 if(myrpt->p.s[myrpt->p.sysstate_cur].totdisable) 02089 tot_ena = "DISABLED"; 02090 else 02091 tot_ena = "ENABLED"; 02092 02093 if(myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable) 02094 link_ena = "DISABLED"; 02095 else 02096 link_ena = "ENABLED"; 02097 02098 if(myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 02099 patch_ena = "DISABLED"; 02100 else 02101 patch_ena = "ENABLED"; 02102 02103 if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable) 02104 sch_ena = "DISABLED"; 02105 else 02106 sch_ena = "ENABLED"; 02107 02108 if(myrpt->p.s[myrpt->p.sysstate_cur].userfundisable) 02109 user_funs = "DISABLED"; 02110 else 02111 user_funs = "ENABLED"; 02112 02113 if(myrpt->p.s[myrpt->p.sysstate_cur].alternatetail) 02114 tail_type = "ALTERNATE"; 02115 else 02116 tail_type = "STANDARD"; 02117 02118 if(!myrpt->totimer) 02119 tot_state = "TIMED OUT!"; 02120 else if(myrpt->totimer != myrpt->p.totime) 02121 tot_state = "ARMED"; 02122 else 02123 tot_state = "RESET"; 02124 02125 if(myrpt->tailid) 02126 ider_state = "QUEUED IN TAIL"; 02127 else if(myrpt->mustid) 02128 ider_state = "QUEUED FOR CLEANUP"; 02129 else 02130 ider_state = "CLEAN"; 02131 02132 switch(myrpt->callmode){ 02133 case 1: 02134 patch_state = "DIALING"; 02135 break; 02136 case 2: 02137 patch_state = "CONNECTING"; 02138 break; 02139 case 3: 02140 patch_state = "UP"; 02141 break; 02142 02143 case 4: 02144 patch_state = "CALL FAILED"; 02145 break; 02146 02147 default: 02148 patch_state = "DOWN"; 02149 } 02150 02151 if(strlen(myrpt->exten)){ 02152 called_number = ast_strdupa(myrpt->exten); 02153 if(!called_number) 02154 called_number = not_applicable; 02155 } 02156 02157 if(strlen(myrpt->lastdtmfcommand)){ 02158 lastdtmfcommand = ast_strdupa(myrpt->lastdtmfcommand); 02159 if(!lastdtmfcommand) 02160 lastdtmfcommand = not_applicable; 02161 } 02162 02163 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02164 02165 ast_cli(fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name); 02166 ast_cli(fd, "Selected system state............................: %d\n", myrpt->p.sysstate_cur); 02167 ast_cli(fd, "Signal on input..................................: %s\n", input_signal); 02168 ast_cli(fd, "System...........................................: %s\n", sys_ena); 02169 ast_cli(fd, "Scheduler........................................: %s\n", sch_ena); 02170 ast_cli(fd, "Tail Time........................................: %s\n", tail_type); 02171 ast_cli(fd, "Time out timer...................................: %s\n", tot_ena); 02172 ast_cli(fd, "Time out timer state.............................: %s\n", tot_state); 02173 ast_cli(fd, "Time outs since system initialization............: %d\n", timeouts); 02174 ast_cli(fd, "Identifier state.................................: %s\n", ider_state); 02175 ast_cli(fd, "Kerchunks today..................................: %d\n", dailykerchunks); 02176 ast_cli(fd, "Kerchunks since system initialization............: %d\n", totalkerchunks); 02177 ast_cli(fd, "Keyups today.....................................: %d\n", dailykeyups); 02178 ast_cli(fd, "Keyups since system initialization...............: %d\n", totalkeyups); 02179 ast_cli(fd, "DTMF commands today..............................: %d\n", dailyexecdcommands); 02180 ast_cli(fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands); 02181 ast_cli(fd, "Last DTMF command executed.......................: %s\n", lastdtmfcommand); 02182 hours = dailytxtime/3600000; 02183 dailytxtime %= 3600000; 02184 minutes = dailytxtime/60000; 02185 dailytxtime %= 60000; 02186 seconds = dailytxtime/1000; 02187 dailytxtime %= 1000; 02188 02189 ast_cli(fd, "TX time today ...................................: %02d:%02d:%02d.%d\n", 02190 hours, minutes, seconds, dailytxtime); 02191 02192 hours = (int) totaltxtime/3600000; 02193 totaltxtime %= 3600000; 02194 minutes = (int) totaltxtime/60000; 02195 totaltxtime %= 60000; 02196 seconds = (int) totaltxtime/1000; 02197 totaltxtime %= 1000; 02198 02199 ast_cli(fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n", 02200 hours, minutes, seconds, (int) totaltxtime); 02201 ast_cli(fd, "Nodes currently connected to us..................: "); 02202 for(j = 0 ;; j++){ 02203 if(!listoflinks[j]){ 02204 if(!j){ 02205 ast_cli(fd,"<NONE>"); 02206 } 02207 break; 02208 } 02209 ast_cli(fd, "%s", listoflinks[j]); 02210 if(j % 4 == 3){ 02211 ast_cli(fd, "\n"); 02212 ast_cli(fd, " : "); 02213 } 02214 else{ 02215 if(listoflinks[j + 1]) 02216 ast_cli(fd, ", "); 02217 } 02218 } 02219 ast_cli(fd,"\n"); 02220 02221 ast_cli(fd, "Last node which transmitted to us................: %s\n", lastnodewhichkeyedusup); 02222 ast_cli(fd, "Autopatch........................................: %s\n", patch_ena); 02223 ast_cli(fd, "Autopatch state..................................: %s\n", patch_state); 02224 ast_cli(fd, "Autopatch called number..........................: %s\n", called_number); 02225 ast_cli(fd, "Reverse patch/IAXRPT connected...................: %s\n", reverse_patch_state); 02226 ast_cli(fd, "User linking commands............................: %s\n", link_ena); 02227 ast_cli(fd, "User functions...................................: %s\n\n", user_funs); 02228 return RESULT_SUCCESS; 02229 } 02230 } 02231 return RESULT_FAILURE; 02232 }
static int rpt_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 10556 of file app_rpt.c.
References ast_log(), ast_safe_sleep(), ast_strlen_zero(), rpt_tele::chan, f, LOG_NOTICE, LOG_WARNING, rpt::name, name, rpt::p, rpt_vars, rpt::s, START_DELAY, strsep(), rpt::sysstate_cur, and t.
Referenced by load_module().
10557 { 10558 int res=-1,i,rem_totx,rem_rx,remkeyed,n,phone_mode = 0; 10559 int iskenwood_pci4,authtold,authreq,setting,notremming,reming; 10560 int ismuted,dtmfed; 10561 #ifdef OLD_ASTERISK 10562 struct localuser *u; 10563 #endif 10564 char tmp[256], keyed = 0,keyed1 = 0; 10565 char *options,*stringp,*tele,c; 10566 struct rpt *myrpt; 10567 struct ast_frame *f,*f1,*f2; 10568 struct ast_channel *who; 10569 struct ast_channel *cs[20]; 10570 struct rpt_link *l; 10571 ZT_CONFINFO ci; /* conference info */ 10572 ZT_PARAMS par; 10573 int ms,elap,nullfd; 10574 time_t t,last_timeout_warning; 10575 struct zt_radio_param z; 10576 struct rpt_tele *telem; 10577 10578 nullfd = open("/dev/null",O_RDWR); 10579 if (ast_strlen_zero(data)) { 10580 ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n"); 10581 return -1; 10582 } 10583 10584 strncpy(tmp, (char *)data, sizeof(tmp)-1); 10585 time(&t); 10586 /* if time has externally shifted negative, screw it */ 10587 if (t < starttime) t = starttime + START_DELAY; 10588 if ((!starttime) || (t < (starttime + START_DELAY))) 10589 { 10590 ast_log(LOG_NOTICE,"Node %s rejecting call: too soon!\n",tmp); 10591 ast_safe_sleep(chan,3000); 10592 return -1; 10593 } 10594 stringp=tmp; 10595 strsep(&stringp, "|"); 10596 options = stringp; 10597 myrpt = NULL; 10598 /* see if we can find our specified one */ 10599 for(i = 0; i < nrpts; i++) 10600 { 10601 /* if name matches, assign it and exit loop */ 10602 if (!strcmp(tmp,rpt_vars[i].name)) 10603 { 10604 myrpt = &rpt_vars[i]; 10605 break; 10606 } 10607 } 10608 if (myrpt == NULL) 10609 { 10610 ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp); 10611 return -1; 10612 } 10613 10614 if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable){ /* Do not allow incoming connections if disabled */ 10615 ast_log(LOG_NOTICE, "Connect attempt to node %s with tx disabled", myrpt->name); 10616 return -1; 10617 } 10618 10619 /* if not phone access, must be an IAX connection */ 10620 if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R'))) 10621 { 10622 int val; 10623 10624 phone_mode = 1; 10625 if (*options == 'D') phone_mode = 2; 10626 ast_set_callerid(chan,"0","app_rpt user","0"); 10627 val = 1; 10628 ast_channel_setoption(chan,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0); 10629 } 10630 else 10631 { 10632 #ifdef ALLOW_LOCAL_CHANNELS 10633 /* Check to insure the connection is IAX2 or Local*/ 10634 if ( (strncmp(chan->name,"IAX2",4)) && (strncmp(chan->name,"Local",5)) ) { 10635 ast_log(LOG_WARNING, "We only accept links via IAX2 or Local!!\n"); 10636 return -1; 10637 } 10638 #else 10639 if (strncmp(chan->name,"IAX2",4)) 10640 { 10641 ast_log(LOG_WARNING, "We only accept links via IAX2!!\n"); 10642 return -1; 10643 } 10644 #endif 10645 } 10646 if (options && (*options == 'R')) 10647 { 10648 10649 /* Parts of this section taken from app_parkandannounce */ 10650 char *return_context; 10651 int l, m, lot, timeout = 0; 10652 char tmp[256],*template; 10653 char *working, *context, *exten, *priority; 10654 char *s,*orig_s; 10655 10656 10657 rpt_mutex_lock(&myrpt->lock); 10658 m = myrpt->callmode; 10659 rpt_mutex_unlock(&myrpt->lock); 10660 10661 if ((!myrpt->p.nobusyout) && m) 10662 { 10663 if (chan->_state != AST_STATE_UP) 10664 { 10665 ast_indicate(chan,AST_CONTROL_BUSY); 10666 } 10667 while(ast_safe_sleep(chan,10000) != -1); 10668 return -1; 10669 } 10670 10671 if (chan->_state != AST_STATE_UP) 10672 { 10673 ast_answer(chan); 10674 } 10675 10676 l=strlen(options)+2; 10677 orig_s=malloc(l); 10678 if(!orig_s) { 10679 ast_log(LOG_WARNING, "Out of memory\n"); 10680 return -1; 10681 } 10682 s=orig_s; 10683 strncpy(s,options,l); 10684 10685 template=strsep(&s,"|"); 10686 if(!template) { 10687 ast_log(LOG_WARNING, "An announce template must be defined\n"); 10688 free(orig_s); 10689 return -1; 10690 } 10691 10692 if(s) { 10693 timeout = atoi(strsep(&s, "|")); 10694 timeout *= 1000; 10695 } 10696 10697 return_context = s; 10698 10699 if(return_context != NULL) { 10700 /* set the return context. Code borrowed from the Goto builtin */ 10701 10702 working = return_context; 10703 context = strsep(&working, "|"); 10704 exten = strsep(&working, "|"); 10705 if(!exten) { 10706 /* Only a priority in this one */ 10707 priority = context; 10708 exten = NULL; 10709 context = NULL; 10710 } else { 10711 priority = strsep(&working, "|"); 10712 if(!priority) { 10713 /* Only an extension and priority in this one */ 10714 priority = exten; 10715 exten = context; 10716 context = NULL; 10717 } 10718 } 10719 if(atoi(priority) < 0) { 10720 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority); 10721 free(orig_s); 10722 return -1; 10723 } 10724 /* At this point we have a priority and maybe an extension and a context */ 10725 chan->priority = atoi(priority); 10726 #ifdef OLD_ASTERISK 10727 if(exten && strcasecmp(exten, "BYEXTENSION")) 10728 #else 10729 if(exten) 10730 #endif 10731 strncpy(chan->exten, exten, sizeof(chan->exten)-1); 10732 if(context) 10733 strncpy(chan->context, context, sizeof(chan->context)-1); 10734 } else { /* increment the priority by default*/ 10735 chan->priority++; 10736 } 10737 10738 if(option_verbose > 2) { 10739 ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num); 10740 if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 10741 ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n"); 10742 } 10743 } 10744 10745 /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout 10746 before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */ 10747 10748 ast_masq_park_call(chan, NULL, timeout, &lot); 10749 10750 if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context); 10751 10752 snprintf(tmp,sizeof(tmp) - 1,"%d,%s",lot,template + 1); 10753 10754 rpt_telemetry(myrpt,REV_PATCH,tmp); 10755 10756 free(orig_s); 10757 10758 return 0; 10759 10760 } 10761 10762 if (!options) 10763 { 10764 struct ast_hostent ahp; 10765 struct hostent *hp; 10766 struct in_addr ia; 10767 char hisip[100],nodeip[100],*val, *s, *s1, *s2, *b,*b1; 10768 10769 /* look at callerid to see what node this comes from */ 10770 if (!chan->cid.cid_num) /* if doesn't have caller id */ 10771 { 10772 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 10773 return -1; 10774 } 10775 10776 /* get his IP from IAX2 module */ 10777 memset(hisip,0,sizeof(hisip)); 10778 #ifdef ALLOW_LOCAL_CHANNELS 10779 /* set IP address if this is a local connection*/ 10780 if (strncmp(chan->name,"Local",5)==0) { 10781 strcpy(hisip,"127.0.0.1"); 10782 } else { 10783 pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1); 10784 } 10785 #else 10786 pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1); 10787 #endif 10788 10789 if (!hisip[0]) 10790 { 10791 ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n"); 10792 return -1; 10793 } 10794 10795 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 10796 ast_shrink_phone_number(b1); 10797 if (!strcmp(myrpt->name,b1)) 10798 { 10799 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 10800 return -1; 10801 } 10802 10803 if (*b1 < '1') 10804 { 10805 ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1); 10806 return -1; 10807 } 10808 10809 10810 /* look for his reported node string */ 10811 val = node_lookup(myrpt,b1); 10812 if (!val) 10813 { 10814 ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1); 10815 return -1; 10816 } 10817 strncpy(tmp,val,sizeof(tmp) - 1); 10818 s = tmp; 10819 s1 = strsep(&s,","); 10820 s2 = strsep(&s,","); 10821 if (!s2) 10822 { 10823 ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1); 10824 return -1; 10825 } 10826 if (strcmp(s2,"NONE")) { 10827 hp = ast_gethostbyname(s2, &ahp); 10828 if (!hp) 10829 { 10830 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2); 10831 return -1; 10832 } 10833 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 10834 #ifdef OLD_ASTERISK 10835 ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia); 10836 #else 10837 strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1); 10838 #endif 10839 if (strcmp(hisip,nodeip)) 10840 { 10841 char *s3 = strchr(s1,'@'); 10842 if (s3) s1 = s3 + 1; 10843 s3 = strchr(s1,'/'); 10844 if (s3) *s3 = 0; 10845 hp = ast_gethostbyname(s1, &ahp); 10846 if (!hp) 10847 { 10848 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1); 10849 return -1; 10850 } 10851 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 10852 #ifdef OLD_ASTERISK 10853 ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia); 10854 #else 10855 strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1); 10856 #endif 10857 if (strcmp(hisip,nodeip)) 10858 { 10859 ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip); 10860 return -1; 10861 } 10862 } 10863 } 10864 } 10865 10866 /* if is not a remote */ 10867 if (!myrpt->remote) 10868 { 10869 10870 char *b,*b1; 10871 int reconnects = 0; 10872 10873 /* look at callerid to see what node this comes from */ 10874 if (!chan->cid.cid_num) /* if doesn't have caller id */ 10875 { 10876 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 10877 return -1; 10878 } 10879 10880 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 10881 ast_shrink_phone_number(b1); 10882 if (!strcmp(myrpt->name,b1)) 10883 { 10884 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 10885 return -1; 10886 } 10887 rpt_mutex_lock(&myrpt->lock); 10888 l = myrpt->links.next; 10889 /* try to find this one in queue */ 10890 while(l != &myrpt->links) 10891 { 10892 if (l->name[0] == '0') 10893 { 10894 l = l->next; 10895 continue; 10896 } 10897 /* if found matching string */ 10898 if (!strcmp(l->name,b1)) break; 10899 l = l->next; 10900 } 10901 /* if found */ 10902 if (l != &myrpt->links) 10903 { 10904 l->killme = 1; 10905 l->retries = l->max_retries + 1; 10906 l->disced = 2; 10907 reconnects = l->reconnects; 10908 reconnects++; 10909 rpt_mutex_unlock(&myrpt->lock); 10910 usleep(500000); 10911 } else 10912 rpt_mutex_unlock(&myrpt->lock); 10913 /* establish call in tranceive mode */ 10914 l = malloc(sizeof(struct rpt_link)); 10915 if (!l) 10916 { 10917 ast_log(LOG_WARNING, "Unable to malloc\n"); 10918 pthread_exit(NULL); 10919 } 10920 /* zero the silly thing */ 10921 memset((char *)l,0,sizeof(struct rpt_link)); 10922 l->mode = 1; 10923 strncpy(l->name,b1,MAXNODESTR - 1); 10924 l->isremote = 0; 10925 l->chan = chan; 10926 l->connected = 1; 10927 l->thisconnected = 1; 10928 l->hasconnected = 1; 10929 l->reconnects = reconnects; 10930 l->phonemode = phone_mode; 10931 l->lastf1 = NULL; 10932 l->lastf2 = NULL; 10933 l->dtmfed = 0; 10934 ast_set_read_format(l->chan,AST_FORMAT_SLINEAR); 10935 ast_set_write_format(l->chan,AST_FORMAT_SLINEAR); 10936 /* allocate a pseudo-channel thru asterisk */ 10937 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 10938 if (!l->pchan) 10939 { 10940 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 10941 pthread_exit(NULL); 10942 } 10943 ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR); 10944 ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR); 10945 #ifdef AST_CDR_FLAG_POST_DISABLED 10946 ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED); 10947 #endif 10948 /* make a conference for the tx */ 10949 ci.chan = 0; 10950 ci.confno = myrpt->conf; 10951 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 10952 /* first put the channel on the conference in proper mode */ 10953 if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1) 10954 { 10955 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 10956 pthread_exit(NULL); 10957 } 10958 rpt_mutex_lock(&myrpt->lock); 10959 if (phone_mode > 1) l->lastrx = 1; 10960 l->max_retries = MAX_RETRIES; 10961 /* insert at end of queue */ 10962 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 10963 __kickshort(myrpt); 10964 rpt_mutex_unlock(&myrpt->lock); 10965 if (chan->_state != AST_STATE_UP) { 10966 ast_answer(chan); 10967 } 10968 if (myrpt->p.archivedir) 10969 { 10970 char str[100]; 10971 10972 if (l->phonemode) 10973 sprintf(str,"LINK(P),%s",l->name); 10974 else 10975 sprintf(str,"LINK,%s",l->name); 10976 donodelog(myrpt,str); 10977 } 10978 return AST_PBX_KEEPALIVE; 10979 } 10980 /* well, then it is a remote */ 10981 rpt_mutex_lock(&myrpt->lock); 10982 /* if remote, error if anyone else already linked */ 10983 if (myrpt->remoteon) 10984 { 10985 rpt_mutex_unlock(&myrpt->lock); 10986 usleep(500000); 10987 if (myrpt->remoteon) 10988 { 10989 ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp); 10990 return -1; 10991 } 10992 rpt_mutex_lock(&myrpt->lock); 10993 } 10994 if ((!strcmp(myrpt->remote, remote_rig_rbi)) && 10995 (ioperm(myrpt->p.iobase,1,1) == -1)) 10996 { 10997 rpt_mutex_unlock(&myrpt->lock); 10998 ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase); 10999 return -1; 11000 } 11001 myrpt->remoteon = 1; 11002 #ifdef OLD_ASTERISK 11003 LOCAL_USER_ADD(u); 11004 #endif 11005 rpt_mutex_unlock(&myrpt->lock); 11006 /* find our index, and load the vars initially */ 11007 for(i = 0; i < nrpts; i++) 11008 { 11009 if (&rpt_vars[i] == myrpt) 11010 { 11011 load_rpt_vars(i,0); 11012 break; 11013 } 11014 } 11015 rpt_mutex_lock(&myrpt->lock); 11016 tele = strchr(myrpt->rxchanname,'/'); 11017 if (!tele) 11018 { 11019 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 11020 rpt_mutex_unlock(&myrpt->lock); 11021 pthread_exit(NULL); 11022 } 11023 *tele++ = 0; 11024 myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL); 11025 myrpt->zaprxchannel = NULL; 11026 if (!strcasecmp(myrpt->rxchanname,"Zap")) 11027 myrpt->zaprxchannel = myrpt->rxchannel; 11028 if (myrpt->rxchannel) 11029 { 11030 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 11031 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 11032 #ifdef AST_CDR_FLAG_POST_DISABLED 11033 ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11034 #endif 11035 myrpt->rxchannel->whentohangup = 0; 11036 myrpt->rxchannel->appl = "Apprpt"; 11037 myrpt->rxchannel->data = "(Link Rx)"; 11038 if (option_verbose > 2) 11039 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 11040 myrpt->rxchanname,tele,myrpt->rxchannel->name); 11041 rpt_mutex_unlock(&myrpt->lock); 11042 ast_call(myrpt->rxchannel,tele,999); 11043 rpt_mutex_lock(&myrpt->lock); 11044 } 11045 else 11046 { 11047 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 11048 rpt_mutex_unlock(&myrpt->lock); 11049 pthread_exit(NULL); 11050 } 11051 *--tele = '/'; 11052 myrpt->zaptxchannel = NULL; 11053 if (myrpt->txchanname) 11054 { 11055 tele = strchr(myrpt->txchanname,'/'); 11056 if (!tele) 11057 { 11058 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 11059 rpt_mutex_unlock(&myrpt->lock); 11060 ast_hangup(myrpt->rxchannel); 11061 pthread_exit(NULL); 11062 } 11063 *tele++ = 0; 11064 myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL); 11065 if (!strcasecmp(myrpt->txchanname,"Zap")) 11066 myrpt->zaptxchannel = myrpt->txchannel; 11067 if (myrpt->txchannel) 11068 { 11069 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 11070 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 11071 #ifdef AST_CDR_FLAG_POST_DISABLED 11072 ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11073 #endif 11074 myrpt->txchannel->whentohangup = 0; 11075 myrpt->txchannel->appl = "Apprpt"; 11076 myrpt->txchannel->data = "(Link Tx)"; 11077 if (option_verbose > 2) 11078 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 11079 myrpt->txchanname,tele,myrpt->txchannel->name); 11080 rpt_mutex_unlock(&myrpt->lock); 11081 ast_call(myrpt->txchannel,tele,999); 11082 rpt_mutex_lock(&myrpt->lock); 11083 } 11084 else 11085 { 11086 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 11087 rpt_mutex_unlock(&myrpt->lock); 11088 ast_hangup(myrpt->rxchannel); 11089 pthread_exit(NULL); 11090 } 11091 *--tele = '/'; 11092 } 11093 else 11094 { 11095 myrpt->txchannel = myrpt->rxchannel; 11096 } 11097 /* allocate a pseudo-channel thru asterisk */ 11098 myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 11099 if (!myrpt->pchannel) 11100 { 11101 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 11102 rpt_mutex_unlock(&myrpt->lock); 11103 if (myrpt->txchannel != myrpt->rxchannel) 11104 ast_hangup(myrpt->txchannel); 11105 ast_hangup(myrpt->rxchannel); 11106 pthread_exit(NULL); 11107 } 11108 ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR); 11109 ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR); 11110 #ifdef AST_CDR_FLAG_POST_DISABLED 11111 ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11112 #endif 11113 if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel; 11114 if (!myrpt->zaptxchannel) myrpt->zaptxchannel = myrpt->pchannel; 11115 /* make a conference for the pseudo */ 11116 ci.chan = 0; 11117 ci.confno = -1; /* make a new conf */ 11118 ci.confmode = ZT_CONF_CONFANNMON ; 11119 /* first put the channel on the conference in announce/monitor mode */ 11120 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 11121 { 11122 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 11123 rpt_mutex_unlock(&myrpt->lock); 11124 ast_hangup(myrpt->pchannel); 11125 if (myrpt->txchannel != myrpt->rxchannel) 11126 ast_hangup(myrpt->txchannel); 11127 ast_hangup(myrpt->rxchannel); 11128 pthread_exit(NULL); 11129 } 11130 /* save pseudo channel conference number */ 11131 myrpt->conf = myrpt->txconf = ci.confno; 11132 /* if serial io port, open it */ 11133 myrpt->iofd = -1; 11134 if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt->p.ioport)) == -1)) 11135 { 11136 rpt_mutex_unlock(&myrpt->lock); 11137 ast_hangup(myrpt->pchannel); 11138 if (myrpt->txchannel != myrpt->rxchannel) 11139 ast_hangup(myrpt->txchannel); 11140 ast_hangup(myrpt->rxchannel); 11141 pthread_exit(NULL); 11142 } 11143 iskenwood_pci4 = 0; 11144 memset(&z,0,sizeof(z)); 11145 if ((myrpt->iofd < 1) && (myrpt->txchannel == myrpt->zaptxchannel)) 11146 { 11147 z.radpar = ZT_RADPAR_REMMODE; 11148 z.data = ZT_RADPAR_REM_NONE; 11149 res = ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z); 11150 /* if PCIRADIO and kenwood selected */ 11151 if ((!res) && (!strcmp(myrpt->remote,remote_rig_kenwood))) 11152 { 11153 z.radpar = ZT_RADPAR_UIOMODE; 11154 z.data = 1; 11155 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11156 { 11157 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11158 return -1; 11159 } 11160 z.radpar = ZT_RADPAR_UIODATA; 11161 z.data = 3; 11162 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11163 { 11164 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11165 return -1; 11166 } 11167 i = ZT_OFFHOOK; 11168 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i) == -1) 11169 { 11170 ast_log(LOG_ERROR,"Cannot set hook\n"); 11171 return -1; 11172 } 11173 iskenwood_pci4 = 1; 11174 } 11175 } 11176 if (myrpt->txchannel == myrpt->zaptxchannel) 11177 { 11178 i = ZT_ONHOOK; 11179 ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i); 11180 /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */ 11181 if ((myrpt->iofd < 1) && (!res) && 11182 (!strcmp(myrpt->remote,remote_rig_ft897) || 11183 (!strcmp(myrpt->remote,remote_rig_ic706)))) 11184 { 11185 z.radpar = ZT_RADPAR_UIOMODE; 11186 z.data = 1; 11187 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11188 { 11189 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11190 return -1; 11191 } 11192 z.radpar = ZT_RADPAR_UIODATA; 11193 z.data = 3; 11194 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11195 { 11196 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11197 return -1; 11198 } 11199 } 11200 } 11201 myrpt->remoterx = 0; 11202 myrpt->remotetx = 0; 11203 myrpt->retxtimer = 0; 11204 myrpt->rerxtimer = 0; 11205 myrpt->remoteon = 1; 11206 myrpt->dtmfidx = -1; 11207 myrpt->dtmfbuf[0] = 0; 11208 myrpt->dtmf_time_rem = 0; 11209 myrpt->hfscanmode = 0; 11210 myrpt->hfscanstatus = 0; 11211 if (myrpt->p.startupmacro) 11212 { 11213 snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro); 11214 } 11215 time(&myrpt->start_time); 11216 myrpt->last_activity_time = myrpt->start_time; 11217 last_timeout_warning = 0; 11218 myrpt->reload = 0; 11219 myrpt->tele.next = &myrpt->tele; 11220 myrpt->tele.prev = &myrpt->tele; 11221 rpt_mutex_unlock(&myrpt->lock); 11222 ast_set_write_format(chan, AST_FORMAT_SLINEAR); 11223 ast_set_read_format(chan, AST_FORMAT_SLINEAR); 11224 rem_rx = 0; 11225 remkeyed = 0; 11226 /* if we are on 2w loop and are a remote, turn EC on */ 11227 if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel)) 11228 { 11229 i = 128; 11230 ioctl(myrpt->zaprxchannel->fds[0],ZT_ECHOCANCEL,&i); 11231 } 11232 if (chan->_state != AST_STATE_UP) { 11233 ast_answer(chan); 11234 } 11235 11236 if (myrpt->rxchannel == myrpt->zaprxchannel) 11237 { 11238 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_GET_PARAMS,&par) != -1) 11239 { 11240 if (par.rxisoffhook) 11241 { 11242 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11243 myrpt->remoterx = 1; 11244 remkeyed = 1; 11245 } 11246 } 11247 } 11248 if (myrpt->p.archivedir) 11249 { 11250 char mycmd[100],mydate[100],*b,*b1; 11251 time_t myt; 11252 long blocksleft; 11253 11254 11255 mkdir(myrpt->p.archivedir,0600); 11256 sprintf(mycmd,"%s/%s",myrpt->p.archivedir,myrpt->name); 11257 mkdir(mycmd,0600); 11258 time(&myt); 11259 strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S", 11260 localtime(&myt)); 11261 sprintf(mycmd,"mixmonitor start %s %s/%s/%s.wav49 a",chan->name, 11262 myrpt->p.archivedir,myrpt->name,mydate); 11263 if (myrpt->p.monminblocks) 11264 { 11265 blocksleft = diskavail(myrpt); 11266 if (myrpt->p.remotetimeout) 11267 { 11268 blocksleft -= (myrpt->p.remotetimeout * 11269 MONITOR_DISK_BLOCKS_PER_MINUTE) / 60; 11270 } 11271 if (blocksleft >= myrpt->p.monminblocks) 11272 ast_cli_command(nullfd,mycmd); 11273 } else ast_cli_command(nullfd,mycmd); 11274 /* look at callerid to see what node this comes from */ 11275 if (!chan->cid.cid_num) /* if doesn't have caller id */ 11276 { 11277 b1 = "0"; 11278 } else { 11279 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 11280 ast_shrink_phone_number(b1); 11281 } 11282 sprintf(mycmd,"CONNECT,%s",b1); 11283 donodelog(myrpt,mycmd); 11284 } 11285 myrpt->loginuser[0] = 0; 11286 myrpt->loginlevel[0] = 0; 11287 myrpt->authtelltimer = 0; 11288 myrpt->authtimer = 0; 11289 authtold = 0; 11290 authreq = 0; 11291 if (myrpt->p.authlevel > 1) authreq = 1; 11292 setrem(myrpt); 11293 n = 0; 11294 dtmfed = 0; 11295 cs[n++] = chan; 11296 cs[n++] = myrpt->rxchannel; 11297 cs[n++] = myrpt->pchannel; 11298 if (myrpt->rxchannel != myrpt->txchannel) 11299 cs[n++] = myrpt->txchannel; 11300 /* start un-locked */ 11301 for(;;) 11302 { 11303 if (ast_check_hangup(chan)) break; 11304 if (ast_check_hangup(myrpt->rxchannel)) break; 11305 notremming = 0; 11306 setting = 0; 11307 reming = 0; 11308 telem = myrpt->tele.next; 11309 while(telem != &myrpt->tele) 11310 { 11311 if (telem->mode == SETREMOTE) setting = 1; 11312 if ((telem->mode == SETREMOTE) || 11313 (telem->mode == SCAN) || 11314 (telem->mode == TUNE)) reming = 1; 11315 else notremming = 1; 11316 telem = telem->next; 11317 } 11318 if (myrpt->reload) 11319 { 11320 myrpt->reload = 0; 11321 /* find our index, and load the vars */ 11322 for(i = 0; i < nrpts; i++) 11323 { 11324 if (&rpt_vars[i] == myrpt) 11325 { 11326 load_rpt_vars(i,0); 11327 break; 11328 } 11329 } 11330 } 11331 time(&t); 11332 if (myrpt->p.remotetimeout) 11333 { 11334 time_t r; 11335 11336 r = (t - myrpt->start_time); 11337 if (r >= myrpt->p.remotetimeout) 11338 { 11339 sayfile(chan,"rpt/node"); 11340 ast_say_character_str(chan,myrpt->name,NULL,chan->language); 11341 sayfile(chan,"rpt/timeout"); 11342 ast_safe_sleep(chan,1000); 11343 break; 11344 } 11345 if ((myrpt->p.remotetimeoutwarning) && 11346 (r >= (myrpt->p.remotetimeout - 11347 myrpt->p.remotetimeoutwarning)) && 11348 (r <= (myrpt->p.remotetimeout - 11349 myrpt->p.remotetimeoutwarningfreq))) 11350 { 11351 if (myrpt->p.remotetimeoutwarningfreq) 11352 { 11353 if ((t - last_timeout_warning) >= 11354 myrpt->p.remotetimeoutwarningfreq) 11355 { 11356 time(&last_timeout_warning); 11357 rpt_telemetry(myrpt,TIMEOUT_WARNING,0); 11358 } 11359 } 11360 else 11361 { 11362 if (!last_timeout_warning) 11363 { 11364 time(&last_timeout_warning); 11365 rpt_telemetry(myrpt,TIMEOUT_WARNING,0); 11366 } 11367 } 11368 } 11369 } 11370 if (myrpt->p.remoteinacttimeout && myrpt->last_activity_time) 11371 { 11372 time_t r; 11373 11374 r = (t - myrpt->last_activity_time); 11375 if (r >= myrpt->p.remoteinacttimeout) 11376 { 11377 sayfile(chan,"rpt/node"); 11378 ast_say_character_str(chan,myrpt->name,NULL,chan->language); 11379 sayfile(chan,"rpt/timeout"); 11380 ast_safe_sleep(chan,1000); 11381 break; 11382 } 11383 if ((myrpt->p.remotetimeoutwarning) && 11384 (r >= (myrpt->p.remoteinacttimeout - 11385 myrpt->p.remotetimeoutwarning)) && 11386 (r <= (myrpt->p.remoteinacttimeout - 11387 myrpt->p.remotetimeoutwarningfreq))) 11388 { 11389 if (myrpt->p.remotetimeoutwarningfreq) 11390 { 11391 if ((t - last_timeout_warning) >= 11392 myrpt->p.remotetimeoutwarningfreq) 11393 { 11394 time(&last_timeout_warning); 11395 rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0); 11396 } 11397 } 11398 else 11399 { 11400 if (!last_timeout_warning) 11401 { 11402 time(&last_timeout_warning); 11403 rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0); 11404 } 11405 } 11406 } 11407 } 11408 ms = MSWAIT; 11409 who = ast_waitfor_n(cs,n,&ms); 11410 if (who == NULL) ms = 0; 11411 elap = MSWAIT - ms; 11412 if (myrpt->macrotimer) myrpt->macrotimer -= elap; 11413 if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; 11414 if (!ms) continue; 11415 /* do local dtmf timer */ 11416 if (myrpt->dtmf_local_timer) 11417 { 11418 if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap; 11419 if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1; 11420 } 11421 rpt_mutex_lock(&myrpt->lock); 11422 do_dtmf_local(myrpt,0); 11423 rpt_mutex_unlock(&myrpt->lock); 11424 rem_totx = myrpt->dtmf_local_timer && (!phone_mode); 11425 rem_totx |= keyed && (!myrpt->tunerequest); 11426 rem_rx = (remkeyed && (!setting)) || (myrpt->tele.next != &myrpt->tele); 11427 if(!strcmp(myrpt->remote, remote_rig_ic706)) 11428 rem_totx |= myrpt->tunerequest; 11429 if (keyed && (!keyed1)) 11430 { 11431 keyed1 = 1; 11432 } 11433 11434 if (!keyed && (keyed1)) 11435 { 11436 time_t myt; 11437 11438 keyed1 = 0; 11439 time(&myt); 11440 /* if login necessary, and not too soon */ 11441 if ((myrpt->p.authlevel) && 11442 (!myrpt->loginlevel[0]) && 11443 (myt > (t + 3))) 11444 { 11445 authreq = 1; 11446 authtold = 0; 11447 myrpt->authtelltimer = AUTHTELLTIME - AUTHTXTIME; 11448 } 11449 } 11450 11451 11452 if (rem_rx && (!myrpt->remoterx)) 11453 { 11454 myrpt->remoterx = 1; 11455 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11456 } 11457 if ((!rem_rx) && (myrpt->remoterx)) 11458 { 11459 myrpt->remoterx = 0; 11460 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 11461 } 11462 /* if auth requested, and not authed yet */ 11463 if (authreq && (!myrpt->loginlevel[0])) 11464 { 11465 if ((!authtold) && ((myrpt->authtelltimer += elap) 11466 >= AUTHTELLTIME)) 11467 { 11468 authtold = 1; 11469 rpt_telemetry(myrpt,LOGINREQ,NULL); 11470 } 11471 if ((myrpt->authtimer += elap) >= AUTHLOGOUTTIME) 11472 { 11473 break; /* if not logged in, hang up after a time */ 11474 } 11475 } 11476 #ifndef OLDKEY 11477 if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME) 11478 { 11479 myrpt->retxtimer = 0; 11480 if ((myrpt->remoterx) && (!myrpt->remotetx)) 11481 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11482 else 11483 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 11484 } 11485 11486 if ((myrpt->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 2)) 11487 { 11488 keyed = 0; 11489 myrpt->rerxtimer = 0; 11490 } 11491 #endif 11492 if (rem_totx && (!myrpt->remotetx)) 11493 { 11494 /* if not authed, and needed, dont transmit */ 11495 if ((!myrpt->p.authlevel) || myrpt->loginlevel[0]) 11496 { 11497 myrpt->remotetx = 1; 11498 if((myrpt->remtxfreqok = check_tx_freq(myrpt))) 11499 { 11500 time(&myrpt->last_activity_time); 11501 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11502 { 11503 z.radpar = ZT_RADPAR_UIODATA; 11504 z.data = 1; 11505 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11506 { 11507 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11508 return -1; 11509 } 11510 } 11511 else 11512 { 11513 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 11514 } 11515 if (myrpt->p.archivedir) donodelog(myrpt,"TXKEY"); 11516 } 11517 } 11518 } 11519 if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */ 11520 { 11521 myrpt->remotetx = 0; 11522 if(!myrpt->remtxfreqok){ 11523 rpt_telemetry(myrpt,UNAUTHTX,NULL); 11524 } 11525 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11526 { 11527 z.radpar = ZT_RADPAR_UIODATA; 11528 z.data = 3; 11529 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11530 { 11531 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11532 return -1; 11533 } 11534 } 11535 else 11536 { 11537 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 11538 } 11539 if (myrpt->p.archivedir) donodelog(myrpt,"TXUNKEY"); 11540 } 11541 if (myrpt->hfscanmode){ 11542 myrpt->scantimer -= elap; 11543 if(myrpt->scantimer <= 0){ 11544 if (!reming) 11545 { 11546 myrpt->scantimer = REM_SCANTIME; 11547 rpt_telemetry(myrpt,SCAN,0); 11548 } else myrpt->scantimer = 1; 11549 } 11550 } 11551 rpt_mutex_lock(&myrpt->lock); 11552 c = myrpt->macrobuf[0]; 11553 if (c && (!myrpt->macrotimer)) 11554 { 11555 myrpt->macrotimer = MACROTIME; 11556 memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1); 11557 if ((c == 'p') || (c == 'P')) 11558 myrpt->macrotimer = MACROPTIME; 11559 rpt_mutex_unlock(&myrpt->lock); 11560 if (myrpt->p.archivedir) 11561 { 11562 char str[100]; 11563 sprintf(str,"DTMF(M),%c",c); 11564 donodelog(myrpt,str); 11565 } 11566 if (handle_remote_dtmf_digit(myrpt,c,&keyed,0) == -1) break; 11567 continue; 11568 } else rpt_mutex_unlock(&myrpt->lock); 11569 if (who == chan) /* if it was a read from incomming */ 11570 { 11571 f = ast_read(chan); 11572 if (!f) 11573 { 11574 if (debug) printf("@@@@ link:Hung Up\n"); 11575 break; 11576 } 11577 if (f->frametype == AST_FRAME_VOICE) 11578 { 11579 if (ioctl(chan->fds[0], ZT_GETCONFMUTE, &ismuted) == -1) 11580 { 11581 ismuted = 0; 11582 } 11583 /* if not transmitting, zero-out audio */ 11584 ismuted |= (!myrpt->remotetx); 11585 if (dtmfed && phone_mode) ismuted = 1; 11586 dtmfed = 0; 11587 if (ismuted) 11588 { 11589 memset(f->data,0,f->datalen); 11590 if (myrpt->lastf1) 11591 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11592 if (myrpt->lastf2) 11593 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11594 } 11595 if (f) f2 = ast_frdup(f); 11596 else f2 = NULL; 11597 f1 = myrpt->lastf2; 11598 myrpt->lastf2 = myrpt->lastf1; 11599 myrpt->lastf1 = f2; 11600 if (ismuted) 11601 { 11602 if (myrpt->lastf1) 11603 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11604 if (myrpt->lastf2) 11605 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11606 } 11607 if (f1) 11608 { 11609 if (phone_mode) 11610 ast_write(myrpt->txchannel,f1); 11611 else 11612 ast_write(myrpt->txchannel,f); 11613 ast_frfree(f1); 11614 } 11615 } 11616 #ifndef OLD_ASTERISK 11617 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 11618 { 11619 if (myrpt->lastf1) 11620 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11621 if (myrpt->lastf2) 11622 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11623 dtmfed = 1; 11624 } 11625 #endif 11626 if (f->frametype == AST_FRAME_DTMF) 11627 { 11628 if (myrpt->lastf1) 11629 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11630 if (myrpt->lastf2) 11631 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11632 dtmfed = 1; 11633 if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1) 11634 { 11635 if (debug) printf("@@@@ rpt:Hung Up\n"); 11636 ast_frfree(f); 11637 break; 11638 } 11639 } 11640 if (f->frametype == AST_FRAME_TEXT) 11641 { 11642 if (handle_remote_data(myrpt,f->data) == -1) 11643 { 11644 if (debug) printf("@@@@ rpt:Hung Up\n"); 11645 ast_frfree(f); 11646 break; 11647 } 11648 } 11649 if (f->frametype == AST_FRAME_CONTROL) 11650 { 11651 if (f->subclass == AST_CONTROL_HANGUP) 11652 { 11653 if (debug) printf("@@@@ rpt:Hung Up\n"); 11654 ast_frfree(f); 11655 break; 11656 } 11657 /* if RX key */ 11658 if (f->subclass == AST_CONTROL_RADIO_KEY) 11659 { 11660 if (debug == 7) printf("@@@@ rx key\n"); 11661 keyed = 1; 11662 myrpt->rerxtimer = 0; 11663 } 11664 /* if RX un-key */ 11665 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 11666 { 11667 myrpt->rerxtimer = 0; 11668 if (debug == 7) printf("@@@@ rx un-key\n"); 11669 keyed = 0; 11670 } 11671 } 11672 ast_frfree(f); 11673 continue; 11674 } 11675 if (who == myrpt->rxchannel) /* if it was a read from radio */ 11676 { 11677 f = ast_read(myrpt->rxchannel); 11678 if (!f) 11679 { 11680 if (debug) printf("@@@@ link:Hung Up\n"); 11681 break; 11682 } 11683 if (f->frametype == AST_FRAME_VOICE) 11684 { 11685 int myreming = 0; 11686 11687 if(!strcmp(myrpt->remote, remote_rig_kenwood)) 11688 myreming = reming; 11689 11690 if (myreming || (!remkeyed) || 11691 ((myrpt->remote) && (myrpt->remotetx)) || 11692 ((myrpt->remmode != REM_MODE_FM) && 11693 notremming)) 11694 memset(f->data,0,f->datalen); 11695 ast_write(myrpt->pchannel,f); 11696 } 11697 else if (f->frametype == AST_FRAME_CONTROL) 11698 { 11699 if (f->subclass == AST_CONTROL_HANGUP) 11700 { 11701 if (debug) printf("@@@@ rpt:Hung Up\n"); 11702 ast_frfree(f); 11703 break; 11704 } 11705 /* if RX key */ 11706 if (f->subclass == AST_CONTROL_RADIO_KEY) 11707 { 11708 if (debug == 7) printf("@@@@ remote rx key\n"); 11709 if (!myrpt->remotetx) 11710 { 11711 remkeyed = 1; 11712 } 11713 } 11714 /* if RX un-key */ 11715 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 11716 { 11717 if (debug == 7) printf("@@@@ remote rx un-key\n"); 11718 if (!myrpt->remotetx) 11719 { 11720 remkeyed = 0; 11721 } 11722 } 11723 } 11724 ast_frfree(f); 11725 continue; 11726 } 11727 if (who == myrpt->pchannel) /* if is remote mix output */ 11728 { 11729 f = ast_read(myrpt->pchannel); 11730 if (!f) 11731 { 11732 if (debug) printf("@@@@ link:Hung Up\n"); 11733 break; 11734 } 11735 if (f->frametype == AST_FRAME_VOICE) 11736 { 11737 ast_write(chan,f); 11738 } 11739 if (f->frametype == AST_FRAME_CONTROL) 11740 { 11741 if (f->subclass == AST_CONTROL_HANGUP) 11742 { 11743 if (debug) printf("@@@@ rpt:Hung Up\n"); 11744 ast_frfree(f); 11745 break; 11746 } 11747 } 11748 ast_frfree(f); 11749 continue; 11750 } 11751 if ((myrpt->rxchannel != myrpt->txchannel) && 11752 (who == myrpt->txchannel)) /* do this cuz you have to */ 11753 { 11754 f = ast_read(myrpt->txchannel); 11755 if (!f) 11756 { 11757 if (debug) printf("@@@@ link:Hung Up\n"); 11758 break; 11759 } 11760 if (f->frametype == AST_FRAME_CONTROL) 11761 { 11762 if (f->subclass == AST_CONTROL_HANGUP) 11763 { 11764 if (debug) printf("@@@@ rpt:Hung Up\n"); 11765 ast_frfree(f); 11766 break; 11767 } 11768 } 11769 ast_frfree(f); 11770 continue; 11771 } 11772 } 11773 if (myrpt->p.archivedir) 11774 { 11775 char mycmd[100],*b,*b1; 11776 11777 /* look at callerid to see what node this comes from */ 11778 if (!chan->cid.cid_num) /* if doesn't have caller id */ 11779 { 11780 b1 = "0"; 11781 } else { 11782 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 11783 ast_shrink_phone_number(b1); 11784 } 11785 sprintf(mycmd,"DISCONNECT,%s",b1); 11786 donodelog(myrpt,mycmd); 11787 } 11788 /* wait for telem to be done */ 11789 while(myrpt->tele.next != &myrpt->tele) usleep(100000); 11790 sprintf(tmp,"mixmonitor stop %s",chan->name); 11791 ast_cli_command(nullfd,tmp); 11792 close(nullfd); 11793 rpt_mutex_lock(&myrpt->lock); 11794 myrpt->hfscanmode = 0; 11795 myrpt->hfscanstatus = 0; 11796 myrpt->remoteon = 0; 11797 rpt_mutex_unlock(&myrpt->lock); 11798 if (myrpt->lastf1) ast_frfree(myrpt->lastf1); 11799 myrpt->lastf1 = NULL; 11800 if (myrpt->lastf2) ast_frfree(myrpt->lastf2); 11801 myrpt->lastf2 = NULL; 11802 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11803 { 11804 z.radpar = ZT_RADPAR_UIOMODE; 11805 z.data = 3; 11806 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11807 { 11808 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11809 return -1; 11810 } 11811 z.radpar = ZT_RADPAR_UIODATA; 11812 z.data = 3; 11813 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1) 11814 { 11815 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11816 return -1; 11817 } 11818 i = ZT_OFFHOOK; 11819 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_HOOK,&i) == -1) 11820 { 11821 ast_log(LOG_ERROR,"Cannot set hook\n"); 11822 return -1; 11823 } 11824 } 11825 if (myrpt->iofd) close(myrpt->iofd); 11826 myrpt->iofd = -1; 11827 ast_hangup(myrpt->pchannel); 11828 if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel); 11829 ast_hangup(myrpt->rxchannel); 11830 closerem(myrpt); 11831 #ifdef OLD_ASTERISK 11832 LOCAL_USER_REMOVE(u); 11833 #endif 11834 return res; 11835 }
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 10389 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, 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().
10390 { 10391 int i,n; 10392 pthread_attr_t attr; 10393 struct ast_config *cfg; 10394 char *this,*val; 10395 10396 /* init nodelog queue */ 10397 nodelog.next = nodelog.prev = &nodelog; 10398 /* go thru all the specified repeaters */ 10399 this = NULL; 10400 n = 0; 10401 /* wait until asterisk starts */ 10402 while(!ast_test_flag(&ast_options,AST_OPT_FLAG_FULLY_BOOTED)) 10403 usleep(250000); 10404 rpt_vars[n].cfg = ast_config_load("rpt.conf"); 10405 cfg = rpt_vars[n].cfg; 10406 if (!cfg) { 10407 ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); 10408 pthread_exit(NULL); 10409 } 10410 while((this = ast_category_browse(cfg,this)) != NULL) 10411 { 10412 for(i = 0 ; i < strlen(this) ; i++){ 10413 if((this[i] < '0') || (this[i] > '9')) 10414 break; 10415 } 10416 if(i != strlen(this)) continue; /* Not a node defn */ 10417 memset(&rpt_vars[n],0,sizeof(rpt_vars[n])); 10418 rpt_vars[n].name = strdup(this); 10419 val = (char *) ast_variable_retrieve(cfg,this,"rxchannel"); 10420 if (val) rpt_vars[n].rxchanname = strdup(val); 10421 val = (char *) ast_variable_retrieve(cfg,this,"txchannel"); 10422 if (val) rpt_vars[n].txchanname = strdup(val); 10423 val = (char *) ast_variable_retrieve(cfg,this,"remote"); 10424 if (val) rpt_vars[n].remote = strdup(val); 10425 ast_mutex_init(&rpt_vars[n].lock); 10426 ast_mutex_init(&rpt_vars[n].remlock); 10427 rpt_vars[n].tele.next = &rpt_vars[n].tele; 10428 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 10429 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 10430 rpt_vars[n].tailmessagen = 0; 10431 #ifdef _MDC_DECODE_H_ 10432 rpt_vars[n].mdc = mdc_decoder_new(8000); 10433 #endif 10434 n++; 10435 } 10436 nrpts = n; 10437 ast_config_destroy(cfg); 10438 10439 /* start em all */ 10440 for(i = 0; i < n; i++) 10441 { 10442 load_rpt_vars(i,1); 10443 10444 /* if is a remote, dont start one for it */ 10445 if (rpt_vars[i].remote) 10446 { 10447 if(retreive_memory(&rpt_vars[i],"init")){ /* Try to retreive initial memory channel */ 10448 strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1); 10449 strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1); 10450 10451 strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1); 10452 rpt_vars[i].remmode = REM_MODE_FM; 10453 rpt_vars[i].offset = REM_SIMPLEX; 10454 rpt_vars[i].powerlevel = REM_MEDPWR; 10455 } 10456 continue; 10457 } 10458 if (!rpt_vars[i].p.ident) 10459 { 10460 ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name); 10461 ast_config_destroy(cfg); 10462 pthread_exit(NULL); 10463 } 10464 pthread_attr_init(&attr); 10465 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10466 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 10467 } 10468 usleep(500000); 10469 time(&starttime); 10470 for(;;) 10471 { 10472 /* Now monitor each thread, and restart it if necessary */ 10473 for(i = 0; i < n; i++) 10474 { 10475 int rv; 10476 if (rpt_vars[i].remote) continue; 10477 if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP) 10478 rv = -1; 10479 else 10480 rv = pthread_kill(rpt_vars[i].rpt_thread,0); 10481 if (rv) 10482 { 10483 if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15) 10484 { 10485 if(rpt_vars[i].threadrestarts >= 5) 10486 { 10487 ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n"); 10488 exit(1); /* Stuck in a restart loop, kill Asterisk and start over */ 10489 } 10490 else 10491 { 10492 ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name); 10493 rpt_vars[i].threadrestarts++; 10494 } 10495 } 10496 else 10497 rpt_vars[i].threadrestarts = 0; 10498 10499 rpt_vars[i].lastthreadrestarttime = time(NULL); 10500 pthread_attr_init(&attr); 10501 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10502 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 10503 ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name); 10504 } 10505 10506 } 10507 for(;;) 10508 { 10509 struct nodelog *nodep; 10510 char *space,datestr[100],fname[300]; 10511 int fd; 10512 10513 ast_mutex_lock(&nodeloglock); 10514 nodep = nodelog.next; 10515 if(nodep == &nodelog) /* if nothing in queue */ 10516 { 10517 ast_mutex_unlock(&nodeloglock); 10518 break; 10519 } 10520 remque((struct qelem *)nodep); 10521 ast_mutex_unlock(&nodeloglock); 10522 space = strchr(nodep->str,' '); 10523 if (!space) 10524 { 10525 free(nodep); 10526 continue; 10527 } 10528 *space = 0; 10529 strftime(datestr,sizeof(datestr) - 1,"%Y%m%d", 10530 localtime(&nodep->timestamp)); 10531 sprintf(fname,"%s/%s/%s.txt",nodep->archivedir, 10532 nodep->str,datestr); 10533 fd = open(fname,O_WRONLY | O_CREAT | O_APPEND,0600); 10534 if (fd == -1) 10535 { 10536 ast_log(LOG_ERROR,"Cannot open node log file %s for write",space + 1); 10537 free(nodep); 10538 continue; 10539 } 10540 if (write(fd,space + 1,strlen(space + 1)) != 10541 strlen(space + 1)) 10542 { 10543 ast_log(LOG_ERROR,"Cannot write node log file %s for write",space + 1); 10544 free(nodep); 10545 continue; 10546 } 10547 close(fd); 10548 free(nodep); 10549 } 10550 usleep(2000000); 10551 } 10552 ast_config_destroy(cfg); 10553 pthread_exit(NULL); 10554 }
static void* rpt_tele_thread | ( | void * | this | ) | [static] |
Definition at line 2906 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, 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, t, TAILMSG, telem_any(), telem_lookup(), TERM, TEST_TONE, rpt_link::thisconnected, TIMEOUT, TIMEOUT_WARNING, TUNE, UNAUTHTX, UNKEY, and wait_interval().
Referenced by rpt_telemetry().
02907 { 02908 ZT_CONFINFO ci; /* conference info */ 02909 int res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x; 02910 struct rpt_tele *mytele = (struct rpt_tele *)this; 02911 struct rpt_tele *tlist; 02912 struct rpt *myrpt; 02913 struct rpt_link *l,*l1,linkbase; 02914 struct ast_channel *mychannel; 02915 int vmajor, vminor, m; 02916 char *p,*ct,*ct_copy,*ident, *nodename,*cp; 02917 time_t t; 02918 struct tm localtm; 02919 char lbuf[MAXLINKLIST],*strs[MAXLINKLIST]; 02920 int i,ns,rbimode; 02921 char mhz[MAXREMSTR]; 02922 char decimals[MAXREMSTR]; 02923 struct zt_params par; 02924 02925 02926 /* get a pointer to myrpt */ 02927 myrpt = mytele->rpt; 02928 02929 /* Snag copies of a few key myrpt variables */ 02930 rpt_mutex_lock(&myrpt->lock); 02931 nodename = ast_strdupa(myrpt->name); 02932 if (myrpt->p.ident) ident = ast_strdupa(myrpt->p.ident); 02933 else ident = ""; 02934 rpt_mutex_unlock(&myrpt->lock); 02935 02936 /* allocate a pseudo-channel thru asterisk */ 02937 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 02938 if (!mychannel) 02939 { 02940 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 02941 rpt_mutex_lock(&myrpt->lock); 02942 remque((struct qelem *)mytele); 02943 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02944 rpt_mutex_unlock(&myrpt->lock); 02945 free(mytele); 02946 pthread_exit(NULL); 02947 } 02948 #ifdef AST_CDR_FLAG_POST_DISABLED 02949 ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED); 02950 #endif 02951 rpt_mutex_lock(&myrpt->lock); 02952 mytele->chan = mychannel; 02953 rpt_mutex_unlock(&myrpt->lock); 02954 /* make a conference for the tx */ 02955 ci.chan = 0; 02956 /* If there's an ID queued, or tail message queued, */ 02957 /* only connect the ID audio to the local tx conference so */ 02958 /* linked systems can't hear it */ 02959 ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) || 02960 (mytele->mode == TAILMSG) || (mytele->mode == LINKUNKEY)) || (mytele->mode == TIMEOUT) ? 02961 myrpt->txconf : myrpt->conf); 02962 ci.confmode = ZT_CONF_CONFANN; 02963 /* first put the channel on the conference in announce mode */ 02964 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 02965 { 02966 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02967 rpt_mutex_lock(&myrpt->lock); 02968 remque((struct qelem *)mytele); 02969 rpt_mutex_unlock(&myrpt->lock); 02970 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02971 free(mytele); 02972 ast_hangup(mychannel); 02973 pthread_exit(NULL); 02974 } 02975 ast_stopstream(mychannel); 02976 switch(mytele->mode) 02977 { 02978 case ID: 02979 case ID1: 02980 /* wait a bit */ 02981 wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel); 02982 res = telem_any(myrpt,mychannel, ident); 02983 imdone=1; 02984 break; 02985 02986 case TAILMSG: 02987 res = ast_streamfile(mychannel, myrpt->p.tailmessages[myrpt->tailmessagen], mychannel->language); 02988 break; 02989 02990 case IDTALKOVER: 02991 p = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "idtalkover"); 02992 if(p) 02993 res = telem_any(myrpt,mychannel, p); 02994 imdone=1; 02995 break; 02996 02997 case PROC: 02998 /* wait a little bit longer */ 02999 wait_interval(myrpt, DLY_TELEM, mychannel); 03000 res = telem_lookup(myrpt, mychannel, myrpt->name, "patchup"); 03001 if(res < 0){ /* Then default message */ 03002 res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language); 03003 } 03004 break; 03005 case TERM: 03006 /* wait a little bit longer */ 03007 wait_interval(myrpt, DLY_CALLTERM, mychannel); 03008 res = telem_lookup(myrpt, mychannel, myrpt->name, "patchdown"); 03009 if(res < 0){ /* Then default message */ 03010 res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language); 03011 } 03012 break; 03013 case COMPLETE: 03014 /* wait a little bit */ 03015 wait_interval(myrpt, DLY_TELEM, mychannel); 03016 res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03017 break; 03018 case MACRO_NOTFOUND: 03019 /* wait a little bit */ 03020 wait_interval(myrpt, DLY_TELEM, mychannel); 03021 res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language); 03022 break; 03023 case MACRO_BUSY: 03024 /* wait a little bit */ 03025 wait_interval(myrpt, DLY_TELEM, mychannel); 03026 res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language); 03027 break; 03028 case UNKEY: 03029 if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */ 03030 imdone = 1; 03031 break; 03032 } 03033 03034 /* 03035 * Reset the Unkey to CT timer 03036 */ 03037 03038 x = get_wait_interval(myrpt, DLY_UNKEY); 03039 rpt_mutex_lock(&myrpt->lock); 03040 myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */ 03041 rpt_mutex_unlock(&myrpt->lock); 03042 03043 /* 03044 * If there's one already queued, don't do another 03045 */ 03046 03047 tlist = myrpt->tele.next; 03048 unkeys_queued = 0; 03049 if (tlist != &myrpt->tele) 03050 { 03051 rpt_mutex_lock(&myrpt->lock); 03052 while(tlist != &myrpt->tele){ 03053 if (tlist->mode == UNKEY) unkeys_queued++; 03054 tlist = tlist->next; 03055 } 03056 rpt_mutex_unlock(&myrpt->lock); 03057 } 03058 if( unkeys_queued > 1){ 03059 imdone = 1; 03060 break; 03061 } 03062 03063 /* Wait for the telemetry timer to expire */ 03064 /* Periodically check the timer since it can be re-initialized above */ 03065 while(myrpt->unkeytocttimer) 03066 { 03067 int ctint; 03068 if(myrpt->unkeytocttimer > 100) 03069 ctint = 100; 03070 else 03071 ctint = myrpt->unkeytocttimer; 03072 ast_safe_sleep(mychannel, ctint); 03073 rpt_mutex_lock(&myrpt->lock); 03074 if(myrpt->unkeytocttimer < ctint) 03075 myrpt->unkeytocttimer = 0; 03076 else 03077 myrpt->unkeytocttimer -= ctint; 03078 rpt_mutex_unlock(&myrpt->lock); 03079 } 03080 03081 /* 03082 * Now, the carrier on the rptr rx should be gone. 03083 * If it re-appeared, then forget about sending the CT 03084 */ 03085 if(myrpt->keyed){ 03086 imdone = 1; 03087 break; 03088 } 03089 03090 rpt_mutex_lock(&myrpt->lock); /* Update the kerchunk counters */ 03091 myrpt->dailykerchunks++; 03092 myrpt->totalkerchunks++; 03093 rpt_mutex_unlock(&myrpt->lock); 03094 03095 haslink = 0; 03096 hastx = 0; 03097 hasremote = 0; 03098 l = myrpt->links.next; 03099 if (l != &myrpt->links) 03100 { 03101 rpt_mutex_lock(&myrpt->lock); 03102 while(l != &myrpt->links) 03103 { 03104 if (l->name[0] == '0') 03105 { 03106 l = l->next; 03107 continue; 03108 } 03109 haslink = 1; 03110 if (l->mode) { 03111 hastx++; 03112 if (l->isremote) hasremote++; 03113 } 03114 l = l->next; 03115 } 03116 rpt_mutex_unlock(&myrpt->lock); 03117 } 03118 if (haslink) 03119 { 03120 03121 res = telem_lookup(myrpt,mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx"); 03122 if(res) 03123 ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name); 03124 03125 03126 /* if in remote cmd mode, indicate it */ 03127 if (myrpt->cmdnode[0]) 03128 { 03129 ast_safe_sleep(mychannel,200); 03130 res = telem_lookup(myrpt,mychannel, myrpt->name, "cmdmode"); 03131 if(res) 03132 ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name); 03133 ast_stopstream(mychannel); 03134 } 03135 } 03136 else if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */ 03137 ct_copy = ast_strdupa(ct); 03138 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03139 if(res) 03140 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03141 } 03142 if (hasremote && (!myrpt->cmdnode[0])) 03143 { 03144 /* set for all to hear */ 03145 ci.chan = 0; 03146 ci.confno = myrpt->conf; 03147 ci.confmode = ZT_CONF_CONFANN; 03148 /* first put the channel on the conference in announce mode */ 03149 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 03150 { 03151 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 03152 rpt_mutex_lock(&myrpt->lock); 03153 remque((struct qelem *)mytele); 03154 rpt_mutex_unlock(&myrpt->lock); 03155 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03156 free(mytele); 03157 ast_hangup(mychannel); 03158 pthread_exit(NULL); 03159 } 03160 if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */ 03161 ast_safe_sleep(mychannel,200); 03162 ct_copy = ast_strdupa(ct); 03163 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03164 if(res) 03165 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03166 } 03167 } 03168 #if defined(_MDC_DECODE_H_) && defined(MDC_SAY_WHEN_DOING_CT) 03169 if (myrpt->lastunit) 03170 { 03171 char mystr[10]; 03172 03173 ast_safe_sleep(mychannel,200); 03174 /* set for all to hear */ 03175 ci.chan = 0; 03176 ci.confno = myrpt->txconf; 03177 ci.confmode = ZT_CONF_CONFANN; 03178 /* first put the channel on the conference in announce mode */ 03179 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 03180 { 03181 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 03182 rpt_mutex_lock(&myrpt->lock); 03183 remque((struct qelem *)mytele); 03184 rpt_mutex_unlock(&myrpt->lock); 03185 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03186 free(mytele); 03187 ast_hangup(mychannel); 03188 pthread_exit(NULL); 03189 } 03190 sprintf(mystr,"%04x",myrpt->lastunit); 03191 myrpt->lastunit = 0; 03192 ast_say_character_str(mychannel,mystr,NULL,mychannel->language); 03193 break; 03194 } 03195 #endif 03196 imdone = 1; 03197 break; 03198 case LINKUNKEY: 03199 if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */ 03200 imdone = 1; 03201 break; 03202 } 03203 03204 /* 03205 * Reset the Unkey to CT timer 03206 */ 03207 03208 x = get_wait_interval(myrpt, DLY_LINKUNKEY); 03209 mytele->mylink.linkunkeytocttimer = x; /* Must be protected as it is changed below */ 03210 03211 /* 03212 * If there's one already queued, don't do another 03213 */ 03214 03215 tlist = myrpt->tele.next; 03216 unkeys_queued = 0; 03217 if (tlist != &myrpt->tele) 03218 { 03219 rpt_mutex_lock(&myrpt->lock); 03220 while(tlist != &myrpt->tele){ 03221 if (tlist->mode == LINKUNKEY) unkeys_queued++; 03222 tlist = tlist->next; 03223 } 03224 rpt_mutex_unlock(&myrpt->lock); 03225 } 03226 if( unkeys_queued > 1){ 03227 imdone = 1; 03228 break; 03229 } 03230 03231 /* Wait for the telemetry timer to expire */ 03232 /* Periodically check the timer since it can be re-initialized above */ 03233 while(mytele->mylink.linkunkeytocttimer) 03234 { 03235 int ctint; 03236 if(mytele->mylink.linkunkeytocttimer > 100) 03237 ctint = 100; 03238 else 03239 ctint = mytele->mylink.linkunkeytocttimer; 03240 ast_safe_sleep(mychannel, ctint); 03241 rpt_mutex_lock(&myrpt->lock); 03242 if(mytele->mylink.linkunkeytocttimer < ctint) 03243 mytele->mylink.linkunkeytocttimer = 0; 03244 else 03245 mytele->mylink.linkunkeytocttimer -= ctint; 03246 rpt_mutex_unlock(&myrpt->lock); 03247 } 03248 03249 if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "linkunkeyct"))){ /* Unlinked Courtesy Tone */ 03250 ct_copy = ast_strdupa(ct); 03251 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03252 if(res) 03253 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03254 } 03255 imdone = 1; 03256 break; 03257 case REMDISC: 03258 /* wait a little bit */ 03259 wait_interval(myrpt, DLY_TELEM, mychannel); 03260 l = myrpt->links.next; 03261 haslink = 0; 03262 /* dont report if a link for this one still on system */ 03263 if (l != &myrpt->links) 03264 { 03265 rpt_mutex_lock(&myrpt->lock); 03266 while(l != &myrpt->links) 03267 { 03268 if (l->name[0] == '0') 03269 { 03270 l = l->next; 03271 continue; 03272 } 03273 if (!strcmp(l->name,mytele->mylink.name)) 03274 { 03275 haslink = 1; 03276 break; 03277 } 03278 l = l->next; 03279 } 03280 rpt_mutex_unlock(&myrpt->lock); 03281 } 03282 if (haslink) 03283 { 03284 imdone = 1; 03285 break; 03286 } 03287 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03288 if (!res) 03289 res = ast_waitstream(mychannel, ""); 03290 else 03291 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03292 ast_stopstream(mychannel); 03293 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03294 res = ast_streamfile(mychannel, ((mytele->mylink.hasconnected) ? 03295 "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language); 03296 break; 03297 case REMALREADY: 03298 /* wait a little bit */ 03299 wait_interval(myrpt, DLY_TELEM, mychannel); 03300 res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language); 03301 break; 03302 case REMNOTFOUND: 03303 /* wait a little bit */ 03304 wait_interval(myrpt, DLY_TELEM, mychannel); 03305 res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language); 03306 break; 03307 case REMGO: 03308 /* wait a little bit */ 03309 wait_interval(myrpt, DLY_TELEM, mychannel); 03310 res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language); 03311 break; 03312 case CONNECTED: 03313 /* wait a little bit */ 03314 wait_interval(myrpt, DLY_TELEM, mychannel); 03315 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03316 if (!res) 03317 res = ast_waitstream(mychannel, ""); 03318 else 03319 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03320 ast_stopstream(mychannel); 03321 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03322 res = ast_streamfile(mychannel, "rpt/connected", mychannel->language); 03323 if (!res) 03324 res = ast_waitstream(mychannel, ""); 03325 else 03326 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03327 ast_stopstream(mychannel); 03328 res = ast_streamfile(mychannel, "digits/2", mychannel->language); 03329 if (!res) 03330 res = ast_waitstream(mychannel, ""); 03331 else 03332 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03333 ast_stopstream(mychannel); 03334 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03335 if (!res) 03336 res = ast_waitstream(mychannel, ""); 03337 else 03338 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03339 ast_stopstream(mychannel); 03340 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03341 imdone = 1; 03342 break; 03343 case CONNFAIL: 03344 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03345 if (!res) 03346 res = ast_waitstream(mychannel, ""); 03347 else 03348 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03349 ast_stopstream(mychannel); 03350 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03351 res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language); 03352 break; 03353 case MEMNOTFOUND: 03354 /* wait a little bit */ 03355 wait_interval(myrpt, DLY_TELEM, mychannel); 03356 res = ast_streamfile(mychannel, "rpt/memory_notfound", mychannel->language); 03357 break; 03358 case SETREMOTE: 03359 ast_mutex_lock(&myrpt->remlock); 03360 res = 0; 03361 if(!strcmp(myrpt->remote, remote_rig_ft897)) 03362 { 03363 res = set_ft897(myrpt); 03364 } 03365 if(!strcmp(myrpt->remote, remote_rig_ic706)) 03366 { 03367 res = set_ic706(myrpt); 03368 } 03369 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 03370 { 03371 if (ioperm(myrpt->p.iobase,1,1) == -1) 03372 { 03373 rpt_mutex_unlock(&myrpt->lock); 03374 ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase); 03375 res = -1; 03376 } 03377 else res = setrbi(myrpt); 03378 } 03379 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) 03380 { 03381 res = setkenwood(myrpt); 03382 if (ast_safe_sleep(mychannel,200) == -1) 03383 { 03384 ast_mutex_unlock(&myrpt->remlock); 03385 res = -1; 03386 break; 03387 } 03388 i = ZT_FLUSH_EVENT; 03389 if (ioctl(myrpt->zaptxchannel->fds[0],ZT_FLUSH,&i) == -1) 03390 { 03391 ast_mutex_unlock(&myrpt->remlock); 03392 ast_log(LOG_ERROR,"Cant flush events"); 03393 res = -1; 03394 break; 03395 } 03396 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_GET_PARAMS,&par) == -1) 03397 { 03398 ast_mutex_unlock(&myrpt->remlock); 03399 ast_log(LOG_ERROR,"Cant get params"); 03400 res = -1; 03401 break; 03402 } 03403 myrpt->remoterx = 03404 (par.rxisoffhook || (myrpt->tele.next != &myrpt->tele)); 03405 } 03406 ast_mutex_unlock(&myrpt->remlock); 03407 if (!res) 03408 { 03409 imdone = 1; 03410 break; 03411 } 03412 /* fall thru to invalid freq */ 03413 case INVFREQ: 03414 /* wait a little bit */ 03415 wait_interval(myrpt, DLY_TELEM, mychannel); 03416 res = ast_streamfile(mychannel, "rpt/invalid-freq", mychannel->language); 03417 break; 03418 case REMMODE: 03419 cp = 0; 03420 wait_interval(myrpt, DLY_TELEM, mychannel); 03421 switch(myrpt->remmode) 03422 { 03423 case REM_MODE_FM: 03424 saycharstr(mychannel,"FM"); 03425 break; 03426 case REM_MODE_USB: 03427 saycharstr(mychannel,"USB"); 03428 break; 03429 case REM_MODE_LSB: 03430 saycharstr(mychannel,"LSB"); 03431 break; 03432 case REM_MODE_AM: 03433 saycharstr(mychannel,"AM"); 03434 break; 03435 } 03436 wait_interval(myrpt, DLY_COMP, mychannel); 03437 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03438 break; 03439 case LOGINREQ: 03440 wait_interval(myrpt, DLY_TELEM, mychannel); 03441 sayfile(mychannel,"rpt/login"); 03442 saycharstr(mychannel,myrpt->name); 03443 break; 03444 case REMLOGIN: 03445 wait_interval(myrpt, DLY_TELEM, mychannel); 03446 saycharstr(mychannel,myrpt->loginuser); 03447 sayfile(mychannel,"rpt/node"); 03448 saycharstr(mychannel,myrpt->name); 03449 wait_interval(myrpt, DLY_COMP, mychannel); 03450 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03451 break; 03452 case REMXXX: 03453 wait_interval(myrpt, DLY_TELEM, mychannel); 03454 res = 0; 03455 switch(mytele->submode) 03456 { 03457 case 100: /* RX PL Off */ 03458 sayfile(mychannel, "rpt/rxpl"); 03459 sayfile(mychannel, "rpt/off"); 03460 break; 03461 case 101: /* RX PL On */ 03462 sayfile(mychannel, "rpt/rxpl"); 03463 sayfile(mychannel, "rpt/on"); 03464 break; 03465 case 102: /* TX PL Off */ 03466 sayfile(mychannel, "rpt/txpl"); 03467 sayfile(mychannel, "rpt/off"); 03468 break; 03469 case 103: /* TX PL On */ 03470 sayfile(mychannel, "rpt/txpl"); 03471 sayfile(mychannel, "rpt/on"); 03472 break; 03473 case 104: /* Low Power */ 03474 sayfile(mychannel, "rpt/lopwr"); 03475 break; 03476 case 105: /* Medium Power */ 03477 sayfile(mychannel, "rpt/medpwr"); 03478 break; 03479 case 106: /* Hi Power */ 03480 sayfile(mychannel, "rpt/hipwr"); 03481 break; 03482 case 113: /* Scan down slow */ 03483 sayfile(mychannel,"rpt/down"); 03484 sayfile(mychannel, "rpt/slow"); 03485 break; 03486 case 114: /* Scan down quick */ 03487 sayfile(mychannel,"rpt/down"); 03488 sayfile(mychannel, "rpt/quick"); 03489 break; 03490 case 115: /* Scan down fast */ 03491 sayfile(mychannel,"rpt/down"); 03492 sayfile(mychannel, "rpt/fast"); 03493 break; 03494 case 116: /* Scan up slow */ 03495 sayfile(mychannel,"rpt/up"); 03496 sayfile(mychannel, "rpt/slow"); 03497 break; 03498 case 117: /* Scan up quick */ 03499 sayfile(mychannel,"rpt/up"); 03500 sayfile(mychannel, "rpt/quick"); 03501 break; 03502 case 118: /* Scan up fast */ 03503 sayfile(mychannel,"rpt/up"); 03504 sayfile(mychannel, "rpt/fast"); 03505 break; 03506 default: 03507 res = -1; 03508 } 03509 wait_interval(myrpt, DLY_COMP, mychannel); 03510 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03511 break; 03512 case SCAN: 03513 ast_mutex_lock(&myrpt->remlock); 03514 if (myrpt->hfscanstop) 03515 { 03516 myrpt->hfscanstatus = 0; 03517 myrpt->hfscanmode = 0; 03518 myrpt->hfscanstop = 0; 03519 mytele->mode = SCANSTAT; 03520 ast_mutex_unlock(&myrpt->remlock); 03521 if (ast_safe_sleep(mychannel,1000) == -1) break; 03522 sayfile(mychannel, "rpt/stop"); 03523 imdone = 1; 03524 break; 03525 } 03526 if (myrpt->hfscanstatus > -2) service_scan(myrpt); 03527 i = myrpt->hfscanstatus; 03528 myrpt->hfscanstatus = 0; 03529 if (i) mytele->mode = SCANSTAT; 03530 ast_mutex_unlock(&myrpt->remlock); 03531 if (i < 0) sayfile(mychannel, "rpt/stop"); 03532 else if (i > 0) saynum(mychannel,i); 03533 imdone = 1; 03534 break; 03535 case TUNE: 03536 ast_mutex_lock(&myrpt->remlock); 03537 if (!strcmp(myrpt->remote,remote_rig_ic706)) 03538 { 03539 set_mode_ic706(myrpt, REM_MODE_AM); 03540 if(play_tone(mychannel, 800, 6000, 8192) == -1) break; 03541 ast_safe_sleep(mychannel,500); 03542 set_mode_ic706(myrpt, myrpt->remmode); 03543 myrpt->tunerequest = 0; 03544 ast_mutex_unlock(&myrpt->remlock); 03545 imdone = 1; 03546 break; 03547 } 03548 set_mode_ft897(myrpt, REM_MODE_AM); 03549 simple_command_ft897(myrpt, 8); 03550 if(play_tone(mychannel, 800, 6000, 8192) == -1) break; 03551 simple_command_ft897(myrpt, 0x88); 03552 ast_safe_sleep(mychannel,500); 03553 set_mode_ft897(myrpt, myrpt->remmode); 03554 myrpt->tunerequest = 0; 03555 ast_mutex_unlock(&myrpt->remlock); 03556 imdone = 1; 03557 break; 03558 case REMSHORTSTATUS: 03559 case REMLONGSTATUS: 03560 wait_interval(myrpt, DLY_TELEM, mychannel); 03561 res = sayfile(mychannel,"rpt/node"); 03562 if(!res) 03563 res = saycharstr(mychannel, myrpt->name); 03564 if(!res) 03565 res = sayfile(mychannel,"rpt/frequency"); 03566 if(!res) 03567 res = split_freq(mhz, decimals, myrpt->freq); 03568 if (!multimode_capable(myrpt)) decimals[3] = 0; 03569 if(!res){ 03570 m = atoi(mhz); 03571 if(m < 100) 03572 res = saynum(mychannel, m); 03573 else 03574 res = saycharstr(mychannel, mhz); 03575 } 03576 if(!res) 03577 res = sayfile(mychannel, "letters/dot"); 03578 if(!res) 03579 res = saycharstr(mychannel, decimals); 03580 03581 if(res) break; 03582 if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */ 03583 switch(myrpt->offset){ 03584 03585 case REM_MINUS: 03586 res = sayfile(mychannel,"rpt/minus"); 03587 break; 03588 03589 case REM_SIMPLEX: 03590 res = sayfile(mychannel,"rpt/simplex"); 03591 break; 03592 03593 case REM_PLUS: 03594 res = sayfile(mychannel,"rpt/plus"); 03595 break; 03596 03597 default: 03598 break; 03599 } 03600 } 03601 else{ /* Must be USB, LSB, or AM */ 03602 switch(myrpt->remmode){ 03603 03604 case REM_MODE_USB: 03605 res = saycharstr(mychannel, "USB"); 03606 break; 03607 03608 case REM_MODE_LSB: 03609 res = saycharstr(mychannel, "LSB"); 03610 break; 03611 03612 case REM_MODE_AM: 03613 res = saycharstr(mychannel, "AM"); 03614 break; 03615 03616 03617 default: 03618 break; 03619 } 03620 } 03621 03622 if (res == -1) break; 03623 03624 if(mytele->mode == REMSHORTSTATUS){ /* Short status? */ 03625 wait_interval(myrpt, DLY_COMP, mychannel); 03626 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03627 break; 03628 } 03629 03630 if (strcmp(myrpt->remote,remote_rig_ic706)) 03631 { 03632 switch(myrpt->powerlevel){ 03633 03634 case REM_LOWPWR: 03635 res = sayfile(mychannel,"rpt/lopwr") ; 03636 break; 03637 case REM_MEDPWR: 03638 res = sayfile(mychannel,"rpt/medpwr"); 03639 break; 03640 case REM_HIPWR: 03641 res = sayfile(mychannel,"rpt/hipwr"); 03642 break; 03643 } 03644 } 03645 03646 rbimode = ((!strncmp(myrpt->remote,remote_rig_rbi,3)) 03647 || (!strncmp(myrpt->remote,remote_rig_ic706,3))); 03648 if (res || (sayfile(mychannel,"rpt/rxpl") == -1)) break; 03649 if (rbimode && (sayfile(mychannel,"rpt/txpl") == -1)) break; 03650 if ((sayfile(mychannel,"rpt/frequency") == -1) || 03651 (saycharstr(mychannel,myrpt->rxpl) == -1)) break; 03652 if ((!rbimode) && ((sayfile(mychannel,"rpt/txpl") == -1) || 03653 (sayfile(mychannel,"rpt/frequency") == -1) || 03654 (saycharstr(mychannel,myrpt->txpl) == -1))) break; 03655 if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */ 03656 if ((sayfile(mychannel,"rpt/rxpl") == -1) || 03657 (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1) || 03658 (sayfile(mychannel,"rpt/txpl") == -1) || 03659 (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1)) 03660 { 03661 break; 03662 } 03663 } 03664 wait_interval(myrpt, DLY_COMP, mychannel); 03665 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03666 break; 03667 case STATUS: 03668 /* wait a little bit */ 03669 wait_interval(myrpt, DLY_TELEM, mychannel); 03670 hastx = 0; 03671 linkbase.next = &linkbase; 03672 linkbase.prev = &linkbase; 03673 rpt_mutex_lock(&myrpt->lock); 03674 /* make our own list of links */ 03675 l = myrpt->links.next; 03676 while(l != &myrpt->links) 03677 { 03678 if (l->name[0] == '0') 03679 { 03680 l = l->next; 03681 continue; 03682 } 03683 l1 = malloc(sizeof(struct rpt_link)); 03684 if (!l1) 03685 { 03686 ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name); 03687 remque((struct qelem *)mytele); 03688 rpt_mutex_unlock(&myrpt->lock); 03689 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03690 free(mytele); 03691 ast_hangup(mychannel); 03692 pthread_exit(NULL); 03693 } 03694 memcpy(l1,l,sizeof(struct rpt_link)); 03695 l1->next = l1->prev = NULL; 03696 insque((struct qelem *)l1,(struct qelem *)linkbase.next); 03697 l = l->next; 03698 } 03699 rpt_mutex_unlock(&myrpt->lock); 03700 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03701 if (!res) 03702 res = ast_waitstream(mychannel, ""); 03703 else 03704 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03705 ast_stopstream(mychannel); 03706 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03707 if (!res) 03708 res = ast_waitstream(mychannel, ""); 03709 else 03710 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03711 ast_stopstream(mychannel); 03712 if (myrpt->callmode) 03713 { 03714 hastx = 1; 03715 res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language); 03716 if (!res) 03717 res = ast_waitstream(mychannel, ""); 03718 else 03719 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03720 ast_stopstream(mychannel); 03721 } 03722 l = linkbase.next; 03723 while(l != &linkbase) 03724 { 03725 char *s; 03726 03727 hastx = 1; 03728 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03729 if (!res) 03730 res = ast_waitstream(mychannel, ""); 03731 else 03732 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03733 ast_stopstream(mychannel); 03734 ast_say_character_str(mychannel,l->name,NULL,mychannel->language); 03735 if (!res) 03736 res = ast_waitstream(mychannel, ""); 03737 else 03738 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03739 ast_stopstream(mychannel); 03740 s = "rpt/tranceive"; 03741 if (!l->mode) s = "rpt/monitor"; 03742 if (!l->thisconnected) s = "rpt/connecting"; 03743 res = ast_streamfile(mychannel, s, mychannel->language); 03744 if (!res) 03745 res = ast_waitstream(mychannel, ""); 03746 else 03747 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03748 ast_stopstream(mychannel); 03749 l = l->next; 03750 } 03751 if (!hastx) 03752 { 03753 res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language); 03754 if (!res) 03755 res = ast_waitstream(mychannel, ""); 03756 else 03757 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03758 ast_stopstream(mychannel); 03759 } 03760 /* destroy our local link queue */ 03761 l = linkbase.next; 03762 while(l != &linkbase) 03763 { 03764 l1 = l; 03765 l = l->next; 03766 remque((struct qelem *)l1); 03767 free(l1); 03768 } 03769 imdone = 1; 03770 break; 03771 case FULLSTATUS: 03772 rpt_mutex_lock(&myrpt->lock); 03773 /* get all the nodes */ 03774 __mklinklist(myrpt,NULL,lbuf); 03775 rpt_mutex_unlock(&myrpt->lock); 03776 /* parse em */ 03777 ns = finddelim(lbuf,strs,MAXLINKLIST); 03778 /* sort em */ 03779 if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar); 03780 /* wait a little bit */ 03781 wait_interval(myrpt, DLY_TELEM, mychannel); 03782 hastx = 0; 03783 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03784 if (!res) 03785 res = ast_waitstream(mychannel, ""); 03786 else 03787 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03788 ast_stopstream(mychannel); 03789 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03790 if (!res) 03791 res = ast_waitstream(mychannel, ""); 03792 else 03793 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03794 ast_stopstream(mychannel); 03795 if (myrpt->callmode) 03796 { 03797 hastx = 1; 03798 res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language); 03799 if (!res) 03800 res = ast_waitstream(mychannel, ""); 03801 else 03802 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03803 ast_stopstream(mychannel); 03804 } 03805 /* go thru all the nodes in list */ 03806 for(i = 0; i < ns; i++) 03807 { 03808 char *s,mode = 'T'; 03809 03810 /* if a mode spec at first, handle it */ 03811 if ((*strs[i] < '0') || (*strs[i] > '9')) 03812 { 03813 mode = *strs[i]; 03814 strs[i]++; 03815 } 03816 03817 hastx = 1; 03818 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03819 if (!res) 03820 res = ast_waitstream(mychannel, ""); 03821 else 03822 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03823 ast_stopstream(mychannel); 03824 ast_say_character_str(mychannel,strs[i],NULL,mychannel->language); 03825 if (!res) 03826 res = ast_waitstream(mychannel, ""); 03827 else 03828 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03829 ast_stopstream(mychannel); 03830 s = "rpt/tranceive"; 03831 if (mode == 'R') s = "rpt/monitor"; 03832 if (mode == 'C') s = "rpt/connecting"; 03833 res = ast_streamfile(mychannel, s, mychannel->language); 03834 if (!res) 03835 res = ast_waitstream(mychannel, ""); 03836 else 03837 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03838 ast_stopstream(mychannel); 03839 } 03840 if (!hastx) 03841 { 03842 res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language); 03843 if (!res) 03844 res = ast_waitstream(mychannel, ""); 03845 else 03846 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03847 ast_stopstream(mychannel); 03848 } 03849 imdone = 1; 03850 break; 03851 03852 case LASTNODEKEY: /* Identify last node which keyed us up */ 03853 rpt_mutex_lock(&myrpt->lock); 03854 if(myrpt->lastnodewhichkeyedusup) 03855 p = ast_strdupa(myrpt->lastnodewhichkeyedusup); /* Make a local copy of the node name */ 03856 else 03857 p = NULL; 03858 rpt_mutex_unlock(&myrpt->lock); 03859 if(!p){ 03860 imdone = 1; /* no node previously keyed us up, or the node which did has been disconnected */ 03861 break; 03862 } 03863 wait_interval(myrpt, DLY_TELEM, mychannel); 03864 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03865 if (!res) 03866 res = ast_waitstream(mychannel, ""); 03867 else 03868 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03869 ast_stopstream(mychannel); 03870 ast_say_character_str(mychannel, p, NULL, mychannel->language); 03871 if (!res) 03872 res = ast_waitstream(mychannel, ""); 03873 else 03874 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03875 ast_stopstream(mychannel); 03876 imdone = 1; 03877 break; 03878 03879 case UNAUTHTX: /* Say unauthorized transmit frequency */ 03880 wait_interval(myrpt, DLY_TELEM, mychannel); 03881 res = ast_streamfile(mychannel, "rpt/unauthtx", mychannel->language); 03882 if (!res) 03883 res = ast_waitstream(mychannel, ""); 03884 else 03885 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03886 ast_stopstream(mychannel); 03887 imdone = 1; 03888 break; 03889 03890 03891 case TIMEOUT: 03892 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03893 if (!res) 03894 res = ast_waitstream(mychannel, ""); 03895 else 03896 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03897 ast_stopstream(mychannel); 03898 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03899 res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language); 03900 break; 03901 03902 case TIMEOUT_WARNING: 03903 time(&t); 03904 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03905 if (!res) 03906 res = ast_waitstream(mychannel, ""); 03907 else 03908 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03909 ast_stopstream(mychannel); 03910 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03911 res = ast_streamfile(mychannel, "rpt/timeout-warning", mychannel->language); 03912 if (!res) 03913 res = ast_waitstream(mychannel, ""); 03914 else 03915 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03916 ast_stopstream(mychannel); 03917 if(!res) /* Say number of seconds */ 03918 ast_say_number(mychannel, myrpt->p.remotetimeout - 03919 (t - myrpt->last_activity_time), 03920 "", mychannel->language, (char *) NULL); 03921 if (!res) 03922 res = ast_waitstream(mychannel, ""); 03923 ast_stopstream(mychannel); 03924 res = ast_streamfile(mychannel, "queue-seconds", mychannel->language); 03925 break; 03926 03927 case ACT_TIMEOUT_WARNING: 03928 time(&t); 03929 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03930 if (!res) 03931 res = ast_waitstream(mychannel, ""); 03932 else 03933 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03934 ast_stopstream(mychannel); 03935 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03936 res = ast_streamfile(mychannel, "rpt/act-timeout-warning", mychannel->language); 03937 if (!res) 03938 res = ast_waitstream(mychannel, ""); 03939 else 03940 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03941 ast_stopstream(mychannel); 03942 if(!res) /* Say number of seconds */ 03943 ast_say_number(mychannel, myrpt->p.remoteinacttimeout - 03944 (t - myrpt->last_activity_time), 03945 "", mychannel->language, (char *) NULL); 03946 if (!res) 03947 res = ast_waitstream(mychannel, ""); 03948 ast_stopstream(mychannel); 03949 res = ast_streamfile(mychannel, "queue-seconds", mychannel->language); 03950 break; 03951 03952 case STATS_TIME: 03953 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 03954 t = time(NULL); 03955 rpt_localtime(&t, &localtm); 03956 /* Say the phase of the day is before the time */ 03957 if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12)) 03958 p = "rpt/goodmorning"; 03959 else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18)) 03960 p = "rpt/goodafternoon"; 03961 else 03962 p = "rpt/goodevening"; 03963 if (sayfile(mychannel,p) == -1) 03964 { 03965 imdone = 1; 03966 break; 03967 } 03968 /* Say the time is ... */ 03969 if (sayfile(mychannel,"rpt/thetimeis") == -1) 03970 { 03971 imdone = 1; 03972 break; 03973 } 03974 /* Say the time */ 03975 res = ast_say_time(mychannel, t, "", mychannel->language); 03976 if (!res) 03977 res = ast_waitstream(mychannel, ""); 03978 ast_stopstream(mychannel); 03979 imdone = 1; 03980 break; 03981 case STATS_VERSION: 03982 p = strstr(tdesc, "version"); 03983 if(!p) 03984 break; 03985 if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2) 03986 break; 03987 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 03988 /* Say "version" */ 03989 if (sayfile(mychannel,"rpt/version") == -1) 03990 { 03991 imdone = 1; 03992 break; 03993 } 03994 if(!res) /* Say "X" */ 03995 ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL); 03996 if (!res) 03997 res = ast_waitstream(mychannel, ""); 03998 ast_stopstream(mychannel); 03999 if (saycharstr(mychannel,".") == -1) 04000 { 04001 imdone = 1; 04002 break; 04003 } 04004 if(!res) /* Say "Y" */ 04005 ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL); 04006 if (!res){ 04007 res = ast_waitstream(mychannel, ""); 04008 ast_stopstream(mychannel); 04009 } 04010 else 04011 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 04012 imdone = 1; 04013 break; 04014 case ARB_ALPHA: 04015 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 04016 if(mytele->param) 04017 saycharstr(mychannel, mytele->param); 04018 imdone = 1; 04019 break; 04020 case REV_PATCH: 04021 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 04022 if(mytele->param) { 04023 04024 /* Parts of this section taken from app_parkandannounce */ 04025 char *tpl_working, *tpl_current; 04026 char *tmp[100], *myparm; 04027 int looptemp=0,i=0, dres = 0; 04028 04029 04030 tpl_working = strdupa(mytele->param); 04031 myparm = strsep(&tpl_working,","); 04032 tpl_current=strsep(&tpl_working, ":"); 04033 04034 while(tpl_current && looptemp < sizeof(tmp)) { 04035 tmp[looptemp]=tpl_current; 04036 looptemp++; 04037 tpl_current=strsep(&tpl_working,":"); 04038 } 04039 04040 for(i=0; i<looptemp; i++) { 04041 if(!strcmp(tmp[i], "PARKED")) { 04042 ast_say_digits(mychannel, atoi(myparm), "", mychannel->language); 04043 } else if(!strcmp(tmp[i], "NODE")) { 04044 ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language); 04045 } else { 04046 dres = ast_streamfile(mychannel, tmp[i], mychannel->language); 04047 if(!dres) { 04048 dres = ast_waitstream(mychannel, ""); 04049 } else { 04050 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name); 04051 dres = 0; 04052 } 04053 } 04054 } 04055 } 04056 imdone = 1; 04057 break; 04058 case TEST_TONE: 04059 imdone = 1; 04060 if (myrpt->stopgen) break; 04061 myrpt->stopgen = -1; 04062 if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0))) 04063 { 04064 myrpt->stopgen = 0; 04065 break; 04066 } 04067 while(mychannel->generatordata && (myrpt->stopgen <= 0)) { 04068 if (ast_safe_sleep(mychannel,1)) break; 04069 imdone = 1; 04070 } 04071 myrpt->stopgen = 0; 04072 break; 04073 default: 04074 break; 04075 } 04076 if (!imdone) 04077 { 04078 if (!res) 04079 res = ast_waitstream(mychannel, ""); 04080 else { 04081 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 04082 res = 0; 04083 } 04084 } 04085 ast_stopstream(mychannel); 04086 rpt_mutex_lock(&myrpt->lock); 04087 if (mytele->mode == TAILMSG) 04088 { 04089 if (!res) 04090 { 04091 myrpt->tailmessagen++; 04092 if(myrpt->tailmessagen >= myrpt->p.tailmessagemax) myrpt->tailmessagen = 0; 04093 } 04094 else 04095 { 04096 myrpt->tmsgtimer = myrpt->p.tailsquashedtime; 04097 } 04098 } 04099 remque((struct qelem *)mytele); 04100 rpt_mutex_unlock(&myrpt->lock); 04101 free(mytele); 04102 ast_hangup(mychannel); 04103 #ifdef APP_RPT_LOCK_DEBUG 04104 { 04105 struct lockthread *t; 04106 04107 sleep(5); 04108 ast_mutex_lock(&locklock); 04109 t = get_lockthread(pthread_self()); 04110 if (t) memset(t,0,sizeof(struct lockthread)); 04111 ast_mutex_unlock(&locklock); 04112 } 04113 #endif 04114 pthread_exit(NULL); 04115 }
static void rpt_telemetry | ( | struct rpt * | myrpt, | |
int | mode, | |||
void * | data | |||
) | [static] |
Definition at line 4117 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(), setrem(), and stop_scan().
04118 { 04119 struct rpt_tele *tele; 04120 struct rpt_link *mylink = (struct rpt_link *) data; 04121 int res; 04122 pthread_attr_t attr; 04123 04124 tele = malloc(sizeof(struct rpt_tele)); 04125 if (!tele) 04126 { 04127 ast_log(LOG_WARNING, "Unable to allocate memory\n"); 04128 pthread_exit(NULL); 04129 return; 04130 } 04131 /* zero it out */ 04132 memset((char *)tele,0,sizeof(struct rpt_tele)); 04133 tele->rpt = myrpt; 04134 tele->mode = mode; 04135 rpt_mutex_lock(&myrpt->lock); 04136 if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED) || 04137 (mode == LINKUNKEY)){ 04138 memset(&tele->mylink,0,sizeof(struct rpt_link)); 04139 if (mylink){ 04140 memcpy(&tele->mylink,mylink,sizeof(struct rpt_link)); 04141 } 04142 } 04143 else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) { 04144 strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1); 04145 tele->param[TELEPARAMSIZE - 1] = 0; 04146 } 04147 if (mode == REMXXX) tele->submode = (int) data; 04148 insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next); 04149 rpt_mutex_unlock(&myrpt->lock); 04150 pthread_attr_init(&attr); 04151 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04152 res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele); 04153 if(res < 0){ 04154 rpt_mutex_lock(&myrpt->lock); 04155 remque((struct qlem *) tele); /* We don't like stuck transmitters, remove it from the queue */ 04156 rpt_mutex_unlock(&myrpt->lock); 04157 ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res)); 04158 } 04159 return; 04160 }
static int saycharstr | ( | struct ast_channel * | mychannel, | |
char * | str | |||
) | [static] |
Definition at line 2690 of file app_rpt.c.
References ast_log(), ast_say_character_str(), ast_stopstream(), ast_waitstream(), and LOG_WARNING.
Referenced by rpt_tele_thread().
02691 { 02692 int res; 02693 02694 res = ast_say_character_str(mychannel,str,NULL,mychannel->language); 02695 if (!res) 02696 res = ast_waitstream(mychannel, ""); 02697 else 02698 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02699 ast_stopstream(mychannel); 02700 return res; 02701 }
static int sayfile | ( | struct ast_channel * | mychannel, | |
char * | fname | |||
) | [static] |
Definition at line 2677 of file app_rpt.c.
References ast_log(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and LOG_WARNING.
Referenced by rpt_tele_thread(), and telem_any().
02678 { 02679 int res; 02680 02681 res = ast_streamfile(mychannel, fname, mychannel->language); 02682 if (!res) 02683 res = ast_waitstream(mychannel, ""); 02684 else 02685 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02686 ast_stopstream(mychannel); 02687 return res; 02688 }
static int saynum | ( | struct ast_channel * | mychannel, | |
int | num | |||
) | [static] |
Definition at line 2703 of file app_rpt.c.
References ast_log(), ast_say_number(), ast_stopstream(), ast_waitstream(), and LOG_WARNING.
Referenced by rpt_tele_thread().
02704 { 02705 int res; 02706 res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL); 02707 if(!res) 02708 res = ast_waitstream(mychannel, ""); 02709 else 02710 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02711 ast_stopstream(mychannel); 02712 return res; 02713 }
static int select_mem_ic706 | ( | struct rpt * | myrpt, | |
int | slot | |||
) | [static] |
Definition at line 7202 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07203 { 07204 unsigned char cmdstr[10]; 07205 07206 cmdstr[0] = cmdstr[1] = 0xfe; 07207 cmdstr[2] = myrpt->p.civaddr; 07208 cmdstr[3] = 0xe0; 07209 cmdstr[4] = 8; 07210 cmdstr[5] = 0; 07211 cmdstr[6] = ((slot / 10) << 4) + (slot % 10); 07212 cmdstr[7] = 0xfd; 07213 07214 return(civ_cmd(myrpt,cmdstr,8)); 07215 }
static void send_link_dtmf | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 4414 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().
04415 { 04416 char str[300]; 04417 struct ast_frame wf; 04418 struct rpt_link *l; 04419 04420 snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c); 04421 wf.frametype = AST_FRAME_TEXT; 04422 wf.subclass = 0; 04423 wf.offset = 0; 04424 wf.mallocd = 0; 04425 wf.datalen = strlen(str) + 1; 04426 wf.samples = 0; 04427 l = myrpt->links.next; 04428 /* first, see if our dude is there */ 04429 while(l != &myrpt->links) 04430 { 04431 if (l->name[0] == '0') 04432 { 04433 l = l->next; 04434 continue; 04435 } 04436 /* if we found it, write it and were done */ 04437 if (!strcmp(l->name,myrpt->cmdnode)) 04438 { 04439 wf.data = str; 04440 if (l->chan) ast_write(l->chan,&wf); 04441 return; 04442 } 04443 l = l->next; 04444 } 04445 l = myrpt->links.next; 04446 /* if not, give it to everyone */ 04447 while(l != &myrpt->links) 04448 { 04449 wf.data = str; 04450 if (l->chan) ast_write(l->chan,&wf); 04451 l = l->next; 04452 } 04453 return; 04454 }
static int send_morse | ( | struct ast_channel * | chan, | |
char * | string, | |||
int | speed, | |||
int | freq, | |||
int | amplitude | |||
) | [static] |
Definition at line 2464 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().
02465 { 02466 02467 static struct morse_bits mbits[] = { 02468 {0, 0}, /* SPACE */ 02469 {0, 0}, 02470 {6, 18},/* " */ 02471 {0, 0}, 02472 {7, 72},/* $ */ 02473 {0, 0}, 02474 {0, 0}, 02475 {6, 30},/* ' */ 02476 {5, 13},/* ( */ 02477 {6, 29},/* ) */ 02478 {0, 0}, 02479 {5, 10},/* + */ 02480 {6, 51},/* , */ 02481 {6, 33},/* - */ 02482 {6, 42},/* . */ 02483 {5, 9}, /* / */ 02484 {5, 31},/* 0 */ 02485 {5, 30},/* 1 */ 02486 {5, 28},/* 2 */ 02487 {5, 24},/* 3 */ 02488 {5, 16},/* 4 */ 02489 {5, 0}, /* 5 */ 02490 {5, 1}, /* 6 */ 02491 {5, 3}, /* 7 */ 02492 {5, 7}, /* 8 */ 02493 {5, 15},/* 9 */ 02494 {6, 7}, /* : */ 02495 {6, 21},/* ; */ 02496 {0, 0}, 02497 {5, 33},/* = */ 02498 {0, 0}, 02499 {6, 12},/* ? */ 02500 {0, 0}, 02501 {2, 2}, /* A */ 02502 {4, 1}, /* B */ 02503 {4, 5}, /* C */ 02504 {3, 1}, /* D */ 02505 {1, 0}, /* E */ 02506 {4, 4}, /* F */ 02507 {3, 3}, /* G */ 02508 {4, 0}, /* H */ 02509 {2, 0}, /* I */ 02510 {4, 14},/* J */ 02511 {3, 5}, /* K */ 02512 {4, 2}, /* L */ 02513 {2, 3}, /* M */ 02514 {2, 1}, /* N */ 02515 {3, 7}, /* O */ 02516 {4, 6}, /* P */ 02517 {4, 11},/* Q */ 02518 {3, 2}, /* R */ 02519 {3, 0}, /* S */ 02520 {1, 1}, /* T */ 02521 {3, 4}, /* U */ 02522 {4, 8}, /* V */ 02523 {3, 6}, /* W */ 02524 {4, 9}, /* X */ 02525 {4, 13},/* Y */ 02526 {4, 3} /* Z */ 02527 }; 02528 02529 02530 int dottime; 02531 int dashtime; 02532 int intralettertime; 02533 int interlettertime; 02534 int interwordtime; 02535 int len, ddcomb; 02536 int res; 02537 int c; 02538 int i; 02539 int flags; 02540 02541 res = 0; 02542 02543 /* Approximate the dot time from the speed arg. */ 02544 02545 dottime = 900/speed; 02546 02547 /* Establish timing releationships */ 02548 02549 dashtime = 3 * dottime; 02550 intralettertime = dottime; 02551 interlettertime = dottime * 4 ; 02552 interwordtime = dottime * 7; 02553 02554 for(;(*string) && (!res); string++){ 02555 02556 c = *string; 02557 02558 /* Convert lower case to upper case */ 02559 02560 if((c >= 'a') && (c <= 'z')) 02561 c -= 0x20; 02562 02563 /* Can't deal with any char code greater than Z, skip it */ 02564 02565 if(c > 'Z') 02566 continue; 02567 02568 /* If space char, wait the inter word time */ 02569 02570 if(c == ' '){ 02571 if(!res) 02572 res = play_silence(chan, interwordtime); 02573 continue; 02574 } 02575 02576 /* Subtract out control char offset to match our table */ 02577 02578 c -= 0x20; 02579 02580 /* Get the character data */ 02581 02582 len = mbits[c].len; 02583 ddcomb = mbits[c].ddcomb; 02584 02585 /* Send the character */ 02586 02587 for(; len ; len--){ 02588 if(!res) 02589 res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude); 02590 if(!res) 02591 res = play_silence(chan, intralettertime); 02592 ddcomb >>= 1; 02593 } 02594 02595 /* Wait the interletter time */ 02596 02597 if(!res) 02598 res = play_silence(chan, interlettertime - intralettertime); 02599 } 02600 02601 /* Wait for all the frames to be sent */ 02602 02603 if (!res) 02604 res = ast_waitstream(chan, ""); 02605 ast_stopstream(chan); 02606 02607 /* 02608 * Wait for the zaptel driver to physically write the tone blocks to the hardware 02609 */ 02610 02611 for(i = 0; i < 20 ; i++){ 02612 flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT; 02613 res = ioctl(chan->fds[0], ZT_IOMUX, &flags); 02614 if(flags & ZT_IOMUX_WRITEEMPTY) 02615 break; 02616 if( ast_safe_sleep(chan, 50)){ 02617 res = -1; 02618 break; 02619 } 02620 } 02621 02622 02623 return res; 02624 }
static int send_tone_telemetry | ( | struct ast_channel * | chan, | |
char * | tonestring | |||
) | [static] |
Definition at line 2626 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().
02627 { 02628 char *stringp; 02629 char *tonesubset; 02630 int f1,f2; 02631 int duration; 02632 int amplitude; 02633 int res; 02634 int i; 02635 int flags; 02636 02637 res = 0; 02638 02639 stringp = ast_strdupa(tonestring); 02640 02641 for(;tonestring;){ 02642 tonesubset = strsep(&stringp,")"); 02643 if(!tonesubset) 02644 break; 02645 if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &litude) != 4) 02646 break; 02647 res = play_tone_pair(chan, f1, f2, duration, amplitude); 02648 if(res) 02649 break; 02650 } 02651 if(!res) 02652 res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */ 02653 02654 if (!res) 02655 res = ast_waitstream(chan, ""); 02656 ast_stopstream(chan); 02657 02658 /* 02659 * Wait for the zaptel driver to physically write the tone blocks to the hardware 02660 */ 02661 02662 for(i = 0; i < 20 ; i++){ 02663 flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT; 02664 res = ioctl(chan->fds[0], ZT_IOMUX, &flags); 02665 if(flags & ZT_IOMUX_WRITEEMPTY) 02666 break; 02667 if( ast_safe_sleep(chan, 50)){ 02668 res = -1; 02669 break; 02670 } 02671 } 02672 02673 return res; 02674 02675 }
static int sendkenwood | ( | struct rpt * | myrpt, | |
char * | txstr, | |||
char * | rxstr | |||
) | [static] |
Definition at line 5973 of file app_rpt.c.
References serial_remote_io().
Referenced by sendrxkenwood().
05974 { 05975 int i; 05976 05977 if (debug) printf("Send to kenwood: %s\n",txstr); 05978 i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr), 05979 (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3); 05980 if (i < 0) return -1; 05981 if ((i > 0) && (rxstr[i - 1] == '\r')) 05982 rxstr[i-- - 1] = 0; 05983 if (debug) printf("Got from kenwood: %s\n",rxstr); 05984 return(i); 05985 }
static int sendrxkenwood | ( | struct rpt * | myrpt, | |
char * | txstr, | |||
char * | rxstr, | |||
char * | cmpstr | |||
) | [static] |
Definition at line 6079 of file app_rpt.c.
References KENWOOD_RETRIES, and sendkenwood().
Referenced by setkenwood().
06081 { 06082 int i,j; 06083 06084 for(i = 0;i < KENWOOD_RETRIES;i++) 06085 { 06086 j = sendkenwood(myrpt,txstr,rxstr); 06087 if (j < 0) return(j); 06088 if (j == 0) continue; 06089 if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0); 06090 } 06091 return(-1); 06092 }
static int serial_remote_io | ( | struct rpt * | myrpt, | |
unsigned char * | txbuf, | |||
int | txbytes, | |||
unsigned char * | rxbuf, | |||
int | rxmaxbytes, | |||
int | asciiflag | |||
) | [static] |
Definition at line 5870 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().
05872 { 05873 int i,j,index,oldmode,olddata; 05874 struct zt_radio_param prm; 05875 char c; 05876 05877 if(debug){ 05878 printf("String output was: "); 05879 for(i = 0; i < txbytes; i++) 05880 printf("%02X ", (unsigned char ) txbuf[i]); 05881 printf("\n"); 05882 } 05883 if (myrpt->iofd > 0) /* if to do out a serial port */ 05884 { 05885 if (rxmaxbytes && rxbuf) tcflush(myrpt->iofd,TCIFLUSH); 05886 if (write(myrpt->iofd,txbuf,txbytes) != txbytes) return -1; 05887 if ((!rxmaxbytes) || (rxbuf == NULL)) return(0); 05888 memset(rxbuf,0,rxmaxbytes); 05889 for(i = 0; i < rxmaxbytes; i++) 05890 { 05891 j = read(myrpt->iofd,&c,1); 05892 if (j < 1) return(i); 05893 rxbuf[i] = c; 05894 if (asciiflag & 1) 05895 { 05896 rxbuf[i + 1] = 0; 05897 if (c == '\r') break; 05898 } 05899 } 05900 if(debug){ 05901 printf("String returned was: "); 05902 for(j = 0; j < i; j++) 05903 printf("%02X ", (unsigned char ) rxbuf[j]); 05904 printf("\n"); 05905 } 05906 return(i); 05907 } 05908 05909 /* if not a zap channel, cant use pciradio stuff */ 05910 if (myrpt->rxchannel != myrpt->zaprxchannel) return -1; 05911 05912 prm.radpar = ZT_RADPAR_UIOMODE; 05913 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1; 05914 oldmode = prm.data; 05915 prm.radpar = ZT_RADPAR_UIODATA; 05916 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1; 05917 olddata = prm.data; 05918 prm.radpar = ZT_RADPAR_REMMODE; 05919 if (asciiflag & 1) prm.data = ZT_RADPAR_REM_SERIAL_ASCII; 05920 else prm.data = ZT_RADPAR_REM_SERIAL; 05921 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05922 if (asciiflag & 2) 05923 { 05924 i = ZT_ONHOOK; 05925 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1; 05926 usleep(100000); 05927 } 05928 prm.radpar = ZT_RADPAR_REMCOMMAND; 05929 prm.data = rxmaxbytes; 05930 memcpy(prm.buf,txbuf,txbytes); 05931 prm.index = txbytes; 05932 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05933 if (rxbuf) 05934 { 05935 *rxbuf = 0; 05936 memcpy(rxbuf,prm.buf,prm.index); 05937 } 05938 index = prm.index; 05939 prm.radpar = ZT_RADPAR_REMMODE; 05940 prm.data = ZT_RADPAR_REM_NONE; 05941 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05942 if (asciiflag & 2) 05943 { 05944 i = ZT_OFFHOOK; 05945 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1; 05946 } 05947 prm.radpar = ZT_RADPAR_UIOMODE; 05948 prm.data = oldmode; 05949 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05950 prm.radpar = ZT_RADPAR_UIODATA; 05951 prm.data = olddata; 05952 if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 05953 return(index); 05954 }
static int service_scan | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7578 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().
07579 { 07580 int res, interval; 07581 char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0; 07582 07583 switch(myrpt->hfscanmode){ 07584 07585 case HF_SCAN_DOWN_SLOW: 07586 interval = -10; /* 100Hz /sec */ 07587 break; 07588 07589 case HF_SCAN_DOWN_QUICK: 07590 interval = -50; /* 500Hz /sec */ 07591 break; 07592 07593 case HF_SCAN_DOWN_FAST: 07594 interval = -200; /* 2KHz /sec */ 07595 break; 07596 07597 case HF_SCAN_UP_SLOW: 07598 interval = 10; /* 100Hz /sec */ 07599 break; 07600 07601 case HF_SCAN_UP_QUICK: 07602 interval = 50; /* 500 Hz/sec */ 07603 break; 07604 07605 case HF_SCAN_UP_FAST: 07606 interval = 200; /* 2KHz /sec */ 07607 break; 07608 07609 default: 07610 myrpt->hfscanmode = 0; /* Huh? */ 07611 return -1; 07612 } 07613 07614 res = split_freq(mhz, decimals, myrpt->freq); 07615 07616 if(!res){ 07617 k100 =decimals[0]; 07618 k10 = decimals[1]; 07619 res = multimode_bump_freq(myrpt, interval); 07620 } 07621 07622 if(!res) 07623 res = split_freq(mhz, decimals, myrpt->freq); 07624 07625 07626 if(res){ 07627 myrpt->hfscanmode = 0; 07628 myrpt->hfscanstatus = -2; 07629 return -1; 07630 } 07631 07632 /* Announce 10KHz boundaries */ 07633 if(k10 != decimals[1]){ 07634 int myhund = (interval < 0) ? k100 : decimals[0]; 07635 int myten = (interval < 0) ? k10 : decimals[1]; 07636 myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10; 07637 } else myrpt->hfscanstatus = 0; 07638 return res; 07639 07640 }
static int set_ctcss_freq_ft897 | ( | struct rpt * | myrpt, | |
char * | txtone, | |||
char * | rxtone | |||
) | [static] |
Definition at line 6638 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_ctcss_freq().
Referenced by set_ft897().
06639 { 06640 unsigned char cmdstr[5]; 06641 char hertz[MAXREMSTR],decimal[MAXREMSTR]; 06642 int h,d; 06643 06644 memset(cmdstr, 0, 5); 06645 06646 if(split_ctcss_freq(hertz, decimal, txtone)) 06647 return -1; 06648 06649 h = atoi(hertz); 06650 d = atoi(decimal); 06651 06652 cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10; 06653 cmdstr[1] = ((h % 10) << 4) + (d % 10); 06654 06655 if(rxtone){ 06656 06657 if(split_ctcss_freq(hertz, decimal, rxtone)) 06658 return -1; 06659 06660 h = atoi(hertz); 06661 d = atoi(decimal); 06662 06663 cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10; 06664 cmdstr[3] = ((h % 10) << 4) + (d % 10); 06665 } 06666 cmdstr[4] = 0x0B; 06667 06668 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06669 }
static int set_ctcss_mode_ft897 | ( | struct rpt * | myrpt, | |
char | txplon, | |||
char | rxplon | |||
) | [static] |
Definition at line 6615 of file app_rpt.c.
References serial_remote_io().
Referenced by set_ft897().
06616 { 06617 unsigned char cmdstr[5]; 06618 06619 memset(cmdstr, 0, 5); 06620 06621 if(rxplon && txplon) 06622 cmdstr[0] = 0x2A; /* Encode and Decode */ 06623 else if (!rxplon && txplon) 06624 cmdstr[0] = 0x4A; /* Encode only */ 06625 else if (rxplon && !txplon) 06626 cmdstr[0] = 0x3A; /* Encode only */ 06627 else 06628 cmdstr[0] = 0x8A; /* OFF */ 06629 06630 cmdstr[4] = 0x0A; 06631 06632 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06633 }
static int set_ctcss_mode_ic706 | ( | struct rpt * | myrpt, | |
char | txplon, | |||
char | rxplon | |||
) | [static] |
Definition at line 7100 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07101 { 07102 unsigned char cmdstr[10]; 07103 int rv; 07104 07105 cmdstr[0] = cmdstr[1] = 0xfe; 07106 cmdstr[2] = myrpt->p.civaddr; 07107 cmdstr[3] = 0xe0; 07108 cmdstr[4] = 0x16; 07109 cmdstr[5] = 0x42; 07110 cmdstr[6] = (txplon != 0); 07111 cmdstr[7] = 0xfd; 07112 07113 rv = civ_cmd(myrpt,cmdstr,8); 07114 if (rv) return(-1); 07115 07116 cmdstr[0] = cmdstr[1] = 0xfe; 07117 cmdstr[2] = myrpt->p.civaddr; 07118 cmdstr[3] = 0xe0; 07119 cmdstr[4] = 0x16; 07120 cmdstr[5] = 0x43; 07121 cmdstr[6] = (rxplon != 0); 07122 cmdstr[7] = 0xfd; 07123 07124 return(civ_cmd(myrpt,cmdstr,8)); 07125 }
static int set_freq_ft897 | ( | struct rpt * | myrpt, | |
char * | newfreq | |||
) | [static] |
Definition at line 6507 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_freq().
Referenced by multimode_bump_freq_ft897(), and set_ft897().
06508 { 06509 unsigned char cmdstr[5]; 06510 int fd,m,d; 06511 char mhz[MAXREMSTR]; 06512 char decimals[MAXREMSTR]; 06513 06514 fd = 0; 06515 if(debug) 06516 printf("New frequency: %s\n",newfreq); 06517 06518 if(split_freq(mhz, decimals, newfreq)) 06519 return -1; 06520 06521 m = atoi(mhz); 06522 d = atoi(decimals); 06523 06524 /* The FT-897 likes packed BCD frequencies */ 06525 06526 cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10); /* 100MHz 10Mhz */ 06527 cmdstr[1] = ((m % 10) << 4) + (d / 10000); /* 1MHz 100KHz */ 06528 cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100); /* 10KHz 1KHz */ 06529 cmdstr[3] = (((d % 100)/10) << 4) + (d % 10); /* 100Hz 10Hz */ 06530 cmdstr[4] = 0x01; /* command */ 06531 06532 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06533 06534 }
static int set_freq_ic706 | ( | struct rpt * | myrpt, | |
char * | newfreq | |||
) | [static] |
Definition at line 7010 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, MAXREMSTR, rpt::p, and split_freq().
Referenced by set_ic706().
07011 { 07012 unsigned char cmdstr[20]; 07013 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07014 int fd,m,d; 07015 07016 fd = 0; 07017 if(debug) 07018 printf("New frequency: %s\n",newfreq); 07019 07020 if(split_freq(mhz, decimals, newfreq)) 07021 return -1; 07022 07023 m = atoi(mhz); 07024 d = atoi(decimals); 07025 07026 /* The ic-706 likes packed BCD frequencies */ 07027 07028 cmdstr[0] = cmdstr[1] = 0xfe; 07029 cmdstr[2] = myrpt->p.civaddr; 07030 cmdstr[3] = 0xe0; 07031 cmdstr[4] = 5; 07032 cmdstr[5] = ((d % 10) << 4); 07033 cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10); 07034 cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000); 07035 cmdstr[8] = (((m % 100)/10) << 4) + (m % 10); 07036 cmdstr[9] = (m / 100); 07037 cmdstr[10] = 0xfd; 07038 07039 return(civ_cmd(myrpt,cmdstr,11)); 07040 }
static int set_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6673 of file app_rpt.c.
References REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, rpt::remmode, set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), and simple_command_ft897().
Referenced by rpt_tele_thread().
06674 { 06675 int res; 06676 06677 if(debug) 06678 printf("@@@@ lock on\n"); 06679 06680 res = simple_command_ft897(myrpt, 0x00); /* LOCK on */ 06681 06682 if(debug) 06683 printf("@@@@ ptt off\n"); 06684 06685 if(!res) 06686 res = simple_command_ft897(myrpt, 0x88); /* PTT off */ 06687 06688 if(debug) 06689 printf("Modulation mode\n"); 06690 06691 if(!res) 06692 res = set_mode_ft897(myrpt, myrpt->remmode); /* Modulation mode */ 06693 06694 if(debug) 06695 printf("Split off\n"); 06696 06697 if(!res) 06698 simple_command_ft897(myrpt, 0x82); /* Split off */ 06699 06700 if(debug) 06701 printf("Frequency\n"); 06702 06703 if(!res) 06704 res = set_freq_ft897(myrpt, myrpt->freq); /* Frequency */ 06705 if((myrpt->remmode == REM_MODE_FM)){ 06706 if(debug) 06707 printf("Offset\n"); 06708 if(!res) 06709 res = set_offset_ft897(myrpt, myrpt->offset); /* Offset if FM */ 06710 if((!res)&&(myrpt->rxplon || myrpt->txplon)){ 06711 if(debug) 06712 printf("CTCSS tone freqs.\n"); 06713 res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */ 06714 } 06715 if(!res){ 06716 if(debug) 06717 printf("CTCSS mode\n"); 06718 res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */ 06719 } 06720 } 06721 if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){ 06722 if(debug) 06723 printf("Clarifier off\n"); 06724 simple_command_ft897(myrpt, 0x85); /* Clarifier off if LSB or USB */ 06725 } 06726 return res; 06727 }
static int set_ic706 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7217 of file app_rpt.c.
References IC706_PL_MEMORY_OFFSET, ic706_pltocode(), mem2vfo_ic706(), REM_MODE_FM, rpt::remmode, rpt::rxpl, select_mem_ic706(), set_ctcss_mode_ic706(), set_freq_ic706(), set_mode_ic706(), set_offset_ic706(), simple_command_ic706(), and vfo_ic706().
Referenced by rpt_tele_thread().
07218 { 07219 int res = 0,i; 07220 07221 if(debug) 07222 printf("Set to VFO A\n"); 07223 07224 if (!res) 07225 res = simple_command_ic706(myrpt,7,0); 07226 07227 07228 if((myrpt->remmode == REM_MODE_FM)) 07229 { 07230 i = ic706_pltocode(myrpt->rxpl); 07231 if (i == -1) return -1; 07232 if(debug) 07233 printf("Select memory number\n"); 07234 if (!res) 07235 res = select_mem_ic706(myrpt,i + IC706_PL_MEMORY_OFFSET); 07236 if(debug) 07237 printf("Transfer memory to VFO\n"); 07238 if (!res) 07239 res = mem2vfo_ic706(myrpt); 07240 } 07241 07242 if(debug) 07243 printf("Set to VFO\n"); 07244 07245 if (!res) 07246 res = vfo_ic706(myrpt); 07247 07248 if(debug) 07249 printf("Modulation mode\n"); 07250 07251 if (!res) 07252 res = set_mode_ic706(myrpt, myrpt->remmode); /* Modulation mode */ 07253 07254 if(debug) 07255 printf("Split off\n"); 07256 07257 if(!res) 07258 simple_command_ic706(myrpt, 0x82,0); /* Split off */ 07259 07260 if(debug) 07261 printf("Frequency\n"); 07262 07263 if(!res) 07264 res = set_freq_ic706(myrpt, myrpt->freq); /* Frequency */ 07265 if((myrpt->remmode == REM_MODE_FM)){ 07266 if(debug) 07267 printf("Offset\n"); 07268 if(!res) 07269 res = set_offset_ic706(myrpt, myrpt->offset); /* Offset if FM */ 07270 if(!res){ 07271 if(debug) 07272 printf("CTCSS mode\n"); 07273 res = set_ctcss_mode_ic706(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */ 07274 } 07275 } 07276 return res; 07277 }
static int set_mode_ft897 | ( | struct rpt * | myrpt, | |
char | newmode | |||
) | [static] |
Definition at line 6582 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().
06583 { 06584 unsigned char cmdstr[5]; 06585 06586 memset(cmdstr, 0, 5); 06587 06588 switch(newmode){ 06589 case REM_MODE_FM: 06590 cmdstr[0] = 0x08; 06591 break; 06592 06593 case REM_MODE_USB: 06594 cmdstr[0] = 0x01; 06595 break; 06596 06597 case REM_MODE_LSB: 06598 cmdstr[0] = 0x00; 06599 break; 06600 06601 case REM_MODE_AM: 06602 cmdstr[0] = 0x04; 06603 break; 06604 06605 default: 06606 return -1; 06607 } 06608 cmdstr[4] = 0x07; 06609 06610 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06611 }
static int set_mode_ic706 | ( | struct rpt * | myrpt, | |
char | newmode | |||
) | [static] |
Definition at line 7071 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().
07072 { 07073 unsigned char c; 07074 07075 switch(newmode){ 07076 case REM_MODE_FM: 07077 c = 5; 07078 break; 07079 07080 case REM_MODE_USB: 07081 c = 1; 07082 break; 07083 07084 case REM_MODE_LSB: 07085 c = 0; 07086 break; 07087 07088 case REM_MODE_AM: 07089 c = 2; 07090 break; 07091 07092 default: 07093 return -1; 07094 } 07095 return simple_command_ic706(myrpt,6,c); 07096 }
static int set_offset_ft897 | ( | struct rpt * | myrpt, | |
char | offset | |||
) | [static] |
Definition at line 6552 of file app_rpt.c.
References REM_MINUS, REM_PLUS, REM_SIMPLEX, and serial_remote_io().
Referenced by set_ft897().
06553 { 06554 unsigned char cmdstr[5]; 06555 06556 memset(cmdstr, 0, 5); 06557 06558 switch(offset){ 06559 case REM_SIMPLEX: 06560 cmdstr[0] = 0x89; 06561 break; 06562 06563 case REM_MINUS: 06564 cmdstr[0] = 0x09; 06565 break; 06566 06567 case REM_PLUS: 06568 cmdstr[0] = 0x49; 06569 break; 06570 06571 default: 06572 return -1; 06573 } 06574 06575 cmdstr[4] = 0x09; 06576 06577 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06578 }
static int set_offset_ic706 | ( | struct rpt * | myrpt, | |
char | offset | |||
) | [static] |
Definition at line 7044 of file app_rpt.c.
References REM_MINUS, REM_PLUS, REM_SIMPLEX, and simple_command_ic706().
Referenced by set_ic706().
07045 { 07046 unsigned char c; 07047 07048 switch(offset){ 07049 case REM_SIMPLEX: 07050 c = 0x10; 07051 break; 07052 07053 case REM_MINUS: 07054 c = 0x11; 07055 break; 07056 07057 case REM_PLUS: 07058 c = 0x12; 07059 break; 07060 07061 default: 07062 return -1; 07063 } 07064 07065 return simple_command_ic706(myrpt,0x0f,c); 07066 07067 }
static int setkenwood | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6094 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().
06095 { 06096 char rxstr[RAD_SERIAL_BUFLEN],txstr[RAD_SERIAL_BUFLEN],freq[20]; 06097 char mhz[MAXREMSTR],offset[20],band,decimals[MAXREMSTR],band1,band2; 06098 06099 int offsets[] = {0,2,1}; 06100 int powers[] = {2,1,0}; 06101 06102 if (sendrxkenwood(myrpt,"VMC 0,0\r",rxstr,"VMC") < 0) return -1; 06103 split_freq(mhz, decimals, myrpt->freq); 06104 if (atoi(mhz) > 400) 06105 { 06106 band = '6'; 06107 band1 = '1'; 06108 band2 = '5'; 06109 strcpy(offset,"005000000"); 06110 } 06111 else 06112 { 06113 band = '2'; 06114 band1 = '0'; 06115 band2 = '2'; 06116 strcpy(offset,"000600000"); 06117 } 06118 strcpy(freq,"000000"); 06119 strncpy(freq,decimals,strlen(decimals)); 06120 sprintf(txstr,"VW %c,%05d%s,0,%d,0,%d,%d,,%02d,,%02d,%s\r", 06121 band,atoi(mhz),freq,offsets[(int)myrpt->offset], 06122 (myrpt->txplon != 0),(myrpt->rxplon != 0), 06123 kenwood_pltocode(myrpt->txpl),kenwood_pltocode(myrpt->rxpl), 06124 offset); 06125 if (sendrxkenwood(myrpt,txstr,rxstr,"VW") < 0) return -1; 06126 sprintf(txstr,"RBN %c\r",band2); 06127 if (sendrxkenwood(myrpt,txstr,rxstr,"RBN") < 0) return -1; 06128 sprintf(txstr,"PC %c,%d\r",band1,powers[(int)myrpt->powerlevel]); 06129 if (sendrxkenwood(myrpt,txstr,rxstr,"PC") < 0) return -1; 06130 return 0; 06131 }
static int setrbi | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6133 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().
06134 { 06135 char tmp[MAXREMSTR] = "",*s; 06136 unsigned char rbicmd[5]; 06137 int band,txoffset = 0,txpower = 0,rxpl; 06138 06139 /* must be a remote system */ 06140 if (!myrpt->remote) return(0); 06141 /* must have rbi hardware */ 06142 if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0); 06143 if (setrbi_check(myrpt) == -1) return(-1); 06144 strncpy(tmp, myrpt->freq, sizeof(tmp) - 1); 06145 s = strchr(tmp,'.'); 06146 /* if no decimal, is invalid */ 06147 06148 if (s == NULL){ 06149 if(debug) 06150 printf("@@@@ Frequency needs a decimal\n"); 06151 return -1; 06152 } 06153 06154 *s++ = 0; 06155 if (strlen(tmp) < 2){ 06156 if(debug) 06157 printf("@@@@ Bad MHz digits: %s\n", tmp); 06158 return -1; 06159 } 06160 06161 if (strlen(s) < 3){ 06162 if(debug) 06163 printf("@@@@ Bad KHz digits: %s\n", s); 06164 return -1; 06165 } 06166 06167 if ((s[2] != '0') && (s[2] != '5')){ 06168 if(debug) 06169 printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]); 06170 return -1; 06171 } 06172 06173 band = rbi_mhztoband(tmp); 06174 if (band == -1){ 06175 if(debug) 06176 printf("@@@@ Bad Band: %s\n", tmp); 06177 return -1; 06178 } 06179 06180 rxpl = rbi_pltocode(myrpt->rxpl); 06181 06182 if (rxpl == -1){ 06183 if(debug) 06184 printf("@@@@ Bad TX PL: %s\n", myrpt->rxpl); 06185 return -1; 06186 } 06187 06188 06189 switch(myrpt->offset) 06190 { 06191 case REM_MINUS: 06192 txoffset = 0; 06193 break; 06194 case REM_PLUS: 06195 txoffset = 0x10; 06196 break; 06197 case REM_SIMPLEX: 06198 txoffset = 0x20; 06199 break; 06200 } 06201 switch(myrpt->powerlevel) 06202 { 06203 case REM_LOWPWR: 06204 txpower = 0; 06205 break; 06206 case REM_MEDPWR: 06207 txpower = 0x20; 06208 break; 06209 case REM_HIPWR: 06210 txpower = 0x10; 06211 break; 06212 } 06213 rbicmd[0] = 0; 06214 rbicmd[1] = band | txpower | 0xc0; 06215 rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80; 06216 if (s[2] == '5') rbicmd[2] |= 0x40; 06217 rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0'); 06218 rbicmd[4] = rxpl; 06219 if (myrpt->txplon) rbicmd[4] |= 0x40; 06220 if (myrpt->rxplon) rbicmd[4] |= 0x80; 06221 rbi_out(myrpt,rbicmd); 06222 return 0; 06223 }
static int setrbi_check | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6225 of file app_rpt.c.
References rpt::freq, MAXREMSTR, rbi_mhztoband(), rbi_pltocode(), rpt::remote, s, and rpt::txpl.
Referenced by setrbi(), and setrem().
06226 { 06227 char tmp[MAXREMSTR] = "",*s; 06228 int band,txpl; 06229 06230 /* must be a remote system */ 06231 if (!myrpt->remote) return(0); 06232 /* must have rbi hardware */ 06233 if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0); 06234 strncpy(tmp, myrpt->freq, sizeof(tmp) - 1); 06235 s = strchr(tmp,'.'); 06236 /* if no decimal, is invalid */ 06237 06238 if (s == NULL){ 06239 if(debug) 06240 printf("@@@@ Frequency needs a decimal\n"); 06241 return -1; 06242 } 06243 06244 *s++ = 0; 06245 if (strlen(tmp) < 2){ 06246 if(debug) 06247 printf("@@@@ Bad MHz digits: %s\n", tmp); 06248 return -1; 06249 } 06250 06251 if (strlen(s) < 3){ 06252 if(debug) 06253 printf("@@@@ Bad KHz digits: %s\n", s); 06254 return -1; 06255 } 06256 06257 if ((s[2] != '0') && (s[2] != '5')){ 06258 if(debug) 06259 printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]); 06260 return -1; 06261 } 06262 06263 band = rbi_mhztoband(tmp); 06264 if (band == -1){ 06265 if(debug) 06266 printf("@@@@ Bad Band: %s\n", tmp); 06267 return -1; 06268 } 06269 06270 txpl = rbi_pltocode(myrpt->txpl); 06271 06272 if (txpl == -1){ 06273 if(debug) 06274 printf("@@@@ Bad TX PL: %s\n", myrpt->txpl); 06275 return -1; 06276 } 06277 return 0; 06278 }
static int setrem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7343 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().
07344 { 07345 char str[300]; 07346 char *offsets[] = {"MINUS","SIMPLEX","PLUS"}; 07347 char *powerlevels[] = {"LOW","MEDIUM","HIGH"}; 07348 char *modes[] = {"FM","USB","LSB","AM"}; 07349 int res = -1; 07350 07351 if (myrpt->p.archivedir) 07352 { 07353 sprintf(str,"FREQ,%s,%s,%s,%s,%s,%s,%d,%d",myrpt->freq, 07354 modes[(int)myrpt->remmode], 07355 myrpt->txpl,myrpt->rxpl,offsets[(int)myrpt->offset], 07356 powerlevels[(int)myrpt->powerlevel],myrpt->txplon, 07357 myrpt->rxplon); 07358 donodelog(myrpt,str); 07359 } 07360 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07361 { 07362 rpt_telemetry(myrpt,SETREMOTE,NULL); 07363 res = 0; 07364 } 07365 if(!strcmp(myrpt->remote, remote_rig_ic706)) 07366 { 07367 rpt_telemetry(myrpt,SETREMOTE,NULL); 07368 res = 0; 07369 } 07370 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 07371 { 07372 res = setrbi_check(myrpt); 07373 if (!res) 07374 { 07375 rpt_telemetry(myrpt,SETREMOTE,NULL); 07376 res = 0; 07377 } 07378 } 07379 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) { 07380 rpt_telemetry(myrpt,SETREMOTE,NULL); 07381 res = 0; 07382 } 07383 else 07384 res = 0; 07385 07386 if (res < 0) ast_log(LOG_ERROR,"Unable to send remote command on node %s\n",myrpt->name); 07387 07388 return res; 07389 }
static int simple_command_ft897 | ( | struct rpt * | myrpt, | |
char | command | |||
) | [static] |
Definition at line 6538 of file app_rpt.c.
References serial_remote_io().
Referenced by closerem_ft897(), rpt_tele_thread(), and set_ft897().
06539 { 06540 unsigned char cmdstr[5]; 06541 06542 memset(cmdstr, 0, 5); 06543 06544 cmdstr[4] = command; 06545 06546 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06547 06548 }
static int simple_command_ic706 | ( | struct rpt * | myrpt, | |
char | command, | |||
char | subcommand | |||
) | [static] |
Definition at line 6992 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706(), set_mode_ic706(), and set_offset_ic706().
06993 { 06994 unsigned char cmdstr[10]; 06995 06996 cmdstr[0] = cmdstr[1] = 0xfe; 06997 cmdstr[2] = myrpt->p.civaddr; 06998 cmdstr[3] = 0xe0; 06999 cmdstr[4] = command; 07000 cmdstr[5] = subcommand; 07001 cmdstr[6] = 0xfd; 07002 07003 return(civ_cmd(myrpt,cmdstr,7)); 07004 }
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 6391 of file app_rpt.c.
References MAXREMSTR.
Referenced by set_ctcss_freq_ft897().
06392 { 06393 char freq_copy[MAXREMSTR]; 06394 char *decp; 06395 06396 decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.'); 06397 if(decp){ 06398 *decp++ = 0; 06399 strncpy(hertz, freq_copy, MAXREMSTR); 06400 strncpy(decimal, decp, strlen(decp)); 06401 decimal[strlen(decp)] = '\0'; 06402 return 0; 06403 } 06404 else 06405 return -1; 06406 }
static int split_freq | ( | char * | mhz, | |
char * | decimals, | |||
char * | freq | |||
) | [static] |
Definition at line 6368 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().
06369 { 06370 char freq_copy[MAXREMSTR]; 06371 char *decp; 06372 06373 decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.'); 06374 if(decp){ 06375 *decp++ = 0; 06376 strncpy(mhz, freq_copy, MAXREMSTR); 06377 strcpy(decimals, "00000"); 06378 strncpy(decimals, decp, strlen(decp)); 06379 decimals[5] = 0; 06380 return 0; 06381 } 06382 else 06383 return -1; 06384 06385 }
static void stop_scan | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7567 of file app_rpt.c.
References rpt::hfscanstop, rpt_telemetry(), and SCAN.
Referenced by handle_remote_dtmf_digit().
07568 { 07569 myrpt->hfscanstop = 1; 07570 rpt_telemetry(myrpt,SCAN,0); 07571 }
static int telem_any | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
char * | entry | |||
) | [static] |
Definition at line 2716 of file app_rpt.c.
References MORSE, retrieve_astcfgint(), sayfile(), send_morse(), and send_tone_telemetry().
Referenced by rpt_tele_thread(), and telem_lookup().
02717 { 02718 int res; 02719 char c; 02720 02721 static int morsespeed; 02722 static int morsefreq; 02723 static int morseampl; 02724 static int morseidfreq = 0; 02725 static int morseidampl; 02726 static char mcat[] = MORSE; 02727 02728 res = 0; 02729 02730 if(!morseidfreq){ /* Get the morse parameters if not already loaded */ 02731 morsespeed = retrieve_astcfgint(myrpt, mcat, "speed", 5, 20, 20); 02732 morsefreq = retrieve_astcfgint(myrpt, mcat, "frequency", 300, 3000, 800); 02733 morseampl = retrieve_astcfgint(myrpt, mcat, "amplitude", 200, 8192, 4096); 02734 morseidampl = retrieve_astcfgint(myrpt, mcat, "idamplitude", 200, 8192, 2048); 02735 morseidfreq = retrieve_astcfgint(myrpt, mcat, "idfrequency", 300, 3000, 330); 02736 } 02737 02738 /* Is it a file, or a tone sequence? */ 02739 02740 if(entry[0] == '|'){ 02741 c = entry[1]; 02742 if((c >= 'a')&&(c <= 'z')) 02743 c -= 0x20; 02744 02745 switch(c){ 02746 case 'I': /* Morse ID */ 02747 res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl); 02748 break; 02749 02750 case 'M': /* Morse Message */ 02751 res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl); 02752 break; 02753 02754 case 'T': /* Tone sequence */ 02755 res = send_tone_telemetry(chan, entry + 2); 02756 break; 02757 default: 02758 res = -1; 02759 } 02760 } 02761 else 02762 res = sayfile(chan, entry); /* File */ 02763 return res; 02764 }
static int telem_lookup | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
char * | node, | |||
char * | name | |||
) | [static] |
Definition at line 2772 of file app_rpt.c.
References ast_log(), ast_strdupa, ast_variable_retrieve(), rpt::cfg, LOG_WARNING, tele_defs, telem_any(), and TELEMETRY.
Referenced by rpt_tele_thread().
02773 { 02774 02775 int res; 02776 int i; 02777 char *entry; 02778 char *telemetry; 02779 char *telemetry_save; 02780 02781 res = 0; 02782 telemetry_save = NULL; 02783 entry = NULL; 02784 02785 /* Retrieve the section name for telemetry from the node section */ 02786 telemetry = (char *) ast_variable_retrieve(myrpt->cfg, node, TELEMETRY); 02787 if(telemetry ){ 02788 telemetry_save = ast_strdupa(telemetry); 02789 if(!telemetry_save){ 02790 ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n"); 02791 return res; 02792 } 02793 entry = (char *) ast_variable_retrieve(myrpt->cfg, telemetry_save, name); 02794 } 02795 02796 /* Try to look up the telemetry name */ 02797 02798 if(!entry){ 02799 /* Telemetry name wasn't found in the config file, use the default */ 02800 for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){ 02801 if(!strcasecmp(tele_defs[i].name, name)) 02802 entry = tele_defs[i].value; 02803 } 02804 } 02805 if(entry){ 02806 if(strlen(entry)) 02807 telem_any(myrpt,chan, entry); 02808 } 02809 else{ 02810 res = -1; 02811 } 02812 return res; 02813 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11840 of file app_rpt.c.
References ast_cli_unregister(), ast_mutex_destroy(), ast_unregister_application(), cli_debug, cli_dump, cli_fun, cli_lstats, cli_nodes, cli_reload, cli_restart, cli_stats, lock, name, rpt::nodes, and rpt_vars.
11842 { 11843 int i; 11844 11845 #ifdef OLD_ASTERISK 11846 STANDARD_HANGUP_LOCALUSERS; 11847 #endif 11848 for(i = 0; i < nrpts; i++) { 11849 if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue; 11850 ast_mutex_destroy(&rpt_vars[i].lock); 11851 ast_mutex_destroy(&rpt_vars[i].remlock); 11852 } 11853 i = ast_unregister_application(app); 11854 11855 /* Unregister cli extensions */ 11856 ast_cli_unregister(&cli_debug); 11857 ast_cli_unregister(&cli_dump); 11858 ast_cli_unregister(&cli_stats); 11859 ast_cli_unregister(&cli_lstats); 11860 ast_cli_unregister(&cli_nodes); 11861 ast_cli_unregister(&cli_reload); 11862 ast_cli_unregister(&cli_restart); 11863 ast_cli_unregister(&cli_fun); 11864 11865 return i; 11866 }
static int vfo_ic706 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7176 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07177 { 07178 unsigned char cmdstr[10]; 07179 07180 cmdstr[0] = cmdstr[1] = 0xfe; 07181 cmdstr[2] = myrpt->p.civaddr; 07182 cmdstr[3] = 0xe0; 07183 cmdstr[4] = 7; 07184 cmdstr[5] = 0xfd; 07185 07186 return(civ_cmd(myrpt,cmdstr,6)); 07187 }
static void wait_interval | ( | struct rpt * | myrpt, | |
int | type, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 2891 of file app_rpt.c.
References ast_log(), ast_safe_sleep(), get_wait_interval(), and LOG_NOTICE.
Referenced by rpt_tele_thread().
02892 { 02893 int interval; 02894 interval = get_wait_interval(myrpt, type); 02895 if(debug) 02896 ast_log(LOG_NOTICE," Delay interval = %d\n", interval); 02897 if(interval) 02898 ast_safe_sleep(chan,interval); 02899 if(debug) 02900 ast_log(LOG_NOTICE,"Delay complete\n"); 02901 return; 02902 }
struct ast_cli_entry cli_debug [static] |
Initial value:
{ { "rpt", "debug", "level" }, rpt_do_debug, "Enable app_rpt debugging", debug_usage }
Definition at line 936 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_dump [static] |
Initial value:
{ { "rpt", "dump" }, rpt_do_dump, "Dump app_rpt structs for debugging", dump_usage }
Definition at line 940 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_fun [static] |
Initial value:
{ { "rpt", "fun" }, rpt_do_fun, "Execute a DTMF function", fun_usage }
Definition at line 964 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_lstats [static] |
Initial value:
{ { "rpt", "lstats" }, rpt_do_lstats, "Dump link statistics", dump_lstats }
Definition at line 952 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_nodes [static] |
Initial value:
{ { "rpt", "nodes" }, rpt_do_nodes, "Dump node list", dump_nodes }
Definition at line 948 of file app_rpt.c.
Referenced by load_module(), and unload_module().
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 }
Definition at line 960 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_stats [static] |
Initial value:
{ { "rpt", "stats" }, rpt_do_stats, "Dump node statistics", dump_stats }
Definition at line 944 of file app_rpt.c.
Referenced by load_module(), and unload_module().
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] |