#include "asterisk.h"
#include <signal.h>
#include <stdio.h>
#include <stdint.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 <netinet/in.h>
#include <arpa/inet.h>
#include <termios.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 "asterisk/dahdi_compat.h"
#include "asterisk/tonezone_compat.h"
Go to the source code of this file.
Data Structures | |
struct | function_table_tag |
struct | morse_bits |
struct | nodelog |
struct | rpt |
struct | rpt_chan_stat |
struct | rpt_link |
struct | rpt_lstat |
struct | rpt_tele |
struct | rpt_xlat |
struct | sysstate |
struct | telem_defaults |
Defines | |
#define | ACTIONSIZE 32 |
#define | ALLOW_LOCAL_CHANNELS |
#define | AUTHLOGOUTTIME 25000 |
#define | AUTHTELLTIME 7000 |
#define | AUTHTXTIME 1000 |
#define | DEFAULT_CIV_ADDR 0x58 |
#define | DEFAULT_IOBASE 0x378 |
#define | DEFAULT_MONITOR_MIN_DISK_BLOCKS 10000 |
#define | DEFAULT_REMOTE_INACT_TIMEOUT (15 * 60) |
#define | DEFAULT_REMOTE_TIMEOUT (60 * 60) |
#define | DEFAULT_REMOTE_TIMEOUT_WARNING (3 * 60) |
#define | DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ 30 |
#define | DELIMCHR ',' |
#define | DISC_TIME 10000 |
#define | DTMF_LOCAL_STARTTIME 500 |
#define | DTMF_LOCAL_TIME 250 |
#define | DTMF_TIMEOUT 3 |
#define | ENDCHAR '#' |
#define | EXTNODEFILE "/var/lib/asterisk/rpt_extnodes" |
#define | EXTNODES "extnodes" |
#define | FUNCCHAR '*' |
#define | FUNCTDELAY 1500 |
#define | FUNCTIONS "functions" |
#define | HANGTIME 5000 |
#define | IC706_PL_MEMORY_OFFSET 50 |
#define | IDTIME 300000 |
#define | KENWOOD_RETRIES 5 |
#define | LINKLISTSHORTTIME 200 |
#define | LINKLISTTIME 10000 |
#define | MACRO "macro" |
#define | MACROPTIME 500 |
#define | MACROTIME 100 |
#define | MAX_RETRIES 5 |
#define | MAX_RETRIES_PERM 1000000000 |
#define | MAX_STAT_LINKS 32 |
#define | MAX_SYSSTATES 10 |
#define | MAXCONNECTTIME 5000 |
#define | MAXDTMF 32 |
#define | MAXLINKLIST 512 |
#define | MAXMACRO 2048 |
#define | MAXNODESTR 300 |
#define | MAXPATCHCONTEXT 100 |
#define | MAXPEERSTR 31 |
#define | MAXREMSTR 15 |
#define | MAXRPTS 20 |
#define | MAXXLAT 20 |
#define | MAXXLATTIME 3 |
#define | MEMORY "memory" |
#define | MONITOR_DISK_BLOCKS_PER_MINUTE 38 |
#define | MORSE "morse" |
#define | MSWAIT 200 |
#define | NODES "nodes" |
#define | NRPTSTAT 7 |
#define | OLDKEY |
#define | POLITEID 30000 |
#define | QUOTECHR 34 |
#define | REDUNDANT_TX_TIME 2000 |
#define | REM_SCANTIME 100 |
#define | RETRY_TIMER_MS 5000 |
#define | rpt_mutex_lock(x) ast_mutex_lock(x) |
#define | rpt_mutex_unlock(x) ast_mutex_unlock(x) |
#define | START_DELAY 2 |
#define | TELEMETRY "telemetry" |
#define | TELEPARAMSIZE 256 |
#define | TOTIME 180000 |
Enumerations | |
enum | { REM_OFF, REM_MONITOR, REM_TX } |
enum | { ID, PROC, TERM, COMPLETE, UNKEY, REMDISC, REMALREADY, REMNOTFOUND, REMGO, CONNECTED, CONNFAIL, STATUS, TIMEOUT, ID1, STATS_TIME, STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH, TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY, FULLSTATUS, MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS, REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE, TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX } |
enum | { REM_SIMPLEX, REM_MINUS, REM_PLUS } |
enum | { REM_LOWPWR, REM_MEDPWR, REM_HIPWR } |
enum | { DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY } |
enum | { SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE } |
enum | { DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM, DLY_COMP, DLY_LINKUNKEY } |
enum | { REM_MODE_FM, REM_MODE_USB, REM_MODE_LSB, REM_MODE_AM } |
enum | { HF_SCAN_OFF, HF_SCAN_DOWN_SLOW, HF_SCAN_DOWN_QUICK, HF_SCAN_DOWN_FAST, HF_SCAN_UP_SLOW, HF_SCAN_UP_QUICK, HF_SCAN_UP_FAST } |
enum | { TOP_TOP, TOP_WON, WON_BEFREAD, BEFREAD_AFTERREAD } |
Functions | |
static void | __kickshort (struct rpt *myrpt) |
static void | __mklinklist (struct rpt *myrpt, struct rpt_link *mylink, char *buf) |
static void | __reg_module (void) |
static void | __unreg_module (void) |
int | ast_playtones_start (struct ast_channel *chan, int vol, const char *tonelist, int interruptible) |
void | ast_playtones_stop (struct ast_channel *chan) |
static int | attempt_reconnect (struct rpt *myrpt, struct rpt_link *l) |
static int | check_freq (struct rpt *myrpt, int m, int d, int *defmode) |
static int | check_freq_ft897 (int m, int d, int *defmode) |
static int | check_freq_ic706 (int m, int d, int *defmode) |
static int | check_freq_kenwood (int m, int d, int *defmode) |
static int | check_freq_rbi (int m, int d, int *defmode) |
static char | check_tx_freq (struct rpt *myrpt) |
static int | civ_cmd (struct rpt *myrpt, unsigned char *cmd, int cmdlen) |
static int | closerem (struct rpt *myrpt) |
static int | closerem_ft897 (struct rpt *myrpt) |
static int | collect_function_digits (struct rpt *myrpt, char *digits, int command_source, struct rpt_link *mylink) |
static int | connect_link (struct rpt *myrpt, char *node, int mode, int perma) |
static int | decimals2int (char *fraction) |
static long | diskavail (struct rpt *myrpt) |
static void | do_dtmf_local (struct rpt *myrpt, char c) |
static void | do_dtmf_phone (struct rpt *myrpt, struct rpt_link *mylink, char c) |
static void | do_scheduler (struct rpt *myrpt) |
static void | donodelog (struct rpt *myrpt, char *str) |
static char * | eatwhite (char *s) |
static int | finddelim (char *str, char *strp[], int limit) |
static char | func_xlat (struct rpt *myrpt, char c, struct rpt_xlat *xlat) |
static int | function_autopatchdn (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_autopatchup (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_cop (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_ilink (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_macro (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_remote (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_status (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | get_wait_interval (struct rpt *myrpt, int type) |
static void | handle_link_data (struct rpt *myrpt, struct rpt_link *mylink, char *str) |
static void | handle_link_phone_dtmf (struct rpt *myrpt, struct rpt_link *mylink, char c) |
static int | handle_remote_data (struct rpt *myrpt, char *str) |
static int | handle_remote_dtmf_digit (struct rpt *myrpt, char c, char *keyed, int phonemode) |
static int | handle_remote_phone_dtmf (struct rpt *myrpt, char c, char *keyed, int phonemode) |
static int | ic706_pltocode (char *str) |
static int | kenwood_pltocode (char *str) |
static int | load_module (void) |
static void | load_rpt_vars (int n, int init) |
static void | local_dtmf_helper (struct rpt *myrpt, char c) |
static int | matchkeyword (char *string, char **param, char *keywords[]) |
static void | mdc1200_notify (struct rpt *myrpt, char *fromnode, unsigned int unit) |
static int | mem2vfo_ic706 (struct rpt *myrpt) |
static int | multimode_bump_freq (struct rpt *myrpt, int interval) |
static int | multimode_bump_freq_ft897 (struct rpt *myrpt, int interval) |
static int | multimode_bump_freq_ic706 (struct rpt *myrpt, int interval) |
static int | multimode_capable (struct rpt *myrpt) |
static int | myatoi (char *str) |
static int | mycompar (const void *a, const void *b) |
static char * | node_lookup (struct rpt *myrpt, char *digitbuf) |
static int | openserial (char *fname) |
static int | play_silence (struct ast_channel *chan, int duration) |
static int | play_tone (struct ast_channel *chan, int freq, int duration, int amplitude) |
static int | play_tone_pair (struct ast_channel *chan, int f1, int f2, int duration, int amplitude) |
static void | queue_id (struct rpt *myrpt) |
static int | rbi_mhztoband (char *str) |
static void | rbi_out (struct rpt *myrpt, unsigned char *data) |
static void | rbi_out_parallel (struct rpt *myrpt, unsigned char *data) |
static int | rbi_pltocode (char *str) |
static int | reload (void) |
static int | retreive_memory (struct rpt *myrpt, char *memory) |
static int | retrieve_astcfgint (struct rpt *myrpt, char *category, char *name, int min, int max, int defl) |
static void * | rpt (void *this) |
static void * | rpt_call (void *this) |
static int | rpt_do_debug (int fd, int argc, char *argv[]) |
static int | rpt_do_dump (int fd, int argc, char *argv[]) |
static int | rpt_do_fun (int fd, int argc, char *argv[]) |
static int | rpt_do_lstats (int fd, int argc, char *argv[]) |
static int | rpt_do_nodes (int fd, int argc, char *argv[]) |
static int | rpt_do_reload (int fd, int argc, char *argv[]) |
static int | rpt_do_restart (int fd, int argc, char *argv[]) |
static int | rpt_do_stats (int fd, int argc, char *argv[]) |
static int | rpt_exec (struct ast_channel *chan, void *data) |
static void | rpt_localtime (time_t *t, struct tm *lt) |
static void * | rpt_master (void *ignore) |
static void * | rpt_tele_thread (void *this) |
static void | rpt_telemetry (struct rpt *myrpt, int mode, void *data) |
static int | saycharstr (struct ast_channel *mychannel, char *str) |
static int | sayfile (struct ast_channel *mychannel, char *fname) |
static int | saynum (struct ast_channel *mychannel, int num) |
static int | select_mem_ic706 (struct rpt *myrpt, int slot) |
static void | send_link_dtmf (struct rpt *myrpt, char c) |
static int | send_morse (struct ast_channel *chan, char *string, int speed, int freq, int amplitude) |
static int | send_tone_telemetry (struct ast_channel *chan, char *tonestring) |
static int | sendkenwood (struct rpt *myrpt, char *txstr, char *rxstr) |
static int | sendrxkenwood (struct rpt *myrpt, char *txstr, char *rxstr, char *cmpstr) |
static int | serial_remote_io (struct rpt *myrpt, unsigned char *txbuf, int txbytes, unsigned char *rxbuf, int rxmaxbytes, int asciiflag) |
static int | service_scan (struct rpt *myrpt) |
static int | set_ctcss_freq_ft897 (struct rpt *myrpt, char *txtone, char *rxtone) |
static int | set_ctcss_mode_ft897 (struct rpt *myrpt, char txplon, char rxplon) |
static int | set_ctcss_mode_ic706 (struct rpt *myrpt, char txplon, char rxplon) |
static int | set_freq_ft897 (struct rpt *myrpt, char *newfreq) |
static int | set_freq_ic706 (struct rpt *myrpt, char *newfreq) |
static int | set_ft897 (struct rpt *myrpt) |
static int | set_ic706 (struct rpt *myrpt) |
static int | set_mode_ft897 (struct rpt *myrpt, char newmode) |
static int | set_mode_ic706 (struct rpt *myrpt, char newmode) |
static int | set_offset_ft897 (struct rpt *myrpt, char offset) |
static int | set_offset_ic706 (struct rpt *myrpt, char offset) |
static int | setkenwood (struct rpt *myrpt) |
static int | setrbi (struct rpt *myrpt) |
static int | setrbi_check (struct rpt *myrpt) |
static int | setrem (struct rpt *myrpt) |
static int | simple_command_ft897 (struct rpt *myrpt, char command) |
static int | simple_command_ic706 (struct rpt *myrpt, char command, char subcommand) |
static char * | skipchars (char *string, char *charlist) |
static int | split_ctcss_freq (char *hertz, char *decimal, char *freq) |
static int | split_freq (char *mhz, char *decimals, char *freq) |
static void | stop_scan (struct rpt *myrpt) |
static int | telem_any (struct rpt *myrpt, struct ast_channel *chan, char *entry) |
static int | telem_lookup (struct rpt *myrpt, struct ast_channel *chan, char *node, char *name) |
static int | unload_module (void) |
static int | vfo_ic706 (struct rpt *myrpt) |
static void | wait_interval (struct rpt *myrpt, int type, struct ast_channel *chan) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Radio Repeater/Remote Base Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } |
static char * | app = "Rpt" |
static const struct ast_module_info * | ast_module_info = &__mod_info |
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 ast_mutex_t | nodeloglock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static ast_mutex_t | nodelookuplock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static int | nrpts = 0 |
static char | reload_usage [] |
static char | remdtmfstr [] = "0123456789*#ABCD" |
static char * | remote_rig_ft897 = "ft897" |
static char * | remote_rig_ic706 = "ic706" |
static char * | remote_rig_kenwood = "kenwood" |
static char * | remote_rig_rbi = "rbi" |
static char | restart_usage [] |
static pthread_t | rpt_master_thread |
static struct rpt | rpt_vars [MAXRPTS] |
static time_t | starttime = 0 |
static char * | synopsis = "Radio Repeater/Remote Base Control System" |
static char * | tdesc = "Radio Repeater / Remote Base version 0.73 09/04/2007" |
static struct telem_defaults | tele_defs [] |
Repeater / Remote Functions: "Simple" Mode: * - autopatch access, # - autopatch hangup Normal mode: See the function list in rpt.conf (autopatchup, autopatchdn) autopatchup can optionally take comma delimited setting=value pairs:
context=string : Override default context with "string" dialtime=ms : Specify the max number of milliseconds between phone number digits (1000 milliseconds = 1 second) farenddisconnect=1 : Automatically disconnect when called party hangs up noct=1 : Don't send repeater courtesy tone during autopatch calls quiet=1 : Don't send dial tone, or connect messages. Do not send patch down message when called party hangs up
Example: 123=autopatchup,dialtime=20000,noct=1,farenddisconnect=1
To send an asterisk (*) while dialing or talking on phone, use the autopatch acess code.
status cmds:
1 - Force ID 2 - Give Time of Day 3 - Give software Version
cop (control operator) cmds:
1 - System warm boot 2 - System enable 3 - System disable 4 - Test Tone On/Off 5 - Dump System Variables on Console (debug) 6 - PTT (phone mode only) 7 - Time out timer enable 8 - Time out timer disable 9 - Autopatch enable 10 - Autopatch disable 11 - Link enable 12 - Link disable 13 - Query System State 14 - Change System State 15 - Scheduler Enable 16 - Scheduler Disable 17 - User functions (time, id, etc) enable 18 - User functions (time, id, etc) disable 19 - Select alternate hang timer 20 - Select standard hang timer
ilink cmds:
1 - Disconnect specified link 2 - Connect specified link -- monitor only 3 - Connect specified link -- tranceive 4 - Enter command mode on specified link 5 - System status 6 - Disconnect all links 11 - Disconnect a previously permanently connected link 12 - Permanently connect specified link -- monitor only 13 - Permanently connect specified link -- tranceive 15 - Full system status (all nodes) 16 - Reconnect links disconnected with "disconnect all links" 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
remote cmds:
1 - Recall Memory MM (*000-*099) (Gets memory from rpt.conf) 2 - Set VFO MMMMM*KKK*O (Mhz digits, Khz digits, Offset) 3 - Set Rx PL Tone HHH*D* 4 - Set Tx PL Tone HHH*D* (Not currently implemented with DHE RBI-1) 5 - Link Status (long) 6 - Set operating mode M (FM, USB, LSB, AM, etc) 100 - RX PL off (Default) 101 - RX PL On 102 - TX PL Off (Default) 103 - TX PL On 104 - Low Power 105 - Med Power 106 - Hi Power 107 - Bump Down 20 Hz 108 - Bump Down 100 Hz 109 - Bump Down 500 Hz 110 - Bump Up 20 Hz 111 - Bump Up 100 Hz 112 - Bump Up 500 Hz 113 - Scan Down Slow 114 - Scan Down Medium 115 - Scan Down Fast 116 - Scan Up Slow 117 - Scan Up Medium 118 - Scan Up Fast 119 - Transmit allowing auto-tune 140 - Link Status (brief) 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)
'duplex' modes: (defaults to duplex=2)
0 - Only remote links key Tx and no main repeat audio. 1 - Everything other then main Rx keys Tx, no main repeat audio. 2 - Normal mode 3 - Normal except no main repeat audio. 4 - Normal except no main repeat audio during autopatch only
Definition in file app_rpt.c.
#define DEFAULT_CIV_ADDR 0x58 |
#define DEFAULT_IOBASE 0x378 |
#define DEFAULT_MONITOR_MIN_DISK_BLOCKS 10000 |
#define DEFAULT_REMOTE_INACT_TIMEOUT (15 * 60) |
#define DEFAULT_REMOTE_TIMEOUT (60 * 60) |
#define DEFAULT_REMOTE_TIMEOUT_WARNING (3 * 60) |
#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ 30 |
#define DELIMCHR ',' |
#define DTMF_LOCAL_STARTTIME 500 |
#define DTMF_LOCAL_TIME 250 |
#define DTMF_TIMEOUT 3 |
#define ENDCHAR '#' |
#define EXTNODEFILE "/var/lib/asterisk/rpt_extnodes" |
#define EXTNODES "extnodes" |
#define FUNCCHAR '*' |
#define FUNCTIONS "functions" |
#define HANGTIME 5000 |
#define IC706_PL_MEMORY_OFFSET 50 |
#define IDTIME 300000 |
#define KENWOOD_RETRIES 5 |
#define LINKLISTSHORTTIME 200 |
#define MACRO "macro" |
#define MACROTIME 100 |
Definition at line 160 of file app_rpt.c.
Referenced by do_scheduler(), function_macro(), rpt(), and rpt_do_fun().
#define MAX_RETRIES 5 |
#define MAX_RETRIES_PERM 1000000000 |
#define MAX_STAT_LINKS 32 |
#define MAX_SYSSTATES 10 |
#define MAXDTMF 32 |
Definition at line 155 of file app_rpt.c.
Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and local_dtmf_helper().
#define MAXLINKLIST 512 |
Definition at line 157 of file app_rpt.c.
Referenced by __mklinklist(), connect_link(), function_ilink(), rpt(), rpt_do_nodes(), and rpt_tele_thread().
#define MAXMACRO 2048 |
Definition at line 156 of file app_rpt.c.
Referenced by do_scheduler(), function_macro(), rpt(), and rpt_do_fun().
#define MAXNODESTR 300 |
#define MAXPATCHCONTEXT 100 |
Definition at line 216 of file app_rpt.c.
Referenced by function_autopatchup(), and local_dtmf_helper().
#define MAXPEERSTR 31 |
#define MAXREMSTR 15 |
Definition at line 184 of file app_rpt.c.
Referenced by check_tx_freq(), function_remote(), multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), rpt_do_lstats(), rpt_tele_thread(), service_scan(), set_ctcss_freq_ft897(), set_freq_ft897(), set_freq_ic706(), setkenwood(), setrbi(), setrbi_check(), split_ctcss_freq(), and split_freq().
#define MAXXLAT 20 |
#define MAXXLATTIME 3 |
#define MEMORY "memory" |
#define MORSE "morse" |
#define MSWAIT 200 |
#define NODES "nodes" |
#define NRPTSTAT 7 |
#define POLITEID 30000 |
#define QUOTECHR 34 |
#define REM_SCANTIME 100 |
#define rpt_mutex_lock | ( | x | ) | ast_mutex_lock(x) |
Definition at line 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_tele_thread(), and rpt_telemetry().
#define rpt_mutex_unlock | ( | x | ) | ast_mutex_unlock(x) |
Definition at line 871 of file app_rpt.c.
Referenced by attempt_reconnect(), connect_link(), do_dtmf_local(), function_autopatchdn(), function_autopatchup(), function_ilink(), function_macro(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rpt_tele_thread(), and rpt_telemetry().
#define START_DELAY 2 |
#define TELEMETRY "telemetry" |
#define TELEPARAMSIZE 256 |
#define TOTIME 180000 |
anonymous enum |
anonymous enum |
Definition at line 233 of file app_rpt.c.
00233 {ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO, 00234 CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME, 00235 STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH, 00236 TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY, FULLSTATUS, 00237 MEMNOTFOUND, INVFREQ, REMMODE, REMLOGIN, REMXXX, REMSHORTSTATUS, 00238 REMLONGSTATUS, LOGINREQ, SCAN, SCANSTAT, TUNE, SETREMOTE, 00239 TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX};
anonymous enum |
anonymous enum |
anonymous enum |
Definition at line 246 of file app_rpt.c.
00246 {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY};
anonymous enum |
Definition at line 248 of file app_rpt.c.
00248 {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE};
anonymous enum |
Definition at line 250 of file app_rpt.c.
00250 {DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM, DLY_COMP, DLY_LINKUNKEY};
anonymous enum |
anonymous enum |
HF_SCAN_OFF | |
HF_SCAN_DOWN_SLOW | |
HF_SCAN_DOWN_QUICK | |
HF_SCAN_DOWN_FAST | |
HF_SCAN_UP_SLOW | |
HF_SCAN_UP_QUICK | |
HF_SCAN_UP_FAST |
Definition at line 254 of file app_rpt.c.
00254 {HF_SCAN_OFF,HF_SCAN_DOWN_SLOW,HF_SCAN_DOWN_QUICK, 00255 HF_SCAN_DOWN_FAST,HF_SCAN_UP_SLOW,HF_SCAN_UP_QUICK,HF_SCAN_UP_FAST};
anonymous enum |
static void __kickshort | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 1396 of file app_rpt.c.
References LINKLISTSHORTTIME, rpt_link::linklisttimer, rpt::links, rpt_link::name, and rpt_link::next.
Referenced by connect_link(), and rpt().
01397 { 01398 struct rpt_link *l; 01399 01400 for(l = myrpt->links.next; l != &myrpt->links; l = l->next) 01401 { 01402 /* if is not a real link, ignore it */ 01403 if (l->name[0] == '0') continue; 01404 l->linklisttimer = LINKLISTSHORTTIME; 01405 } 01406 return; 01407 }
Definition at line 1347 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().
01348 { 01349 struct rpt_link *l; 01350 char mode; 01351 int i,spos; 01352 01353 buf[0] = 0; /* clear output buffer */ 01354 /* go thru all links */ 01355 for(l = myrpt->links.next; l != &myrpt->links; l = l->next) 01356 { 01357 /* if is not a real link, ignore it */ 01358 if (l->name[0] == '0') continue; 01359 /* dont count our stuff */ 01360 if (l == mylink) continue; 01361 if (mylink && (!strcmp(l->name,mylink->name))) continue; 01362 /* figure out mode to report */ 01363 mode = 'T'; /* use Tranceive by default */ 01364 if (!l->mode) mode = 'R'; /* indicate RX for our mode */ 01365 if (!l->thisconnected) mode = 'C'; /* indicate connecting */ 01366 spos = strlen(buf); /* current buf size (b4 we add our stuff) */ 01367 if (spos) 01368 { 01369 strcat(buf,","); 01370 spos++; 01371 } 01372 /* add nodes into buffer */ 01373 if (l->linklist[0]) 01374 { 01375 snprintf(buf + spos,MAXLINKLIST - spos, 01376 "%c%s,%s",mode,l->name,l->linklist); 01377 } 01378 else /* if no nodes, add this node into buffer */ 01379 { 01380 snprintf(buf + spos,MAXLINKLIST - spos, 01381 "%c%s",mode,l->name); 01382 } 01383 /* if we are in tranceive mode, let all modes stand */ 01384 if (mode == 'T') continue; 01385 /* downgrade everyone on this node if appropriate */ 01386 for(i = spos; buf[i]; i++) 01387 { 01388 if (buf[i] == 'T') buf[i] = mode; 01389 if ((buf[i] == 'R') && (mode == 'C')) buf[i] = mode; 01390 } 01391 } 01392 return; 01393 }
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, ast_channel::name, playtones_def::nitems, playtones, playtones_def::reppos, s, and playtones_def::vol.
Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dialtone_indicate(), do_dtmf_local(), handle_playtones(), milliwatt_exec(), play_dialtone(), playtone(), read_exec(), and send_digit_to_chan().
00213 { 00214 char *s, *data = ast_strdupa(playlst); /* cute */ 00215 struct playtones_def d = { vol, -1, 0, 1, NULL}; 00216 char *stringp; 00217 char *separator; 00218 00219 if (vol < 1) 00220 d.vol = 7219; /* Default to -8db */ 00221 00222 d.interruptible = interruptible; 00223 00224 stringp=data; 00225 /* the stringp/data is not null here */ 00226 /* check if the data is separated with '|' or with ',' by default */ 00227 if (strchr(stringp,'|')) 00228 separator = "|"; 00229 else 00230 separator = ","; 00231 s = strsep(&stringp,separator); 00232 while (s && *s) { 00233 int freq1, freq2, time, modulate=0, midinote=0; 00234 00235 if (s[0]=='!') 00236 s++; 00237 else if (d.reppos == -1) 00238 d.reppos = d.nitems; 00239 if (sscanf(s, "%30d+%30d/%30d", &freq1, &freq2, &time) == 3) { 00240 /* f1+f2/time format */ 00241 } else if (sscanf(s, "%30d+%30d", &freq1, &freq2) == 2) { 00242 /* f1+f2 format */ 00243 time = 0; 00244 } else if (sscanf(s, "%30d*%30d/%30d", &freq1, &freq2, &time) == 3) { 00245 /* f1*f2/time format */ 00246 modulate = 1; 00247 } else if (sscanf(s, "%30d*%30d", &freq1, &freq2) == 2) { 00248 /* f1*f2 format */ 00249 time = 0; 00250 modulate = 1; 00251 } else if (sscanf(s, "%30d/%30d", &freq1, &time) == 2) { 00252 /* f1/time format */ 00253 freq2 = 0; 00254 } else if (sscanf(s, "%30d", &freq1) == 1) { 00255 /* f1 format */ 00256 freq2 = 0; 00257 time = 0; 00258 } else if (sscanf(s, "M%30d+M%30d/%30d", &freq1, &freq2, &time) == 3) { 00259 /* Mf1+Mf2/time format */ 00260 midinote = 1; 00261 } else if (sscanf(s, "M%30d+M%30d", &freq1, &freq2) == 2) { 00262 /* Mf1+Mf2 format */ 00263 time = 0; 00264 midinote = 1; 00265 } else if (sscanf(s, "M%30d*M%30d/%30d", &freq1, &freq2, &time) == 3) { 00266 /* Mf1*Mf2/time format */ 00267 modulate = 1; 00268 midinote = 1; 00269 } else if (sscanf(s, "M%30d*M%30d", &freq1, &freq2) == 2) { 00270 /* Mf1*Mf2 format */ 00271 time = 0; 00272 modulate = 1; 00273 midinote = 1; 00274 } else if (sscanf(s, "M%30d/%30d", &freq1, &time) == 2) { 00275 /* Mf1/time format */ 00276 freq2 = -1; 00277 midinote = 1; 00278 } else if (sscanf(s, "M%30d", &freq1) == 1) { 00279 /* Mf1 format */ 00280 freq2 = -1; 00281 time = 0; 00282 midinote = 1; 00283 } else { 00284 ast_log(LOG_WARNING,"%s: tone component '%s' of '%s' is no good\n",chan->name,s,playlst); 00285 return -1; 00286 } 00287 00288 if (midinote) { 00289 /* midi notes must be between 0 and 127 */ 00290 if ((freq1 >= 0) && (freq1 <= 127)) 00291 freq1 = midi_tohz[freq1]; 00292 else 00293 freq1 = 0; 00294 00295 if ((freq2 >= 0) && (freq2 <= 127)) 00296 freq2 = midi_tohz[freq2]; 00297 else 00298 freq2 = 0; 00299 } 00300 00301 if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) { 00302 return -1; 00303 } 00304 d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0; 00305 d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * d.vol; 00306 d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * d.vol; 00307 00308 d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0; 00309 d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * d.vol; 00310 d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * d.vol; 00311 d.items[d.nitems].duration = time; 00312 d.items[d.nitems].modulate = modulate; 00313 d.nitems++; 00314 00315 s = strsep(&stringp,separator); 00316 } 00317 00318 if (ast_activate_generator(chan, &playtones, &d)) { 00319 free(d.items); 00320 return -1; 00321 } 00322 return 0; 00323 }
void ast_playtones_stop | ( | struct ast_channel * | chan | ) |
Stop the tones from playing
Definition at line 325 of file indications.c.
References ast_deactivate_generator().
Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_end(), disa_exec(), handle_stopplaytones(), playtone(), read_exec(), and stop_indicate().
00326 { 00327 ast_deactivate_generator(chan); 00328 }
Definition at line 8419 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, and VERBOSE_PREFIX_3.
Referenced by rpt().
08420 { 08421 char *val, *s, *s1, *s2, *tele; 08422 char tmp[300], deststr[300] = ""; 08423 08424 val = node_lookup(myrpt,l->name); 08425 if (!val) 08426 { 08427 fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name); 08428 return -1; 08429 } 08430 08431 rpt_mutex_lock(&myrpt->lock); 08432 /* remove from queue */ 08433 remque((struct qelem *) l); 08434 rpt_mutex_unlock(&myrpt->lock); 08435 strncpy(tmp,val,sizeof(tmp) - 1); 08436 s = tmp; 08437 s1 = strsep(&s,","); 08438 s2 = strsep(&s,","); 08439 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 08440 tele = strchr(deststr, '/'); 08441 if (!tele) { 08442 fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr); 08443 return -1; 08444 } 08445 *tele++ = 0; 08446 l->elaptime = 0; 08447 l->connecttime = 0; 08448 l->thisconnected = 0; 08449 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 08450 if (l->chan){ 08451 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 08452 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 08453 l->chan->whentohangup = 0; 08454 l->chan->appl = "Apprpt"; 08455 l->chan->data = "(Remote Rx)"; 08456 if (option_verbose > 2) 08457 ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n", 08458 deststr, tele, l->chan->name); 08459 if(l->chan->cid.cid_num) 08460 free(l->chan->cid.cid_num); 08461 l->chan->cid.cid_num = strdup(myrpt->name); 08462 ast_call(l->chan,tele,999); 08463 08464 } 08465 else 08466 { 08467 if (option_verbose > 2) 08468 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 08469 deststr,tele,l->chan->name); 08470 return -1; 08471 } 08472 rpt_mutex_lock(&myrpt->lock); 08473 /* put back in queue */ 08474 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 08475 rpt_mutex_unlock(&myrpt->lock); 08476 ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name); 08477 return 0; 08478 }
static int check_freq | ( | struct rpt * | myrpt, | |
int | m, | |||
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 7411 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().
07412 { 07413 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07414 return check_freq_ft897(m, d, defmode); 07415 else if(!strcmp(myrpt->remote, remote_rig_ic706)) 07416 return check_freq_ic706(m, d, defmode); 07417 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 07418 return check_freq_rbi(m, d, defmode); 07419 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) 07420 return check_freq_kenwood(m, d, defmode); 07421 else 07422 return -1; 07423 }
static int check_freq_ft897 | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6426 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().
06427 { 06428 int dflmd = REM_MODE_FM; 06429 06430 if(m == 1){ /* 160 meters */ 06431 dflmd = REM_MODE_LSB; 06432 if(d < 80000) 06433 return -1; 06434 } 06435 else if(m == 3){ /* 80 meters */ 06436 dflmd = REM_MODE_LSB; 06437 if(d < 50000) 06438 return -1; 06439 } 06440 else if(m == 7){ /* 40 meters */ 06441 dflmd = REM_MODE_LSB; 06442 if(d > 30000) 06443 return -1; 06444 } 06445 else if(m == 14){ /* 20 meters */ 06446 dflmd = REM_MODE_USB; 06447 if(d > 35000) 06448 return -1; 06449 } 06450 else if(m == 18){ /* 17 meters */ 06451 dflmd = REM_MODE_USB; 06452 if((d < 6800) || (d > 16800)) 06453 return -1; 06454 } 06455 else if(m == 21){ /* 15 meters */ 06456 dflmd = REM_MODE_USB; 06457 if((d < 20000) || (d > 45000)) 06458 return -1; 06459 } 06460 else if(m == 24){ /* 12 meters */ 06461 dflmd = REM_MODE_USB; 06462 if((d < 89000) || (d > 99000)) 06463 return -1; 06464 } 06465 else if(m == 28){ /* 10 meters */ 06466 dflmd = REM_MODE_USB; 06467 } 06468 else if(m == 29){ 06469 if(d >= 51000) 06470 dflmd = REM_MODE_FM; 06471 else 06472 dflmd = REM_MODE_USB; 06473 if(d > 70000) 06474 return -1; 06475 } 06476 else if(m == 50){ /* 6 meters */ 06477 if(d >= 30000) 06478 dflmd = REM_MODE_FM; 06479 else 06480 dflmd = REM_MODE_USB; 06481 06482 } 06483 else if((m >= 51) && ( m < 54)){ 06484 dflmd = REM_MODE_FM; 06485 } 06486 else if(m == 144){ /* 2 meters */ 06487 if(d >= 30000) 06488 dflmd = REM_MODE_FM; 06489 else 06490 dflmd = REM_MODE_USB; 06491 } 06492 else if((m >= 145) && (m < 148)){ 06493 dflmd = REM_MODE_FM; 06494 } 06495 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06496 if(m < 438) 06497 dflmd = REM_MODE_USB; 06498 else 06499 dflmd = REM_MODE_FM; 06500 ; 06501 } 06502 else 06503 return -1; 06504 06505 if(defmode) 06506 *defmode = dflmd; 06507 06508 return 0; 06509 }
static int check_freq_ic706 | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6797 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().
06798 { 06799 int dflmd = REM_MODE_FM; 06800 06801 if(m == 1){ /* 160 meters */ 06802 dflmd = REM_MODE_LSB; 06803 if(d < 80000) 06804 return -1; 06805 } 06806 else if(m == 3){ /* 80 meters */ 06807 dflmd = REM_MODE_LSB; 06808 if(d < 50000) 06809 return -1; 06810 } 06811 else if(m == 7){ /* 40 meters */ 06812 dflmd = REM_MODE_LSB; 06813 if(d > 30000) 06814 return -1; 06815 } 06816 else if(m == 14){ /* 20 meters */ 06817 dflmd = REM_MODE_USB; 06818 if(d > 35000) 06819 return -1; 06820 } 06821 else if(m == 18){ /* 17 meters */ 06822 dflmd = REM_MODE_USB; 06823 if((d < 6800) || (d > 16800)) 06824 return -1; 06825 } 06826 else if(m == 21){ /* 15 meters */ 06827 dflmd = REM_MODE_USB; 06828 if((d < 20000) || (d > 45000)) 06829 return -1; 06830 } 06831 else if(m == 24){ /* 12 meters */ 06832 dflmd = REM_MODE_USB; 06833 if((d < 89000) || (d > 99000)) 06834 return -1; 06835 } 06836 else if(m == 28){ /* 10 meters */ 06837 dflmd = REM_MODE_USB; 06838 } 06839 else if(m == 29){ 06840 if(d >= 51000) 06841 dflmd = REM_MODE_FM; 06842 else 06843 dflmd = REM_MODE_USB; 06844 if(d > 70000) 06845 return -1; 06846 } 06847 else if(m == 50){ /* 6 meters */ 06848 if(d >= 30000) 06849 dflmd = REM_MODE_FM; 06850 else 06851 dflmd = REM_MODE_USB; 06852 06853 } 06854 else if((m >= 51) && ( m < 54)){ 06855 dflmd = REM_MODE_FM; 06856 } 06857 else if(m == 144){ /* 2 meters */ 06858 if(d >= 30000) 06859 dflmd = REM_MODE_FM; 06860 else 06861 dflmd = REM_MODE_USB; 06862 } 06863 else if((m >= 145) && (m < 148)){ 06864 dflmd = REM_MODE_FM; 06865 } 06866 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06867 if(m < 438) 06868 dflmd = REM_MODE_USB; 06869 else 06870 dflmd = REM_MODE_FM; 06871 ; 06872 } 06873 else 06874 return -1; 06875 06876 if(defmode) 06877 *defmode = dflmd; 06878 06879 return 0; 06880 }
static int check_freq_kenwood | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6288 of file app_rpt.c.
References REM_MODE_FM.
Referenced by check_freq().
06289 { 06290 int dflmd = REM_MODE_FM; 06291 06292 if (m == 144){ /* 2 meters */ 06293 if(d < 10100) 06294 return -1; 06295 } 06296 else if((m >= 145) && (m < 148)){ 06297 ; 06298 } 06299 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06300 ; 06301 } 06302 else 06303 return -1; 06304 06305 if(defmode) 06306 *defmode = dflmd; 06307 06308 06309 return 0; 06310 }
static int check_freq_rbi | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 6316 of file app_rpt.c.
References REM_MODE_FM.
Referenced by check_freq().
06317 { 06318 int dflmd = REM_MODE_FM; 06319 06320 if(m == 50){ /* 6 meters */ 06321 if(d < 10100) 06322 return -1; 06323 } 06324 else if((m >= 51) && ( m < 54)){ 06325 ; 06326 } 06327 else if(m == 144){ /* 2 meters */ 06328 if(d < 10100) 06329 return -1; 06330 } 06331 else if((m >= 145) && (m < 148)){ 06332 ; 06333 } 06334 else if((m >= 222) && (m < 225)){ /* 1.25 meters */ 06335 ; 06336 } 06337 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 06338 ; 06339 } 06340 else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */ 06341 ; 06342 } 06343 else 06344 return -1; 06345 06346 if(defmode) 06347 *defmode = dflmd; 06348 06349 06350 return 0; 06351 }
static char check_tx_freq | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7429 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.
07430 { 07431 int i; 07432 int radio_mhz, radio_decimals, ulimit_mhz, ulimit_decimals, llimit_mhz, llimit_decimals; 07433 char radio_mhz_char[MAXREMSTR]; 07434 char radio_decimals_char[MAXREMSTR]; 07435 char limit_mhz_char[MAXREMSTR]; 07436 char limit_decimals_char[MAXREMSTR]; 07437 char limits[256]; 07438 char *limit_ranges[40]; 07439 struct ast_variable *limitlist; 07440 07441 07442 /* Must have user logged in and tx_limits defined */ 07443 07444 if(!myrpt->p.txlimitsstanzaname || !myrpt->loginuser[0] || !myrpt->loginlevel[0]){ 07445 if(debug > 3){ 07446 ast_log(LOG_NOTICE, "No tx band table defined, or no user logged in\n"); 07447 } 07448 return 1; /* Assume it's ok otherwise */ 07449 } 07450 07451 /* Retrieve the band table for the loginlevel */ 07452 limitlist = ast_variable_browse(myrpt->cfg, myrpt->p.txlimitsstanzaname); 07453 07454 if(!limitlist){ 07455 ast_log(LOG_WARNING, "No entries in %s band table stanza\n", myrpt->p.txlimitsstanzaname); 07456 return 0; 07457 } 07458 07459 split_freq(radio_mhz_char, radio_decimals_char, myrpt->freq); 07460 radio_mhz = atoi(radio_mhz_char); 07461 radio_decimals = decimals2int(radio_decimals_char); 07462 07463 07464 if(debug > 3){ 07465 ast_log(LOG_NOTICE, "Login User = %s, login level = %s\n", myrpt->loginuser, myrpt->loginlevel); 07466 } 07467 07468 /* Find our entry */ 07469 07470 for(;limitlist; limitlist=limitlist->next){ 07471 if(!strcmp(limitlist->name, myrpt->loginlevel)) 07472 break; 07473 } 07474 07475 if(!limitlist){ 07476 ast_log(LOG_WARNING, "Can't find %s entry in band table stanza %s\n", myrpt->loginlevel, myrpt->p.txlimitsstanzaname); 07477 return 0; 07478 } 07479 07480 if(debug > 3){ 07481 ast_log(LOG_NOTICE, "Auth %s = %s\n", limitlist->name, limitlist->value); 07482 } 07483 07484 /* Parse the limits */ 07485 07486 strncpy(limits, limitlist->value, 256); 07487 limits[255] = 0; 07488 finddelim(limits, limit_ranges, 40); 07489 for(i = 0; i < 40 && limit_ranges[i] ; i++){ 07490 char range[40]; 07491 char *r,*s; 07492 strncpy(range, limit_ranges[i], 40); 07493 range[39] = 0; 07494 if(debug > 3){ 07495 ast_log(LOG_NOTICE, "Checking to see if %s is within limits of %s\n", myrpt->freq, range); 07496 } 07497 07498 r = strchr(range, '-'); 07499 if(!r){ 07500 ast_log(LOG_WARNING, "Malformed range in %s tx band table entry\n", limitlist->name); 07501 return 0; 07502 } 07503 *r++ = 0; 07504 s = eatwhite(range); 07505 r = eatwhite(r); 07506 split_freq(limit_mhz_char, limit_decimals_char, s); 07507 llimit_mhz = atoi(limit_mhz_char); 07508 llimit_decimals = decimals2int(limit_decimals_char); 07509 split_freq(limit_mhz_char, limit_decimals_char, r); 07510 ulimit_mhz = atoi(limit_mhz_char); 07511 ulimit_decimals = decimals2int(limit_decimals_char); 07512 07513 if((radio_mhz >= llimit_mhz) && (radio_mhz <= ulimit_mhz)){ 07514 if(radio_mhz == llimit_mhz){ /* CASE 1: TX freq is in llimit mhz portion of band */ 07515 if(radio_decimals >= llimit_decimals){ /* Cannot be below llimit decimals */ 07516 if(llimit_mhz == ulimit_mhz){ /* If bandwidth < 1Mhz, check ulimit decimals */ 07517 if(radio_decimals <= ulimit_decimals){ 07518 return 1; 07519 } 07520 else{ 07521 if(debug > 3) 07522 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 1\n"); 07523 return 0; 07524 } 07525 } 07526 else{ 07527 return 1; 07528 } 07529 } 07530 else{ /* Is below llimit decimals */ 07531 if(debug > 3) 07532 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 2\n"); 07533 return 0; 07534 } 07535 } 07536 else if(radio_mhz == ulimit_mhz){ /* CASE 2: TX freq not in llimit mhz portion of band */ 07537 if(radio_decimals <= ulimit_decimals){ 07538 return 1; 07539 } 07540 else{ /* Is above ulimit decimals */ 07541 if(debug > 3) 07542 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 3\n"); 07543 return 0; 07544 } 07545 } 07546 else /* CASE 3: TX freq within a multi-Mhz band and ok */ 07547 return 1; 07548 } 07549 } 07550 if(debug > 3) /* No match found in TX band table */ 07551 ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 4\n"); 07552 return 0; 07553 }
static int civ_cmd | ( | struct rpt * | myrpt, | |
unsigned char * | cmd, | |||
int | cmdlen | |||
) | [static] |
Definition at line 5964 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().
05965 { 05966 unsigned char rxbuf[100]; 05967 int i,rv ; 05968 05969 rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0); 05970 if (rv == -1) return(-1); 05971 if (rv != (cmdlen + 6)) return(1); 05972 for(i = 0; i < 6; i++) 05973 if (rxbuf[i] != cmd[i]) return(1); 05974 if (rxbuf[cmdlen] != 0xfe) return(1); 05975 if (rxbuf[cmdlen + 1] != 0xfe) return(1); 05976 if (rxbuf[cmdlen + 4] != 0xfb) return(1); 05977 if (rxbuf[cmdlen + 5] != 0xfd) return(1); 05978 return(0); 05979 }
static int closerem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7399 of file app_rpt.c.
References closerem_ft897(), and rpt::remote.
07400 { 07401 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07402 return closerem_ft897(myrpt); 07403 else 07404 return 0; 07405 }
static int closerem_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6737 of file app_rpt.c.
References simple_command_ft897().
Referenced by closerem().
06738 { 06739 simple_command_ft897(myrpt, 0x88); /* PTT off */ 06740 return 0; 06741 }
static int collect_function_digits | ( | struct rpt * | myrpt, | |
char * | digits, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5228 of file app_rpt.c.
References ast_variable_browse(), rpt::cfg, DC_ERROR, DC_INDETERMINATE, rpt::dphone_functions, rpt::dphone_longestfunc, function_table, rpt::functions, rpt::link_functions, rpt::link_longestfunc, rpt::longestfunc, ast_variable::name, ast_variable::next, rpt::p, rpt::phone_functions, rpt::phone_longestfunc, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, and ast_variable::value.
Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and local_dtmf_helper().
05230 { 05231 int i; 05232 char *stringp,*action,*param,*functiondigits; 05233 char function_table_name[30] = ""; 05234 char workstring[200]; 05235 05236 struct ast_variable *vp; 05237 05238 if(debug) 05239 printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source); 05240 05241 if (command_source == SOURCE_DPHONE) { 05242 if (!myrpt->p.dphone_functions) return DC_INDETERMINATE; 05243 strncpy(function_table_name, myrpt->p.dphone_functions, sizeof(function_table_name) - 1); 05244 } 05245 else if (command_source == SOURCE_PHONE) { 05246 if (!myrpt->p.phone_functions) return DC_INDETERMINATE; 05247 strncpy(function_table_name, myrpt->p.phone_functions, sizeof(function_table_name) - 1); 05248 } 05249 else if (command_source == SOURCE_LNK) 05250 strncpy(function_table_name, myrpt->p.link_functions, sizeof(function_table_name) - 1); 05251 else 05252 strncpy(function_table_name, myrpt->p.functions, sizeof(function_table_name) - 1); 05253 vp = ast_variable_browse(myrpt->cfg, function_table_name); 05254 while(vp) { 05255 if(!strncasecmp(vp->name, digits, strlen(vp->name))) 05256 break; 05257 vp = vp->next; 05258 } 05259 if(!vp) { 05260 int n; 05261 05262 n = myrpt->longestfunc; 05263 if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc; 05264 else 05265 if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc; 05266 else 05267 if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc; 05268 05269 if(strlen(digits) >= n) 05270 return DC_ERROR; 05271 else 05272 return DC_INDETERMINATE; 05273 } 05274 /* Found a match, retrieve value part and parse */ 05275 strncpy(workstring, vp->value, sizeof(workstring) - 1 ); 05276 stringp = workstring; 05277 action = strsep(&stringp, ","); 05278 param = stringp; 05279 if(debug) 05280 printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)"); 05281 /* Look up the action */ 05282 for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){ 05283 if(!strncasecmp(action, function_table[i].action, strlen(action))) 05284 break; 05285 } 05286 if(debug) 05287 printf("@@@@ table index i = %d\n",i); 05288 if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){ 05289 /* Error, action not in table */ 05290 return DC_ERROR; 05291 } 05292 if(function_table[i].function == NULL){ 05293 /* Error, function undefined */ 05294 if(debug) 05295 printf("@@@@ NULL for action: %s\n",action); 05296 return DC_ERROR; 05297 } 05298 functiondigits = digits + strlen(vp->name); 05299 return (*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink); 05300 }
static int connect_link | ( | struct rpt * | myrpt, | |
char * | node, | |||
int | mode, | |||
int | perma | |||
) | [static] |
Definition at line 4467 of file app_rpt.c.
References __kickshort(), __mklinklist(), rpt::archivedir, ast_call(), AST_CDR_FLAG_POST_DISABLED, AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_request(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_true(), rpt_link::chan, rpt::conf, rpt_link::disced, donodelog(), finddelim(), free, rpt::lastlinknode, rpt::links, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::longestnode, malloc, MAX_RETRIES, rpt_link::max_retries, MAX_RETRIES_PERM, MAXLINKLIST, MAXNODESTR, rpt_link::mode, rpt::name, rpt_link::name, rpt_link::next, node_lookup(), rpt::p, rpt_link::reconnects, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, s, and strdup.
Referenced by function_ilink().
04468 { 04469 char *val, *s, *s1, *s2, *tele; 04470 char lstr[MAXLINKLIST],*strs[MAXLINKLIST]; 04471 char tmp[300], deststr[300] = "",modechange = 0; 04472 struct rpt_link *l; 04473 int reconnects = 0; 04474 int i,n; 04475 struct dahdi_confinfo ci; /* conference info */ 04476 04477 val = node_lookup(myrpt,node); 04478 if (!val){ 04479 if(strlen(node) >= myrpt->longestnode) 04480 return -1; /* No such node */ 04481 return 1; /* No match yet */ 04482 } 04483 if(debug > 3){ 04484 ast_log(LOG_NOTICE,"Connect attempt to node %s\n", node); 04485 ast_log(LOG_NOTICE,"Mode: %s\n",(mode)?"Transceive":"Monitor"); 04486 ast_log(LOG_NOTICE,"Connection type: %s\n",(perma)?"Permalink":"Normal"); 04487 } 04488 04489 strncpy(tmp,val,sizeof(tmp) - 1); 04490 s = tmp; 04491 s1 = strsep(&s,","); 04492 s2 = strsep(&s,","); 04493 rpt_mutex_lock(&myrpt->lock); 04494 l = myrpt->links.next; 04495 /* try to find this one in queue */ 04496 while(l != &myrpt->links){ 04497 if (l->name[0] == '0') 04498 { 04499 l = l->next; 04500 continue; 04501 } 04502 /* if found matching string */ 04503 if (!strcmp(l->name, node)) 04504 break; 04505 l = l->next; 04506 } 04507 /* if found */ 04508 if (l != &myrpt->links){ 04509 /* if already in this mode, just ignore */ 04510 if ((l->mode) || (!l->chan)) { 04511 rpt_mutex_unlock(&myrpt->lock); 04512 return 2; /* Already linked */ 04513 } 04514 reconnects = l->reconnects; 04515 rpt_mutex_unlock(&myrpt->lock); 04516 if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV); 04517 l->retries = l->max_retries + 1; 04518 l->disced = 2; 04519 modechange = 1; 04520 } else 04521 { 04522 __mklinklist(myrpt,NULL,lstr); 04523 rpt_mutex_unlock(&myrpt->lock); 04524 n = finddelim(lstr,strs,MAXLINKLIST); 04525 for(i = 0; i < n; i++) 04526 { 04527 if ((*strs[i] < '0') || 04528 (*strs[i] > '9')) strs[i]++; 04529 if (!strcmp(strs[i],node)) 04530 { 04531 return 2; /* Already linked */ 04532 } 04533 } 04534 } 04535 strncpy(myrpt->lastlinknode,node,MAXNODESTR - 1); 04536 /* establish call */ 04537 l = malloc(sizeof(struct rpt_link)); 04538 if (!l) 04539 { 04540 ast_log(LOG_WARNING, "Unable to malloc\n"); 04541 return -1; 04542 } 04543 /* zero the silly thing */ 04544 memset((char *)l,0,sizeof(struct rpt_link)); 04545 l->mode = mode; 04546 l->outbound = 1; 04547 l->thisconnected = 0; 04548 strncpy(l->name, node, MAXNODESTR - 1); 04549 l->isremote = (s && ast_true(s)); 04550 if (modechange) l->connected = 1; 04551 l->hasconnected = l->perma = perma; 04552 #ifdef ALLOW_LOCAL_CHANNELS 04553 if ((strncasecmp(s1,"iax2/", 5) == 0) || (strncasecmp(s1, "local/", 6) == 0)) 04554 strncpy(deststr, s1, sizeof(deststr)); 04555 else 04556 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 04557 #else 04558 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 04559 #endif 04560 tele = strchr(deststr, '/'); 04561 if (!tele){ 04562 ast_log(LOG_WARNING,"link3:Dial number (%s) must be in format tech/number\n",deststr); 04563 free(l); 04564 return -1; 04565 } 04566 *tele++ = 0; 04567 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 04568 if (l->chan){ 04569 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 04570 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 04571 #ifdef AST_CDR_FLAG_POST_DISABLED 04572 ast_set_flag(l->chan->cdr,AST_CDR_FLAG_POST_DISABLED); 04573 #endif 04574 l->chan->whentohangup = 0; 04575 l->chan->appl = "Apprpt"; 04576 l->chan->data = "(Remote Rx)"; 04577 if (debug > 3) 04578 ast_log(LOG_NOTICE, "rpt (remote) initiating call to %s/%s on %s\n", 04579 deststr, tele, l->chan->name); 04580 if(l->chan->cid.cid_num) 04581 free(l->chan->cid.cid_num); 04582 l->chan->cid.cid_num = strdup(myrpt->name); 04583 ast_call(l->chan,tele,999); 04584 } 04585 else { 04586 if(debug > 3) 04587 ast_log(LOG_NOTICE, "Unable to place call to %s/%s on %s\n", 04588 deststr,tele,l->chan->name); 04589 if (myrpt->p.archivedir) 04590 { 04591 char str[100]; 04592 sprintf(str,"LINKFAIL,%s",l->name); 04593 donodelog(myrpt,str); 04594 } 04595 free(l); 04596 return -1; 04597 } 04598 /* allocate a pseudo-channel thru asterisk */ 04599 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04600 if (!l->pchan){ 04601 ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n"); 04602 ast_hangup(l->chan); 04603 free(l); 04604 return -1; 04605 } 04606 ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR); 04607 ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR); 04608 #ifdef AST_CDR_FLAG_POST_DISABLED 04609 ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED); 04610 #endif 04611 /* make a conference for the tx */ 04612 ci.chan = 0; 04613 ci.confno = myrpt->conf; 04614 ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER; 04615 /* first put the channel on the conference in proper mode */ 04616 if (ioctl(l->pchan->fds[0], DAHDI_SETCONF, &ci) == -1) 04617 { 04618 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04619 ast_hangup(l->chan); 04620 ast_hangup(l->pchan); 04621 free(l); 04622 return -1; 04623 } 04624 rpt_mutex_lock(&myrpt->lock); 04625 l->reconnects = reconnects; 04626 /* insert at end of queue */ 04627 l->max_retries = MAX_RETRIES; 04628 if (perma) 04629 l->max_retries = MAX_RETRIES_PERM; 04630 if (l->isremote) l->retries = l->max_retries + 1; 04631 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 04632 __kickshort(myrpt); 04633 rpt_mutex_unlock(&myrpt->lock); 04634 return 0; 04635 }
static int decimals2int | ( | char * | fraction | ) | [static] |
Definition at line 6357 of file app_rpt.c.
Referenced by check_tx_freq().
06358 { 06359 int i; 06360 char len = strlen(fraction); 06361 int multiplier = 100000; 06362 int res = 0; 06363 06364 if(!len) 06365 return 0; 06366 for( i = 0 ; i < len ; i++, multiplier /= 10) 06367 res += (fraction[i] - '0') * multiplier; 06368 return res; 06369 }
static long diskavail | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 1024 of file app_rpt.c.
References rpt::archivedir, ast_log(), LOG_WARNING, rpt::name, and rpt::p.
Referenced by rpt().
01025 { 01026 struct statfs statfsbuf; 01027 01028 if (!myrpt->p.archivedir) return(0); 01029 if (statfs(myrpt->p.archivedir,&statfsbuf) == -1) 01030 { 01031 ast_log(LOG_WARNING,"Cannot get filesystem size for %s node %s\n", 01032 myrpt->p.archivedir,myrpt->name); 01033 return(-1); 01034 } 01035 return(statfsbuf.f_bavail); 01036 }
static void do_dtmf_local | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 1089 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, ast_channel::name, rpt_mutex_lock, rpt_mutex_unlock, and rpt::txchannel.
Referenced by function_ilink(), function_remote(), handle_link_data(), handle_remote_dtmf_digit(), and rpt().
01090 { 01091 int i; 01092 char digit; 01093 static const char* dtmf_tones[] = { 01094 "!941+1336/200,!0/200", /* 0 */ 01095 "!697+1209/200,!0/200", /* 1 */ 01096 "!697+1336/200,!0/200", /* 2 */ 01097 "!697+1477/200,!0/200", /* 3 */ 01098 "!770+1209/200,!0/200", /* 4 */ 01099 "!770+1336/200,!0/200", /* 5 */ 01100 "!770+1477/200,!0/200", /* 6 */ 01101 "!852+1209/200,!0/200", /* 7 */ 01102 "!852+1336/200,!0/200", /* 8 */ 01103 "!852+1477/200,!0/200", /* 9 */ 01104 "!697+1633/200,!0/200", /* A */ 01105 "!770+1633/200,!0/200", /* B */ 01106 "!852+1633/200,!0/200", /* C */ 01107 "!941+1633/200,!0/200", /* D */ 01108 "!941+1209/200,!0/200", /* * */ 01109 "!941+1477/200,!0/200" }; /* # */ 01110 01111 01112 if (c) 01113 { 01114 snprintf(myrpt->dtmf_local_str + strlen(myrpt->dtmf_local_str),sizeof(myrpt->dtmf_local_str) - 1,"%c",c); 01115 if (!myrpt->dtmf_local_timer) 01116 myrpt->dtmf_local_timer = DTMF_LOCAL_STARTTIME; 01117 } 01118 /* if at timeout */ 01119 if (myrpt->dtmf_local_timer == 1) 01120 { 01121 /* if anything in the string */ 01122 if (myrpt->dtmf_local_str[0]) 01123 { 01124 digit = myrpt->dtmf_local_str[0]; 01125 myrpt->dtmf_local_str[0] = 0; 01126 for(i = 1; myrpt->dtmf_local_str[i]; i++) 01127 { 01128 myrpt->dtmf_local_str[i - 1] = 01129 myrpt->dtmf_local_str[i]; 01130 } 01131 myrpt->dtmf_local_str[i - 1] = 0; 01132 myrpt->dtmf_local_timer = DTMF_LOCAL_TIME; 01133 rpt_mutex_unlock(&myrpt->lock); 01134 if (digit >= '0' && digit <='9') 01135 ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'0'], 0); 01136 else if (digit >= 'A' && digit <= 'D') 01137 ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'A'+10], 0); 01138 else if (digit == '*') 01139 ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[14], 0); 01140 else if (digit == '#') 01141 ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[15], 0); 01142 else { 01143 /* not handled */ 01144 ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, myrpt->txchannel->name); 01145 } 01146 rpt_mutex_lock(&myrpt->lock); 01147 } 01148 else 01149 { 01150 myrpt->dtmf_local_timer = 0; 01151 } 01152 } 01153 }
Definition at line 1038 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().
01039 { 01040 struct rpt_link *l; 01041 01042 l = myrpt->links.next; 01043 /* go thru all the links */ 01044 while(l != &myrpt->links) 01045 { 01046 if (!l->phonemode) 01047 { 01048 l = l->next; 01049 continue; 01050 } 01051 /* dont send to self */ 01052 if (mylink && (l == mylink)) 01053 { 01054 l = l->next; 01055 continue; 01056 } 01057 if (l->chan) ast_senddigit(l->chan,c); 01058 l = l->next; 01059 } 01060 return; 01061 }
static void do_scheduler | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 8654 of file app_rpt.c.
References ast_log(), ast_variable_browse(), ast_variable_retrieve(), rpt::cfg, rpt::curtv, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, LOG_NOTICE, LOG_WARNING, rpt::macro, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, ast_variable::name, ast_variable::next, rpt::p, rpt::remote, rpt_localtime(), rpt::s, rpt::skedstanzaname, rpt::sysstate_cur, and ast_variable::value.
Referenced by rpt().
08655 { 08656 int i,res; 08657 struct tm tmnow; 08658 struct ast_variable *skedlist; 08659 char *strs[5],*vp,*val,value[100]; 08660 08661 memcpy(&myrpt->lasttv, &myrpt->curtv, sizeof(struct timeval)); 08662 08663 if( (res = gettimeofday(&myrpt->curtv, NULL)) < 0) 08664 ast_log(LOG_NOTICE, "Scheduler gettime of day returned: %s\n", strerror(res)); 08665 08666 /* Try to get close to a 1 second resolution */ 08667 08668 if(myrpt->lasttv.tv_sec == myrpt->curtv.tv_sec) 08669 return; 08670 08671 rpt_localtime(&myrpt->curtv.tv_sec, &tmnow); 08672 08673 /* If midnight, then reset all daily statistics */ 08674 08675 if((tmnow.tm_hour == 0)&&(tmnow.tm_min == 0)&&(tmnow.tm_sec == 0)){ 08676 myrpt->dailykeyups = 0; 08677 myrpt->dailytxtime = 0; 08678 myrpt->dailykerchunks = 0; 08679 myrpt->dailyexecdcommands = 0; 08680 } 08681 08682 if(tmnow.tm_sec != 0) 08683 return; 08684 08685 /* Code below only executes once per minute */ 08686 08687 08688 /* Don't schedule if remote */ 08689 08690 if (myrpt->remote) 08691 return; 08692 08693 /* Don't schedule if disabled */ 08694 08695 if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable){ 08696 if(debug > 6) 08697 ast_log(LOG_NOTICE, "Scheduler disabled\n"); 08698 return; 08699 } 08700 08701 if(!myrpt->p.skedstanzaname){ /* No stanza means we do nothing */ 08702 if(debug > 6) 08703 ast_log(LOG_NOTICE,"No stanza for scheduler in rpt.conf\n"); 08704 return; 08705 } 08706 08707 /* get pointer to linked list of scheduler entries */ 08708 skedlist = ast_variable_browse(myrpt->cfg, myrpt->p.skedstanzaname); 08709 08710 if(debug > 6){ 08711 ast_log(LOG_NOTICE, "Time now: %02d:%02d %02d %02d %02d\n", 08712 tmnow.tm_hour,tmnow.tm_min,tmnow.tm_mday,tmnow.tm_mon + 1, tmnow.tm_wday); 08713 } 08714 /* walk the list */ 08715 for(; skedlist; skedlist = skedlist->next){ 08716 if(debug > 6) 08717 ast_log(LOG_NOTICE, "Scheduler entry %s = %s being considered\n",skedlist->name, skedlist->value); 08718 strncpy(value,skedlist->value,99); 08719 value[99] = 0; 08720 /* point to the substrings for minute, hour, dom, month, and dow */ 08721 for( i = 0, vp = value ; i < 5; i++){ 08722 if(!*vp) 08723 break; 08724 while((*vp == ' ') || (*vp == 0x09)) /* get rid of any leading white space */ 08725 vp++; 08726 strs[i] = vp; /* save pointer to beginning of substring */ 08727 while((*vp != ' ') && (*vp != 0x09) && (*vp != 0)) /* skip over substring */ 08728 vp++; 08729 if(*vp) 08730 *vp++ = 0; /* mark end of substring */ 08731 } 08732 if(debug > 6) 08733 ast_log(LOG_NOTICE, "i = %d, min = %s, hour = %s, mday=%s, mon=%s, wday=%s\n",i, 08734 strs[0], strs[1], strs[2], strs[3], strs[4]); 08735 if(i == 5){ 08736 if((*strs[0] != '*')&&(atoi(strs[0]) != tmnow.tm_min)) 08737 continue; 08738 if((*strs[1] != '*')&&(atoi(strs[1]) != tmnow.tm_hour)) 08739 continue; 08740 if((*strs[2] != '*')&&(atoi(strs[2]) != tmnow.tm_mday)) 08741 continue; 08742 if((*strs[3] != '*')&&(atoi(strs[3]) != tmnow.tm_mon + 1)) 08743 continue; 08744 if(atoi(strs[4]) == 7) 08745 strs[4] = "0"; 08746 if((*strs[4] != '*')&&(atoi(strs[4]) != tmnow.tm_wday)) 08747 continue; 08748 if(debug) 08749 ast_log(LOG_NOTICE, "Executing scheduler entry %s = %s\n", skedlist->name, skedlist->value); 08750 if(atoi(skedlist->name) == 0) 08751 return; /* Zero is reserved for the startup macro */ 08752 val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, skedlist->name); 08753 if (!val){ 08754 ast_log(LOG_WARNING,"Scheduler could not find macro %s\n",skedlist->name); 08755 return; /* Macro not found */ 08756 } 08757 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)){ 08758 ast_log(LOG_WARNING, "Scheduler could not execute macro %s: Macro buffer full\n", 08759 skedlist->name); 08760 return; /* Macro buffer full */ 08761 } 08762 myrpt->macrotimer = MACROTIME; 08763 strncat(myrpt->macrobuf,val,MAXMACRO - strlen(myrpt->macrobuf) - 1); 08764 } 08765 else{ 08766 ast_log(LOG_WARNING,"Malformed scheduler entry in rpt.conf: %s = %s\n", 08767 skedlist->name, skedlist->value); 08768 } 08769 } 08770 08771 }
static void donodelog | ( | struct rpt * | myrpt, | |
char * | str | |||
) | [static] |
Definition at line 1064 of file app_rpt.c.
References nodelog::archivedir, rpt::archivedir, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, malloc, rpt::name, nodeloglock, rpt::p, nodelog::prev, nodelog::str, and nodelog::timestamp.
Referenced by connect_link(), function_remote(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_data(), handle_remote_phone_dtmf(), local_dtmf_helper(), rpt(), and setrem().
01065 { 01066 struct nodelog *nodep; 01067 char datestr[100]; 01068 01069 if (!myrpt->p.archivedir) return; 01070 nodep = (struct nodelog *)malloc(sizeof(struct nodelog)); 01071 if (nodep == NULL) 01072 { 01073 ast_log(LOG_ERROR,"Cannot get memory for node log"); 01074 return; 01075 } 01076 time(&nodep->timestamp); 01077 strncpy(nodep->archivedir,myrpt->p.archivedir, 01078 sizeof(nodep->archivedir) - 1); 01079 strftime(datestr,sizeof(datestr) - 1,"%Y%m%d%H%M%S", 01080 localtime(&nodep->timestamp)); 01081 snprintf(nodep->str,sizeof(nodep->str) - 1,"%s %s,%s\n", 01082 myrpt->name,datestr,str); 01083 ast_mutex_lock(&nodeloglock); 01084 insque((struct qelem *) nodep, (struct qelem *) nodelog.prev); 01085 ast_mutex_unlock(&nodeloglock); 01086 }
static char* eatwhite | ( | char * | s | ) | [static] |
static int finddelim | ( | char * | str, | |
char * | strp[], | |||
int | limit | |||
) | [static] |
Definition at line 1307 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().
01308 { 01309 int i,l,inquo; 01310 01311 inquo = 0; 01312 i = 0; 01313 strp[i++] = str; 01314 if (!*str) 01315 { 01316 strp[0] = 0; 01317 return(0); 01318 } 01319 for(l = 0; *str && (l < limit) ; str++) 01320 { 01321 if (*str == QUOTECHR) 01322 { 01323 if (inquo) 01324 { 01325 *str = 0; 01326 inquo = 0; 01327 } 01328 else 01329 { 01330 strp[i - 1] = str + 1; 01331 inquo = 1; 01332 } 01333 } 01334 if ((*str == DELIMCHR) && (!inquo)) 01335 { 01336 *str = 0; 01337 l++; 01338 strp[i++] = str + 1; 01339 } 01340 } 01341 strp[i] = 0; 01342 return(i); 01343 01344 }
Definition at line 1242 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().
01243 { 01244 time_t now; 01245 int gotone; 01246 01247 time(&now); 01248 gotone = 0; 01249 /* if too much time, reset the skate machine */ 01250 if ((now - xlat->lastone) > MAXXLATTIME) 01251 { 01252 xlat->funcindex = xlat->endindex = 0; 01253 } 01254 if (xlat->funccharseq[0] && (c == xlat->funccharseq[xlat->funcindex++])) 01255 { 01256 time(&xlat->lastone); 01257 gotone = 1; 01258 if (!xlat->funccharseq[xlat->funcindex]) 01259 { 01260 xlat->funcindex = xlat->endindex = 0; 01261 return(myrpt->p.funcchar); 01262 } 01263 } else xlat->funcindex = 0; 01264 if (xlat->endcharseq[0] && (c == xlat->endcharseq[xlat->endindex++])) 01265 { 01266 time(&xlat->lastone); 01267 gotone = 1; 01268 if (!xlat->endcharseq[xlat->endindex]) 01269 { 01270 xlat->funcindex = xlat->endindex = 0; 01271 return(myrpt->p.endchar); 01272 } 01273 } else xlat->endindex = 0; 01274 /* if in middle of decode seq, send nothing back */ 01275 if (gotone) return(0); 01276 /* if no pass chars specified, return em all */ 01277 if (!xlat->passchars[0]) return(c); 01278 /* if a "pass char", pass it */ 01279 if (strchr(xlat->passchars,c)) return(c); 01280 return(0); 01281 }
static int function_autopatchdn | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 4998 of file app_rpt.c.
References rpt::callmode, DC_COMPLETE, DC_ERROR, rpt::lock, rpt::p, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::s, rpt::sysstate_cur, and TERM.
04999 { 05000 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 05001 return DC_ERROR; 05002 05003 if(debug) 05004 printf("@@@@ Autopatch down\n"); 05005 05006 rpt_mutex_lock(&myrpt->lock); 05007 05008 if (!myrpt->callmode){ 05009 rpt_mutex_unlock(&myrpt->lock); 05010 return DC_COMPLETE; 05011 } 05012 05013 myrpt->callmode = 0; 05014 rpt_mutex_unlock(&myrpt->lock); 05015 rpt_telemetry(myrpt, TERM, NULL); 05016 return DC_COMPLETE; 05017 }
static int function_autopatchup | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 4901 of file app_rpt.c.
References ast_log(), ast_pthread_create, ast_strdupa, rpt::callmode, rpt::cidx, DC_COMPLETE, DC_ERROR, rpt::endchar, rpt::exten, finddelim(), rpt::lock, LOG_ERROR, matchkeyword(), MAXPATCHCONTEXT, rpt::mydtmf, rpt::ourcontext, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchnoct, rpt::patchquiet, rpt_call(), rpt::rpt_call_thread, rpt_mutex_lock, rpt_mutex_unlock, rpt::s, skipchars(), and rpt::sysstate_cur.
04902 { 04903 pthread_attr_t attr; 04904 int i, index, paramlength; 04905 char *lparam; 04906 char *value = NULL; 04907 char *paramlist[20]; 04908 04909 static char *keywords[] = { 04910 "context", 04911 "dialtime", 04912 "farenddisconnect", 04913 "noct", 04914 "quiet", 04915 NULL 04916 }; 04917 04918 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 04919 return DC_ERROR; 04920 04921 if(debug) 04922 printf("@@@@ Autopatch up\n"); 04923 04924 if(!myrpt->callmode){ 04925 /* Set defaults */ 04926 myrpt->patchnoct = 0; 04927 myrpt->patchdialtime = 0; 04928 myrpt->patchfarenddisconnect = 0; 04929 myrpt->patchquiet = 0; 04930 strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT); 04931 04932 if(param){ 04933 /* Process parameter list */ 04934 lparam = ast_strdupa(param); 04935 if(!lparam){ 04936 ast_log(LOG_ERROR,"App_rpt out of memory on line %d\n",__LINE__); 04937 return DC_ERROR; 04938 } 04939 paramlength = finddelim(lparam, paramlist, 20); 04940 for(i = 0; i < paramlength; i++){ 04941 index = matchkeyword(paramlist[i], &value, keywords); 04942 if(value) 04943 value = skipchars(value, "= "); 04944 switch(index){ 04945 04946 case 1: /* context */ 04947 strncpy(myrpt->patchcontext, value, MAXPATCHCONTEXT - 1) ; 04948 break; 04949 04950 case 2: /* dialtime */ 04951 myrpt->patchdialtime = atoi(value); 04952 break; 04953 04954 case 3: /* farenddisconnect */ 04955 myrpt->patchfarenddisconnect = atoi(value); 04956 break; 04957 04958 case 4: /* noct */ 04959 myrpt->patchnoct = atoi(value); 04960 break; 04961 04962 case 5: /* quiet */ 04963 myrpt->patchquiet = atoi(value); 04964 break; 04965 04966 default: 04967 break; 04968 } 04969 } 04970 } 04971 } 04972 04973 rpt_mutex_lock(&myrpt->lock); 04974 04975 /* if on call, force * into current audio stream */ 04976 04977 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){ 04978 myrpt->mydtmf = myrpt->p.endchar; 04979 } 04980 if (myrpt->callmode){ 04981 rpt_mutex_unlock(&myrpt->lock); 04982 return DC_COMPLETE; 04983 } 04984 myrpt->callmode = 1; 04985 myrpt->cidx = 0; 04986 myrpt->exten[myrpt->cidx] = 0; 04987 rpt_mutex_unlock(&myrpt->lock); 04988 pthread_attr_init(&attr); 04989 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04990 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt); 04991 return DC_COMPLETE; 04992 }
static int function_cop | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5099 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.
05100 { 05101 char string[16]; 05102 int res; 05103 05104 if(!param) 05105 return DC_ERROR; 05106 05107 switch(myatoi(param)){ 05108 case 1: /* System reset */ 05109 res = system("killall -9 asterisk"); 05110 return DC_COMPLETE; 05111 05112 case 2: 05113 myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 0; 05114 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA"); 05115 return DC_COMPLETE; 05116 05117 case 3: 05118 myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 1; 05119 return DC_COMPLETE; 05120 05121 case 4: /* test tone on */ 05122 if (myrpt->stopgen < 0) 05123 { 05124 myrpt->stopgen = 1; 05125 } 05126 else 05127 { 05128 myrpt->stopgen = 0; 05129 rpt_telemetry(myrpt, TEST_TONE, NULL); 05130 } 05131 return DC_COMPLETE; 05132 05133 case 5: /* Disgorge variables to log for debug purposes */ 05134 myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 05135 return DC_COMPLETE; 05136 05137 case 6: /* Simulate COR being activated (phone only) */ 05138 if (command_source != SOURCE_PHONE) return DC_INDETERMINATE; 05139 return DC_DOKEY; 05140 05141 05142 case 7: /* Time out timer enable */ 05143 myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 0; 05144 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTENA"); 05145 return DC_COMPLETE; 05146 05147 case 8: /* Time out timer disable */ 05148 myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 1; 05149 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTDIS"); 05150 return DC_COMPLETE; 05151 05152 case 9: /* Autopatch enable */ 05153 myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 0; 05154 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APENA"); 05155 return DC_COMPLETE; 05156 05157 case 10: /* Autopatch disable */ 05158 myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 1; 05159 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APDIS"); 05160 return DC_COMPLETE; 05161 05162 case 11: /* Link Enable */ 05163 myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 0; 05164 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKENA"); 05165 return DC_COMPLETE; 05166 05167 case 12: /* Link Disable */ 05168 myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 1; 05169 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKDIS"); 05170 return DC_COMPLETE; 05171 05172 case 13: /* Query System State */ 05173 string[0] = string[1] = 'S'; 05174 string[2] = myrpt->p.sysstate_cur + '0'; 05175 string[3] = '\0'; 05176 rpt_telemetry(myrpt, ARB_ALPHA, (void *) string); 05177 return DC_COMPLETE; 05178 05179 case 14: /* Change System State */ 05180 if(strlen(digitbuf) == 0) 05181 break; 05182 if((digitbuf[0] < '0') || (digitbuf[0] > '9')) 05183 return DC_ERROR; 05184 myrpt->p.sysstate_cur = digitbuf[0] - '0'; 05185 string[0] = string[1] = 'S'; 05186 string[2] = myrpt->p.sysstate_cur + '0'; 05187 string[3] = '\0'; 05188 rpt_telemetry(myrpt, ARB_ALPHA, (void *) string); 05189 return DC_COMPLETE; 05190 05191 case 15: /* Scheduler Enable */ 05192 myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 0; 05193 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKENA"); 05194 return DC_COMPLETE; 05195 05196 case 16: /* Scheduler Disable */ 05197 myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 1; 05198 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKDIS"); 05199 return DC_COMPLETE; 05200 05201 case 17: /* User functions Enable */ 05202 myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 0; 05203 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFENA"); 05204 return DC_COMPLETE; 05205 05206 case 18: /* User Functions Disable */ 05207 myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 1; 05208 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFDIS"); 05209 return DC_COMPLETE; 05210 05211 case 19: /* Alternate Tail Enable */ 05212 myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 1; 05213 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATENA"); 05214 return DC_COMPLETE; 05215 05216 case 20: /* Alternate Tail Disable */ 05217 myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 0; 05218 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATDIS"); 05219 return DC_COMPLETE; 05220 } 05221 return DC_INDETERMINATE; 05222 }
static int function_ilink | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 4643 of file app_rpt.c.
References AST_FRAME_TEXT, ast_log(), ast_safe_sleep(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt_link::chan, rpt::cmdnode, COMPLETE, connect_link(), CONNFAIL, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt_link::disced, do_dtmf_local(), finddelim(), ast_frame::frametype, FULLSTATUS, rpt::lastlinknode, LASTNODEKEY, rpt::links, rpt::lock, LOG_NOTICE, rpt::longestnode, ast_frame::mallocd, MAX_RETRIES, rpt_link::max_retries, MAXLINKLIST, MAXNODESTR, mdc1200_notify(), rpt_link::mode, myatoi(), rpt::name, rpt_link::name, rpt_link::next, node_lookup(), ast_frame::offset, rpt::p, rpt_link::perma, rpt::propagate_dtmf, rpt::propagate_phonedtmf, REMALREADY, REMGO, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::s, s, ast_frame::samples, rpt::savednodes, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, SOURCE_RPT, STATUS, ast_frame::subclass, and rpt::sysstate_cur.
04644 { 04645 04646 char *val, *s, *s1, *s2; 04647 char tmp[300]; 04648 char digitbuf[MAXNODESTR],*strs[MAXLINKLIST]; 04649 char mode,perma; 04650 struct rpt_link *l; 04651 int i,r; 04652 04653 if(!param) 04654 return DC_ERROR; 04655 04656 04657 if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable ) 04658 return DC_ERROR; 04659 04660 strncpy(digitbuf,digits,MAXNODESTR - 1); 04661 04662 if(debug > 6) 04663 printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 04664 04665 switch(myatoi(param)){ 04666 case 11: /* Perm Link off */ 04667 case 1: /* Link off */ 04668 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04669 strcpy(digitbuf,myrpt->lastlinknode); 04670 val = node_lookup(myrpt,digitbuf); 04671 if (!val){ 04672 if(strlen(digitbuf) >= myrpt->longestnode) 04673 return DC_ERROR; 04674 break; 04675 } 04676 strncpy(tmp,val,sizeof(tmp) - 1); 04677 s = tmp; 04678 s1 = strsep(&s,","); 04679 s2 = strsep(&s,","); 04680 rpt_mutex_lock(&myrpt->lock); 04681 l = myrpt->links.next; 04682 /* try to find this one in queue */ 04683 while(l != &myrpt->links){ 04684 if (l->name[0] == '0') 04685 { 04686 l = l->next; 04687 continue; 04688 } 04689 /* if found matching string */ 04690 if (!strcmp(l->name, digitbuf)) 04691 break; 04692 l = l->next; 04693 } 04694 if (l != &myrpt->links){ /* if found */ 04695 struct ast_frame wf; 04696 04697 /* must use perm command on perm link */ 04698 if ((myatoi(param) < 10) && 04699 (l->max_retries > MAX_RETRIES)) 04700 { 04701 rpt_mutex_unlock(&myrpt->lock); 04702 return DC_COMPLETE; 04703 } 04704 strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1); 04705 l->retries = l->max_retries + 1; 04706 l->disced = 1; 04707 rpt_mutex_unlock(&myrpt->lock); 04708 wf.frametype = AST_FRAME_TEXT; 04709 wf.subclass = 0; 04710 wf.offset = 0; 04711 wf.mallocd = 0; 04712 wf.datalen = strlen(discstr) + 1; 04713 wf.samples = 0; 04714 wf.data = discstr; 04715 if (l->chan) 04716 { 04717 ast_write(l->chan,&wf); 04718 if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR; 04719 ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 04720 } 04721 rpt_telemetry(myrpt, COMPLETE, NULL); 04722 return DC_COMPLETE; 04723 } 04724 rpt_mutex_unlock(&myrpt->lock); 04725 return DC_COMPLETE; 04726 case 2: /* Link Monitor */ 04727 case 3: /* Link transceive */ 04728 case 12: /* Link Monitor permanent */ 04729 case 13: /* Link transceive permanent */ 04730 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04731 strcpy(digitbuf,myrpt->lastlinknode); 04732 /* Attempt connection */ 04733 perma = (atoi(param) > 10) ? 1 : 0; 04734 mode = (atoi(param) & 1) ? 1 : 0; 04735 r = connect_link(myrpt, digitbuf, mode, perma); 04736 switch(r){ 04737 case 0: 04738 rpt_telemetry(myrpt, COMPLETE, NULL); 04739 return DC_COMPLETE; 04740 04741 case 1: 04742 break; 04743 04744 case 2: 04745 rpt_telemetry(myrpt, REMALREADY, NULL); 04746 return DC_COMPLETE; 04747 04748 default: 04749 rpt_telemetry(myrpt, CONNFAIL, NULL); 04750 return DC_COMPLETE; 04751 } 04752 break; 04753 04754 case 4: /* Enter Command Mode */ 04755 04756 /* if doesnt allow link cmd, or no links active, return */ 04757 if (((command_source != SOURCE_RPT) && 04758 (command_source != SOURCE_PHONE) && 04759 (command_source != SOURCE_DPHONE)) || 04760 (myrpt->links.next == &myrpt->links)) 04761 return DC_COMPLETE; 04762 04763 /* if already in cmd mode, or selected self, fughetabahtit */ 04764 if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){ 04765 04766 rpt_telemetry(myrpt, REMALREADY, NULL); 04767 return DC_COMPLETE; 04768 } 04769 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 04770 strcpy(digitbuf,myrpt->lastlinknode); 04771 /* node must at least exist in list */ 04772 val = node_lookup(myrpt,digitbuf); 04773 if (!val){ 04774 if(strlen(digitbuf) >= myrpt->longestnode) 04775 return DC_ERROR; 04776 break; 04777 04778 } 04779 rpt_mutex_lock(&myrpt->lock); 04780 strcpy(myrpt->lastlinknode,digitbuf); 04781 strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1); 04782 rpt_mutex_unlock(&myrpt->lock); 04783 rpt_telemetry(myrpt, REMGO, NULL); 04784 return DC_COMPLETE; 04785 04786 case 5: /* Status */ 04787 rpt_telemetry(myrpt, STATUS, NULL); 04788 return DC_COMPLETE; 04789 04790 case 15: /* Full Status */ 04791 rpt_telemetry(myrpt, FULLSTATUS, NULL); 04792 return DC_COMPLETE; 04793 04794 04795 case 6: /* All Links Off, including permalinks */ 04796 rpt_mutex_lock(&myrpt->lock); 04797 myrpt->savednodes[0] = 0; 04798 l = myrpt->links.next; 04799 /* loop through all links */ 04800 while(l != &myrpt->links){ 04801 struct ast_frame wf; 04802 if (l->name[0] == '0') /* Skip any IAXRPT monitoring */ 04803 { 04804 l = l->next; 04805 continue; 04806 } 04807 /* Make a string of disconnected nodes for possible restoration */ 04808 sprintf(tmp,"%c%c%s",(l->mode) ? 'X' : 'M',(l->perma) ? 'P':'T',l->name); 04809 if(strlen(tmp) + strlen(myrpt->savednodes) + 1 < MAXNODESTR){ 04810 if(myrpt->savednodes[0]) 04811 strcat(myrpt->savednodes, ","); 04812 strcat(myrpt->savednodes, tmp); 04813 } 04814 l->retries = l->max_retries + 1; 04815 l->disced = 2; /* Silently disconnect */ 04816 rpt_mutex_unlock(&myrpt->lock); 04817 /* ast_log(LOG_NOTICE,"dumping link %s\n",l->name); */ 04818 04819 wf.frametype = AST_FRAME_TEXT; 04820 wf.subclass = 0; 04821 wf.offset = 0; 04822 wf.mallocd = 0; 04823 wf.datalen = strlen(discstr) + 1; 04824 wf.samples = 0; 04825 wf.data = discstr; 04826 if (l->chan) 04827 { 04828 ast_write(l->chan,&wf); 04829 ast_safe_sleep(l->chan,250); /* It's dead already, why check the return value? */ 04830 ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 04831 } 04832 rpt_mutex_lock(&myrpt->lock); 04833 l = l->next; 04834 } 04835 rpt_mutex_unlock(&myrpt->lock); 04836 if(debug > 3) 04837 ast_log(LOG_NOTICE,"Nodes disconnected: %s\n",myrpt->savednodes); 04838 rpt_telemetry(myrpt, COMPLETE, NULL); 04839 return DC_COMPLETE; 04840 04841 case 7: /* Identify last node which keyed us up */ 04842 rpt_telemetry(myrpt, LASTNODEKEY, NULL); 04843 break; 04844 04845 04846 #ifdef _MDC_DECODE_H_ 04847 case 8: 04848 myrpt->lastunit = 0xd00d; 04849 mdc1200_notify(myrpt,NULL,myrpt->lastunit); 04850 mdc1200_send(myrpt,myrpt->lastunit); 04851 break; 04852 #endif 04853 04854 case 16: /* Restore links disconnected with "disconnect all links" command */ 04855 strcpy(tmp, myrpt->savednodes); /* Make a copy */ 04856 finddelim(tmp, strs, MAXLINKLIST); /* convert into substrings */ 04857 for(i = 0; tmp[0] && strs[i] != NULL && i < MAXLINKLIST; i++){ 04858 s1 = strs[i]; 04859 mode = (s1[0] == 'X') ? 1 : 0; 04860 perma = (s1[1] == 'P') ? 1 : 0; 04861 connect_link(myrpt, s1 + 2, mode, perma); /* Try to reconnect */ 04862 } 04863 rpt_telemetry(myrpt, COMPLETE, NULL); 04864 break; 04865 04866 case 200: 04867 case 201: 04868 case 202: 04869 case 203: 04870 case 204: 04871 case 205: 04872 case 206: 04873 case 207: 04874 case 208: 04875 case 209: 04876 case 210: 04877 case 211: 04878 case 212: 04879 case 213: 04880 case 214: 04881 case 215: 04882 if (((myrpt->p.propagate_dtmf) && 04883 (command_source == SOURCE_LNK)) || 04884 ((myrpt->p.propagate_phonedtmf) && 04885 ((command_source == SOURCE_PHONE) || 04886 (command_source == SOURCE_DPHONE)))) 04887 do_dtmf_local(myrpt, 04888 remdtmfstr[myatoi(param) - 200]); 04889 default: 04890 return DC_ERROR; 04891 04892 } 04893 04894 return DC_INDETERMINATE; 04895 }
static int function_macro | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5054 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.
05055 { 05056 05057 char *val; 05058 int i; 05059 if (myrpt->remote) 05060 return DC_ERROR; 05061 05062 if(debug) 05063 printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 05064 05065 if(strlen(digitbuf) < 1) /* needs 1 digit */ 05066 return DC_INDETERMINATE; 05067 05068 for(i = 0 ; i < digitbuf[i] ; i++) { 05069 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 05070 return DC_ERROR; 05071 } 05072 05073 if (*digitbuf == '0') val = myrpt->p.startupmacro; 05074 else val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, digitbuf); 05075 /* param was 1 for local buf */ 05076 if (!val){ 05077 if (strlen(digitbuf) < myrpt->macro_longest) 05078 return DC_INDETERMINATE; 05079 rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL); 05080 return DC_COMPLETE; 05081 } 05082 rpt_mutex_lock(&myrpt->lock); 05083 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)) 05084 { 05085 rpt_mutex_unlock(&myrpt->lock); 05086 rpt_telemetry(myrpt, MACRO_BUSY, NULL); 05087 return DC_ERROR; 05088 } 05089 myrpt->macrotimer = MACROTIME; 05090 strncat(myrpt->macrobuf, val, MAXMACRO - strlen(myrpt->macrobuf) - 1); 05091 rpt_mutex_unlock(&myrpt->lock); 05092 return DC_COMPLETE; 05093 }
static int function_remote | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 7756 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, TUNE, rpt::tunerequest, rpt::txchannel, rpt::txpl, and rpt::txplon.
07757 { 07758 char *s,*s1,*s2; 07759 int i,j,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode=0; 07760 intptr_t p; 07761 char multimode = 0; 07762 char oc,*cp,*cp1,*cp2; 07763 char tmp[20], freq[20] = "", savestr[20] = ""; 07764 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07765 07766 if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK)) 07767 return DC_ERROR; 07768 07769 p = myatoi(param); 07770 07771 if ((p != 99) && (p != 5) && (p != 140) && myrpt->p.authlevel && 07772 (!myrpt->loginlevel[0])) return DC_ERROR; 07773 multimode = multimode_capable(myrpt); 07774 07775 switch(p){ 07776 07777 case 1: /* retrieve memory */ 07778 if(strlen(digitbuf) < 2) /* needs 2 digits */ 07779 break; 07780 07781 for(i = 0 ; i < 2 ; i++){ 07782 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07783 return DC_ERROR; 07784 } 07785 07786 r = retreive_memory(myrpt, digitbuf); 07787 if (r < 0){ 07788 rpt_telemetry(myrpt,MEMNOTFOUND,NULL); 07789 return DC_COMPLETE; 07790 } 07791 if (r > 0){ 07792 return DC_ERROR; 07793 } 07794 if (setrem(myrpt) == -1) return DC_ERROR; 07795 return DC_COMPLETE; 07796 07797 case 2: /* set freq and offset */ 07798 07799 07800 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */ 07801 if(digitbuf[i] == '*'){ 07802 j++; 07803 continue; 07804 } 07805 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07806 goto invalid_freq; 07807 else{ 07808 if(j == 0) 07809 l++; /* # of digits before first * */ 07810 if(j == 1) 07811 k++; /* # of digits after first * */ 07812 } 07813 } 07814 07815 i = strlen(digitbuf) - 1; 07816 if(multimode){ 07817 if((j > 2) || (l > 3) || (k > 6)) 07818 goto invalid_freq; /* &^@#! */ 07819 } 07820 else{ 07821 if((j > 2) || (l > 4) || (k > 3)) 07822 goto invalid_freq; /* &^@#! */ 07823 } 07824 07825 /* Wait for M+*K+* */ 07826 07827 if(j < 2) 07828 break; /* Not yet */ 07829 07830 /* We have a frequency */ 07831 07832 strncpy(tmp, digitbuf ,sizeof(tmp) - 1); 07833 07834 s = tmp; 07835 s1 = strsep(&s, "*"); /* Pick off MHz */ 07836 s2 = strsep(&s,"*"); /* Pick off KHz and Hz */ 07837 ls2 = strlen(s2); 07838 07839 switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */ 07840 case 1: 07841 ht = 0; 07842 k = 100 * atoi(s2); 07843 break; 07844 07845 case 2: 07846 ht = 0; 07847 k = 10 * atoi(s2); 07848 break; 07849 07850 case 3: 07851 if(!multimode){ 07852 if((s2[2] != '0')&&(s2[2] != '5')) 07853 goto invalid_freq; 07854 } 07855 ht = 0; 07856 k = atoi(s2); 07857 break; 07858 case 4: 07859 k = atoi(s2)/10; 07860 ht = 10 * (atoi(s2+(ls2-1))); 07861 break; 07862 07863 case 5: 07864 k = atoi(s2)/100; 07865 ht = (atoi(s2+(ls2-2))); 07866 break; 07867 07868 default: 07869 goto invalid_freq; 07870 } 07871 07872 /* Check frequency for validity and establish a default mode */ 07873 07874 snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht); 07875 07876 if(debug) 07877 printf("New frequency: %s\n", freq); 07878 07879 split_freq(mhz, decimals, freq); 07880 m = atoi(mhz); 07881 d = atoi(decimals); 07882 07883 if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */ 07884 goto invalid_freq; 07885 07886 07887 if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */ 07888 break; /* Not yet */ 07889 07890 07891 offset = REM_SIMPLEX; /* Assume simplex */ 07892 07893 if(defmode == REM_MODE_FM){ 07894 oc = *s; /* Pick off offset */ 07895 07896 if (oc){ 07897 switch(oc){ 07898 case '1': 07899 offset = REM_MINUS; 07900 break; 07901 07902 case '2': 07903 offset = REM_SIMPLEX; 07904 break; 07905 07906 case '3': 07907 offset = REM_PLUS; 07908 break; 07909 07910 default: 07911 goto invalid_freq; 07912 } 07913 } 07914 } 07915 offsave = myrpt->offset; 07916 modesave = myrpt->remmode; 07917 strncpy(savestr, myrpt->freq, sizeof(savestr) - 1); 07918 strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1); 07919 myrpt->offset = offset; 07920 myrpt->remmode = defmode; 07921 07922 if (setrem(myrpt) == -1){ 07923 myrpt->offset = offsave; 07924 myrpt->remmode = modesave; 07925 strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1); 07926 goto invalid_freq; 07927 } 07928 07929 return DC_COMPLETE; 07930 07931 invalid_freq: 07932 rpt_telemetry(myrpt,INVFREQ,NULL); 07933 return DC_ERROR; 07934 07935 case 3: /* set rx PL tone */ 07936 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 07937 if(digitbuf[i] == '*'){ 07938 j++; 07939 continue; 07940 } 07941 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07942 return DC_ERROR; 07943 else{ 07944 if(j) 07945 l++; 07946 else 07947 k++; 07948 } 07949 } 07950 if((j > 1) || (k > 3) || (l > 1)) 07951 return DC_ERROR; /* &$@^! */ 07952 i = strlen(digitbuf) - 1; 07953 if((j != 1) || (k < 2)|| (l != 1)) 07954 break; /* Not yet */ 07955 if(debug) 07956 printf("PL digits entered %s\n", digitbuf); 07957 07958 strncpy(tmp, digitbuf, sizeof(tmp) - 1); 07959 /* see if we have at least 1 */ 07960 s = strchr(tmp,'*'); 07961 if(s) 07962 *s = '.'; 07963 strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1); 07964 strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1); 07965 if(!strcmp(myrpt->remote, remote_rig_rbi)) 07966 { 07967 strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1); 07968 } 07969 if (setrem(myrpt) == -1){ 07970 strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1); 07971 return DC_ERROR; 07972 } 07973 07974 07975 return DC_COMPLETE; 07976 07977 case 4: /* set tx PL tone */ 07978 /* cant set tx tone on RBI (rx tone does both) */ 07979 if(!strcmp(myrpt->remote, remote_rig_rbi)) 07980 return DC_ERROR; 07981 if(!strcmp(myrpt->remote, remote_rig_ic706)) 07982 return DC_ERROR; 07983 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 07984 if(digitbuf[i] == '*'){ 07985 j++; 07986 continue; 07987 } 07988 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 07989 return DC_ERROR; 07990 else{ 07991 if(j) 07992 l++; 07993 else 07994 k++; 07995 } 07996 } 07997 if((j > 1) || (k > 3) || (l > 1)) 07998 return DC_ERROR; /* &$@^! */ 07999 i = strlen(digitbuf) - 1; 08000 if((j != 1) || (k < 2)|| (l != 1)) 08001 break; /* Not yet */ 08002 if(debug) 08003 printf("PL digits entered %s\n", digitbuf); 08004 08005 strncpy(tmp, digitbuf, sizeof(tmp) - 1); 08006 /* see if we have at least 1 */ 08007 s = strchr(tmp,'*'); 08008 if(s) 08009 *s = '.'; 08010 strncpy(savestr, myrpt->txpl, sizeof(savestr) - 1); 08011 strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1); 08012 08013 if (setrem(myrpt) == -1){ 08014 strncpy(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1); 08015 return DC_ERROR; 08016 } 08017 08018 08019 return DC_COMPLETE; 08020 08021 08022 case 6: /* MODE (FM,USB,LSB,AM) */ 08023 if(strlen(digitbuf) < 1) 08024 break; 08025 08026 if(!multimode) 08027 return DC_ERROR; /* Multimode radios only */ 08028 08029 switch(*digitbuf){ 08030 case '1': 08031 split_freq(mhz, decimals, myrpt->freq); 08032 m=atoi(mhz); 08033 if(m < 29) /* No FM allowed below 29MHz! */ 08034 return DC_ERROR; 08035 myrpt->remmode = REM_MODE_FM; 08036 08037 rpt_telemetry(myrpt,REMMODE,NULL); 08038 break; 08039 08040 case '2': 08041 myrpt->remmode = REM_MODE_USB; 08042 rpt_telemetry(myrpt,REMMODE,NULL); 08043 break; 08044 08045 case '3': 08046 myrpt->remmode = REM_MODE_LSB; 08047 rpt_telemetry(myrpt,REMMODE,NULL); 08048 break; 08049 08050 case '4': 08051 myrpt->remmode = REM_MODE_AM; 08052 rpt_telemetry(myrpt,REMMODE,NULL); 08053 break; 08054 08055 default: 08056 return DC_ERROR; 08057 } 08058 08059 if(setrem(myrpt)) 08060 return DC_ERROR; 08061 return DC_COMPLETEQUIET; 08062 case 99: 08063 /* cant log in when logged in */ 08064 if (myrpt->loginlevel[0]) 08065 return DC_ERROR; 08066 *myrpt->loginuser = 0; 08067 myrpt->loginlevel[0] = 0; 08068 cp = strdup(param); 08069 cp1 = strchr(cp,','); 08070 ast_mutex_lock(&myrpt->lock); 08071 if (cp1) 08072 { 08073 *cp1 = 0; 08074 cp2 = strchr(cp1 + 1,','); 08075 if (cp2) 08076 { 08077 *cp2 = 0; 08078 strncpy(myrpt->loginlevel,cp2 + 1, 08079 sizeof(myrpt->loginlevel) - 1); 08080 } 08081 strncpy(myrpt->loginuser,cp1 + 1,sizeof(myrpt->loginuser)); 08082 ast_mutex_unlock(&myrpt->lock); 08083 if (myrpt->p.archivedir) 08084 { 08085 char str[100]; 08086 08087 sprintf(str,"LOGIN,%s,%s", 08088 myrpt->loginuser,myrpt->loginlevel); 08089 donodelog(myrpt,str); 08090 } 08091 if (debug) 08092 printf("loginuser %s level %s\n",myrpt->loginuser,myrpt->loginlevel); 08093 rpt_telemetry(myrpt,REMLOGIN,NULL); 08094 } 08095 free(cp); 08096 return DC_COMPLETEQUIET; 08097 case 100: /* RX PL Off */ 08098 myrpt->rxplon = 0; 08099 setrem(myrpt); 08100 rpt_telemetry(myrpt,REMXXX,(void *)p); 08101 return DC_COMPLETEQUIET; 08102 case 101: /* RX PL On */ 08103 myrpt->rxplon = 1; 08104 setrem(myrpt); 08105 rpt_telemetry(myrpt,REMXXX,(void *)p); 08106 return DC_COMPLETEQUIET; 08107 case 102: /* TX PL Off */ 08108 myrpt->txplon = 0; 08109 setrem(myrpt); 08110 rpt_telemetry(myrpt,REMXXX,(void *)p); 08111 return DC_COMPLETEQUIET; 08112 case 103: /* TX PL On */ 08113 myrpt->txplon = 1; 08114 setrem(myrpt); 08115 rpt_telemetry(myrpt,REMXXX,(void *)p); 08116 return DC_COMPLETEQUIET; 08117 case 104: /* Low Power */ 08118 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08119 return DC_ERROR; 08120 myrpt->powerlevel = REM_LOWPWR; 08121 setrem(myrpt); 08122 rpt_telemetry(myrpt,REMXXX,(void *)p); 08123 return DC_COMPLETEQUIET; 08124 case 105: /* Medium Power */ 08125 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08126 return DC_ERROR; 08127 myrpt->powerlevel = REM_MEDPWR; 08128 setrem(myrpt); 08129 rpt_telemetry(myrpt,REMXXX,(void *)p); 08130 return DC_COMPLETEQUIET; 08131 case 106: /* Hi Power */ 08132 if(!strcmp(myrpt->remote, remote_rig_ic706)) 08133 return DC_ERROR; 08134 myrpt->powerlevel = REM_HIPWR; 08135 setrem(myrpt); 08136 rpt_telemetry(myrpt,REMXXX,(void *)p); 08137 return DC_COMPLETEQUIET; 08138 case 107: /* Bump down 20Hz */ 08139 multimode_bump_freq(myrpt, -20); 08140 return DC_COMPLETE; 08141 case 108: /* Bump down 100Hz */ 08142 multimode_bump_freq(myrpt, -100); 08143 return DC_COMPLETE; 08144 case 109: /* Bump down 500Hz */ 08145 multimode_bump_freq(myrpt, -500); 08146 return DC_COMPLETE; 08147 case 110: /* Bump up 20Hz */ 08148 multimode_bump_freq(myrpt, 20); 08149 return DC_COMPLETE; 08150 case 111: /* Bump up 100Hz */ 08151 multimode_bump_freq(myrpt, 100); 08152 return DC_COMPLETE; 08153 case 112: /* Bump up 500Hz */ 08154 multimode_bump_freq(myrpt, 500); 08155 return DC_COMPLETE; 08156 case 113: /* Scan down slow */ 08157 myrpt->scantimer = REM_SCANTIME; 08158 myrpt->hfscanmode = HF_SCAN_DOWN_SLOW; 08159 rpt_telemetry(myrpt,REMXXX,(void *)p); 08160 return DC_COMPLETEQUIET; 08161 case 114: /* Scan down quick */ 08162 myrpt->scantimer = REM_SCANTIME; 08163 myrpt->hfscanmode = HF_SCAN_DOWN_QUICK; 08164 rpt_telemetry(myrpt,REMXXX,(void *)p); 08165 return DC_COMPLETEQUIET; 08166 case 115: /* Scan down fast */ 08167 myrpt->scantimer = REM_SCANTIME; 08168 myrpt->hfscanmode = HF_SCAN_DOWN_FAST; 08169 rpt_telemetry(myrpt,REMXXX,(void *)p); 08170 return DC_COMPLETEQUIET; 08171 case 116: /* Scan up slow */ 08172 myrpt->scantimer = REM_SCANTIME; 08173 myrpt->hfscanmode = HF_SCAN_UP_SLOW; 08174 rpt_telemetry(myrpt,REMXXX,(void *)p); 08175 return DC_COMPLETEQUIET; 08176 case 117: /* Scan up quick */ 08177 myrpt->scantimer = REM_SCANTIME; 08178 myrpt->hfscanmode = HF_SCAN_UP_QUICK; 08179 rpt_telemetry(myrpt,REMXXX,(void *)p); 08180 return DC_COMPLETEQUIET; 08181 case 118: /* Scan up fast */ 08182 myrpt->scantimer = REM_SCANTIME; 08183 myrpt->hfscanmode = HF_SCAN_UP_FAST; 08184 rpt_telemetry(myrpt,REMXXX,(void *)p); 08185 return DC_COMPLETEQUIET; 08186 case 119: /* Tune Request */ 08187 /* if not currently going, and valid to do */ 08188 if((!myrpt->tunerequest) && 08189 ((!strcmp(myrpt->remote, remote_rig_ft897) || 08190 !strcmp(myrpt->remote, remote_rig_ic706)) )) { 08191 myrpt->remotetx = 0; 08192 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 08193 myrpt->tunerequest = 1; 08194 rpt_telemetry(myrpt,TUNE,NULL); 08195 return DC_COMPLETEQUIET; 08196 } 08197 return DC_ERROR; 08198 case 5: /* Long Status */ 08199 rpt_telemetry(myrpt,REMLONGSTATUS,NULL); 08200 return DC_COMPLETEQUIET; 08201 case 140: /* Short Status */ 08202 rpt_telemetry(myrpt,REMSHORTSTATUS,NULL); 08203 return DC_COMPLETEQUIET; 08204 case 200: 08205 case 201: 08206 case 202: 08207 case 203: 08208 case 204: 08209 case 205: 08210 case 206: 08211 case 207: 08212 case 208: 08213 case 209: 08214 case 210: 08215 case 211: 08216 case 212: 08217 case 213: 08218 case 214: 08219 case 215: 08220 do_dtmf_local(myrpt,remdtmfstr[p - 200]); 08221 return DC_COMPLETEQUIET; 08222 default: 08223 break; 08224 } 08225 return DC_INDETERMINATE; 08226 }
static int function_status | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 5023 of file app_rpt.c.
References DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, ID1, myatoi(), rpt::p, rpt_telemetry(), rpt::s, STATS_TIME, STATS_VERSION, and rpt::sysstate_cur.
05024 { 05025 05026 if (!param) 05027 return DC_ERROR; 05028 05029 if ((myrpt->p.s[myrpt->p.sysstate_cur].txdisable) || (myrpt->p.s[myrpt->p.sysstate_cur].userfundisable)) 05030 return DC_ERROR; 05031 05032 if(debug) 05033 printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 05034 05035 switch(myatoi(param)){ 05036 case 1: /* System ID */ 05037 rpt_telemetry(myrpt, ID1, NULL); 05038 return DC_COMPLETE; 05039 case 2: /* System Time */ 05040 rpt_telemetry(myrpt, STATS_TIME, NULL); 05041 return DC_COMPLETE; 05042 case 3: /* app_rpt.c version */ 05043 rpt_telemetry(myrpt, STATS_VERSION, NULL); 05044 default: 05045 return DC_ERROR; 05046 } 05047 return DC_INDETERMINATE; 05048 }
static int get_wait_interval | ( | struct rpt * | myrpt, | |
int | type | |||
) | [static] |
Definition at line 2818 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().
02819 { 02820 int interval; 02821 char *wait_times; 02822 char *wait_times_save; 02823 02824 wait_times_save = NULL; 02825 wait_times = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "wait_times"); 02826 02827 if(wait_times){ 02828 wait_times_save = ast_strdupa(wait_times); 02829 if(!wait_times_save){ 02830 ast_log(LOG_WARNING, "Out of memory in wait_interval()\n"); 02831 wait_times = NULL; 02832 } 02833 } 02834 02835 switch(type){ 02836 case DLY_TELEM: 02837 if(wait_times) 02838 interval = retrieve_astcfgint(myrpt,wait_times_save, "telemwait", 500, 5000, 1000); 02839 else 02840 interval = 1000; 02841 break; 02842 02843 case DLY_ID: 02844 if(wait_times) 02845 interval = retrieve_astcfgint(myrpt,wait_times_save, "idwait",250,5000,500); 02846 else 02847 interval = 500; 02848 break; 02849 02850 case DLY_UNKEY: 02851 if(wait_times) 02852 interval = retrieve_astcfgint(myrpt,wait_times_save, "unkeywait",500,5000,1000); 02853 else 02854 interval = 1000; 02855 break; 02856 02857 case DLY_LINKUNKEY: 02858 if(wait_times) 02859 interval = retrieve_astcfgint(myrpt,wait_times_save, "linkunkeywait",500,5000,1000); 02860 else 02861 interval = 1000; 02862 break; 02863 02864 case DLY_CALLTERM: 02865 if(wait_times) 02866 interval = retrieve_astcfgint(myrpt,wait_times_save, "calltermwait",500,5000,1500); 02867 else 02868 interval = 1500; 02869 break; 02870 02871 case DLY_COMP: 02872 if(wait_times) 02873 interval = retrieve_astcfgint(myrpt,wait_times_save, "compwait",500,5000,200); 02874 else 02875 interval = 200; 02876 break; 02877 02878 default: 02879 return 0; 02880 } 02881 return interval; 02882 }
Definition at line 5303 of file app_rpt.c.
References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_TEXT, ast_log(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt::callmode, rpt_link::chan, rpt::cidx, collect_function_digits(), rpt::dailyexecdcommands, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_COMPLETEQUIET, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt_link::disced, do_dtmf_local(), do_dtmf_phone(), donodelog(), rpt::endchar, rpt::exten, ast_frame::frametype, func_xlat(), rpt::funcchar, rpt::lastdtmfcommand, rpt_link::linklist, rpt_link::linklistreceived, rpt::links, rpt::lock, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, rpt_link::max_retries, MAXDTMF, mdc1200_notify(), rpt::mydtmf, rpt_link::name, rpt::name, rpt_link::next, ast_frame::offset, rpt::outxlat, rpt::p, rpt::patchcontext, rpt::patchquiet, rpt::pchannel, PROC, rpt::propagate_dtmf, rpt::propagate_phonedtmf, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), ast_frame::samples, seq, SOURCE_LNK, rpt::stopgen, ast_frame::subclass, and rpt::totalexecdcommands.
Referenced by rpt().
05305 { 05306 /* XXX ATTENTION: if you change the size of these arrays you MUST 05307 * change the limits in corresponding sscanf() calls below. */ 05308 char tmp[512],cmd[300] = "",dest[300],src[300],c; 05309 int seq, res; 05310 struct rpt_link *l; 05311 struct ast_frame wf; 05312 05313 wf.frametype = AST_FRAME_TEXT; 05314 wf.subclass = 0; 05315 wf.offset = 0; 05316 wf.mallocd = 0; 05317 wf.datalen = strlen(str) + 1; 05318 wf.samples = 0; 05319 /* put string in our buffer */ 05320 strncpy(tmp,str,sizeof(tmp) - 1); 05321 05322 if (!strcmp(tmp,discstr)) 05323 { 05324 mylink->disced = 1; 05325 mylink->retries = mylink->max_retries + 1; 05326 ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV); 05327 return; 05328 } 05329 if (tmp[0] == 'L') 05330 { 05331 rpt_mutex_lock(&myrpt->lock); 05332 strcpy(mylink->linklist,tmp + 2); 05333 time(&mylink->linklistreceived); 05334 rpt_mutex_unlock(&myrpt->lock); 05335 if (debug > 6) ast_log(LOG_NOTICE,"@@@@ node %s received node list %s from node %s\n", 05336 myrpt->name,tmp,mylink->name); 05337 return; 05338 } 05339 if (tmp[0] == 'I') 05340 { 05341 /* XXX WARNING: be very careful with the limits on the folowing 05342 * sscanf() call, make sure they match the values defined above */ 05343 if (sscanf(tmp,"%299s %299s %30x",cmd,src,&seq) != 3) 05344 { 05345 ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str); 05346 return; 05347 } 05348 mdc1200_notify(myrpt,src,seq); 05349 strcpy(dest,"*"); 05350 } 05351 else 05352 { 05353 /* XXX WARNING: be very careful with the limits on the folowing 05354 * sscanf() call, make sure they match the values defined above */ 05355 if (sscanf(tmp,"%299s %299s %299s %30d %1c",cmd,dest,src,&seq,&c) != 5) 05356 { 05357 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 05358 return; 05359 } 05360 if (strcmp(cmd,"D")) 05361 { 05362 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 05363 return; 05364 } 05365 } 05366 if (dest[0] == '0') 05367 { 05368 strcpy(dest,myrpt->name); 05369 } 05370 05371 /* if not for me, redistribute to all links */ 05372 if (strcmp(dest,myrpt->name)) 05373 { 05374 l = myrpt->links.next; 05375 /* see if this is one in list */ 05376 while(l != &myrpt->links) 05377 { 05378 if (l->name[0] == '0') 05379 { 05380 l = l->next; 05381 continue; 05382 } 05383 /* dont send back from where it came */ 05384 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 05385 { 05386 l = l->next; 05387 continue; 05388 } 05389 /* if it is, send it and we're done */ 05390 if (!strcmp(l->name,dest)) 05391 { 05392 /* send, but not to src */ 05393 if (strcmp(l->name,src)) { 05394 wf.data = str; 05395 if (l->chan) ast_write(l->chan,&wf); 05396 } 05397 return; 05398 } 05399 l = l->next; 05400 } 05401 l = myrpt->links.next; 05402 /* otherwise, send it to all of em */ 05403 while(l != &myrpt->links) 05404 { 05405 if (l->name[0] == '0') 05406 { 05407 l = l->next; 05408 continue; 05409 } 05410 /* dont send back from where it came */ 05411 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 05412 { 05413 l = l->next; 05414 continue; 05415 } 05416 /* send, but not to src */ 05417 if (strcmp(l->name,src)) { 05418 wf.data = str; 05419 if (l->chan) ast_write(l->chan,&wf); 05420 } 05421 l = l->next; 05422 } 05423 return; 05424 } 05425 if (myrpt->p.archivedir) 05426 { 05427 char str[100]; 05428 05429 sprintf(str,"DTMF,%s,%c",mylink->name,c); 05430 donodelog(myrpt,str); 05431 } 05432 c = func_xlat(myrpt,c,&myrpt->p.outxlat); 05433 if (!c) return; 05434 rpt_mutex_lock(&myrpt->lock); 05435 if (c == myrpt->p.endchar) myrpt->stopgen = 1; 05436 if (myrpt->callmode == 1) 05437 { 05438 myrpt->exten[myrpt->cidx++] = c; 05439 myrpt->exten[myrpt->cidx] = 0; 05440 /* if this exists */ 05441 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05442 { 05443 myrpt->callmode = 2; 05444 if(!myrpt->patchquiet){ 05445 rpt_mutex_unlock(&myrpt->lock); 05446 rpt_telemetry(myrpt,PROC,NULL); 05447 rpt_mutex_lock(&myrpt->lock); 05448 } 05449 } 05450 /* if can continue, do so */ 05451 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05452 { 05453 /* call has failed, inform user */ 05454 myrpt->callmode = 4; 05455 } 05456 } 05457 if (c == myrpt->p.funcchar) 05458 { 05459 myrpt->rem_dtmfidx = 0; 05460 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05461 time(&myrpt->rem_dtmf_time); 05462 rpt_mutex_unlock(&myrpt->lock); 05463 return; 05464 } 05465 else if (myrpt->rem_dtmfidx < 0) 05466 { 05467 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 05468 { 05469 myrpt->mydtmf = c; 05470 } 05471 if (myrpt->p.propagate_dtmf) do_dtmf_local(myrpt,c); 05472 if (myrpt->p.propagate_phonedtmf) do_dtmf_phone(myrpt,mylink,c); 05473 rpt_mutex_unlock(&myrpt->lock); 05474 return; 05475 } 05476 else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0)) 05477 { 05478 time(&myrpt->rem_dtmf_time); 05479 if (myrpt->rem_dtmfidx < MAXDTMF) 05480 { 05481 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 05482 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05483 05484 rpt_mutex_unlock(&myrpt->lock); 05485 strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1); 05486 res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink); 05487 rpt_mutex_lock(&myrpt->lock); 05488 05489 switch(res){ 05490 05491 case DC_INDETERMINATE: 05492 break; 05493 05494 case DC_REQ_FLUSH: 05495 myrpt->rem_dtmfidx = 0; 05496 myrpt->rem_dtmfbuf[0] = 0; 05497 break; 05498 05499 05500 case DC_COMPLETE: 05501 case DC_COMPLETEQUIET: 05502 myrpt->totalexecdcommands++; 05503 myrpt->dailyexecdcommands++; 05504 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 05505 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 05506 myrpt->rem_dtmfbuf[0] = 0; 05507 myrpt->rem_dtmfidx = -1; 05508 myrpt->rem_dtmf_time = 0; 05509 break; 05510 05511 case DC_ERROR: 05512 default: 05513 myrpt->rem_dtmfbuf[0] = 0; 05514 myrpt->rem_dtmfidx = -1; 05515 myrpt->rem_dtmf_time = 0; 05516 break; 05517 } 05518 } 05519 05520 } 05521 rpt_mutex_unlock(&myrpt->lock); 05522 return; 05523 }
static void handle_link_phone_dtmf | ( | struct rpt * | myrpt, | |
struct rpt_link * | mylink, | |||
char | c | |||
) | [static] |
Definition at line 5525 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().
05527 { 05528 05529 char cmd[300]; 05530 int res; 05531 05532 if (myrpt->p.archivedir) 05533 { 05534 char str[100]; 05535 05536 sprintf(str,"DTMF(P),%s,%c",mylink->name,c); 05537 donodelog(myrpt,str); 05538 } 05539 rpt_mutex_lock(&myrpt->lock); 05540 if (c == myrpt->p.endchar) 05541 { 05542 if (mylink->lastrx) 05543 { 05544 mylink->lastrx = 0; 05545 rpt_mutex_unlock(&myrpt->lock); 05546 return; 05547 } 05548 myrpt->stopgen = 1; 05549 if (myrpt->cmdnode[0]) 05550 { 05551 myrpt->cmdnode[0] = 0; 05552 myrpt->dtmfidx = -1; 05553 myrpt->dtmfbuf[0] = 0; 05554 rpt_mutex_unlock(&myrpt->lock); 05555 rpt_telemetry(myrpt,COMPLETE,NULL); 05556 return; 05557 } 05558 } 05559 if (myrpt->cmdnode[0]) 05560 { 05561 rpt_mutex_unlock(&myrpt->lock); 05562 send_link_dtmf(myrpt,c); 05563 return; 05564 } 05565 if (myrpt->callmode == 1) 05566 { 05567 myrpt->exten[myrpt->cidx++] = c; 05568 myrpt->exten[myrpt->cidx] = 0; 05569 /* if this exists */ 05570 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05571 { 05572 myrpt->callmode = 2; 05573 if(!myrpt->patchquiet){ 05574 rpt_mutex_unlock(&myrpt->lock); 05575 rpt_telemetry(myrpt,PROC,NULL); 05576 rpt_mutex_lock(&myrpt->lock); 05577 } 05578 } 05579 /* if can continue, do so */ 05580 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05581 { 05582 /* call has failed, inform user */ 05583 myrpt->callmode = 4; 05584 } 05585 } 05586 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 05587 { 05588 myrpt->mydtmf = c; 05589 } 05590 if (c == myrpt->p.funcchar) 05591 { 05592 myrpt->rem_dtmfidx = 0; 05593 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05594 time(&myrpt->rem_dtmf_time); 05595 rpt_mutex_unlock(&myrpt->lock); 05596 return; 05597 } 05598 else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0)) 05599 { 05600 time(&myrpt->rem_dtmf_time); 05601 if (myrpt->rem_dtmfidx < MAXDTMF) 05602 { 05603 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 05604 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 05605 05606 rpt_mutex_unlock(&myrpt->lock); 05607 strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1); 05608 switch(mylink->phonemode) 05609 { 05610 case 1: 05611 res = collect_function_digits(myrpt, cmd, 05612 SOURCE_PHONE, mylink); 05613 break; 05614 case 2: 05615 res = collect_function_digits(myrpt, cmd, 05616 SOURCE_DPHONE,mylink); 05617 break; 05618 default: 05619 res = collect_function_digits(myrpt, cmd, 05620 SOURCE_LNK, mylink); 05621 break; 05622 } 05623 05624 rpt_mutex_lock(&myrpt->lock); 05625 05626 switch(res){ 05627 05628 case DC_INDETERMINATE: 05629 break; 05630 05631 case DC_DOKEY: 05632 mylink->lastrx = 1; 05633 break; 05634 05635 case DC_REQ_FLUSH: 05636 myrpt->rem_dtmfidx = 0; 05637 myrpt->rem_dtmfbuf[0] = 0; 05638 break; 05639 05640 05641 case DC_COMPLETE: 05642 case DC_COMPLETEQUIET: 05643 myrpt->totalexecdcommands++; 05644 myrpt->dailyexecdcommands++; 05645 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 05646 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 05647 myrpt->rem_dtmfbuf[0] = 0; 05648 myrpt->rem_dtmfidx = -1; 05649 myrpt->rem_dtmf_time = 0; 05650 break; 05651 05652 case DC_ERROR: 05653 default: 05654 myrpt->rem_dtmfbuf[0] = 0; 05655 myrpt->rem_dtmfidx = -1; 05656 myrpt->rem_dtmf_time = 0; 05657 break; 05658 } 05659 } 05660 05661 } 05662 rpt_mutex_unlock(&myrpt->lock); 05663 return; 05664 }
static int handle_remote_data | ( | struct rpt * | myrpt, | |
char * | str | |||
) | [static] |
Definition at line 8339 of file app_rpt.c.
References rpt::archivedir, ast_log(), COMPLETE, donodelog(), func_xlat(), handle_remote_dtmf_digit(), LOG_WARNING, mdc1200_notify(), rpt::name, rpt::outxlat, rpt::p, rpt_telemetry(), and seq.
08340 { 08341 /* XXX ATTENTION: if you change the size of these arrays you MUST 08342 * change the limits in corresponding sscanf() calls below. */ 08343 char tmp[300],cmd[300],dest[300],src[300],c; 08344 int seq,res; 08345 08346 /* put string in our buffer */ 08347 strncpy(tmp,str,sizeof(tmp) - 1); 08348 if (!strcmp(tmp,discstr)) return 0; 08349 08350 #ifndef DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES 08351 if (tmp[0] == 'I') 08352 { 08353 /* XXX WARNING: be very careful with the limits on the folowing 08354 * sscanf() call, make sure they match the values defined above */ 08355 if (sscanf(tmp,"%299s %299s %30x",cmd,src,&seq) != 3) 08356 { 08357 ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str); 08358 return 0; 08359 } 08360 mdc1200_notify(myrpt,src,seq); 08361 return 0; 08362 } 08363 #endif 08364 /* XXX WARNING: be very careful with the limits on the folowing 08365 * sscanf() call, make sure they match the values defined above */ 08366 if (sscanf(tmp,"%299s %299s %299s %30d %1c",cmd,dest,src,&seq,&c) != 5) 08367 { 08368 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 08369 return 0; 08370 } 08371 if (strcmp(cmd,"D")) 08372 { 08373 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 08374 return 0; 08375 } 08376 /* if not for me, ignore */ 08377 if (strcmp(dest,myrpt->name)) return 0; 08378 if (myrpt->p.archivedir) 08379 { 08380 char str[100]; 08381 08382 sprintf(str,"DTMF,%c",c); 08383 donodelog(myrpt,str); 08384 } 08385 c = func_xlat(myrpt,c,&myrpt->p.outxlat); 08386 if (!c) return(0); 08387 res = handle_remote_dtmf_digit(myrpt,c, NULL, 0); 08388 if (res != 1) 08389 return res; 08390 rpt_telemetry(myrpt,COMPLETE,NULL); 08391 return 0; 08392 }
static int handle_remote_dtmf_digit | ( | struct rpt * | myrpt, | |
char | c, | |||
char * | keyed, | |||
int | phonemode | |||
) | [static] |
Definition at line 8229 of file app_rpt.c.
References collect_function_digits(), rpt::dailyexecdcommands, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, do_dtmf_local(), rpt::dtmf_time_rem, DTMF_TIMEOUT, rpt::dtmfbuf, rpt::dtmfidx, rpt::funcchar, rpt::hfscanmode, rpt::last_activity_time, rpt::lastdtmfcommand, rpt::lock, MAXDTMF, rpt::p, rpt::propagate_dtmf, rpt_mutex_lock, rpt_mutex_unlock, SOURCE_DPHONE, SOURCE_PHONE, SOURCE_RMT, stop_scan(), and rpt::totalexecdcommands.
Referenced by handle_remote_data(), and handle_remote_phone_dtmf().
08230 { 08231 time_t now; 08232 int ret,res = 0,src; 08233 08234 time(&myrpt->last_activity_time); 08235 /* Stop scan mode if in scan mode */ 08236 if(myrpt->hfscanmode){ 08237 stop_scan(myrpt); 08238 return 0; 08239 } 08240 08241 time(&now); 08242 /* if timed-out */ 08243 if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now) 08244 { 08245 myrpt->dtmfidx = -1; 08246 myrpt->dtmfbuf[0] = 0; 08247 myrpt->dtmf_time_rem = 0; 08248 } 08249 /* if decode not active */ 08250 if (myrpt->dtmfidx == -1) 08251 { 08252 /* if not lead-in digit, dont worry */ 08253 if (c != myrpt->p.funcchar) 08254 { 08255 if (!myrpt->p.propagate_dtmf) 08256 { 08257 rpt_mutex_lock(&myrpt->lock); 08258 do_dtmf_local(myrpt,c); 08259 rpt_mutex_unlock(&myrpt->lock); 08260 } 08261 return 0; 08262 } 08263 myrpt->dtmfidx = 0; 08264 myrpt->dtmfbuf[0] = 0; 08265 myrpt->dtmf_time_rem = now; 08266 return 0; 08267 } 08268 /* if too many in buffer, start over */ 08269 if (myrpt->dtmfidx >= MAXDTMF) 08270 { 08271 myrpt->dtmfidx = 0; 08272 myrpt->dtmfbuf[0] = 0; 08273 myrpt->dtmf_time_rem = now; 08274 } 08275 if (c == myrpt->p.funcchar) 08276 { 08277 /* if star at beginning, or 2 together, erase buffer */ 08278 if ((myrpt->dtmfidx < 1) || 08279 (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->p.funcchar)) 08280 { 08281 myrpt->dtmfidx = 0; 08282 myrpt->dtmfbuf[0] = 0; 08283 myrpt->dtmf_time_rem = now; 08284 return 0; 08285 } 08286 } 08287 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 08288 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08289 myrpt->dtmf_time_rem = now; 08290 08291 08292 src = SOURCE_RMT; 08293 if (phonemode > 1) src = SOURCE_DPHONE; 08294 else if (phonemode) src = SOURCE_PHONE; 08295 ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL); 08296 08297 switch(ret){ 08298 08299 case DC_INDETERMINATE: 08300 res = 0; 08301 break; 08302 08303 case DC_DOKEY: 08304 if (keyed) *keyed = 1; 08305 res = 0; 08306 break; 08307 08308 case DC_REQ_FLUSH: 08309 myrpt->dtmfidx = 0; 08310 myrpt->dtmfbuf[0] = 0; 08311 res = 0; 08312 break; 08313 08314 08315 case DC_COMPLETE: 08316 res = 1; 08317 case DC_COMPLETEQUIET: 08318 myrpt->totalexecdcommands++; 08319 myrpt->dailyexecdcommands++; 08320 strncpy(myrpt->lastdtmfcommand, myrpt->dtmfbuf, MAXDTMF-1); 08321 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 08322 myrpt->dtmfbuf[0] = 0; 08323 myrpt->dtmfidx = -1; 08324 myrpt->dtmf_time_rem = 0; 08325 break; 08326 08327 case DC_ERROR: 08328 default: 08329 myrpt->dtmfbuf[0] = 0; 08330 myrpt->dtmfidx = -1; 08331 myrpt->dtmf_time_rem = 0; 08332 res = 0; 08333 break; 08334 } 08335 08336 return res; 08337 }
static int handle_remote_phone_dtmf | ( | struct rpt * | myrpt, | |
char | c, | |||
char * | keyed, | |||
int | phonemode | |||
) | [static] |
Definition at line 8394 of file app_rpt.c.
References rpt::archivedir, COMPLETE, DC_INDETERMINATE, donodelog(), rpt::endchar, handle_remote_dtmf_digit(), rpt::p, and rpt_telemetry().
08395 { 08396 int res; 08397 08398 08399 if (keyed && *keyed && (c == myrpt->p.endchar)) 08400 { 08401 *keyed = 0; 08402 return DC_INDETERMINATE; 08403 } 08404 08405 if (myrpt->p.archivedir) 08406 { 08407 char str[100]; 08408 08409 sprintf(str,"DTMF(P),%c",c); 08410 donodelog(myrpt,str); 08411 } 08412 res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode); 08413 if (res != 1) 08414 return res; 08415 rpt_telemetry(myrpt,COMPLETE,NULL); 08416 return 0; 08417 }
static int ic706_pltocode | ( | char * | str | ) | [static] |
Definition at line 6883 of file app_rpt.c.
References s.
Referenced by set_ic706().
06884 { 06885 int i; 06886 char *s; 06887 06888 s = strchr(str,'.'); 06889 i = 0; 06890 if (s) i = atoi(s + 1); 06891 i += atoi(str) * 10; 06892 switch(i) 06893 { 06894 case 670: 06895 return 0; 06896 case 693: 06897 return 1; 06898 case 719: 06899 return 2; 06900 case 744: 06901 return 3; 06902 case 770: 06903 return 4; 06904 case 797: 06905 return 5; 06906 case 825: 06907 return 6; 06908 case 854: 06909 return 7; 06910 case 885: 06911 return 8; 06912 case 915: 06913 return 9; 06914 case 948: 06915 return 10; 06916 case 974: 06917 return 11; 06918 case 1000: 06919 return 12; 06920 case 1035: 06921 return 13; 06922 case 1072: 06923 return 14; 06924 case 1109: 06925 return 15; 06926 case 1148: 06927 return 16; 06928 case 1188: 06929 return 17; 06930 case 1230: 06931 return 18; 06932 case 1273: 06933 return 19; 06934 case 1318: 06935 return 20; 06936 case 1365: 06937 return 21; 06938 case 1413: 06939 return 22; 06940 case 1462: 06941 return 23; 06942 case 1514: 06943 return 24; 06944 case 1567: 06945 return 25; 06946 case 1598: 06947 return 26; 06948 case 1622: 06949 return 27; 06950 case 1655: 06951 return 28; 06952 case 1679: 06953 return 29; 06954 case 1713: 06955 return 30; 06956 case 1738: 06957 return 31; 06958 case 1773: 06959 return 32; 06960 case 1799: 06961 return 33; 06962 case 1835: 06963 return 34; 06964 case 1862: 06965 return 35; 06966 case 1899: 06967 return 36; 06968 case 1928: 06969 return 37; 06970 case 1966: 06971 return 38; 06972 case 1995: 06973 return 39; 06974 case 2035: 06975 return 40; 06976 case 2065: 06977 return 41; 06978 case 2107: 06979 return 42; 06980 case 2181: 06981 return 43; 06982 case 2257: 06983 return 44; 06984 case 2291: 06985 return 45; 06986 case 2336: 06987 return 46; 06988 case 2418: 06989 return 47; 06990 case 2503: 06991 return 48; 06992 case 2541: 06993 return 49; 06994 } 06995 return -1; 06996 }
static int kenwood_pltocode | ( | char * | str | ) | [static] |
Definition at line 5996 of file app_rpt.c.
References s.
Referenced by setkenwood().
05997 { 05998 int i; 05999 char *s; 06000 06001 s = strchr(str,'.'); 06002 i = 0; 06003 if (s) i = atoi(s + 1); 06004 i += atoi(str) * 10; 06005 switch(i) 06006 { 06007 case 670: 06008 return 1; 06009 case 719: 06010 return 3; 06011 case 744: 06012 return 4; 06013 case 770: 06014 return 5; 06015 case 797: 06016 return 6; 06017 case 825: 06018 return 7; 06019 case 854: 06020 return 8; 06021 case 885: 06022 return 9; 06023 case 915: 06024 return 10; 06025 case 948: 06026 return 11; 06027 case 974: 06028 return 12; 06029 case 1000: 06030 return 13; 06031 case 1035: 06032 return 14; 06033 case 1072: 06034 return 15; 06035 case 1109: 06036 return 16; 06037 case 1148: 06038 return 17; 06039 case 1188: 06040 return 18; 06041 case 1230: 06042 return 19; 06043 case 1273: 06044 return 20; 06045 case 1318: 06046 return 21; 06047 case 1365: 06048 return 22; 06049 case 1413: 06050 return 23; 06051 case 1462: 06052 return 24; 06053 case 1514: 06054 return 25; 06055 case 1567: 06056 return 26; 06057 case 1622: 06058 return 27; 06059 case 1679: 06060 return 28; 06061 case 1738: 06062 return 29; 06063 case 1799: 06064 return 30; 06065 case 1862: 06066 return 31; 06067 case 1928: 06068 return 32; 06069 case 2035: 06070 return 33; 06071 case 2107: 06072 return 34; 06073 case 2181: 06074 return 35; 06075 case 2257: 06076 return 36; 06077 case 2336: 06078 return 37; 06079 case 2418: 06080 return 38; 06081 case 2503: 06082 return 39; 06083 } 06084 return -1; 06085 }
static int load_module | ( | void | ) | [static] |
Definition at line 11888 of file app_rpt.c.
References ast_cli_register(), ast_pthread_create, ast_register_application(), cli_debug, cli_dump, cli_fun, cli_lstats, cli_nodes, cli_reload, cli_restart, cli_stats, rpt_exec(), and rpt_master().
11890 { 11891 ast_pthread_create(&rpt_master_thread,NULL,rpt_master,NULL); 11892 11893 /* Register cli extensions */ 11894 ast_cli_register(&cli_debug); 11895 ast_cli_register(&cli_dump); 11896 ast_cli_register(&cli_stats); 11897 ast_cli_register(&cli_lstats); 11898 ast_cli_register(&cli_nodes); 11899 ast_cli_register(&cli_reload); 11900 ast_cli_register(&cli_restart); 11901 ast_cli_register(&cli_fun); 11902 11903 return ast_register_application(app, rpt_exec, synopsis, descrip); 11904 }
static void load_rpt_vars | ( | int | n, | |
int | init | |||
) | [static] |
Definition at line 1621 of file app_rpt.c.
References rpt::acctcode, sysstate::alternatetail, rpt::althangtime, rpt::archivedir, ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), rpt::authlevel, sysstate::autopatchdisable, rpt::cfg, rpt::civaddr, rpt::csstanzaname, DEFAULT_CIV_ADDR, DEFAULT_IOBASE, DEFAULT_MONITOR_MIN_DISK_BLOCKS, DEFAULT_REMOTE_INACT_TIMEOUT, DEFAULT_REMOTE_TIMEOUT, DEFAULT_REMOTE_TIMEOUT_WARNING, DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ, desc, rpt::dphone_functions, rpt::dphone_longestfunc, rpt::duplex, ENDCHAR, rpt::endchar, rpt_xlat::endcharseq, rpt::extnodefile, EXTNODEFILE, rpt::extnodes, EXTNODES, finddelim(), FUNCCHAR, rpt::funcchar, rpt_xlat::funccharseq, rpt::functions, FUNCTIONS, HANGTIME, rpt::hangtime, rpt::ident, IDTIME, rpt::idtime, rpt::inxlat, rpt::iobase, rpt::ioport, rpt::link_functions, rpt::link_longestfunc, sysstate::linkfundisable, rpt::linktolink, lock, LOG_NOTICE, LOG_WARNING, rpt::longestfunc, rpt::longestnode, rpt::macro, MACRO, rpt::macro_longest, MAX_SYSSTATES, MAXXLAT, rpt::memory, MEMORY, rpt::monminblocks, ast_variable::name, rpt::name, name, ast_variable::next, rpt::nobusyout, rpt::nodes, NODES, rpt::notelemtx, option_verbose, rpt::ourcallerid, rpt::ourcontext, rpt::outxlat, rpt::p, rpt_xlat::passchars, rpt::phone_functions, rpt::phone_longestfunc, POLITEID, rpt::politeid, rpt::propagate_dtmf, rpt::propagate_phonedtmf, rpt::remoteinacttimeout, rpt::remotetimeout, rpt::remotetimeoutwarning, rpt::remotetimeoutwarningfreq, retrieve_astcfgint(), rpt_vars, rpt::s, sysstate::schedulerdisable, rpt::simple, rpt::skedstanzaname, rpt::startupmacro, rpt::tailmessagemax, rpt::tailmessages, rpt::tailmessagetime, rpt::tailsquashedtime, rpt::tonezone, sysstate::totdisable, TOTIME, rpt::totime, sysstate::txdisable, rpt::txlimitsstanzaname, typeof(), sysstate::userfundisable, ast_variable::value, and VERBOSE_PREFIX_3.
Referenced by rpt(), and rpt_master().
01622 { 01623 char *this,*val; 01624 int i,j,longestnode; 01625 struct ast_variable *vp; 01626 struct ast_config *cfg; 01627 char *strs[100]; 01628 char s1[256]; 01629 static char *cs_keywords[] = {"rptena","rptdis","apena","apdis","lnkena","lnkdis","totena","totdis","skena","skdis", 01630 "ufena","ufdis","atena","atdis",NULL}; 01631 01632 if (option_verbose > 2) 01633 ast_verbose(VERBOSE_PREFIX_3 "%s config for repeater %s\n", 01634 (init) ? "Loading initial" : "Re-Loading",rpt_vars[n].name); 01635 ast_mutex_lock(&rpt_vars[n].lock); 01636 if (rpt_vars[n].cfg) ast_config_destroy(rpt_vars[n].cfg); 01637 cfg = ast_config_load("rpt.conf"); 01638 if (!cfg) { 01639 ast_mutex_unlock(&rpt_vars[n].lock); 01640 ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); 01641 pthread_exit(NULL); 01642 } 01643 rpt_vars[n].cfg = cfg; 01644 this = rpt_vars[n].name; 01645 memset(&rpt_vars[n].p,0,sizeof(rpt_vars[n].p)); 01646 if (init) 01647 { 01648 /* clear all the fields in the structure after 'p' */ 01649 memset(&rpt_vars[n].p + sizeof(rpt_vars[0].p), 0, sizeof(rpt_vars[0]) - sizeof(rpt_vars[0].p) - offsetof(typeof(rpt_vars[0]), p)); 01650 rpt_vars[n].tele.next = &rpt_vars[n].tele; 01651 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 01652 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 01653 rpt_vars[n].tailmessagen = 0; 01654 } 01655 #ifdef __RPT_NOTCH 01656 /* zot out filters stuff */ 01657 memset(&rpt_vars[n].filters,0,sizeof(rpt_vars[n].filters)); 01658 #endif 01659 val = (char *) ast_variable_retrieve(cfg,this,"context"); 01660 if (val) rpt_vars[n].p.ourcontext = val; 01661 else rpt_vars[n].p.ourcontext = this; 01662 val = (char *) ast_variable_retrieve(cfg,this,"callerid"); 01663 if (val) rpt_vars[n].p.ourcallerid = val; 01664 val = (char *) ast_variable_retrieve(cfg,this,"accountcode"); 01665 if (val) rpt_vars[n].p.acctcode = val; 01666 val = (char *) ast_variable_retrieve(cfg,this,"idrecording"); 01667 if (val) rpt_vars[n].p.ident = val; 01668 val = (char *) ast_variable_retrieve(cfg,this,"hangtime"); 01669 if (val) rpt_vars[n].p.hangtime = atoi(val); 01670 else rpt_vars[n].p.hangtime = HANGTIME; 01671 val = (char *) ast_variable_retrieve(cfg,this,"althangtime"); 01672 if (val) rpt_vars[n].p.althangtime = atoi(val); 01673 else rpt_vars[n].p.althangtime = HANGTIME; 01674 val = (char *) ast_variable_retrieve(cfg,this,"totime"); 01675 if (val) rpt_vars[n].p.totime = atoi(val); 01676 else rpt_vars[n].p.totime = TOTIME; 01677 rpt_vars[n].p.tailmessagetime = retrieve_astcfgint(&rpt_vars[n],this, "tailmessagetime", 0, 2400000, 0); 01678 rpt_vars[n].p.tailsquashedtime = retrieve_astcfgint(&rpt_vars[n],this, "tailsquashedtime", 0, 2400000, 0); 01679 rpt_vars[n].p.duplex = retrieve_astcfgint(&rpt_vars[n],this,"duplex",0,4,2); 01680 rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", -60000, 2400000, IDTIME); /* Enforce a min max including zero */ 01681 rpt_vars[n].p.politeid = retrieve_astcfgint(&rpt_vars[n],this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */ 01682 val = (char *) ast_variable_retrieve(cfg,this,"tonezone"); 01683 if (val) rpt_vars[n].p.tonezone = val; 01684 rpt_vars[n].p.tailmessages[0] = 0; 01685 rpt_vars[n].p.tailmessagemax = 0; 01686 val = (char *) ast_variable_retrieve(cfg,this,"tailmessagelist"); 01687 if (val) rpt_vars[n].p.tailmessagemax = finddelim(val, rpt_vars[n].p.tailmessages, 500); 01688 val = (char *) ast_variable_retrieve(cfg,this,"memory"); 01689 if (!val) val = MEMORY; 01690 rpt_vars[n].p.memory = val; 01691 val = (char *) ast_variable_retrieve(cfg,this,"macro"); 01692 if (!val) val = MACRO; 01693 rpt_vars[n].p.macro = val; 01694 val = (char *) ast_variable_retrieve(cfg,this,"startup_macro"); 01695 if (val) rpt_vars[n].p.startupmacro = val; 01696 val = (char *) ast_variable_retrieve(cfg,this,"iobase"); 01697 /* do not use atoi() here, we need to be able to have 01698 the input specified in hex or decimal so we use 01699 sscanf with a %i */ 01700 if ((!val) || (sscanf(val,"%30i",&rpt_vars[n].p.iobase) != 1)) 01701 rpt_vars[n].p.iobase = DEFAULT_IOBASE; 01702 val = (char *) ast_variable_retrieve(cfg,this,"ioport"); 01703 rpt_vars[n].p.ioport = val; 01704 val = (char *) ast_variable_retrieve(cfg,this,"functions"); 01705 if (!val) 01706 { 01707 val = FUNCTIONS; 01708 rpt_vars[n].p.simple = 1; 01709 } 01710 rpt_vars[n].p.functions = val; 01711 val = (char *) ast_variable_retrieve(cfg,this,"link_functions"); 01712 if (val) rpt_vars[n].p.link_functions = val; 01713 else 01714 rpt_vars[n].p.link_functions = rpt_vars[n].p.functions; 01715 val = (char *) ast_variable_retrieve(cfg,this,"phone_functions"); 01716 if (val) rpt_vars[n].p.phone_functions = val; 01717 val = (char *) ast_variable_retrieve(cfg,this,"dphone_functions"); 01718 if (val) rpt_vars[n].p.dphone_functions = val; 01719 val = (char *) ast_variable_retrieve(cfg,this,"funcchar"); 01720 if (!val) rpt_vars[n].p.funcchar = FUNCCHAR; else 01721 rpt_vars[n].p.funcchar = *val; 01722 val = (char *) ast_variable_retrieve(cfg,this,"endchar"); 01723 if (!val) rpt_vars[n].p.endchar = ENDCHAR; else 01724 rpt_vars[n].p.endchar = *val; 01725 val = (char *) ast_variable_retrieve(cfg,this,"nobusyout"); 01726 if (val) rpt_vars[n].p.nobusyout = ast_true(val); 01727 val = (char *) ast_variable_retrieve(cfg,this,"notelemtx"); 01728 if (val) rpt_vars[n].p.notelemtx = ast_true(val); 01729 val = (char *) ast_variable_retrieve(cfg,this,"propagate_dtmf"); 01730 if (val) rpt_vars[n].p.propagate_dtmf = ast_true(val); 01731 val = (char *) ast_variable_retrieve(cfg,this,"propagate_phonedtmf"); 01732 if (val) rpt_vars[n].p.propagate_phonedtmf = ast_true(val); 01733 val = (char *) ast_variable_retrieve(cfg,this,"linktolink"); 01734 if (val) rpt_vars[n].p.linktolink = ast_true(val); 01735 val = (char *) ast_variable_retrieve(cfg,this,"nodes"); 01736 if (!val) val = NODES; 01737 rpt_vars[n].p.nodes = val; 01738 val = (char *) ast_variable_retrieve(cfg,this,"extnodes"); 01739 if (!val) val = EXTNODES; 01740 rpt_vars[n].p.extnodes = val; 01741 val = (char *) ast_variable_retrieve(cfg,this,"extnodefile"); 01742 if (!val) val = EXTNODEFILE; 01743 rpt_vars[n].p.extnodefile = val; 01744 val = (char *) ast_variable_retrieve(cfg,this,"archivedir"); 01745 if (val) rpt_vars[n].p.archivedir = val; 01746 val = (char *) ast_variable_retrieve(cfg,this,"authlevel"); 01747 if (val) rpt_vars[n].p.authlevel = atoi(val); 01748 else rpt_vars[n].p.authlevel = 0; 01749 val = (char *) ast_variable_retrieve(cfg,this,"monminblocks"); 01750 if (val) rpt_vars[n].p.monminblocks = atol(val); 01751 else rpt_vars[n].p.monminblocks = DEFAULT_MONITOR_MIN_DISK_BLOCKS; 01752 val = (char *) ast_variable_retrieve(cfg,this,"remote_inact_timeout"); 01753 if (val) rpt_vars[n].p.remoteinacttimeout = atoi(val); 01754 else rpt_vars[n].p.remoteinacttimeout = DEFAULT_REMOTE_INACT_TIMEOUT; 01755 val = (char *) ast_variable_retrieve(cfg,this,"civaddr"); 01756 if (val) rpt_vars[n].p.civaddr = atoi(val); 01757 else rpt_vars[n].p.civaddr = DEFAULT_CIV_ADDR; 01758 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout"); 01759 if (val) rpt_vars[n].p.remotetimeout = atoi(val); 01760 else rpt_vars[n].p.remotetimeout = DEFAULT_REMOTE_TIMEOUT; 01761 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning"); 01762 if (val) rpt_vars[n].p.remotetimeoutwarning = atoi(val); 01763 else rpt_vars[n].p.remotetimeoutwarning = DEFAULT_REMOTE_TIMEOUT_WARNING; 01764 val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning_freq"); 01765 if (val) rpt_vars[n].p.remotetimeoutwarningfreq = atoi(val); 01766 else rpt_vars[n].p.remotetimeoutwarningfreq = DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ; 01767 #ifdef __RPT_NOTCH 01768 val = (char *) ast_variable_retrieve(cfg,this,"rxnotch"); 01769 if (val) { 01770 i = finddelim(val,strs,MAXFILTERS * 2); 01771 i &= ~1; /* force an even number, rounded down */ 01772 if (i >= 2) for(j = 0; j < i; j += 2) 01773 { 01774 rpt_mknotch(atof(strs[j]),atof(strs[j + 1]), 01775 &rpt_vars[n].filters[j >> 1].gain, 01776 &rpt_vars[n].filters[j >> 1].const0, 01777 &rpt_vars[n].filters[j >> 1].const1, 01778 &rpt_vars[n].filters[j >> 1].const2); 01779 sprintf(rpt_vars[n].filters[j >> 1].desc,"%s Hz, BW = %s", 01780 strs[j],strs[j + 1]); 01781 } 01782 01783 } 01784 #endif 01785 val = (char *) ast_variable_retrieve(cfg,this,"inxlat"); 01786 if (val) { 01787 memset(&rpt_vars[n].p.inxlat,0,sizeof(struct rpt_xlat)); 01788 i = finddelim(val,strs,3); 01789 if (i) strncpy(rpt_vars[n].p.inxlat.funccharseq,strs[0],MAXXLAT - 1); 01790 if (i > 1) strncpy(rpt_vars[n].p.inxlat.endcharseq,strs[1],MAXXLAT - 1); 01791 if (i > 2) strncpy(rpt_vars[n].p.inxlat.passchars,strs[2],MAXXLAT - 1); 01792 } 01793 val = (char *) ast_variable_retrieve(cfg,this,"outxlat"); 01794 if (val) { 01795 memset(&rpt_vars[n].p.outxlat,0,sizeof(struct rpt_xlat)); 01796 i = finddelim(val,strs,3); 01797 if (i) strncpy(rpt_vars[n].p.outxlat.funccharseq,strs[0],MAXXLAT - 1); 01798 if (i > 1) strncpy(rpt_vars[n].p.outxlat.endcharseq,strs[1],MAXXLAT - 1); 01799 if (i > 2) strncpy(rpt_vars[n].p.outxlat.passchars,strs[2],MAXXLAT - 1); 01800 } 01801 /* retreive the stanza name for the control states if there is one */ 01802 val = (char *) ast_variable_retrieve(cfg,this,"controlstates"); 01803 rpt_vars[n].p.csstanzaname = val; 01804 01805 /* retreive the stanza name for the scheduler if there is one */ 01806 val = (char *) ast_variable_retrieve(cfg,this,"scheduler"); 01807 rpt_vars[n].p.skedstanzaname = val; 01808 01809 /* retreive the stanza name for the txlimits */ 01810 val = (char *) ast_variable_retrieve(cfg,this,"txlimits"); 01811 rpt_vars[n].p.txlimitsstanzaname = val; 01812 01813 longestnode = 0; 01814 01815 vp = ast_variable_browse(cfg, rpt_vars[n].p.nodes); 01816 01817 while(vp){ 01818 j = strlen(vp->name); 01819 if (j > longestnode) 01820 longestnode = j; 01821 vp = vp->next; 01822 } 01823 01824 rpt_vars[n].longestnode = longestnode; 01825 01826 /* 01827 * For this repeater, Determine the length of the longest function 01828 */ 01829 rpt_vars[n].longestfunc = 0; 01830 vp = ast_variable_browse(cfg, rpt_vars[n].p.functions); 01831 while(vp){ 01832 j = strlen(vp->name); 01833 if (j > rpt_vars[n].longestfunc) 01834 rpt_vars[n].longestfunc = j; 01835 vp = vp->next; 01836 } 01837 /* 01838 * For this repeater, Determine the length of the longest function 01839 */ 01840 rpt_vars[n].link_longestfunc = 0; 01841 vp = ast_variable_browse(cfg, rpt_vars[n].p.link_functions); 01842 while(vp){ 01843 j = strlen(vp->name); 01844 if (j > rpt_vars[n].link_longestfunc) 01845 rpt_vars[n].link_longestfunc = j; 01846 vp = vp->next; 01847 } 01848 rpt_vars[n].phone_longestfunc = 0; 01849 if (rpt_vars[n].p.phone_functions) 01850 { 01851 vp = ast_variable_browse(cfg, rpt_vars[n].p.phone_functions); 01852 while(vp){ 01853 j = strlen(vp->name); 01854 if (j > rpt_vars[n].phone_longestfunc) 01855 rpt_vars[n].phone_longestfunc = j; 01856 vp = vp->next; 01857 } 01858 } 01859 rpt_vars[n].dphone_longestfunc = 0; 01860 if (rpt_vars[n].p.dphone_functions) 01861 { 01862 vp = ast_variable_browse(cfg, rpt_vars[n].p.dphone_functions); 01863 while(vp){ 01864 j = strlen(vp->name); 01865 if (j > rpt_vars[n].dphone_longestfunc) 01866 rpt_vars[n].dphone_longestfunc = j; 01867 vp = vp->next; 01868 } 01869 } 01870 rpt_vars[n].macro_longest = 1; 01871 vp = ast_variable_browse(cfg, rpt_vars[n].p.macro); 01872 while(vp){ 01873 j = strlen(vp->name); 01874 if (j > rpt_vars[n].macro_longest) 01875 rpt_vars[n].macro_longest = j; 01876 vp = vp->next; 01877 } 01878 01879 /* Browse for control states */ 01880 if(rpt_vars[n].p.csstanzaname) 01881 vp = ast_variable_browse(cfg, rpt_vars[n].p.csstanzaname); 01882 else 01883 vp = NULL; 01884 for( i = 0 ; vp && (i < MAX_SYSSTATES) ; i++){ /* Iterate over the number of control state lines in the stanza */ 01885 int k,nukw,statenum; 01886 statenum=atoi(vp->name); 01887 strncpy(s1, vp->value, 255); 01888 s1[255] = 0; 01889 nukw = finddelim(s1,strs,32); 01890 01891 for (k = 0 ; k < nukw ; k++){ /* for each user specified keyword */ 01892 for(j = 0 ; cs_keywords[j] != NULL ; j++){ /* try to match to one in our internal table */ 01893 if(!strcmp(strs[k],cs_keywords[j])){ 01894 switch(j){ 01895 case 0: /* rptena */ 01896 rpt_vars[n].p.s[statenum].txdisable = 0; 01897 break; 01898 case 1: /* rptdis */ 01899 rpt_vars[n].p.s[statenum].txdisable = 1; 01900 break; 01901 01902 case 2: /* apena */ 01903 rpt_vars[n].p.s[statenum].autopatchdisable = 0; 01904 break; 01905 01906 case 3: /* apdis */ 01907 rpt_vars[n].p.s[statenum].autopatchdisable = 1; 01908 break; 01909 01910 case 4: /* lnkena */ 01911 rpt_vars[n].p.s[statenum].linkfundisable = 0; 01912 break; 01913 01914 case 5: /* lnkdis */ 01915 rpt_vars[n].p.s[statenum].linkfundisable = 1; 01916 break; 01917 01918 case 6: /* totena */ 01919 rpt_vars[n].p.s[statenum].totdisable = 0; 01920 break; 01921 01922 case 7: /* totdis */ 01923 rpt_vars[n].p.s[statenum].totdisable = 1; 01924 break; 01925 01926 case 8: /* skena */ 01927 rpt_vars[n].p.s[statenum].schedulerdisable = 0; 01928 break; 01929 01930 case 9: /* skdis */ 01931 rpt_vars[n].p.s[statenum].schedulerdisable = 1; 01932 break; 01933 01934 case 10: /* ufena */ 01935 rpt_vars[n].p.s[statenum].userfundisable = 0; 01936 break; 01937 01938 case 11: /* ufdis */ 01939 rpt_vars[n].p.s[statenum].userfundisable = 1; 01940 break; 01941 01942 case 12: /* atena */ 01943 rpt_vars[n].p.s[statenum].alternatetail = 1; 01944 break; 01945 01946 case 13: /* atdis */ 01947 rpt_vars[n].p.s[statenum].alternatetail = 0; 01948 break; 01949 01950 default: 01951 ast_log(LOG_WARNING, 01952 "Unhandled control state keyword %s", cs_keywords[i]); 01953 break; 01954 } 01955 } 01956 } 01957 } 01958 vp = vp->next; 01959 } 01960 ast_mutex_unlock(&rpt_vars[n].lock); 01961 }
static void local_dtmf_helper | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 8481 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().
08482 { 08483 int res; 08484 pthread_attr_t attr; 08485 char cmd[MAXDTMF+1] = ""; 08486 08487 if (myrpt->p.archivedir) 08488 { 08489 char str[100]; 08490 08491 sprintf(str,"DTMF,MAIN,%c",c); 08492 donodelog(myrpt,str); 08493 } 08494 if (c == myrpt->p.endchar) 08495 { 08496 /* if in simple mode, kill autopatch */ 08497 if (myrpt->p.simple && myrpt->callmode) 08498 { 08499 rpt_mutex_lock(&myrpt->lock); 08500 myrpt->callmode = 0; 08501 rpt_mutex_unlock(&myrpt->lock); 08502 rpt_telemetry(myrpt,TERM,NULL); 08503 return; 08504 } 08505 rpt_mutex_lock(&myrpt->lock); 08506 myrpt->stopgen = 1; 08507 if (myrpt->cmdnode[0]) 08508 { 08509 myrpt->cmdnode[0] = 0; 08510 myrpt->dtmfidx = -1; 08511 myrpt->dtmfbuf[0] = 0; 08512 rpt_mutex_unlock(&myrpt->lock); 08513 rpt_telemetry(myrpt,COMPLETE,NULL); 08514 } 08515 else 08516 { 08517 rpt_mutex_unlock(&myrpt->lock); 08518 if (myrpt->p.propagate_phonedtmf) 08519 do_dtmf_phone(myrpt,NULL,c); 08520 } 08521 return; 08522 } 08523 rpt_mutex_lock(&myrpt->lock); 08524 if (myrpt->cmdnode[0]) 08525 { 08526 rpt_mutex_unlock(&myrpt->lock); 08527 send_link_dtmf(myrpt,c); 08528 return; 08529 } 08530 if (!myrpt->p.simple) 08531 { 08532 if (c == myrpt->p.funcchar) 08533 { 08534 myrpt->dtmfidx = 0; 08535 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08536 rpt_mutex_unlock(&myrpt->lock); 08537 time(&myrpt->dtmf_time); 08538 return; 08539 } 08540 else if ((c != myrpt->p.endchar) && (myrpt->dtmfidx >= 0)) 08541 { 08542 time(&myrpt->dtmf_time); 08543 08544 if (myrpt->dtmfidx < MAXDTMF) 08545 { 08546 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 08547 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 08548 08549 strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1); 08550 08551 rpt_mutex_unlock(&myrpt->lock); 08552 res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL); 08553 rpt_mutex_lock(&myrpt->lock); 08554 switch(res){ 08555 case DC_INDETERMINATE: 08556 break; 08557 case DC_REQ_FLUSH: 08558 myrpt->dtmfidx = 0; 08559 myrpt->dtmfbuf[0] = 0; 08560 break; 08561 case DC_COMPLETE: 08562 case DC_COMPLETEQUIET: 08563 myrpt->totalexecdcommands++; 08564 myrpt->dailyexecdcommands++; 08565 strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1); 08566 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 08567 myrpt->dtmfbuf[0] = 0; 08568 myrpt->dtmfidx = -1; 08569 myrpt->dtmf_time = 0; 08570 break; 08571 08572 case DC_ERROR: 08573 default: 08574 myrpt->dtmfbuf[0] = 0; 08575 myrpt->dtmfidx = -1; 08576 myrpt->dtmf_time = 0; 08577 break; 08578 } 08579 if(res != DC_INDETERMINATE) { 08580 rpt_mutex_unlock(&myrpt->lock); 08581 return; 08582 } 08583 } 08584 } 08585 } 08586 else /* if simple */ 08587 { 08588 if ((!myrpt->callmode) && (c == myrpt->p.funcchar)) 08589 { 08590 myrpt->callmode = 1; 08591 myrpt->patchnoct = 0; 08592 myrpt->patchquiet = 0; 08593 myrpt->patchfarenddisconnect = 0; 08594 myrpt->patchdialtime = 0; 08595 strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT); 08596 myrpt->cidx = 0; 08597 myrpt->exten[myrpt->cidx] = 0; 08598 rpt_mutex_unlock(&myrpt->lock); 08599 pthread_attr_init(&attr); 08600 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 08601 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt); 08602 return; 08603 } 08604 } 08605 if (myrpt->callmode == 1) 08606 { 08607 myrpt->exten[myrpt->cidx++] = c; 08608 myrpt->exten[myrpt->cidx] = 0; 08609 /* if this exists */ 08610 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 08611 { 08612 myrpt->callmode = 2; 08613 rpt_mutex_unlock(&myrpt->lock); 08614 if(!myrpt->patchquiet) 08615 rpt_telemetry(myrpt,PROC,NULL); 08616 return; 08617 } 08618 /* if can continue, do so */ 08619 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 08620 { 08621 /* call has failed, inform user */ 08622 myrpt->callmode = 4; 08623 } 08624 rpt_mutex_unlock(&myrpt->lock); 08625 return; 08626 } 08627 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 08628 { 08629 myrpt->mydtmf = c; 08630 } 08631 rpt_mutex_unlock(&myrpt->lock); 08632 if ((myrpt->dtmfidx < 0) && myrpt->p.propagate_phonedtmf) 08633 do_dtmf_phone(myrpt,NULL,c); 08634 return; 08635 }
static int matchkeyword | ( | char * | string, | |
char ** | param, | |||
char * | keywords[] | |||
) | [static] |
Definition at line 1477 of file app_rpt.c.
Referenced by function_autopatchup().
01478 { 01479 int i,ls; 01480 for( i = 0 ; keywords[i] ; i++){ 01481 ls = strlen(keywords[i]); 01482 if(!ls){ 01483 *param = NULL; 01484 return 0; 01485 } 01486 if(!strncmp(string, keywords[i], ls)){ 01487 if(param) 01488 *param = string + ls; 01489 return i + 1; 01490 } 01491 } 01492 param = NULL; 01493 return 0; 01494 }
static void mdc1200_notify | ( | struct rpt * | myrpt, | |
char * | fromnode, | |||
unsigned int | unit | |||
) | [static] |
Definition at line 1191 of file app_rpt.c.
References ast_verbose(), and rpt::name.
Referenced by function_ilink(), handle_link_data(), handle_remote_data(), and rpt().
01192 { 01193 if (!fromnode) 01194 { 01195 ast_verbose("Got MDC-1200 ID %04X from local system (%s)\n", 01196 unit,myrpt->name); 01197 } 01198 else 01199 { 01200 ast_verbose("Got MDC-1200 ID %04X from node %s (%s)\n", 01201 unit,fromnode,myrpt->name); 01202 } 01203 }
static int mem2vfo_ic706 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7197 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07198 { 07199 unsigned char cmdstr[10]; 07200 07201 cmdstr[0] = cmdstr[1] = 0xfe; 07202 cmdstr[2] = myrpt->p.civaddr; 07203 cmdstr[3] = 0xe0; 07204 cmdstr[4] = 0x0a; 07205 cmdstr[5] = 0xfd; 07206 07207 return(civ_cmd(myrpt,cmdstr,6)); 07208 }
static int multimode_bump_freq | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 7560 of file app_rpt.c.
References multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), and rpt::remote.
Referenced by function_remote(), and service_scan().
07561 { 07562 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07563 return multimode_bump_freq_ft897(myrpt, interval); 07564 else if(!strcmp(myrpt->remote, remote_rig_ic706)) 07565 return multimode_bump_freq_ic706(myrpt, interval); 07566 else 07567 return -1; 07568 }
static int multimode_bump_freq_ft897 | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 6749 of file app_rpt.c.
References check_freq_ft897(), rpt::freq, MAXREMSTR, set_freq_ft897(), and split_freq().
Referenced by multimode_bump_freq().
06750 { 06751 int m,d; 06752 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 06753 06754 if(debug) 06755 printf("Before bump: %s\n", myrpt->freq); 06756 06757 if(split_freq(mhz, decimals, myrpt->freq)) 06758 return -1; 06759 06760 m = atoi(mhz); 06761 d = atoi(decimals); 06762 06763 d += (interval / 10); /* 10Hz resolution */ 06764 if(d < 0){ 06765 m--; 06766 d += 100000; 06767 } 06768 else if(d >= 100000){ 06769 m++; 06770 d -= 100000; 06771 } 06772 06773 if(check_freq_ft897(m, d, NULL)){ 06774 if(debug) 06775 printf("Bump freq invalid\n"); 06776 return -1; 06777 } 06778 06779 snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d); 06780 06781 if(debug) 06782 printf("After bump: %s\n", myrpt->freq); 06783 06784 return set_freq_ft897(myrpt, myrpt->freq); 06785 }
static int multimode_bump_freq_ic706 | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 7293 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().
07294 { 07295 int m,d; 07296 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07297 unsigned char cmdstr[20]; 07298 07299 if(debug) 07300 printf("Before bump: %s\n", myrpt->freq); 07301 07302 if(split_freq(mhz, decimals, myrpt->freq)) 07303 return -1; 07304 07305 m = atoi(mhz); 07306 d = atoi(decimals); 07307 07308 d += (interval / 10); /* 10Hz resolution */ 07309 if(d < 0){ 07310 m--; 07311 d += 100000; 07312 } 07313 else if(d >= 100000){ 07314 m++; 07315 d -= 100000; 07316 } 07317 07318 if(check_freq_ic706(m, d, NULL)){ 07319 if(debug) 07320 printf("Bump freq invalid\n"); 07321 return -1; 07322 } 07323 07324 snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d); 07325 07326 if(debug) 07327 printf("After bump: %s\n", myrpt->freq); 07328 07329 /* The ic-706 likes packed BCD frequencies */ 07330 07331 cmdstr[0] = cmdstr[1] = 0xfe; 07332 cmdstr[2] = myrpt->p.civaddr; 07333 cmdstr[3] = 0xe0; 07334 cmdstr[4] = 0; 07335 cmdstr[5] = ((d % 10) << 4); 07336 cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10); 07337 cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000); 07338 cmdstr[8] = (((m % 100)/10) << 4) + (m % 10); 07339 cmdstr[9] = (m / 100); 07340 cmdstr[10] = 0xfd; 07341 07342 return(serial_remote_io(myrpt,cmdstr,11,NULL,0,0)); 07343 }
static int multimode_capable | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 879 of file app_rpt.c.
References rpt::remote.
Referenced by function_remote(), and rpt_tele_thread().
00880 { 00881 if(!strcmp(myrpt->remote, remote_rig_ft897)) 00882 return 1; 00883 if(!strcmp(myrpt->remote, remote_rig_ic706)) 00884 return 1; 00885 return 0; 00886 }
static int myatoi | ( | char * | str | ) | [static] |
Definition at line 1519 of file app_rpt.c.
Referenced by function_cop(), function_ilink(), function_remote(), function_status(), retrieve_astcfgint(), and rpt_do_debug().
01520 { 01521 int ret; 01522 01523 if (str == NULL) return -1; 01524 /* leave this %i alone, non-base-10 input is useful here */ 01525 if (sscanf(str,"%30i",&ret) != 1) return -1; 01526 return ret; 01527 }
static int mycompar | ( | const void * | a, | |
const void * | b | |||
) | [static] |
Definition at line 1529 of file app_rpt.c.
Referenced by rpt_do_nodes(), and rpt_tele_thread().
01530 { 01531 char **x = (char **) a; 01532 char **y = (char **) b; 01533 int xoff,yoff; 01534 01535 if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0; 01536 if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0; 01537 return(strcmp((*x) + xoff,(*y) + yoff)); 01538 }
static char* node_lookup | ( | struct rpt * | myrpt, | |
char * | digitbuf | |||
) | [static] |
Definition at line 1409 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, nodelookuplock, rpt::nodes, rpt::p, and val.
Referenced by attempt_reconnect(), connect_link(), and function_ilink().
01410 { 01411 01412 char *val; 01413 int longestnode,j; 01414 struct stat mystat; 01415 static time_t last = 0; 01416 static struct ast_config *ourcfg = NULL; 01417 struct ast_variable *vp; 01418 01419 /* try to look it up locally first */ 01420 val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf); 01421 if (val) return(val); 01422 ast_mutex_lock(&nodelookuplock); 01423 /* if file does not exist */ 01424 if (stat(myrpt->p.extnodefile,&mystat) == -1) 01425 { 01426 if (ourcfg) ast_config_destroy(ourcfg); 01427 ourcfg = NULL; 01428 ast_mutex_unlock(&nodelookuplock); 01429 return(NULL); 01430 } 01431 /* if we need to reload */ 01432 if (mystat.st_mtime > last) 01433 { 01434 if (ourcfg) ast_config_destroy(ourcfg); 01435 ourcfg = ast_config_load(myrpt->p.extnodefile); 01436 /* if file not there, just bail */ 01437 if (!ourcfg) 01438 { 01439 ast_mutex_unlock(&nodelookuplock); 01440 return(NULL); 01441 } 01442 /* reset "last" time */ 01443 last = mystat.st_mtime; 01444 01445 /* determine longest node length again */ 01446 longestnode = 0; 01447 vp = ast_variable_browse(myrpt->cfg, myrpt->p.nodes); 01448 while(vp){ 01449 j = strlen(vp->name); 01450 if (j > longestnode) 01451 longestnode = j; 01452 vp = vp->next; 01453 } 01454 01455 vp = ast_variable_browse(ourcfg, myrpt->p.extnodes); 01456 while(vp){ 01457 j = strlen(vp->name); 01458 if (j > longestnode) 01459 longestnode = j; 01460 vp = vp->next; 01461 } 01462 01463 myrpt->longestnode = longestnode; 01464 } 01465 val = NULL; 01466 if (ourcfg) 01467 val = (char *) ast_variable_retrieve(ourcfg, myrpt->p.extnodes, digitbuf); 01468 ast_mutex_unlock(&nodelookuplock); 01469 return(val); 01470 }
static int openserial | ( | char * | fname | ) | [static] |
Definition at line 1155 of file app_rpt.c.
References ast_log(), ECHO, errno, LOG_WARNING, and MAX.
01156 { 01157 struct termios mode; 01158 int fd; 01159 01160 fd = open(fname,O_RDWR); 01161 if (fd == -1) 01162 { 01163 ast_log(LOG_WARNING,"Cannot open serial port %s\n",fname); 01164 return -1; 01165 } 01166 memset(&mode, 0, sizeof(mode)); 01167 if (tcgetattr(fd, &mode)) { 01168 ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", fname, strerror(errno)); 01169 return -1; 01170 } 01171 #ifndef SOLARIS 01172 cfmakeraw(&mode); 01173 #else 01174 mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP 01175 |INLCR|IGNCR|ICRNL|IXON); 01176 mode.c_oflag &= ~OPOST; 01177 mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 01178 mode.c_cflag &= ~(CSIZE|PARENB|CRTSCTS); 01179 mode.c_cflag |= CS8; 01180 mode.c_cc[TIME] = 3; 01181 mode.c_cc[MAX] = 1; 01182 #endif 01183 01184 cfsetispeed(&mode, B9600); 01185 cfsetospeed(&mode, B9600); 01186 if (tcsetattr(fd, TCSANOW, &mode)) 01187 ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", fname, strerror(errno)); 01188 return(fd); 01189 }
static int play_silence | ( | struct ast_channel * | chan, | |
int | duration | |||
) | [static] |
Definition at line 2457 of file app_rpt.c.
References play_tone_pair().
Referenced by send_morse().
02458 { 02459 return play_tone_pair(chan, 0, 0, duration, 0); 02460 }
static int play_tone | ( | struct ast_channel * | chan, | |
int | freq, | |||
int | duration, | |||
int | amplitude | |||
) | [static] |
Definition at line 2452 of file app_rpt.c.
References play_tone_pair().
Referenced by rpt_tele_thread(), and send_morse().
02453 { 02454 return play_tone_pair(chan, freq, 0, duration, amplitude); 02455 }
static int play_tone_pair | ( | struct ast_channel * | chan, | |
int | f1, | |||
int | f2, | |||
int | duration, | |||
int | amplitude | |||
) | [static] |
Definition at line 2438 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().
02439 { 02440 int res; 02441 02442 if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude))) 02443 return res; 02444 02445 while(chan->generatordata) { 02446 if (ast_safe_sleep(chan,1)) return -1; 02447 } 02448 02449 return 0; 02450 }
static void queue_id | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 8640 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().
08641 { 08642 if(myrpt->p.idtime){ /* ID time must be non-zero */ 08643 myrpt->mustid = myrpt->tailid = 0; 08644 myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */ 08645 rpt_mutex_unlock(&myrpt->lock); 08646 rpt_telemetry(myrpt,ID,NULL); 08647 rpt_mutex_lock(&myrpt->lock); 08648 } 08649 }
static int rbi_mhztoband | ( | char * | str | ) | [static] |
Definition at line 5697 of file app_rpt.c.
Referenced by setrbi(), and setrbi_check().
05698 { 05699 int i; 05700 05701 i = atoi(str) / 10; /* get the 10's of mhz */ 05702 switch(i) 05703 { 05704 case 2: 05705 return 10; 05706 case 5: 05707 return 11; 05708 case 14: 05709 return 2; 05710 case 22: 05711 return 3; 05712 case 44: 05713 return 4; 05714 case 124: 05715 return 0; 05716 case 125: 05717 return 1; 05718 case 126: 05719 return 8; 05720 case 127: 05721 return 5; 05722 case 128: 05723 return 6; 05724 case 129: 05725 return 7; 05726 default: 05727 break; 05728 } 05729 return -1; 05730 }
static void rbi_out | ( | struct rpt * | myrpt, | |
unsigned char * | data | |||
) | [static] |
Definition at line 5856 of file app_rpt.c.
References ast_log(), ast_channel::fds, LOG_WARNING, ast_channel::name, rbi_out_parallel(), and rpt::zaprxchannel.
Referenced by setrbi().
05857 { 05858 struct dahdi_radio_param r; 05859 05860 memset(&r,0,sizeof(struct dahdi_radio_param)); 05861 r.radpar = DAHDI_RADPAR_REMMODE; 05862 r.data = DAHDI_RADPAR_REM_RBI1; 05863 /* if setparam ioctl fails, its probably not a pciradio card */ 05864 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&r) == -1) 05865 { 05866 rbi_out_parallel(myrpt,data); 05867 return; 05868 } 05869 r.radpar = DAHDI_RADPAR_REMCOMMAND; 05870 memcpy(&r.data,data,5); 05871 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&r) == -1) 05872 { 05873 ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->zaprxchannel->name); 05874 return; 05875 } 05876 }
static void rbi_out_parallel | ( | struct rpt * | myrpt, | |
unsigned char * | data | |||
) | [static] |
Definition at line 5828 of file app_rpt.c.
References rpt::iobase, and rpt::p.
Referenced by rbi_out().
05829 { 05830 #ifdef __i386__ 05831 int i,j; 05832 unsigned char od,d; 05833 static volatile long long delayvar; 05834 05835 for(i = 0 ; i < 5 ; i++){ 05836 od = *data++; 05837 for(j = 0 ; j < 8 ; j++){ 05838 d = od & 1; 05839 outb(d,myrpt->p.iobase); 05840 /* >= 15 us */ 05841 for(delayvar = 1; delayvar < 15000; delayvar++); 05842 od >>= 1; 05843 outb(d | 2,myrpt->p.iobase); 05844 /* >= 30 us */ 05845 for(delayvar = 1; delayvar < 30000; delayvar++); 05846 outb(d,myrpt->p.iobase); 05847 /* >= 10 us */ 05848 for(delayvar = 1; delayvar < 10000; delayvar++); 05849 } 05850 } 05851 /* >= 50 us */ 05852 for(delayvar = 1; delayvar < 50000; delayvar++); 05853 #endif 05854 }
static int rbi_pltocode | ( | char * | str | ) | [static] |
Definition at line 5733 of file app_rpt.c.
References s.
Referenced by setrbi(), and setrbi_check().
05734 { 05735 int i; 05736 char *s; 05737 05738 s = strchr(str,'.'); 05739 i = 0; 05740 if (s) i = atoi(s + 1); 05741 i += atoi(str) * 10; 05742 switch(i) 05743 { 05744 case 670: 05745 return 0; 05746 case 719: 05747 return 1; 05748 case 744: 05749 return 2; 05750 case 770: 05751 return 3; 05752 case 797: 05753 return 4; 05754 case 825: 05755 return 5; 05756 case 854: 05757 return 6; 05758 case 885: 05759 return 7; 05760 case 915: 05761 return 8; 05762 case 948: 05763 return 9; 05764 case 974: 05765 return 10; 05766 case 1000: 05767 return 11; 05768 case 1035: 05769 return 12; 05770 case 1072: 05771 return 13; 05772 case 1109: 05773 return 14; 05774 case 1148: 05775 return 15; 05776 case 1188: 05777 return 16; 05778 case 1230: 05779 return 17; 05780 case 1273: 05781 return 18; 05782 case 1318: 05783 return 19; 05784 case 1365: 05785 return 20; 05786 case 1413: 05787 return 21; 05788 case 1462: 05789 return 22; 05790 case 1514: 05791 return 23; 05792 case 1567: 05793 return 24; 05794 case 1622: 05795 return 25; 05796 case 1679: 05797 return 26; 05798 case 1738: 05799 return 27; 05800 case 1799: 05801 return 28; 05802 case 1862: 05803 return 29; 05804 case 1928: 05805 return 30; 05806 case 2035: 05807 return 31; 05808 case 2107: 05809 return 32; 05810 case 2181: 05811 return 33; 05812 case 2257: 05813 return 34; 05814 case 2336: 05815 return 35; 05816 case 2418: 05817 return 36; 05818 case 2503: 05819 return 37; 05820 } 05821 return -1; 05822 }
static int reload | ( | void | ) | [static] |
static int retreive_memory | ( | struct rpt * | myrpt, | |
char * | memory | |||
) | [static] |
Definition at line 7657 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().
07658 { 07659 char tmp[30], *s, *s1, *val; 07660 07661 val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.memory, memory); 07662 if (!val){ 07663 return -1; 07664 } 07665 strncpy(tmp,val,sizeof(tmp) - 1); 07666 tmp[sizeof(tmp)-1] = 0; 07667 07668 s = strchr(tmp,','); 07669 if (!s) 07670 return 1; 07671 *s++ = 0; 07672 s1 = strchr(s,','); 07673 if (!s1) 07674 return 1; 07675 *s1++ = 0; 07676 strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1); 07677 strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1); 07678 strncpy(myrpt->txpl, s, sizeof(myrpt->rxpl) - 1); 07679 myrpt->remmode = REM_MODE_FM; 07680 myrpt->offset = REM_SIMPLEX; 07681 myrpt->powerlevel = REM_MEDPWR; 07682 myrpt->txplon = myrpt->rxplon = 0; 07683 while(*s1){ 07684 switch(*s1++){ 07685 case 'A': 07686 case 'a': 07687 strcpy(myrpt->rxpl, "100.0"); 07688 strcpy(myrpt->txpl, "100.0"); 07689 myrpt->remmode = REM_MODE_AM; 07690 break; 07691 case 'B': 07692 case 'b': 07693 strcpy(myrpt->rxpl, "100.0"); 07694 strcpy(myrpt->txpl, "100.0"); 07695 myrpt->remmode = REM_MODE_LSB; 07696 break; 07697 case 'F': 07698 myrpt->remmode = REM_MODE_FM; 07699 break; 07700 case 'L': 07701 case 'l': 07702 myrpt->powerlevel = REM_LOWPWR; 07703 break; 07704 case 'H': 07705 case 'h': 07706 myrpt->powerlevel = REM_HIPWR; 07707 break; 07708 07709 case 'M': 07710 case 'm': 07711 myrpt->powerlevel = REM_MEDPWR; 07712 break; 07713 07714 case '-': 07715 myrpt->offset = REM_MINUS; 07716 break; 07717 07718 case '+': 07719 myrpt->offset = REM_PLUS; 07720 break; 07721 07722 case 'S': 07723 case 's': 07724 myrpt->offset = REM_SIMPLEX; 07725 break; 07726 07727 case 'T': 07728 case 't': 07729 myrpt->txplon = 1; 07730 break; 07731 07732 case 'R': 07733 case 'r': 07734 myrpt->rxplon = 1; 07735 break; 07736 07737 case 'U': 07738 case 'u': 07739 strcpy(myrpt->rxpl, "100.0"); 07740 strcpy(myrpt->txpl, "100.0"); 07741 myrpt->remmode = REM_MODE_USB; 07742 break; 07743 default: 07744 return 1; 07745 } 07746 } 07747 return 0; 07748 }
static int retrieve_astcfgint | ( | struct rpt * | myrpt, | |
char * | category, | |||
char * | name, | |||
int | min, | |||
int | max, | |||
int | defl | |||
) | [static] |
Definition at line 1594 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().
01595 { 01596 char *var; 01597 int ret; 01598 char include_zero = 0; 01599 01600 if(min < 0){ /* If min is negative, this means include 0 as a valid entry */ 01601 min = -min; 01602 include_zero = 1; 01603 } 01604 01605 var = (char *) ast_variable_retrieve(myrpt->cfg, category, name); 01606 if(var){ 01607 ret = myatoi(var); 01608 if(include_zero && !ret) 01609 return 0; 01610 if(ret < min) 01611 ret = min; 01612 if(ret > max) 01613 ret = max; 01614 } 01615 else 01616 ret = defl; 01617 return ret; 01618 }
static void* rpt | ( | void * | this | ) | [static] |
Definition at line 8774 of file app_rpt.c.
References __kickshort(), __mklinklist(), ast_channel::_state, sysstate::alternatetail, rpt::althangtime, ast_channel::appl, rpt::archivedir, ast_call(), AST_CDR_FLAG_POST_DISABLED, ast_channel_setoption(), ast_check_hangup(), ast_closestream(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_FORMAT_SLINEAR, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frdup(), ast_frfree, ast_hangup(), ast_indicate(), ast_log(), AST_OPTION_RELAXDTMF, AST_OPTION_TONE_VERIFY, AST_PTHREADT_STOP, ast_read(), ast_request(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_BUSY, AST_STATE_UP, ast_variable_retrieve(), ast_verbose(), ast_waitfor_n(), ast_write(), ast_writefile(), ast_writestream(), attempt_reconnect(), rpt::callmode, ast_channel::cdr, rpt::cfg, rpt_link::chan, rpt_tele::chan, rpt::cmdnode, rpt::conf, CONNECTED, rpt_link::connected, rpt_link::connecttime, CONNFAIL, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, ast_frame::data, ast_channel::data, ast_frame::datalen, DISC_TIME, rpt_link::disced, rpt_link::disctime, rpt::disgorgetime, diskavail(), do_dtmf_local(), do_scheduler(), donodelog(), rpt::dtmf_local_timer, rpt::dtmf_time, DTMF_TIMEOUT, rpt::dtmfbuf, rpt_link::dtmfed, rpt::dtmfidx, rpt::duplex, rpt_link::elaptime, rpt::exten, rpt::exttx, f, ast_channel::fds, free, func_xlat(), handle_link_data(), handle_link_phone_dtmf(), rpt::hangtime, rpt_link::hasconnected, ID, IDTALKOVER, rpt::idtime, rpt::idtimer, rpt::inxlat, rpt_link::isremote, rpt::keyed, rpt_link::killme, rpt::lastdtmfcommand, rpt_link::lastf1, rpt::lastf1, rpt_link::lastf2, rpt::lastf2, rpt::lastnodewhichkeyedusup, rpt_link::lastrx, rpt_link::lastrx1, rpt_link::lasttx, LINKLISTTIME, rpt_link::linklisttimer, rpt::links, rpt::linktolink, LINKUNKEY, load_rpt_vars(), local_dtmf_helper(), rpt::localtx, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macrobuf, MACROPTIME, MACROTIME, rpt::macrotimer, rpt_link::max_retries, MAXCONNECTTIME, MAXLINKLIST, MAXMACRO, mdc1200_notify(), rpt_link::mode, rpt_tele::mode, rpt::monchannel, rpt::monminblocks, rpt::monstream, MSWAIT, rpt::mustid, rpt_link::name, ast_channel::name, rpt::name, rpt_link::next, rpt_tele::next, rpt::notelemtx, option_verbose, rpt_link::outbound, rpt::p, rpt_link::pchan, rpt::pchannel, rpt_link::phonemode, rpt::politeid, rpt_link::prev, queue_id(), rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, REMDISC, rpt_link::rerxtimer, rpt::rerxtimer, rpt_link::retries, RETRY_TIMER_MS, rpt_link::retrytimer, rpt_link::retxtimer, rpt::retxtimer, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, rpt::rxchannel, s, rpt::s, rpt::scram, rpt::skedtimer, START_DELAY, rpt::startupmacro, rpt::sysstate_cur, t, rpt::tailevent, rpt::tailid, rpt::tailmessages, rpt::tailmessagetime, TAILMSG, rpt::tailtimer, rpt::tele, rpt_link::thisconnected, TIMEOUT, rpt::timeouts, rpt::tmsgtimer, rpt::tonotify, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, rpt::totime, rpt::totimer, rpt::tounkeyed, rpt::txchanname, rpt::txchannel, rpt::txconf, sysstate::txdisable, rpt::txpchannel, UNKEY, VERBOSE_PREFIX_3, ast_channel::whentohangup, rpt::zaprxchannel, and rpt::zaptxchannel.
08775 { 08776 struct rpt *myrpt = (struct rpt *)this; 08777 char *tele,*idtalkover,c; 08778 int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,othertelemqueued; 08779 int tailmessagequeued,ctqueued,dtmfed; 08780 struct ast_channel *who; 08781 struct dahdi_confinfo ci; /* conference info */ 08782 time_t t; 08783 struct rpt_link *l,*m; 08784 struct rpt_tele *telem; 08785 char tmpstr[300],lstr[MAXLINKLIST]; 08786 08787 08788 if (myrpt->p.archivedir) mkdir(myrpt->p.archivedir,0600); 08789 sprintf(tmpstr,"%s/%s",myrpt->p.archivedir,myrpt->name); 08790 mkdir(tmpstr,0600); 08791 rpt_mutex_lock(&myrpt->lock); 08792 08793 telem = myrpt->tele.next; 08794 while(telem != &myrpt->tele) 08795 { 08796 ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV); 08797 telem = telem->next; 08798 } 08799 rpt_mutex_unlock(&myrpt->lock); 08800 /* find our index, and load the vars initially */ 08801 for(i = 0; i < nrpts; i++) 08802 { 08803 if (&rpt_vars[i] == myrpt) 08804 { 08805 load_rpt_vars(i,0); 08806 break; 08807 } 08808 } 08809 rpt_mutex_lock(&myrpt->lock); 08810 strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1); 08811 tele = strchr(tmpstr,'/'); 08812 if (!tele) 08813 { 08814 fprintf(stderr,"rpt:Rxchannel Dial number (%s) must be in format tech/number\n",myrpt->rxchanname); 08815 rpt_mutex_unlock(&myrpt->lock); 08816 myrpt->rpt_thread = AST_PTHREADT_STOP; 08817 pthread_exit(NULL); 08818 } 08819 *tele++ = 0; 08820 myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 08821 myrpt->zaprxchannel = NULL; 08822 if (!strcasecmp(tmpstr,"Zap")) 08823 myrpt->zaprxchannel = myrpt->rxchannel; 08824 if (myrpt->rxchannel) 08825 { 08826 if (myrpt->rxchannel->_state == AST_STATE_BUSY) 08827 { 08828 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 08829 rpt_mutex_unlock(&myrpt->lock); 08830 ast_hangup(myrpt->rxchannel); 08831 myrpt->rpt_thread = AST_PTHREADT_STOP; 08832 pthread_exit(NULL); 08833 } 08834 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 08835 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 08836 #ifdef AST_CDR_FLAG_POST_DISABLED 08837 ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08838 #endif 08839 myrpt->rxchannel->whentohangup = 0; 08840 myrpt->rxchannel->appl = "Apprpt"; 08841 myrpt->rxchannel->data = "(Repeater Rx)"; 08842 if (option_verbose > 2) 08843 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 08844 tmpstr,tele,myrpt->rxchannel->name); 08845 ast_call(myrpt->rxchannel,tele,999); 08846 if (myrpt->rxchannel->_state != AST_STATE_UP) 08847 { 08848 rpt_mutex_unlock(&myrpt->lock); 08849 ast_hangup(myrpt->rxchannel); 08850 myrpt->rpt_thread = AST_PTHREADT_STOP; 08851 pthread_exit(NULL); 08852 } 08853 } 08854 else 08855 { 08856 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 08857 rpt_mutex_unlock(&myrpt->lock); 08858 myrpt->rpt_thread = AST_PTHREADT_STOP; 08859 pthread_exit(NULL); 08860 } 08861 myrpt->zaptxchannel = NULL; 08862 if (myrpt->txchanname) 08863 { 08864 strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1); 08865 tele = strchr(tmpstr,'/'); 08866 if (!tele) 08867 { 08868 fprintf(stderr,"rpt:Txchannel Dial number (%s) must be in format tech/number\n",myrpt->txchanname); 08869 rpt_mutex_unlock(&myrpt->lock); 08870 ast_hangup(myrpt->rxchannel); 08871 myrpt->rpt_thread = AST_PTHREADT_STOP; 08872 pthread_exit(NULL); 08873 } 08874 *tele++ = 0; 08875 myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 08876 if (!strcasecmp(tmpstr,"Zap")) 08877 myrpt->zaptxchannel = myrpt->txchannel; 08878 if (myrpt->txchannel) 08879 { 08880 if (myrpt->txchannel->_state == AST_STATE_BUSY) 08881 { 08882 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 08883 rpt_mutex_unlock(&myrpt->lock); 08884 ast_hangup(myrpt->txchannel); 08885 ast_hangup(myrpt->rxchannel); 08886 myrpt->rpt_thread = AST_PTHREADT_STOP; 08887 pthread_exit(NULL); 08888 } 08889 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 08890 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 08891 #ifdef AST_CDR_FLAG_POST_DISABLED 08892 ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08893 #endif 08894 myrpt->txchannel->whentohangup = 0; 08895 myrpt->txchannel->appl = "Apprpt"; 08896 myrpt->txchannel->data = "(Repeater Tx)"; 08897 if (option_verbose > 2) 08898 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 08899 tmpstr,tele,myrpt->txchannel->name); 08900 ast_call(myrpt->txchannel,tele,999); 08901 if (myrpt->rxchannel->_state != AST_STATE_UP) 08902 { 08903 rpt_mutex_unlock(&myrpt->lock); 08904 ast_hangup(myrpt->rxchannel); 08905 ast_hangup(myrpt->txchannel); 08906 myrpt->rpt_thread = AST_PTHREADT_STOP; 08907 pthread_exit(NULL); 08908 } 08909 } 08910 else 08911 { 08912 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 08913 rpt_mutex_unlock(&myrpt->lock); 08914 ast_hangup(myrpt->rxchannel); 08915 myrpt->rpt_thread = AST_PTHREADT_STOP; 08916 pthread_exit(NULL); 08917 } 08918 } 08919 else 08920 { 08921 myrpt->txchannel = myrpt->rxchannel; 08922 } 08923 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 08924 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 08925 /* allocate a pseudo-channel thru asterisk */ 08926 myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08927 if (!myrpt->pchannel) 08928 { 08929 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08930 rpt_mutex_unlock(&myrpt->lock); 08931 if (myrpt->txchannel != myrpt->rxchannel) 08932 ast_hangup(myrpt->txchannel); 08933 ast_hangup(myrpt->rxchannel); 08934 myrpt->rpt_thread = AST_PTHREADT_STOP; 08935 pthread_exit(NULL); 08936 } 08937 #ifdef AST_CDR_FLAG_POST_DISABLED 08938 ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08939 #endif 08940 if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel; 08941 if (!myrpt->zaptxchannel) 08942 { 08943 /* allocate a pseudo-channel thru asterisk */ 08944 myrpt->zaptxchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08945 if (!myrpt->zaptxchannel) 08946 { 08947 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08948 rpt_mutex_unlock(&myrpt->lock); 08949 if (myrpt->txchannel != myrpt->rxchannel) 08950 ast_hangup(myrpt->txchannel); 08951 ast_hangup(myrpt->rxchannel); 08952 myrpt->rpt_thread = AST_PTHREADT_STOP; 08953 pthread_exit(NULL); 08954 } 08955 ast_set_read_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR); 08956 ast_set_write_format(myrpt->zaptxchannel,AST_FORMAT_SLINEAR); 08957 #ifdef AST_CDR_FLAG_POST_DISABLED 08958 ast_set_flag(myrpt->zaptxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08959 #endif 08960 } 08961 /* allocate a pseudo-channel thru asterisk */ 08962 myrpt->monchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 08963 if (!myrpt->monchannel) 08964 { 08965 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 08966 rpt_mutex_unlock(&myrpt->lock); 08967 if (myrpt->txchannel != myrpt->rxchannel) 08968 ast_hangup(myrpt->txchannel); 08969 ast_hangup(myrpt->rxchannel); 08970 myrpt->rpt_thread = AST_PTHREADT_STOP; 08971 pthread_exit(NULL); 08972 } 08973 ast_set_read_format(myrpt->monchannel,AST_FORMAT_SLINEAR); 08974 ast_set_write_format(myrpt->monchannel,AST_FORMAT_SLINEAR); 08975 #ifdef AST_CDR_FLAG_POST_DISABLED 08976 ast_set_flag(myrpt->monchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 08977 #endif 08978 /* make a conference for the tx */ 08979 ci.chan = 0; 08980 ci.confno = -1; /* make a new conf */ 08981 ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_LISTENER; 08982 /* first put the channel on the conference in proper mode */ 08983 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_SETCONF,&ci) == -1) 08984 { 08985 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 08986 rpt_mutex_unlock(&myrpt->lock); 08987 ast_hangup(myrpt->pchannel); 08988 ast_hangup(myrpt->monchannel); 08989 if (myrpt->txchannel != myrpt->rxchannel) 08990 ast_hangup(myrpt->txchannel); 08991 ast_hangup(myrpt->rxchannel); 08992 myrpt->rpt_thread = AST_PTHREADT_STOP; 08993 pthread_exit(NULL); 08994 } 08995 /* save tx conference number */ 08996 myrpt->txconf = ci.confno; 08997 /* make a conference for the pseudo */ 08998 ci.chan = 0; 08999 ci.confno = -1; /* make a new conf */ 09000 ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? DAHDI_CONF_CONFANNMON : 09001 (DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER); 09002 /* first put the channel on the conference in announce mode */ 09003 if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1) 09004 { 09005 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 09006 rpt_mutex_unlock(&myrpt->lock); 09007 ast_hangup(myrpt->pchannel); 09008 ast_hangup(myrpt->monchannel); 09009 if (myrpt->txchannel != myrpt->rxchannel) 09010 ast_hangup(myrpt->txchannel); 09011 ast_hangup(myrpt->rxchannel); 09012 myrpt->rpt_thread = AST_PTHREADT_STOP; 09013 pthread_exit(NULL); 09014 } 09015 /* save pseudo channel conference number */ 09016 myrpt->conf = ci.confno; 09017 /* make a conference for the pseudo */ 09018 ci.chan = 0; 09019 if ((strstr(myrpt->txchannel->name,"pseudo") == NULL) && 09020 (myrpt->zaptxchannel == myrpt->txchannel)) 09021 { 09022 /* get tx channel's port number */ 09023 if (ioctl(myrpt->txchannel->fds[0],DAHDI_CHANNO,&ci.confno) == -1) 09024 { 09025 ast_log(LOG_WARNING, "Unable to set tx channel's chan number\n"); 09026 rpt_mutex_unlock(&myrpt->lock); 09027 ast_hangup(myrpt->pchannel); 09028 ast_hangup(myrpt->monchannel); 09029 if (myrpt->txchannel != myrpt->rxchannel) 09030 ast_hangup(myrpt->txchannel); 09031 ast_hangup(myrpt->rxchannel); 09032 myrpt->rpt_thread = AST_PTHREADT_STOP; 09033 pthread_exit(NULL); 09034 } 09035 ci.confmode = DAHDI_CONF_MONITORTX; 09036 } 09037 else 09038 { 09039 ci.confno = myrpt->txconf; 09040 ci.confmode = DAHDI_CONF_CONFANNMON; 09041 } 09042 /* first put the channel on the conference in announce mode */ 09043 if (ioctl(myrpt->monchannel->fds[0],DAHDI_SETCONF,&ci) == -1) 09044 { 09045 ast_log(LOG_WARNING, "Unable to set conference mode for monitor\n"); 09046 rpt_mutex_unlock(&myrpt->lock); 09047 ast_hangup(myrpt->pchannel); 09048 ast_hangup(myrpt->monchannel); 09049 if (myrpt->txchannel != myrpt->rxchannel) 09050 ast_hangup(myrpt->txchannel); 09051 ast_hangup(myrpt->rxchannel); 09052 myrpt->rpt_thread = AST_PTHREADT_STOP; 09053 pthread_exit(NULL); 09054 } 09055 /* allocate a pseudo-channel thru asterisk */ 09056 myrpt->txpchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 09057 if (!myrpt->txpchannel) 09058 { 09059 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 09060 rpt_mutex_unlock(&myrpt->lock); 09061 ast_hangup(myrpt->pchannel); 09062 ast_hangup(myrpt->monchannel); 09063 if (myrpt->txchannel != myrpt->rxchannel) 09064 ast_hangup(myrpt->txchannel); 09065 ast_hangup(myrpt->rxchannel); 09066 myrpt->rpt_thread = AST_PTHREADT_STOP; 09067 pthread_exit(NULL); 09068 } 09069 #ifdef AST_CDR_FLAG_POST_DISABLED 09070 ast_set_flag(myrpt->txpchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 09071 #endif 09072 /* make a conference for the tx */ 09073 ci.chan = 0; 09074 ci.confno = myrpt->txconf; 09075 ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER ; 09076 /* first put the channel on the conference in proper mode */ 09077 if (ioctl(myrpt->txpchannel->fds[0],DAHDI_SETCONF,&ci) == -1) 09078 { 09079 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 09080 rpt_mutex_unlock(&myrpt->lock); 09081 ast_hangup(myrpt->txpchannel); 09082 ast_hangup(myrpt->monchannel); 09083 if (myrpt->txchannel != myrpt->rxchannel) 09084 ast_hangup(myrpt->txchannel); 09085 ast_hangup(myrpt->rxchannel); 09086 myrpt->rpt_thread = AST_PTHREADT_STOP; 09087 pthread_exit(NULL); 09088 } 09089 /* Now, the idea here is to copy from the physical rx channel buffer 09090 into the pseudo tx buffer, and from the pseudo rx buffer into the 09091 tx channel buffer */ 09092 myrpt->links.next = &myrpt->links; 09093 myrpt->links.prev = &myrpt->links; 09094 myrpt->tailtimer = 0; 09095 myrpt->totimer = 0; 09096 myrpt->tmsgtimer = myrpt->p.tailmessagetime; 09097 myrpt->idtimer = myrpt->p.politeid; 09098 myrpt->mustid = myrpt->tailid = 0; 09099 myrpt->callmode = 0; 09100 myrpt->tounkeyed = 0; 09101 myrpt->tonotify = 0; 09102 myrpt->retxtimer = 0; 09103 myrpt->rerxtimer = 0; 09104 myrpt->skedtimer = 0; 09105 myrpt->tailevent = 0; 09106 lasttx = 0; 09107 myrpt->keyed = 0; 09108 idtalkover = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "idtalkover"); 09109 myrpt->dtmfidx = -1; 09110 myrpt->dtmfbuf[0] = 0; 09111 myrpt->rem_dtmfidx = -1; 09112 myrpt->rem_dtmfbuf[0] = 0; 09113 myrpt->dtmf_time = 0; 09114 myrpt->rem_dtmf_time = 0; 09115 myrpt->disgorgetime = 0; 09116 myrpt->lastnodewhichkeyedusup[0] = '\0'; 09117 myrpt->dailytxtime = 0; 09118 myrpt->totaltxtime = 0; 09119 myrpt->dailykeyups = 0; 09120 myrpt->totalkeyups = 0; 09121 myrpt->dailykerchunks = 0; 09122 myrpt->totalkerchunks = 0; 09123 myrpt->dailyexecdcommands = 0; 09124 myrpt->totalexecdcommands = 0; 09125 myrpt->timeouts = 0; 09126 myrpt->exten[0] = '\0'; 09127 myrpt->lastdtmfcommand[0] = '\0'; 09128 if (myrpt->p.startupmacro) 09129 { 09130 snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro); 09131 } 09132 rpt_mutex_unlock(&myrpt->lock); 09133 val = 1; 09134 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0); 09135 val = 1; 09136 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0); 09137 if (myrpt->p.archivedir) donodelog(myrpt,"STARTUP"); 09138 dtmfed = 0; 09139 while (ms >= 0) 09140 { 09141 struct ast_frame *f,*f1,*f2; 09142 struct ast_channel *cs[300],*cs1[300]; 09143 int totx=0,elap=0,n,x,toexit=0; 09144 09145 /* DEBUG Dump */ 09146 if((myrpt->disgorgetime) && (time(NULL) >= myrpt->disgorgetime)){ 09147 struct rpt_link *zl; 09148 struct rpt_tele *zt; 09149 09150 myrpt->disgorgetime = 0; 09151 ast_log(LOG_NOTICE,"********** Variable Dump Start (app_rpt) **********\n"); 09152 ast_log(LOG_NOTICE,"totx = %d\n",totx); 09153 ast_log(LOG_NOTICE,"remrx = %d\n",remrx); 09154 ast_log(LOG_NOTICE,"lasttx = %d\n",lasttx); 09155 ast_log(LOG_NOTICE,"elap = %d\n",elap); 09156 ast_log(LOG_NOTICE,"toexit = %d\n",toexit); 09157 09158 ast_log(LOG_NOTICE,"myrpt->keyed = %d\n",myrpt->keyed); 09159 ast_log(LOG_NOTICE,"myrpt->localtx = %d\n",myrpt->localtx); 09160 ast_log(LOG_NOTICE,"myrpt->callmode = %d\n",myrpt->callmode); 09161 ast_log(LOG_NOTICE,"myrpt->mustid = %d\n",myrpt->mustid); 09162 ast_log(LOG_NOTICE,"myrpt->tounkeyed = %d\n",myrpt->tounkeyed); 09163 ast_log(LOG_NOTICE,"myrpt->tonotify = %d\n",myrpt->tonotify); 09164 ast_log(LOG_NOTICE,"myrpt->retxtimer = %ld\n",myrpt->retxtimer); 09165 ast_log(LOG_NOTICE,"myrpt->totimer = %d\n",myrpt->totimer); 09166 ast_log(LOG_NOTICE,"myrpt->tailtimer = %d\n",myrpt->tailtimer); 09167 ast_log(LOG_NOTICE,"myrpt->tailevent = %d\n",myrpt->tailevent); 09168 09169 zl = myrpt->links.next; 09170 while(zl != &myrpt->links){ 09171 ast_log(LOG_NOTICE,"*** Link Name: %s ***\n",zl->name); 09172 ast_log(LOG_NOTICE," link->lasttx %d\n",zl->lasttx); 09173 ast_log(LOG_NOTICE," link->lastrx %d\n",zl->lastrx); 09174 ast_log(LOG_NOTICE," link->connected %d\n",zl->connected); 09175 ast_log(LOG_NOTICE," link->hasconnected %d\n",zl->hasconnected); 09176 ast_log(LOG_NOTICE," link->outbound %d\n",zl->outbound); 09177 ast_log(LOG_NOTICE," link->disced %d\n",zl->disced); 09178 ast_log(LOG_NOTICE," link->killme %d\n",zl->killme); 09179 ast_log(LOG_NOTICE," link->disctime %ld\n",zl->disctime); 09180 ast_log(LOG_NOTICE," link->retrytimer %ld\n",zl->retrytimer); 09181 ast_log(LOG_NOTICE," link->retries = %d\n",zl->retries); 09182 ast_log(LOG_NOTICE," link->reconnects = %d\n",zl->reconnects); 09183 zl = zl->next; 09184 } 09185 09186 zt = myrpt->tele.next; 09187 if(zt != &myrpt->tele) 09188 ast_log(LOG_NOTICE,"*** Telemetry Queue ***\n"); 09189 while(zt != &myrpt->tele){ 09190 ast_log(LOG_NOTICE," Telemetry mode: %d\n",zt->mode); 09191 zt = zt->next; 09192 } 09193 ast_log(LOG_NOTICE,"******* Variable Dump End (app_rpt) *******\n"); 09194 09195 } 09196 09197 09198 if (myrpt->reload) 09199 { 09200 struct rpt_tele *telem; 09201 09202 rpt_mutex_lock(&myrpt->lock); 09203 telem = myrpt->tele.next; 09204 while(telem != &myrpt->tele) 09205 { 09206 ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV); 09207 telem = telem->next; 09208 } 09209 myrpt->reload = 0; 09210 rpt_mutex_unlock(&myrpt->lock); 09211 usleep(10000); 09212 /* find our index, and load the vars */ 09213 for(i = 0; i < nrpts; i++) 09214 { 09215 if (&rpt_vars[i] == myrpt) 09216 { 09217 load_rpt_vars(i,0); 09218 break; 09219 } 09220 } 09221 } 09222 09223 rpt_mutex_lock(&myrpt->lock); 09224 if (ast_check_hangup(myrpt->rxchannel)) break; 09225 if (ast_check_hangup(myrpt->txchannel)) break; 09226 if (ast_check_hangup(myrpt->pchannel)) break; 09227 if (ast_check_hangup(myrpt->monchannel)) break; 09228 if (ast_check_hangup(myrpt->txpchannel)) break; 09229 if (myrpt->zaptxchannel && ast_check_hangup(myrpt->zaptxchannel)) break; 09230 09231 /* Set local tx with keyed */ 09232 myrpt->localtx = myrpt->keyed; 09233 /* If someone's connected, and they're transmitting from their end to us, set remrx true */ 09234 l = myrpt->links.next; 09235 remrx = 0; 09236 while(l != &myrpt->links) 09237 { 09238 if (l->lastrx){ 09239 remrx = 1; 09240 if(l->name[0] != '0') /* Ignore '0' nodes */ 09241 strcpy(myrpt->lastnodewhichkeyedusup, l->name); /* Note the node which is doing the key up */ 09242 } 09243 l = l->next; 09244 } 09245 /* Create a "must_id" flag for the cleanup ID */ 09246 if(myrpt->p.idtime) /* ID time must be non-zero */ 09247 myrpt->mustid |= (myrpt->idtimer) && (myrpt->keyed || remrx) ; 09248 /* Build a fresh totx from myrpt->keyed and autopatch activated */ 09249 totx = myrpt->callmode; 09250 /* If full duplex, add local tx to totx */ 09251 if (myrpt->p.duplex > 1) 09252 { 09253 totx = totx || myrpt->localtx; 09254 } 09255 /* Traverse the telemetry list to see what's queued */ 09256 identqueued = 0; 09257 othertelemqueued = 0; 09258 tailmessagequeued = 0; 09259 ctqueued = 0; 09260 telem = myrpt->tele.next; 09261 while(telem != &myrpt->tele) 09262 { 09263 if((telem->mode == ID) || (telem->mode == IDTALKOVER)){ 09264 identqueued = 1; /* Identification telemetry */ 09265 } 09266 else if(telem->mode == TAILMSG) 09267 { 09268 tailmessagequeued = 1; /* Tail message telemetry */ 09269 } 09270 else 09271 { 09272 if ((telem->mode != UNKEY) && (telem->mode != LINKUNKEY)) 09273 othertelemqueued = 1; /* Other telemetry */ 09274 else 09275 ctqueued = 1; /* Courtesy tone telemetry */ 09276 } 09277 telem = telem->next; 09278 } 09279 09280 /* Add in any "other" telemetry, unless specified otherwise */ 09281 if (!myrpt->p.notelemtx) totx = totx || othertelemqueued; 09282 /* Update external (to links) transmitter PTT state with everything but ID, CT, and tailmessage telemetry */ 09283 myrpt->exttx = totx; 09284 totx = totx || myrpt->dtmf_local_timer; 09285 /* If half or 3/4 duplex, add localtx to external link tx */ 09286 if (myrpt->p.duplex < 2) myrpt->exttx = myrpt->exttx || myrpt->localtx; 09287 /* Add in ID telemetry to local transmitter */ 09288 totx = totx || remrx; 09289 /* If 3/4 or full duplex, add in ident and CT telemetry */ 09290 if (myrpt->p.duplex > 0) 09291 totx = totx || identqueued || ctqueued; 09292 /* If full duplex, add local dtmf stuff active */ 09293 if (myrpt->p.duplex > 1) 09294 { 09295 totx = totx || (myrpt->dtmfidx > -1) || 09296 myrpt->cmdnode[0]; 09297 } 09298 /* Reset time out timer variables if there is no activity */ 09299 if (!totx) 09300 { 09301 myrpt->totimer = myrpt->p.totime; 09302 myrpt->tounkeyed = 0; 09303 myrpt->tonotify = 0; 09304 } 09305 else{ 09306 myrpt->tailtimer = myrpt->p.s[myrpt->p.sysstate_cur].alternatetail ? 09307 myrpt->p.althangtime : /* Initialize tail timer */ 09308 myrpt->p.hangtime; 09309 } 09310 /* Disable the local transmitter if we are timed out */ 09311 totx = totx && myrpt->totimer; 09312 /* if timed-out and not said already, say it */ 09313 if ((!myrpt->totimer) && (!myrpt->tonotify)) 09314 { 09315 myrpt->tonotify = 1; 09316 myrpt->timeouts++; 09317 rpt_mutex_unlock(&myrpt->lock); 09318 rpt_telemetry(myrpt,TIMEOUT,NULL); 09319 rpt_mutex_lock(&myrpt->lock); 09320 } 09321 09322 /* If unkey and re-key, reset time out timer */ 09323 if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!myrpt->keyed)) 09324 { 09325 myrpt->tounkeyed = 1; 09326 } 09327 if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->keyed) 09328 { 09329 myrpt->totimer = myrpt->p.totime; 09330 myrpt->tounkeyed = 0; 09331 myrpt->tonotify = 0; 09332 rpt_mutex_unlock(&myrpt->lock); 09333 continue; 09334 } 09335 /* if timed-out and in circuit busy after call */ 09336 if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4)) 09337 { 09338 myrpt->callmode = 0; 09339 } 09340 /* get rid of tail if timed out */ 09341 if (!myrpt->totimer) myrpt->tailtimer = 0; 09342 /* if not timed-out, add in tail */ 09343 if (myrpt->totimer) totx = totx || myrpt->tailtimer; 09344 /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */ 09345 /* If tail message, kill the message if someone keys up over it */ 09346 if ((myrpt->keyed || remrx) && ((identqueued && idtalkover) || (tailmessagequeued))) { 09347 int hasid = 0,hastalkover = 0; 09348 09349 telem = myrpt->tele.next; 09350 while(telem != &myrpt->tele){ 09351 if(telem->mode == ID){ 09352 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 09353 hasid = 1; 09354 } 09355 if(telem->mode == TAILMSG){ 09356 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 09357 } 09358 if (telem->mode == IDTALKOVER) hastalkover = 1; 09359 telem = telem->next; 09360 } 09361 rpt_mutex_unlock(&myrpt->lock); 09362 if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */ 09363 rpt_mutex_lock(&myrpt->lock); 09364 } 09365 /* Try to be polite */ 09366 /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/ 09367 /* If within 30 seconds of the time to ID, try do it in the tail */ 09368 /* else if at ID time limit, do it right over the top of them */ 09369 /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */ 09370 if(myrpt->mustid && (!myrpt->idtimer)) 09371 queue_id(myrpt); 09372 09373 if ((myrpt->p.idtime && totx && (!myrpt->exttx) && 09374 (myrpt->idtimer <= myrpt->p.politeid) && myrpt->tailtimer)) /* ID time must be non-zero */ 09375 { 09376 myrpt->tailid = 1; 09377 } 09378 09379 /* If tail timer expires, then check for tail messages */ 09380 09381 if(myrpt->tailevent){ 09382 myrpt->tailevent = 0; 09383 if(myrpt->tailid){ 09384 totx = 1; 09385 queue_id(myrpt); 09386 } 09387 else if ((myrpt->p.tailmessages[0]) && 09388 (myrpt->p.tailmessagetime) && (myrpt->tmsgtimer == 0)){ 09389 totx = 1; 09390 myrpt->tmsgtimer = myrpt->p.tailmessagetime; 09391 rpt_mutex_unlock(&myrpt->lock); 09392 rpt_telemetry(myrpt, TAILMSG, NULL); 09393 rpt_mutex_lock(&myrpt->lock); 09394 } 09395 } 09396 09397 /* Main TX control */ 09398 09399 /* let telemetry transmit anyway (regardless of timeout) */ 09400 if (myrpt->p.duplex > 0) totx = totx || (myrpt->tele.next != &myrpt->tele); 09401 if (totx && (!lasttx)) 09402 { 09403 char mydate[100],myfname[100]; 09404 time_t myt; 09405 09406 if (myrpt->monstream) ast_closestream(myrpt->monstream); 09407 if (myrpt->p.archivedir) 09408 { 09409 long blocksleft; 09410 09411 time(&myt); 09412 strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S", 09413 localtime(&myt)); 09414 sprintf(myfname,"%s/%s/%s",myrpt->p.archivedir, 09415 myrpt->name,mydate); 09416 myrpt->monstream = ast_writefile(myfname,"wav49", 09417 "app_rpt Air Archive",O_CREAT | O_APPEND,0,0600); 09418 if (myrpt->p.monminblocks) 09419 { 09420 blocksleft = diskavail(myrpt); 09421 if (blocksleft >= myrpt->p.monminblocks) 09422 donodelog(myrpt,"TXKEY,MAIN"); 09423 } else donodelog(myrpt,"TXKEY,MAIN"); 09424 } 09425 lasttx = 1; 09426 myrpt->dailykeyups++; 09427 myrpt->totalkeyups++; 09428 rpt_mutex_unlock(&myrpt->lock); 09429 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 09430 rpt_mutex_lock(&myrpt->lock); 09431 } 09432 totx = totx && !myrpt->p.s[myrpt->p.sysstate_cur].txdisable; 09433 if ((!totx) && lasttx) 09434 { 09435 if (myrpt->monstream) ast_closestream(myrpt->monstream); 09436 myrpt->monstream = NULL; 09437 09438 lasttx = 0; 09439 rpt_mutex_unlock(&myrpt->lock); 09440 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 09441 rpt_mutex_lock(&myrpt->lock); 09442 donodelog(myrpt,"TXUNKEY,MAIN"); 09443 } 09444 time(&t); 09445 /* if DTMF timeout */ 09446 if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((myrpt->dtmf_time + DTMF_TIMEOUT) < t)) 09447 { 09448 myrpt->dtmfidx = -1; 09449 myrpt->dtmfbuf[0] = 0; 09450 } 09451 /* if remote DTMF timeout */ 09452 if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t)) 09453 { 09454 myrpt->rem_dtmfidx = -1; 09455 myrpt->rem_dtmfbuf[0] = 0; 09456 } 09457 09458 /* Reconnect */ 09459 09460 l = myrpt->links.next; 09461 while(l != &myrpt->links) 09462 { 09463 if (l->killme) 09464 { 09465 /* remove from queue */ 09466 remque((struct qelem *) l); 09467 if (!strcmp(myrpt->cmdnode,l->name)) 09468 myrpt->cmdnode[0] = 0; 09469 rpt_mutex_unlock(&myrpt->lock); 09470 /* hang-up on call to device */ 09471 if (l->chan) ast_hangup(l->chan); 09472 ast_hangup(l->pchan); 09473 free(l); 09474 rpt_mutex_lock(&myrpt->lock); 09475 /* re-start link traversal */ 09476 l = myrpt->links.next; 09477 continue; 09478 } 09479 l = l->next; 09480 } 09481 n = 0; 09482 cs[n++] = myrpt->rxchannel; 09483 cs[n++] = myrpt->pchannel; 09484 cs[n++] = myrpt->monchannel; 09485 cs[n++] = myrpt->txpchannel; 09486 if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel; 09487 if (myrpt->zaptxchannel != myrpt->txchannel) 09488 cs[n++] = myrpt->zaptxchannel; 09489 l = myrpt->links.next; 09490 while(l != &myrpt->links) 09491 { 09492 if ((!l->killme) && (!l->disctime) && l->chan) 09493 { 09494 cs[n++] = l->chan; 09495 cs[n++] = l->pchan; 09496 } 09497 l = l->next; 09498 } 09499 rpt_mutex_unlock(&myrpt->lock); 09500 ms = MSWAIT; 09501 for(x = 0; x < n; x++) 09502 { 09503 int s = -(-x - myrpt->scram - 1) % n; 09504 cs1[x] = cs[s]; 09505 } 09506 myrpt->scram++; 09507 who = ast_waitfor_n(cs1,n,&ms); 09508 if (who == NULL) ms = 0; 09509 elap = MSWAIT - ms; 09510 rpt_mutex_lock(&myrpt->lock); 09511 l = myrpt->links.next; 09512 while(l != &myrpt->links) 09513 { 09514 if (l->linklisttimer) 09515 { 09516 l->linklisttimer -= elap; 09517 if (l->linklisttimer < 0) l->linklisttimer = 0; 09518 } 09519 if ((!l->linklisttimer) && (l->name[0] != '0') && (!l->isremote)) 09520 { 09521 struct ast_frame lf; 09522 09523 memset(&lf,0,sizeof(lf)); 09524 lf.frametype = AST_FRAME_TEXT; 09525 lf.subclass = 0; 09526 lf.offset = 0; 09527 lf.mallocd = 0; 09528 lf.samples = 0; 09529 l->linklisttimer = LINKLISTTIME; 09530 strcpy(lstr,"L "); 09531 __mklinklist(myrpt,l,lstr + 2); 09532 if (l->chan) 09533 { 09534 lf.datalen = strlen(lstr) + 1; 09535 lf.data = lstr; 09536 ast_write(l->chan,&lf); 09537 if (debug > 6) ast_log(LOG_NOTICE, 09538 "@@@@ node %s sent node string %s to node %s\n", 09539 myrpt->name,lstr,l->name); 09540 } 09541 } 09542 #ifndef OLDKEY 09543 if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME) 09544 { 09545 l->retxtimer = 0; 09546 if (l->chan && l->phonemode == 0) 09547 { 09548 if (l->lasttx) 09549 ast_indicate(l->chan,AST_CONTROL_RADIO_KEY); 09550 else 09551 ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 09552 } 09553 } 09554 if ((l->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 5)) 09555 { 09556 if (debug == 7) printf("@@@@ rx un-key\n"); 09557 l->lastrx = 0; 09558 l->rerxtimer = 0; 09559 if(myrpt->p.duplex) 09560 rpt_telemetry(myrpt,LINKUNKEY,l); 09561 if (myrpt->p.archivedir) 09562 { 09563 char str[100]; 09564 09565 l->lastrx1 = 0; 09566 sprintf(str,"RXUNKEY(T),%s",l->name); 09567 donodelog(myrpt,str); 09568 } 09569 } 09570 #endif 09571 if (l->disctime) /* Disconnect timer active on a channel ? */ 09572 { 09573 l->disctime -= elap; 09574 if (l->disctime <= 0) /* Disconnect timer expired on inbound channel ? */ 09575 l->disctime = 0; /* Yep */ 09576 } 09577 09578 if (l->retrytimer) 09579 { 09580 l->retrytimer -= elap; 09581 if (l->retrytimer < 0) l->retrytimer = 0; 09582 } 09583 09584 /* Tally connect time */ 09585 l->connecttime += elap; 09586 09587 /* ignore non-timing channels */ 09588 if (l->elaptime < 0) 09589 { 09590 l = l->next; 09591 continue; 09592 } 09593 l->elaptime += elap; 09594 /* if connection has taken too long */ 09595 if ((l->elaptime > MAXCONNECTTIME) && 09596 ((!l->chan) || (l->chan->_state != AST_STATE_UP))) 09597 { 09598 l->elaptime = 0; 09599 rpt_mutex_unlock(&myrpt->lock); 09600 if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 09601 rpt_mutex_lock(&myrpt->lock); 09602 break; 09603 } 09604 if ((!l->chan) && (!l->retrytimer) && l->outbound && 09605 (l->retries++ < l->max_retries) && (l->hasconnected)) 09606 { 09607 if (l->chan) ast_hangup(l->chan); 09608 l->chan = 0; 09609 rpt_mutex_unlock(&myrpt->lock); 09610 if ((l->name[0] != '0') && (!l->isremote)) 09611 { 09612 if (attempt_reconnect(myrpt,l) == -1) 09613 { 09614 l->retrytimer = RETRY_TIMER_MS; 09615 } 09616 } 09617 else 09618 { 09619 l->retrytimer = l->max_retries + 1; 09620 } 09621 09622 rpt_mutex_lock(&myrpt->lock); 09623 break; 09624 } 09625 if ((!l->chan) && (!l->retrytimer) && l->outbound && 09626 (l->retries >= l->max_retries)) 09627 { 09628 /* remove from queue */ 09629 remque((struct qelem *) l); 09630 if (!strcmp(myrpt->cmdnode,l->name)) 09631 myrpt->cmdnode[0] = 0; 09632 rpt_mutex_unlock(&myrpt->lock); 09633 if (l->name[0] != '0') 09634 { 09635 if (!l->hasconnected) 09636 rpt_telemetry(myrpt,CONNFAIL,l); 09637 else rpt_telemetry(myrpt,REMDISC,l); 09638 } 09639 if (myrpt->p.archivedir) 09640 { 09641 char str[100]; 09642 09643 if (!l->hasconnected) 09644 sprintf(str,"LINKFAIL,%s",l->name); 09645 else 09646 sprintf(str,"LINKDISC,%s",l->name); 09647 donodelog(myrpt,str); 09648 } 09649 /* hang-up on call to device */ 09650 ast_hangup(l->pchan); 09651 free(l); 09652 rpt_mutex_lock(&myrpt->lock); 09653 break; 09654 } 09655 if ((!l->chan) && (!l->disctime) && (!l->outbound)) 09656 { 09657 /* remove from queue */ 09658 remque((struct qelem *) l); 09659 if (!strcmp(myrpt->cmdnode,l->name)) 09660 myrpt->cmdnode[0] = 0; 09661 rpt_mutex_unlock(&myrpt->lock); 09662 if (l->name[0] != '0') 09663 { 09664 rpt_telemetry(myrpt,REMDISC,l); 09665 } 09666 if (myrpt->p.archivedir) 09667 { 09668 char str[100]; 09669 09670 sprintf(str,"LINKDISC,%s",l->name); 09671 donodelog(myrpt,str); 09672 } 09673 /* hang-up on call to device */ 09674 ast_hangup(l->pchan); 09675 free(l); 09676 rpt_mutex_lock(&myrpt->lock); 09677 break; 09678 } 09679 l = l->next; 09680 } 09681 if(totx){ 09682 myrpt->dailytxtime += elap; 09683 myrpt->totaltxtime += elap; 09684 } 09685 i = myrpt->tailtimer; 09686 if (myrpt->tailtimer) myrpt->tailtimer -= elap; 09687 if (myrpt->tailtimer < 0) myrpt->tailtimer = 0; 09688 if((i) && (myrpt->tailtimer == 0)) 09689 myrpt->tailevent = 1; 09690 if ((!myrpt->p.s[myrpt->p.sysstate_cur].totdisable) && myrpt->totimer) myrpt->totimer -= elap; 09691 if (myrpt->totimer < 0) myrpt->totimer = 0; 09692 if (myrpt->idtimer) myrpt->idtimer -= elap; 09693 if (myrpt->idtimer < 0) myrpt->idtimer = 0; 09694 if (myrpt->tmsgtimer) myrpt->tmsgtimer -= elap; 09695 if (myrpt->tmsgtimer < 0) myrpt->tmsgtimer = 0; 09696 /* do macro timers */ 09697 if (myrpt->macrotimer) myrpt->macrotimer -= elap; 09698 if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; 09699 /* do local dtmf timer */ 09700 if (myrpt->dtmf_local_timer) 09701 { 09702 if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap; 09703 if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1; 09704 } 09705 do_dtmf_local(myrpt,0); 09706 /* Execute scheduler appx. every 2 tenths of a second */ 09707 if (myrpt->skedtimer <= 0){ 09708 myrpt->skedtimer = 200; 09709 do_scheduler(myrpt); 09710 } 09711 else 09712 myrpt->skedtimer -=elap; 09713 if (!ms) 09714 { 09715 rpt_mutex_unlock(&myrpt->lock); 09716 continue; 09717 } 09718 c = myrpt->macrobuf[0]; 09719 time(&t); 09720 if (c && (!myrpt->macrotimer) && 09721 starttime && (t > (starttime + START_DELAY))) 09722 { 09723 myrpt->macrotimer = MACROTIME; 09724 memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1); 09725 if ((c == 'p') || (c == 'P')) 09726 myrpt->macrotimer = MACROPTIME; 09727 rpt_mutex_unlock(&myrpt->lock); 09728 if (myrpt->p.archivedir) 09729 { 09730 char str[100]; 09731 09732 sprintf(str,"DTMF(M),MAIN,%c",c); 09733 donodelog(myrpt,str); 09734 } 09735 local_dtmf_helper(myrpt,c); 09736 } else rpt_mutex_unlock(&myrpt->lock); 09737 if (who == myrpt->rxchannel) /* if it was a read from rx */ 09738 { 09739 int ismuted; 09740 09741 f = ast_read(myrpt->rxchannel); 09742 if (!f) 09743 { 09744 if (debug) printf("@@@@ rpt:Hung Up\n"); 09745 break; 09746 } 09747 if (f->frametype == AST_FRAME_VOICE) 09748 { 09749 #ifdef _MDC_DECODE_H_ 09750 unsigned char ubuf[2560]; 09751 short *sp; 09752 int n; 09753 #endif 09754 09755 if ((!myrpt->localtx) && (!myrpt->p.linktolink)) { 09756 memset(f->data,0,f->datalen); 09757 } 09758 09759 #ifdef _MDC_DECODE_H_ 09760 sp = (short *) f->data; 09761 /* convert block to unsigned char */ 09762 for(n = 0; n < f->datalen / 2; n++) 09763 { 09764 ubuf[n] = (*sp++ >> 8) + 128; 09765 } 09766 n = mdc_decoder_process_samples(myrpt->mdc,ubuf,f->datalen / 2); 09767 if (n == 1) 09768 { 09769 unsigned char op,arg; 09770 unsigned short unitID; 09771 09772 mdc_decoder_get_packet(myrpt->mdc,&op,&arg,&unitID); 09773 if (debug > 2) 09774 { 09775 ast_log(LOG_NOTICE,"Got (single-length) packet:\n"); 09776 ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n", 09777 op & 255,arg & 255,unitID); 09778 } 09779 if ((op == 1) && (arg == 0)) 09780 { 09781 myrpt->lastunit = unitID; 09782 mdc1200_notify(myrpt,NULL,myrpt->lastunit); 09783 mdc1200_send(myrpt,myrpt->lastunit); 09784 } 09785 } 09786 if ((debug > 2) && (i == 2)) 09787 { 09788 unsigned char op,arg,ex1,ex2,ex3,ex4; 09789 unsigned short unitID; 09790 09791 mdc_decoder_get_double_packet(myrpt->mdc,&op,&arg,&unitID, 09792 &ex1,&ex2,&ex3,&ex4); 09793 ast_log(LOG_NOTICE,"Got (double-length) packet:\n"); 09794 ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n", 09795 op & 255,arg & 255,unitID); 09796 ast_log(LOG_NOTICE,"ex1: %02x, ex2: %02x, ex3: %02x, ex4: %02x\n", 09797 ex1 & 255, ex2 & 255, ex3 & 255, ex4 & 255); 09798 } 09799 #endif 09800 #ifdef __RPT_NOTCH 09801 /* apply inbound filters, if any */ 09802 rpt_filter(myrpt,f->data,f->datalen / 2); 09803 #endif 09804 if (ioctl(myrpt->zaprxchannel->fds[0], DAHDI_GETCONFMUTE, &ismuted) == -1) 09805 { 09806 ismuted = 0; 09807 } 09808 if (dtmfed) ismuted = 1; 09809 dtmfed = 0; 09810 if (ismuted) 09811 { 09812 memset(f->data,0,f->datalen); 09813 if (myrpt->lastf1) 09814 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09815 if (myrpt->lastf2) 09816 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09817 } 09818 if (f) f2 = ast_frdup(f); 09819 else f2 = NULL; 09820 f1 = myrpt->lastf2; 09821 myrpt->lastf2 = myrpt->lastf1; 09822 myrpt->lastf1 = f2; 09823 if (ismuted) 09824 { 09825 if (myrpt->lastf1) 09826 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09827 if (myrpt->lastf2) 09828 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09829 } 09830 if (f1) 09831 { 09832 ast_write(myrpt->pchannel,f1); 09833 ast_frfree(f1); 09834 } 09835 } 09836 #ifndef OLD_ASTERISK 09837 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 09838 { 09839 if (myrpt->lastf1) 09840 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09841 if (myrpt->lastf2) 09842 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09843 dtmfed = 1; 09844 } 09845 #endif 09846 else if (f->frametype == AST_FRAME_DTMF) 09847 { 09848 c = (char) f->subclass; /* get DTMF char */ 09849 ast_frfree(f); 09850 if (myrpt->lastf1) 09851 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 09852 if (myrpt->lastf2) 09853 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 09854 dtmfed = 1; 09855 if (!myrpt->keyed) continue; 09856 c = func_xlat(myrpt,c,&myrpt->p.inxlat); 09857 if (c) local_dtmf_helper(myrpt,c); 09858 continue; 09859 } 09860 else if (f->frametype == AST_FRAME_CONTROL) 09861 { 09862 if (f->subclass == AST_CONTROL_HANGUP) 09863 { 09864 if (debug) printf("@@@@ rpt:Hung Up\n"); 09865 ast_frfree(f); 09866 break; 09867 } 09868 /* if RX key */ 09869 if (f->subclass == AST_CONTROL_RADIO_KEY) 09870 { 09871 if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink)) 09872 { 09873 if (debug == 7) printf("@@@@ rx key\n"); 09874 myrpt->keyed = 1; 09875 } 09876 if (myrpt->p.archivedir) 09877 { 09878 donodelog(myrpt,"RXKEY,MAIN"); 09879 } 09880 } 09881 /* if RX un-key */ 09882 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 09883 { 09884 if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink)) 09885 { 09886 if (debug == 7) printf("@@@@ rx un-key\n"); 09887 if(myrpt->p.duplex && myrpt->keyed) { 09888 rpt_telemetry(myrpt,UNKEY,NULL); 09889 } 09890 } 09891 myrpt->keyed = 0; 09892 if (myrpt->p.archivedir) 09893 { 09894 donodelog(myrpt,"RXUNKEY,MAIN"); 09895 } 09896 } 09897 } 09898 ast_frfree(f); 09899 continue; 09900 } 09901 if (who == myrpt->pchannel) /* if it was a read from pseudo */ 09902 { 09903 f = ast_read(myrpt->pchannel); 09904 if (!f) 09905 { 09906 if (debug) printf("@@@@ rpt:Hung Up\n"); 09907 break; 09908 } 09909 if (f->frametype == AST_FRAME_VOICE) 09910 { 09911 ast_write(myrpt->txpchannel,f); 09912 } 09913 if (f->frametype == AST_FRAME_CONTROL) 09914 { 09915 if (f->subclass == AST_CONTROL_HANGUP) 09916 { 09917 if (debug) printf("@@@@ rpt:Hung Up\n"); 09918 ast_frfree(f); 09919 break; 09920 } 09921 } 09922 ast_frfree(f); 09923 continue; 09924 } 09925 if (who == myrpt->txchannel) /* if it was a read from tx */ 09926 { 09927 f = ast_read(myrpt->txchannel); 09928 if (!f) 09929 { 09930 if (debug) printf("@@@@ rpt:Hung Up\n"); 09931 break; 09932 } 09933 if (f->frametype == AST_FRAME_CONTROL) 09934 { 09935 if (f->subclass == AST_CONTROL_HANGUP) 09936 { 09937 if (debug) printf("@@@@ rpt:Hung Up\n"); 09938 ast_frfree(f); 09939 break; 09940 } 09941 } 09942 ast_frfree(f); 09943 continue; 09944 } 09945 if (who == myrpt->zaptxchannel) /* if it was a read from pseudo-tx */ 09946 { 09947 f = ast_read(myrpt->zaptxchannel); 09948 if (!f) 09949 { 09950 if (debug) printf("@@@@ rpt:Hung Up\n"); 09951 break; 09952 } 09953 if (f->frametype == AST_FRAME_VOICE) 09954 { 09955 ast_write(myrpt->txchannel,f); 09956 } 09957 if (f->frametype == AST_FRAME_CONTROL) 09958 { 09959 if (f->subclass == AST_CONTROL_HANGUP) 09960 { 09961 if (debug) printf("@@@@ rpt:Hung Up\n"); 09962 ast_frfree(f); 09963 break; 09964 } 09965 } 09966 ast_frfree(f); 09967 continue; 09968 } 09969 toexit = 0; 09970 rpt_mutex_lock(&myrpt->lock); 09971 l = myrpt->links.next; 09972 while(l != &myrpt->links) 09973 { 09974 if (l->disctime) 09975 { 09976 l = l->next; 09977 continue; 09978 } 09979 if (who == l->chan) /* if it was a read from rx */ 09980 { 09981 int remnomute; 09982 09983 remrx = 0; 09984 /* see if any other links are receiving */ 09985 m = myrpt->links.next; 09986 while(m != &myrpt->links) 09987 { 09988 /* if not us, count it */ 09989 if ((m != l) && (m->lastrx)) remrx = 1; 09990 m = m->next; 09991 } 09992 rpt_mutex_unlock(&myrpt->lock); 09993 remnomute = myrpt->localtx && 09994 (!(myrpt->cmdnode[0] || 09995 (myrpt->dtmfidx > -1))); 09996 totx = (((l->isremote) ? (remnomute) : 09997 myrpt->exttx) || remrx) && l->mode; 09998 if (l->phonemode == 0 && l->chan && (l->lasttx != totx)) 09999 { 10000 if (totx) 10001 { 10002 ast_indicate(l->chan,AST_CONTROL_RADIO_KEY); 10003 } 10004 else 10005 { 10006 ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 10007 } 10008 if (myrpt->p.archivedir) 10009 { 10010 char str[100]; 10011 10012 if (totx) 10013 sprintf(str,"TXKEY,%s",l->name); 10014 else 10015 sprintf(str,"TXUNKEY,%s",l->name); 10016 donodelog(myrpt,str); 10017 } 10018 } 10019 l->lasttx = totx; 10020 f = ast_read(l->chan); 10021 if (!f) 10022 { 10023 rpt_mutex_lock(&myrpt->lock); 10024 __kickshort(myrpt); 10025 rpt_mutex_unlock(&myrpt->lock); 10026 if ((!l->disced) && (!l->outbound)) 10027 { 10028 if ((l->name[0] == '0') || l->isremote) 10029 l->disctime = 1; 10030 else 10031 l->disctime = DISC_TIME; 10032 rpt_mutex_lock(&myrpt->lock); 10033 ast_hangup(l->chan); 10034 l->chan = 0; 10035 break; 10036 } 10037 10038 if (l->retrytimer) 10039 { 10040 ast_hangup(l->chan); 10041 l->chan = 0; 10042 rpt_mutex_lock(&myrpt->lock); 10043 break; 10044 } 10045 if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected)) 10046 { 10047 rpt_mutex_lock(&myrpt->lock); 10048 if (l->chan) ast_hangup(l->chan); 10049 l->chan = 0; 10050 l->hasconnected = 1; 10051 l->retrytimer = RETRY_TIMER_MS; 10052 l->elaptime = 0; 10053 l->connecttime = 0; 10054 l->thisconnected = 0; 10055 break; 10056 } 10057 rpt_mutex_lock(&myrpt->lock); 10058 /* remove from queue */ 10059 remque((struct qelem *) l); 10060 if (!strcmp(myrpt->cmdnode,l->name)) 10061 myrpt->cmdnode[0] = 0; 10062 __kickshort(myrpt); 10063 rpt_mutex_unlock(&myrpt->lock); 10064 if (!l->hasconnected) 10065 rpt_telemetry(myrpt,CONNFAIL,l); 10066 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 10067 if (myrpt->p.archivedir) 10068 { 10069 char str[100]; 10070 10071 if (!l->hasconnected) 10072 sprintf(str,"LINKFAIL,%s",l->name); 10073 else 10074 sprintf(str,"LINKDISC,%s",l->name); 10075 donodelog(myrpt,str); 10076 } 10077 if (l->lastf1) ast_frfree(l->lastf1); 10078 l->lastf1 = NULL; 10079 if (l->lastf2) ast_frfree(l->lastf2); 10080 l->lastf2 = NULL; 10081 /* hang-up on call to device */ 10082 ast_hangup(l->chan); 10083 ast_hangup(l->pchan); 10084 free(l); 10085 rpt_mutex_lock(&myrpt->lock); 10086 break; 10087 } 10088 if (f->frametype == AST_FRAME_VOICE) 10089 { 10090 int ismuted; 10091 10092 if (l->phonemode) 10093 { 10094 if (ioctl(l->chan->fds[0], DAHDI_GETCONFMUTE, &ismuted) == -1) 10095 { 10096 ismuted = 0; 10097 } 10098 /* if not receiving, zero-out audio */ 10099 ismuted |= (!l->lastrx); 10100 if (l->dtmfed && l->phonemode) ismuted = 1; 10101 l->dtmfed = 0; 10102 if (ismuted) 10103 { 10104 memset(f->data,0,f->datalen); 10105 if (l->lastf1) 10106 memset(l->lastf1->data,0,l->lastf1->datalen); 10107 if (l->lastf2) 10108 memset(l->lastf2->data,0,l->lastf2->datalen); 10109 } 10110 if (f) f2 = ast_frdup(f); 10111 else f2 = NULL; 10112 f1 = l->lastf2; 10113 l->lastf2 = l->lastf1; 10114 l->lastf1 = f2; 10115 if (ismuted) 10116 { 10117 if (l->lastf1) 10118 memset(l->lastf1->data,0,l->lastf1->datalen); 10119 if (l->lastf2) 10120 memset(l->lastf2->data,0,l->lastf2->datalen); 10121 } 10122 if (f1) 10123 { 10124 ast_write(l->pchan,f1); 10125 ast_frfree(f1); 10126 } 10127 } 10128 else 10129 { 10130 if (!l->lastrx) 10131 memset(f->data,0,f->datalen); 10132 ast_write(l->pchan,f); 10133 } 10134 } 10135 #ifndef OLD_ASTERISK 10136 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 10137 { 10138 if (l->lastf1) 10139 memset(l->lastf1->data,0,l->lastf1->datalen); 10140 if (l->lastf2) 10141 memset(l->lastf2->data,0,l->lastf2->datalen); 10142 l->dtmfed = 1; 10143 } 10144 #endif 10145 10146 if (f->frametype == AST_FRAME_TEXT) 10147 { 10148 handle_link_data(myrpt,l,f->data); 10149 } 10150 if (f->frametype == AST_FRAME_DTMF) 10151 { 10152 if (l->lastf1) 10153 memset(l->lastf1->data,0,l->lastf1->datalen); 10154 if (l->lastf2) 10155 memset(l->lastf2->data,0,l->lastf2->datalen); 10156 l->dtmfed = 1; 10157 handle_link_phone_dtmf(myrpt,l,f->subclass); 10158 } 10159 if (f->frametype == AST_FRAME_CONTROL) 10160 { 10161 if (f->subclass == AST_CONTROL_ANSWER) 10162 { 10163 char lconnected = l->connected; 10164 10165 __kickshort(myrpt); 10166 l->connected = 1; 10167 l->hasconnected = 1; 10168 l->thisconnected = 1; 10169 l->elaptime = -1; 10170 if (!l->isremote) l->retries = 0; 10171 if (!lconnected) 10172 { 10173 rpt_telemetry(myrpt,CONNECTED,l); 10174 if (myrpt->p.archivedir) 10175 { 10176 char str[100]; 10177 10178 if (l->mode) 10179 sprintf(str,"LINKTRX,%s",l->name); 10180 else 10181 sprintf(str,"LINKMONITOR,%s",l->name); 10182 donodelog(myrpt,str); 10183 } 10184 } 10185 else 10186 l->reconnects++; 10187 } 10188 /* if RX key */ 10189 if (f->subclass == AST_CONTROL_RADIO_KEY) 10190 { 10191 if (debug == 7 ) printf("@@@@ rx key\n"); 10192 l->lastrx = 1; 10193 l->rerxtimer = 0; 10194 if (myrpt->p.archivedir && (!l->lastrx1)) 10195 { 10196 char str[100]; 10197 10198 l->lastrx1 = 1; 10199 sprintf(str,"RXKEY,%s",l->name); 10200 donodelog(myrpt,str); 10201 } 10202 } 10203 /* if RX un-key */ 10204 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 10205 { 10206 if (debug == 7) printf("@@@@ rx un-key\n"); 10207 l->lastrx = 0; 10208 l->rerxtimer = 0; 10209 if(myrpt->p.duplex) 10210 rpt_telemetry(myrpt,LINKUNKEY,l); 10211 if (myrpt->p.archivedir && (l->lastrx1)) 10212 { 10213 char str[100]; 10214 10215 l->lastrx1 = 0; 10216 sprintf(str,"RXUNKEY,%s",l->name); 10217 donodelog(myrpt,str); 10218 } 10219 } 10220 if (f->subclass == AST_CONTROL_HANGUP) 10221 { 10222 ast_frfree(f); 10223 rpt_mutex_lock(&myrpt->lock); 10224 __kickshort(myrpt); 10225 rpt_mutex_unlock(&myrpt->lock); 10226 if ((!l->outbound) && (!l->disced)) 10227 { 10228 if ((l->name[0] == '0') || l->isremote) 10229 l->disctime = 1; 10230 else 10231 l->disctime = DISC_TIME; 10232 rpt_mutex_lock(&myrpt->lock); 10233 ast_hangup(l->chan); 10234 l->chan = 0; 10235 break; 10236 } 10237 if (l->retrytimer) 10238 { 10239 if (l->chan) ast_hangup(l->chan); 10240 l->chan = 0; 10241 rpt_mutex_lock(&myrpt->lock); 10242 break; 10243 } 10244 if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected)) 10245 { 10246 rpt_mutex_lock(&myrpt->lock); 10247 if (l->chan) ast_hangup(l->chan); 10248 l->chan = 0; 10249 l->hasconnected = 1; 10250 l->elaptime = 0; 10251 l->retrytimer = RETRY_TIMER_MS; 10252 l->connecttime = 0; 10253 l->thisconnected = 0; 10254 break; 10255 } 10256 rpt_mutex_lock(&myrpt->lock); 10257 /* remove from queue */ 10258 remque((struct qelem *) l); 10259 if (!strcmp(myrpt->cmdnode,l->name)) 10260 myrpt->cmdnode[0] = 0; 10261 __kickshort(myrpt); 10262 rpt_mutex_unlock(&myrpt->lock); 10263 if (!l->hasconnected) 10264 rpt_telemetry(myrpt,CONNFAIL,l); 10265 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 10266 if (myrpt->p.archivedir) 10267 { 10268 char str[100]; 10269 10270 if (!l->hasconnected) 10271 sprintf(str,"LINKFAIL,%s",l->name); 10272 else 10273 sprintf(str,"LINKDISC,%s",l->name); 10274 donodelog(myrpt,str); 10275 } 10276 if (l->lastf1) ast_frfree(l->lastf1); 10277 l->lastf1 = NULL; 10278 if (l->lastf2) ast_frfree(l->lastf2); 10279 l->lastf2 = NULL; 10280 /* hang-up on call to device */ 10281 ast_hangup(l->chan); 10282 ast_hangup(l->pchan); 10283 free(l); 10284 rpt_mutex_lock(&myrpt->lock); 10285 break; 10286 } 10287 } 10288 ast_frfree(f); 10289 rpt_mutex_lock(&myrpt->lock); 10290 break; 10291 } 10292 if (who == l->pchan) 10293 { 10294 rpt_mutex_unlock(&myrpt->lock); 10295 f = ast_read(l->pchan); 10296 if (!f) 10297 { 10298 if (debug) printf("@@@@ rpt:Hung Up\n"); 10299 toexit = 1; 10300 rpt_mutex_lock(&myrpt->lock); 10301 break; 10302 } 10303 if (f->frametype == AST_FRAME_VOICE) 10304 { 10305 if (l->chan) ast_write(l->chan,f); 10306 } 10307 if (f->frametype == AST_FRAME_CONTROL) 10308 { 10309 if (f->subclass == AST_CONTROL_HANGUP) 10310 { 10311 if (debug) printf("@@@@ rpt:Hung Up\n"); 10312 ast_frfree(f); 10313 toexit = 1; 10314 rpt_mutex_lock(&myrpt->lock); 10315 break; 10316 } 10317 } 10318 ast_frfree(f); 10319 rpt_mutex_lock(&myrpt->lock); 10320 break; 10321 } 10322 l = l->next; 10323 } 10324 rpt_mutex_unlock(&myrpt->lock); 10325 if (toexit) break; 10326 if (who == myrpt->monchannel) 10327 { 10328 f = ast_read(myrpt->monchannel); 10329 if (!f) 10330 { 10331 if (debug) printf("@@@@ rpt:Hung Up\n"); 10332 break; 10333 } 10334 if (f->frametype == AST_FRAME_VOICE) 10335 { 10336 if (myrpt->monstream) 10337 ast_writestream(myrpt->monstream,f); 10338 } 10339 if (f->frametype == AST_FRAME_CONTROL) 10340 { 10341 if (f->subclass == AST_CONTROL_HANGUP) 10342 { 10343 if (debug) printf("@@@@ rpt:Hung Up\n"); 10344 ast_frfree(f); 10345 break; 10346 } 10347 } 10348 ast_frfree(f); 10349 continue; 10350 } 10351 if (who == myrpt->txpchannel) /* if it was a read from remote tx */ 10352 { 10353 f = ast_read(myrpt->txpchannel); 10354 if (!f) 10355 { 10356 if (debug) printf("@@@@ rpt:Hung Up\n"); 10357 break; 10358 } 10359 if (f->frametype == AST_FRAME_CONTROL) 10360 { 10361 if (f->subclass == AST_CONTROL_HANGUP) 10362 { 10363 if (debug) printf("@@@@ rpt:Hung Up\n"); 10364 ast_frfree(f); 10365 break; 10366 } 10367 } 10368 ast_frfree(f); 10369 continue; 10370 } 10371 } 10372 usleep(100000); 10373 ast_hangup(myrpt->pchannel); 10374 ast_hangup(myrpt->monchannel); 10375 ast_hangup(myrpt->txpchannel); 10376 if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel); 10377 if (myrpt->zaptxchannel != myrpt->txchannel) ast_hangup(myrpt->zaptxchannel); 10378 if (myrpt->lastf1) ast_frfree(myrpt->lastf1); 10379 myrpt->lastf1 = NULL; 10380 if (myrpt->lastf2) ast_frfree(myrpt->lastf2); 10381 myrpt->lastf2 = NULL; 10382 ast_hangup(myrpt->rxchannel); 10383 rpt_mutex_lock(&myrpt->lock); 10384 l = myrpt->links.next; 10385 while(l != &myrpt->links) 10386 { 10387 struct rpt_link *ll = l; 10388 /* remove from queue */ 10389 remque((struct qelem *) l); 10390 /* hang-up on call to device */ 10391 if (l->chan) ast_hangup(l->chan); 10392 ast_hangup(l->pchan); 10393 l = l->next; 10394 free(ll); 10395 } 10396 rpt_mutex_unlock(&myrpt->lock); 10397 if (debug) printf("@@@@ rpt:Hung up channel\n"); 10398 myrpt->rpt_thread = AST_PTHREADT_STOP; 10399 pthread_exit(NULL); 10400 return NULL; 10401 }
static void* rpt_call | ( | void * | this | ) | [static] |
Definition at line 4163 of file app_rpt.c.
References rpt::acctcode, ast_callerid_parse(), AST_CDR_FLAG_POST_DISABLED, ast_cdr_setaccount(), ast_channel_undefer_dtmf(), ast_copy_string(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, ast_hangup(), ast_log(), ast_pbx_start(), ast_queue_frame(), ast_request(), ast_safe_sleep(), ast_senddigit(), ast_set_flag, ast_softhangup(), AST_SOFTHANGUP_DEV, rpt::callmode, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, rpt::cidx, rpt::conf, ast_channel::context, rpt::duplex, rpt::exten, ast_channel::exten, ast_channel::fds, free, rpt::lock, LOG_WARNING, MSWAIT, rpt::mydtmf, name, rpt::ourcallerid, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchquiet, ast_channel::pbx, rpt::pchannel, ast_channel::priority, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), strdup, ast_frame::subclass, TERM, and rpt::tonezone.
Referenced by function_autopatchup(), and local_dtmf_helper().
04164 { 04165 struct dahdi_confinfo ci; /* conference info */ 04166 struct rpt *myrpt = (struct rpt *)this; 04167 int res; 04168 int stopped,congstarted,dialtimer,lastcidx,aborted; 04169 struct ast_channel *mychannel,*genchannel; 04170 04171 04172 myrpt->mydtmf = 0; 04173 /* allocate a pseudo-channel thru asterisk */ 04174 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04175 if (!mychannel) 04176 { 04177 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 04178 pthread_exit(NULL); 04179 } 04180 #ifdef AST_CDR_FLAG_POST_DISABLED 04181 ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED); 04182 #endif 04183 ci.chan = 0; 04184 ci.confno = myrpt->conf; /* use the pseudo conference */ 04185 ci.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER 04186 | DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 04187 /* first put the channel on the conference */ 04188 if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1) 04189 { 04190 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04191 ast_hangup(mychannel); 04192 myrpt->callmode = 0; 04193 pthread_exit(NULL); 04194 } 04195 /* allocate a pseudo-channel thru asterisk */ 04196 genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 04197 if (!genchannel) 04198 { 04199 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 04200 ast_hangup(mychannel); 04201 pthread_exit(NULL); 04202 } 04203 #ifdef AST_CDR_FLAG_POST_DISABLED 04204 ast_set_flag(genchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 04205 #endif 04206 ci.chan = 0; 04207 ci.confno = myrpt->conf; 04208 ci.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER 04209 | DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 04210 /* first put the channel on the conference */ 04211 if (ioctl(genchannel->fds[0],DAHDI_SETCONF,&ci) == -1) 04212 { 04213 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04214 ast_hangup(mychannel); 04215 ast_hangup(genchannel); 04216 myrpt->callmode = 0; 04217 pthread_exit(NULL); 04218 } 04219 if (myrpt->p.tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->p.tonezone) == -1)) 04220 { 04221 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone); 04222 ast_hangup(mychannel); 04223 ast_hangup(genchannel); 04224 myrpt->callmode = 0; 04225 pthread_exit(NULL); 04226 } 04227 if (myrpt->p.tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->p.tonezone) == -1)) 04228 { 04229 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone); 04230 ast_hangup(mychannel); 04231 ast_hangup(genchannel); 04232 myrpt->callmode = 0; 04233 pthread_exit(NULL); 04234 } 04235 /* start dialtone if patchquiet is 0. Special patch modes don't send dial tone */ 04236 if ((!myrpt->patchquiet) && (tone_zone_play_tone(mychannel->fds[0],DAHDI_TONE_DIALTONE) < 0)) 04237 { 04238 ast_log(LOG_WARNING, "Cannot start dialtone\n"); 04239 ast_hangup(mychannel); 04240 ast_hangup(genchannel); 04241 myrpt->callmode = 0; 04242 pthread_exit(NULL); 04243 } 04244 stopped = 0; 04245 congstarted = 0; 04246 dialtimer = 0; 04247 lastcidx = 0; 04248 aborted = 0; 04249 04250 04251 while ((myrpt->callmode == 1) || (myrpt->callmode == 4)) 04252 { 04253 04254 if((myrpt->patchdialtime)&&(myrpt->callmode == 1)&&(myrpt->cidx != lastcidx)){ 04255 dialtimer = 0; 04256 lastcidx = myrpt->cidx; 04257 } 04258 04259 if((myrpt->patchdialtime)&&(dialtimer >= myrpt->patchdialtime)){ 04260 rpt_mutex_lock(&myrpt->lock); 04261 aborted = 1; 04262 myrpt->callmode = 0; 04263 rpt_mutex_unlock(&myrpt->lock); 04264 break; 04265 } 04266 04267 if ((!myrpt->patchquiet) && (!stopped) && (myrpt->callmode == 1) && (myrpt->cidx > 0)) 04268 { 04269 stopped = 1; 04270 /* stop dial tone */ 04271 tone_zone_play_tone(mychannel->fds[0],-1); 04272 } 04273 if (myrpt->callmode == 4) 04274 { 04275 if(!congstarted){ 04276 congstarted = 1; 04277 /* start congestion tone */ 04278 tone_zone_play_tone(mychannel->fds[0],DAHDI_TONE_CONGESTION); 04279 } 04280 } 04281 res = ast_safe_sleep(mychannel, MSWAIT); 04282 if (res < 0) 04283 { 04284 ast_hangup(mychannel); 04285 ast_hangup(genchannel); 04286 rpt_mutex_lock(&myrpt->lock); 04287 myrpt->callmode = 0; 04288 rpt_mutex_unlock(&myrpt->lock); 04289 pthread_exit(NULL); 04290 } 04291 dialtimer += MSWAIT; 04292 } 04293 /* stop any tone generation */ 04294 tone_zone_play_tone(mychannel->fds[0],-1); 04295 /* end if done */ 04296 if (!myrpt->callmode) 04297 { 04298 ast_hangup(mychannel); 04299 ast_hangup(genchannel); 04300 rpt_mutex_lock(&myrpt->lock); 04301 myrpt->callmode = 0; 04302 rpt_mutex_unlock(&myrpt->lock); 04303 if((!myrpt->patchquiet) && aborted) 04304 rpt_telemetry(myrpt, TERM, NULL); 04305 pthread_exit(NULL); 04306 } 04307 04308 if (myrpt->p.ourcallerid && *myrpt->p.ourcallerid){ 04309 char *name, *loc, *instr; 04310 instr = strdup(myrpt->p.ourcallerid); 04311 if(instr){ 04312 ast_callerid_parse(instr, &name, &loc); 04313 if(loc){ 04314 if(mychannel->cid.cid_num) 04315 free(mychannel->cid.cid_num); 04316 mychannel->cid.cid_num = strdup(loc); 04317 } 04318 if(name){ 04319 if(mychannel->cid.cid_name) 04320 free(mychannel->cid.cid_name); 04321 mychannel->cid.cid_name = strdup(name); 04322 } 04323 free(instr); 04324 } 04325 } 04326 04327 ast_copy_string(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1); 04328 ast_copy_string(mychannel->context, myrpt->patchcontext, sizeof(mychannel->context) - 1); 04329 04330 if (myrpt->p.acctcode) 04331 ast_cdr_setaccount(mychannel,myrpt->p.acctcode); 04332 mychannel->priority = 1; 04333 ast_channel_undefer_dtmf(mychannel); 04334 if (ast_pbx_start(mychannel) < 0) 04335 { 04336 ast_log(LOG_WARNING, "Unable to start PBX!!\n"); 04337 ast_hangup(mychannel); 04338 ast_hangup(genchannel); 04339 rpt_mutex_lock(&myrpt->lock); 04340 myrpt->callmode = 0; 04341 rpt_mutex_unlock(&myrpt->lock); 04342 pthread_exit(NULL); 04343 } 04344 usleep(10000); 04345 rpt_mutex_lock(&myrpt->lock); 04346 myrpt->callmode = 3; 04347 /* set appropriate conference for the pseudo */ 04348 ci.chan = 0; 04349 ci.confno = myrpt->conf; 04350 ci.confmode = (myrpt->p.duplex == 2) ? DAHDI_CONF_CONFANNMON : 04351 (DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER); 04352 /* first put the channel on the conference in announce mode */ 04353 if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1) 04354 { 04355 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04356 ast_hangup(mychannel); 04357 ast_hangup(genchannel); 04358 myrpt->callmode = 0; 04359 pthread_exit(NULL); 04360 } 04361 while(myrpt->callmode) 04362 { 04363 if ((!mychannel->pbx) && (myrpt->callmode != 4)) 04364 { 04365 if(myrpt->patchfarenddisconnect){ /* If patch is setup for far end disconnect */ 04366 myrpt->callmode = 0; 04367 if(!myrpt->patchquiet){ 04368 rpt_mutex_unlock(&myrpt->lock); 04369 rpt_telemetry(myrpt, TERM, NULL); 04370 rpt_mutex_lock(&myrpt->lock); 04371 } 04372 } 04373 else{ /* Send congestion until patch is downed by command */ 04374 myrpt->callmode = 4; 04375 rpt_mutex_unlock(&myrpt->lock); 04376 /* start congestion tone */ 04377 tone_zone_play_tone(genchannel->fds[0],DAHDI_TONE_CONGESTION); 04378 rpt_mutex_lock(&myrpt->lock); 04379 } 04380 } 04381 if (myrpt->mydtmf) 04382 { 04383 struct ast_frame wf = {AST_FRAME_DTMF, } ; 04384 wf.subclass = myrpt->mydtmf; 04385 rpt_mutex_unlock(&myrpt->lock); 04386 ast_queue_frame(mychannel,&wf); 04387 ast_senddigit(genchannel,myrpt->mydtmf); 04388 rpt_mutex_lock(&myrpt->lock); 04389 myrpt->mydtmf = 0; 04390 } 04391 rpt_mutex_unlock(&myrpt->lock); 04392 usleep(MSWAIT * 1000); 04393 rpt_mutex_lock(&myrpt->lock); 04394 } 04395 rpt_mutex_unlock(&myrpt->lock); 04396 tone_zone_play_tone(genchannel->fds[0],-1); 04397 if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV); 04398 ast_hangup(genchannel); 04399 rpt_mutex_lock(&myrpt->lock); 04400 myrpt->callmode = 0; 04401 rpt_mutex_unlock(&myrpt->lock); 04402 /* set appropriate conference for the pseudo */ 04403 ci.chan = 0; 04404 ci.confno = myrpt->conf; 04405 ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? DAHDI_CONF_CONFANNMON : 04406 (DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER); 04407 /* first put the channel on the conference in announce mode */ 04408 if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1) 04409 { 04410 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 04411 } 04412 pthread_exit(NULL); 04413 }
static int rpt_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1967 of file app_rpt.c.
References ast_cli(), myatoi(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01968 { 01969 int newlevel; 01970 01971 if (argc != 4) 01972 return RESULT_SHOWUSAGE; 01973 newlevel = myatoi(argv[3]); 01974 if((newlevel < 0) || (newlevel > 7)) 01975 return RESULT_SHOWUSAGE; 01976 if(newlevel) 01977 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel); 01978 else 01979 ast_cli(fd, "app_rpt Debugging disabled\n"); 01980 01981 debug = newlevel; 01982 return RESULT_SUCCESS; 01983 }
static int rpt_do_dump | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1989 of file app_rpt.c.
References ast_cli(), name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and rpt_vars.
01990 { 01991 int i; 01992 01993 if (argc != 3) 01994 return RESULT_SHOWUSAGE; 01995 01996 for(i = 0; i < nrpts; i++) 01997 { 01998 if (!strcmp(argv[2],rpt_vars[i].name)) 01999 { 02000 rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 02001 ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]); 02002 return RESULT_SUCCESS; 02003 } 02004 } 02005 return RESULT_FAILURE; 02006 }
static int rpt_do_fun | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2409 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.
02410 { 02411 int i,busy=0; 02412 02413 if (argc != 4) return RESULT_SHOWUSAGE; 02414 02415 for(i = 0; i < nrpts; i++){ 02416 if(!strcmp(argv[2], rpt_vars[i].name)){ 02417 struct rpt *myrpt = &rpt_vars[i]; 02418 rpt_mutex_lock(&myrpt->lock); 02419 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(argv[3])){ 02420 rpt_mutex_unlock(&myrpt->lock); 02421 busy=1; 02422 } 02423 if(!busy){ 02424 myrpt->macrotimer = MACROTIME; 02425 strncat(myrpt->macrobuf, argv[3], MAXMACRO - strlen(myrpt->macrobuf) - 1); 02426 } 02427 rpt_mutex_unlock(&myrpt->lock); 02428 } 02429 } 02430 if(busy){ 02431 ast_cli(fd, "Function decoder busy"); 02432 } 02433 return RESULT_FAILURE; 02434 }
static int rpt_do_lstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2237 of file app_rpt.c.
References ast_cli(), ast_log(), rpt_link::chan, rpt_link::chan_stat, rpt_lstat::connecttime, rpt_link::connecttime, free, rpt::links, rpt::lock, LOG_ERROR, malloc, MAXPEERSTR, MAXREMSTR, rpt_link::mode, rpt_link::name, name, rpt_link::next, rpt_lstat::next, NRPTSTAT, rpt_link::outbound, pbx_substitute_variables_helper(), rpt_lstat::prev, rpt_link::reconnects, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, s, t, and rpt_link::thisconnected.
02238 { 02239 int i,j; 02240 char *connstate; 02241 struct rpt *myrpt; 02242 struct rpt_link *l; 02243 struct rpt_lstat *s,*t; 02244 struct rpt_lstat s_head; 02245 if(argc != 3) 02246 return RESULT_SHOWUSAGE; 02247 02248 s = NULL; 02249 s_head.next = &s_head; 02250 s_head.prev = &s_head; 02251 02252 for(i = 0; i < nrpts; i++) 02253 { 02254 if (!strcmp(argv[2],rpt_vars[i].name)){ 02255 /* Make a copy of all stat variables while locked */ 02256 myrpt = &rpt_vars[i]; 02257 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02258 /* Traverse the list of connected nodes */ 02259 j = 0; 02260 l = myrpt->links.next; 02261 while(l && (l != &myrpt->links)){ 02262 if (l->name[0] == '0'){ /* Skip '0' nodes */ 02263 l = l->next; 02264 continue; 02265 } 02266 if((s = (struct rpt_lstat *) malloc(sizeof(struct rpt_lstat))) == NULL){ 02267 ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n"); 02268 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02269 return RESULT_FAILURE; 02270 } 02271 memset(s, 0, sizeof(struct rpt_lstat)); 02272 strncpy(s->name, l->name, MAXREMSTR - 1); 02273 if (l->chan) pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1); 02274 else strcpy(s->peer,"(none)"); 02275 s->mode = l->mode; 02276 s->outbound = l->outbound; 02277 s->reconnects = l->reconnects; 02278 s->connecttime = l->connecttime; 02279 s->thisconnected = l->thisconnected; 02280 memcpy(s->chan_stat,l->chan_stat,NRPTSTAT * sizeof(struct rpt_chan_stat)); 02281 insque((struct qelem *) s, (struct qelem *) s_head.next); 02282 memset(l->chan_stat,0,NRPTSTAT * sizeof(struct rpt_chan_stat)); 02283 l = l->next; 02284 } 02285 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02286 ast_cli(fd, "NODE PEER RECONNECTS DIRECTION CONNECT TIME CONNECT STATE\n"); 02287 ast_cli(fd, "---- ---- ---------- --------- ------------ -------------\n"); 02288 02289 for(s = s_head.next; s != &s_head; s = s->next){ 02290 int hours, minutes, seconds; 02291 long long connecttime = s->connecttime; 02292 char conntime[21]; 02293 hours = (int) connecttime/3600000; 02294 connecttime %= 3600000; 02295 minutes = (int) connecttime/60000; 02296 connecttime %= 60000; 02297 seconds = (int) connecttime/1000; 02298 connecttime %= 1000; 02299 snprintf(conntime, 20, "%02d:%02d:%02d.%d", 02300 hours, minutes, seconds, (int) connecttime); 02301 conntime[20] = 0; 02302 if(s->thisconnected) 02303 connstate = "ESTABLISHED"; 02304 else 02305 connstate = "CONNECTING"; 02306 ast_cli(fd, "%-10s%-20s%-12d%-11s%-20s%-20s\n", 02307 s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime, connstate); 02308 } 02309 /* destroy our local link queue */ 02310 s = s_head.next; 02311 while(s != &s_head){ 02312 t = s; 02313 s = s->next; 02314 remque((struct qelem *)t); 02315 free(t); 02316 } 02317 return RESULT_SUCCESS; 02318 } 02319 } 02320 return RESULT_FAILURE; 02321 }
static int rpt_do_nodes | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2327 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.
02328 { 02329 int i,j; 02330 char ns; 02331 char lbuf[MAXLINKLIST],*strs[MAXLINKLIST]; 02332 struct rpt *myrpt; 02333 if(argc != 3) 02334 return RESULT_SHOWUSAGE; 02335 02336 for(i = 0; i < nrpts; i++) 02337 { 02338 if (!strcmp(argv[2],rpt_vars[i].name)){ 02339 /* Make a copy of all stat variables while locked */ 02340 myrpt = &rpt_vars[i]; 02341 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02342 __mklinklist(myrpt,NULL,lbuf); 02343 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02344 /* parse em */ 02345 ns = finddelim(lbuf,strs,MAXLINKLIST); 02346 /* sort em */ 02347 if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar); 02348 ast_cli(fd,"\n"); 02349 ast_cli(fd, "************************* CONNECTED NODES *************************\n\n"); 02350 for(j = 0 ;; j++){ 02351 if(!strs[j]){ 02352 if(!j){ 02353 ast_cli(fd,"<NONE>"); 02354 } 02355 break; 02356 } 02357 ast_cli(fd, "%s", strs[j]); 02358 if(j % 8 == 7){ 02359 ast_cli(fd, "\n"); 02360 } 02361 else{ 02362 if(strs[j + 1]) 02363 ast_cli(fd, ", "); 02364 } 02365 } 02366 ast_cli(fd,"\n\n"); 02367 return RESULT_SUCCESS; 02368 } 02369 } 02370 return RESULT_FAILURE; 02371 }
static int rpt_do_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2377 of file app_rpt.c.
References reload(), RESULT_FAILURE, RESULT_SHOWUSAGE, and rpt_vars.
02378 { 02379 int n; 02380 02381 if (argc > 2) return RESULT_SHOWUSAGE; 02382 02383 for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1; 02384 02385 return RESULT_FAILURE; 02386 }
static int rpt_do_restart | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2392 of file app_rpt.c.
References ast_softhangup(), AST_SOFTHANGUP_DEV, RESULT_FAILURE, RESULT_SHOWUSAGE, rpt_vars, and rpt::rxchannel.
02393 { 02394 int i; 02395 02396 if (argc > 2) return RESULT_SHOWUSAGE; 02397 for(i = 0; i < nrpts; i++) 02398 { 02399 if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV); 02400 } 02401 return RESULT_FAILURE; 02402 }
static int rpt_do_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2012 of file app_rpt.c.
References ast_cli(), ast_strdupa, rpt::callmode, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, rpt::exten, rpt::keyed, rpt::lastdtmfcommand, rpt::lastnodewhichkeyedusup, rpt::links, rpt::lock, MAX_STAT_LINKS, rpt::mustid, rpt::name, rpt_link::name, name, rpt_link::next, rpt::p, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, rpt::s, rpt::sysstate_cur, rpt::tailid, rpt::timeouts, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, rpt::totime, and rpt::totimer.
02013 { 02014 int i,j; 02015 int dailytxtime, dailykerchunks; 02016 int totalkerchunks, dailykeyups, totalkeyups, timeouts; 02017 int totalexecdcommands, dailyexecdcommands, hours, minutes, seconds; 02018 long long totaltxtime; 02019 struct rpt_link *l; 02020 char *listoflinks[MAX_STAT_LINKS]; 02021 char *lastnodewhichkeyedusup, *lastdtmfcommand; 02022 char *tot_state, *ider_state, *patch_state; 02023 char *reverse_patch_state, *sys_ena, *tot_ena, *link_ena, *patch_ena; 02024 char *sch_ena, *input_signal, *called_number, *user_funs, *tail_type; 02025 struct rpt *myrpt; 02026 02027 static char *not_applicable = "N/A"; 02028 02029 if(argc != 3) 02030 return RESULT_SHOWUSAGE; 02031 02032 for(i = 0 ; i < MAX_STAT_LINKS; i++) 02033 listoflinks[i] = NULL; 02034 02035 tot_state = ider_state = 02036 patch_state = reverse_patch_state = 02037 input_signal = called_number = 02038 lastdtmfcommand = not_applicable; 02039 02040 for(i = 0; i < nrpts; i++) 02041 { 02042 if (!strcmp(argv[2],rpt_vars[i].name)){ 02043 /* Make a copy of all stat variables while locked */ 02044 myrpt = &rpt_vars[i]; 02045 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 02046 02047 dailytxtime = myrpt->dailytxtime; 02048 totaltxtime = myrpt->totaltxtime; 02049 dailykeyups = myrpt->dailykeyups; 02050 totalkeyups = myrpt->totalkeyups; 02051 dailykerchunks = myrpt->dailykerchunks; 02052 totalkerchunks = myrpt->totalkerchunks; 02053 dailyexecdcommands = myrpt->dailyexecdcommands; 02054 totalexecdcommands = myrpt->totalexecdcommands; 02055 timeouts = myrpt->timeouts; 02056 02057 /* Traverse the list of connected nodes */ 02058 reverse_patch_state = "DOWN"; 02059 j = 0; 02060 l = myrpt->links.next; 02061 while(l && (l != &myrpt->links)){ 02062 if (l->name[0] == '0'){ /* Skip '0' nodes */ 02063 reverse_patch_state = "UP"; 02064 l = l->next; 02065 continue; 02066 } 02067 listoflinks[j] = ast_strdupa(l->name); 02068 if(listoflinks[j]) 02069 j++; 02070 l = l->next; 02071 } 02072 02073 lastnodewhichkeyedusup = ast_strdupa(myrpt->lastnodewhichkeyedusup); 02074 if((!lastnodewhichkeyedusup) || (!strlen(lastnodewhichkeyedusup))) 02075 lastnodewhichkeyedusup = not_applicable; 02076 02077 if(myrpt->keyed) 02078 input_signal = "YES"; 02079 else 02080 input_signal = "NO"; 02081 02082 if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable) 02083 sys_ena = "DISABLED"; 02084 else 02085 sys_ena = "ENABLED"; 02086 02087 if(myrpt->p.s[myrpt->p.sysstate_cur].totdisable) 02088 tot_ena = "DISABLED"; 02089 else 02090 tot_ena = "ENABLED"; 02091 02092 if(myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable) 02093 link_ena = "DISABLED"; 02094 else 02095 link_ena = "ENABLED"; 02096 02097 if(myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable) 02098 patch_ena = "DISABLED"; 02099 else 02100 patch_ena = "ENABLED"; 02101 02102 if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable) 02103 sch_ena = "DISABLED"; 02104 else 02105 sch_ena = "ENABLED"; 02106 02107 if(myrpt->p.s[myrpt->p.sysstate_cur].userfundisable) 02108 user_funs = "DISABLED"; 02109 else 02110 user_funs = "ENABLED"; 02111 02112 if(myrpt->p.s[myrpt->p.sysstate_cur].alternatetail) 02113 tail_type = "ALTERNATE"; 02114 else 02115 tail_type = "STANDARD"; 02116 02117 if(!myrpt->totimer) 02118 tot_state = "TIMED OUT!"; 02119 else if(myrpt->totimer != myrpt->p.totime) 02120 tot_state = "ARMED"; 02121 else 02122 tot_state = "RESET"; 02123 02124 if(myrpt->tailid) 02125 ider_state = "QUEUED IN TAIL"; 02126 else if(myrpt->mustid) 02127 ider_state = "QUEUED FOR CLEANUP"; 02128 else 02129 ider_state = "CLEAN"; 02130 02131 switch(myrpt->callmode){ 02132 case 1: 02133 patch_state = "DIALING"; 02134 break; 02135 case 2: 02136 patch_state = "CONNECTING"; 02137 break; 02138 case 3: 02139 patch_state = "UP"; 02140 break; 02141 02142 case 4: 02143 patch_state = "CALL FAILED"; 02144 break; 02145 02146 default: 02147 patch_state = "DOWN"; 02148 } 02149 02150 if(strlen(myrpt->exten)){ 02151 called_number = ast_strdupa(myrpt->exten); 02152 if(!called_number) 02153 called_number = not_applicable; 02154 } 02155 02156 if(strlen(myrpt->lastdtmfcommand)){ 02157 lastdtmfcommand = ast_strdupa(myrpt->lastdtmfcommand); 02158 if(!lastdtmfcommand) 02159 lastdtmfcommand = not_applicable; 02160 } 02161 02162 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 02163 02164 ast_cli(fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name); 02165 ast_cli(fd, "Selected system state............................: %d\n", myrpt->p.sysstate_cur); 02166 ast_cli(fd, "Signal on input..................................: %s\n", input_signal); 02167 ast_cli(fd, "System...........................................: %s\n", sys_ena); 02168 ast_cli(fd, "Scheduler........................................: %s\n", sch_ena); 02169 ast_cli(fd, "Tail Time........................................: %s\n", tail_type); 02170 ast_cli(fd, "Time out timer...................................: %s\n", tot_ena); 02171 ast_cli(fd, "Time out timer state.............................: %s\n", tot_state); 02172 ast_cli(fd, "Time outs since system initialization............: %d\n", timeouts); 02173 ast_cli(fd, "Identifier state.................................: %s\n", ider_state); 02174 ast_cli(fd, "Kerchunks today..................................: %d\n", dailykerchunks); 02175 ast_cli(fd, "Kerchunks since system initialization............: %d\n", totalkerchunks); 02176 ast_cli(fd, "Keyups today.....................................: %d\n", dailykeyups); 02177 ast_cli(fd, "Keyups since system initialization...............: %d\n", totalkeyups); 02178 ast_cli(fd, "DTMF commands today..............................: %d\n", dailyexecdcommands); 02179 ast_cli(fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands); 02180 ast_cli(fd, "Last DTMF command executed.......................: %s\n", lastdtmfcommand); 02181 hours = dailytxtime/3600000; 02182 dailytxtime %= 3600000; 02183 minutes = dailytxtime/60000; 02184 dailytxtime %= 60000; 02185 seconds = dailytxtime/1000; 02186 dailytxtime %= 1000; 02187 02188 ast_cli(fd, "TX time today ...................................: %02d:%02d:%02d.%d\n", 02189 hours, minutes, seconds, dailytxtime); 02190 02191 hours = (int) totaltxtime/3600000; 02192 totaltxtime %= 3600000; 02193 minutes = (int) totaltxtime/60000; 02194 totaltxtime %= 60000; 02195 seconds = (int) totaltxtime/1000; 02196 totaltxtime %= 1000; 02197 02198 ast_cli(fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n", 02199 hours, minutes, seconds, (int) totaltxtime); 02200 ast_cli(fd, "Nodes currently connected to us..................: "); 02201 for(j = 0 ;; j++){ 02202 if(!listoflinks[j]){ 02203 if(!j){ 02204 ast_cli(fd,"<NONE>"); 02205 } 02206 break; 02207 } 02208 ast_cli(fd, "%s", listoflinks[j]); 02209 if(j % 4 == 3){ 02210 ast_cli(fd, "\n"); 02211 ast_cli(fd, " : "); 02212 } 02213 else{ 02214 if(listoflinks[j + 1]) 02215 ast_cli(fd, ", "); 02216 } 02217 } 02218 ast_cli(fd,"\n"); 02219 02220 ast_cli(fd, "Last node which transmitted to us................: %s\n", lastnodewhichkeyedusup); 02221 ast_cli(fd, "Autopatch........................................: %s\n", patch_ena); 02222 ast_cli(fd, "Autopatch state..................................: %s\n", patch_state); 02223 ast_cli(fd, "Autopatch called number..........................: %s\n", called_number); 02224 ast_cli(fd, "Reverse patch/IAXRPT connected...................: %s\n", reverse_patch_state); 02225 ast_cli(fd, "User linking commands............................: %s\n", link_ena); 02226 ast_cli(fd, "User functions...................................: %s\n\n", user_funs); 02227 return RESULT_SUCCESS; 02228 } 02229 } 02230 return RESULT_FAILURE; 02231 }
static int rpt_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 10571 of file app_rpt.c.
References ast_log(), ast_safe_sleep(), ast_strlen_zero(), rpt_tele::chan, f, LOG_NOTICE, LOG_WARNING, rpt::name, name, rpt::p, rpt_vars, rpt::s, START_DELAY, rpt::sysstate_cur, and t.
Referenced by load_module().
10572 { 10573 int res=-1,i,rem_totx,rem_rx,remkeyed,n,phone_mode = 0; 10574 int iskenwood_pci4,authtold,authreq,setting,notremming,reming; 10575 int ismuted,dtmfed; 10576 #ifdef OLD_ASTERISK 10577 struct localuser *u; 10578 #endif 10579 char tmp[256], keyed = 0,keyed1 = 0; 10580 char *options,*stringp,*tele,c; 10581 struct rpt *myrpt; 10582 struct ast_frame *f,*f1,*f2; 10583 struct ast_channel *who; 10584 struct ast_channel *cs[20]; 10585 struct rpt_link *l; 10586 struct dahdi_confinfo ci; /* conference info */ 10587 struct dahdi_params par; 10588 int ms,elap,nullfd; 10589 time_t t,last_timeout_warning; 10590 struct dahdi_radio_param z; 10591 struct rpt_tele *telem; 10592 10593 nullfd = open("/dev/null",O_RDWR); 10594 if (ast_strlen_zero(data)) { 10595 ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n"); 10596 return -1; 10597 } 10598 10599 strncpy(tmp, (char *)data, sizeof(tmp)-1); 10600 time(&t); 10601 /* if time has externally shifted negative, screw it */ 10602 if (t < starttime) t = starttime + START_DELAY; 10603 if ((!starttime) || (t < (starttime + START_DELAY))) 10604 { 10605 ast_log(LOG_NOTICE,"Node %s rejecting call: too soon!\n",tmp); 10606 ast_safe_sleep(chan,3000); 10607 return -1; 10608 } 10609 stringp=tmp; 10610 strsep(&stringp, "|"); 10611 options = stringp; 10612 myrpt = NULL; 10613 /* see if we can find our specified one */ 10614 for(i = 0; i < nrpts; i++) 10615 { 10616 /* if name matches, assign it and exit loop */ 10617 if (!strcmp(tmp,rpt_vars[i].name)) 10618 { 10619 myrpt = &rpt_vars[i]; 10620 break; 10621 } 10622 } 10623 if (myrpt == NULL) 10624 { 10625 ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp); 10626 return -1; 10627 } 10628 10629 if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable){ /* Do not allow incoming connections if disabled */ 10630 ast_log(LOG_NOTICE, "Connect attempt to node %s with tx disabled", myrpt->name); 10631 return -1; 10632 } 10633 10634 /* if not phone access, must be an IAX connection */ 10635 if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R'))) 10636 { 10637 int val; 10638 10639 phone_mode = 1; 10640 if (*options == 'D') phone_mode = 2; 10641 ast_set_callerid(chan,"0","app_rpt user","0"); 10642 val = 1; 10643 ast_channel_setoption(chan,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0); 10644 } 10645 else 10646 { 10647 #ifdef ALLOW_LOCAL_CHANNELS 10648 /* Check to insure the connection is IAX2 or Local*/ 10649 if ( (strncmp(chan->name,"IAX2",4)) && (strncmp(chan->name,"Local",5)) ) { 10650 ast_log(LOG_WARNING, "We only accept links via IAX2 or Local!!\n"); 10651 return -1; 10652 } 10653 #else 10654 if (strncmp(chan->name,"IAX2",4)) 10655 { 10656 ast_log(LOG_WARNING, "We only accept links via IAX2!!\n"); 10657 return -1; 10658 } 10659 #endif 10660 } 10661 if (options && (*options == 'R')) 10662 { 10663 10664 /* Parts of this section taken from app_parkandannounce */ 10665 char *return_context; 10666 int l, m, lot, timeout = 0; 10667 char tmp[256],*template; 10668 char *working, *context, *exten, *priority; 10669 char *s,*orig_s; 10670 10671 10672 rpt_mutex_lock(&myrpt->lock); 10673 m = myrpt->callmode; 10674 rpt_mutex_unlock(&myrpt->lock); 10675 10676 if ((!myrpt->p.nobusyout) && m) 10677 { 10678 if (chan->_state != AST_STATE_UP) 10679 { 10680 ast_indicate(chan,AST_CONTROL_BUSY); 10681 } 10682 while(ast_safe_sleep(chan,10000) != -1); 10683 return -1; 10684 } 10685 10686 if (chan->_state != AST_STATE_UP) 10687 { 10688 ast_answer(chan); 10689 } 10690 10691 l=strlen(options)+2; 10692 orig_s=malloc(l); 10693 if(!orig_s) { 10694 ast_log(LOG_WARNING, "Out of memory\n"); 10695 return -1; 10696 } 10697 s=orig_s; 10698 strncpy(s,options,l); 10699 10700 template=strsep(&s,"|"); 10701 if(!template) { 10702 ast_log(LOG_WARNING, "An announce template must be defined\n"); 10703 free(orig_s); 10704 return -1; 10705 } 10706 10707 if(s) { 10708 timeout = atoi(strsep(&s, "|")); 10709 timeout *= 1000; 10710 } 10711 10712 return_context = s; 10713 10714 if(return_context != NULL) { 10715 /* set the return context. Code borrowed from the Goto builtin */ 10716 10717 working = return_context; 10718 context = strsep(&working, "|"); 10719 exten = strsep(&working, "|"); 10720 if(!exten) { 10721 /* Only a priority in this one */ 10722 priority = context; 10723 exten = NULL; 10724 context = NULL; 10725 } else { 10726 priority = strsep(&working, "|"); 10727 if(!priority) { 10728 /* Only an extension and priority in this one */ 10729 priority = exten; 10730 exten = context; 10731 context = NULL; 10732 } 10733 } 10734 if(atoi(priority) < 0) { 10735 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority); 10736 free(orig_s); 10737 return -1; 10738 } 10739 /* At this point we have a priority and maybe an extension and a context */ 10740 chan->priority = atoi(priority); 10741 #ifdef OLD_ASTERISK 10742 if(exten && strcasecmp(exten, "BYEXTENSION")) 10743 #else 10744 if(exten) 10745 #endif 10746 strncpy(chan->exten, exten, sizeof(chan->exten)-1); 10747 if(context) 10748 strncpy(chan->context, context, sizeof(chan->context)-1); 10749 } else { /* increment the priority by default*/ 10750 chan->priority++; 10751 } 10752 10753 if(option_verbose > 2) { 10754 ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num); 10755 if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 10756 ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n"); 10757 } 10758 } 10759 10760 /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout 10761 before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */ 10762 10763 ast_masq_park_call(chan, NULL, timeout, &lot); 10764 10765 if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context); 10766 10767 snprintf(tmp,sizeof(tmp) - 1,"%d,%s",lot,template + 1); 10768 10769 rpt_telemetry(myrpt,REV_PATCH,tmp); 10770 10771 free(orig_s); 10772 10773 return 0; 10774 10775 } 10776 10777 if (!options) 10778 { 10779 struct ast_hostent ahp; 10780 struct hostent *hp; 10781 struct in_addr ia; 10782 char hisip[100],nodeip[100],*val, *s, *s1, *s2, *b,*b1; 10783 10784 /* look at callerid to see what node this comes from */ 10785 if (!chan->cid.cid_num) /* if doesn't have caller id */ 10786 { 10787 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 10788 return -1; 10789 } 10790 10791 /* get his IP from IAX2 module */ 10792 memset(hisip,0,sizeof(hisip)); 10793 #ifdef ALLOW_LOCAL_CHANNELS 10794 /* set IP address if this is a local connection*/ 10795 if (strncmp(chan->name,"Local",5)==0) { 10796 strcpy(hisip,"127.0.0.1"); 10797 } else { 10798 pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1); 10799 } 10800 #else 10801 pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1); 10802 #endif 10803 10804 if (!hisip[0]) 10805 { 10806 ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n"); 10807 return -1; 10808 } 10809 10810 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 10811 ast_shrink_phone_number(b1); 10812 if (!strcmp(myrpt->name,b1)) 10813 { 10814 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 10815 return -1; 10816 } 10817 10818 if (*b1 < '1') 10819 { 10820 ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1); 10821 return -1; 10822 } 10823 10824 10825 /* look for his reported node string */ 10826 val = node_lookup(myrpt,b1); 10827 if (!val) 10828 { 10829 ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1); 10830 return -1; 10831 } 10832 strncpy(tmp,val,sizeof(tmp) - 1); 10833 s = tmp; 10834 s1 = strsep(&s,","); 10835 s2 = strsep(&s,","); 10836 if (!s2) 10837 { 10838 ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1); 10839 return -1; 10840 } 10841 if (strcmp(s2,"NONE")) { 10842 hp = ast_gethostbyname(s2, &ahp); 10843 if (!hp) 10844 { 10845 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2); 10846 return -1; 10847 } 10848 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 10849 #ifdef OLD_ASTERISK 10850 ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia); 10851 #else 10852 strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1); 10853 #endif 10854 if (strcmp(hisip,nodeip)) 10855 { 10856 char *s3 = strchr(s1,'@'); 10857 if (s3) s1 = s3 + 1; 10858 s3 = strchr(s1,'/'); 10859 if (s3) *s3 = 0; 10860 hp = ast_gethostbyname(s1, &ahp); 10861 if (!hp) 10862 { 10863 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1); 10864 return -1; 10865 } 10866 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 10867 #ifdef OLD_ASTERISK 10868 ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia); 10869 #else 10870 strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1); 10871 #endif 10872 if (strcmp(hisip,nodeip)) 10873 { 10874 ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip); 10875 return -1; 10876 } 10877 } 10878 } 10879 } 10880 10881 /* if is not a remote */ 10882 if (!myrpt->remote) 10883 { 10884 10885 char *b,*b1; 10886 int reconnects = 0; 10887 10888 /* look at callerid to see what node this comes from */ 10889 if (!chan->cid.cid_num) /* if doesn't have caller id */ 10890 { 10891 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 10892 return -1; 10893 } 10894 10895 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 10896 ast_shrink_phone_number(b1); 10897 if (!strcmp(myrpt->name,b1)) 10898 { 10899 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 10900 return -1; 10901 } 10902 rpt_mutex_lock(&myrpt->lock); 10903 l = myrpt->links.next; 10904 /* try to find this one in queue */ 10905 while(l != &myrpt->links) 10906 { 10907 if (l->name[0] == '0') 10908 { 10909 l = l->next; 10910 continue; 10911 } 10912 /* if found matching string */ 10913 if (!strcmp(l->name,b1)) break; 10914 l = l->next; 10915 } 10916 /* if found */ 10917 if (l != &myrpt->links) 10918 { 10919 l->killme = 1; 10920 l->retries = l->max_retries + 1; 10921 l->disced = 2; 10922 reconnects = l->reconnects; 10923 reconnects++; 10924 rpt_mutex_unlock(&myrpt->lock); 10925 usleep(500000); 10926 } else 10927 rpt_mutex_unlock(&myrpt->lock); 10928 /* establish call in tranceive mode */ 10929 l = malloc(sizeof(struct rpt_link)); 10930 if (!l) 10931 { 10932 ast_log(LOG_WARNING, "Unable to malloc\n"); 10933 pthread_exit(NULL); 10934 } 10935 /* zero the silly thing */ 10936 memset((char *)l,0,sizeof(struct rpt_link)); 10937 l->mode = 1; 10938 strncpy(l->name,b1,MAXNODESTR - 1); 10939 l->isremote = 0; 10940 l->chan = chan; 10941 l->connected = 1; 10942 l->thisconnected = 1; 10943 l->hasconnected = 1; 10944 l->reconnects = reconnects; 10945 l->phonemode = phone_mode; 10946 l->lastf1 = NULL; 10947 l->lastf2 = NULL; 10948 l->dtmfed = 0; 10949 ast_set_read_format(l->chan,AST_FORMAT_SLINEAR); 10950 ast_set_write_format(l->chan,AST_FORMAT_SLINEAR); 10951 /* allocate a pseudo-channel thru asterisk */ 10952 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 10953 if (!l->pchan) 10954 { 10955 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 10956 pthread_exit(NULL); 10957 } 10958 ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR); 10959 ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR); 10960 #ifdef AST_CDR_FLAG_POST_DISABLED 10961 ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED); 10962 #endif 10963 /* make a conference for the tx */ 10964 ci.chan = 0; 10965 ci.confno = myrpt->conf; 10966 ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER; 10967 /* first put the channel on the conference in proper mode */ 10968 if (ioctl(l->pchan->fds[0],DAHDI_SETCONF,&ci) == -1) 10969 { 10970 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 10971 pthread_exit(NULL); 10972 } 10973 rpt_mutex_lock(&myrpt->lock); 10974 if (phone_mode > 1) l->lastrx = 1; 10975 l->max_retries = MAX_RETRIES; 10976 /* insert at end of queue */ 10977 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 10978 __kickshort(myrpt); 10979 rpt_mutex_unlock(&myrpt->lock); 10980 if (chan->_state != AST_STATE_UP) { 10981 ast_answer(chan); 10982 } 10983 if (myrpt->p.archivedir) 10984 { 10985 char str[100]; 10986 10987 if (l->phonemode) 10988 sprintf(str,"LINK(P),%s",l->name); 10989 else 10990 sprintf(str,"LINK,%s",l->name); 10991 donodelog(myrpt,str); 10992 } 10993 return AST_PBX_KEEPALIVE; 10994 } 10995 /* well, then it is a remote */ 10996 rpt_mutex_lock(&myrpt->lock); 10997 /* if remote, error if anyone else already linked */ 10998 if (myrpt->remoteon) 10999 { 11000 rpt_mutex_unlock(&myrpt->lock); 11001 usleep(500000); 11002 if (myrpt->remoteon) 11003 { 11004 ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp); 11005 return -1; 11006 } 11007 rpt_mutex_lock(&myrpt->lock); 11008 } 11009 #ifdef HAVE_IOPERM 11010 if ((!strcmp(myrpt->remote, remote_rig_rbi)) && 11011 (ioperm(myrpt->p.iobase,1,1) == -1)) 11012 { 11013 rpt_mutex_unlock(&myrpt->lock); 11014 ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase); 11015 return -1; 11016 } 11017 #endif 11018 myrpt->remoteon = 1; 11019 #ifdef OLD_ASTERISK 11020 LOCAL_USER_ADD(u); 11021 #endif 11022 rpt_mutex_unlock(&myrpt->lock); 11023 /* find our index, and load the vars initially */ 11024 for(i = 0; i < nrpts; i++) 11025 { 11026 if (&rpt_vars[i] == myrpt) 11027 { 11028 load_rpt_vars(i,0); 11029 break; 11030 } 11031 } 11032 rpt_mutex_lock(&myrpt->lock); 11033 tele = strchr(myrpt->rxchanname,'/'); 11034 if (!tele) 11035 { 11036 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 11037 rpt_mutex_unlock(&myrpt->lock); 11038 pthread_exit(NULL); 11039 } 11040 *tele++ = 0; 11041 myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL); 11042 myrpt->zaprxchannel = NULL; 11043 if (!strcasecmp(myrpt->rxchanname,"Zap")) 11044 myrpt->zaprxchannel = myrpt->rxchannel; 11045 if (myrpt->rxchannel) 11046 { 11047 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 11048 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 11049 #ifdef AST_CDR_FLAG_POST_DISABLED 11050 ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11051 #endif 11052 myrpt->rxchannel->whentohangup = 0; 11053 myrpt->rxchannel->appl = "Apprpt"; 11054 myrpt->rxchannel->data = "(Link Rx)"; 11055 if (option_verbose > 2) 11056 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 11057 myrpt->rxchanname,tele,myrpt->rxchannel->name); 11058 rpt_mutex_unlock(&myrpt->lock); 11059 ast_call(myrpt->rxchannel,tele,999); 11060 rpt_mutex_lock(&myrpt->lock); 11061 } 11062 else 11063 { 11064 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 11065 rpt_mutex_unlock(&myrpt->lock); 11066 pthread_exit(NULL); 11067 } 11068 *--tele = '/'; 11069 myrpt->zaptxchannel = NULL; 11070 if (myrpt->txchanname) 11071 { 11072 tele = strchr(myrpt->txchanname,'/'); 11073 if (!tele) 11074 { 11075 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 11076 rpt_mutex_unlock(&myrpt->lock); 11077 ast_hangup(myrpt->rxchannel); 11078 pthread_exit(NULL); 11079 } 11080 *tele++ = 0; 11081 myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL); 11082 if (!strcasecmp(myrpt->txchanname,"Zap")) 11083 myrpt->zaptxchannel = myrpt->txchannel; 11084 if (myrpt->txchannel) 11085 { 11086 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 11087 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 11088 #ifdef AST_CDR_FLAG_POST_DISABLED 11089 ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11090 #endif 11091 myrpt->txchannel->whentohangup = 0; 11092 myrpt->txchannel->appl = "Apprpt"; 11093 myrpt->txchannel->data = "(Link Tx)"; 11094 if (option_verbose > 2) 11095 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 11096 myrpt->txchanname,tele,myrpt->txchannel->name); 11097 rpt_mutex_unlock(&myrpt->lock); 11098 ast_call(myrpt->txchannel,tele,999); 11099 rpt_mutex_lock(&myrpt->lock); 11100 } 11101 else 11102 { 11103 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 11104 rpt_mutex_unlock(&myrpt->lock); 11105 ast_hangup(myrpt->rxchannel); 11106 pthread_exit(NULL); 11107 } 11108 *--tele = '/'; 11109 } 11110 else 11111 { 11112 myrpt->txchannel = myrpt->rxchannel; 11113 } 11114 /* allocate a pseudo-channel thru asterisk */ 11115 myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 11116 if (!myrpt->pchannel) 11117 { 11118 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 11119 rpt_mutex_unlock(&myrpt->lock); 11120 if (myrpt->txchannel != myrpt->rxchannel) 11121 ast_hangup(myrpt->txchannel); 11122 ast_hangup(myrpt->rxchannel); 11123 pthread_exit(NULL); 11124 } 11125 ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR); 11126 ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR); 11127 #ifdef AST_CDR_FLAG_POST_DISABLED 11128 ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED); 11129 #endif 11130 if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel; 11131 if (!myrpt->zaptxchannel) myrpt->zaptxchannel = myrpt->pchannel; 11132 /* make a conference for the pseudo */ 11133 ci.chan = 0; 11134 ci.confno = -1; /* make a new conf */ 11135 ci.confmode = DAHDI_CONF_CONFANNMON ; 11136 /* first put the channel on the conference in announce/monitor mode */ 11137 if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1) 11138 { 11139 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 11140 rpt_mutex_unlock(&myrpt->lock); 11141 ast_hangup(myrpt->pchannel); 11142 if (myrpt->txchannel != myrpt->rxchannel) 11143 ast_hangup(myrpt->txchannel); 11144 ast_hangup(myrpt->rxchannel); 11145 pthread_exit(NULL); 11146 } 11147 /* save pseudo channel conference number */ 11148 myrpt->conf = myrpt->txconf = ci.confno; 11149 /* if serial io port, open it */ 11150 myrpt->iofd = -1; 11151 if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt->p.ioport)) == -1)) 11152 { 11153 rpt_mutex_unlock(&myrpt->lock); 11154 ast_hangup(myrpt->pchannel); 11155 if (myrpt->txchannel != myrpt->rxchannel) 11156 ast_hangup(myrpt->txchannel); 11157 ast_hangup(myrpt->rxchannel); 11158 pthread_exit(NULL); 11159 } 11160 iskenwood_pci4 = 0; 11161 memset(&z,0,sizeof(z)); 11162 if ((myrpt->iofd < 1) && (myrpt->txchannel == myrpt->zaptxchannel)) 11163 { 11164 z.radpar = DAHDI_RADPAR_REMMODE; 11165 z.data = DAHDI_RADPAR_REM_NONE; 11166 res = ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z); 11167 /* if PCIRADIO and kenwood selected */ 11168 if ((!res) && (!strcmp(myrpt->remote,remote_rig_kenwood))) 11169 { 11170 z.radpar = DAHDI_RADPAR_UIOMODE; 11171 z.data = 1; 11172 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1) 11173 { 11174 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11175 return -1; 11176 } 11177 z.radpar = DAHDI_RADPAR_UIODATA; 11178 z.data = 3; 11179 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1) 11180 { 11181 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11182 return -1; 11183 } 11184 i = DAHDI_OFFHOOK; 11185 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_HOOK,&i) == -1) 11186 { 11187 ast_log(LOG_ERROR,"Cannot set hook\n"); 11188 return -1; 11189 } 11190 iskenwood_pci4 = 1; 11191 } 11192 } 11193 if (myrpt->txchannel == myrpt->zaptxchannel) 11194 { 11195 i = DAHDI_ONHOOK; 11196 ioctl(myrpt->zaptxchannel->fds[0],DAHDI_HOOK,&i); 11197 /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */ 11198 if ((myrpt->iofd < 1) && (!res) && 11199 (!strcmp(myrpt->remote,remote_rig_ft897) || 11200 (!strcmp(myrpt->remote,remote_rig_ic706)))) 11201 { 11202 z.radpar = DAHDI_RADPAR_UIOMODE; 11203 z.data = 1; 11204 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1) 11205 { 11206 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11207 return -1; 11208 } 11209 z.radpar = DAHDI_RADPAR_UIODATA; 11210 z.data = 3; 11211 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1) 11212 { 11213 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11214 return -1; 11215 } 11216 } 11217 } 11218 myrpt->remoterx = 0; 11219 myrpt->remotetx = 0; 11220 myrpt->retxtimer = 0; 11221 myrpt->rerxtimer = 0; 11222 myrpt->remoteon = 1; 11223 myrpt->dtmfidx = -1; 11224 myrpt->dtmfbuf[0] = 0; 11225 myrpt->dtmf_time_rem = 0; 11226 myrpt->hfscanmode = 0; 11227 myrpt->hfscanstatus = 0; 11228 if (myrpt->p.startupmacro) 11229 { 11230 snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro); 11231 } 11232 time(&myrpt->start_time); 11233 myrpt->last_activity_time = myrpt->start_time; 11234 last_timeout_warning = 0; 11235 myrpt->reload = 0; 11236 myrpt->tele.next = &myrpt->tele; 11237 myrpt->tele.prev = &myrpt->tele; 11238 rpt_mutex_unlock(&myrpt->lock); 11239 ast_set_write_format(chan, AST_FORMAT_SLINEAR); 11240 ast_set_read_format(chan, AST_FORMAT_SLINEAR); 11241 rem_rx = 0; 11242 remkeyed = 0; 11243 /* if we are on 2w loop and are a remote, turn EC on */ 11244 if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel)) 11245 { 11246 i = 128; 11247 ioctl(myrpt->zaprxchannel->fds[0],DAHDI_ECHOCANCEL,&i); 11248 } 11249 if (chan->_state != AST_STATE_UP) { 11250 ast_answer(chan); 11251 } 11252 11253 if (myrpt->rxchannel == myrpt->zaprxchannel) 11254 { 11255 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_GET_PARAMS,&par) != -1) 11256 { 11257 if (par.rxisoffhook) 11258 { 11259 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11260 myrpt->remoterx = 1; 11261 remkeyed = 1; 11262 } 11263 } 11264 } 11265 if (myrpt->p.archivedir) 11266 { 11267 char mycmd[100],mydate[100],*b,*b1; 11268 time_t myt; 11269 long blocksleft; 11270 11271 11272 mkdir(myrpt->p.archivedir,0600); 11273 sprintf(mycmd,"%s/%s",myrpt->p.archivedir,myrpt->name); 11274 mkdir(mycmd,0600); 11275 time(&myt); 11276 strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S", 11277 localtime(&myt)); 11278 sprintf(mycmd,"mixmonitor start %s %s/%s/%s.wav49 a",chan->name, 11279 myrpt->p.archivedir,myrpt->name,mydate); 11280 if (myrpt->p.monminblocks) 11281 { 11282 blocksleft = diskavail(myrpt); 11283 if (myrpt->p.remotetimeout) 11284 { 11285 blocksleft -= (myrpt->p.remotetimeout * 11286 MONITOR_DISK_BLOCKS_PER_MINUTE) / 60; 11287 } 11288 if (blocksleft >= myrpt->p.monminblocks) 11289 ast_cli_command(nullfd,mycmd); 11290 } else ast_cli_command(nullfd,mycmd); 11291 /* look at callerid to see what node this comes from */ 11292 if (!chan->cid.cid_num) /* if doesn't have caller id */ 11293 { 11294 b1 = "0"; 11295 } else { 11296 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 11297 ast_shrink_phone_number(b1); 11298 } 11299 sprintf(mycmd,"CONNECT,%s",b1); 11300 donodelog(myrpt,mycmd); 11301 } 11302 myrpt->loginuser[0] = 0; 11303 myrpt->loginlevel[0] = 0; 11304 myrpt->authtelltimer = 0; 11305 myrpt->authtimer = 0; 11306 authtold = 0; 11307 authreq = 0; 11308 if (myrpt->p.authlevel > 1) authreq = 1; 11309 setrem(myrpt); 11310 n = 0; 11311 dtmfed = 0; 11312 cs[n++] = chan; 11313 cs[n++] = myrpt->rxchannel; 11314 cs[n++] = myrpt->pchannel; 11315 if (myrpt->rxchannel != myrpt->txchannel) 11316 cs[n++] = myrpt->txchannel; 11317 /* start un-locked */ 11318 for(;;) 11319 { 11320 if (ast_check_hangup(chan)) break; 11321 if (ast_check_hangup(myrpt->rxchannel)) break; 11322 notremming = 0; 11323 setting = 0; 11324 reming = 0; 11325 telem = myrpt->tele.next; 11326 while(telem != &myrpt->tele) 11327 { 11328 if (telem->mode == SETREMOTE) setting = 1; 11329 if ((telem->mode == SETREMOTE) || 11330 (telem->mode == SCAN) || 11331 (telem->mode == TUNE)) reming = 1; 11332 else notremming = 1; 11333 telem = telem->next; 11334 } 11335 if (myrpt->reload) 11336 { 11337 myrpt->reload = 0; 11338 /* find our index, and load the vars */ 11339 for(i = 0; i < nrpts; i++) 11340 { 11341 if (&rpt_vars[i] == myrpt) 11342 { 11343 load_rpt_vars(i,0); 11344 break; 11345 } 11346 } 11347 } 11348 time(&t); 11349 if (myrpt->p.remotetimeout) 11350 { 11351 time_t r; 11352 11353 r = (t - myrpt->start_time); 11354 if (r >= myrpt->p.remotetimeout) 11355 { 11356 sayfile(chan,"rpt/node"); 11357 ast_say_character_str(chan,myrpt->name,NULL,chan->language); 11358 sayfile(chan,"rpt/timeout"); 11359 ast_safe_sleep(chan,1000); 11360 break; 11361 } 11362 if ((myrpt->p.remotetimeoutwarning) && 11363 (r >= (myrpt->p.remotetimeout - 11364 myrpt->p.remotetimeoutwarning)) && 11365 (r <= (myrpt->p.remotetimeout - 11366 myrpt->p.remotetimeoutwarningfreq))) 11367 { 11368 if (myrpt->p.remotetimeoutwarningfreq) 11369 { 11370 if ((t - last_timeout_warning) >= 11371 myrpt->p.remotetimeoutwarningfreq) 11372 { 11373 time(&last_timeout_warning); 11374 rpt_telemetry(myrpt,TIMEOUT_WARNING,0); 11375 } 11376 } 11377 else 11378 { 11379 if (!last_timeout_warning) 11380 { 11381 time(&last_timeout_warning); 11382 rpt_telemetry(myrpt,TIMEOUT_WARNING,0); 11383 } 11384 } 11385 } 11386 } 11387 if (myrpt->p.remoteinacttimeout && myrpt->last_activity_time) 11388 { 11389 time_t r; 11390 11391 r = (t - myrpt->last_activity_time); 11392 if (r >= myrpt->p.remoteinacttimeout) 11393 { 11394 sayfile(chan,"rpt/node"); 11395 ast_say_character_str(chan,myrpt->name,NULL,chan->language); 11396 sayfile(chan,"rpt/timeout"); 11397 ast_safe_sleep(chan,1000); 11398 break; 11399 } 11400 if ((myrpt->p.remotetimeoutwarning) && 11401 (r >= (myrpt->p.remoteinacttimeout - 11402 myrpt->p.remotetimeoutwarning)) && 11403 (r <= (myrpt->p.remoteinacttimeout - 11404 myrpt->p.remotetimeoutwarningfreq))) 11405 { 11406 if (myrpt->p.remotetimeoutwarningfreq) 11407 { 11408 if ((t - last_timeout_warning) >= 11409 myrpt->p.remotetimeoutwarningfreq) 11410 { 11411 time(&last_timeout_warning); 11412 rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0); 11413 } 11414 } 11415 else 11416 { 11417 if (!last_timeout_warning) 11418 { 11419 time(&last_timeout_warning); 11420 rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0); 11421 } 11422 } 11423 } 11424 } 11425 ms = MSWAIT; 11426 who = ast_waitfor_n(cs,n,&ms); 11427 if (who == NULL) ms = 0; 11428 elap = MSWAIT - ms; 11429 if (myrpt->macrotimer) myrpt->macrotimer -= elap; 11430 if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; 11431 if (!ms) continue; 11432 /* do local dtmf timer */ 11433 if (myrpt->dtmf_local_timer) 11434 { 11435 if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap; 11436 if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1; 11437 } 11438 rpt_mutex_lock(&myrpt->lock); 11439 do_dtmf_local(myrpt,0); 11440 rpt_mutex_unlock(&myrpt->lock); 11441 rem_totx = myrpt->dtmf_local_timer && (!phone_mode); 11442 rem_totx |= keyed && (!myrpt->tunerequest); 11443 rem_rx = (remkeyed && (!setting)) || (myrpt->tele.next != &myrpt->tele); 11444 if(!strcmp(myrpt->remote, remote_rig_ic706)) 11445 rem_totx |= myrpt->tunerequest; 11446 if (keyed && (!keyed1)) 11447 { 11448 keyed1 = 1; 11449 } 11450 11451 if (!keyed && (keyed1)) 11452 { 11453 time_t myt; 11454 11455 keyed1 = 0; 11456 time(&myt); 11457 /* if login necessary, and not too soon */ 11458 if ((myrpt->p.authlevel) && 11459 (!myrpt->loginlevel[0]) && 11460 (myt > (t + 3))) 11461 { 11462 authreq = 1; 11463 authtold = 0; 11464 myrpt->authtelltimer = AUTHTELLTIME - AUTHTXTIME; 11465 } 11466 } 11467 11468 11469 if (rem_rx && (!myrpt->remoterx)) 11470 { 11471 myrpt->remoterx = 1; 11472 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11473 } 11474 if ((!rem_rx) && (myrpt->remoterx)) 11475 { 11476 myrpt->remoterx = 0; 11477 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 11478 } 11479 /* if auth requested, and not authed yet */ 11480 if (authreq && (!myrpt->loginlevel[0])) 11481 { 11482 if ((!authtold) && ((myrpt->authtelltimer += elap) 11483 >= AUTHTELLTIME)) 11484 { 11485 authtold = 1; 11486 rpt_telemetry(myrpt,LOGINREQ,NULL); 11487 } 11488 if ((myrpt->authtimer += elap) >= AUTHLOGOUTTIME) 11489 { 11490 break; /* if not logged in, hang up after a time */ 11491 } 11492 } 11493 #ifndef OLDKEY 11494 if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME) 11495 { 11496 myrpt->retxtimer = 0; 11497 if ((myrpt->remoterx) && (!myrpt->remotetx)) 11498 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 11499 else 11500 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 11501 } 11502 11503 if ((myrpt->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 2)) 11504 { 11505 keyed = 0; 11506 myrpt->rerxtimer = 0; 11507 } 11508 #endif 11509 if (rem_totx && (!myrpt->remotetx)) 11510 { 11511 /* if not authed, and needed, dont transmit */ 11512 if ((!myrpt->p.authlevel) || myrpt->loginlevel[0]) 11513 { 11514 myrpt->remotetx = 1; 11515 if((myrpt->remtxfreqok = check_tx_freq(myrpt))) 11516 { 11517 time(&myrpt->last_activity_time); 11518 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11519 { 11520 z.radpar = DAHDI_RADPAR_UIODATA; 11521 z.data = 1; 11522 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1) 11523 { 11524 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11525 return -1; 11526 } 11527 } 11528 else 11529 { 11530 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 11531 } 11532 if (myrpt->p.archivedir) donodelog(myrpt,"TXKEY"); 11533 } 11534 } 11535 } 11536 if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */ 11537 { 11538 myrpt->remotetx = 0; 11539 if(!myrpt->remtxfreqok){ 11540 rpt_telemetry(myrpt,UNAUTHTX,NULL); 11541 } 11542 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11543 { 11544 z.radpar = DAHDI_RADPAR_UIODATA; 11545 z.data = 3; 11546 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1) 11547 { 11548 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11549 return -1; 11550 } 11551 } 11552 else 11553 { 11554 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 11555 } 11556 if (myrpt->p.archivedir) donodelog(myrpt,"TXUNKEY"); 11557 } 11558 if (myrpt->hfscanmode){ 11559 myrpt->scantimer -= elap; 11560 if(myrpt->scantimer <= 0){ 11561 if (!reming) 11562 { 11563 myrpt->scantimer = REM_SCANTIME; 11564 rpt_telemetry(myrpt,SCAN,0); 11565 } else myrpt->scantimer = 1; 11566 } 11567 } 11568 rpt_mutex_lock(&myrpt->lock); 11569 c = myrpt->macrobuf[0]; 11570 if (c && (!myrpt->macrotimer)) 11571 { 11572 myrpt->macrotimer = MACROTIME; 11573 memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1); 11574 if ((c == 'p') || (c == 'P')) 11575 myrpt->macrotimer = MACROPTIME; 11576 rpt_mutex_unlock(&myrpt->lock); 11577 if (myrpt->p.archivedir) 11578 { 11579 char str[100]; 11580 sprintf(str,"DTMF(M),%c",c); 11581 donodelog(myrpt,str); 11582 } 11583 if (handle_remote_dtmf_digit(myrpt,c,&keyed,0) == -1) break; 11584 continue; 11585 } else rpt_mutex_unlock(&myrpt->lock); 11586 if (who == chan) /* if it was a read from incomming */ 11587 { 11588 f = ast_read(chan); 11589 if (!f) 11590 { 11591 if (debug) printf("@@@@ link:Hung Up\n"); 11592 break; 11593 } 11594 if (f->frametype == AST_FRAME_VOICE) 11595 { 11596 if (ioctl(chan->fds[0], DAHDI_GETCONFMUTE, &ismuted) == -1) 11597 { 11598 ismuted = 0; 11599 } 11600 /* if not transmitting, zero-out audio */ 11601 ismuted |= (!myrpt->remotetx); 11602 if (dtmfed && phone_mode) ismuted = 1; 11603 dtmfed = 0; 11604 if (ismuted) 11605 { 11606 memset(f->data,0,f->datalen); 11607 if (myrpt->lastf1) 11608 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11609 if (myrpt->lastf2) 11610 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11611 } 11612 if (f) f2 = ast_frdup(f); 11613 else f2 = NULL; 11614 f1 = myrpt->lastf2; 11615 myrpt->lastf2 = myrpt->lastf1; 11616 myrpt->lastf1 = f2; 11617 if (ismuted) 11618 { 11619 if (myrpt->lastf1) 11620 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11621 if (myrpt->lastf2) 11622 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11623 } 11624 if (f1) 11625 { 11626 if (phone_mode) 11627 ast_write(myrpt->txchannel,f1); 11628 else 11629 ast_write(myrpt->txchannel,f); 11630 ast_frfree(f1); 11631 } 11632 } 11633 #ifndef OLD_ASTERISK 11634 else if (f->frametype == AST_FRAME_DTMF_BEGIN) 11635 { 11636 if (myrpt->lastf1) 11637 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11638 if (myrpt->lastf2) 11639 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11640 dtmfed = 1; 11641 } 11642 #endif 11643 if (f->frametype == AST_FRAME_DTMF) 11644 { 11645 if (myrpt->lastf1) 11646 memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen); 11647 if (myrpt->lastf2) 11648 memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen); 11649 dtmfed = 1; 11650 if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1) 11651 { 11652 if (debug) printf("@@@@ rpt:Hung Up\n"); 11653 ast_frfree(f); 11654 break; 11655 } 11656 } 11657 if (f->frametype == AST_FRAME_TEXT) 11658 { 11659 if (handle_remote_data(myrpt,f->data) == -1) 11660 { 11661 if (debug) printf("@@@@ rpt:Hung Up\n"); 11662 ast_frfree(f); 11663 break; 11664 } 11665 } 11666 if (f->frametype == AST_FRAME_CONTROL) 11667 { 11668 if (f->subclass == AST_CONTROL_HANGUP) 11669 { 11670 if (debug) printf("@@@@ rpt:Hung Up\n"); 11671 ast_frfree(f); 11672 break; 11673 } 11674 /* if RX key */ 11675 if (f->subclass == AST_CONTROL_RADIO_KEY) 11676 { 11677 if (debug == 7) printf("@@@@ rx key\n"); 11678 keyed = 1; 11679 myrpt->rerxtimer = 0; 11680 } 11681 /* if RX un-key */ 11682 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 11683 { 11684 myrpt->rerxtimer = 0; 11685 if (debug == 7) printf("@@@@ rx un-key\n"); 11686 keyed = 0; 11687 } 11688 } 11689 ast_frfree(f); 11690 continue; 11691 } 11692 if (who == myrpt->rxchannel) /* if it was a read from radio */ 11693 { 11694 f = ast_read(myrpt->rxchannel); 11695 if (!f) 11696 { 11697 if (debug) printf("@@@@ link:Hung Up\n"); 11698 break; 11699 } 11700 if (f->frametype == AST_FRAME_VOICE) 11701 { 11702 int myreming = 0; 11703 11704 if(!strcmp(myrpt->remote, remote_rig_kenwood)) 11705 myreming = reming; 11706 11707 if (myreming || (!remkeyed) || 11708 ((myrpt->remote) && (myrpt->remotetx)) || 11709 ((myrpt->remmode != REM_MODE_FM) && 11710 notremming)) 11711 memset(f->data,0,f->datalen); 11712 ast_write(myrpt->pchannel,f); 11713 } 11714 else if (f->frametype == AST_FRAME_CONTROL) 11715 { 11716 if (f->subclass == AST_CONTROL_HANGUP) 11717 { 11718 if (debug) printf("@@@@ rpt:Hung Up\n"); 11719 ast_frfree(f); 11720 break; 11721 } 11722 /* if RX key */ 11723 if (f->subclass == AST_CONTROL_RADIO_KEY) 11724 { 11725 if (debug == 7) printf("@@@@ remote rx key\n"); 11726 if (!myrpt->remotetx) 11727 { 11728 remkeyed = 1; 11729 } 11730 } 11731 /* if RX un-key */ 11732 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 11733 { 11734 if (debug == 7) printf("@@@@ remote rx un-key\n"); 11735 if (!myrpt->remotetx) 11736 { 11737 remkeyed = 0; 11738 } 11739 } 11740 } 11741 ast_frfree(f); 11742 continue; 11743 } 11744 if (who == myrpt->pchannel) /* if is remote mix output */ 11745 { 11746 f = ast_read(myrpt->pchannel); 11747 if (!f) 11748 { 11749 if (debug) printf("@@@@ link:Hung Up\n"); 11750 break; 11751 } 11752 if (f->frametype == AST_FRAME_VOICE) 11753 { 11754 ast_write(chan,f); 11755 } 11756 if (f->frametype == AST_FRAME_CONTROL) 11757 { 11758 if (f->subclass == AST_CONTROL_HANGUP) 11759 { 11760 if (debug) printf("@@@@ rpt:Hung Up\n"); 11761 ast_frfree(f); 11762 break; 11763 } 11764 } 11765 ast_frfree(f); 11766 continue; 11767 } 11768 if ((myrpt->rxchannel != myrpt->txchannel) && 11769 (who == myrpt->txchannel)) /* do this cuz you have to */ 11770 { 11771 f = ast_read(myrpt->txchannel); 11772 if (!f) 11773 { 11774 if (debug) printf("@@@@ link:Hung Up\n"); 11775 break; 11776 } 11777 if (f->frametype == AST_FRAME_CONTROL) 11778 { 11779 if (f->subclass == AST_CONTROL_HANGUP) 11780 { 11781 if (debug) printf("@@@@ rpt:Hung Up\n"); 11782 ast_frfree(f); 11783 break; 11784 } 11785 } 11786 ast_frfree(f); 11787 continue; 11788 } 11789 } 11790 if (myrpt->p.archivedir) 11791 { 11792 char mycmd[100],*b,*b1; 11793 11794 /* look at callerid to see what node this comes from */ 11795 if (!chan->cid.cid_num) /* if doesn't have caller id */ 11796 { 11797 b1 = "0"; 11798 } else { 11799 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 11800 ast_shrink_phone_number(b1); 11801 } 11802 sprintf(mycmd,"DISCONNECT,%s",b1); 11803 donodelog(myrpt,mycmd); 11804 } 11805 /* wait for telem to be done */ 11806 while(myrpt->tele.next != &myrpt->tele) usleep(100000); 11807 sprintf(tmp,"mixmonitor stop %s",chan->name); 11808 ast_cli_command(nullfd,tmp); 11809 close(nullfd); 11810 rpt_mutex_lock(&myrpt->lock); 11811 myrpt->hfscanmode = 0; 11812 myrpt->hfscanstatus = 0; 11813 myrpt->remoteon = 0; 11814 rpt_mutex_unlock(&myrpt->lock); 11815 if (myrpt->lastf1) ast_frfree(myrpt->lastf1); 11816 myrpt->lastf1 = NULL; 11817 if (myrpt->lastf2) ast_frfree(myrpt->lastf2); 11818 myrpt->lastf2 = NULL; 11819 if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel)) 11820 { 11821 z.radpar = DAHDI_RADPAR_UIOMODE; 11822 z.data = 3; 11823 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1) 11824 { 11825 ast_log(LOG_ERROR,"Cannot set UIOMODE\n"); 11826 return -1; 11827 } 11828 z.radpar = DAHDI_RADPAR_UIODATA; 11829 z.data = 3; 11830 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1) 11831 { 11832 ast_log(LOG_ERROR,"Cannot set UIODATA\n"); 11833 return -1; 11834 } 11835 i = DAHDI_OFFHOOK; 11836 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_HOOK,&i) == -1) 11837 { 11838 ast_log(LOG_ERROR,"Cannot set hook\n"); 11839 return -1; 11840 } 11841 } 11842 if (myrpt->iofd) close(myrpt->iofd); 11843 myrpt->iofd = -1; 11844 ast_hangup(myrpt->pchannel); 11845 if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel); 11846 ast_hangup(myrpt->rxchannel); 11847 closerem(myrpt); 11848 #ifdef OLD_ASTERISK 11849 LOCAL_USER_REMOVE(u); 11850 #endif 11851 return res; 11852 }
static void rpt_localtime | ( | time_t * | t, | |
struct tm * | lt | |||
) | [static] |
Definition at line 1583 of file app_rpt.c.
References ast_localtime(), and localtime_r.
Referenced by do_scheduler(), and rpt_tele_thread().
01584 { 01585 #ifdef OLD_ASTERISK 01586 localtime_r(t, lt); 01587 #else 01588 ast_localtime(t, lt, NULL); 01589 #endif 01590 }
static void* rpt_master | ( | void * | ignore | ) | [static] |
Definition at line 10404 of file app_rpt.c.
References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), AST_OPT_FLAG_FULLY_BOOTED, ast_options, ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_test_flag, ast_variable_retrieve(), rpt::cfg, free, rpt::ident, rpt::lastthreadrestarttime, load_rpt_vars(), lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, name, rpt::name, rpt_tele::next, nodeloglock, 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, strdup, rpt::tailmessagen, rpt::tele, rpt::threadrestarts, and rpt::txchanname.
Referenced by load_module().
10405 { 10406 int i,n; 10407 pthread_attr_t attr; 10408 struct ast_config *cfg; 10409 char *this,*val; 10410 10411 /* init nodelog queue */ 10412 nodelog.next = nodelog.prev = &nodelog; 10413 /* go thru all the specified repeaters */ 10414 this = NULL; 10415 n = 0; 10416 /* wait until asterisk starts */ 10417 while(!ast_test_flag(&ast_options,AST_OPT_FLAG_FULLY_BOOTED)) 10418 usleep(250000); 10419 rpt_vars[n].cfg = ast_config_load("rpt.conf"); 10420 cfg = rpt_vars[n].cfg; 10421 if (!cfg) { 10422 ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); 10423 pthread_exit(NULL); 10424 } 10425 while((this = ast_category_browse(cfg,this)) != NULL) 10426 { 10427 for(i = 0 ; i < strlen(this) ; i++){ 10428 if((this[i] < '0') || (this[i] > '9')) 10429 break; 10430 } 10431 if(i != strlen(this)) continue; /* Not a node defn */ 10432 memset(&rpt_vars[n],0,sizeof(rpt_vars[n])); 10433 rpt_vars[n].name = strdup(this); 10434 val = (char *) ast_variable_retrieve(cfg,this,"rxchannel"); 10435 if (val) rpt_vars[n].rxchanname = strdup(val); 10436 val = (char *) ast_variable_retrieve(cfg,this,"txchannel"); 10437 if (val) rpt_vars[n].txchanname = strdup(val); 10438 val = (char *) ast_variable_retrieve(cfg,this,"remote"); 10439 if (val) rpt_vars[n].remote = strdup(val); 10440 ast_mutex_init(&rpt_vars[n].lock); 10441 ast_mutex_init(&rpt_vars[n].remlock); 10442 rpt_vars[n].tele.next = &rpt_vars[n].tele; 10443 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 10444 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 10445 rpt_vars[n].tailmessagen = 0; 10446 #ifdef _MDC_DECODE_H_ 10447 rpt_vars[n].mdc = mdc_decoder_new(8000); 10448 #endif 10449 n++; 10450 } 10451 nrpts = n; 10452 ast_config_destroy(cfg); 10453 10454 /* start em all */ 10455 for(i = 0; i < n; i++) 10456 { 10457 load_rpt_vars(i,1); 10458 10459 /* if is a remote, dont start one for it */ 10460 if (rpt_vars[i].remote) 10461 { 10462 if(retreive_memory(&rpt_vars[i],"init")){ /* Try to retreive initial memory channel */ 10463 strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1); 10464 strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1); 10465 10466 strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1); 10467 rpt_vars[i].remmode = REM_MODE_FM; 10468 rpt_vars[i].offset = REM_SIMPLEX; 10469 rpt_vars[i].powerlevel = REM_MEDPWR; 10470 } 10471 continue; 10472 } 10473 if (!rpt_vars[i].p.ident) 10474 { 10475 ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name); 10476 ast_config_destroy(cfg); 10477 pthread_exit(NULL); 10478 } 10479 pthread_attr_init(&attr); 10480 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10481 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 10482 } 10483 usleep(500000); 10484 time(&starttime); 10485 for(;;) 10486 { 10487 /* Now monitor each thread, and restart it if necessary */ 10488 for(i = 0; i < n; i++) 10489 { 10490 int rv; 10491 if (rpt_vars[i].remote) continue; 10492 if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP) 10493 rv = -1; 10494 else 10495 rv = pthread_kill(rpt_vars[i].rpt_thread,0); 10496 if (rv) 10497 { 10498 if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15) 10499 { 10500 if(rpt_vars[i].threadrestarts >= 5) 10501 { 10502 ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n"); 10503 exit(1); /* Stuck in a restart loop, kill Asterisk and start over */ 10504 } 10505 else 10506 { 10507 ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name); 10508 rpt_vars[i].threadrestarts++; 10509 } 10510 } 10511 else 10512 rpt_vars[i].threadrestarts = 0; 10513 10514 rpt_vars[i].lastthreadrestarttime = time(NULL); 10515 pthread_attr_init(&attr); 10516 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 10517 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 10518 ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name); 10519 } 10520 10521 } 10522 for(;;) 10523 { 10524 struct nodelog *nodep; 10525 char *space,datestr[100],fname[300]; 10526 int fd; 10527 10528 ast_mutex_lock(&nodeloglock); 10529 nodep = nodelog.next; 10530 if(nodep == &nodelog) /* if nothing in queue */ 10531 { 10532 ast_mutex_unlock(&nodeloglock); 10533 break; 10534 } 10535 remque((struct qelem *)nodep); 10536 ast_mutex_unlock(&nodeloglock); 10537 space = strchr(nodep->str,' '); 10538 if (!space) 10539 { 10540 free(nodep); 10541 continue; 10542 } 10543 *space = 0; 10544 strftime(datestr,sizeof(datestr) - 1,"%Y%m%d", 10545 localtime(&nodep->timestamp)); 10546 sprintf(fname,"%s/%s/%s.txt",nodep->archivedir, 10547 nodep->str,datestr); 10548 fd = open(fname,O_WRONLY | O_CREAT | O_APPEND,0600); 10549 if (fd == -1) 10550 { 10551 ast_log(LOG_ERROR,"Cannot open node log file %s for write",space + 1); 10552 free(nodep); 10553 continue; 10554 } 10555 if (write(fd,space + 1,strlen(space + 1)) != 10556 strlen(space + 1)) 10557 { 10558 ast_log(LOG_ERROR,"Cannot write node log file %s for write",space + 1); 10559 free(nodep); 10560 continue; 10561 } 10562 close(fd); 10563 free(nodep); 10564 } 10565 sleep(2); 10566 } 10567 ast_config_destroy(cfg); 10568 pthread_exit(NULL); 10569 }
static void* rpt_tele_thread | ( | void * | this | ) | [static] |
Definition at line 2905 of file app_rpt.c.
References __mklinklist(), ACT_TIMEOUT_WARNING, ARB_ALPHA, AST_CDR_FLAG_POST_DISABLED, AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_safe_sleep(), ast_say_character_str(), ast_say_digits(), ast_say_number(), ast_say_time, ast_set_flag, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_tonepair_start(), ast_variable_retrieve(), ast_waitstream(), ast_channel::cdr, rpt_tele::chan, COMPLETE, CONNECTED, CONNFAIL, DLY_CALLTERM, DLY_COMP, DLY_ID, DLY_LINKUNKEY, DLY_TELEM, DLY_UNKEY, ast_channel::fds, finddelim(), free, FULLSTATUS, get_wait_interval(), rpt_link::hasconnected, ID, ID1, IDTALKOVER, INVFREQ, rpt_link::isremote, ast_channel::language, 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, ast_channel::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, rpt_tele::submode, t, TAILMSG, telem_any(), telem_lookup(), TERM, TEST_TONE, rpt_link::thisconnected, TIMEOUT, TIMEOUT_WARNING, TUNE, UNAUTHTX, UNKEY, and wait_interval().
Referenced by rpt_telemetry().
02906 { 02907 struct dahdi_confinfo ci; /* conference info */ 02908 int res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x; 02909 struct rpt_tele *mytele = (struct rpt_tele *)this; 02910 struct rpt_tele *tlist; 02911 struct rpt *myrpt; 02912 struct rpt_link *l,*l1,linkbase; 02913 struct ast_channel *mychannel; 02914 int vmajor, vminor, m; 02915 char *p,*ct,*ct_copy,*ident, *nodename,*cp; 02916 time_t t; 02917 struct tm localtm; 02918 char lbuf[MAXLINKLIST],*strs[MAXLINKLIST]; 02919 int i,ns,rbimode; 02920 char mhz[MAXREMSTR]; 02921 char decimals[MAXREMSTR]; 02922 struct dahdi_params par; 02923 02924 02925 /* get a pointer to myrpt */ 02926 myrpt = mytele->rpt; 02927 02928 /* Snag copies of a few key myrpt variables */ 02929 rpt_mutex_lock(&myrpt->lock); 02930 nodename = ast_strdupa(myrpt->name); 02931 if (myrpt->p.ident) ident = ast_strdupa(myrpt->p.ident); 02932 else ident = ""; 02933 rpt_mutex_unlock(&myrpt->lock); 02934 02935 /* allocate a pseudo-channel thru asterisk */ 02936 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 02937 if (!mychannel) 02938 { 02939 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 02940 rpt_mutex_lock(&myrpt->lock); 02941 remque((struct qelem *)mytele); 02942 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02943 rpt_mutex_unlock(&myrpt->lock); 02944 free(mytele); 02945 pthread_exit(NULL); 02946 } 02947 #ifdef AST_CDR_FLAG_POST_DISABLED 02948 ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED); 02949 #endif 02950 rpt_mutex_lock(&myrpt->lock); 02951 mytele->chan = mychannel; 02952 rpt_mutex_unlock(&myrpt->lock); 02953 /* make a conference for the tx */ 02954 ci.chan = 0; 02955 /* If there's an ID queued, or tail message queued, */ 02956 /* only connect the ID audio to the local tx conference so */ 02957 /* linked systems can't hear it */ 02958 ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) || 02959 (mytele->mode == TAILMSG) || (mytele->mode == LINKUNKEY)) || (mytele->mode == TIMEOUT) ? 02960 myrpt->txconf : myrpt->conf); 02961 ci.confmode = DAHDI_CONF_CONFANN; 02962 /* first put the channel on the conference in announce mode */ 02963 if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1) 02964 { 02965 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02966 rpt_mutex_lock(&myrpt->lock); 02967 remque((struct qelem *)mytele); 02968 rpt_mutex_unlock(&myrpt->lock); 02969 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02970 free(mytele); 02971 ast_hangup(mychannel); 02972 pthread_exit(NULL); 02973 } 02974 ast_stopstream(mychannel); 02975 switch(mytele->mode) 02976 { 02977 case ID: 02978 case ID1: 02979 /* wait a bit */ 02980 wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel); 02981 res = telem_any(myrpt,mychannel, ident); 02982 imdone=1; 02983 break; 02984 02985 case TAILMSG: 02986 res = ast_streamfile(mychannel, myrpt->p.tailmessages[myrpt->tailmessagen], mychannel->language); 02987 break; 02988 02989 case IDTALKOVER: 02990 p = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "idtalkover"); 02991 if(p) 02992 res = telem_any(myrpt,mychannel, p); 02993 imdone=1; 02994 break; 02995 02996 case PROC: 02997 /* wait a little bit longer */ 02998 wait_interval(myrpt, DLY_TELEM, mychannel); 02999 res = telem_lookup(myrpt, mychannel, myrpt->name, "patchup"); 03000 if(res < 0){ /* Then default message */ 03001 res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language); 03002 } 03003 break; 03004 case TERM: 03005 /* wait a little bit longer */ 03006 wait_interval(myrpt, DLY_CALLTERM, mychannel); 03007 res = telem_lookup(myrpt, mychannel, myrpt->name, "patchdown"); 03008 if(res < 0){ /* Then default message */ 03009 res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language); 03010 } 03011 break; 03012 case COMPLETE: 03013 /* wait a little bit */ 03014 wait_interval(myrpt, DLY_TELEM, mychannel); 03015 res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03016 break; 03017 case MACRO_NOTFOUND: 03018 /* wait a little bit */ 03019 wait_interval(myrpt, DLY_TELEM, mychannel); 03020 res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language); 03021 break; 03022 case MACRO_BUSY: 03023 /* wait a little bit */ 03024 wait_interval(myrpt, DLY_TELEM, mychannel); 03025 res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language); 03026 break; 03027 case UNKEY: 03028 if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */ 03029 imdone = 1; 03030 break; 03031 } 03032 03033 /* 03034 * Reset the Unkey to CT timer 03035 */ 03036 03037 x = get_wait_interval(myrpt, DLY_UNKEY); 03038 rpt_mutex_lock(&myrpt->lock); 03039 myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */ 03040 rpt_mutex_unlock(&myrpt->lock); 03041 03042 /* 03043 * If there's one already queued, don't do another 03044 */ 03045 03046 tlist = myrpt->tele.next; 03047 unkeys_queued = 0; 03048 if (tlist != &myrpt->tele) 03049 { 03050 rpt_mutex_lock(&myrpt->lock); 03051 while(tlist != &myrpt->tele){ 03052 if (tlist->mode == UNKEY) unkeys_queued++; 03053 tlist = tlist->next; 03054 } 03055 rpt_mutex_unlock(&myrpt->lock); 03056 } 03057 if( unkeys_queued > 1){ 03058 imdone = 1; 03059 break; 03060 } 03061 03062 /* Wait for the telemetry timer to expire */ 03063 /* Periodically check the timer since it can be re-initialized above */ 03064 while(myrpt->unkeytocttimer) 03065 { 03066 int ctint; 03067 if(myrpt->unkeytocttimer > 100) 03068 ctint = 100; 03069 else 03070 ctint = myrpt->unkeytocttimer; 03071 ast_safe_sleep(mychannel, ctint); 03072 rpt_mutex_lock(&myrpt->lock); 03073 if(myrpt->unkeytocttimer < ctint) 03074 myrpt->unkeytocttimer = 0; 03075 else 03076 myrpt->unkeytocttimer -= ctint; 03077 rpt_mutex_unlock(&myrpt->lock); 03078 } 03079 03080 /* 03081 * Now, the carrier on the rptr rx should be gone. 03082 * If it re-appeared, then forget about sending the CT 03083 */ 03084 if(myrpt->keyed){ 03085 imdone = 1; 03086 break; 03087 } 03088 03089 rpt_mutex_lock(&myrpt->lock); /* Update the kerchunk counters */ 03090 myrpt->dailykerchunks++; 03091 myrpt->totalkerchunks++; 03092 rpt_mutex_unlock(&myrpt->lock); 03093 03094 haslink = 0; 03095 hastx = 0; 03096 hasremote = 0; 03097 l = myrpt->links.next; 03098 if (l != &myrpt->links) 03099 { 03100 rpt_mutex_lock(&myrpt->lock); 03101 while(l != &myrpt->links) 03102 { 03103 if (l->name[0] == '0') 03104 { 03105 l = l->next; 03106 continue; 03107 } 03108 haslink = 1; 03109 if (l->mode) { 03110 hastx++; 03111 if (l->isremote) hasremote++; 03112 } 03113 l = l->next; 03114 } 03115 rpt_mutex_unlock(&myrpt->lock); 03116 } 03117 if (haslink) 03118 { 03119 03120 res = telem_lookup(myrpt,mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx"); 03121 if(res) 03122 ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name); 03123 03124 03125 /* if in remote cmd mode, indicate it */ 03126 if (myrpt->cmdnode[0]) 03127 { 03128 ast_safe_sleep(mychannel,200); 03129 res = telem_lookup(myrpt,mychannel, myrpt->name, "cmdmode"); 03130 if(res) 03131 ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name); 03132 ast_stopstream(mychannel); 03133 } 03134 } 03135 else if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */ 03136 ct_copy = ast_strdupa(ct); 03137 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03138 if(res) 03139 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03140 } 03141 if (hasremote && (!myrpt->cmdnode[0])) 03142 { 03143 /* set for all to hear */ 03144 ci.chan = 0; 03145 ci.confno = myrpt->conf; 03146 ci.confmode = DAHDI_CONF_CONFANN; 03147 /* first put the channel on the conference in announce mode */ 03148 if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1) 03149 { 03150 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 03151 rpt_mutex_lock(&myrpt->lock); 03152 remque((struct qelem *)mytele); 03153 rpt_mutex_unlock(&myrpt->lock); 03154 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03155 free(mytele); 03156 ast_hangup(mychannel); 03157 pthread_exit(NULL); 03158 } 03159 if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */ 03160 ast_safe_sleep(mychannel,200); 03161 ct_copy = ast_strdupa(ct); 03162 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03163 if(res) 03164 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03165 } 03166 } 03167 #if defined(_MDC_DECODE_H_) && defined(MDC_SAY_WHEN_DOING_CT) 03168 if (myrpt->lastunit) 03169 { 03170 char mystr[10]; 03171 03172 ast_safe_sleep(mychannel,200); 03173 /* set for all to hear */ 03174 ci.chan = 0; 03175 ci.confno = myrpt->txconf; 03176 ci.confmode = DAHDI_CONF_CONFANN; 03177 /* first put the channel on the conference in announce mode */ 03178 if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1) 03179 { 03180 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 03181 rpt_mutex_lock(&myrpt->lock); 03182 remque((struct qelem *)mytele); 03183 rpt_mutex_unlock(&myrpt->lock); 03184 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03185 free(mytele); 03186 ast_hangup(mychannel); 03187 pthread_exit(NULL); 03188 } 03189 sprintf(mystr,"%04x",myrpt->lastunit); 03190 myrpt->lastunit = 0; 03191 ast_say_character_str(mychannel,mystr,NULL,mychannel->language); 03192 break; 03193 } 03194 #endif 03195 imdone = 1; 03196 break; 03197 case LINKUNKEY: 03198 if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */ 03199 imdone = 1; 03200 break; 03201 } 03202 03203 /* 03204 * Reset the Unkey to CT timer 03205 */ 03206 03207 x = get_wait_interval(myrpt, DLY_LINKUNKEY); 03208 mytele->mylink.linkunkeytocttimer = x; /* Must be protected as it is changed below */ 03209 03210 /* 03211 * If there's one already queued, don't do another 03212 */ 03213 03214 tlist = myrpt->tele.next; 03215 unkeys_queued = 0; 03216 if (tlist != &myrpt->tele) 03217 { 03218 rpt_mutex_lock(&myrpt->lock); 03219 while(tlist != &myrpt->tele){ 03220 if (tlist->mode == LINKUNKEY) unkeys_queued++; 03221 tlist = tlist->next; 03222 } 03223 rpt_mutex_unlock(&myrpt->lock); 03224 } 03225 if( unkeys_queued > 1){ 03226 imdone = 1; 03227 break; 03228 } 03229 03230 /* Wait for the telemetry timer to expire */ 03231 /* Periodically check the timer since it can be re-initialized above */ 03232 while(mytele->mylink.linkunkeytocttimer) 03233 { 03234 int ctint; 03235 if(mytele->mylink.linkunkeytocttimer > 100) 03236 ctint = 100; 03237 else 03238 ctint = mytele->mylink.linkunkeytocttimer; 03239 ast_safe_sleep(mychannel, ctint); 03240 rpt_mutex_lock(&myrpt->lock); 03241 if(mytele->mylink.linkunkeytocttimer < ctint) 03242 mytele->mylink.linkunkeytocttimer = 0; 03243 else 03244 mytele->mylink.linkunkeytocttimer -= ctint; 03245 rpt_mutex_unlock(&myrpt->lock); 03246 } 03247 03248 if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "linkunkeyct"))){ /* Unlinked Courtesy Tone */ 03249 ct_copy = ast_strdupa(ct); 03250 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 03251 if(res) 03252 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 03253 } 03254 imdone = 1; 03255 break; 03256 case REMDISC: 03257 /* wait a little bit */ 03258 wait_interval(myrpt, DLY_TELEM, mychannel); 03259 l = myrpt->links.next; 03260 haslink = 0; 03261 /* dont report if a link for this one still on system */ 03262 if (l != &myrpt->links) 03263 { 03264 rpt_mutex_lock(&myrpt->lock); 03265 while(l != &myrpt->links) 03266 { 03267 if (l->name[0] == '0') 03268 { 03269 l = l->next; 03270 continue; 03271 } 03272 if (!strcmp(l->name,mytele->mylink.name)) 03273 { 03274 haslink = 1; 03275 break; 03276 } 03277 l = l->next; 03278 } 03279 rpt_mutex_unlock(&myrpt->lock); 03280 } 03281 if (haslink) 03282 { 03283 imdone = 1; 03284 break; 03285 } 03286 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03287 if (!res) 03288 res = ast_waitstream(mychannel, ""); 03289 else 03290 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03291 ast_stopstream(mychannel); 03292 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03293 res = ast_streamfile(mychannel, ((mytele->mylink.hasconnected) ? 03294 "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language); 03295 break; 03296 case REMALREADY: 03297 /* wait a little bit */ 03298 wait_interval(myrpt, DLY_TELEM, mychannel); 03299 res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language); 03300 break; 03301 case REMNOTFOUND: 03302 /* wait a little bit */ 03303 wait_interval(myrpt, DLY_TELEM, mychannel); 03304 res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language); 03305 break; 03306 case REMGO: 03307 /* wait a little bit */ 03308 wait_interval(myrpt, DLY_TELEM, mychannel); 03309 res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language); 03310 break; 03311 case CONNECTED: 03312 /* wait a little bit */ 03313 wait_interval(myrpt, DLY_TELEM, mychannel); 03314 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03315 if (!res) 03316 res = ast_waitstream(mychannel, ""); 03317 else 03318 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03319 ast_stopstream(mychannel); 03320 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03321 res = ast_streamfile(mychannel, "rpt/connected", mychannel->language); 03322 if (!res) 03323 res = ast_waitstream(mychannel, ""); 03324 else 03325 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03326 ast_stopstream(mychannel); 03327 res = ast_streamfile(mychannel, "digits/2", mychannel->language); 03328 if (!res) 03329 res = ast_waitstream(mychannel, ""); 03330 else 03331 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03332 ast_stopstream(mychannel); 03333 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03334 if (!res) 03335 res = ast_waitstream(mychannel, ""); 03336 else 03337 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03338 ast_stopstream(mychannel); 03339 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03340 imdone = 1; 03341 break; 03342 case CONNFAIL: 03343 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03344 if (!res) 03345 res = ast_waitstream(mychannel, ""); 03346 else 03347 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03348 ast_stopstream(mychannel); 03349 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 03350 res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language); 03351 break; 03352 case MEMNOTFOUND: 03353 /* wait a little bit */ 03354 wait_interval(myrpt, DLY_TELEM, mychannel); 03355 res = ast_streamfile(mychannel, "rpt/memory_notfound", mychannel->language); 03356 break; 03357 case SETREMOTE: 03358 ast_mutex_lock(&myrpt->remlock); 03359 res = 0; 03360 if(!strcmp(myrpt->remote, remote_rig_ft897)) 03361 { 03362 res = set_ft897(myrpt); 03363 } 03364 if(!strcmp(myrpt->remote, remote_rig_ic706)) 03365 { 03366 res = set_ic706(myrpt); 03367 } 03368 #ifdef HAVE_IOPERM 03369 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 03370 { 03371 if (ioperm(myrpt->p.iobase,1,1) == -1) 03372 { 03373 rpt_mutex_unlock(&myrpt->lock); 03374 ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase); 03375 res = -1; 03376 } 03377 else res = setrbi(myrpt); 03378 } 03379 #endif 03380 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) 03381 { 03382 res = setkenwood(myrpt); 03383 if (ast_safe_sleep(mychannel,200) == -1) 03384 { 03385 ast_mutex_unlock(&myrpt->remlock); 03386 res = -1; 03387 break; 03388 } 03389 i = DAHDI_FLUSH_EVENT; 03390 if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_FLUSH,&i) == -1) 03391 { 03392 ast_mutex_unlock(&myrpt->remlock); 03393 ast_log(LOG_ERROR,"Cant flush events"); 03394 res = -1; 03395 break; 03396 } 03397 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_GET_PARAMS,&par) == -1) 03398 { 03399 ast_mutex_unlock(&myrpt->remlock); 03400 ast_log(LOG_ERROR,"Cant get params"); 03401 res = -1; 03402 break; 03403 } 03404 myrpt->remoterx = 03405 (par.rxisoffhook || (myrpt->tele.next != &myrpt->tele)); 03406 } 03407 ast_mutex_unlock(&myrpt->remlock); 03408 if (!res) 03409 { 03410 imdone = 1; 03411 break; 03412 } 03413 /* fall thru to invalid freq */ 03414 case INVFREQ: 03415 /* wait a little bit */ 03416 wait_interval(myrpt, DLY_TELEM, mychannel); 03417 res = ast_streamfile(mychannel, "rpt/invalid-freq", mychannel->language); 03418 break; 03419 case REMMODE: 03420 cp = 0; 03421 wait_interval(myrpt, DLY_TELEM, mychannel); 03422 switch(myrpt->remmode) 03423 { 03424 case REM_MODE_FM: 03425 saycharstr(mychannel,"FM"); 03426 break; 03427 case REM_MODE_USB: 03428 saycharstr(mychannel,"USB"); 03429 break; 03430 case REM_MODE_LSB: 03431 saycharstr(mychannel,"LSB"); 03432 break; 03433 case REM_MODE_AM: 03434 saycharstr(mychannel,"AM"); 03435 break; 03436 } 03437 wait_interval(myrpt, DLY_COMP, mychannel); 03438 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03439 break; 03440 case LOGINREQ: 03441 wait_interval(myrpt, DLY_TELEM, mychannel); 03442 sayfile(mychannel,"rpt/login"); 03443 saycharstr(mychannel,myrpt->name); 03444 break; 03445 case REMLOGIN: 03446 wait_interval(myrpt, DLY_TELEM, mychannel); 03447 saycharstr(mychannel,myrpt->loginuser); 03448 sayfile(mychannel,"rpt/node"); 03449 saycharstr(mychannel,myrpt->name); 03450 wait_interval(myrpt, DLY_COMP, mychannel); 03451 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03452 break; 03453 case REMXXX: 03454 wait_interval(myrpt, DLY_TELEM, mychannel); 03455 res = 0; 03456 switch(mytele->submode) 03457 { 03458 case 100: /* RX PL Off */ 03459 sayfile(mychannel, "rpt/rxpl"); 03460 sayfile(mychannel, "rpt/off"); 03461 break; 03462 case 101: /* RX PL On */ 03463 sayfile(mychannel, "rpt/rxpl"); 03464 sayfile(mychannel, "rpt/on"); 03465 break; 03466 case 102: /* TX PL Off */ 03467 sayfile(mychannel, "rpt/txpl"); 03468 sayfile(mychannel, "rpt/off"); 03469 break; 03470 case 103: /* TX PL On */ 03471 sayfile(mychannel, "rpt/txpl"); 03472 sayfile(mychannel, "rpt/on"); 03473 break; 03474 case 104: /* Low Power */ 03475 sayfile(mychannel, "rpt/lopwr"); 03476 break; 03477 case 105: /* Medium Power */ 03478 sayfile(mychannel, "rpt/medpwr"); 03479 break; 03480 case 106: /* Hi Power */ 03481 sayfile(mychannel, "rpt/hipwr"); 03482 break; 03483 case 113: /* Scan down slow */ 03484 sayfile(mychannel,"rpt/down"); 03485 sayfile(mychannel, "rpt/slow"); 03486 break; 03487 case 114: /* Scan down quick */ 03488 sayfile(mychannel,"rpt/down"); 03489 sayfile(mychannel, "rpt/quick"); 03490 break; 03491 case 115: /* Scan down fast */ 03492 sayfile(mychannel,"rpt/down"); 03493 sayfile(mychannel, "rpt/fast"); 03494 break; 03495 case 116: /* Scan up slow */ 03496 sayfile(mychannel,"rpt/up"); 03497 sayfile(mychannel, "rpt/slow"); 03498 break; 03499 case 117: /* Scan up quick */ 03500 sayfile(mychannel,"rpt/up"); 03501 sayfile(mychannel, "rpt/quick"); 03502 break; 03503 case 118: /* Scan up fast */ 03504 sayfile(mychannel,"rpt/up"); 03505 sayfile(mychannel, "rpt/fast"); 03506 break; 03507 default: 03508 res = -1; 03509 } 03510 wait_interval(myrpt, DLY_COMP, mychannel); 03511 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03512 break; 03513 case SCAN: 03514 ast_mutex_lock(&myrpt->remlock); 03515 if (myrpt->hfscanstop) 03516 { 03517 myrpt->hfscanstatus = 0; 03518 myrpt->hfscanmode = 0; 03519 myrpt->hfscanstop = 0; 03520 mytele->mode = SCANSTAT; 03521 ast_mutex_unlock(&myrpt->remlock); 03522 if (ast_safe_sleep(mychannel,1000) == -1) break; 03523 sayfile(mychannel, "rpt/stop"); 03524 imdone = 1; 03525 break; 03526 } 03527 if (myrpt->hfscanstatus > -2) service_scan(myrpt); 03528 i = myrpt->hfscanstatus; 03529 myrpt->hfscanstatus = 0; 03530 if (i) mytele->mode = SCANSTAT; 03531 ast_mutex_unlock(&myrpt->remlock); 03532 if (i < 0) sayfile(mychannel, "rpt/stop"); 03533 else if (i > 0) saynum(mychannel,i); 03534 imdone = 1; 03535 break; 03536 case TUNE: 03537 ast_mutex_lock(&myrpt->remlock); 03538 if (!strcmp(myrpt->remote,remote_rig_ic706)) 03539 { 03540 set_mode_ic706(myrpt, REM_MODE_AM); 03541 if(play_tone(mychannel, 800, 6000, 8192) == -1) break; 03542 ast_safe_sleep(mychannel,500); 03543 set_mode_ic706(myrpt, myrpt->remmode); 03544 myrpt->tunerequest = 0; 03545 ast_mutex_unlock(&myrpt->remlock); 03546 imdone = 1; 03547 break; 03548 } 03549 set_mode_ft897(myrpt, REM_MODE_AM); 03550 simple_command_ft897(myrpt, 8); 03551 if(play_tone(mychannel, 800, 6000, 8192) == -1) break; 03552 simple_command_ft897(myrpt, 0x88); 03553 ast_safe_sleep(mychannel,500); 03554 set_mode_ft897(myrpt, myrpt->remmode); 03555 myrpt->tunerequest = 0; 03556 ast_mutex_unlock(&myrpt->remlock); 03557 imdone = 1; 03558 break; 03559 case REMSHORTSTATUS: 03560 case REMLONGSTATUS: 03561 wait_interval(myrpt, DLY_TELEM, mychannel); 03562 res = sayfile(mychannel,"rpt/node"); 03563 if(!res) 03564 res = saycharstr(mychannel, myrpt->name); 03565 if(!res) 03566 res = sayfile(mychannel,"rpt/frequency"); 03567 if(!res) 03568 res = split_freq(mhz, decimals, myrpt->freq); 03569 if (!multimode_capable(myrpt)) decimals[3] = 0; 03570 if(!res){ 03571 m = atoi(mhz); 03572 if(m < 100) 03573 res = saynum(mychannel, m); 03574 else 03575 res = saycharstr(mychannel, mhz); 03576 } 03577 if(!res) 03578 res = sayfile(mychannel, "letters/dot"); 03579 if(!res) 03580 res = saycharstr(mychannel, decimals); 03581 03582 if(res) break; 03583 if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */ 03584 switch(myrpt->offset){ 03585 03586 case REM_MINUS: 03587 res = sayfile(mychannel,"rpt/minus"); 03588 break; 03589 03590 case REM_SIMPLEX: 03591 res = sayfile(mychannel,"rpt/simplex"); 03592 break; 03593 03594 case REM_PLUS: 03595 res = sayfile(mychannel,"rpt/plus"); 03596 break; 03597 03598 default: 03599 break; 03600 } 03601 } 03602 else{ /* Must be USB, LSB, or AM */ 03603 switch(myrpt->remmode){ 03604 03605 case REM_MODE_USB: 03606 res = saycharstr(mychannel, "USB"); 03607 break; 03608 03609 case REM_MODE_LSB: 03610 res = saycharstr(mychannel, "LSB"); 03611 break; 03612 03613 case REM_MODE_AM: 03614 res = saycharstr(mychannel, "AM"); 03615 break; 03616 03617 03618 default: 03619 break; 03620 } 03621 } 03622 03623 if (res == -1) break; 03624 03625 if(mytele->mode == REMSHORTSTATUS){ /* Short status? */ 03626 wait_interval(myrpt, DLY_COMP, mychannel); 03627 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03628 break; 03629 } 03630 03631 if (strcmp(myrpt->remote,remote_rig_ic706)) 03632 { 03633 switch(myrpt->powerlevel){ 03634 03635 case REM_LOWPWR: 03636 res = sayfile(mychannel,"rpt/lopwr") ; 03637 break; 03638 case REM_MEDPWR: 03639 res = sayfile(mychannel,"rpt/medpwr"); 03640 break; 03641 case REM_HIPWR: 03642 res = sayfile(mychannel,"rpt/hipwr"); 03643 break; 03644 } 03645 } 03646 03647 rbimode = ((!strncmp(myrpt->remote,remote_rig_rbi,3)) 03648 || (!strncmp(myrpt->remote,remote_rig_ic706,3))); 03649 if (res || (sayfile(mychannel,"rpt/rxpl") == -1)) break; 03650 if (rbimode && (sayfile(mychannel,"rpt/txpl") == -1)) break; 03651 if ((sayfile(mychannel,"rpt/frequency") == -1) || 03652 (saycharstr(mychannel,myrpt->rxpl) == -1)) break; 03653 if ((!rbimode) && ((sayfile(mychannel,"rpt/txpl") == -1) || 03654 (sayfile(mychannel,"rpt/frequency") == -1) || 03655 (saycharstr(mychannel,myrpt->txpl) == -1))) break; 03656 if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */ 03657 if ((sayfile(mychannel,"rpt/rxpl") == -1) || 03658 (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1) || 03659 (sayfile(mychannel,"rpt/txpl") == -1) || 03660 (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1)) 03661 { 03662 break; 03663 } 03664 } 03665 wait_interval(myrpt, DLY_COMP, mychannel); 03666 if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 03667 break; 03668 case STATUS: 03669 /* wait a little bit */ 03670 wait_interval(myrpt, DLY_TELEM, mychannel); 03671 hastx = 0; 03672 linkbase.next = &linkbase; 03673 linkbase.prev = &linkbase; 03674 rpt_mutex_lock(&myrpt->lock); 03675 /* make our own list of links */ 03676 l = myrpt->links.next; 03677 while(l != &myrpt->links) 03678 { 03679 if (l->name[0] == '0') 03680 { 03681 l = l->next; 03682 continue; 03683 } 03684 l1 = malloc(sizeof(struct rpt_link)); 03685 if (!l1) 03686 { 03687 ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name); 03688 remque((struct qelem *)mytele); 03689 rpt_mutex_unlock(&myrpt->lock); 03690 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 03691 free(mytele); 03692 ast_hangup(mychannel); 03693 pthread_exit(NULL); 03694 } 03695 memcpy(l1,l,sizeof(struct rpt_link)); 03696 l1->next = l1->prev = NULL; 03697 insque((struct qelem *)l1,(struct qelem *)linkbase.next); 03698 l = l->next; 03699 } 03700 rpt_mutex_unlock(&myrpt->lock); 03701 res = ast_streamfile(mychannel, "rpt/node", 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 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03708 if (!res) 03709 res = ast_waitstream(mychannel, ""); 03710 else 03711 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03712 ast_stopstream(mychannel); 03713 if (myrpt->callmode) 03714 { 03715 hastx = 1; 03716 res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language); 03717 if (!res) 03718 res = ast_waitstream(mychannel, ""); 03719 else 03720 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03721 ast_stopstream(mychannel); 03722 } 03723 l = linkbase.next; 03724 while(l != &linkbase) 03725 { 03726 char *s; 03727 03728 hastx = 1; 03729 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03730 if (!res) 03731 res = ast_waitstream(mychannel, ""); 03732 else 03733 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03734 ast_stopstream(mychannel); 03735 ast_say_character_str(mychannel,l->name,NULL,mychannel->language); 03736 if (!res) 03737 res = ast_waitstream(mychannel, ""); 03738 else 03739 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03740 ast_stopstream(mychannel); 03741 s = "rpt/tranceive"; 03742 if (!l->mode) s = "rpt/monitor"; 03743 if (!l->thisconnected) s = "rpt/connecting"; 03744 res = ast_streamfile(mychannel, s, mychannel->language); 03745 if (!res) 03746 res = ast_waitstream(mychannel, ""); 03747 else 03748 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03749 ast_stopstream(mychannel); 03750 l = l->next; 03751 } 03752 if (!hastx) 03753 { 03754 res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language); 03755 if (!res) 03756 res = ast_waitstream(mychannel, ""); 03757 else 03758 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03759 ast_stopstream(mychannel); 03760 } 03761 /* destroy our local link queue */ 03762 l = linkbase.next; 03763 while(l != &linkbase) 03764 { 03765 l1 = l; 03766 l = l->next; 03767 remque((struct qelem *)l1); 03768 free(l1); 03769 } 03770 imdone = 1; 03771 break; 03772 case FULLSTATUS: 03773 rpt_mutex_lock(&myrpt->lock); 03774 /* get all the nodes */ 03775 __mklinklist(myrpt,NULL,lbuf); 03776 rpt_mutex_unlock(&myrpt->lock); 03777 /* parse em */ 03778 ns = finddelim(lbuf,strs,MAXLINKLIST); 03779 /* sort em */ 03780 if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar); 03781 /* wait a little bit */ 03782 wait_interval(myrpt, DLY_TELEM, mychannel); 03783 hastx = 0; 03784 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03785 if (!res) 03786 res = ast_waitstream(mychannel, ""); 03787 else 03788 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03789 ast_stopstream(mychannel); 03790 ast_say_character_str(mychannel,myrpt->name,NULL,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 if (myrpt->callmode) 03797 { 03798 hastx = 1; 03799 res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language); 03800 if (!res) 03801 res = ast_waitstream(mychannel, ""); 03802 else 03803 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03804 ast_stopstream(mychannel); 03805 } 03806 /* go thru all the nodes in list */ 03807 for(i = 0; i < ns; i++) 03808 { 03809 char *s,mode = 'T'; 03810 03811 /* if a mode spec at first, handle it */ 03812 if ((*strs[i] < '0') || (*strs[i] > '9')) 03813 { 03814 mode = *strs[i]; 03815 strs[i]++; 03816 } 03817 03818 hastx = 1; 03819 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03820 if (!res) 03821 res = ast_waitstream(mychannel, ""); 03822 else 03823 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03824 ast_stopstream(mychannel); 03825 ast_say_character_str(mychannel,strs[i],NULL,mychannel->language); 03826 if (!res) 03827 res = ast_waitstream(mychannel, ""); 03828 else 03829 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03830 ast_stopstream(mychannel); 03831 s = "rpt/tranceive"; 03832 if (mode == 'R') s = "rpt/monitor"; 03833 if (mode == 'C') s = "rpt/connecting"; 03834 res = ast_streamfile(mychannel, s, mychannel->language); 03835 if (!res) 03836 res = ast_waitstream(mychannel, ""); 03837 else 03838 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03839 ast_stopstream(mychannel); 03840 } 03841 if (!hastx) 03842 { 03843 res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language); 03844 if (!res) 03845 res = ast_waitstream(mychannel, ""); 03846 else 03847 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03848 ast_stopstream(mychannel); 03849 } 03850 imdone = 1; 03851 break; 03852 03853 case LASTNODEKEY: /* Identify last node which keyed us up */ 03854 rpt_mutex_lock(&myrpt->lock); 03855 if(myrpt->lastnodewhichkeyedusup) 03856 p = ast_strdupa(myrpt->lastnodewhichkeyedusup); /* Make a local copy of the node name */ 03857 else 03858 p = NULL; 03859 rpt_mutex_unlock(&myrpt->lock); 03860 if(!p){ 03861 imdone = 1; /* no node previously keyed us up, or the node which did has been disconnected */ 03862 break; 03863 } 03864 wait_interval(myrpt, DLY_TELEM, mychannel); 03865 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03866 if (!res) 03867 res = ast_waitstream(mychannel, ""); 03868 else 03869 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03870 ast_stopstream(mychannel); 03871 ast_say_character_str(mychannel, p, NULL, mychannel->language); 03872 if (!res) 03873 res = ast_waitstream(mychannel, ""); 03874 else 03875 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03876 ast_stopstream(mychannel); 03877 imdone = 1; 03878 break; 03879 03880 case UNAUTHTX: /* Say unauthorized transmit frequency */ 03881 wait_interval(myrpt, DLY_TELEM, mychannel); 03882 res = ast_streamfile(mychannel, "rpt/unauthtx", mychannel->language); 03883 if (!res) 03884 res = ast_waitstream(mychannel, ""); 03885 else 03886 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03887 ast_stopstream(mychannel); 03888 imdone = 1; 03889 break; 03890 03891 03892 case TIMEOUT: 03893 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03894 if (!res) 03895 res = ast_waitstream(mychannel, ""); 03896 else 03897 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03898 ast_stopstream(mychannel); 03899 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03900 res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language); 03901 break; 03902 03903 case TIMEOUT_WARNING: 03904 time(&t); 03905 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03906 if (!res) 03907 res = ast_waitstream(mychannel, ""); 03908 else 03909 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03910 ast_stopstream(mychannel); 03911 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03912 res = ast_streamfile(mychannel, "rpt/timeout-warning", mychannel->language); 03913 if (!res) 03914 res = ast_waitstream(mychannel, ""); 03915 else 03916 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03917 ast_stopstream(mychannel); 03918 if(!res) /* Say number of seconds */ 03919 ast_say_number(mychannel, myrpt->p.remotetimeout - 03920 (t - myrpt->last_activity_time), 03921 "", mychannel->language, (char *) NULL); 03922 if (!res) 03923 res = ast_waitstream(mychannel, ""); 03924 ast_stopstream(mychannel); 03925 res = ast_streamfile(mychannel, "queue-seconds", mychannel->language); 03926 break; 03927 03928 case ACT_TIMEOUT_WARNING: 03929 time(&t); 03930 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 03931 if (!res) 03932 res = ast_waitstream(mychannel, ""); 03933 else 03934 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03935 ast_stopstream(mychannel); 03936 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 03937 res = ast_streamfile(mychannel, "rpt/act-timeout-warning", mychannel->language); 03938 if (!res) 03939 res = ast_waitstream(mychannel, ""); 03940 else 03941 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 03942 ast_stopstream(mychannel); 03943 if(!res) /* Say number of seconds */ 03944 ast_say_number(mychannel, myrpt->p.remoteinacttimeout - 03945 (t - myrpt->last_activity_time), 03946 "", mychannel->language, (char *) NULL); 03947 if (!res) 03948 res = ast_waitstream(mychannel, ""); 03949 ast_stopstream(mychannel); 03950 res = ast_streamfile(mychannel, "queue-seconds", mychannel->language); 03951 break; 03952 03953 case STATS_TIME: 03954 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 03955 t = time(NULL); 03956 rpt_localtime(&t, &localtm); 03957 /* Say the phase of the day is before the time */ 03958 if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12)) 03959 p = "rpt/goodmorning"; 03960 else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18)) 03961 p = "rpt/goodafternoon"; 03962 else 03963 p = "rpt/goodevening"; 03964 if (sayfile(mychannel,p) == -1) 03965 { 03966 imdone = 1; 03967 break; 03968 } 03969 /* Say the time is ... */ 03970 if (sayfile(mychannel,"rpt/thetimeis") == -1) 03971 { 03972 imdone = 1; 03973 break; 03974 } 03975 /* Say the time */ 03976 res = ast_say_time(mychannel, t, "", mychannel->language); 03977 if (!res) 03978 res = ast_waitstream(mychannel, ""); 03979 ast_stopstream(mychannel); 03980 imdone = 1; 03981 break; 03982 case STATS_VERSION: 03983 p = strstr(tdesc, "version"); 03984 if(!p) 03985 break; 03986 if(sscanf(p, "version %30d.%30d", &vmajor, &vminor) != 2) 03987 break; 03988 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 03989 /* Say "version" */ 03990 if (sayfile(mychannel,"rpt/version") == -1) 03991 { 03992 imdone = 1; 03993 break; 03994 } 03995 if(!res) /* Say "X" */ 03996 ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL); 03997 if (!res) 03998 res = ast_waitstream(mychannel, ""); 03999 ast_stopstream(mychannel); 04000 if (saycharstr(mychannel,".") == -1) 04001 { 04002 imdone = 1; 04003 break; 04004 } 04005 if(!res) /* Say "Y" */ 04006 ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL); 04007 if (!res){ 04008 res = ast_waitstream(mychannel, ""); 04009 ast_stopstream(mychannel); 04010 } 04011 else 04012 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 04013 imdone = 1; 04014 break; 04015 case ARB_ALPHA: 04016 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 04017 if(mytele->param) 04018 saycharstr(mychannel, mytele->param); 04019 imdone = 1; 04020 break; 04021 case REV_PATCH: 04022 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 04023 if(mytele->param) { 04024 04025 /* Parts of this section taken from app_parkandannounce */ 04026 char *tpl_working, *tpl_current; 04027 char *tmp[100], *myparm; 04028 int looptemp=0,i=0, dres = 0; 04029 04030 04031 tpl_working = strdupa(mytele->param); 04032 myparm = strsep(&tpl_working,","); 04033 tpl_current=strsep(&tpl_working, ":"); 04034 04035 while(tpl_current && looptemp < sizeof(tmp)) { 04036 tmp[looptemp]=tpl_current; 04037 looptemp++; 04038 tpl_current=strsep(&tpl_working,":"); 04039 } 04040 04041 for(i=0; i<looptemp; i++) { 04042 if(!strcmp(tmp[i], "PARKED")) { 04043 ast_say_digits(mychannel, atoi(myparm), "", mychannel->language); 04044 } else if(!strcmp(tmp[i], "NODE")) { 04045 ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language); 04046 } else { 04047 dres = ast_streamfile(mychannel, tmp[i], mychannel->language); 04048 if(!dres) { 04049 dres = ast_waitstream(mychannel, ""); 04050 } else { 04051 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name); 04052 dres = 0; 04053 } 04054 } 04055 } 04056 } 04057 imdone = 1; 04058 break; 04059 case TEST_TONE: 04060 imdone = 1; 04061 if (myrpt->stopgen) break; 04062 myrpt->stopgen = -1; 04063 if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0))) 04064 { 04065 myrpt->stopgen = 0; 04066 break; 04067 } 04068 while(mychannel->generatordata && (myrpt->stopgen <= 0)) { 04069 if (ast_safe_sleep(mychannel,1)) break; 04070 imdone = 1; 04071 } 04072 myrpt->stopgen = 0; 04073 break; 04074 default: 04075 break; 04076 } 04077 if (!imdone) 04078 { 04079 if (!res) 04080 res = ast_waitstream(mychannel, ""); 04081 else { 04082 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 04083 res = 0; 04084 } 04085 } 04086 ast_stopstream(mychannel); 04087 rpt_mutex_lock(&myrpt->lock); 04088 if (mytele->mode == TAILMSG) 04089 { 04090 if (!res) 04091 { 04092 myrpt->tailmessagen++; 04093 if(myrpt->tailmessagen >= myrpt->p.tailmessagemax) myrpt->tailmessagen = 0; 04094 } 04095 else 04096 { 04097 myrpt->tmsgtimer = myrpt->p.tailsquashedtime; 04098 } 04099 } 04100 remque((struct qelem *)mytele); 04101 rpt_mutex_unlock(&myrpt->lock); 04102 free(mytele); 04103 ast_hangup(mychannel); 04104 #ifdef APP_RPT_LOCK_DEBUG 04105 { 04106 struct lockthread *t; 04107 04108 sleep(5); 04109 ast_mutex_lock(&locklock); 04110 t = get_lockthread(pthread_self()); 04111 if (t) memset(t,0,sizeof(struct lockthread)); 04112 ast_mutex_unlock(&locklock); 04113 } 04114 #endif 04115 pthread_exit(NULL); 04116 }
static void rpt_telemetry | ( | struct rpt * | myrpt, | |
int | mode, | |||
void * | data | |||
) | [static] |
Definition at line 4118 of file app_rpt.c.
References ARB_ALPHA, ast_log(), ast_pthread_create, CONNECTED, CONNFAIL, LINKUNKEY, rpt::lock, LOG_WARNING, malloc, rpt_tele::next, REMDISC, REMXXX, REV_PATCH, rpt_mutex_lock, rpt_mutex_unlock, rpt_tele_thread(), rpt::tele, and TELEPARAMSIZE.
Referenced by function_autopatchdn(), function_cop(), function_ilink(), function_macro(), function_remote(), function_status(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_data(), handle_remote_phone_dtmf(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), setrem(), and stop_scan().
04119 { 04120 struct rpt_tele *tele; 04121 struct rpt_link *mylink = (struct rpt_link *) data; 04122 int res; 04123 pthread_attr_t attr; 04124 04125 tele = malloc(sizeof(struct rpt_tele)); 04126 if (!tele) 04127 { 04128 ast_log(LOG_WARNING, "Unable to allocate memory\n"); 04129 pthread_exit(NULL); 04130 return; 04131 } 04132 /* zero it out */ 04133 memset((char *)tele,0,sizeof(struct rpt_tele)); 04134 tele->rpt = myrpt; 04135 tele->mode = mode; 04136 rpt_mutex_lock(&myrpt->lock); 04137 if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED) || 04138 (mode == LINKUNKEY)){ 04139 memset(&tele->mylink,0,sizeof(struct rpt_link)); 04140 if (mylink){ 04141 memcpy(&tele->mylink,mylink,sizeof(struct rpt_link)); 04142 } 04143 } 04144 else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) { 04145 strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1); 04146 tele->param[TELEPARAMSIZE - 1] = 0; 04147 } 04148 if (mode == REMXXX) tele->submode = (intptr_t) data; 04149 insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next); 04150 rpt_mutex_unlock(&myrpt->lock); 04151 pthread_attr_init(&attr); 04152 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 04153 res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele); 04154 if(res < 0){ 04155 rpt_mutex_lock(&myrpt->lock); 04156 remque((struct qlem *) tele); /* We don't like stuck transmitters, remove it from the queue */ 04157 rpt_mutex_unlock(&myrpt->lock); 04158 ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res)); 04159 } 04160 return; 04161 }
static int saycharstr | ( | struct ast_channel * | mychannel, | |
char * | str | |||
) | [static] |
Definition at line 2689 of file app_rpt.c.
References ast_log(), ast_say_character_str(), ast_stopstream(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.
Referenced by rpt_tele_thread().
02690 { 02691 int res; 02692 02693 res = ast_say_character_str(mychannel,str,NULL,mychannel->language); 02694 if (!res) 02695 res = ast_waitstream(mychannel, ""); 02696 else 02697 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02698 ast_stopstream(mychannel); 02699 return res; 02700 }
static int sayfile | ( | struct ast_channel * | mychannel, | |
char * | fname | |||
) | [static] |
Definition at line 2676 of file app_rpt.c.
References ast_log(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.
Referenced by rpt_tele_thread(), and telem_any().
02677 { 02678 int res; 02679 02680 res = ast_streamfile(mychannel, fname, mychannel->language); 02681 if (!res) 02682 res = ast_waitstream(mychannel, ""); 02683 else 02684 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02685 ast_stopstream(mychannel); 02686 return res; 02687 }
static int saynum | ( | struct ast_channel * | mychannel, | |
int | num | |||
) | [static] |
Definition at line 2702 of file app_rpt.c.
References ast_log(), ast_say_number(), ast_stopstream(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.
Referenced by rpt_tele_thread().
02703 { 02704 int res; 02705 res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL); 02706 if(!res) 02707 res = ast_waitstream(mychannel, ""); 02708 else 02709 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02710 ast_stopstream(mychannel); 02711 return res; 02712 }
static int select_mem_ic706 | ( | struct rpt * | myrpt, | |
int | slot | |||
) | [static] |
Definition at line 7210 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07211 { 07212 unsigned char cmdstr[10]; 07213 07214 cmdstr[0] = cmdstr[1] = 0xfe; 07215 cmdstr[2] = myrpt->p.civaddr; 07216 cmdstr[3] = 0xe0; 07217 cmdstr[4] = 8; 07218 cmdstr[5] = 0; 07219 cmdstr[6] = ((slot / 10) << 4) + (slot % 10); 07220 cmdstr[7] = 0xfd; 07221 07222 return(civ_cmd(myrpt,cmdstr,8)); 07223 }
static void send_link_dtmf | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 4415 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().
04416 { 04417 char str[300]; 04418 struct ast_frame wf; 04419 struct rpt_link *l; 04420 04421 snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c); 04422 wf.frametype = AST_FRAME_TEXT; 04423 wf.subclass = 0; 04424 wf.offset = 0; 04425 wf.mallocd = 0; 04426 wf.datalen = strlen(str) + 1; 04427 wf.samples = 0; 04428 l = myrpt->links.next; 04429 /* first, see if our dude is there */ 04430 while(l != &myrpt->links) 04431 { 04432 if (l->name[0] == '0') 04433 { 04434 l = l->next; 04435 continue; 04436 } 04437 /* if we found it, write it and were done */ 04438 if (!strcmp(l->name,myrpt->cmdnode)) 04439 { 04440 wf.data = str; 04441 if (l->chan) ast_write(l->chan,&wf); 04442 return; 04443 } 04444 l = l->next; 04445 } 04446 l = myrpt->links.next; 04447 /* if not, give it to everyone */ 04448 while(l != &myrpt->links) 04449 { 04450 wf.data = str; 04451 if (l->chan) ast_write(l->chan,&wf); 04452 l = l->next; 04453 } 04454 return; 04455 }
static int send_morse | ( | struct ast_channel * | chan, | |
char * | string, | |||
int | speed, | |||
int | freq, | |||
int | amplitude | |||
) | [static] |
Definition at line 2463 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().
02464 { 02465 02466 static struct morse_bits mbits[] = { 02467 {0, 0}, /* SPACE */ 02468 {0, 0}, 02469 {6, 18},/* " */ 02470 {0, 0}, 02471 {7, 72},/* $ */ 02472 {0, 0}, 02473 {0, 0}, 02474 {6, 30},/* ' */ 02475 {5, 13},/* ( */ 02476 {6, 29},/* ) */ 02477 {0, 0}, 02478 {5, 10},/* + */ 02479 {6, 51},/* , */ 02480 {6, 33},/* - */ 02481 {6, 42},/* . */ 02482 {5, 9}, /* / */ 02483 {5, 31},/* 0 */ 02484 {5, 30},/* 1 */ 02485 {5, 28},/* 2 */ 02486 {5, 24},/* 3 */ 02487 {5, 16},/* 4 */ 02488 {5, 0}, /* 5 */ 02489 {5, 1}, /* 6 */ 02490 {5, 3}, /* 7 */ 02491 {5, 7}, /* 8 */ 02492 {5, 15},/* 9 */ 02493 {6, 7}, /* : */ 02494 {6, 21},/* ; */ 02495 {0, 0}, 02496 {5, 33},/* = */ 02497 {0, 0}, 02498 {6, 12},/* ? */ 02499 {0, 0}, 02500 {2, 2}, /* A */ 02501 {4, 1}, /* B */ 02502 {4, 5}, /* C */ 02503 {3, 1}, /* D */ 02504 {1, 0}, /* E */ 02505 {4, 4}, /* F */ 02506 {3, 3}, /* G */ 02507 {4, 0}, /* H */ 02508 {2, 0}, /* I */ 02509 {4, 14},/* J */ 02510 {3, 5}, /* K */ 02511 {4, 2}, /* L */ 02512 {2, 3}, /* M */ 02513 {2, 1}, /* N */ 02514 {3, 7}, /* O */ 02515 {4, 6}, /* P */ 02516 {4, 11},/* Q */ 02517 {3, 2}, /* R */ 02518 {3, 0}, /* S */ 02519 {1, 1}, /* T */ 02520 {3, 4}, /* U */ 02521 {4, 8}, /* V */ 02522 {3, 6}, /* W */ 02523 {4, 9}, /* X */ 02524 {4, 13},/* Y */ 02525 {4, 3} /* Z */ 02526 }; 02527 02528 02529 int dottime; 02530 int dashtime; 02531 int intralettertime; 02532 int interlettertime; 02533 int interwordtime; 02534 int len, ddcomb; 02535 int res; 02536 int c; 02537 int i; 02538 int flags; 02539 02540 res = 0; 02541 02542 /* Approximate the dot time from the speed arg. */ 02543 02544 dottime = 900/speed; 02545 02546 /* Establish timing releationships */ 02547 02548 dashtime = 3 * dottime; 02549 intralettertime = dottime; 02550 interlettertime = dottime * 4 ; 02551 interwordtime = dottime * 7; 02552 02553 for(;(*string) && (!res); string++){ 02554 02555 c = *string; 02556 02557 /* Convert lower case to upper case */ 02558 02559 if((c >= 'a') && (c <= 'z')) 02560 c -= 0x20; 02561 02562 /* Can't deal with any char code greater than Z, skip it */ 02563 02564 if(c > 'Z') 02565 continue; 02566 02567 /* If space char, wait the inter word time */ 02568 02569 if(c == ' '){ 02570 if(!res) 02571 res = play_silence(chan, interwordtime); 02572 continue; 02573 } 02574 02575 /* Subtract out control char offset to match our table */ 02576 02577 c -= 0x20; 02578 02579 /* Get the character data */ 02580 02581 len = mbits[c].len; 02582 ddcomb = mbits[c].ddcomb; 02583 02584 /* Send the character */ 02585 02586 for(; len ; len--){ 02587 if(!res) 02588 res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude); 02589 if(!res) 02590 res = play_silence(chan, intralettertime); 02591 ddcomb >>= 1; 02592 } 02593 02594 /* Wait the interletter time */ 02595 02596 if(!res) 02597 res = play_silence(chan, interlettertime - intralettertime); 02598 } 02599 02600 /* Wait for all the frames to be sent */ 02601 02602 if (!res) 02603 res = ast_waitstream(chan, ""); 02604 ast_stopstream(chan); 02605 02606 /* 02607 * Wait for the zaptel driver to physically write the tone blocks to the hardware 02608 */ 02609 02610 for(i = 0; i < 20 ; i++){ 02611 flags = DAHDI_IOMUX_WRITEEMPTY | DAHDI_IOMUX_NOWAIT; 02612 res = ioctl(chan->fds[0], DAHDI_IOMUX, &flags); 02613 if(flags & DAHDI_IOMUX_WRITEEMPTY) 02614 break; 02615 if( ast_safe_sleep(chan, 50)){ 02616 res = -1; 02617 break; 02618 } 02619 } 02620 02621 02622 return res; 02623 }
static int send_tone_telemetry | ( | struct ast_channel * | chan, | |
char * | tonestring | |||
) | [static] |
Definition at line 2625 of file app_rpt.c.
References ast_safe_sleep(), ast_stopstream(), ast_strdupa, ast_waitstream(), ast_channel::fds, and play_tone_pair().
Referenced by telem_any().
02626 { 02627 char *stringp; 02628 char *tonesubset; 02629 int f1,f2; 02630 int duration; 02631 int amplitude; 02632 int res; 02633 int i; 02634 int flags; 02635 02636 res = 0; 02637 02638 stringp = ast_strdupa(tonestring); 02639 02640 for(;tonestring;){ 02641 tonesubset = strsep(&stringp,")"); 02642 if(!tonesubset) 02643 break; 02644 if(sscanf(tonesubset,"(%30d,%30d,%30d,%30d", &f1, &f2, &duration, &litude) != 4) 02645 break; 02646 res = play_tone_pair(chan, f1, f2, duration, amplitude); 02647 if(res) 02648 break; 02649 } 02650 if(!res) 02651 res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */ 02652 02653 if (!res) 02654 res = ast_waitstream(chan, ""); 02655 ast_stopstream(chan); 02656 02657 /* 02658 * Wait for the zaptel driver to physically write the tone blocks to the hardware 02659 */ 02660 02661 for(i = 0; i < 20 ; i++){ 02662 flags = DAHDI_IOMUX_WRITEEMPTY | DAHDI_IOMUX_NOWAIT; 02663 res = ioctl(chan->fds[0], DAHDI_IOMUX, &flags); 02664 if(flags & DAHDI_IOMUX_WRITEEMPTY) 02665 break; 02666 if( ast_safe_sleep(chan, 50)){ 02667 res = -1; 02668 break; 02669 } 02670 } 02671 02672 return res; 02673 02674 }
static int sendkenwood | ( | struct rpt * | myrpt, | |
char * | txstr, | |||
char * | rxstr | |||
) | [static] |
Definition at line 5981 of file app_rpt.c.
References serial_remote_io().
Referenced by sendrxkenwood().
05982 { 05983 int i; 05984 05985 if (debug) printf("Send to kenwood: %s\n",txstr); 05986 i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr), 05987 (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3); 05988 if (i < 0) return -1; 05989 if ((i > 0) && (rxstr[i - 1] == '\r')) 05990 rxstr[i-- - 1] = 0; 05991 if (debug) printf("Got from kenwood: %s\n",rxstr); 05992 return(i); 05993 }
static int sendrxkenwood | ( | struct rpt * | myrpt, | |
char * | txstr, | |||
char * | rxstr, | |||
char * | cmpstr | |||
) | [static] |
Definition at line 6087 of file app_rpt.c.
References KENWOOD_RETRIES, and sendkenwood().
Referenced by setkenwood().
06089 { 06090 int i,j; 06091 06092 for(i = 0;i < KENWOOD_RETRIES;i++) 06093 { 06094 j = sendkenwood(myrpt,txstr,rxstr); 06095 if (j < 0) return(j); 06096 if (j == 0) continue; 06097 if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0); 06098 } 06099 return(-1); 06100 }
static int serial_remote_io | ( | struct rpt * | myrpt, | |
unsigned char * | txbuf, | |||
int | txbytes, | |||
unsigned char * | rxbuf, | |||
int | rxmaxbytes, | |||
int | asciiflag | |||
) | [static] |
Definition at line 5878 of file app_rpt.c.
References ast_channel::fds, rpt::iofd, rpt::rxchannel, and rpt::zaprxchannel.
Referenced by civ_cmd(), multimode_bump_freq_ic706(), sendkenwood(), set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), and simple_command_ft897().
05880 { 05881 int i,j,index,oldmode,olddata; 05882 struct dahdi_radio_param prm; 05883 char c; 05884 05885 if(debug){ 05886 printf("String output was: "); 05887 for(i = 0; i < txbytes; i++) 05888 printf("%02X ", (unsigned char ) txbuf[i]); 05889 printf("\n"); 05890 } 05891 if (myrpt->iofd > 0) /* if to do out a serial port */ 05892 { 05893 if (rxmaxbytes && rxbuf) tcflush(myrpt->iofd,TCIFLUSH); 05894 if (write(myrpt->iofd,txbuf,txbytes) != txbytes) return -1; 05895 if ((!rxmaxbytes) || (rxbuf == NULL)) return(0); 05896 memset(rxbuf,0,rxmaxbytes); 05897 for(i = 0; i < rxmaxbytes; i++) 05898 { 05899 j = read(myrpt->iofd,&c,1); 05900 if (j < 1) return(i); 05901 rxbuf[i] = c; 05902 if (asciiflag & 1) 05903 { 05904 rxbuf[i + 1] = 0; 05905 if (c == '\r') break; 05906 } 05907 } 05908 if(debug){ 05909 printf("String returned was: "); 05910 for(j = 0; j < i; j++) 05911 printf("%02X ", (unsigned char ) rxbuf[j]); 05912 printf("\n"); 05913 } 05914 return(i); 05915 } 05916 05917 /* if not a zap channel, cant use pciradio stuff */ 05918 if (myrpt->rxchannel != myrpt->zaprxchannel) return -1; 05919 05920 prm.radpar = DAHDI_RADPAR_UIOMODE; 05921 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_GETPARAM,&prm) == -1) return -1; 05922 oldmode = prm.data; 05923 prm.radpar = DAHDI_RADPAR_UIODATA; 05924 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_GETPARAM,&prm) == -1) return -1; 05925 olddata = prm.data; 05926 prm.radpar = DAHDI_RADPAR_REMMODE; 05927 if (asciiflag & 1) prm.data = DAHDI_RADPAR_REM_SERIAL_ASCII; 05928 else prm.data = DAHDI_RADPAR_REM_SERIAL; 05929 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1; 05930 if (asciiflag & 2) 05931 { 05932 i = DAHDI_ONHOOK; 05933 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_HOOK,&i) == -1) return -1; 05934 usleep(100000); 05935 } 05936 prm.radpar = DAHDI_RADPAR_REMCOMMAND; 05937 prm.data = rxmaxbytes; 05938 memcpy(prm.buf,txbuf,txbytes); 05939 prm.index = txbytes; 05940 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1; 05941 if (rxbuf) 05942 { 05943 *rxbuf = 0; 05944 memcpy(rxbuf,prm.buf,prm.index); 05945 } 05946 index = prm.index; 05947 prm.radpar = DAHDI_RADPAR_REMMODE; 05948 prm.data = DAHDI_RADPAR_REM_NONE; 05949 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1; 05950 if (asciiflag & 2) 05951 { 05952 i = DAHDI_OFFHOOK; 05953 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_HOOK,&i) == -1) return -1; 05954 } 05955 prm.radpar = DAHDI_RADPAR_UIOMODE; 05956 prm.data = oldmode; 05957 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1; 05958 prm.radpar = DAHDI_RADPAR_UIODATA; 05959 prm.data = olddata; 05960 if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1; 05961 return(index); 05962 }
static int service_scan | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7586 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().
07587 { 07588 int res, interval; 07589 char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0; 07590 07591 switch(myrpt->hfscanmode){ 07592 07593 case HF_SCAN_DOWN_SLOW: 07594 interval = -10; /* 100Hz /sec */ 07595 break; 07596 07597 case HF_SCAN_DOWN_QUICK: 07598 interval = -50; /* 500Hz /sec */ 07599 break; 07600 07601 case HF_SCAN_DOWN_FAST: 07602 interval = -200; /* 2KHz /sec */ 07603 break; 07604 07605 case HF_SCAN_UP_SLOW: 07606 interval = 10; /* 100Hz /sec */ 07607 break; 07608 07609 case HF_SCAN_UP_QUICK: 07610 interval = 50; /* 500 Hz/sec */ 07611 break; 07612 07613 case HF_SCAN_UP_FAST: 07614 interval = 200; /* 2KHz /sec */ 07615 break; 07616 07617 default: 07618 myrpt->hfscanmode = 0; /* Huh? */ 07619 return -1; 07620 } 07621 07622 res = split_freq(mhz, decimals, myrpt->freq); 07623 07624 if(!res){ 07625 k100 =decimals[0]; 07626 k10 = decimals[1]; 07627 res = multimode_bump_freq(myrpt, interval); 07628 } 07629 07630 if(!res) 07631 res = split_freq(mhz, decimals, myrpt->freq); 07632 07633 07634 if(res){ 07635 myrpt->hfscanmode = 0; 07636 myrpt->hfscanstatus = -2; 07637 return -1; 07638 } 07639 07640 /* Announce 10KHz boundaries */ 07641 if(k10 != decimals[1]){ 07642 int myhund = (interval < 0) ? k100 : decimals[0]; 07643 int myten = (interval < 0) ? k10 : decimals[1]; 07644 myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10; 07645 } else myrpt->hfscanstatus = 0; 07646 return res; 07647 07648 }
static int set_ctcss_freq_ft897 | ( | struct rpt * | myrpt, | |
char * | txtone, | |||
char * | rxtone | |||
) | [static] |
Definition at line 6646 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_ctcss_freq().
Referenced by set_ft897().
06647 { 06648 unsigned char cmdstr[5]; 06649 char hertz[MAXREMSTR],decimal[MAXREMSTR]; 06650 int h,d; 06651 06652 memset(cmdstr, 0, 5); 06653 06654 if(split_ctcss_freq(hertz, decimal, txtone)) 06655 return -1; 06656 06657 h = atoi(hertz); 06658 d = atoi(decimal); 06659 06660 cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10; 06661 cmdstr[1] = ((h % 10) << 4) + (d % 10); 06662 06663 if(rxtone){ 06664 06665 if(split_ctcss_freq(hertz, decimal, rxtone)) 06666 return -1; 06667 06668 h = atoi(hertz); 06669 d = atoi(decimal); 06670 06671 cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10; 06672 cmdstr[3] = ((h % 10) << 4) + (d % 10); 06673 } 06674 cmdstr[4] = 0x0B; 06675 06676 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06677 }
static int set_ctcss_mode_ft897 | ( | struct rpt * | myrpt, | |
char | txplon, | |||
char | rxplon | |||
) | [static] |
Definition at line 6623 of file app_rpt.c.
References serial_remote_io().
Referenced by set_ft897().
06624 { 06625 unsigned char cmdstr[5]; 06626 06627 memset(cmdstr, 0, 5); 06628 06629 if(rxplon && txplon) 06630 cmdstr[0] = 0x2A; /* Encode and Decode */ 06631 else if (!rxplon && txplon) 06632 cmdstr[0] = 0x4A; /* Encode only */ 06633 else if (rxplon && !txplon) 06634 cmdstr[0] = 0x3A; /* Encode only */ 06635 else 06636 cmdstr[0] = 0x8A; /* OFF */ 06637 06638 cmdstr[4] = 0x0A; 06639 06640 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06641 }
static int set_ctcss_mode_ic706 | ( | struct rpt * | myrpt, | |
char | txplon, | |||
char | rxplon | |||
) | [static] |
Definition at line 7108 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07109 { 07110 unsigned char cmdstr[10]; 07111 int rv; 07112 07113 cmdstr[0] = cmdstr[1] = 0xfe; 07114 cmdstr[2] = myrpt->p.civaddr; 07115 cmdstr[3] = 0xe0; 07116 cmdstr[4] = 0x16; 07117 cmdstr[5] = 0x42; 07118 cmdstr[6] = (txplon != 0); 07119 cmdstr[7] = 0xfd; 07120 07121 rv = civ_cmd(myrpt,cmdstr,8); 07122 if (rv) return(-1); 07123 07124 cmdstr[0] = cmdstr[1] = 0xfe; 07125 cmdstr[2] = myrpt->p.civaddr; 07126 cmdstr[3] = 0xe0; 07127 cmdstr[4] = 0x16; 07128 cmdstr[5] = 0x43; 07129 cmdstr[6] = (rxplon != 0); 07130 cmdstr[7] = 0xfd; 07131 07132 return(civ_cmd(myrpt,cmdstr,8)); 07133 }
static int set_freq_ft897 | ( | struct rpt * | myrpt, | |
char * | newfreq | |||
) | [static] |
Definition at line 6515 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_freq().
Referenced by multimode_bump_freq_ft897(), and set_ft897().
06516 { 06517 unsigned char cmdstr[5]; 06518 int fd,m,d; 06519 char mhz[MAXREMSTR]; 06520 char decimals[MAXREMSTR]; 06521 06522 fd = 0; 06523 if(debug) 06524 printf("New frequency: %s\n",newfreq); 06525 06526 if(split_freq(mhz, decimals, newfreq)) 06527 return -1; 06528 06529 m = atoi(mhz); 06530 d = atoi(decimals); 06531 06532 /* The FT-897 likes packed BCD frequencies */ 06533 06534 cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10); /* 100MHz 10Mhz */ 06535 cmdstr[1] = ((m % 10) << 4) + (d / 10000); /* 1MHz 100KHz */ 06536 cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100); /* 10KHz 1KHz */ 06537 cmdstr[3] = (((d % 100)/10) << 4) + (d % 10); /* 100Hz 10Hz */ 06538 cmdstr[4] = 0x01; /* command */ 06539 06540 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06541 06542 }
static int set_freq_ic706 | ( | struct rpt * | myrpt, | |
char * | newfreq | |||
) | [static] |
Definition at line 7018 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, MAXREMSTR, rpt::p, and split_freq().
Referenced by set_ic706().
07019 { 07020 unsigned char cmdstr[20]; 07021 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 07022 int fd,m,d; 07023 07024 fd = 0; 07025 if(debug) 07026 printf("New frequency: %s\n",newfreq); 07027 07028 if(split_freq(mhz, decimals, newfreq)) 07029 return -1; 07030 07031 m = atoi(mhz); 07032 d = atoi(decimals); 07033 07034 /* The ic-706 likes packed BCD frequencies */ 07035 07036 cmdstr[0] = cmdstr[1] = 0xfe; 07037 cmdstr[2] = myrpt->p.civaddr; 07038 cmdstr[3] = 0xe0; 07039 cmdstr[4] = 5; 07040 cmdstr[5] = ((d % 10) << 4); 07041 cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10); 07042 cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000); 07043 cmdstr[8] = (((m % 100)/10) << 4) + (m % 10); 07044 cmdstr[9] = (m / 100); 07045 cmdstr[10] = 0xfd; 07046 07047 return(civ_cmd(myrpt,cmdstr,11)); 07048 }
static int set_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6681 of file app_rpt.c.
References REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, rpt::remmode, set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), and simple_command_ft897().
Referenced by rpt_tele_thread().
06682 { 06683 int res; 06684 06685 if(debug) 06686 printf("@@@@ lock on\n"); 06687 06688 res = simple_command_ft897(myrpt, 0x00); /* LOCK on */ 06689 06690 if(debug) 06691 printf("@@@@ ptt off\n"); 06692 06693 if(!res) 06694 res = simple_command_ft897(myrpt, 0x88); /* PTT off */ 06695 06696 if(debug) 06697 printf("Modulation mode\n"); 06698 06699 if(!res) 06700 res = set_mode_ft897(myrpt, myrpt->remmode); /* Modulation mode */ 06701 06702 if(debug) 06703 printf("Split off\n"); 06704 06705 if(!res) 06706 simple_command_ft897(myrpt, 0x82); /* Split off */ 06707 06708 if(debug) 06709 printf("Frequency\n"); 06710 06711 if(!res) 06712 res = set_freq_ft897(myrpt, myrpt->freq); /* Frequency */ 06713 if((myrpt->remmode == REM_MODE_FM)){ 06714 if(debug) 06715 printf("Offset\n"); 06716 if(!res) 06717 res = set_offset_ft897(myrpt, myrpt->offset); /* Offset if FM */ 06718 if((!res)&&(myrpt->rxplon || myrpt->txplon)){ 06719 if(debug) 06720 printf("CTCSS tone freqs.\n"); 06721 res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */ 06722 } 06723 if(!res){ 06724 if(debug) 06725 printf("CTCSS mode\n"); 06726 res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */ 06727 } 06728 } 06729 if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){ 06730 if(debug) 06731 printf("Clarifier off\n"); 06732 simple_command_ft897(myrpt, 0x85); /* Clarifier off if LSB or USB */ 06733 } 06734 return res; 06735 }
static int set_ic706 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7225 of file app_rpt.c.
References IC706_PL_MEMORY_OFFSET, ic706_pltocode(), mem2vfo_ic706(), REM_MODE_FM, rpt::remmode, rpt::rxpl, select_mem_ic706(), set_ctcss_mode_ic706(), set_freq_ic706(), set_mode_ic706(), set_offset_ic706(), simple_command_ic706(), and vfo_ic706().
Referenced by rpt_tele_thread().
07226 { 07227 int res = 0,i; 07228 07229 if(debug) 07230 printf("Set to VFO A\n"); 07231 07232 if (!res) 07233 res = simple_command_ic706(myrpt,7,0); 07234 07235 07236 if((myrpt->remmode == REM_MODE_FM)) 07237 { 07238 i = ic706_pltocode(myrpt->rxpl); 07239 if (i == -1) return -1; 07240 if(debug) 07241 printf("Select memory number\n"); 07242 if (!res) 07243 res = select_mem_ic706(myrpt,i + IC706_PL_MEMORY_OFFSET); 07244 if(debug) 07245 printf("Transfer memory to VFO\n"); 07246 if (!res) 07247 res = mem2vfo_ic706(myrpt); 07248 } 07249 07250 if(debug) 07251 printf("Set to VFO\n"); 07252 07253 if (!res) 07254 res = vfo_ic706(myrpt); 07255 07256 if(debug) 07257 printf("Modulation mode\n"); 07258 07259 if (!res) 07260 res = set_mode_ic706(myrpt, myrpt->remmode); /* Modulation mode */ 07261 07262 if(debug) 07263 printf("Split off\n"); 07264 07265 if(!res) 07266 simple_command_ic706(myrpt, 0x82,0); /* Split off */ 07267 07268 if(debug) 07269 printf("Frequency\n"); 07270 07271 if(!res) 07272 res = set_freq_ic706(myrpt, myrpt->freq); /* Frequency */ 07273 if((myrpt->remmode == REM_MODE_FM)){ 07274 if(debug) 07275 printf("Offset\n"); 07276 if(!res) 07277 res = set_offset_ic706(myrpt, myrpt->offset); /* Offset if FM */ 07278 if(!res){ 07279 if(debug) 07280 printf("CTCSS mode\n"); 07281 res = set_ctcss_mode_ic706(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */ 07282 } 07283 } 07284 return res; 07285 }
static int set_mode_ft897 | ( | struct rpt * | myrpt, | |
char | newmode | |||
) | [static] |
Definition at line 6590 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().
06591 { 06592 unsigned char cmdstr[5]; 06593 06594 memset(cmdstr, 0, 5); 06595 06596 switch(newmode){ 06597 case REM_MODE_FM: 06598 cmdstr[0] = 0x08; 06599 break; 06600 06601 case REM_MODE_USB: 06602 cmdstr[0] = 0x01; 06603 break; 06604 06605 case REM_MODE_LSB: 06606 cmdstr[0] = 0x00; 06607 break; 06608 06609 case REM_MODE_AM: 06610 cmdstr[0] = 0x04; 06611 break; 06612 06613 default: 06614 return -1; 06615 } 06616 cmdstr[4] = 0x07; 06617 06618 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06619 }
static int set_mode_ic706 | ( | struct rpt * | myrpt, | |
char | newmode | |||
) | [static] |
Definition at line 7079 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().
07080 { 07081 unsigned char c; 07082 07083 switch(newmode){ 07084 case REM_MODE_FM: 07085 c = 5; 07086 break; 07087 07088 case REM_MODE_USB: 07089 c = 1; 07090 break; 07091 07092 case REM_MODE_LSB: 07093 c = 0; 07094 break; 07095 07096 case REM_MODE_AM: 07097 c = 2; 07098 break; 07099 07100 default: 07101 return -1; 07102 } 07103 return simple_command_ic706(myrpt,6,c); 07104 }
static int set_offset_ft897 | ( | struct rpt * | myrpt, | |
char | offset | |||
) | [static] |
Definition at line 6560 of file app_rpt.c.
References REM_MINUS, REM_PLUS, REM_SIMPLEX, and serial_remote_io().
Referenced by set_ft897().
06561 { 06562 unsigned char cmdstr[5]; 06563 06564 memset(cmdstr, 0, 5); 06565 06566 switch(offset){ 06567 case REM_SIMPLEX: 06568 cmdstr[0] = 0x89; 06569 break; 06570 06571 case REM_MINUS: 06572 cmdstr[0] = 0x09; 06573 break; 06574 06575 case REM_PLUS: 06576 cmdstr[0] = 0x49; 06577 break; 06578 06579 default: 06580 return -1; 06581 } 06582 06583 cmdstr[4] = 0x09; 06584 06585 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06586 }
static int set_offset_ic706 | ( | struct rpt * | myrpt, | |
char | offset | |||
) | [static] |
Definition at line 7052 of file app_rpt.c.
References REM_MINUS, REM_PLUS, REM_SIMPLEX, and simple_command_ic706().
Referenced by set_ic706().
07053 { 07054 unsigned char c; 07055 07056 switch(offset){ 07057 case REM_SIMPLEX: 07058 c = 0x10; 07059 break; 07060 07061 case REM_MINUS: 07062 c = 0x11; 07063 break; 07064 07065 case REM_PLUS: 07066 c = 0x12; 07067 break; 07068 07069 default: 07070 return -1; 07071 } 07072 07073 return simple_command_ic706(myrpt,0x0f,c); 07074 07075 }
static int setkenwood | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6102 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().
06103 { 06104 char rxstr[RAD_SERIAL_BUFLEN],txstr[RAD_SERIAL_BUFLEN],freq[20]; 06105 char mhz[MAXREMSTR],offset[20],band,decimals[MAXREMSTR],band1,band2; 06106 06107 int offsets[] = {0,2,1}; 06108 int powers[] = {2,1,0}; 06109 06110 if (sendrxkenwood(myrpt,"VMC 0,0\r",rxstr,"VMC") < 0) return -1; 06111 split_freq(mhz, decimals, myrpt->freq); 06112 if (atoi(mhz) > 400) 06113 { 06114 band = '6'; 06115 band1 = '1'; 06116 band2 = '5'; 06117 strcpy(offset,"005000000"); 06118 } 06119 else 06120 { 06121 band = '2'; 06122 band1 = '0'; 06123 band2 = '2'; 06124 strcpy(offset,"000600000"); 06125 } 06126 strcpy(freq,"000000"); 06127 strncpy(freq,decimals,strlen(decimals)); 06128 sprintf(txstr,"VW %c,%05d%s,0,%d,0,%d,%d,,%02d,,%02d,%s\r", 06129 band,atoi(mhz),freq,offsets[(int)myrpt->offset], 06130 (myrpt->txplon != 0),(myrpt->rxplon != 0), 06131 kenwood_pltocode(myrpt->txpl),kenwood_pltocode(myrpt->rxpl), 06132 offset); 06133 if (sendrxkenwood(myrpt,txstr,rxstr,"VW") < 0) return -1; 06134 sprintf(txstr,"RBN %c\r",band2); 06135 if (sendrxkenwood(myrpt,txstr,rxstr,"RBN") < 0) return -1; 06136 sprintf(txstr,"PC %c,%d\r",band1,powers[(int)myrpt->powerlevel]); 06137 if (sendrxkenwood(myrpt,txstr,rxstr,"PC") < 0) return -1; 06138 return 0; 06139 }
static int setrbi | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6141 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().
06142 { 06143 char tmp[MAXREMSTR] = "",*s; 06144 unsigned char rbicmd[5]; 06145 int band,txoffset = 0,txpower = 0,rxpl; 06146 06147 /* must be a remote system */ 06148 if (!myrpt->remote) return(0); 06149 /* must have rbi hardware */ 06150 if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0); 06151 if (setrbi_check(myrpt) == -1) return(-1); 06152 strncpy(tmp, myrpt->freq, sizeof(tmp) - 1); 06153 s = strchr(tmp,'.'); 06154 /* if no decimal, is invalid */ 06155 06156 if (s == NULL){ 06157 if(debug) 06158 printf("@@@@ Frequency needs a decimal\n"); 06159 return -1; 06160 } 06161 06162 *s++ = 0; 06163 if (strlen(tmp) < 2){ 06164 if(debug) 06165 printf("@@@@ Bad MHz digits: %s\n", tmp); 06166 return -1; 06167 } 06168 06169 if (strlen(s) < 3){ 06170 if(debug) 06171 printf("@@@@ Bad KHz digits: %s\n", s); 06172 return -1; 06173 } 06174 06175 if ((s[2] != '0') && (s[2] != '5')){ 06176 if(debug) 06177 printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]); 06178 return -1; 06179 } 06180 06181 band = rbi_mhztoband(tmp); 06182 if (band == -1){ 06183 if(debug) 06184 printf("@@@@ Bad Band: %s\n", tmp); 06185 return -1; 06186 } 06187 06188 rxpl = rbi_pltocode(myrpt->rxpl); 06189 06190 if (rxpl == -1){ 06191 if(debug) 06192 printf("@@@@ Bad TX PL: %s\n", myrpt->rxpl); 06193 return -1; 06194 } 06195 06196 06197 switch(myrpt->offset) 06198 { 06199 case REM_MINUS: 06200 txoffset = 0; 06201 break; 06202 case REM_PLUS: 06203 txoffset = 0x10; 06204 break; 06205 case REM_SIMPLEX: 06206 txoffset = 0x20; 06207 break; 06208 } 06209 switch(myrpt->powerlevel) 06210 { 06211 case REM_LOWPWR: 06212 txpower = 0; 06213 break; 06214 case REM_MEDPWR: 06215 txpower = 0x20; 06216 break; 06217 case REM_HIPWR: 06218 txpower = 0x10; 06219 break; 06220 } 06221 rbicmd[0] = 0; 06222 rbicmd[1] = band | txpower | 0xc0; 06223 rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80; 06224 if (s[2] == '5') rbicmd[2] |= 0x40; 06225 rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0'); 06226 rbicmd[4] = rxpl; 06227 if (myrpt->txplon) rbicmd[4] |= 0x40; 06228 if (myrpt->rxplon) rbicmd[4] |= 0x80; 06229 rbi_out(myrpt,rbicmd); 06230 return 0; 06231 }
static int setrbi_check | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 6233 of file app_rpt.c.
References rpt::freq, MAXREMSTR, rbi_mhztoband(), rbi_pltocode(), rpt::remote, s, and rpt::txpl.
Referenced by setrbi(), and setrem().
06234 { 06235 char tmp[MAXREMSTR] = "",*s; 06236 int band,txpl; 06237 06238 /* must be a remote system */ 06239 if (!myrpt->remote) return(0); 06240 /* must have rbi hardware */ 06241 if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0); 06242 strncpy(tmp, myrpt->freq, sizeof(tmp) - 1); 06243 s = strchr(tmp,'.'); 06244 /* if no decimal, is invalid */ 06245 06246 if (s == NULL){ 06247 if(debug) 06248 printf("@@@@ Frequency needs a decimal\n"); 06249 return -1; 06250 } 06251 06252 *s++ = 0; 06253 if (strlen(tmp) < 2){ 06254 if(debug) 06255 printf("@@@@ Bad MHz digits: %s\n", tmp); 06256 return -1; 06257 } 06258 06259 if (strlen(s) < 3){ 06260 if(debug) 06261 printf("@@@@ Bad KHz digits: %s\n", s); 06262 return -1; 06263 } 06264 06265 if ((s[2] != '0') && (s[2] != '5')){ 06266 if(debug) 06267 printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]); 06268 return -1; 06269 } 06270 06271 band = rbi_mhztoband(tmp); 06272 if (band == -1){ 06273 if(debug) 06274 printf("@@@@ Bad Band: %s\n", tmp); 06275 return -1; 06276 } 06277 06278 txpl = rbi_pltocode(myrpt->txpl); 06279 06280 if (txpl == -1){ 06281 if(debug) 06282 printf("@@@@ Bad TX PL: %s\n", myrpt->txpl); 06283 return -1; 06284 } 06285 return 0; 06286 }
static int setrem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7351 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().
07352 { 07353 char str[300]; 07354 char *offsets[] = {"MINUS","SIMPLEX","PLUS"}; 07355 char *powerlevels[] = {"LOW","MEDIUM","HIGH"}; 07356 char *modes[] = {"FM","USB","LSB","AM"}; 07357 int res = -1; 07358 07359 if (myrpt->p.archivedir) 07360 { 07361 sprintf(str,"FREQ,%s,%s,%s,%s,%s,%s,%d,%d",myrpt->freq, 07362 modes[(int)myrpt->remmode], 07363 myrpt->txpl,myrpt->rxpl,offsets[(int)myrpt->offset], 07364 powerlevels[(int)myrpt->powerlevel],myrpt->txplon, 07365 myrpt->rxplon); 07366 donodelog(myrpt,str); 07367 } 07368 if(!strcmp(myrpt->remote, remote_rig_ft897)) 07369 { 07370 rpt_telemetry(myrpt,SETREMOTE,NULL); 07371 res = 0; 07372 } 07373 if(!strcmp(myrpt->remote, remote_rig_ic706)) 07374 { 07375 rpt_telemetry(myrpt,SETREMOTE,NULL); 07376 res = 0; 07377 } 07378 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 07379 { 07380 res = setrbi_check(myrpt); 07381 if (!res) 07382 { 07383 rpt_telemetry(myrpt,SETREMOTE,NULL); 07384 res = 0; 07385 } 07386 } 07387 else if(!strcmp(myrpt->remote, remote_rig_kenwood)) { 07388 rpt_telemetry(myrpt,SETREMOTE,NULL); 07389 res = 0; 07390 } 07391 else 07392 res = 0; 07393 07394 if (res < 0) ast_log(LOG_ERROR,"Unable to send remote command on node %s\n",myrpt->name); 07395 07396 return res; 07397 }
static int simple_command_ft897 | ( | struct rpt * | myrpt, | |
char | command | |||
) | [static] |
Definition at line 6546 of file app_rpt.c.
References serial_remote_io().
Referenced by closerem_ft897(), rpt_tele_thread(), and set_ft897().
06547 { 06548 unsigned char cmdstr[5]; 06549 06550 memset(cmdstr, 0, 5); 06551 06552 cmdstr[4] = command; 06553 06554 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 06555 06556 }
static int simple_command_ic706 | ( | struct rpt * | myrpt, | |
char | command, | |||
char | subcommand | |||
) | [static] |
Definition at line 7000 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706(), set_mode_ic706(), and set_offset_ic706().
07001 { 07002 unsigned char cmdstr[10]; 07003 07004 cmdstr[0] = cmdstr[1] = 0xfe; 07005 cmdstr[2] = myrpt->p.civaddr; 07006 cmdstr[3] = 0xe0; 07007 cmdstr[4] = command; 07008 cmdstr[5] = subcommand; 07009 cmdstr[6] = 0xfd; 07010 07011 return(civ_cmd(myrpt,cmdstr,7)); 07012 }
static char* skipchars | ( | char * | string, | |
char * | charlist | |||
) | [static] |
Definition at line 1501 of file app_rpt.c.
Referenced by function_autopatchup().
01502 { 01503 int i; 01504 while(*string){ 01505 for(i = 0; charlist[i] ; i++){ 01506 if(*string == charlist[i]){ 01507 string++; 01508 break; 01509 } 01510 } 01511 if(!charlist[i]) 01512 return string; 01513 } 01514 return string; 01515 }
static int split_ctcss_freq | ( | char * | hertz, | |
char * | decimal, | |||
char * | freq | |||
) | [static] |
Definition at line 6399 of file app_rpt.c.
References MAXREMSTR.
Referenced by set_ctcss_freq_ft897().
06400 { 06401 char freq_copy[MAXREMSTR]; 06402 char *decp; 06403 06404 decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.'); 06405 if(decp){ 06406 *decp++ = 0; 06407 strncpy(hertz, freq_copy, MAXREMSTR); 06408 strncpy(decimal, decp, strlen(decp)); 06409 decimal[strlen(decp)] = '\0'; 06410 return 0; 06411 } 06412 else 06413 return -1; 06414 }
static int split_freq | ( | char * | mhz, | |
char * | decimals, | |||
char * | freq | |||
) | [static] |
Definition at line 6376 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().
06377 { 06378 char freq_copy[MAXREMSTR]; 06379 char *decp; 06380 06381 decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.'); 06382 if(decp){ 06383 *decp++ = 0; 06384 strncpy(mhz, freq_copy, MAXREMSTR); 06385 strcpy(decimals, "00000"); 06386 strncpy(decimals, decp, strlen(decp)); 06387 decimals[5] = 0; 06388 return 0; 06389 } 06390 else 06391 return -1; 06392 06393 }
static void stop_scan | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7575 of file app_rpt.c.
References rpt::hfscanstop, rpt_telemetry(), and SCAN.
Referenced by handle_remote_dtmf_digit().
07576 { 07577 myrpt->hfscanstop = 1; 07578 rpt_telemetry(myrpt,SCAN,0); 07579 }
static int telem_any | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
char * | entry | |||
) | [static] |
Definition at line 2715 of file app_rpt.c.
References MORSE, retrieve_astcfgint(), sayfile(), send_morse(), and send_tone_telemetry().
Referenced by rpt_tele_thread(), and telem_lookup().
02716 { 02717 int res; 02718 char c; 02719 02720 static int morsespeed; 02721 static int morsefreq; 02722 static int morseampl; 02723 static int morseidfreq = 0; 02724 static int morseidampl; 02725 static char mcat[] = MORSE; 02726 02727 res = 0; 02728 02729 if(!morseidfreq){ /* Get the morse parameters if not already loaded */ 02730 morsespeed = retrieve_astcfgint(myrpt, mcat, "speed", 5, 20, 20); 02731 morsefreq = retrieve_astcfgint(myrpt, mcat, "frequency", 300, 3000, 800); 02732 morseampl = retrieve_astcfgint(myrpt, mcat, "amplitude", 200, 8192, 4096); 02733 morseidampl = retrieve_astcfgint(myrpt, mcat, "idamplitude", 200, 8192, 2048); 02734 morseidfreq = retrieve_astcfgint(myrpt, mcat, "idfrequency", 300, 3000, 330); 02735 } 02736 02737 /* Is it a file, or a tone sequence? */ 02738 02739 if(entry[0] == '|'){ 02740 c = entry[1]; 02741 if((c >= 'a')&&(c <= 'z')) 02742 c -= 0x20; 02743 02744 switch(c){ 02745 case 'I': /* Morse ID */ 02746 res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl); 02747 break; 02748 02749 case 'M': /* Morse Message */ 02750 res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl); 02751 break; 02752 02753 case 'T': /* Tone sequence */ 02754 res = send_tone_telemetry(chan, entry + 2); 02755 break; 02756 default: 02757 res = -1; 02758 } 02759 } 02760 else 02761 res = sayfile(chan, entry); /* File */ 02762 return res; 02763 }
static int telem_lookup | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
char * | node, | |||
char * | name | |||
) | [static] |
Definition at line 2771 of file app_rpt.c.
References ast_log(), ast_strdupa, ast_variable_retrieve(), rpt::cfg, LOG_WARNING, tele_defs, telem_any(), and TELEMETRY.
Referenced by rpt_tele_thread().
02772 { 02773 02774 int res; 02775 int i; 02776 char *entry; 02777 char *telemetry; 02778 char *telemetry_save; 02779 02780 res = 0; 02781 telemetry_save = NULL; 02782 entry = NULL; 02783 02784 /* Retrieve the section name for telemetry from the node section */ 02785 telemetry = (char *) ast_variable_retrieve(myrpt->cfg, node, TELEMETRY); 02786 if(telemetry ){ 02787 telemetry_save = ast_strdupa(telemetry); 02788 if(!telemetry_save){ 02789 ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n"); 02790 return res; 02791 } 02792 entry = (char *) ast_variable_retrieve(myrpt->cfg, telemetry_save, name); 02793 } 02794 02795 /* Try to look up the telemetry name */ 02796 02797 if(!entry){ 02798 /* Telemetry name wasn't found in the config file, use the default */ 02799 for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){ 02800 if(!strcasecmp(tele_defs[i].name, name)) 02801 entry = tele_defs[i].value; 02802 } 02803 } 02804 if(entry){ 02805 if(strlen(entry)) 02806 telem_any(myrpt,chan, entry); 02807 } 02808 else{ 02809 res = -1; 02810 } 02811 return res; 02812 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11857 of file app_rpt.c.
References ast_cli_unregister(), ast_mutex_destroy(), ast_unregister_application(), cli_debug, cli_dump, cli_fun, cli_lstats, cli_nodes, cli_reload, cli_restart, cli_stats, lock, name, rpt::nodes, and rpt_vars.
11859 { 11860 int i; 11861 11862 #ifdef OLD_ASTERISK 11863 STANDARD_HANGUP_LOCALUSERS; 11864 #endif 11865 for(i = 0; i < nrpts; i++) { 11866 if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue; 11867 ast_mutex_destroy(&rpt_vars[i].lock); 11868 ast_mutex_destroy(&rpt_vars[i].remlock); 11869 } 11870 i = ast_unregister_application(app); 11871 11872 /* Unregister cli extensions */ 11873 ast_cli_unregister(&cli_debug); 11874 ast_cli_unregister(&cli_dump); 11875 ast_cli_unregister(&cli_stats); 11876 ast_cli_unregister(&cli_lstats); 11877 ast_cli_unregister(&cli_nodes); 11878 ast_cli_unregister(&cli_reload); 11879 ast_cli_unregister(&cli_restart); 11880 ast_cli_unregister(&cli_fun); 11881 11882 return i; 11883 }
static int vfo_ic706 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 7184 of file app_rpt.c.
References civ_cmd(), rpt::civaddr, and rpt::p.
Referenced by set_ic706().
07185 { 07186 unsigned char cmdstr[10]; 07187 07188 cmdstr[0] = cmdstr[1] = 0xfe; 07189 cmdstr[2] = myrpt->p.civaddr; 07190 cmdstr[3] = 0xe0; 07191 cmdstr[4] = 7; 07192 cmdstr[5] = 0xfd; 07193 07194 return(civ_cmd(myrpt,cmdstr,6)); 07195 }
static void wait_interval | ( | struct rpt * | myrpt, | |
int | type, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 2890 of file app_rpt.c.
References ast_log(), ast_safe_sleep(), get_wait_interval(), and LOG_NOTICE.
Referenced by rpt_tele_thread().
02891 { 02892 int interval; 02893 interval = get_wait_interval(myrpt, type); 02894 if(debug) 02895 ast_log(LOG_NOTICE," Delay interval = %d\n", interval); 02896 if(interval) 02897 ast_safe_sleep(chan,interval); 02898 if(debug) 02899 ast_log(LOG_NOTICE,"Delay complete\n"); 02900 return; 02901 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Radio Repeater/Remote Base Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
struct ast_cli_entry cli_debug [static] |
Initial value:
{ { "rpt", "debug", "level" }, rpt_do_debug, "Enable app_rpt debugging", debug_usage }
Definition at line 935 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_dump [static] |
Initial value:
{ { "rpt", "dump" }, rpt_do_dump, "Dump app_rpt structs for debugging", dump_usage }
Definition at line 939 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_fun [static] |
Initial value:
{ { "rpt", "fun" }, rpt_do_fun, "Execute a DTMF function", fun_usage }
Definition at line 963 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_lstats [static] |
Initial value:
{ { "rpt", "lstats" }, rpt_do_lstats, "Dump link statistics", dump_lstats }
Definition at line 951 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_nodes [static] |
Initial value:
{ { "rpt", "nodes" }, rpt_do_nodes, "Dump node list", dump_nodes }
Definition at line 947 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_reload [static] |
Initial value:
{ { "rpt", "reload" }, rpt_do_reload, "Reload app_rpt config", reload_usage }
struct ast_cli_entry cli_restart [static] |
Initial value:
{ { "rpt", "restart" }, rpt_do_restart, "Restart app_rpt", restart_usage }
Definition at line 959 of file app_rpt.c.
Referenced by load_module(), and unload_module().
struct ast_cli_entry cli_stats [static] |
Initial value:
{ { "rpt", "stats" }, rpt_do_stats, "Dump node statistics", dump_stats }
Definition at line 943 of file app_rpt.c.
Referenced by load_module(), and unload_module().
int debug = 0 [static] |
Definition at line 353 of file app_rpt.c.
Referenced by add_sdp(), aji_load_config(), check_user_full(), handle_pri_show_debug(), handle_request(), process_sdp(), process_sdp_a_audio(), process_sdp_a_video(), 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} |
ast_mutex_t nodeloglock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
ast_mutex_t nodelookuplock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [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] |
Referenced by load_rpt_vars(), reload(), rpt(), rpt_do_dump(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_reload(), rpt_do_restart(), rpt_do_stats(), rpt_exec(), rpt_master(), and unload_module().
time_t starttime = 0 [static] |
char* synopsis = "Radio Repeater/Remote Base Control System" [static] |
char* tdesc = "Radio Repeater / Remote Base version 0.73 09/04/2007" [static] |
struct telem_defaults tele_defs[] [static] |