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