Wed Aug 15 01:24:37 2007

Asterisk developer's documentation


app_rpt.c File Reference

Radio Repeater / Remote Base program version 0.70 07/22/07. More...

#include "asterisk.h"
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/io.h>
#include <sys/vfs.h>
#include <math.h>
#include <zaptel/zaptel.h>
#include <zaptel/tonezone.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
#include "asterisk/cdr.h"
#include <termios.h>

Include dependency graph for app_rpt.c:

Go to the source code of this file.

Data Structures

struct  function_table_tag
struct  morse_bits
struct  nodelog
struct  rpt
struct  rpt_chan_stat
struct  rpt_link
struct  rpt_lstat
struct  rpt_tele
struct  rpt_xlat
struct  sysstate
struct  telem_defaults

Defines

#define ACTIONSIZE   32
#define AUTHLOGOUTTIME   25000
#define AUTHTELLTIME   7000
#define AUTHTXTIME   1000
#define DEFAULT_CIV_ADDR   0x58
#define DEFAULT_IOBASE   0x378
#define DEFAULT_MONITOR_MIN_DISK_BLOCKS   10000
#define DEFAULT_REMOTE_INACT_TIMEOUT   (15 * 60)
#define DEFAULT_REMOTE_TIMEOUT   (60 * 60)
#define DEFAULT_REMOTE_TIMEOUT_WARNING   (3 * 60)
#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ   30
#define DELIMCHR   ','
#define DISC_TIME   10000
#define DTMF_LOCAL_STARTTIME   500
#define DTMF_LOCAL_TIME   250
#define DTMF_TIMEOUT   3
#define ENDCHAR   '#'
#define EXTNODEFILE   "/var/lib/asterisk/rpt_extnodes"
#define EXTNODES   "extnodes"
#define FUNCCHAR   '*'
#define FUNCTDELAY   1500
#define FUNCTIONS   "functions"
#define HANGTIME   5000
#define IC706_PL_MEMORY_OFFSET   50
#define IDTIME   300000
#define KENWOOD_RETRIES   5
#define LINKLISTSHORTTIME   200
#define LINKLISTTIME   10000
#define MACRO   "macro"
#define MACROPTIME   500
#define MACROTIME   100
#define MAX_RETRIES   5
#define MAX_RETRIES_PERM   1000000000
#define MAX_STAT_LINKS   32
#define MAX_SYSSTATES   10
#define MAXCONNECTTIME   5000
#define MAXDTMF   32
#define MAXLINKLIST   512
#define MAXMACRO   2048
#define MAXNODESTR   300
#define MAXPATCHCONTEXT   100
#define MAXPEERSTR   31
#define MAXREMSTR   15
#define MAXRPTS   20
#define MAXXLAT   20
#define MAXXLATTIME   3
#define MEMORY   "memory"
#define MONITOR_DISK_BLOCKS_PER_MINUTE   38
#define MORSE   "morse"
#define MSWAIT   200
#define NODES   "nodes"
#define NRPTSTAT   7
#define OLDKEY
#define POLITEID   30000
#define QUOTECHR   34
#define REDUNDANT_TX_TIME   2000
#define REM_SCANTIME   100
#define RETRY_TIMER_MS   5000
#define rpt_mutex_lock(x)   ast_mutex_lock(x)
#define rpt_mutex_unlock(x)   ast_mutex_unlock(x)
#define START_DELAY   10
#define TELEMETRY   "telemetry"
#define TELEPARAMSIZE   256
#define TOTIME   180000

Enumerations

enum  { REM_OFF, REM_MONITOR, REM_TX }
enum  {
  ID, PROC, TERM, COMPLETE,
  UNKEY, REMDISC, REMALREADY, REMNOTFOUND,
  REMGO, CONNECTED, CONNFAIL, STATUS,
  TIMEOUT, ID1, STATS_TIME, STATS_VERSION,
  IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH,
  TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY,
  FULLSTATUS, MEMNOTFOUND, INVFREQ, REMMODE,
  REMLOGIN, REMXXX, REMSHORTSTATUS, REMLONGSTATUS,
  LOGINREQ, SCAN, SCANSTAT, TUNE,
  SETREMOTE, TIMEOUT_WARNING, ACT_TIMEOUT_WARNING, LINKUNKEY,
  UNAUTHTX
}
enum  { REM_SIMPLEX, REM_MINUS, REM_PLUS }
enum  { REM_LOWPWR, REM_MEDPWR, REM_HIPWR }
enum  {
  DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE,
  DC_COMPLETEQUIET, DC_DOKEY
}
enum  {
  SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE,
  SOURCE_DPHONE
}
enum  {
  DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM,
  DLY_COMP, DLY_LINKUNKEY
}
enum  { REM_MODE_FM, REM_MODE_USB, REM_MODE_LSB, REM_MODE_AM }
enum  {
  HF_SCAN_OFF, HF_SCAN_DOWN_SLOW, HF_SCAN_DOWN_QUICK, HF_SCAN_DOWN_FAST,
  HF_SCAN_UP_SLOW, HF_SCAN_UP_QUICK, HF_SCAN_UP_FAST
}
enum  { TOP_TOP, TOP_WON, WON_BEFREAD, BEFREAD_AFTERREAD }

Functions

static void __kickshort (struct rpt *myrpt)
static void __mklinklist (struct rpt *myrpt, struct rpt_link *mylink, char *buf)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Radio Repeater/Remote Base Application",.load=load_module,.unload=unload_module,.reload=reload,)
 AST_MUTEX_DEFINE_STATIC (nodelookuplock)
 AST_MUTEX_DEFINE_STATIC (nodeloglock)
int ast_playtones_start (struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
void ast_playtones_stop (struct ast_channel *chan)
static int attempt_reconnect (struct rpt *myrpt, struct rpt_link *l)
static int check_freq (struct rpt *myrpt, int m, int d, int *defmode)
static int check_freq_ft897 (int m, int d, int *defmode)
static int check_freq_ic706 (int m, int d, int *defmode)
static int check_freq_kenwood (int m, int d, int *defmode)
static int check_freq_rbi (int m, int d, int *defmode)
static char check_tx_freq (struct rpt *myrpt)
static int civ_cmd (struct rpt *myrpt, unsigned char *cmd, int cmdlen)
static int closerem (struct rpt *myrpt)
static int closerem_ft897 (struct rpt *myrpt)
static int collect_function_digits (struct rpt *myrpt, char *digits, int command_source, struct rpt_link *mylink)
static int connect_link (struct rpt *myrpt, char *node, int mode, int perma)
static int decimals2int (char *fraction)
static long diskavail (struct rpt *myrpt)
static void do_dtmf_local (struct rpt *myrpt, char c)
static void do_dtmf_phone (struct rpt *myrpt, struct rpt_link *mylink, char c)
static void do_scheduler (struct rpt *myrpt)
static void donodelog (struct rpt *myrpt, char *str)
static char * eatwhite (char *s)
static int finddelim (char *str, char *strp[], int limit)
static char func_xlat (struct rpt *myrpt, char c, struct rpt_xlat *xlat)
static int function_autopatchdn (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
static int function_autopatchup (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
static int function_cop (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
static int function_ilink (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
static int function_macro (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
static int function_remote (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
static int function_status (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink)
static int get_wait_interval (struct rpt *myrpt, int type)
static void handle_link_data (struct rpt *myrpt, struct rpt_link *mylink, char *str)
static void handle_link_phone_dtmf (struct rpt *myrpt, struct rpt_link *mylink, char c)
static int handle_remote_data (struct rpt *myrpt, char *str)
static int handle_remote_dtmf_digit (struct rpt *myrpt, char c, char *keyed, int phonemode)
static int handle_remote_phone_dtmf (struct rpt *myrpt, char c, char *keyed, int phonemode)
static int ic706_pltocode (char *str)
static int kenwood_pltocode (char *str)
static int load_module (void)
static void load_rpt_vars (int n, int init)
static void local_dtmf_helper (struct rpt *myrpt, char c)
static int matchkeyword (char *string, char **param, char *keywords[])
static int mem2vfo_ic706 (struct rpt *myrpt)
static int multimode_bump_freq (struct rpt *myrpt, int interval)
static int multimode_bump_freq_ft897 (struct rpt *myrpt, int interval)
static int multimode_bump_freq_ic706 (struct rpt *myrpt, int interval)
static int multimode_capable (struct rpt *myrpt)
static int myatoi (char *str)
static int mycompar (const void *a, const void *b)
static char * node_lookup (struct rpt *myrpt, char *digitbuf)
static int openserial (char *fname)
static int play_silence (struct ast_channel *chan, int duration)
static int play_tone (struct ast_channel *chan, int freq, int duration, int amplitude)
static int play_tone_pair (struct ast_channel *chan, int f1, int f2, int duration, int amplitude)
static void queue_id (struct rpt *myrpt)
static int rbi_mhztoband (char *str)
static void rbi_out (struct rpt *myrpt, unsigned char *data)
static void rbi_out_parallel (struct rpt *myrpt, unsigned char *data)
static int rbi_pltocode (char *str)
static int reload (void)
static int retreive_memory (struct rpt *myrpt, char *memory)
static int retrieve_astcfgint (struct rpt *myrpt, char *category, char *name, int min, int max, int defl)
static void * rpt (void *this)
static void * rpt_call (void *this)
static int rpt_do_debug (int fd, int argc, char *argv[])
static int rpt_do_dump (int fd, int argc, char *argv[])
static int rpt_do_fun (int fd, int argc, char *argv[])
static int rpt_do_lstats (int fd, int argc, char *argv[])
static int rpt_do_nodes (int fd, int argc, char *argv[])
static int rpt_do_reload (int fd, int argc, char *argv[])
static int rpt_do_restart (int fd, int argc, char *argv[])
static int rpt_do_stats (int fd, int argc, char *argv[])
static int rpt_exec (struct ast_channel *chan, void *data)
static void rpt_localtime (time_t *t, struct tm *lt)
static void * rpt_master (void *ignore)
static void * rpt_tele_thread (void *this)
static void rpt_telemetry (struct rpt *myrpt, int mode, void *data)
static int saycharstr (struct ast_channel *mychannel, char *str)
static int sayfile (struct ast_channel *mychannel, char *fname)
static int saynum (struct ast_channel *mychannel, int num)
static int select_mem_ic706 (struct rpt *myrpt, int slot)
static void send_link_dtmf (struct rpt *myrpt, char c)
static int send_morse (struct ast_channel *chan, char *string, int speed, int freq, int amplitude)
static int send_tone_telemetry (struct ast_channel *chan, char *tonestring)
static int sendkenwood (struct rpt *myrpt, char *txstr, char *rxstr)
static int sendrxkenwood (struct rpt *myrpt, char *txstr, char *rxstr, char *cmpstr)
static int serial_remote_io (struct rpt *myrpt, unsigned char *txbuf, int txbytes, unsigned char *rxbuf, int rxmaxbytes, int asciiflag)
static int service_scan (struct rpt *myrpt)
static int set_ctcss_freq_ft897 (struct rpt *myrpt, char *txtone, char *rxtone)
static int set_ctcss_mode_ft897 (struct rpt *myrpt, char txplon, char rxplon)
static int set_ctcss_mode_ic706 (struct rpt *myrpt, char txplon, char rxplon)
static int set_freq_ft897 (struct rpt *myrpt, char *newfreq)
static int set_freq_ic706 (struct rpt *myrpt, char *newfreq)
static int set_ft897 (struct rpt *myrpt)
static int set_ic706 (struct rpt *myrpt)
static int set_mode_ft897 (struct rpt *myrpt, char newmode)
static int set_mode_ic706 (struct rpt *myrpt, char newmode)
static int set_offset_ft897 (struct rpt *myrpt, char offset)
static int set_offset_ic706 (struct rpt *myrpt, char offset)
static int setkenwood (struct rpt *myrpt)
static int setrbi (struct rpt *myrpt)
static int setrbi_check (struct rpt *myrpt)
static int setrem (struct rpt *myrpt)
static int simple_command_ft897 (struct rpt *myrpt, char command)
static int simple_command_ic706 (struct rpt *myrpt, char command, char subcommand)
static char * skipchars (char *string, char *charlist)
static int split_ctcss_freq (char *hertz, char *decimal, char *freq)
static int split_freq (char *mhz, char *decimals, char *freq)
static void stop_scan (struct rpt *myrpt)
static int telem_any (struct rpt *myrpt, struct ast_channel *chan, char *entry)
static int telem_lookup (struct rpt *myrpt, struct ast_channel *chan, char *node, char *name)
static int unload_module (void)
static int vfo_ic706 (struct rpt *myrpt)
static void wait_interval (struct rpt *myrpt, int type, struct ast_channel *chan)

Variables

static char * app = "Rpt"
static struct
ast_cli_entry 
cli_debug
static struct
ast_cli_entry 
cli_dump
static struct
ast_cli_entry 
cli_fun
static struct
ast_cli_entry 
cli_lstats
static struct
ast_cli_entry 
cli_nodes
static struct
ast_cli_entry 
cli_reload
static struct
ast_cli_entry 
cli_restart
static struct
ast_cli_entry 
cli_stats
static int debug = 0
static char debug_usage []
static char * descrip
char * discstr = "!!DISCONNECT!!"
static char dump_lstats []
static char dump_nodes []
static char dump_stats []
static char dump_usage []
static char fun_usage []
static struct
function_table_tag 
function_table []
int max_chan_stat [] = {22000,1000,22000,100,22000,2000,22000}
static int nrpts = 0
static char reload_usage []
static char remdtmfstr [] = "0123456789*#ABCD"
static char * remote_rig_ft897 = "ft897"
static char * remote_rig_ic706 = "ic706"
static char * remote_rig_kenwood = "kenwood"
static char * remote_rig_rbi = "rbi"
static char restart_usage []
static pthread_t rpt_master_thread
static struct rpt rpt_vars [MAXRPTS]
static time_t starttime = 0
static char * synopsis = "Radio Repeater/Remote Base Control System"
static char * tdesc = "Radio Repeater / Remote Base version 0.70 07/22/2007"
static struct
telem_defaults 
tele_defs []


Detailed Description

Radio Repeater / Remote Base program version 0.70 07/22/07.

Author:
Jim Dixon, WB6NIL <jim@lambdatel.com>
Note:
Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.com>
See http://www.zapatatelephony.org/app_rpt.html

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 Documentation

#define ACTIONSIZE   32

Definition at line 219 of file app_rpt.c.

#define AUTHLOGOUTTIME   25000

Definition at line 168 of file app_rpt.c.

Referenced by rpt_exec().

#define AUTHTELLTIME   7000

Definition at line 166 of file app_rpt.c.

Referenced by rpt_exec().

#define AUTHTXTIME   1000

Definition at line 167 of file app_rpt.c.

Referenced by rpt_exec().

#define DEFAULT_CIV_ADDR   0x58

Definition at line 211 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_IOBASE   0x378

Definition at line 209 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_MONITOR_MIN_DISK_BLOCKS   10000

Definition at line 192 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_INACT_TIMEOUT   (15 * 60)

Definition at line 193 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT   (60 * 60)

Definition at line 194 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING   (3 * 60)

Definition at line 195 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ   30

Definition at line 196 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DELIMCHR   ','

Definition at line 187 of file app_rpt.c.

Referenced by finddelim().

#define DISC_TIME   10000

Definition at line 174 of file app_rpt.c.

Referenced by rpt().

#define DTMF_LOCAL_STARTTIME   500

Definition at line 226 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_LOCAL_TIME   250

Definition at line 225 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_TIMEOUT   3

Definition at line 163 of file app_rpt.c.

Referenced by handle_remote_dtmf_digit(), and rpt().

#define ENDCHAR   '#'

Definition at line 206 of file app_rpt.c.

Referenced by load_rpt_vars().

#define EXTNODEFILE   "/var/lib/asterisk/rpt_extnodes"

Definition at line 207 of file app_rpt.c.

Referenced by load_rpt_vars().

#define EXTNODES   "extnodes"

Definition at line 199 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCCHAR   '*'

Definition at line 205 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCTDELAY   1500

Definition at line 390 of file app_rpt.c.

#define FUNCTIONS   "functions"

Definition at line 202 of file app_rpt.c.

Referenced by load_rpt_vars().

#define HANGTIME   5000

Definition at line 384 of file app_rpt.c.

Referenced by load_rpt_vars().

#define IC706_PL_MEMORY_OFFSET   50

Definition at line 228 of file app_rpt.c.

Referenced by set_ic706().

#define IDTIME   300000

Definition at line 386 of file app_rpt.c.

Referenced by load_rpt_vars().

#define KENWOOD_RETRIES   5

Definition at line 164 of file app_rpt.c.

Referenced by sendrxkenwood().

#define LINKLISTSHORTTIME   200

Definition at line 160 of file app_rpt.c.

Referenced by __kickshort().

#define LINKLISTTIME   10000

Definition at line 159 of file app_rpt.c.

Referenced by rpt().

#define MACRO   "macro"

Definition at line 201 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MACROPTIME   500

Definition at line 162 of file app_rpt.c.

Referenced by rpt(), and rpt_exec().

#define MACROTIME   100

Definition at line 161 of file app_rpt.c.

Referenced by do_scheduler(), function_macro(), rpt(), rpt_do_fun(), and rpt_exec().

#define MAX_RETRIES   5

Definition at line 175 of file app_rpt.c.

Referenced by connect_link(), function_ilink(), and rpt_exec().

#define MAX_RETRIES_PERM   1000000000

Definition at line 176 of file app_rpt.c.

Referenced by connect_link().

#define MAX_STAT_LINKS   32

Definition at line 388 of file app_rpt.c.

Referenced by rpt_do_stats().

#define MAX_SYSSTATES   10

Definition at line 395 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXCONNECTTIME   5000

Definition at line 213 of file app_rpt.c.

Referenced by rpt().

#define MAXDTMF   32

Definition at line 156 of file app_rpt.c.

Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and local_dtmf_helper().

#define MAXLINKLIST   512

Definition at line 158 of file app_rpt.c.

Referenced by __mklinklist(), connect_link(), function_ilink(), rpt(), rpt_do_nodes(), and rpt_tele_thread().

#define MAXMACRO   2048

Definition at line 157 of file app_rpt.c.

Referenced by do_scheduler(), function_macro(), rpt(), rpt_do_fun(), and rpt_exec().

#define MAXNODESTR   300

Definition at line 215 of file app_rpt.c.

Referenced by connect_link(), function_ilink(), and rpt_exec().

#define MAXPATCHCONTEXT   100

Definition at line 217 of file app_rpt.c.

Referenced by function_autopatchup(), and local_dtmf_helper().

#define MAXPEERSTR   31

Definition at line 184 of file app_rpt.c.

Referenced by rpt_do_lstats().

#define MAXREMSTR   15

Definition at line 185 of file app_rpt.c.

Referenced by check_tx_freq(), function_remote(), multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), rpt_do_lstats(), rpt_tele_thread(), service_scan(), set_ctcss_freq_ft897(), set_freq_ft897(), set_freq_ic706(), setkenwood(), setrbi(), setrbi_check(), split_ctcss_freq(), and split_freq().

#define MAXRPTS   20

Definition at line 387 of file app_rpt.c.

#define MAXXLAT   20

Definition at line 392 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXXLATTIME   3

Definition at line 393 of file app_rpt.c.

Referenced by func_xlat().

#define MEMORY   "memory"

Definition at line 200 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MONITOR_DISK_BLOCKS_PER_MINUTE   38

Definition at line 190 of file app_rpt.c.

Referenced by rpt_exec().

#define MORSE   "morse"

Definition at line 204 of file app_rpt.c.

Referenced by telem_any().

#define MSWAIT   200

Definition at line 383 of file app_rpt.c.

Referenced by rpt(), rpt_call(), and rpt_exec().

#define NODES   "nodes"

Definition at line 198 of file app_rpt.c.

Referenced by load_rpt_vars().

#define NRPTSTAT   7

Definition at line 361 of file app_rpt.c.

Referenced by rpt_do_lstats().

#define OLDKEY

Definition at line 2 of file app_rpt.c.

#define POLITEID   30000

Definition at line 389 of file app_rpt.c.

Referenced by load_rpt_vars().

#define QUOTECHR   34

Definition at line 188 of file app_rpt.c.

Referenced by finddelim().

#define REDUNDANT_TX_TIME   2000

Definition at line 178 of file app_rpt.c.

Referenced by rpt(), and rpt_exec().

#define REM_SCANTIME   100

Definition at line 223 of file app_rpt.c.

Referenced by function_remote(), and rpt_exec().

#define RETRY_TIMER_MS   5000

Definition at line 180 of file app_rpt.c.

Referenced by rpt().

#define rpt_mutex_lock (  )     ast_mutex_lock(x)

Definition at line 869 of file app_rpt.c.

Referenced by attempt_reconnect(), connect_link(), do_dtmf_local(), function_autopatchdn(), function_autopatchup(), function_ilink(), function_macro(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rpt_exec(), rpt_tele_thread(), and rpt_telemetry().

#define rpt_mutex_unlock (  )     ast_mutex_unlock(x)

Definition at line 870 of file app_rpt.c.

Referenced by attempt_reconnect(), connect_link(), do_dtmf_local(), function_autopatchdn(), function_autopatchup(), function_ilink(), function_macro(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rpt_exec(), rpt_tele_thread(), and rpt_telemetry().

#define START_DELAY   10

Definition at line 182 of file app_rpt.c.

Referenced by rpt(), and rpt_exec().

#define TELEMETRY   "telemetry"

Definition at line 203 of file app_rpt.c.

Referenced by telem_lookup().

#define TELEPARAMSIZE   256

Definition at line 221 of file app_rpt.c.

Referenced by rpt_telemetry().

#define TOTIME   180000

Definition at line 385 of file app_rpt.c.

Referenced by load_rpt_vars().


Enumeration Type Documentation

anonymous enum

Enumerator:
REM_OFF 
REM_MONITOR 
REM_TX 

Definition at line 230 of file app_rpt.c.

anonymous enum

Enumerator:
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 

Definition at line 232 of file app_rpt.c.

anonymous enum

Enumerator:
REM_SIMPLEX 
REM_MINUS 
REM_PLUS 

Definition at line 241 of file app_rpt.c.

anonymous enum

Enumerator:
REM_LOWPWR 
REM_MEDPWR 
REM_HIPWR 

Definition at line 243 of file app_rpt.c.

anonymous enum

Enumerator:
DC_INDETERMINATE 
DC_REQ_FLUSH 
DC_ERROR 
DC_COMPLETE 
DC_COMPLETEQUIET 
DC_DOKEY 

Definition at line 245 of file app_rpt.c.

anonymous enum

Enumerator:
SOURCE_RPT 
SOURCE_LNK 
SOURCE_RMT 
SOURCE_PHONE 
SOURCE_DPHONE 

Definition at line 247 of file app_rpt.c.

anonymous enum

Enumerator:
DLY_TELEM 
DLY_ID 
DLY_UNKEY 
DLY_CALLTERM 
DLY_COMP 
DLY_LINKUNKEY 

Definition at line 249 of file app_rpt.c.

anonymous enum

Enumerator:
REM_MODE_FM 
REM_MODE_USB 
REM_MODE_LSB 
REM_MODE_AM 

Definition at line 251 of file app_rpt.c.

anonymous enum

Enumerator:
HF_SCAN_OFF 
HF_SCAN_DOWN_SLOW 
HF_SCAN_DOWN_QUICK 
HF_SCAN_DOWN_FAST 
HF_SCAN_UP_SLOW 
HF_SCAN_UP_QUICK 
HF_SCAN_UP_FAST 

Definition at line 253 of file app_rpt.c.

anonymous enum

Enumerator:
TOP_TOP 
TOP_WON 
WON_BEFREAD 
BEFREAD_AFTERREAD 

Definition at line 357 of file app_rpt.c.


Function Documentation

static void __kickshort ( struct rpt myrpt  )  [static]

Definition at line 1344 of file app_rpt.c.

References LINKLISTSHORTTIME, rpt_link::linklisttimer, rpt::links, rpt_link::name, and rpt_link::next.

Referenced by connect_link(), rpt(), and rpt_exec().

01345 {
01346 struct rpt_link *l;
01347 
01348    for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
01349    {
01350       /* if is not a real link, ignore it */
01351       if (l->name[0] == '0') continue;
01352       l->linklisttimer = LINKLISTSHORTTIME;
01353    }
01354    return;
01355 }

static void __mklinklist ( struct rpt myrpt,
struct rpt_link mylink,
char *  buf 
) [static]

Definition at line 1295 of file app_rpt.c.

References rpt_link::linklist, rpt::links, MAXLINKLIST, rpt_link::mode, rpt_link::name, rpt_link::next, and rpt_link::thisconnected.

Referenced by connect_link(), rpt(), rpt_do_nodes(), and rpt_tele_thread().

01296 {
01297 struct rpt_link *l;
01298 char mode;
01299 int   i,spos;
01300 
01301    buf[0] = 0; /* clear output buffer */
01302    /* go thru all links */
01303    for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
01304    {
01305       /* if is not a real link, ignore it */
01306       if (l->name[0] == '0') continue;
01307       /* dont count our stuff */
01308       if (l == mylink) continue;
01309       if (mylink && (!strcmp(l->name,mylink->name))) continue;
01310       /* figure out mode to report */
01311       mode = 'T'; /* use Tranceive by default */
01312       if (!l->mode) mode = 'R'; /* indicate RX for our mode */
01313       if (!l->thisconnected)  mode = 'C'; /* indicate connecting */
01314       spos = strlen(buf); /* current buf size (b4 we add our stuff) */
01315       if (spos)
01316       {
01317          strcat(buf,",");
01318          spos++;
01319       }
01320       /* add nodes into buffer */
01321       if (l->linklist[0])
01322       {
01323          snprintf(buf + spos,MAXLINKLIST - spos,
01324             "%c%s,%s",mode,l->name,l->linklist);
01325       }
01326       else /* if no nodes, add this node into buffer */
01327       {
01328          snprintf(buf + spos,MAXLINKLIST - spos,
01329             "%c%s",mode,l->name);
01330       }
01331       /* if we are in tranceive mode, let all modes stand */
01332       if (mode == 'T') continue;
01333       /* downgrade everyone on this node if appropriate */
01334       for(i = spos; buf[i]; i++)
01335       {
01336          if (buf[i] == 'T') buf[i] = mode;
01337          if ((buf[i] == 'R') && (mode == 'C')) buf[i] = mode;
01338       }
01339    }
01340    return;
01341 }

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
"Radio Repeater/Remote Base Application"  ,
load = load_module,
unload = unload_module,
reload = reload 
)

AST_MUTEX_DEFINE_STATIC ( nodelookuplock   ) 

AST_MUTEX_DEFINE_STATIC ( nodeloglock   ) 

int ast_playtones_start ( struct ast_channel chan,
int  vol,
const char *  tonelist,
int  interruptible 
)

Definition at line 212 of file indications.c.

References ast_activate_generator(), ast_log(), ast_realloc, ast_strdupa, playtones_item::duration, playtones_item::fac1, playtones_item::fac2, free, playtones_item::init_v2_1, playtones_item::init_v2_2, playtones_item::init_v3_1, playtones_item::init_v3_2, playtones_def::interruptible, playtones_def::items, LOG_WARNING, playtones_item::modulate, playtones_def::nitems, playtones_def::reppos, s, strsep(), and playtones_def::vol.

00213 {
00214    char *s, *data = ast_strdupa(playlst); /* cute */
00215    struct playtones_def d = { vol, -1, 0, 1, NULL};
00216    char *stringp;
00217    char *separator;
00218    
00219    if (vol < 1)
00220       d.vol = 7219; /* Default to -8db */
00221 
00222    d.interruptible = interruptible;
00223    
00224    stringp=data;
00225    /* the stringp/data is not null here */
00226    /* check if the data is separated with '|' or with ',' by default */
00227    if (strchr(stringp,'|'))
00228       separator = "|";
00229    else
00230       separator = ",";
00231    s = strsep(&stringp,separator);
00232    while (s && *s) {
00233       int freq1, freq2, time, modulate=0, midinote=0;
00234 
00235       if (s[0]=='!')
00236          s++;
00237       else if (d.reppos == -1)
00238          d.reppos = d.nitems;
00239       if (sscanf(s, "%d+%d/%d", &freq1, &freq2, &time) == 3) {
00240          /* f1+f2/time format */
00241       } else if (sscanf(s, "%d+%d", &freq1, &freq2) == 2) {
00242          /* f1+f2 format */
00243          time = 0;
00244       } else if (sscanf(s, "%d*%d/%d", &freq1, &freq2, &time) == 3) {
00245          /* f1*f2/time format */
00246          modulate = 1;
00247       } else if (sscanf(s, "%d*%d", &freq1, &freq2) == 2) {
00248          /* f1*f2 format */
00249          time = 0;
00250          modulate = 1;
00251       } else if (sscanf(s, "%d/%d", &freq1, &time) == 2) {
00252          /* f1/time format */
00253          freq2 = 0;
00254       } else if (sscanf(s, "%d", &freq1) == 1) {
00255          /* f1 format */
00256          freq2 = 0;
00257          time = 0;
00258       } else if (sscanf(s, "M%d+M%d/%d", &freq1, &freq2, &time) == 3) {
00259          /* Mf1+Mf2/time format */
00260          midinote = 1;
00261       } else if (sscanf(s, "M%d+M%d", &freq1, &freq2) == 2) {
00262          /* Mf1+Mf2 format */
00263          time = 0;
00264          midinote = 1;
00265       } else if (sscanf(s, "M%d*M%d/%d", &freq1, &freq2, &time) == 3) {
00266          /* Mf1*Mf2/time format */
00267          modulate = 1;
00268          midinote = 1;
00269       } else if (sscanf(s, "M%d*M%d", &freq1, &freq2) == 2) {
00270          /* Mf1*Mf2 format */
00271          time = 0;
00272          modulate = 1;
00273          midinote = 1;
00274       } else if (sscanf(s, "M%d/%d", &freq1, &time) == 2) {
00275          /* Mf1/time format */
00276          freq2 = -1;
00277          midinote = 1;
00278       } else if (sscanf(s, "M%d", &freq1) == 1) {
00279          /* Mf1 format */
00280          freq2 = -1;
00281          time = 0;
00282          midinote = 1;
00283       } else {
00284          ast_log(LOG_WARNING,"%s: tone component '%s' of '%s' is no good\n",chan->name,s,playlst);
00285          return -1;
00286       }
00287 
00288       if (midinote) {
00289          /* midi notes must be between 0 and 127 */
00290          if ((freq1 >= 0) && (freq1 <= 127))
00291             freq1 = midi_tohz[freq1];
00292          else
00293             freq1 = 0;
00294 
00295          if ((freq2 >= 0) && (freq2 <= 127))
00296             freq2 = midi_tohz[freq2];
00297          else
00298             freq2 = 0;
00299       }
00300 
00301       if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) {
00302          return -1;
00303       }
00304       d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (freq1 / 8000.0)) * 32768.0;
00305       d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (freq1 / 8000.0)) * d.vol;
00306       d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (freq1 / 8000.0)) * d.vol;
00307 
00308       d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (freq2 / 8000.0)) * 32768.0;
00309       d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (freq2 / 8000.0)) * d.vol;
00310       d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (freq2 / 8000.0)) * d.vol;
00311       d.items[d.nitems].duration = time;
00312       d.items[d.nitems].modulate = modulate;
00313       d.nitems++;
00314 
00315       s = strsep(&stringp,separator);
00316    }
00317 
00318    if (ast_activate_generator(chan, &playtones, &d)) {
00319       free(d.items);
00320       return -1;
00321    }
00322    return 0;
00323 }

void ast_playtones_stop ( struct ast_channel chan  ) 

Stop the tones from playing

Definition at line 325 of file indications.c.

References ast_deactivate_generator().

00326 {
00327    ast_deactivate_generator(chan);
00328 }

static int attempt_reconnect ( struct rpt myrpt,
struct rpt_link l 
) [static]

Definition at line 8294 of file app_rpt.c.

References ast_call(), AST_FORMAT_SLINEAR, ast_log(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_verbose(), free, rpt::links, rpt::lock, LOG_NOTICE, rpt::name, rpt_link::name, rpt_link::next, node_lookup(), option_verbose, rpt_mutex_lock, rpt_mutex_unlock, s, strdup, strsep(), and VERBOSE_PREFIX_3.

Referenced by rpt().

08295 {
08296    char *val, *s, *s1, *s2, *tele;
08297    char tmp[300], deststr[300] = "";
08298 
08299    val = node_lookup(myrpt,l->name);
08300    if (!val)
08301    {
08302       fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name);
08303       return -1;
08304    }
08305 
08306    rpt_mutex_lock(&myrpt->lock);
08307    /* remove from queue */
08308    remque((struct qelem *) l);
08309    rpt_mutex_unlock(&myrpt->lock);
08310    strncpy(tmp,val,sizeof(tmp) - 1);
08311    s = tmp;
08312    s1 = strsep(&s,",");
08313    s2 = strsep(&s,",");
08314    snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
08315    tele = strchr(deststr, '/');
08316    if (!tele) {
08317       fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr);
08318       return -1;
08319    }
08320    *tele++ = 0;
08321    l->elaptime = 0;
08322    l->connecttime = 0;
08323    l->thisconnected = 0;
08324    l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
08325    if (l->chan){
08326       ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
08327       ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
08328       l->chan->whentohangup = 0;
08329       l->chan->appl = "Apprpt";
08330       l->chan->data = "(Remote Rx)";
08331       if (option_verbose > 2)
08332          ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n",
08333             deststr, tele, l->chan->name);
08334       if(l->chan->cid.cid_num)
08335          free(l->chan->cid.cid_num);
08336       l->chan->cid.cid_num = strdup(myrpt->name);
08337                 ast_call(l->chan,tele,999); 
08338 
08339    }
08340    else 
08341    {
08342       if (option_verbose > 2)
08343          ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n",
08344             deststr,tele,l->chan->name);
08345       return -1;
08346    }
08347    rpt_mutex_lock(&myrpt->lock);
08348    /* put back in queue */
08349    insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
08350    rpt_mutex_unlock(&myrpt->lock);
08351    ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name);
08352    return 0;
08353 }

static int check_freq ( struct rpt myrpt,
int  m,
int  d,
int *  defmode 
) [static]

Definition at line 7306 of file app_rpt.c.

References check_freq_ft897(), check_freq_ic706(), check_freq_kenwood(), check_freq_rbi(), and rpt::remote.

Referenced by function_remote().

07307 {
07308    if(!strcmp(myrpt->remote, remote_rig_ft897))
07309       return check_freq_ft897(m, d, defmode);
07310    else if(!strcmp(myrpt->remote, remote_rig_ic706))
07311       return check_freq_ic706(m, d, defmode);
07312    else if(!strcmp(myrpt->remote, remote_rig_rbi))
07313       return check_freq_rbi(m, d, defmode);
07314    else if(!strcmp(myrpt->remote, remote_rig_kenwood))
07315       return check_freq_kenwood(m, d, defmode);
07316    else
07317       return -1;
07318 }

static int check_freq_ft897 ( int  m,
int  d,
int *  defmode 
) [static]

Definition at line 6321 of file app_rpt.c.

References REM_MODE_FM, REM_MODE_LSB, and REM_MODE_USB.

Referenced by check_freq(), and multimode_bump_freq_ft897().

06322 {
06323    int dflmd = REM_MODE_FM;
06324 
06325    if(m == 1){ /* 160 meters */
06326       dflmd =  REM_MODE_LSB; 
06327       if(d < 80000)
06328          return -1;
06329    }
06330    else if(m == 3){ /* 80 meters */
06331       dflmd = REM_MODE_LSB;
06332       if(d < 50000)
06333          return -1;
06334    }
06335    else if(m == 7){ /* 40 meters */
06336       dflmd = REM_MODE_LSB;
06337       if(d > 30000)
06338          return -1;
06339    }
06340    else if(m == 14){ /* 20 meters */
06341       dflmd = REM_MODE_USB;
06342       if(d > 35000)
06343          return -1;
06344    }
06345    else if(m == 18){ /* 17 meters */
06346       dflmd = REM_MODE_USB;
06347       if((d < 6800) || (d > 16800))
06348          return -1;
06349    }
06350    else if(m == 21){ /* 15 meters */
06351       dflmd = REM_MODE_USB;
06352       if((d < 20000) || (d > 45000))
06353          return -1;
06354    }
06355    else if(m == 24){ /* 12 meters */
06356       dflmd = REM_MODE_USB;
06357       if((d < 89000) || (d > 99000))
06358          return -1;
06359    }
06360    else if(m == 28){ /* 10 meters */
06361       dflmd = REM_MODE_USB;
06362    }
06363    else if(m == 29){ 
06364       if(d >= 51000)
06365          dflmd = REM_MODE_FM;
06366       else
06367          dflmd = REM_MODE_USB;
06368       if(d > 70000)
06369          return -1;
06370    }
06371    else if(m == 50){ /* 6 meters */
06372       if(d >= 30000)
06373          dflmd = REM_MODE_FM;
06374       else
06375          dflmd = REM_MODE_USB;
06376 
06377    }
06378    else if((m >= 51) && ( m < 54)){
06379       dflmd = REM_MODE_FM;
06380    }
06381    else if(m == 144){ /* 2 meters */
06382       if(d >= 30000)
06383          dflmd = REM_MODE_FM;
06384       else
06385          dflmd = REM_MODE_USB;
06386    }
06387    else if((m >= 145) && (m < 148)){
06388       dflmd = REM_MODE_FM;
06389    }
06390    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06391       if(m  < 438)
06392          dflmd = REM_MODE_USB;
06393       else
06394          dflmd = REM_MODE_FM;
06395       ;
06396    }
06397    else
06398       return -1;
06399 
06400    if(defmode)
06401       *defmode = dflmd;
06402 
06403    return 0;
06404 }

static int check_freq_ic706 ( int  m,
int  d,
int *  defmode 
) [static]

Definition at line 6692 of file app_rpt.c.

References REM_MODE_FM, REM_MODE_LSB, and REM_MODE_USB.

Referenced by check_freq(), and multimode_bump_freq_ic706().

06693 {
06694    int dflmd = REM_MODE_FM;
06695 
06696    if(m == 1){ /* 160 meters */
06697       dflmd =  REM_MODE_LSB; 
06698       if(d < 80000)
06699          return -1;
06700    }
06701    else if(m == 3){ /* 80 meters */
06702       dflmd = REM_MODE_LSB;
06703       if(d < 50000)
06704          return -1;
06705    }
06706    else if(m == 7){ /* 40 meters */
06707       dflmd = REM_MODE_LSB;
06708       if(d > 30000)
06709          return -1;
06710    }
06711    else if(m == 14){ /* 20 meters */
06712       dflmd = REM_MODE_USB;
06713       if(d > 35000)
06714          return -1;
06715    }
06716    else if(m == 18){ /* 17 meters */
06717       dflmd = REM_MODE_USB;
06718       if((d < 6800) || (d > 16800))
06719          return -1;
06720    }
06721    else if(m == 21){ /* 15 meters */
06722       dflmd = REM_MODE_USB;
06723       if((d < 20000) || (d > 45000))
06724          return -1;
06725    }
06726    else if(m == 24){ /* 12 meters */
06727       dflmd = REM_MODE_USB;
06728       if((d < 89000) || (d > 99000))
06729          return -1;
06730    }
06731    else if(m == 28){ /* 10 meters */
06732       dflmd = REM_MODE_USB;
06733    }
06734    else if(m == 29){ 
06735       if(d >= 51000)
06736          dflmd = REM_MODE_FM;
06737       else
06738          dflmd = REM_MODE_USB;
06739       if(d > 70000)
06740          return -1;
06741    }
06742    else if(m == 50){ /* 6 meters */
06743       if(d >= 30000)
06744          dflmd = REM_MODE_FM;
06745       else
06746          dflmd = REM_MODE_USB;
06747 
06748    }
06749    else if((m >= 51) && ( m < 54)){
06750       dflmd = REM_MODE_FM;
06751    }
06752    else if(m == 144){ /* 2 meters */
06753       if(d >= 30000)
06754          dflmd = REM_MODE_FM;
06755       else
06756          dflmd = REM_MODE_USB;
06757    }
06758    else if((m >= 145) && (m < 148)){
06759       dflmd = REM_MODE_FM;
06760    }
06761    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06762       if(m  < 438)
06763          dflmd = REM_MODE_USB;
06764       else
06765          dflmd = REM_MODE_FM;
06766       ;
06767    }
06768    else
06769       return -1;
06770 
06771    if(defmode)
06772       *defmode = dflmd;
06773 
06774    return 0;
06775 }

static int check_freq_kenwood ( int  m,
int  d,
int *  defmode 
) [static]

Definition at line 6183 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

06184 {
06185    int dflmd = REM_MODE_FM;
06186 
06187    if (m == 144){ /* 2 meters */
06188       if(d < 10100)
06189          return -1;
06190    }
06191    else if((m >= 145) && (m < 148)){
06192       ;
06193    }
06194    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06195       ;
06196    }
06197    else
06198       return -1;
06199    
06200    if(defmode)
06201       *defmode = dflmd; 
06202 
06203 
06204    return 0;
06205 }

static int check_freq_rbi ( int  m,
int  d,
int *  defmode 
) [static]

Definition at line 6211 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

06212 {
06213    int dflmd = REM_MODE_FM;
06214 
06215    if(m == 50){ /* 6 meters */
06216       if(d < 10100)
06217          return -1;
06218    }
06219    else if((m >= 51) && ( m < 54)){
06220                 ;
06221    }
06222    else if(m == 144){ /* 2 meters */
06223       if(d < 10100)
06224          return -1;
06225    }
06226    else if((m >= 145) && (m < 148)){
06227       ;
06228    }
06229    else if((m >= 222) && (m < 225)){ /* 1.25 meters */
06230       ;
06231    }
06232    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06233       ;
06234    }
06235    else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */
06236       ;
06237    }
06238    else
06239       return -1;
06240    
06241    if(defmode)
06242       *defmode = dflmd; 
06243 
06244 
06245    return 0;
06246 }

static char check_tx_freq ( struct rpt myrpt  )  [static]

Definition at line 7324 of file app_rpt.c.

References ast_log(), ast_variable_browse(), rpt::cfg, decimals2int(), eatwhite(), finddelim(), rpt::freq, LOG_NOTICE, LOG_WARNING, rpt::loginlevel, rpt::loginuser, MAXREMSTR, ast_variable::name, ast_variable::next, rpt::p, s, split_freq(), rpt::txlimitsstanzaname, and ast_variable::value.

Referenced by rpt_exec().

07325 {
07326    int i;
07327    int radio_mhz, radio_decimals, ulimit_mhz, ulimit_decimals, llimit_mhz, llimit_decimals;
07328    char radio_mhz_char[MAXREMSTR];
07329    char radio_decimals_char[MAXREMSTR];
07330    char limit_mhz_char[MAXREMSTR];
07331    char limit_decimals_char[MAXREMSTR];
07332    char limits[256];
07333    char *limit_ranges[40];
07334    struct ast_variable *limitlist;
07335    
07336 
07337    /* Must have user logged in and tx_limits defined */
07338 
07339    if(!myrpt->p.txlimitsstanzaname || !myrpt->loginuser[0] || !myrpt->loginlevel[0]){
07340       if(debug > 3){
07341          ast_log(LOG_NOTICE, "No tx band table defined, or no user logged in\n");
07342       }
07343       return 1; /* Assume it's ok otherwise */
07344    }
07345 
07346    /* Retrieve the band table for the loginlevel */
07347    limitlist = ast_variable_browse(myrpt->cfg, myrpt->p.txlimitsstanzaname);
07348 
07349    if(!limitlist){
07350       ast_log(LOG_WARNING, "No entries in %s band table stanza\n", myrpt->p.txlimitsstanzaname);
07351       return 0;
07352    }
07353 
07354    split_freq(radio_mhz_char, radio_decimals_char, myrpt->freq);
07355    radio_mhz = atoi(radio_mhz_char);
07356    radio_decimals = decimals2int(radio_decimals_char);
07357 
07358 
07359    if(debug > 3){
07360       ast_log(LOG_NOTICE, "Login User = %s, login level = %s\n", myrpt->loginuser, myrpt->loginlevel);
07361    }
07362 
07363    /* Find our entry */
07364 
07365    for(;limitlist; limitlist=limitlist->next){
07366       if(!strcmp(limitlist->name, myrpt->loginlevel))
07367          break;
07368    }
07369 
07370    if(!limitlist){
07371       ast_log(LOG_WARNING, "Can't find %s entry in band table stanza %s\n", myrpt->loginlevel, myrpt->p.txlimitsstanzaname);
07372       return 0;
07373    }
07374    
07375    if(debug > 3){
07376       ast_log(LOG_NOTICE, "Auth %s = %s\n", limitlist->name, limitlist->value);
07377    }
07378 
07379    /* Parse the limits */
07380 
07381    strncpy(limits, limitlist->value, 256);
07382    limits[255] = 0;
07383    finddelim(limits, limit_ranges, 40);
07384    for(i = 0; i < 40 && limit_ranges[i] ; i++){
07385       char range[40];
07386       char *r,*s;
07387       strncpy(range, limit_ranges[i], 40);
07388       range[39] = 0;
07389                 if(debug > 3){
07390          ast_log(LOG_NOTICE, "Checking to see if %s is within limits of %s\n", myrpt->freq, range);
07391                 }        
07392    
07393       r = strchr(range, '-');
07394       if(!r){
07395          ast_log(LOG_WARNING, "Malformed range in %s tx band table entry\n", limitlist->name);
07396          return 0;
07397       }
07398       *r++ = 0;
07399       s = eatwhite(range);
07400       r = eatwhite(r);
07401       split_freq(limit_mhz_char, limit_decimals_char, s);
07402       llimit_mhz = atoi(limit_mhz_char);
07403       llimit_decimals = decimals2int(limit_decimals_char);
07404       split_freq(limit_mhz_char, limit_decimals_char, r);
07405       ulimit_mhz = atoi(limit_mhz_char);
07406       ulimit_decimals = decimals2int(limit_decimals_char);
07407          
07408       if((radio_mhz >= llimit_mhz) && (radio_mhz <= ulimit_mhz)){
07409          if(radio_mhz == llimit_mhz){ /* CASE 1: TX freq is in llimit mhz portion of band */
07410             if(radio_decimals >= llimit_decimals){ /* Cannot be below llimit decimals */
07411                if(llimit_mhz == ulimit_mhz){ /* If bandwidth < 1Mhz, check ulimit decimals */
07412                   if(radio_decimals <= ulimit_decimals){
07413                      return 1;
07414                   }
07415                   else{
07416                      if(debug > 3)
07417                         ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 1\n");
07418                      return 0;
07419                   }
07420                }
07421                else{
07422                   return 1;
07423                }
07424             }
07425             else{ /* Is below llimit decimals */
07426                if(debug > 3)
07427                   ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 2\n");
07428                return 0;
07429             }
07430          }
07431          else if(radio_mhz == ulimit_mhz){ /* CASE 2: TX freq not in llimit mhz portion of band */
07432             if(radio_decimals <= ulimit_decimals){
07433                return 1;
07434             }
07435             else{ /* Is above ulimit decimals */
07436                if(debug > 3)
07437                   ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 3\n");
07438                return 0;
07439             }
07440          }
07441          else /* CASE 3: TX freq within a multi-Mhz band and ok */
07442             return 1; 
07443       }
07444    }
07445    if(debug > 3) /* No match found in TX band table */
07446       ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 4\n");
07447    return 0;
07448 }

static int civ_cmd ( struct rpt myrpt,
unsigned char *  cmd,
int  cmdlen 
) [static]

Definition at line 5859 of file app_rpt.c.

References serial_remote_io().

Referenced by mem2vfo_ic706(), select_mem_ic706(), set_ctcss_mode_ic706(), set_freq_ic706(), simple_command_ic706(), and vfo_ic706().

05860 {
05861 unsigned char rxbuf[100];
05862 int   i,rv ;
05863 
05864    rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0);
05865    if (rv == -1) return(-1);
05866    if (rv != (cmdlen + 6)) return(1);
05867    for(i = 0; i < 6; i++)
05868       if (rxbuf[i] != cmd[i]) return(1);
05869    if (rxbuf[cmdlen] != 0xfe) return(1);
05870    if (rxbuf[cmdlen + 1] != 0xfe) return(1);
05871    if (rxbuf[cmdlen + 4] != 0xfb) return(1);
05872    if (rxbuf[cmdlen + 5] != 0xfd) return(1);
05873    return(0);
05874 }

static int closerem ( struct rpt myrpt  )  [static]

Definition at line 7294 of file app_rpt.c.

References closerem_ft897(), and rpt::remote.

Referenced by rpt_exec().

07295 {
07296    if(!strcmp(myrpt->remote, remote_rig_ft897))
07297       return closerem_ft897(myrpt);
07298    else
07299       return 0;
07300 }

static int closerem_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6632 of file app_rpt.c.

References simple_command_ft897().

Referenced by closerem().

06633 {
06634    simple_command_ft897(myrpt, 0x88); /* PTT off */
06635    return 0;
06636 }  

static int collect_function_digits ( struct rpt myrpt,
char *  digits,
int  command_source,
struct rpt_link mylink 
) [static]

Definition at line 5147 of file app_rpt.c.

References ast_variable_browse(), rpt::cfg, DC_ERROR, DC_INDETERMINATE, rpt::dphone_functions, rpt::dphone_longestfunc, rpt::functions, rpt::link_functions, rpt::link_longestfunc, rpt::longestfunc, ast_variable::name, ast_variable::next, rpt::p, rpt::phone_functions, rpt::phone_longestfunc, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, strsep(), and ast_variable::value.

Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and local_dtmf_helper().

05149 {
05150    int i;
05151    char *stringp,*action,*param,*functiondigits;
05152    char function_table_name[30] = "";
05153    char workstring[200];
05154    
05155    struct ast_variable *vp;
05156    
05157    if(debug)   
05158       printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source);
05159    
05160    if (command_source == SOURCE_DPHONE) {
05161       if (!myrpt->p.dphone_functions) return DC_INDETERMINATE;
05162       strncpy(function_table_name, myrpt->p.dphone_functions, sizeof(function_table_name) - 1);
05163       }
05164    else if (command_source == SOURCE_PHONE) {
05165       if (!myrpt->p.phone_functions) return DC_INDETERMINATE;
05166       strncpy(function_table_name, myrpt->p.phone_functions, sizeof(function_table_name) - 1);
05167       }
05168    else if (command_source == SOURCE_LNK)
05169       strncpy(function_table_name, myrpt->p.link_functions, sizeof(function_table_name) - 1);
05170    else
05171       strncpy(function_table_name, myrpt->p.functions, sizeof(function_table_name) - 1);
05172    vp = ast_variable_browse(myrpt->cfg, function_table_name);
05173    while(vp) {
05174       if(!strncasecmp(vp->name, digits, strlen(vp->name)))
05175          break;
05176       vp = vp->next;
05177    }  
05178    if(!vp) {
05179       int n;
05180 
05181       n = myrpt->longestfunc;
05182       if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc;
05183       else 
05184       if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc;
05185       else 
05186       if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc;
05187       
05188       if(strlen(digits) >= n)
05189          return DC_ERROR;
05190       else
05191          return DC_INDETERMINATE;
05192    }  
05193    /* Found a match, retrieve value part and parse */
05194    strncpy(workstring, vp->value, sizeof(workstring) - 1 );
05195    stringp = workstring;
05196    action = strsep(&stringp, ",");
05197    param = stringp;
05198    if(debug)
05199       printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)");
05200    /* Look up the action */
05201    for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){
05202       if(!strncasecmp(action, function_table[i].action, strlen(action)))
05203          break;
05204    }
05205    if(debug)
05206       printf("@@@@ table index i = %d\n",i);
05207    if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){
05208       /* Error, action not in table */
05209       return DC_ERROR;
05210    }
05211    if(function_table[i].function == NULL){
05212       /* Error, function undefined */
05213       if(debug)
05214          printf("@@@@ NULL for action: %s\n",action);
05215       return DC_ERROR;
05216    }
05217    functiondigits = digits + strlen(vp->name);
05218    return (*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink);
05219 }

static int connect_link ( struct rpt myrpt,
char *  node,
int  mode,
int  perma 
) [static]

Definition at line 4408 of file app_rpt.c.

References __kickshort(), __mklinklist(), rpt::archivedir, ast_call(), AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_true(), rpt_link::chan, rpt::conf, rpt_link::disced, donodelog(), finddelim(), free, rpt::lastlinknode, rpt::links, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::longestnode, malloc, MAX_RETRIES, rpt_link::max_retries, MAX_RETRIES_PERM, MAXLINKLIST, MAXNODESTR, rpt_link::mode, rpt::name, rpt_link::name, rpt_link::next, node_lookup(), rpt::p, rpt_link::reconnects, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, s, strdup, and strsep().

Referenced by function_ilink().

04409 {
04410    char *val, *s, *s1, *s2, *tele;
04411    char lstr[MAXLINKLIST],*strs[MAXLINKLIST];
04412    char tmp[300], deststr[300] = "",modechange = 0;
04413    struct rpt_link *l;
04414    int reconnects = 0;
04415    int i,n;
04416    ZT_CONFINFO ci;  /* conference info */
04417 
04418    val = node_lookup(myrpt,node);
04419    if (!val){
04420       if(strlen(node) >= myrpt->longestnode)
04421          return -1; /* No such node */
04422       return 1; /* No match yet */
04423    }
04424    if(debug > 3){
04425       ast_log(LOG_NOTICE,"Connect attempt to node %s\n", node);
04426       ast_log(LOG_NOTICE,"Mode: %s\n",(mode)?"Transceive":"Monitor");
04427       ast_log(LOG_NOTICE,"Connection type: %s\n",(perma)?"Permalink":"Normal");
04428    }
04429 
04430    strncpy(tmp,val,sizeof(tmp) - 1);
04431    s = tmp;
04432    s1 = strsep(&s,",");
04433    s2 = strsep(&s,",");
04434    rpt_mutex_lock(&myrpt->lock);
04435    l = myrpt->links.next;
04436    /* try to find this one in queue */
04437    while(l != &myrpt->links){
04438       if (l->name[0] == '0') 
04439       {
04440          l = l->next;
04441          continue;
04442       }
04443    /* if found matching string */
04444       if (!strcmp(l->name, node))
04445          break;
04446       l = l->next;
04447    }
04448    /* if found */
04449    if (l != &myrpt->links){ 
04450    /* if already in this mode, just ignore */
04451       if ((l->mode) || (!l->chan)) {
04452          rpt_mutex_unlock(&myrpt->lock);
04453          return 2; /* Already linked */
04454       }
04455       reconnects = l->reconnects;
04456       rpt_mutex_unlock(&myrpt->lock);
04457       if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV);
04458       l->retries = l->max_retries + 1;
04459       l->disced = 2;
04460       modechange = 1;
04461    } else
04462    {
04463       __mklinklist(myrpt,NULL,lstr);
04464       rpt_mutex_unlock(&myrpt->lock);
04465       n = finddelim(lstr,strs,MAXLINKLIST);
04466       for(i = 0; i < n; i++)
04467       {
04468          if ((*strs[i] < '0') || 
04469              (*strs[i] > '9')) strs[i]++;
04470          if (!strcmp(strs[i],node))
04471          {
04472             return 2; /* Already linked */
04473          }
04474       }
04475    }
04476    strncpy(myrpt->lastlinknode,node,MAXNODESTR - 1);
04477    /* establish call */
04478    l = malloc(sizeof(struct rpt_link));
04479    if (!l)
04480    {
04481       ast_log(LOG_WARNING, "Unable to malloc\n");
04482       return -1;
04483    }
04484    /* zero the silly thing */
04485    memset((char *)l,0,sizeof(struct rpt_link));
04486    l->mode = mode;
04487    l->outbound = 1;
04488    l->thisconnected = 0;
04489    strncpy(l->name, node, MAXNODESTR - 1);
04490    l->isremote = (s && ast_true(s));
04491    if (modechange) l->connected = 1;
04492    l->hasconnected = l->perma = perma;
04493    snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
04494    tele = strchr(deststr, '/');
04495    if (!tele){
04496       ast_log(LOG_WARNING,"link3:Dial number (%s) must be in format tech/number\n",deststr);
04497       free(l);
04498       return -1;
04499    }
04500    *tele++ = 0;
04501    l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
04502    if (l->chan){
04503       ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
04504       ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
04505       l->chan->whentohangup = 0;
04506       l->chan->appl = "Apprpt";
04507       l->chan->data = "(Remote Rx)";
04508       if (debug > 3)
04509          ast_log(LOG_NOTICE, "rpt (remote) initiating call to %s/%s on %s\n",
04510       deststr, tele, l->chan->name);
04511       if(l->chan->cid.cid_num)
04512          free(l->chan->cid.cid_num);
04513       l->chan->cid.cid_num = strdup(myrpt->name);
04514       ast_call(l->chan,tele,999);
04515    }
04516    else {
04517       if(debug > 3) 
04518          ast_log(LOG_NOTICE, "Unable to place call to %s/%s on %s\n",
04519       deststr,tele,l->chan->name);
04520       if (myrpt->p.archivedir)
04521       {
04522          char str[100];
04523          sprintf(str,"LINKFAIL,%s",l->name);
04524          donodelog(myrpt,str);
04525       }
04526       free(l);
04527       return -1;
04528    }
04529    /* allocate a pseudo-channel thru asterisk */
04530    l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
04531    if (!l->pchan){
04532       ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n");
04533       ast_hangup(l->chan);
04534       free(l);
04535       return -1;
04536    }
04537    ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR);
04538    ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR);
04539    /* make a conference for the tx */
04540    ci.chan = 0;
04541    ci.confno = myrpt->conf;
04542    ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER;
04543    /* first put the channel on the conference in proper mode */
04544    if (ioctl(l->pchan->fds[0], ZT_SETCONF, &ci) == -1)
04545    {
04546       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04547       ast_hangup(l->chan);
04548       ast_hangup(l->pchan);
04549       free(l);
04550       return -1;
04551    }
04552    rpt_mutex_lock(&myrpt->lock);
04553    l->reconnects = reconnects;
04554    /* insert at end of queue */
04555    l->max_retries = MAX_RETRIES;
04556    if (perma)
04557       l->max_retries = MAX_RETRIES_PERM;
04558    if (l->isremote) l->retries = l->max_retries + 1;
04559    insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
04560    __kickshort(myrpt);
04561    rpt_mutex_unlock(&myrpt->lock);
04562    return 0;
04563 }

static int decimals2int ( char *  fraction  )  [static]

Definition at line 6252 of file app_rpt.c.

Referenced by check_tx_freq().

06253 {
06254    int i;
06255    char len = strlen(fraction);
06256    int multiplier = 100000;
06257    int res = 0;
06258 
06259    if(!len)
06260       return 0;
06261    for( i = 0 ; i < len ; i++, multiplier /= 10)
06262       res += (fraction[i] - '0') * multiplier;
06263    return res;
06264 }

static long diskavail ( struct rpt myrpt  )  [static]

Definition at line 1023 of file app_rpt.c.

References rpt::archivedir, ast_log(), LOG_WARNING, rpt::name, and rpt::p.

Referenced by rpt(), and rpt_exec().

01024 {
01025 struct   statfs statfsbuf;
01026 
01027    if (!myrpt->p.archivedir) return(0);
01028    if (statfs(myrpt->p.archivedir,&statfsbuf) == -1)
01029    {
01030       ast_log(LOG_WARNING,"Cannot get filesystem size for %s node %s\n",
01031          myrpt->p.archivedir,myrpt->name);
01032       return(-1);
01033    }
01034    return(statfsbuf.f_bavail);
01035 }

static void do_dtmf_local ( struct rpt myrpt,
char  c 
) [static]

Definition at line 1088 of file app_rpt.c.

References ast_log(), ast_playtones_start(), DTMF_LOCAL_STARTTIME, rpt::dtmf_local_str, DTMF_LOCAL_TIME, rpt::dtmf_local_timer, rpt::lock, LOG_DEBUG, rpt_mutex_lock, rpt_mutex_unlock, and rpt::txchannel.

Referenced by function_ilink(), function_remote(), handle_link_data(), handle_remote_dtmf_digit(), rpt(), and rpt_exec().

01089 {
01090 int   i;
01091 char  digit;
01092 static const char* dtmf_tones[] = {
01093    "!941+1336/200,!0/200", /* 0 */
01094    "!697+1209/200,!0/200", /* 1 */
01095    "!697+1336/200,!0/200", /* 2 */
01096    "!697+1477/200,!0/200", /* 3 */
01097    "!770+1209/200,!0/200", /* 4 */
01098    "!770+1336/200,!0/200", /* 5 */
01099    "!770+1477/200,!0/200", /* 6 */
01100    "!852+1209/200,!0/200", /* 7 */
01101    "!852+1336/200,!0/200", /* 8 */
01102    "!852+1477/200,!0/200", /* 9 */
01103    "!697+1633/200,!0/200", /* A */
01104    "!770+1633/200,!0/200", /* B */
01105    "!852+1633/200,!0/200", /* C */
01106    "!941+1633/200,!0/200", /* D */
01107    "!941+1209/200,!0/200", /* * */
01108    "!941+1477/200,!0/200" };  /* # */
01109 
01110 
01111    if (c)
01112    {
01113       snprintf(myrpt->dtmf_local_str + strlen(myrpt->dtmf_local_str),sizeof(myrpt->dtmf_local_str) - 1,"%c",c);
01114       if (!myrpt->dtmf_local_timer) 
01115           myrpt->dtmf_local_timer = DTMF_LOCAL_STARTTIME;
01116    }
01117    /* if at timeout */
01118    if (myrpt->dtmf_local_timer == 1)
01119    {
01120       /* if anything in the string */
01121       if (myrpt->dtmf_local_str[0])
01122       {
01123          digit = myrpt->dtmf_local_str[0];
01124          myrpt->dtmf_local_str[0] = 0;
01125          for(i = 1; myrpt->dtmf_local_str[i]; i++)
01126          {
01127             myrpt->dtmf_local_str[i - 1] =
01128                myrpt->dtmf_local_str[i];
01129          }
01130          myrpt->dtmf_local_str[i - 1] = 0;
01131          myrpt->dtmf_local_timer = DTMF_LOCAL_TIME;
01132          rpt_mutex_unlock(&myrpt->lock);
01133          if (digit >= '0' && digit <='9')
01134             ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'0'], 0);
01135          else if (digit >= 'A' && digit <= 'D')
01136             ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'A'+10], 0);
01137          else if (digit == '*')
01138             ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[14], 0);
01139          else if (digit == '#')
01140             ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[15], 0);
01141          else {
01142             /* not handled */
01143             ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, myrpt->txchannel->name);
01144          }
01145          rpt_mutex_lock(&myrpt->lock);
01146       }
01147       else
01148       {
01149          myrpt->dtmf_local_timer = 0;
01150       }
01151    }
01152 }

static void do_dtmf_phone ( struct rpt myrpt,
struct rpt_link mylink,
char  c 
) [static]

Definition at line 1037 of file app_rpt.c.

References ast_senddigit(), rpt_link::chan, rpt::links, rpt_link::next, and rpt_link::phonemode.

Referenced by handle_link_data(), and local_dtmf_helper().

01038 {
01039 struct        rpt_link *l;
01040 
01041        l = myrpt->links.next;
01042        /* go thru all the links */
01043        while(l != &myrpt->links)
01044        {
01045                if (!l->phonemode)
01046                {
01047                        l = l->next;
01048                        continue;
01049                }
01050                /* dont send to self */
01051                if (mylink && (l == mylink))
01052                {
01053                        l = l->next;
01054                        continue;
01055                }
01056                if (l->chan) ast_senddigit(l->chan,c);
01057                l = l->next;
01058        }
01059        return;
01060 }

static void do_scheduler ( struct rpt myrpt  )  [static]

Definition at line 8529 of file app_rpt.c.

References ast_log(), ast_variable_browse(), ast_variable_retrieve(), rpt::cfg, rpt::curtv, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, LOG_NOTICE, LOG_WARNING, rpt::macro, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, ast_variable::name, ast_variable::next, rpt::p, rpt::remote, rpt_localtime(), rpt::s, sysstate::schedulerdisable, rpt::skedstanzaname, rpt::sysstate_cur, and ast_variable::value.

Referenced by rpt().

08530 {
08531    int i,res;
08532    struct tm tmnow;
08533    struct ast_variable *skedlist;
08534    char *strs[5],*vp,*val,value[100];
08535 
08536    memcpy(&myrpt->lasttv, &myrpt->curtv, sizeof(struct timeval));
08537    
08538    if( (res = gettimeofday(&myrpt->curtv, NULL)) < 0)
08539       ast_log(LOG_NOTICE, "Scheduler gettime of day returned: %s\n", strerror(res));
08540 
08541    /* Try to get close to a 1 second resolution */
08542    
08543    if(myrpt->lasttv.tv_sec == myrpt->curtv.tv_sec)
08544       return;
08545 
08546    rpt_localtime(&myrpt->curtv.tv_sec, &tmnow);
08547 
08548    /* If midnight, then reset all daily statistics */
08549    
08550    if((tmnow.tm_hour == 0)&&(tmnow.tm_min == 0)&&(tmnow.tm_sec == 0)){
08551       myrpt->dailykeyups = 0;
08552       myrpt->dailytxtime = 0;
08553       myrpt->dailykerchunks = 0;
08554       myrpt->dailyexecdcommands = 0;
08555    }
08556 
08557    if(tmnow.tm_sec != 0)
08558       return;
08559 
08560    /* Code below only executes once per minute */
08561 
08562 
08563    /* Don't schedule if remote */
08564 
08565         if (myrpt->remote)
08566                 return;
08567 
08568    /* Don't schedule if disabled */
08569 
08570         if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable){
08571       if(debug > 6)
08572          ast_log(LOG_NOTICE, "Scheduler disabled\n");
08573       return;
08574    }
08575 
08576    if(!myrpt->p.skedstanzaname){ /* No stanza means we do nothing */
08577       if(debug > 6)
08578          ast_log(LOG_NOTICE,"No stanza for scheduler in rpt.conf\n");
08579       return;
08580    }
08581 
08582         /* get pointer to linked list of scheduler entries */
08583         skedlist = ast_variable_browse(myrpt->cfg, myrpt->p.skedstanzaname);
08584 
08585    if(debug > 6){
08586       ast_log(LOG_NOTICE, "Time now: %02d:%02d %02d %02d %02d\n",
08587          tmnow.tm_hour,tmnow.tm_min,tmnow.tm_mday,tmnow.tm_mon + 1, tmnow.tm_wday); 
08588    }
08589    /* walk the list */
08590    for(; skedlist; skedlist = skedlist->next){
08591       if(debug > 6)
08592          ast_log(LOG_NOTICE, "Scheduler entry %s = %s being considered\n",skedlist->name, skedlist->value);
08593       strncpy(value,skedlist->value,99);
08594       value[99] = 0;
08595       /* point to the substrings for minute, hour, dom, month, and dow */
08596       for( i = 0, vp = value ; i < 5; i++){
08597          if(!*vp)
08598             break;
08599          while((*vp == ' ') || (*vp == 0x09)) /* get rid of any leading white space */
08600             vp++;
08601          strs[i] = vp; /* save pointer to beginning of substring */
08602          while((*vp != ' ') && (*vp != 0x09) && (*vp != 0)) /* skip over substring */
08603             vp++;
08604          if(*vp)
08605             *vp++ = 0; /* mark end of substring */
08606       }
08607       if(debug > 6)
08608          ast_log(LOG_NOTICE, "i = %d, min = %s, hour = %s, mday=%s, mon=%s, wday=%s\n",i,
08609             strs[0], strs[1], strs[2], strs[3], strs[4]); 
08610       if(i == 5){
08611          if((*strs[0] != '*')&&(atoi(strs[0]) != tmnow.tm_min))
08612             continue;
08613          if((*strs[1] != '*')&&(atoi(strs[1]) != tmnow.tm_hour))
08614             continue;
08615          if((*strs[2] != '*')&&(atoi(strs[2]) != tmnow.tm_mday))
08616             continue;
08617          if((*strs[3] != '*')&&(atoi(strs[3]) != tmnow.tm_mon + 1))
08618             continue;
08619          if(atoi(strs[4]) == 7)
08620             strs[4] = "0";
08621          if((*strs[4] != '*')&&(atoi(strs[4]) != tmnow.tm_wday))
08622             continue;
08623          if(debug)
08624             ast_log(LOG_NOTICE, "Executing scheduler entry %s = %s\n", skedlist->name, skedlist->value);
08625          if(atoi(skedlist->name) == 0)
08626             return; /* Zero is reserved for the startup macro */
08627          val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, skedlist->name);
08628          if (!val){
08629             ast_log(LOG_WARNING,"Scheduler could not find macro %s\n",skedlist->name);
08630             return; /* Macro not found */
08631          }
08632          if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)){
08633             ast_log(LOG_WARNING, "Scheduler could not execute macro %s: Macro buffer full\n",
08634                skedlist->name);
08635             return; /* Macro buffer full */
08636          }
08637          myrpt->macrotimer = MACROTIME;
08638          strncat(myrpt->macrobuf,val,MAXMACRO - 1);
08639       }
08640       else{
08641          ast_log(LOG_WARNING,"Malformed scheduler entry in rpt.conf: %s = %s\n",
08642             skedlist->name, skedlist->value);
08643       }
08644    }
08645 
08646 }

static void donodelog ( struct rpt myrpt,
char *  str 
) [static]

Definition at line 1063 of file app_rpt.c.

References nodelog::archivedir, rpt::archivedir, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, malloc, rpt::name, rpt::p, nodelog::prev, nodelog::str, and nodelog::timestamp.

Referenced by connect_link(), function_remote(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_data(), handle_remote_phone_dtmf(), local_dtmf_helper(), rpt(), rpt_exec(), and setrem().

01064 {
01065 struct nodelog *nodep;
01066 char  datestr[100];
01067 
01068    if (!myrpt->p.archivedir) return;
01069    nodep = (struct nodelog *)malloc(sizeof(struct nodelog));
01070    if (nodep == NULL)
01071    {
01072       ast_log(LOG_ERROR,"Cannot get memory for node log");
01073       return;
01074    }
01075    time(&nodep->timestamp);
01076    strncpy(nodep->archivedir,myrpt->p.archivedir,
01077       sizeof(nodep->archivedir) - 1);
01078    strftime(datestr,sizeof(datestr) - 1,"%Y%m%d%H%M%S",
01079       localtime(&nodep->timestamp));
01080    snprintf(nodep->str,sizeof(nodep->str) - 1,"%s %s,%s\n",
01081       myrpt->name,datestr,str);
01082    ast_mutex_lock(&nodeloglock);
01083    insque((struct qelem *) nodep, (struct qelem *) nodelog.prev);
01084    ast_mutex_unlock(&nodeloglock);
01085 }

static char* eatwhite ( char *  s  )  [static]

Definition at line 1235 of file app_rpt.c.

Referenced by check_tx_freq().

01236 {
01237    while((*s == ' ') || (*s == 0x09)){ /* get rid of any leading white space */
01238       if(!*s)
01239          break;
01240       s++;
01241    }
01242    return s;
01243 }

static int finddelim ( char *  str,
char *  strp[],
int  limit 
) [static]

Definition at line 1255 of file app_rpt.c.

References DELIMCHR, and QUOTECHR.

Referenced by check_tx_freq(), connect_link(), function_autopatchup(), function_ilink(), load_rpt_vars(), rpt_do_nodes(), and rpt_tele_thread().

01256 {
01257 int     i,l,inquo;
01258 
01259         inquo = 0;
01260         i = 0;
01261         strp[i++] = str;
01262         if (!*str)
01263            {
01264                 strp[0] = 0;
01265                 return(0);
01266            }
01267         for(l = 0; *str && (l < limit) ; str++)
01268            {
01269                 if (*str == QUOTECHR)
01270                    {
01271                         if (inquo)
01272                            {
01273                                 *str = 0;
01274                                 inquo = 0;
01275                            }
01276                         else
01277                            {
01278                                 strp[i - 1] = str + 1;
01279                                 inquo = 1;
01280                            }
01281       }
01282                 if ((*str == DELIMCHR) && (!inquo))
01283                 {
01284                         *str = 0;
01285          l++;
01286                         strp[i++] = str + 1;
01287                 }
01288            }
01289         strp[i] = 0;
01290         return(i);
01291 
01292 }

static char func_xlat ( struct rpt myrpt,
char  c,
struct rpt_xlat xlat 
) [static]

Definition at line 1190 of file app_rpt.c.

References rpt::endchar, rpt_xlat::endcharseq, rpt_xlat::endindex, rpt::funcchar, rpt_xlat::funccharseq, rpt_xlat::funcindex, rpt_xlat::lastone, MAXXLATTIME, rpt::p, and rpt_xlat::passchars.

Referenced by handle_link_data(), handle_remote_data(), and rpt().

01191 {
01192 time_t   now;
01193 int   gotone;
01194 
01195    time(&now);
01196    gotone = 0;
01197    /* if too much time, reset the skate machine */
01198    if ((now - xlat->lastone) > MAXXLATTIME)
01199    {
01200       xlat->funcindex = xlat->endindex = 0;
01201    }
01202    if (xlat->funccharseq[0] && (c == xlat->funccharseq[xlat->funcindex++]))
01203    {
01204       time(&xlat->lastone);
01205       gotone = 1;
01206       if (!xlat->funccharseq[xlat->funcindex])
01207       {
01208          xlat->funcindex = xlat->endindex = 0;
01209          return(myrpt->p.funcchar);
01210       }
01211    } else xlat->funcindex = 0;
01212    if (xlat->endcharseq[0] && (c == xlat->endcharseq[xlat->endindex++]))
01213    {
01214       time(&xlat->lastone);
01215       gotone = 1;
01216       if (!xlat->endcharseq[xlat->endindex])
01217       {
01218          xlat->funcindex = xlat->endindex = 0;
01219          return(myrpt->p.endchar);
01220       }
01221    } else xlat->endindex = 0;
01222    /* if in middle of decode seq, send nothing back */
01223    if (gotone) return(0);
01224    /* if no pass chars specified, return em all */
01225    if (!xlat->passchars[0]) return(c);
01226    /* if a "pass char", pass it */
01227    if (strchr(xlat->passchars,c)) return(c);
01228    return(0);
01229 }

static int function_autopatchdn ( struct rpt myrpt,
char *  param,
char *  digitbuf,
int  command_source,
struct rpt_link mylink 
) [static]

Definition at line 4918 of file app_rpt.c.

References sysstate::autopatchdisable, rpt::callmode, DC_COMPLETE, DC_ERROR, rpt::lock, rpt::p, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::s, rpt::sysstate_cur, TERM, and sysstate::txdisable.

04919 {
04920    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
04921       return DC_ERROR;
04922    
04923    if(debug)
04924       printf("@@@@ Autopatch down\n");
04925       
04926    rpt_mutex_lock(&myrpt->lock);
04927    
04928    if (!myrpt->callmode){
04929       rpt_mutex_unlock(&myrpt->lock);
04930       return DC_COMPLETE;
04931    }
04932    
04933    myrpt->callmode = 0;
04934    rpt_mutex_unlock(&myrpt->lock);
04935    rpt_telemetry(myrpt, TERM, NULL);
04936    return DC_COMPLETE;
04937 }

static int function_autopatchup ( struct rpt myrpt,
char *  param,
char *  digitbuf,
int  command_source,
struct rpt_link mylink 
) [static]

Definition at line 4821 of file app_rpt.c.

References ast_log(), ast_pthread_create, ast_strdupa, sysstate::autopatchdisable, rpt::callmode, rpt::cidx, DC_COMPLETE, DC_ERROR, rpt::endchar, rpt::exten, finddelim(), rpt::lock, LOG_ERROR, matchkeyword(), MAXPATCHCONTEXT, rpt::mydtmf, rpt::ourcontext, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchnoct, rpt::patchquiet, rpt_call(), rpt::rpt_call_thread, rpt_mutex_lock, rpt_mutex_unlock, rpt::s, skipchars(), rpt::sysstate_cur, and sysstate::txdisable.

04822 {
04823    pthread_attr_t attr;
04824    int i, index, paramlength;
04825    char *lparam;
04826    char *value = NULL;
04827    char *paramlist[20];
04828 
04829    static char *keywords[] = {
04830    "context",
04831    "dialtime",
04832    "farenddisconnect",
04833    "noct",
04834    "quiet",
04835    NULL
04836    };
04837       
04838    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
04839       return DC_ERROR;
04840       
04841    if(debug)
04842       printf("@@@@ Autopatch up\n");
04843 
04844    if(!myrpt->callmode){
04845       /* Set defaults */
04846       myrpt->patchnoct = 0;
04847       myrpt->patchdialtime = 0;
04848       myrpt->patchfarenddisconnect = 0;
04849       myrpt->patchquiet = 0;
04850       strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT);
04851 
04852       if(param){
04853          /* Process parameter list */
04854          lparam = ast_strdupa(param);
04855          if(!lparam){
04856             ast_log(LOG_ERROR,"App_rpt out of memory on line %d\n",__LINE__);
04857             return DC_ERROR;  
04858          }
04859          paramlength = finddelim(lparam, paramlist, 20);          
04860          for(i = 0; i < paramlength; i++){
04861             index = matchkeyword(paramlist[i], &value, keywords);
04862             if(value)
04863                value = skipchars(value, "= ");
04864             switch(index){
04865 
04866                case 1: /* context */
04867                   strncpy(myrpt->patchcontext, value, MAXPATCHCONTEXT - 1) ;
04868                   break;
04869                   
04870                case 2: /* dialtime */
04871                   myrpt->patchdialtime = atoi(value);
04872                   break;
04873 
04874                case 3: /* farenddisconnect */
04875                   myrpt->patchfarenddisconnect = atoi(value);
04876                   break;
04877 
04878                case 4:  /* noct */
04879                   myrpt->patchnoct = atoi(value);
04880                   break;
04881 
04882                case 5: /* quiet */
04883                   myrpt->patchquiet = atoi(value);
04884                   break;
04885                            
04886                default:
04887                   break;
04888             }
04889          }
04890       }
04891    }
04892                
04893    rpt_mutex_lock(&myrpt->lock);
04894 
04895    /* if on call, force * into current audio stream */
04896    
04897    if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){
04898       myrpt->mydtmf = myrpt->p.endchar;
04899    }
04900    if (myrpt->callmode){
04901       rpt_mutex_unlock(&myrpt->lock);
04902       return DC_COMPLETE;
04903    }
04904    myrpt->callmode = 1;
04905    myrpt->cidx = 0;
04906    myrpt->exten[myrpt->cidx] = 0;
04907    rpt_mutex_unlock(&myrpt->lock);
04908    pthread_attr_init(&attr);
04909    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04910    ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt);
04911    return DC_COMPLETE;
04912 }

static int function_cop ( struct rpt myrpt,
char *  param,
char *  digitbuf,
int  command_source,
struct rpt_link mylink 
) [static]

Definition at line 5019 of file app_rpt.c.

References sysstate::alternatetail, ARB_ALPHA, sysstate::autopatchdisable, DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, rpt::disgorgetime, sysstate::linkfundisable, myatoi(), rpt::p, rpt_telemetry(), rpt::s, sysstate::schedulerdisable, SOURCE_PHONE, rpt::stopgen, rpt::sysstate_cur, TEST_TONE, sysstate::totdisable, sysstate::txdisable, and sysstate::userfundisable.

05020 {
05021    char string[16];
05022 
05023    if(!param)
05024       return DC_ERROR;
05025    
05026    switch(myatoi(param)){
05027       case 1: /* System reset */
05028          system("killall -9 asterisk");
05029          return DC_COMPLETE;
05030 
05031       case 2:
05032          myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 0;
05033          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA");
05034          return DC_COMPLETE;
05035          
05036       case 3:
05037          myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 1;
05038          return DC_COMPLETE;
05039          
05040       case 4: /* test tone on */
05041          if (myrpt->stopgen < 0) 
05042          {
05043             myrpt->stopgen = 1;
05044          }
05045          else 
05046          {
05047             myrpt->stopgen = 0;
05048             rpt_telemetry(myrpt, TEST_TONE, NULL);
05049          }
05050          return DC_COMPLETE;
05051 
05052       case 5: /* Disgorge variables to log for debug purposes */
05053          myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
05054          return DC_COMPLETE;
05055 
05056       case 6: /* Simulate COR being activated (phone only) */
05057          if (command_source != SOURCE_PHONE) return DC_INDETERMINATE;
05058          return DC_DOKEY;  
05059 
05060 
05061       case 7: /* Time out timer enable */
05062          myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 0;
05063          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTENA");
05064          return DC_COMPLETE;
05065          
05066       case 8: /* Time out timer disable */
05067          myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 1;
05068          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTDIS");
05069          return DC_COMPLETE;
05070 
05071                 case 9: /* Autopatch enable */
05072                         myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 0;
05073                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APENA");
05074                         return DC_COMPLETE;
05075 
05076                 case 10: /* Autopatch disable */
05077                         myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 1;
05078                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APDIS");
05079                         return DC_COMPLETE;
05080 
05081                 case 11: /* Link Enable */
05082                         myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 0;
05083                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKENA");
05084                         return DC_COMPLETE;
05085 
05086                 case 12: /* Link Disable */
05087                         myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 1;
05088                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKDIS");
05089                         return DC_COMPLETE;
05090 
05091       case 13: /* Query System State */
05092          string[0] = string[1] = 'S';
05093          string[2] = myrpt->p.sysstate_cur + '0';
05094          string[3] = '\0';
05095          rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
05096          return DC_COMPLETE;
05097 
05098       case 14: /* Change System State */
05099          if(strlen(digitbuf) == 0)
05100             break;
05101          if((digitbuf[0] < '0') || (digitbuf[0] > '9'))
05102             return DC_ERROR;
05103          myrpt->p.sysstate_cur = digitbuf[0] - '0';
05104                         string[0] = string[1] = 'S';
05105                         string[2] = myrpt->p.sysstate_cur + '0';
05106                         string[3] = '\0';
05107                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
05108                         return DC_COMPLETE;
05109 
05110                 case 15: /* Scheduler Enable */
05111                         myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 0;
05112                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKENA");
05113                         return DC_COMPLETE;
05114 
05115                 case 16: /* Scheduler Disable */
05116                         myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 1;
05117                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKDIS");
05118                         return DC_COMPLETE;
05119 
05120                 case 17: /* User functions Enable */
05121                         myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 0;
05122                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFENA");
05123                         return DC_COMPLETE;
05124 
05125                 case 18: /* User Functions Disable */
05126                         myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 1;
05127                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFDIS");
05128                         return DC_COMPLETE;
05129 
05130                 case 19: /* Alternate Tail Enable */
05131                         myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 1;
05132                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATENA");
05133                         return DC_COMPLETE;
05134 
05135                 case 20: /* Alternate Tail Disable */
05136                         myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 0;
05137                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATDIS");
05138                         return DC_COMPLETE;
05139    }  
05140    return DC_INDETERMINATE;
05141 }

static int function_ilink ( struct rpt myrpt,
char *  param,
char *  digitbuf,
int  command_source,
struct rpt_link mylink 
) [static]

Definition at line 4571 of file app_rpt.c.

References AST_FRAME_TEXT, ast_log(), ast_safe_sleep(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt_link::chan, rpt::cmdnode, COMPLETE, connect_link(), CONNFAIL, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt_link::disced, do_dtmf_local(), finddelim(), ast_frame::frametype, FULLSTATUS, rpt::lastlinknode, LASTNODEKEY, sysstate::linkfundisable, rpt::links, rpt::lock, LOG_NOTICE, rpt::longestnode, ast_frame::mallocd, MAX_RETRIES, rpt_link::max_retries, MAXLINKLIST, MAXNODESTR, rpt_link::mode, myatoi(), rpt::name, rpt_link::name, rpt_link::next, node_lookup(), ast_frame::offset, rpt::p, rpt_link::perma, rpt::propagate_dtmf, rpt::propagate_phonedtmf, REMALREADY, REMGO, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::s, s, ast_frame::samples, rpt::savednodes, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, SOURCE_RPT, STATUS, strsep(), ast_frame::subclass, rpt::sysstate_cur, and sysstate::txdisable.

04572 {
04573 
04574    char *val, *s, *s1, *s2;
04575    char tmp[300];
04576    char digitbuf[MAXNODESTR],*strs[MAXLINKLIST];
04577    char mode,perma;
04578    struct rpt_link *l;
04579    int i,r;
04580 
04581    if(!param)
04582       return DC_ERROR;
04583       
04584          
04585    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable )
04586       return DC_ERROR;
04587 
04588    strncpy(digitbuf,digits,MAXNODESTR - 1);
04589 
04590    if(debug > 6)
04591       printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
04592       
04593    switch(myatoi(param)){
04594       case 11: /* Perm Link off */
04595       case 1: /* Link off */
04596          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
04597             strcpy(digitbuf,myrpt->lastlinknode);
04598          val = node_lookup(myrpt,digitbuf);
04599          if (!val){
04600             if(strlen(digitbuf) >= myrpt->longestnode)
04601                return DC_ERROR;
04602             break;
04603          }
04604          strncpy(tmp,val,sizeof(tmp) - 1);
04605          s = tmp;
04606          s1 = strsep(&s,",");
04607          s2 = strsep(&s,",");
04608          rpt_mutex_lock(&myrpt->lock);
04609          l = myrpt->links.next;
04610          /* try to find this one in queue */
04611          while(l != &myrpt->links){
04612             if (l->name[0] == '0') 
04613             {
04614                l = l->next;
04615                continue;
04616             }
04617             /* if found matching string */
04618             if (!strcmp(l->name, digitbuf))
04619                break;
04620             l = l->next;
04621          }
04622          if (l != &myrpt->links){ /* if found */
04623             struct   ast_frame wf;
04624 
04625             /* must use perm command on perm link */
04626             if ((myatoi(param) < 10) && 
04627                 (l->max_retries > MAX_RETRIES))
04628             {
04629                rpt_mutex_unlock(&myrpt->lock);
04630                return DC_COMPLETE;
04631             }
04632             strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1);
04633             l->retries = l->max_retries + 1;
04634             l->disced = 1;
04635             rpt_mutex_unlock(&myrpt->lock);
04636             wf.frametype = AST_FRAME_TEXT;
04637             wf.subclass = 0;
04638             wf.offset = 0;
04639             wf.mallocd = 0;
04640             wf.datalen = strlen(discstr) + 1;
04641             wf.samples = 0;
04642             wf.data = discstr;
04643             if (l->chan)
04644             {
04645                ast_write(l->chan,&wf);
04646                if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR;
04647                ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
04648             }
04649             rpt_telemetry(myrpt, COMPLETE, NULL);
04650             return DC_COMPLETE;
04651          }
04652          rpt_mutex_unlock(&myrpt->lock);  
04653          return DC_COMPLETE;
04654       case 2: /* Link Monitor */
04655       case 3: /* Link transceive */
04656       case 12: /* Link Monitor permanent */
04657       case 13: /* Link transceive permanent */
04658          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
04659             strcpy(digitbuf,myrpt->lastlinknode);
04660          /* Attempt connection  */
04661          perma = (atoi(param) > 10) ? 1 : 0;
04662          mode = (atoi(param) & 1) ? 1 : 0;
04663          r = connect_link(myrpt, digitbuf, mode, perma);
04664          switch(r){
04665             case 0:
04666                rpt_telemetry(myrpt, COMPLETE, NULL);
04667                return DC_COMPLETE;
04668 
04669             case 1:
04670                break;
04671             
04672             case 2:
04673                rpt_telemetry(myrpt, REMALREADY, NULL);
04674                return DC_COMPLETE;
04675             
04676             default:
04677                rpt_telemetry(myrpt, CONNFAIL, NULL);
04678                return DC_COMPLETE;
04679          }
04680          break;
04681 
04682       case 4: /* Enter Command Mode */
04683       
04684          /* if doesnt allow link cmd, or no links active, return */
04685          if (((command_source != SOURCE_RPT) && 
04686             (command_source != SOURCE_PHONE) &&
04687             (command_source != SOURCE_DPHONE)) ||
04688              (myrpt->links.next == &myrpt->links))
04689             return DC_COMPLETE;
04690          
04691          /* if already in cmd mode, or selected self, fughetabahtit */
04692          if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){
04693          
04694             rpt_telemetry(myrpt, REMALREADY, NULL);
04695             return DC_COMPLETE;
04696          }
04697          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
04698             strcpy(digitbuf,myrpt->lastlinknode);
04699          /* node must at least exist in list */
04700          val = node_lookup(myrpt,digitbuf);
04701          if (!val){
04702             if(strlen(digitbuf) >= myrpt->longestnode)
04703                return DC_ERROR;
04704             break;
04705          
04706          }
04707          rpt_mutex_lock(&myrpt->lock);
04708          strcpy(myrpt->lastlinknode,digitbuf);
04709          strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1);
04710          rpt_mutex_unlock(&myrpt->lock);
04711          rpt_telemetry(myrpt, REMGO, NULL);  
04712          return DC_COMPLETE;
04713          
04714       case 5: /* Status */
04715          rpt_telemetry(myrpt, STATUS, NULL);
04716          return DC_COMPLETE;
04717 
04718       case 15: /* Full Status */
04719          rpt_telemetry(myrpt, FULLSTATUS, NULL);
04720          return DC_COMPLETE;
04721          
04722          
04723       case 6: /* All Links Off, including permalinks */
04724                        rpt_mutex_lock(&myrpt->lock);
04725          myrpt->savednodes[0] = 0;
04726                         l = myrpt->links.next;
04727                         /* loop through all links */
04728                         while(l != &myrpt->links){
04729             struct   ast_frame wf;
04730                                 if (l->name[0] == '0') /* Skip any IAXRPT monitoring */
04731                                 {
04732                                         l = l->next;
04733                                         continue;
04734                                 }
04735             /* Make a string of disconnected nodes for possible restoration */
04736             sprintf(tmp,"%c%c%s",(l->mode) ? 'X' : 'M',(l->perma) ? 'P':'T',l->name);
04737             if(strlen(tmp) + strlen(myrpt->savednodes) + 1 < MAXNODESTR){ 
04738                if(myrpt->savednodes[0])
04739                   strcat(myrpt->savednodes, ",");
04740                strcat(myrpt->savednodes, tmp);
04741             }
04742                               l->retries = l->max_retries + 1;
04743                                 l->disced = 2; /* Silently disconnect */
04744                                 rpt_mutex_unlock(&myrpt->lock);
04745             /* ast_log(LOG_NOTICE,"dumping link %s\n",l->name); */
04746                                 
04747                                 wf.frametype = AST_FRAME_TEXT;
04748                                 wf.subclass = 0;
04749                                 wf.offset = 0;
04750                                 wf.mallocd = 0;
04751                                 wf.datalen = strlen(discstr) + 1;
04752                                 wf.samples = 0;
04753                                 wf.data = discstr;
04754                                 if (l->chan)
04755                                 {
04756                                         ast_write(l->chan,&wf);
04757                                         ast_safe_sleep(l->chan,250); /* It's dead already, why check the return value? */
04758                                         ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
04759                                 }
04760             rpt_mutex_lock(&myrpt->lock);
04761                                 l = l->next;
04762                         }
04763          rpt_mutex_unlock(&myrpt->lock);
04764          if(debug > 3)
04765             ast_log(LOG_NOTICE,"Nodes disconnected: %s\n",myrpt->savednodes);
04766                         rpt_telemetry(myrpt, COMPLETE, NULL);
04767          return DC_COMPLETE;
04768 
04769       case 7: /* Identify last node which keyed us up */
04770          rpt_telemetry(myrpt, LASTNODEKEY, NULL);
04771          break;
04772 
04773 
04774       case 16: /* Restore links disconnected with "disconnect all links" command */
04775          strcpy(tmp, myrpt->savednodes); /* Make a copy */
04776          finddelim(tmp, strs, MAXLINKLIST); /* convert into substrings */
04777          for(i = 0; tmp[0] && strs[i] != NULL && i < MAXLINKLIST; i++){
04778             s1 = strs[i];
04779             mode = (s1[0] == 'X') ? 1 : 0;
04780             perma = (s1[1] == 'P') ? 1 : 0;
04781             connect_link(myrpt, s1 + 2, mode, perma); /* Try to reconnect */
04782          }
04783                         rpt_telemetry(myrpt, COMPLETE, NULL);
04784          break;
04785    
04786       case 200:
04787       case 201:
04788       case 202:
04789       case 203:
04790       case 204:
04791       case 205:
04792       case 206:
04793       case 207:
04794       case 208:
04795       case 209:
04796       case 210:
04797       case 211:
04798       case 212:
04799       case 213:
04800       case 214:
04801       case 215:
04802          if (((myrpt->p.propagate_dtmf) && 
04803               (command_source == SOURCE_LNK)) ||
04804              ((myrpt->p.propagate_phonedtmf) &&
04805             ((command_source == SOURCE_PHONE) ||
04806                 (command_source == SOURCE_DPHONE))))
04807                do_dtmf_local(myrpt,
04808                   remdtmfstr[myatoi(param) - 200]);
04809       default:
04810          return DC_ERROR;
04811          
04812    }
04813    
04814    return DC_INDETERMINATE;
04815 }  

static int function_macro ( struct rpt myrpt,
char *  param,
char *  digitbuf,
int  command_source,
struct rpt_link mylink 
) [static]

Definition at line 4974 of file app_rpt.c.

References ast_variable_retrieve(), rpt::cfg, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt::lock, rpt::macro, MACRO_BUSY, rpt::macro_longest, MACRO_NOTFOUND, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, rpt::p, rpt::remote, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), and rpt::startupmacro.

04975 {
04976 
04977 char  *val;
04978 int   i;
04979    if (myrpt->remote)
04980       return DC_ERROR;
04981 
04982    if(debug) 
04983       printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
04984    
04985    if(strlen(digitbuf) < 1) /* needs 1 digit */
04986       return DC_INDETERMINATE;
04987          
04988    for(i = 0 ; i < digitbuf[i] ; i++) {
04989       if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
04990          return DC_ERROR;
04991    }
04992    
04993    if (*digitbuf == '0') val = myrpt->p.startupmacro;
04994    else val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, digitbuf);
04995    /* param was 1 for local buf */
04996    if (!val){
04997                 if (strlen(digitbuf) < myrpt->macro_longest)
04998                         return DC_INDETERMINATE;
04999       rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL);
05000       return DC_COMPLETE;
05001    }        
05002    rpt_mutex_lock(&myrpt->lock);
05003    if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val))
05004    {
05005       rpt_mutex_unlock(&myrpt->lock);
05006       rpt_telemetry(myrpt, MACRO_BUSY, NULL);
05007       return DC_ERROR;
05008    }
05009    myrpt->macrotimer = MACROTIME;
05010    strncat(myrpt->macrobuf,val,MAXMACRO - 1);
05011    rpt_mutex_unlock(&myrpt->lock);
05012    return DC_COMPLETE;  
05013 }

static int function_remote ( struct rpt myrpt,
char *  param,
char *  digitbuf,
int  command_source,
struct rpt_link mylink 
) [static]

Definition at line 7651 of file app_rpt.c.

References rpt::archivedir, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_mutex_lock(), ast_mutex_unlock(), rpt::authlevel, check_freq(), DC_COMPLETE, DC_COMPLETEQUIET, DC_ERROR, DC_INDETERMINATE, do_dtmf_local(), donodelog(), free, rpt::freq, HF_SCAN_DOWN_FAST, HF_SCAN_DOWN_QUICK, HF_SCAN_DOWN_SLOW, HF_SCAN_UP_FAST, HF_SCAN_UP_QUICK, HF_SCAN_UP_SLOW, rpt::hfscanmode, INVFREQ, rpt::lock, rpt::loginlevel, rpt::loginuser, MAXREMSTR, MEMNOTFOUND, multimode_bump_freq(), multimode_capable(), myatoi(), rpt::offset, offset, rpt::p, rpt::powerlevel, REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, REM_PLUS, REM_SCANTIME, REM_SIMPLEX, REMLOGIN, REMLONGSTATUS, REMMODE, rpt::remmode, rpt::remote, rpt::remotetx, REMSHORTSTATUS, REMXXX, retreive_memory(), rpt_telemetry(), rpt::rxpl, rpt::rxplon, s, rpt::scantimer, setrem(), SOURCE_LNK, SOURCE_RPT, split_freq(), strdup, strsep(), TUNE, rpt::tunerequest, rpt::txchannel, rpt::txpl, and rpt::txplon.

07652 {
07653    char *s,*s1,*s2;
07654    int i,j,p,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode;
07655    char multimode = 0;
07656    char oc,*cp,*cp1,*cp2;
07657    char tmp[20], freq[20] = "", savestr[20] = "";
07658    char mhz[MAXREMSTR], decimals[MAXREMSTR];
07659 
07660    if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK))
07661       return DC_ERROR;
07662       
07663    p = myatoi(param);
07664 
07665    if ((p != 99) && (p != 5) && (p != 140) && myrpt->p.authlevel && 
07666       (!myrpt->loginlevel[0])) return DC_ERROR;
07667    multimode = multimode_capable(myrpt);
07668 
07669    switch(p){
07670 
07671       case 1:  /* retrieve memory */
07672          if(strlen(digitbuf) < 2) /* needs 2 digits */
07673             break;
07674          
07675          for(i = 0 ; i < 2 ; i++){
07676             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
07677                return DC_ERROR;
07678          }
07679        
07680          r = retreive_memory(myrpt, digitbuf);
07681          if (r < 0){
07682             rpt_telemetry(myrpt,MEMNOTFOUND,NULL);
07683             return DC_COMPLETE;
07684          }
07685          if (r > 0){
07686             return DC_ERROR;
07687          }
07688          if (setrem(myrpt) == -1) return DC_ERROR;
07689          return DC_COMPLETE;  
07690          
07691       case 2:  /* set freq and offset */
07692       
07693          
07694             for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */
07695             if(digitbuf[i] == '*'){
07696                j++;
07697                continue;
07698             }
07699             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
07700                goto invalid_freq;
07701             else{
07702                if(j == 0)
07703                   l++; /* # of digits before first * */
07704                if(j == 1)
07705                   k++; /* # of digits after first * */
07706             }
07707          }
07708       
07709          i = strlen(digitbuf) - 1;
07710          if(multimode){
07711             if((j > 2) || (l > 3) || (k > 6))
07712                goto invalid_freq; /* &^@#! */
07713          }
07714          else{
07715             if((j > 2) || (l > 4) || (k > 3))
07716                goto invalid_freq; /* &^@#! */
07717          }
07718 
07719          /* Wait for M+*K+* */
07720 
07721          if(j < 2)
07722             break; /* Not yet */
07723 
07724          /* We have a frequency */
07725 
07726          strncpy(tmp, digitbuf ,sizeof(tmp) - 1);
07727          
07728          s = tmp;
07729          s1 = strsep(&s, "*"); /* Pick off MHz */
07730          s2 = strsep(&s,"*"); /* Pick off KHz and Hz */
07731          ls2 = strlen(s2); 
07732          
07733          switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */
07734             case 1:
07735                ht = 0;
07736                k = 100 * atoi(s2);
07737                break;
07738             
07739             case 2:
07740                ht = 0;
07741                k = 10 * atoi(s2);
07742                break;
07743                
07744             case 3:
07745                if(!multimode){
07746                   if((s2[2] != '0')&&(s2[2] != '5'))
07747                      goto invalid_freq;
07748                }
07749                ht = 0;
07750                k = atoi(s2);
07751                   break;
07752             case 4:
07753                k = atoi(s2)/10;
07754                ht = 10 * (atoi(s2+(ls2-1)));
07755                break;
07756 
07757             case 5:
07758                k = atoi(s2)/100;
07759                ht = (atoi(s2+(ls2-2)));
07760                break;
07761                
07762             default:
07763                goto invalid_freq;
07764          }
07765 
07766          /* Check frequency for validity and establish a default mode */
07767          
07768          snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht);
07769 
07770          if(debug)
07771             printf("New frequency: %s\n", freq);      
07772    
07773          split_freq(mhz, decimals, freq);
07774          m = atoi(mhz);
07775          d = atoi(decimals);
07776 
07777                         if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */
07778                                 goto invalid_freq;
07779 
07780 
07781          if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */
07782             break; /* Not yet */
07783 
07784 
07785          offset = REM_SIMPLEX; /* Assume simplex */
07786 
07787          if(defmode == REM_MODE_FM){
07788             oc = *s; /* Pick off offset */
07789          
07790             if (oc){
07791                switch(oc){
07792                   case '1':
07793                      offset = REM_MINUS;
07794                      break;
07795                   
07796                   case '2':
07797                      offset = REM_SIMPLEX;
07798                   break;
07799                   
07800                   case '3':
07801                      offset = REM_PLUS;
07802                      break;
07803                   
07804                   default:
07805                      goto invalid_freq;
07806                } 
07807             } 
07808          }  
07809          offsave = myrpt->offset;
07810          modesave = myrpt->remmode;
07811          strncpy(savestr, myrpt->freq, sizeof(savestr) - 1);
07812          strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1);
07813          myrpt->offset = offset;
07814          myrpt->remmode = defmode;
07815 
07816          if (setrem(myrpt) == -1){
07817             myrpt->offset = offsave;
07818             myrpt->remmode = modesave;
07819             strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1);
07820             goto invalid_freq;
07821          }
07822 
07823          return DC_COMPLETE;
07824 
07825 invalid_freq:
07826          rpt_telemetry(myrpt,INVFREQ,NULL);
07827          return DC_ERROR; 
07828       
07829       case 3: /* set rx PL tone */
07830             for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
07831             if(digitbuf[i] == '*'){
07832                j++;
07833                continue;
07834             }
07835             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
07836                return DC_ERROR;
07837             else{
07838                if(j)
07839                   l++;
07840                else
07841                   k++;
07842             }
07843          }
07844          if((j > 1) || (k > 3) || (l > 1))
07845             return DC_ERROR; /* &$@^! */
07846          i = strlen(digitbuf) - 1;
07847          if((j != 1) || (k < 2)|| (l != 1))
07848             break; /* Not yet */
07849          if(debug)
07850             printf("PL digits entered %s\n", digitbuf);
07851             
07852          strncpy(tmp, digitbuf, sizeof(tmp) - 1);
07853          /* see if we have at least 1 */
07854          s = strchr(tmp,'*');
07855          if(s)
07856             *s = '.';
07857          strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1);
07858          strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1);
07859          if(!strcmp(myrpt->remote, remote_rig_rbi))
07860          {
07861             strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1);
07862          }
07863          if (setrem(myrpt) == -1){
07864             strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1);
07865             return DC_ERROR;
07866          }
07867       
07868       
07869          return DC_COMPLETE;
07870       
07871       case 4: /* set tx PL tone */
07872          /* cant set tx tone on RBI (rx tone does both) */
07873          if(!strcmp(myrpt->remote, remote_rig_rbi))
07874             return DC_ERROR;
07875          if(!strcmp(myrpt->remote, remote_rig_ic706))
07876             return DC_ERROR;
07877             for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
07878             if(digitbuf[i] == '*'){
07879                j++;
07880                continue;
07881             }
07882             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
07883                return DC_ERROR;
07884             else{
07885                if(j)
07886                   l++;
07887                else
07888                   k++;
07889             }
07890          }
07891          if((j > 1) || (k > 3) || (l > 1))
07892             return DC_ERROR; /* &$@^! */
07893          i = strlen(digitbuf) - 1;
07894          if((j != 1) || (k < 2)|| (l != 1))
07895             break; /* Not yet */
07896          if(debug)
07897             printf("PL digits entered %s\n", digitbuf);
07898             
07899          strncpy(tmp, digitbuf, sizeof(tmp) - 1);
07900          /* see if we have at least 1 */
07901          s = strchr(tmp,'*');
07902          if(s)
07903             *s = '.';
07904          strncpy(savestr, myrpt->txpl, sizeof(savestr) - 1);
07905          strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1);
07906          
07907          if (setrem(myrpt) == -1){
07908             strncpy(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1);
07909             return DC_ERROR;
07910          }
07911       
07912       
07913          return DC_COMPLETE;
07914       
07915 
07916       case 6: /* MODE (FM,USB,LSB,AM) */
07917          if(strlen(digitbuf) < 1)
07918             break;
07919 
07920          if(!multimode)
07921             return DC_ERROR; /* Multimode radios only */
07922 
07923          switch(*digitbuf){
07924             case '1':
07925                split_freq(mhz, decimals, myrpt->freq); 
07926                m=atoi(mhz);
07927                if(m < 29) /* No FM allowed below 29MHz! */
07928                   return DC_ERROR;
07929                myrpt->remmode = REM_MODE_FM;
07930                
07931                rpt_telemetry(myrpt,REMMODE,NULL);
07932                break;
07933 
07934             case '2':
07935                myrpt->remmode = REM_MODE_USB;
07936                rpt_telemetry(myrpt,REMMODE,NULL);
07937                break;   
07938 
07939             case '3':
07940                myrpt->remmode = REM_MODE_LSB;
07941                rpt_telemetry(myrpt,REMMODE,NULL);
07942                break;
07943             
07944             case '4':
07945                myrpt->remmode = REM_MODE_AM;
07946                rpt_telemetry(myrpt,REMMODE,NULL);
07947                break;
07948       
07949             default:
07950                return DC_ERROR;
07951          }
07952 
07953          if(setrem(myrpt))
07954             return DC_ERROR;
07955          return DC_COMPLETEQUIET;
07956       case 99:
07957          /* cant log in when logged in */
07958          if (myrpt->loginlevel[0]) 
07959             return DC_ERROR;
07960          *myrpt->loginuser = 0;
07961          myrpt->loginlevel[0] = 0;
07962          cp = strdup(param);
07963          cp1 = strchr(cp,',');
07964          ast_mutex_lock(&myrpt->lock);
07965          if (cp1) 
07966          {
07967             *cp1 = 0;
07968             cp2 = strchr(cp1 + 1,',');
07969             if (cp2) 
07970             {
07971                *cp2 = 0;
07972                strncpy(myrpt->loginlevel,cp2 + 1,
07973                   sizeof(myrpt->loginlevel) - 1);
07974             }
07975             strncpy(myrpt->loginuser,cp1 + 1,sizeof(myrpt->loginuser));
07976             ast_mutex_unlock(&myrpt->lock);
07977             if (myrpt->p.archivedir)
07978             {
07979                char str[100];
07980 
07981                sprintf(str,"LOGIN,%s,%s",
07982                    myrpt->loginuser,myrpt->loginlevel);
07983                donodelog(myrpt,str);
07984             }
07985             if (debug) 
07986                printf("loginuser %s level %s\n",myrpt->loginuser,myrpt->loginlevel);
07987             rpt_telemetry(myrpt,REMLOGIN,NULL);
07988          }
07989          free(cp);
07990          return DC_COMPLETEQUIET;
07991       case 100: /* RX PL Off */
07992          myrpt->rxplon = 0;
07993          setrem(myrpt);
07994          rpt_telemetry(myrpt,REMXXX,(void *)p);
07995          return DC_COMPLETEQUIET;
07996       case 101: /* RX PL On */
07997          myrpt->rxplon = 1;
07998          setrem(myrpt);
07999          rpt_telemetry(myrpt,REMXXX,(void *)p);
08000          return DC_COMPLETEQUIET;
08001       case 102: /* TX PL Off */
08002          myrpt->txplon = 0;
08003          setrem(myrpt);
08004          rpt_telemetry(myrpt,REMXXX,(void *)p);
08005          return DC_COMPLETEQUIET;
08006       case 103: /* TX PL On */
08007          myrpt->txplon = 1;
08008          setrem(myrpt);
08009          rpt_telemetry(myrpt,REMXXX,(void *)p);
08010          return DC_COMPLETEQUIET;
08011       case 104: /* Low Power */
08012          if(!strcmp(myrpt->remote, remote_rig_ic706))
08013             return DC_ERROR;
08014          myrpt->powerlevel = REM_LOWPWR;
08015          setrem(myrpt);
08016          rpt_telemetry(myrpt,REMXXX,(void *)p);
08017          return DC_COMPLETEQUIET;
08018       case 105: /* Medium Power */
08019          if(!strcmp(myrpt->remote, remote_rig_ic706))
08020             return DC_ERROR;
08021          myrpt->powerlevel = REM_MEDPWR;
08022          setrem(myrpt);
08023          rpt_telemetry(myrpt,REMXXX,(void *)p);
08024          return DC_COMPLETEQUIET;
08025       case 106: /* Hi Power */
08026          if(!strcmp(myrpt->remote, remote_rig_ic706))
08027             return DC_ERROR;
08028          myrpt->powerlevel = REM_HIPWR;
08029          setrem(myrpt);
08030          rpt_telemetry(myrpt,REMXXX,(void *)p);
08031          return DC_COMPLETEQUIET;
08032       case 107: /* Bump down 20Hz */
08033          multimode_bump_freq(myrpt, -20);
08034          return DC_COMPLETE;
08035       case 108: /* Bump down 100Hz */
08036          multimode_bump_freq(myrpt, -100);
08037          return DC_COMPLETE;
08038       case 109: /* Bump down 500Hz */
08039          multimode_bump_freq(myrpt, -500);
08040          return DC_COMPLETE;
08041       case 110: /* Bump up 20Hz */
08042          multimode_bump_freq(myrpt, 20);
08043          return DC_COMPLETE;
08044       case 111: /* Bump up 100Hz */
08045          multimode_bump_freq(myrpt, 100);
08046          return DC_COMPLETE;
08047       case 112: /* Bump up 500Hz */
08048          multimode_bump_freq(myrpt, 500);
08049          return DC_COMPLETE;
08050       case 113: /* Scan down slow */
08051          myrpt->scantimer = REM_SCANTIME;
08052          myrpt->hfscanmode = HF_SCAN_DOWN_SLOW;
08053          rpt_telemetry(myrpt,REMXXX,(void *)p);
08054          return DC_COMPLETEQUIET;
08055       case 114: /* Scan down quick */
08056          myrpt->scantimer = REM_SCANTIME;
08057          myrpt->hfscanmode = HF_SCAN_DOWN_QUICK;
08058          rpt_telemetry(myrpt,REMXXX,(void *)p);
08059          return DC_COMPLETEQUIET;
08060       case 115: /* Scan down fast */
08061          myrpt->scantimer = REM_SCANTIME;
08062          myrpt->hfscanmode = HF_SCAN_DOWN_FAST;
08063          rpt_telemetry(myrpt,REMXXX,(void *)p);
08064          return DC_COMPLETEQUIET;
08065       case 116: /* Scan up slow */
08066          myrpt->scantimer = REM_SCANTIME;
08067          myrpt->hfscanmode = HF_SCAN_UP_SLOW;
08068          rpt_telemetry(myrpt,REMXXX,(void *)p);
08069          return DC_COMPLETEQUIET;
08070       case 117: /* Scan up quick */
08071          myrpt->scantimer = REM_SCANTIME;
08072          myrpt->hfscanmode = HF_SCAN_UP_QUICK;
08073          rpt_telemetry(myrpt,REMXXX,(void *)p);
08074          return DC_COMPLETEQUIET;
08075       case 118: /* Scan up fast */
08076          myrpt->scantimer = REM_SCANTIME;
08077          myrpt->hfscanmode = HF_SCAN_UP_FAST;
08078          rpt_telemetry(myrpt,REMXXX,(void *)p);
08079          return DC_COMPLETEQUIET;
08080       case 119: /* Tune Request */
08081          /* if not currently going, and valid to do */
08082          if((!myrpt->tunerequest) && 
08083              ((!strcmp(myrpt->remote, remote_rig_ft897) || 
08084             !strcmp(myrpt->remote, remote_rig_ic706)) )) { 
08085             myrpt->remotetx = 0;
08086             ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
08087             myrpt->tunerequest = 1;
08088             rpt_telemetry(myrpt,TUNE,NULL);
08089             return DC_COMPLETEQUIET;
08090          }
08091          return DC_ERROR;        
08092       case 5: /* Long Status */
08093          rpt_telemetry(myrpt,REMLONGSTATUS,NULL);
08094          return DC_COMPLETEQUIET;
08095       case 140: /* Short Status */
08096          rpt_telemetry(myrpt,REMSHORTSTATUS,NULL);
08097          return DC_COMPLETEQUIET;
08098       case 200:
08099       case 201:
08100       case 202:
08101       case 203:
08102       case 204:
08103       case 205:
08104       case 206:
08105       case 207:
08106       case 208:
08107       case 209:
08108       case 210:
08109       case 211:
08110       case 212:
08111       case 213:
08112       case 214:
08113       case 215:
08114          do_dtmf_local(myrpt,remdtmfstr[p - 200]);
08115          return DC_COMPLETEQUIET;
08116       default:
08117          break;
08118    }
08119    return DC_INDETERMINATE;
08120 }

static int function_status ( struct rpt myrpt,
char *  param,
char *  digitbuf,
int  command_source,
struct rpt_link mylink 
) [static]

Definition at line 4943 of file app_rpt.c.

References DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, ID1, myatoi(), rpt::p, rpt_telemetry(), rpt::s, STATS_TIME, STATS_VERSION, rpt::sysstate_cur, sysstate::txdisable, and sysstate::userfundisable.

04944 {
04945 
04946    if (!param)
04947       return DC_ERROR;
04948 
04949    if ((myrpt->p.s[myrpt->p.sysstate_cur].txdisable) || (myrpt->p.s[myrpt->p.sysstate_cur].userfundisable))
04950       return DC_ERROR;
04951 
04952    if(debug)
04953       printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
04954    
04955    switch(myatoi(param)){
04956       case 1: /* System ID */
04957          rpt_telemetry(myrpt, ID1, NULL);
04958          return DC_COMPLETE;
04959       case 2: /* System Time */
04960          rpt_telemetry(myrpt, STATS_TIME, NULL);
04961          return DC_COMPLETE;
04962       case 3: /* app_rpt.c version */
04963          rpt_telemetry(myrpt, STATS_VERSION, NULL);
04964       default:
04965          return DC_ERROR;
04966    }
04967    return DC_INDETERMINATE;
04968 }

static int get_wait_interval ( struct rpt myrpt,
int  type 
) [static]

Definition at line 2770 of file app_rpt.c.

References ast_log(), ast_strdupa, ast_variable_retrieve(), rpt::cfg, DLY_CALLTERM, DLY_COMP, DLY_ID, DLY_LINKUNKEY, DLY_TELEM, DLY_UNKEY, LOG_WARNING, rpt::name, and retrieve_astcfgint().

Referenced by rpt_tele_thread(), and wait_interval().

02771 {
02772         int interval;
02773         char *wait_times;
02774         char *wait_times_save;
02775                                                                                                                   
02776         wait_times_save = NULL;
02777         wait_times = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "wait_times");
02778                                                                                                                   
02779         if(wait_times){
02780                 wait_times_save = ast_strdupa(wait_times);
02781                 if(!wait_times_save){
02782                         ast_log(LOG_WARNING, "Out of memory in wait_interval()\n");
02783                         wait_times = NULL;
02784                 }
02785         }
02786                                                                                                                   
02787         switch(type){
02788                 case DLY_TELEM:
02789                         if(wait_times)
02790                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "telemwait", 500, 5000, 1000);
02791                         else
02792                                 interval = 1000;
02793                         break;
02794                                                                                                                   
02795                 case DLY_ID:
02796                         if(wait_times)
02797                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "idwait",250,5000,500);
02798                         else
02799                                 interval = 500;
02800                         break;
02801                                                                                                                   
02802                 case DLY_UNKEY:
02803                         if(wait_times)
02804                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "unkeywait",500,5000,1000);
02805                         else
02806                                 interval = 1000;
02807                         break;
02808                                                                                                                   
02809                 case DLY_LINKUNKEY:
02810                         if(wait_times)
02811                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "linkunkeywait",500,5000,1000);
02812                         else
02813                                 interval = 1000;
02814                         break;
02815                                                                                                                   
02816                 case DLY_CALLTERM:
02817                         if(wait_times)
02818                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "calltermwait",500,5000,1500);
02819                         else
02820                                 interval = 1500;
02821                         break;
02822                                                                                                                   
02823                 case DLY_COMP:
02824                         if(wait_times)
02825                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "compwait",500,5000,200);
02826                         else
02827                                 interval = 200;
02828                         break;
02829                                                                                                                   
02830                 default:
02831                         return 0;
02832         }
02833    return interval;
02834 }                                                                                                                  

static void handle_link_data ( struct rpt myrpt,
struct rpt_link mylink,
char *  str 
) [static]

Definition at line 5222 of file app_rpt.c.

References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_TEXT, ast_log(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt::callmode, rpt_link::chan, rpt::cidx, collect_function_digits(), rpt::dailyexecdcommands, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_COMPLETEQUIET, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt_link::disced, do_dtmf_local(), do_dtmf_phone(), donodelog(), rpt::endchar, rpt::exten, ast_frame::frametype, func_xlat(), rpt::funcchar, rpt::lastdtmfcommand, rpt_link::linklist, rpt_link::linklistreceived, rpt::links, rpt::lock, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, rpt_link::max_retries, MAXDTMF, rpt::mydtmf, rpt_link::name, rpt::name, rpt_link::next, ast_frame::offset, rpt::outxlat, rpt::p, rpt::patchcontext, rpt::patchquiet, rpt::pchannel, PROC, rpt::propagate_dtmf, rpt::propagate_phonedtmf, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), ast_frame::samples, seq, SOURCE_LNK, rpt::stopgen, ast_frame::subclass, and rpt::totalexecdcommands.

Referenced by rpt().

05224 {
05225 char  tmp[512],cmd[300] = "",dest[300],src[300],c;
05226 int   seq, res;
05227 struct rpt_link *l;
05228 struct   ast_frame wf;
05229 
05230    wf.frametype = AST_FRAME_TEXT;
05231    wf.subclass = 0;
05232    wf.offset = 0;
05233    wf.mallocd = 0;
05234    wf.datalen = strlen(str) + 1;
05235    wf.samples = 0;
05236    /* put string in our buffer */
05237    strncpy(tmp,str,sizeof(tmp) - 1);
05238 
05239         if (!strcmp(tmp,discstr))
05240         {
05241                 mylink->disced = 1;
05242       mylink->retries = mylink->max_retries + 1;
05243                 ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV);
05244                 return;
05245         }
05246    if (tmp[0] == 'L')
05247    {
05248       rpt_mutex_lock(&myrpt->lock);
05249       strcpy(mylink->linklist,tmp + 2);
05250       time(&mylink->linklistreceived);
05251       rpt_mutex_unlock(&myrpt->lock);
05252       if (debug > 6) ast_log(LOG_NOTICE,"@@@@ node %s recieved node list %s from node %s\n",
05253          myrpt->name,tmp,mylink->name);
05254       return;
05255    }
05256    if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
05257    {
05258       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
05259       return;
05260    }
05261    if (strcmp(cmd,"D"))
05262    {
05263       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
05264       return;
05265    }
05266    if (dest[0] == '0')
05267    {
05268       strcpy(dest,myrpt->name);
05269    }     
05270 
05271    /* if not for me, redistribute to all links */
05272    if (strcmp(dest,myrpt->name))
05273    {
05274       l = myrpt->links.next;
05275       /* see if this is one in list */
05276       while(l != &myrpt->links)
05277       {
05278          if (l->name[0] == '0') 
05279          {
05280             l = l->next;
05281             continue;
05282          }
05283          /* dont send back from where it came */
05284          if ((l == mylink) || (!strcmp(l->name,mylink->name)))
05285          {
05286             l = l->next;
05287             continue;
05288          }
05289          /* if it is, send it and we're done */
05290          if (!strcmp(l->name,dest))
05291          {
05292             /* send, but not to src */
05293             if (strcmp(l->name,src)) {
05294                wf.data = str;
05295                if (l->chan) ast_write(l->chan,&wf);
05296             }
05297             return;
05298          }
05299          l = l->next;
05300       }
05301       l = myrpt->links.next;
05302       /* otherwise, send it to all of em */
05303       while(l != &myrpt->links)
05304       {
05305          if (l->name[0] == '0') 
05306          {
05307             l = l->next;
05308             continue;
05309          }
05310          /* dont send back from where it came */
05311          if ((l == mylink) || (!strcmp(l->name,mylink->name)))
05312          {
05313             l = l->next;
05314             continue;
05315          }
05316          /* send, but not to src */
05317          if (strcmp(l->name,src)) {
05318             wf.data = str;
05319             if (l->chan) ast_write(l->chan,&wf); 
05320          }
05321          l = l->next;
05322       }
05323       return;
05324    }
05325    if (myrpt->p.archivedir)
05326    {
05327       char str[100];
05328 
05329       sprintf(str,"DTMF,%s,%c",mylink->name,c);
05330       donodelog(myrpt,str);
05331    }
05332    c = func_xlat(myrpt,c,&myrpt->p.outxlat);
05333    if (!c) return;
05334    rpt_mutex_lock(&myrpt->lock);
05335    if (c == myrpt->p.endchar) myrpt->stopgen = 1;
05336    if (myrpt->callmode == 1)
05337    {
05338       myrpt->exten[myrpt->cidx++] = c;
05339       myrpt->exten[myrpt->cidx] = 0;
05340       /* if this exists */
05341       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
05342       {
05343          myrpt->callmode = 2;
05344          if(!myrpt->patchquiet){
05345             rpt_mutex_unlock(&myrpt->lock);
05346             rpt_telemetry(myrpt,PROC,NULL); 
05347             rpt_mutex_lock(&myrpt->lock);
05348          }
05349       }
05350       /* if can continue, do so */
05351       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 
05352       {
05353          /* call has failed, inform user */
05354          myrpt->callmode = 4;
05355       }
05356    }
05357    if (c == myrpt->p.funcchar)
05358    {
05359       myrpt->rem_dtmfidx = 0;
05360       myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
05361       time(&myrpt->rem_dtmf_time);
05362       rpt_mutex_unlock(&myrpt->lock);
05363       return;
05364    } 
05365    else if (myrpt->rem_dtmfidx < 0)
05366    {
05367       if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
05368       {
05369          myrpt->mydtmf = c;
05370       }
05371       if (myrpt->p.propagate_dtmf) do_dtmf_local(myrpt,c);
05372       if (myrpt->p.propagate_phonedtmf) do_dtmf_phone(myrpt,mylink,c);
05373       rpt_mutex_unlock(&myrpt->lock);
05374       return;
05375    }
05376    else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0))
05377    {
05378       time(&myrpt->rem_dtmf_time);
05379       if (myrpt->rem_dtmfidx < MAXDTMF)
05380       {
05381          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
05382          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
05383          
05384          rpt_mutex_unlock(&myrpt->lock);
05385          strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
05386          res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink);
05387          rpt_mutex_lock(&myrpt->lock);
05388          
05389          switch(res){
05390 
05391             case DC_INDETERMINATE:
05392                break;
05393             
05394             case DC_REQ_FLUSH:
05395                myrpt->rem_dtmfidx = 0;
05396                myrpt->rem_dtmfbuf[0] = 0;
05397                break;
05398             
05399             
05400             case DC_COMPLETE:
05401             case DC_COMPLETEQUIET:
05402                myrpt->totalexecdcommands++;
05403                myrpt->dailyexecdcommands++;
05404                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
05405                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
05406                myrpt->rem_dtmfbuf[0] = 0;
05407                myrpt->rem_dtmfidx = -1;
05408                myrpt->rem_dtmf_time = 0;
05409                break;
05410             
05411             case DC_ERROR:
05412             default:
05413                myrpt->rem_dtmfbuf[0] = 0;
05414                myrpt->rem_dtmfidx = -1;
05415                myrpt->rem_dtmf_time = 0;
05416                break;
05417          }
05418       }
05419 
05420    }
05421    rpt_mutex_unlock(&myrpt->lock);
05422    return;
05423 }

static void handle_link_phone_dtmf ( struct rpt myrpt,
struct rpt_link mylink,
char  c 
) [static]

Definition at line 5425 of file app_rpt.c.

References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), rpt::callmode, rpt::cidx, rpt::cmdnode, collect_function_digits(), COMPLETE, rpt::dailyexecdcommands, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, donodelog(), rpt::dtmfbuf, rpt::dtmfidx, rpt::endchar, rpt::exten, rpt::funcchar, rpt::lastdtmfcommand, rpt_link::lastrx, rpt::lock, MAXDTMF, rpt::mydtmf, rpt_link::name, rpt::p, rpt::patchcontext, rpt::patchquiet, rpt::pchannel, rpt_link::phonemode, PROC, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), send_link_dtmf(), SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, rpt::stopgen, and rpt::totalexecdcommands.

Referenced by rpt().

05427 {
05428 
05429 char  cmd[300];
05430 int   res;
05431 
05432    if (myrpt->p.archivedir)
05433    {
05434       char str[100];
05435 
05436       sprintf(str,"DTMF(P),%s,%c",mylink->name,c);
05437       donodelog(myrpt,str);
05438    }
05439    rpt_mutex_lock(&myrpt->lock);
05440    if (c == myrpt->p.endchar)
05441    {
05442       if (mylink->lastrx)
05443       {
05444          mylink->lastrx = 0;
05445          rpt_mutex_unlock(&myrpt->lock);
05446          return;
05447       }
05448       myrpt->stopgen = 1;
05449       if (myrpt->cmdnode[0])
05450       {
05451          myrpt->cmdnode[0] = 0;
05452          myrpt->dtmfidx = -1;
05453          myrpt->dtmfbuf[0] = 0;
05454          rpt_mutex_unlock(&myrpt->lock);
05455          rpt_telemetry(myrpt,COMPLETE,NULL);
05456          return;
05457       }
05458    }
05459    if (myrpt->cmdnode[0])
05460    {
05461       rpt_mutex_unlock(&myrpt->lock);
05462       send_link_dtmf(myrpt,c);
05463       return;
05464    }
05465    if (myrpt->callmode == 1)
05466    {
05467       myrpt->exten[myrpt->cidx++] = c;
05468       myrpt->exten[myrpt->cidx] = 0;
05469       /* if this exists */
05470       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
05471       {
05472          myrpt->callmode = 2;
05473          if(!myrpt->patchquiet){
05474             rpt_mutex_unlock(&myrpt->lock);
05475             rpt_telemetry(myrpt,PROC,NULL); 
05476             rpt_mutex_lock(&myrpt->lock);
05477          }
05478       }
05479       /* if can continue, do so */
05480       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 
05481       {
05482          /* call has failed, inform user */
05483          myrpt->callmode = 4;
05484       }
05485    }
05486    if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
05487    {
05488       myrpt->mydtmf = c;
05489    }
05490    if (c == myrpt->p.funcchar)
05491    {
05492       myrpt->rem_dtmfidx = 0;
05493       myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
05494       time(&myrpt->rem_dtmf_time);
05495       rpt_mutex_unlock(&myrpt->lock);
05496       return;
05497    } 
05498    else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0))
05499    {
05500       time(&myrpt->rem_dtmf_time);
05501       if (myrpt->rem_dtmfidx < MAXDTMF)
05502       {
05503          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
05504          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
05505          
05506          rpt_mutex_unlock(&myrpt->lock);
05507          strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
05508          switch(mylink->phonemode)
05509          {
05510              case 1:
05511             res = collect_function_digits(myrpt, cmd, 
05512                SOURCE_PHONE, mylink);
05513             break;
05514              case 2:
05515             res = collect_function_digits(myrpt, cmd, 
05516                SOURCE_DPHONE,mylink);
05517             break;
05518              default:
05519             res = collect_function_digits(myrpt, cmd, 
05520                SOURCE_LNK, mylink);
05521             break;
05522          }
05523 
05524          rpt_mutex_lock(&myrpt->lock);
05525          
05526          switch(res){
05527 
05528             case DC_INDETERMINATE:
05529                break;
05530             
05531             case DC_DOKEY:
05532                mylink->lastrx = 1;
05533                break;
05534             
05535             case DC_REQ_FLUSH:
05536                myrpt->rem_dtmfidx = 0;
05537                myrpt->rem_dtmfbuf[0] = 0;
05538                break;
05539             
05540             
05541             case DC_COMPLETE:
05542             case DC_COMPLETEQUIET:
05543                myrpt->totalexecdcommands++;
05544                myrpt->dailyexecdcommands++;
05545                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
05546                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
05547                myrpt->rem_dtmfbuf[0] = 0;
05548                myrpt->rem_dtmfidx = -1;
05549                myrpt->rem_dtmf_time = 0;
05550                break;
05551             
05552             case DC_ERROR:
05553             default:
05554                myrpt->rem_dtmfbuf[0] = 0;
05555                myrpt->rem_dtmfidx = -1;
05556                myrpt->rem_dtmf_time = 0;
05557                break;
05558          }
05559       }
05560 
05561    }
05562    rpt_mutex_unlock(&myrpt->lock);
05563    return;
05564 }

static int handle_remote_data ( struct rpt myrpt,
char *  str 
) [static]

Definition at line 8233 of file app_rpt.c.

References rpt::archivedir, ast_log(), COMPLETE, donodelog(), func_xlat(), handle_remote_dtmf_digit(), LOG_WARNING, rpt::name, rpt::outxlat, rpt::p, rpt_telemetry(), and seq.

Referenced by rpt_exec().

08234 {
08235 char  tmp[300],cmd[300],dest[300],src[300],c;
08236 int   seq,res;
08237 
08238    /* put string in our buffer */
08239    strncpy(tmp,str,sizeof(tmp) - 1);
08240    if (!strcmp(tmp,discstr)) return 0;
08241    if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
08242    {
08243       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
08244       return 0;
08245    }
08246    if (strcmp(cmd,"D"))
08247    {
08248       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
08249       return 0;
08250    }
08251    /* if not for me, ignore */
08252    if (strcmp(dest,myrpt->name)) return 0;
08253    if (myrpt->p.archivedir)
08254    {
08255       char str[100];
08256 
08257       sprintf(str,"DTMF,%c",c);
08258       donodelog(myrpt,str);
08259    }
08260    c = func_xlat(myrpt,c,&myrpt->p.outxlat);
08261    if (!c) return(0);
08262    res = handle_remote_dtmf_digit(myrpt,c, NULL, 0);
08263    if (res != 1)
08264       return res;
08265    rpt_telemetry(myrpt,COMPLETE,NULL);
08266    return 0;
08267 }

static int handle_remote_dtmf_digit ( struct rpt myrpt,
char  c,
char *  keyed,
int  phonemode 
) [static]

Definition at line 8123 of file app_rpt.c.

References collect_function_digits(), rpt::dailyexecdcommands, DC_COMPLETE, DC_COMPLETEQUIET, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, do_dtmf_local(), rpt::dtmf_time_rem, DTMF_TIMEOUT, rpt::dtmfbuf, rpt::dtmfidx, rpt::funcchar, rpt::hfscanmode, rpt::last_activity_time, rpt::lastdtmfcommand, rpt::lock, MAXDTMF, rpt::p, rpt::propagate_dtmf, rpt_mutex_lock, rpt_mutex_unlock, SOURCE_DPHONE, SOURCE_PHONE, SOURCE_RMT, stop_scan(), and rpt::totalexecdcommands.

Referenced by handle_remote_data(), handle_remote_phone_dtmf(), and rpt_exec().

08124 {
08125 time_t   now;
08126 int   ret,res = 0,src;
08127 
08128    time(&myrpt->last_activity_time);
08129    /* Stop scan mode if in scan mode */
08130    if(myrpt->hfscanmode){
08131       stop_scan(myrpt);
08132       return 0;
08133    }
08134 
08135    time(&now);
08136    /* if timed-out */
08137    if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now)
08138    {
08139       myrpt->dtmfidx = -1;
08140       myrpt->dtmfbuf[0] = 0;
08141       myrpt->dtmf_time_rem = 0;
08142    }
08143    /* if decode not active */
08144    if (myrpt->dtmfidx == -1)
08145    {
08146       /* if not lead-in digit, dont worry */
08147       if (c != myrpt->p.funcchar)
08148       {
08149          if (!myrpt->p.propagate_dtmf)
08150          {
08151             rpt_mutex_lock(&myrpt->lock);
08152             do_dtmf_local(myrpt,c);
08153             rpt_mutex_unlock(&myrpt->lock);
08154          }
08155          return 0;
08156       }
08157       myrpt->dtmfidx = 0;
08158       myrpt->dtmfbuf[0] = 0;
08159       myrpt->dtmf_time_rem = now;
08160       return 0;
08161    }
08162    /* if too many in buffer, start over */
08163    if (myrpt->dtmfidx >= MAXDTMF)
08164    {
08165       myrpt->dtmfidx = 0;
08166       myrpt->dtmfbuf[0] = 0;
08167       myrpt->dtmf_time_rem = now;
08168    }
08169    if (c == myrpt->p.funcchar)
08170    {
08171       /* if star at beginning, or 2 together, erase buffer */
08172       if ((myrpt->dtmfidx < 1) || 
08173          (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->p.funcchar))
08174       {
08175          myrpt->dtmfidx = 0;
08176          myrpt->dtmfbuf[0] = 0;
08177          myrpt->dtmf_time_rem = now;
08178          return 0;
08179       }
08180    }
08181    myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
08182    myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
08183    myrpt->dtmf_time_rem = now;
08184    
08185    
08186    src = SOURCE_RMT;
08187    if (phonemode > 1) src = SOURCE_DPHONE;
08188    else if (phonemode) src = SOURCE_PHONE;
08189    ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL);
08190    
08191    switch(ret){
08192    
08193       case DC_INDETERMINATE:
08194          res = 0;
08195          break;
08196             
08197       case DC_DOKEY:
08198          if (keyed) *keyed = 1;
08199          res = 0;
08200          break;
08201             
08202       case DC_REQ_FLUSH:
08203          myrpt->dtmfidx = 0;
08204          myrpt->dtmfbuf[0] = 0;
08205          res = 0;
08206          break;
08207             
08208             
08209       case DC_COMPLETE:
08210          res = 1;
08211       case DC_COMPLETEQUIET:
08212          myrpt->totalexecdcommands++;
08213          myrpt->dailyexecdcommands++;
08214          strncpy(myrpt->lastdtmfcommand, myrpt->dtmfbuf, MAXDTMF-1);
08215          myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
08216          myrpt->dtmfbuf[0] = 0;
08217          myrpt->dtmfidx = -1;
08218          myrpt->dtmf_time_rem = 0;
08219          break;
08220             
08221       case DC_ERROR:
08222       default:
08223          myrpt->dtmfbuf[0] = 0;
08224          myrpt->dtmfidx = -1;
08225          myrpt->dtmf_time_rem = 0;
08226          res = 0;
08227          break;
08228    }
08229 
08230    return res;
08231 }

static int handle_remote_phone_dtmf ( struct rpt myrpt,
char  c,
char *  keyed,
int  phonemode 
) [static]

Definition at line 8269 of file app_rpt.c.

References rpt::archivedir, COMPLETE, DC_INDETERMINATE, donodelog(), rpt::endchar, handle_remote_dtmf_digit(), rpt::p, and rpt_telemetry().

Referenced by rpt_exec().

08270 {
08271 int   res;
08272 
08273 
08274    if (keyed && *keyed && (c == myrpt->p.endchar))
08275    {
08276       *keyed = 0;
08277       return DC_INDETERMINATE;
08278    }
08279 
08280    if (myrpt->p.archivedir)
08281    {
08282       char str[100];
08283 
08284       sprintf(str,"DTMF(P),%c",c);
08285       donodelog(myrpt,str);
08286    }
08287    res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode);
08288    if (res != 1)
08289       return res;
08290    rpt_telemetry(myrpt,COMPLETE,NULL);
08291    return 0;
08292 }

static int ic706_pltocode ( char *  str  )  [static]

Definition at line 6778 of file app_rpt.c.

References s.

Referenced by set_ic706().

06779 {
06780 int i;
06781 char *s;
06782 
06783    s = strchr(str,'.');
06784    i = 0;
06785    if (s) i = atoi(s + 1);
06786    i += atoi(str) * 10;
06787    switch(i)
06788    {
06789        case 670:
06790       return 0;
06791        case 693:
06792       return 1;
06793        case 719:
06794       return 2;
06795        case 744:
06796       return 3;
06797        case 770:
06798       return 4;
06799        case 797:
06800       return 5;
06801        case 825:
06802       return 6;
06803        case 854:
06804       return 7;
06805        case 885:
06806       return 8;
06807        case 915:
06808       return 9;
06809        case 948:
06810       return 10;
06811        case 974:
06812       return 11;
06813        case 1000:
06814       return 12;
06815        case 1035:
06816       return 13;
06817        case 1072:
06818       return 14;
06819        case 1109:
06820       return 15;
06821        case 1148:
06822       return 16;
06823        case 1188:
06824       return 17;
06825        case 1230:
06826       return 18;
06827        case 1273:
06828       return 19;
06829        case 1318:
06830       return 20;
06831        case 1365:
06832       return 21;
06833        case 1413:
06834       return 22;
06835        case 1462:
06836       return 23;
06837        case 1514:
06838       return 24;
06839        case 1567:
06840       return 25;
06841        case 1598:
06842       return 26;
06843        case 1622:
06844       return 27;
06845        case 1655:
06846       return 28;     
06847        case 1679:
06848       return 29;
06849        case 1713:
06850       return 30;
06851        case 1738:
06852       return 31;
06853        case 1773:
06854       return 32;
06855        case 1799:
06856       return 33;
06857             case 1835:
06858       return 34;
06859        case 1862:
06860       return 35;
06861        case 1899:
06862       return 36;
06863        case 1928:
06864       return 37;
06865        case 1966:
06866       return 38;
06867        case 1995:
06868       return 39;
06869        case 2035:
06870       return 40;
06871        case 2065:
06872       return 41;
06873        case 2107:
06874       return 42;
06875        case 2181:
06876       return 43;
06877        case 2257:
06878       return 44;
06879        case 2291:
06880       return 45;
06881        case 2336:
06882       return 46;
06883        case 2418:
06884       return 47;
06885        case 2503:
06886       return 48;
06887        case 2541:
06888       return 49;
06889    }
06890    return -1;
06891 }

static int kenwood_pltocode ( char *  str  )  [static]

Definition at line 5891 of file app_rpt.c.

References s.

Referenced by setkenwood().

05892 {
05893 int i;
05894 char *s;
05895 
05896    s = strchr(str,'.');
05897    i = 0;
05898    if (s) i = atoi(s + 1);
05899    i += atoi(str) * 10;
05900    switch(i)
05901    {
05902        case 670:
05903       return 1;
05904        case 719:
05905       return 3;
05906        case 744:
05907       return 4;
05908        case 770:
05909       return 5;
05910        case 797:
05911       return 6;
05912        case 825:
05913       return 7;
05914        case 854:
05915       return 8;
05916        case 885:
05917       return 9;
05918        case 915:
05919       return 10;
05920        case 948:
05921       return 11;
05922        case 974:
05923       return 12;
05924        case 1000:
05925       return 13;
05926        case 1035:
05927       return 14;
05928        case 1072:
05929       return 15;
05930        case 1109:
05931       return 16;
05932        case 1148:
05933       return 17;
05934        case 1188:
05935       return 18;
05936        case 1230:
05937       return 19;
05938        case 1273:
05939       return 20;
05940        case 1318:
05941       return 21;
05942        case 1365:
05943       return 22;
05944        case 1413:
05945       return 23;
05946        case 1462:
05947       return 24;
05948        case 1514:
05949       return 25;
05950        case 1567:
05951       return 26;
05952        case 1622:
05953       return 27;
05954        case 1679:
05955       return 28;
05956        case 1738:
05957       return 29;
05958        case 1799:
05959       return 30;
05960        case 1862:
05961       return 31;
05962        case 1928:
05963       return 32;
05964        case 2035:
05965       return 33;
05966        case 2107:
05967       return 34;
05968        case 2181:
05969       return 35;
05970        case 2257:
05971       return 36;
05972        case 2336:
05973       return 37;
05974        case 2418:
05975       return 38;
05976        case 2503:
05977       return 39;
05978    }
05979    return -1;
05980 }

static int load_module ( void   )  [static]

Definition at line 11641 of file app_rpt.c.

References ast_cli_register(), ast_pthread_create, ast_register_application(), rpt_exec(), and rpt_master().

static void load_rpt_vars ( int  n,
int  init 
) [static]

Definition at line 1569 of file app_rpt.c.

References rpt::acctcode, sysstate::alternatetail, rpt::althangtime, rpt::archivedir, ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), rpt::authlevel, sysstate::autopatchdisable, rpt::cfg, rpt::civaddr, rpt::csstanzaname, DEFAULT_CIV_ADDR, DEFAULT_IOBASE, DEFAULT_MONITOR_MIN_DISK_BLOCKS, DEFAULT_REMOTE_INACT_TIMEOUT, DEFAULT_REMOTE_TIMEOUT, DEFAULT_REMOTE_TIMEOUT_WARNING, DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ, desc, rpt::dphone_functions, rpt::dphone_longestfunc, rpt::duplex, ENDCHAR, rpt::endchar, rpt_xlat::endcharseq, rpt::extnodefile, EXTNODEFILE, rpt::extnodes, EXTNODES, finddelim(), FUNCCHAR, rpt::funcchar, rpt_xlat::funccharseq, rpt::functions, FUNCTIONS, HANGTIME, rpt::hangtime, rpt::ident, IDTIME, rpt::idtime, rpt::inxlat, rpt::iobase, rpt::ioport, rpt::link_functions, rpt::link_longestfunc, sysstate::linkfundisable, rpt::linktolink, lock, LOG_NOTICE, LOG_WARNING, rpt::longestfunc, rpt::longestnode, rpt::macro, MACRO, rpt::macro_longest, MAX_SYSSTATES, MAXXLAT, rpt::memory, MEMORY, rpt::monminblocks, ast_variable::name, rpt::name, name, ast_variable::next, rpt_tele::next, rpt::nobusyout, rpt::nodes, NODES, rpt::notelemtx, option_verbose, rpt::ourcallerid, rpt::ourcontext, rpt::outxlat, rpt::p, rpt_xlat::passchars, rpt::phone_functions, rpt::phone_longestfunc, POLITEID, rpt::politeid, rpt_tele::prev, rpt::propagate_dtmf, rpt::propagate_phonedtmf, rpt::remoteinacttimeout, rpt::remotetimeout, rpt::remotetimeoutwarning, rpt::remotetimeoutwarningfreq, retrieve_astcfgint(), rpt::rpt_thread, rpt_vars, rpt::s, sysstate::schedulerdisable, rpt::simple, rpt::skedstanzaname, rpt::startupmacro, rpt::tailmessagemax, rpt::tailmessagen, rpt::tailmessages, rpt::tailmessagetime, rpt::tailsquashedtime, rpt::tele, rpt::tonezone, sysstate::totdisable, TOTIME, rpt::totime, sysstate::txdisable, rpt::txlimitsstanzaname, sysstate::userfundisable, ast_variable::value, and VERBOSE_PREFIX_3.

Referenced by rpt(), rpt_exec(), and rpt_master().

01570 {
01571 char *this,*val;
01572 int   i,j,longestnode;
01573 struct ast_variable *vp;
01574 struct ast_config *cfg;
01575 char *strs[100];
01576 char s1[256];
01577 static char *cs_keywords[] = {"rptena","rptdis","apena","apdis","lnkena","lnkdis","totena","totdis","skena","skdis",
01578             "ufena","ufdis","atena","atdis",NULL};
01579 
01580    if (option_verbose > 2)
01581       ast_verbose(VERBOSE_PREFIX_3 "%s config for repeater %s\n",
01582          (init) ? "Loading initial" : "Re-Loading",rpt_vars[n].name);
01583    ast_mutex_lock(&rpt_vars[n].lock);
01584    if (rpt_vars[n].cfg) ast_config_destroy(rpt_vars[n].cfg);
01585    cfg = ast_config_load("rpt.conf");
01586    if (!cfg) {
01587       ast_mutex_unlock(&rpt_vars[n].lock);
01588       ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf.  Radio Repeater disabled.\n");
01589       pthread_exit(NULL);
01590    }
01591    rpt_vars[n].cfg = cfg; 
01592    this = rpt_vars[n].name;
01593    memset(&rpt_vars[n].p,0,sizeof(rpt_vars[n].p));
01594    if (init)
01595    {
01596       char *cp;
01597       int savearea = (char *)&rpt_vars[n].p - (char *)&rpt_vars[n];
01598 
01599       cp = (char *) &rpt_vars[n].p;
01600       memset(cp + sizeof(rpt_vars[n].p),0,
01601          sizeof(rpt_vars[n]) - (sizeof(rpt_vars[n].p) + savearea));
01602       rpt_vars[n].tele.next = &rpt_vars[n].tele;
01603       rpt_vars[n].tele.prev = &rpt_vars[n].tele;
01604       rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
01605       rpt_vars[n].tailmessagen = 0;
01606    }
01607 #ifdef   __RPT_NOTCH
01608    /* zot out filters stuff */
01609    memset(&rpt_vars[n].filters,0,sizeof(rpt_vars[n].filters));
01610 #endif
01611    val = (char *) ast_variable_retrieve(cfg,this,"context");
01612    if (val) rpt_vars[n].p.ourcontext = val;
01613    else rpt_vars[n].p.ourcontext = this;
01614    val = (char *) ast_variable_retrieve(cfg,this,"callerid");
01615    if (val) rpt_vars[n].p.ourcallerid = val;
01616    val = (char *) ast_variable_retrieve(cfg,this,"accountcode");
01617    if (val) rpt_vars[n].p.acctcode = val;
01618    val = (char *) ast_variable_retrieve(cfg,this,"idrecording");
01619    if (val) rpt_vars[n].p.ident = val;
01620    val = (char *) ast_variable_retrieve(cfg,this,"hangtime");
01621    if (val) rpt_vars[n].p.hangtime = atoi(val);
01622       else rpt_vars[n].p.hangtime = HANGTIME;
01623    val = (char *) ast_variable_retrieve(cfg,this,"althangtime");
01624    if (val) rpt_vars[n].p.althangtime = atoi(val);
01625       else rpt_vars[n].p.althangtime = HANGTIME;
01626    val = (char *) ast_variable_retrieve(cfg,this,"totime");
01627    if (val) rpt_vars[n].p.totime = atoi(val);
01628       else rpt_vars[n].p.totime = TOTIME;
01629    rpt_vars[n].p.tailmessagetime = retrieve_astcfgint(&rpt_vars[n],this, "tailmessagetime", 0, 2400000, 0);    
01630    rpt_vars[n].p.tailsquashedtime = retrieve_astcfgint(&rpt_vars[n],this, "tailsquashedtime", 0, 2400000, 0);     
01631    rpt_vars[n].p.duplex = retrieve_astcfgint(&rpt_vars[n],this,"duplex",0,4,2);
01632    rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", -60000, 2400000, IDTIME);   /* Enforce a min max including zero */
01633    rpt_vars[n].p.politeid = retrieve_astcfgint(&rpt_vars[n],this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */
01634    val = (char *) ast_variable_retrieve(cfg,this,"tonezone");
01635    if (val) rpt_vars[n].p.tonezone = val;
01636    rpt_vars[n].p.tailmessages[0] = 0;
01637    rpt_vars[n].p.tailmessagemax = 0;
01638    val = (char *) ast_variable_retrieve(cfg,this,"tailmessagelist");
01639    if (val) rpt_vars[n].p.tailmessagemax = finddelim(val, rpt_vars[n].p.tailmessages, 500);
01640    val = (char *) ast_variable_retrieve(cfg,this,"memory");
01641    if (!val) val = MEMORY;
01642    rpt_vars[n].p.memory = val;
01643    val = (char *) ast_variable_retrieve(cfg,this,"macro");
01644    if (!val) val = MACRO;
01645    rpt_vars[n].p.macro = val;
01646    val = (char *) ast_variable_retrieve(cfg,this,"startup_macro");
01647    if (val) rpt_vars[n].p.startupmacro = val;
01648    val = (char *) ast_variable_retrieve(cfg,this,"iobase");
01649    /* do not use atoi() here, we need to be able to have
01650       the input specified in hex or decimal so we use
01651       sscanf with a %i */
01652    if ((!val) || (sscanf(val,"%i",&rpt_vars[n].p.iobase) != 1))
01653    rpt_vars[n].p.iobase = DEFAULT_IOBASE;
01654    val = (char *) ast_variable_retrieve(cfg,this,"ioport");
01655    rpt_vars[n].p.ioport = val;
01656    val = (char *) ast_variable_retrieve(cfg,this,"functions");
01657    if (!val)
01658       {
01659          val = FUNCTIONS;
01660          rpt_vars[n].p.simple = 1;
01661       } 
01662    rpt_vars[n].p.functions = val;
01663    val =  (char *) ast_variable_retrieve(cfg,this,"link_functions");
01664    if (val) rpt_vars[n].p.link_functions = val;
01665    else 
01666       rpt_vars[n].p.link_functions = rpt_vars[n].p.functions;
01667    val = (char *) ast_variable_retrieve(cfg,this,"phone_functions");
01668    if (val) rpt_vars[n].p.phone_functions = val;
01669    val = (char *) ast_variable_retrieve(cfg,this,"dphone_functions");
01670    if (val) rpt_vars[n].p.dphone_functions = val;
01671    val = (char *) ast_variable_retrieve(cfg,this,"funcchar");
01672    if (!val) rpt_vars[n].p.funcchar = FUNCCHAR; else 
01673       rpt_vars[n].p.funcchar = *val;      
01674    val = (char *) ast_variable_retrieve(cfg,this,"endchar");
01675    if (!val) rpt_vars[n].p.endchar = ENDCHAR; else 
01676       rpt_vars[n].p.endchar = *val;    
01677    val = (char *) ast_variable_retrieve(cfg,this,"nobusyout");
01678    if (val) rpt_vars[n].p.nobusyout = ast_true(val);
01679    val = (char *) ast_variable_retrieve(cfg,this,"notelemtx");
01680    if (val) rpt_vars[n].p.notelemtx = ast_true(val);
01681    val = (char *) ast_variable_retrieve(cfg,this,"propagate_dtmf");
01682    if (val) rpt_vars[n].p.propagate_dtmf = ast_true(val);
01683    val = (char *) ast_variable_retrieve(cfg,this,"propagate_phonedtmf");
01684    if (val) rpt_vars[n].p.propagate_phonedtmf = ast_true(val);
01685    val = (char *) ast_variable_retrieve(cfg,this,"linktolink");
01686    if (val) rpt_vars[n].p.linktolink = ast_true(val);
01687    val = (char *) ast_variable_retrieve(cfg,this,"nodes");
01688    if (!val) val = NODES;
01689    rpt_vars[n].p.nodes = val;
01690    val = (char *) ast_variable_retrieve(cfg,this,"extnodes");
01691    if (!val) val = EXTNODES;
01692    rpt_vars[n].p.extnodes = val;
01693    val = (char *) ast_variable_retrieve(cfg,this,"extnodefile");
01694    if (!val) val = EXTNODEFILE;
01695    rpt_vars[n].p.extnodefile = val;
01696    val = (char *) ast_variable_retrieve(cfg,this,"archivedir");
01697    if (val) rpt_vars[n].p.archivedir = val;
01698    val = (char *) ast_variable_retrieve(cfg,this,"authlevel");
01699    if (val) rpt_vars[n].p.authlevel = atoi(val); 
01700    else rpt_vars[n].p.authlevel = 0;
01701    val = (char *) ast_variable_retrieve(cfg,this,"monminblocks");
01702    if (val) rpt_vars[n].p.monminblocks = atol(val); 
01703    else rpt_vars[n].p.monminblocks = DEFAULT_MONITOR_MIN_DISK_BLOCKS;
01704    val = (char *) ast_variable_retrieve(cfg,this,"remote_inact_timeout");
01705    if (val) rpt_vars[n].p.remoteinacttimeout = atoi(val); 
01706    else rpt_vars[n].p.remoteinacttimeout = DEFAULT_REMOTE_INACT_TIMEOUT;
01707    val = (char *) ast_variable_retrieve(cfg,this,"civaddr");
01708    if (val) rpt_vars[n].p.civaddr = atoi(val); 
01709    else rpt_vars[n].p.civaddr = DEFAULT_CIV_ADDR;
01710    val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout");
01711    if (val) rpt_vars[n].p.remotetimeout = atoi(val); 
01712    else rpt_vars[n].p.remotetimeout = DEFAULT_REMOTE_TIMEOUT;
01713    val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning");
01714    if (val) rpt_vars[n].p.remotetimeoutwarning = atoi(val); 
01715    else rpt_vars[n].p.remotetimeoutwarning = DEFAULT_REMOTE_TIMEOUT_WARNING;
01716    val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning_freq");
01717    if (val) rpt_vars[n].p.remotetimeoutwarningfreq = atoi(val); 
01718    else rpt_vars[n].p.remotetimeoutwarningfreq = DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ;
01719 #ifdef   __RPT_NOTCH
01720    val = (char *) ast_variable_retrieve(cfg,this,"rxnotch");
01721    if (val) {
01722       i = finddelim(val,strs,MAXFILTERS * 2);
01723       i &= ~1; /* force an even number, rounded down */
01724       if (i >= 2) for(j = 0; j < i; j += 2)
01725       {
01726          rpt_mknotch(atof(strs[j]),atof(strs[j + 1]),
01727            &rpt_vars[n].filters[j >> 1].gain,
01728              &rpt_vars[n].filters[j >> 1].const0,
01729             &rpt_vars[n].filters[j >> 1].const1,
01730                 &rpt_vars[n].filters[j >> 1].const2);
01731          sprintf(rpt_vars[n].filters[j >> 1].desc,"%s Hz, BW = %s",
01732             strs[j],strs[j + 1]);
01733       }
01734 
01735    }
01736 #endif
01737    val = (char *) ast_variable_retrieve(cfg,this,"inxlat");
01738    if (val) {
01739       memset(&rpt_vars[n].p.inxlat,0,sizeof(struct rpt_xlat));
01740       i = finddelim(val,strs,3);
01741       if (i) strncpy(rpt_vars[n].p.inxlat.funccharseq,strs[0],MAXXLAT - 1);
01742       if (i > 1) strncpy(rpt_vars[n].p.inxlat.endcharseq,strs[1],MAXXLAT - 1);
01743       if (i > 2) strncpy(rpt_vars[n].p.inxlat.passchars,strs[2],MAXXLAT - 1);
01744    }
01745    val = (char *) ast_variable_retrieve(cfg,this,"outxlat");
01746    if (val) {
01747       memset(&rpt_vars[n].p.outxlat,0,sizeof(struct rpt_xlat));
01748       i = finddelim(val,strs,3);
01749       if (i) strncpy(rpt_vars[n].p.outxlat.funccharseq,strs[0],MAXXLAT - 1);
01750       if (i > 1) strncpy(rpt_vars[n].p.outxlat.endcharseq,strs[1],MAXXLAT - 1);
01751       if (i > 2) strncpy(rpt_vars[n].p.outxlat.passchars,strs[2],MAXXLAT - 1);
01752    }
01753    /* retreive the stanza name for the control states if there is one */
01754    val = (char *) ast_variable_retrieve(cfg,this,"controlstates");
01755    rpt_vars[n].p.csstanzaname = val;
01756       
01757    /* retreive the stanza name for the scheduler if there is one */
01758    val = (char *) ast_variable_retrieve(cfg,this,"scheduler");
01759    rpt_vars[n].p.skedstanzaname = val;
01760 
01761    /* retreive the stanza name for the txlimits */
01762    val = (char *) ast_variable_retrieve(cfg,this,"txlimits");
01763    rpt_vars[n].p.txlimitsstanzaname = val;
01764 
01765    longestnode = 0;
01766 
01767    vp = ast_variable_browse(cfg, rpt_vars[n].p.nodes);
01768       
01769    while(vp){
01770       j = strlen(vp->name);
01771       if (j > longestnode)
01772          longestnode = j;
01773       vp = vp->next;
01774    }
01775 
01776    rpt_vars[n].longestnode = longestnode;
01777       
01778    /*
01779    * For this repeater, Determine the length of the longest function 
01780    */
01781    rpt_vars[n].longestfunc = 0;
01782    vp = ast_variable_browse(cfg, rpt_vars[n].p.functions);
01783    while(vp){
01784       j = strlen(vp->name);
01785       if (j > rpt_vars[n].longestfunc)
01786          rpt_vars[n].longestfunc = j;
01787       vp = vp->next;
01788    }
01789    /*
01790    * For this repeater, Determine the length of the longest function 
01791    */
01792    rpt_vars[n].link_longestfunc = 0;
01793    vp = ast_variable_browse(cfg, rpt_vars[n].p.link_functions);
01794    while(vp){
01795       j = strlen(vp->name);
01796       if (j > rpt_vars[n].link_longestfunc)
01797          rpt_vars[n].link_longestfunc = j;
01798       vp = vp->next;
01799    }
01800    rpt_vars[n].phone_longestfunc = 0;
01801    if (rpt_vars[n].p.phone_functions)
01802    {
01803       vp = ast_variable_browse(cfg, rpt_vars[n].p.phone_functions);
01804       while(vp){
01805          j = strlen(vp->name);
01806          if (j > rpt_vars[n].phone_longestfunc)
01807             rpt_vars[n].phone_longestfunc = j;
01808          vp = vp->next;
01809       }
01810    }
01811    rpt_vars[n].dphone_longestfunc = 0;
01812    if (rpt_vars[n].p.dphone_functions)
01813    {
01814       vp = ast_variable_browse(cfg, rpt_vars[n].p.dphone_functions);
01815       while(vp){
01816          j = strlen(vp->name);
01817          if (j > rpt_vars[n].dphone_longestfunc)
01818             rpt_vars[n].dphone_longestfunc = j;
01819          vp = vp->next;
01820       }
01821    }
01822    rpt_vars[n].macro_longest = 1;
01823    vp = ast_variable_browse(cfg, rpt_vars[n].p.macro);
01824    while(vp){
01825       j = strlen(vp->name);
01826       if (j > rpt_vars[n].macro_longest)
01827          rpt_vars[n].macro_longest = j;
01828       vp = vp->next;
01829    }
01830    
01831    /* Browse for control states */
01832    if(rpt_vars[n].p.csstanzaname)
01833       vp = ast_variable_browse(cfg, rpt_vars[n].p.csstanzaname);
01834    else
01835       vp = NULL;
01836    for( i = 0 ; vp && (i < MAX_SYSSTATES) ; i++){ /* Iterate over the number of control state lines in the stanza */
01837       int k,nukw,statenum;
01838       statenum=atoi(vp->name);
01839       strncpy(s1, vp->value, 255);
01840       s1[255] = 0;
01841       nukw  = finddelim(s1,strs,32);
01842       
01843       for (k = 0 ; k < nukw ; k++){ /* for each user specified keyword */  
01844          for(j = 0 ; cs_keywords[j] != NULL ; j++){ /* try to match to one in our internal table */
01845             if(!strcmp(strs[k],cs_keywords[j])){
01846                switch(j){
01847                   case 0: /* rptena */
01848                      rpt_vars[n].p.s[statenum].txdisable = 0;
01849                      break;
01850                   case 1: /* rptdis */
01851                      rpt_vars[n].p.s[statenum].txdisable = 1;
01852                      break;
01853          
01854                   case 2: /* apena */
01855                      rpt_vars[n].p.s[statenum].autopatchdisable = 0;
01856                      break;
01857 
01858                   case 3: /* apdis */
01859                      rpt_vars[n].p.s[statenum].autopatchdisable = 1;
01860                      break;
01861 
01862                   case 4: /* lnkena */
01863                      rpt_vars[n].p.s[statenum].linkfundisable = 0;
01864                      break;
01865    
01866                   case 5: /* lnkdis */
01867                      rpt_vars[n].p.s[statenum].linkfundisable = 1;
01868                      break;
01869 
01870                   case 6: /* totena */
01871                      rpt_vars[n].p.s[statenum].totdisable = 0;
01872                      break;
01873                
01874                   case 7: /* totdis */
01875                      rpt_vars[n].p.s[statenum].totdisable = 1;
01876                      break;
01877 
01878                   case 8: /* skena */
01879                      rpt_vars[n].p.s[statenum].schedulerdisable = 0;
01880                      break;
01881 
01882                   case 9: /* skdis */
01883                      rpt_vars[n].p.s[statenum].schedulerdisable = 1;
01884                      break;
01885 
01886                   case 10: /* ufena */
01887                      rpt_vars[n].p.s[statenum].userfundisable = 0;
01888                      break;
01889 
01890                   case 11: /* ufdis */
01891                      rpt_vars[n].p.s[statenum].userfundisable = 1;
01892                      break;
01893 
01894                   case 12: /* atena */
01895                      rpt_vars[n].p.s[statenum].alternatetail = 1;
01896                      break;
01897 
01898                   case 13: /* atdis */
01899                      rpt_vars[n].p.s[statenum].alternatetail = 0;
01900                      break;
01901          
01902                   default:
01903                      ast_log(LOG_WARNING,
01904                         "Unhandled control state keyword %s", cs_keywords[i]);
01905                      break;
01906                }
01907             }
01908          }
01909       }
01910       vp = vp->next;
01911    }
01912    ast_mutex_unlock(&rpt_vars[n].lock);
01913 }

static void local_dtmf_helper ( struct rpt myrpt,
char  c 
) [static]

Definition at line 8356 of file app_rpt.c.

References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), ast_pthread_create, rpt::callmode, rpt::cidx, rpt::cmdnode, collect_function_digits(), COMPLETE, rpt::dailyexecdcommands, DC_COMPLETE, DC_COMPLETEQUIET, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, do_dtmf_phone(), donodelog(), rpt::dtmf_time, rpt::dtmfbuf, rpt::dtmfidx, rpt::endchar, rpt::exten, rpt::funcchar, rpt::lastdtmfcommand, rpt::lock, MAXDTMF, MAXPATCHCONTEXT, rpt::mydtmf, rpt::ourcontext, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchnoct, rpt::patchquiet, rpt::pchannel, PROC, rpt::propagate_phonedtmf, rpt_call(), rpt::rpt_call_thread, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), send_link_dtmf(), rpt::simple, SOURCE_RPT, rpt::stopgen, TERM, and rpt::totalexecdcommands.

Referenced by rpt().

08357 {
08358 int   res;
08359 pthread_attr_t attr;
08360 char  cmd[MAXDTMF+1] = "";
08361 
08362    if (myrpt->p.archivedir)
08363    {
08364       char str[100];
08365 
08366       sprintf(str,"DTMF,MAIN,%c",c);
08367       donodelog(myrpt,str);
08368    }
08369    if (c == myrpt->p.endchar)
08370    {
08371    /* if in simple mode, kill autopatch */
08372       if (myrpt->p.simple && myrpt->callmode)
08373       {
08374          rpt_mutex_lock(&myrpt->lock);
08375          myrpt->callmode = 0;
08376          rpt_mutex_unlock(&myrpt->lock);
08377          rpt_telemetry(myrpt,TERM,NULL);
08378          return;
08379       }
08380       rpt_mutex_lock(&myrpt->lock);
08381       myrpt->stopgen = 1;
08382       if (myrpt->cmdnode[0])
08383       {
08384          myrpt->cmdnode[0] = 0;
08385          myrpt->dtmfidx = -1;
08386          myrpt->dtmfbuf[0] = 0;
08387          rpt_mutex_unlock(&myrpt->lock);
08388          rpt_telemetry(myrpt,COMPLETE,NULL);
08389       } 
08390       else
08391                 {
08392                         rpt_mutex_unlock(&myrpt->lock);
08393                         if (myrpt->p.propagate_phonedtmf)
08394                                do_dtmf_phone(myrpt,NULL,c);
08395                 }
08396       return;
08397    }
08398    rpt_mutex_lock(&myrpt->lock);
08399    if (myrpt->cmdnode[0])
08400    {
08401       rpt_mutex_unlock(&myrpt->lock);
08402       send_link_dtmf(myrpt,c);
08403       return;
08404    }
08405    if (!myrpt->p.simple)
08406    {
08407       if (c == myrpt->p.funcchar)
08408       {
08409          myrpt->dtmfidx = 0;
08410          myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
08411          rpt_mutex_unlock(&myrpt->lock);
08412          time(&myrpt->dtmf_time);
08413          return;
08414       } 
08415       else if ((c != myrpt->p.endchar) && (myrpt->dtmfidx >= 0))
08416       {
08417          time(&myrpt->dtmf_time);
08418          
08419          if (myrpt->dtmfidx < MAXDTMF)
08420          {
08421             myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
08422             myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
08423             
08424             strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1);
08425             
08426             rpt_mutex_unlock(&myrpt->lock);
08427             res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL);
08428             rpt_mutex_lock(&myrpt->lock);
08429             switch(res){
08430                 case DC_INDETERMINATE:
08431                break;
08432                 case DC_REQ_FLUSH:
08433                myrpt->dtmfidx = 0;
08434                myrpt->dtmfbuf[0] = 0;
08435                break;
08436                 case DC_COMPLETE:
08437                 case DC_COMPLETEQUIET:
08438                myrpt->totalexecdcommands++;
08439                myrpt->dailyexecdcommands++;
08440                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
08441                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
08442                myrpt->dtmfbuf[0] = 0;
08443                myrpt->dtmfidx = -1;
08444                myrpt->dtmf_time = 0;
08445                break;
08446 
08447                 case DC_ERROR:
08448                 default:
08449                myrpt->dtmfbuf[0] = 0;
08450                myrpt->dtmfidx = -1;
08451                myrpt->dtmf_time = 0;
08452                break;
08453             }
08454             if(res != DC_INDETERMINATE) {
08455                rpt_mutex_unlock(&myrpt->lock);
08456                return;
08457             }
08458          } 
08459       }
08460    }
08461    else /* if simple */
08462    {
08463       if ((!myrpt->callmode) && (c == myrpt->p.funcchar))
08464       {
08465          myrpt->callmode = 1;
08466          myrpt->patchnoct = 0;
08467          myrpt->patchquiet = 0;
08468          myrpt->patchfarenddisconnect = 0;
08469          myrpt->patchdialtime = 0;
08470          strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT);
08471          myrpt->cidx = 0;
08472          myrpt->exten[myrpt->cidx] = 0;
08473          rpt_mutex_unlock(&myrpt->lock);
08474               pthread_attr_init(&attr);
08475               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08476          ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt);
08477          return;
08478       }
08479    }
08480    if (myrpt->callmode == 1)
08481    {
08482       myrpt->exten[myrpt->cidx++] = c;
08483       myrpt->exten[myrpt->cidx] = 0;
08484       /* if this exists */
08485       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
08486       {
08487          myrpt->callmode = 2;
08488          rpt_mutex_unlock(&myrpt->lock);
08489          if(!myrpt->patchquiet)
08490             rpt_telemetry(myrpt,PROC,NULL); 
08491          return;
08492       }
08493       /* if can continue, do so */
08494       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
08495       {
08496          /* call has failed, inform user */
08497          myrpt->callmode = 4;
08498       }
08499       rpt_mutex_unlock(&myrpt->lock);
08500       return;
08501    }
08502    if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
08503    {
08504       myrpt->mydtmf = c;
08505    }
08506    rpt_mutex_unlock(&myrpt->lock);
08507    if ((myrpt->dtmfidx < 0) && myrpt->p.propagate_phonedtmf)
08508       do_dtmf_phone(myrpt,NULL,c);
08509    return;
08510 }

static int matchkeyword ( char *  string,
char **  param,
char *  keywords[] 
) [static]

Definition at line 1425 of file app_rpt.c.

Referenced by function_autopatchup().

01426 {
01427 int   i,ls;
01428    for( i = 0 ; keywords[i] ; i++){
01429       ls = strlen(keywords[i]);
01430       if(!ls){
01431          *param = NULL;
01432          return 0;
01433       }
01434       if(!strncmp(string, keywords[i], ls)){
01435          if(param)
01436             *param = string + ls;
01437          return i + 1; 
01438       }
01439    }
01440    param = NULL;
01441    return 0;
01442 }

static int mem2vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7092 of file app_rpt.c.

References civ_cmd(), rpt::civaddr, and rpt::p.

Referenced by set_ic706().

07093 {
07094    unsigned char cmdstr[10];
07095    
07096    cmdstr[0] = cmdstr[1] = 0xfe;
07097    cmdstr[2] = myrpt->p.civaddr;
07098    cmdstr[3] = 0xe0;
07099    cmdstr[4] = 0x0a;
07100    cmdstr[5] = 0xfd;
07101 
07102    return(civ_cmd(myrpt,cmdstr,6));
07103 }

static int multimode_bump_freq ( struct rpt myrpt,
int  interval 
) [static]

Definition at line 7455 of file app_rpt.c.

References multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), and rpt::remote.

Referenced by function_remote(), and service_scan().

07456 {
07457    if(!strcmp(myrpt->remote, remote_rig_ft897))
07458       return multimode_bump_freq_ft897(myrpt, interval);
07459    else if(!strcmp(myrpt->remote, remote_rig_ic706))
07460       return multimode_bump_freq_ic706(myrpt, interval);
07461    else
07462       return -1;
07463 }

static int multimode_bump_freq_ft897 ( struct rpt myrpt,
int  interval 
) [static]

Definition at line 6644 of file app_rpt.c.

References check_freq_ft897(), rpt::freq, MAXREMSTR, set_freq_ft897(), and split_freq().

Referenced by multimode_bump_freq().

06645 {
06646    int m,d;
06647    char mhz[MAXREMSTR], decimals[MAXREMSTR];
06648 
06649    if(debug)
06650       printf("Before bump: %s\n", myrpt->freq);
06651 
06652    if(split_freq(mhz, decimals, myrpt->freq))
06653       return -1;
06654    
06655    m = atoi(mhz);
06656    d = atoi(decimals);
06657 
06658    d += (interval / 10); /* 10Hz resolution */
06659    if(d < 0){
06660       m--;
06661       d += 100000;
06662    }
06663    else if(d >= 100000){
06664       m++;
06665       d -= 100000;
06666    }
06667 
06668    if(check_freq_ft897(m, d, NULL)){
06669       if(debug)
06670          printf("Bump freq invalid\n");
06671       return -1;
06672    }
06673 
06674    snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d);
06675 
06676    if(debug)
06677       printf("After bump: %s\n", myrpt->freq);
06678 
06679    return set_freq_ft897(myrpt, myrpt->freq);   
06680 }

static int multimode_bump_freq_ic706 ( struct rpt myrpt,
int  interval 
) [static]

Definition at line 7188 of file app_rpt.c.

References check_freq_ic706(), rpt::civaddr, rpt::freq, MAXREMSTR, rpt::p, serial_remote_io(), and split_freq().

Referenced by multimode_bump_freq().

07189 {
07190    int m,d;
07191    char mhz[MAXREMSTR], decimals[MAXREMSTR];
07192    unsigned char cmdstr[20];
07193 
07194    if(debug)
07195       printf("Before bump: %s\n", myrpt->freq);
07196 
07197    if(split_freq(mhz, decimals, myrpt->freq))
07198       return -1;
07199    
07200    m = atoi(mhz);
07201    d = atoi(decimals);
07202 
07203    d += (interval / 10); /* 10Hz resolution */
07204    if(d < 0){
07205       m--;
07206       d += 100000;
07207    }
07208    else if(d >= 100000){
07209       m++;
07210       d -= 100000;
07211    }
07212 
07213    if(check_freq_ic706(m, d, NULL)){
07214       if(debug)
07215          printf("Bump freq invalid\n");
07216       return -1;
07217    }
07218 
07219    snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d);
07220 
07221    if(debug)
07222       printf("After bump: %s\n", myrpt->freq);
07223 
07224    /* The ic-706 likes packed BCD frequencies */
07225 
07226    cmdstr[0] = cmdstr[1] = 0xfe;
07227    cmdstr[2] = myrpt->p.civaddr;
07228    cmdstr[3] = 0xe0;
07229    cmdstr[4] = 0;
07230    cmdstr[5] = ((d % 10) << 4);
07231    cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10);
07232    cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000);
07233    cmdstr[8] = (((m % 100)/10) << 4) + (m % 10);
07234    cmdstr[9] = (m / 100);
07235    cmdstr[10] = 0xfd;
07236 
07237    return(serial_remote_io(myrpt,cmdstr,11,NULL,0,0));
07238 }

static int multimode_capable ( struct rpt myrpt  )  [static]

Definition at line 878 of file app_rpt.c.

References rpt::remote.

Referenced by function_remote(), and rpt_tele_thread().

00879 {
00880    if(!strcmp(myrpt->remote, remote_rig_ft897))
00881       return 1;
00882    if(!strcmp(myrpt->remote, remote_rig_ic706))
00883       return 1;
00884    return 0;
00885 }  

static int myatoi ( char *  str  )  [static]

Definition at line 1467 of file app_rpt.c.

Referenced by function_cop(), function_ilink(), function_remote(), function_status(), retrieve_astcfgint(), and rpt_do_debug().

01468 {
01469 int   ret;
01470 
01471    if (str == NULL) return -1;
01472    /* leave this %i alone, non-base-10 input is useful here */
01473    if (sscanf(str,"%i",&ret) != 1) return -1;
01474    return ret;
01475 }

static int mycompar ( const void *  a,
const void *  b 
) [static]

Definition at line 1477 of file app_rpt.c.

Referenced by rpt_do_nodes(), and rpt_tele_thread().

01478 {
01479 char  **x = (char **) a;
01480 char  **y = (char **) b;
01481 int   xoff,yoff;
01482 
01483    if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0;
01484    if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0;
01485    return(strcmp((*x) + xoff,(*y) + yoff));
01486 }

static char* node_lookup ( struct rpt myrpt,
char *  digitbuf 
) [static]

Definition at line 1357 of file app_rpt.c.

References ast_config_destroy(), ast_config_load(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), ast_variable_retrieve(), rpt::cfg, rpt::extnodefile, rpt::extnodes, last, rpt::longestnode, ast_variable::name, ast_variable::next, rpt::nodes, and rpt::p.

Referenced by attempt_reconnect(), connect_link(), function_ilink(), and rpt_exec().

01358 {
01359 
01360 char *val;
01361 int longestnode,j;
01362 struct stat mystat;
01363 static time_t last = 0;
01364 static struct ast_config *ourcfg = NULL;
01365 struct ast_variable *vp;
01366 
01367    /* try to look it up locally first */
01368    val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf);
01369    if (val) return(val);
01370    ast_mutex_lock(&nodelookuplock);
01371    /* if file does not exist */
01372    if (stat(myrpt->p.extnodefile,&mystat) == -1)
01373    {
01374       if (ourcfg) ast_config_destroy(ourcfg);
01375       ourcfg = NULL;
01376       ast_mutex_unlock(&nodelookuplock);
01377       return(NULL);
01378    }
01379    /* if we need to reload */
01380    if (mystat.st_mtime > last)
01381    {
01382       if (ourcfg) ast_config_destroy(ourcfg);
01383       ourcfg = ast_config_load(myrpt->p.extnodefile);
01384       /* if file not there, just bail */
01385       if (!ourcfg)
01386       {
01387          ast_mutex_unlock(&nodelookuplock);
01388          return(NULL);
01389       }
01390       /* reset "last" time */
01391       last = mystat.st_mtime;
01392 
01393       /* determine longest node length again */    
01394       longestnode = 0;
01395       vp = ast_variable_browse(myrpt->cfg, myrpt->p.nodes);
01396       while(vp){
01397          j = strlen(vp->name);
01398          if (j > longestnode)
01399             longestnode = j;
01400          vp = vp->next;
01401       }
01402 
01403       vp = ast_variable_browse(ourcfg, myrpt->p.extnodes);
01404       while(vp){
01405          j = strlen(vp->name);
01406          if (j > longestnode)
01407             longestnode = j;
01408          vp = vp->next;
01409       }
01410 
01411       myrpt->longestnode = longestnode;
01412    }
01413    val = NULL;
01414    if (ourcfg)
01415       val = (char *) ast_variable_retrieve(ourcfg, myrpt->p.extnodes, digitbuf);
01416    ast_mutex_unlock(&nodelookuplock);
01417    return(val);
01418 }

static int openserial ( char *  fname  )  [static]

Definition at line 1154 of file app_rpt.c.

References ast_log(), ECHO, LOG_WARNING, and MAX.

Referenced by rpt_exec().

01155 {
01156    struct termios mode;
01157    int fd;
01158 
01159    fd = open(fname,O_RDWR);
01160    if (fd == -1)
01161    {
01162       ast_log(LOG_WARNING,"Cannot open serial port %s\n",fname);
01163       return -1;
01164    }
01165    memset(&mode, 0, sizeof(mode));
01166    if (tcgetattr(fd, &mode)) {
01167       ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", fname, strerror(errno));
01168       return -1;
01169    }
01170 #ifndef SOLARIS
01171    cfmakeraw(&mode);
01172 #else
01173         mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
01174                         |INLCR|IGNCR|ICRNL|IXON);
01175         mode.c_oflag &= ~OPOST;
01176         mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
01177         mode.c_cflag &= ~(CSIZE|PARENB|CRTSCTS);
01178         mode.c_cflag |= CS8;
01179    mode.c_cc[TIME] = 3;
01180    mode.c_cc[MAX] = 1;
01181 #endif
01182 
01183    cfsetispeed(&mode, B9600);
01184    cfsetospeed(&mode, B9600);
01185    if (tcsetattr(fd, TCSANOW, &mode)) 
01186       ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", fname, strerror(errno));
01187    return(fd); 
01188 }

static int play_silence ( struct ast_channel chan,
int  duration 
) [static]

Definition at line 2409 of file app_rpt.c.

References play_tone_pair().

Referenced by send_morse().

02410 {
02411    return play_tone_pair(chan, 0, 0, duration, 0);
02412 }

static int play_tone ( struct ast_channel chan,
int  freq,
int  duration,
int  amplitude 
) [static]

Definition at line 2404 of file app_rpt.c.

References play_tone_pair().

Referenced by rpt_tele_thread(), and send_morse().

02405 {
02406    return play_tone_pair(chan, freq, 0, duration, amplitude);
02407 }

static int play_tone_pair ( struct ast_channel chan,
int  f1,
int  f2,
int  duration,
int  amplitude 
) [static]

Definition at line 2390 of file app_rpt.c.

References ast_safe_sleep(), ast_tonepair_start(), and ast_channel::generatordata.

Referenced by play_silence(), play_tone(), and send_tone_telemetry().

02391 {
02392    int res;
02393 
02394         if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude)))
02395                 return res;
02396                                                                                                                                             
02397         while(chan->generatordata) {
02398       if (ast_safe_sleep(chan,1)) return -1;
02399    }
02400 
02401         return 0;
02402 }

static void queue_id ( struct rpt myrpt  )  [static]

Definition at line 8515 of file app_rpt.c.

References ID, rpt::idtime, rpt::idtimer, rpt::lock, rpt::mustid, rpt::p, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), and rpt::tailid.

Referenced by rpt().

08516 {
08517    if(myrpt->p.idtime){ /* ID time must be non-zero */
08518       myrpt->mustid = myrpt->tailid = 0;
08519       myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */
08520       rpt_mutex_unlock(&myrpt->lock);
08521       rpt_telemetry(myrpt,ID,NULL);
08522       rpt_mutex_lock(&myrpt->lock);
08523    }
08524 }

static int rbi_mhztoband ( char *  str  )  [static]

Definition at line 5597 of file app_rpt.c.

Referenced by setrbi(), and setrbi_check().

05598 {
05599 int   i;
05600 
05601    i = atoi(str) / 10; /* get the 10's of mhz */
05602    switch(i)
05603    {
05604        case 2:
05605       return 10;
05606        case 5:
05607       return 11;
05608        case 14:
05609       return 2;
05610        case 22:
05611       return 3;
05612        case 44:
05613       return 4;
05614        case 124:
05615       return 0;
05616        case 125:
05617       return 1;
05618        case 126:
05619       return 8;
05620        case 127:
05621       return 5;
05622        case 128:
05623       return 6;
05624        case 129:
05625       return 7;
05626        default:
05627       break;
05628    }
05629    return -1;
05630 }

static void rbi_out ( struct rpt myrpt,
unsigned char *  data 
) [static]

Definition at line 5754 of file app_rpt.c.

References ast_log(), ast_channel::fds, LOG_WARNING, rbi_out_parallel(), and rpt::rxchannel.

Referenced by setrbi().

05755 {
05756 struct zt_radio_param r;
05757 
05758    memset(&r,0,sizeof(struct zt_radio_param));
05759    r.radpar = ZT_RADPAR_REMMODE;
05760    r.data = ZT_RADPAR_REM_RBI1;
05761    /* if setparam ioctl fails, its probably not a pciradio card */
05762    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
05763    {
05764       rbi_out_parallel(myrpt,data);
05765       return;
05766    }
05767    r.radpar = ZT_RADPAR_REMCOMMAND;
05768    memcpy(&r.data,data,5);
05769    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
05770    {
05771       ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->rxchannel->name);
05772       return;
05773    }
05774 }

static void rbi_out_parallel ( struct rpt myrpt,
unsigned char *  data 
) [static]

Definition at line 5728 of file app_rpt.c.

References rpt::iobase, and rpt::p.

Referenced by rbi_out().

05729     {
05730     int i,j;
05731     unsigned char od,d;
05732     static volatile long long delayvar;
05733 
05734     for(i = 0 ; i < 5 ; i++){
05735         od = *data++; 
05736         for(j = 0 ; j < 8 ; j++){
05737             d = od & 1;
05738             outb(d,myrpt->p.iobase);
05739        /* >= 15 us */
05740        for(delayvar = 1; delayvar < 15000; delayvar++); 
05741             od >>= 1;
05742             outb(d | 2,myrpt->p.iobase);
05743        /* >= 30 us */
05744        for(delayvar = 1; delayvar < 30000; delayvar++); 
05745             outb(d,myrpt->p.iobase);
05746        /* >= 10 us */
05747        for(delayvar = 1; delayvar < 10000; delayvar++); 
05748             }
05749         }
05750    /* >= 50 us */
05751         for(delayvar = 1; delayvar < 50000; delayvar++); 
05752     }

static int rbi_pltocode ( char *  str  )  [static]

Definition at line 5633 of file app_rpt.c.

References s.

Referenced by setrbi(), and setrbi_check().

05634 {
05635 int i;
05636 char *s;
05637 
05638    s = strchr(str,'.');
05639    i = 0;
05640    if (s) i = atoi(s + 1);
05641    i += atoi(str) * 10;
05642    switch(i)
05643    {
05644        case 670:
05645       return 0;
05646        case 719:
05647       return 1;
05648        case 744:
05649       return 2;
05650        case 770:
05651       return 3;
05652        case 797:
05653       return 4;
05654        case 825:
05655       return 5;
05656        case 854:
05657       return 6;
05658        case 885:
05659       return 7;
05660        case 915:
05661       return 8;
05662        case 948:
05663       return 9;
05664        case 974:
05665       return 10;
05666        case 1000:
05667       return 11;
05668        case 1035:
05669       return 12;
05670        case 1072:
05671       return 13;
05672        case 1109:
05673       return 14;
05674        case 1148:
05675       return 15;
05676        case 1188:
05677       return 16;
05678        case 1230:
05679       return 17;
05680        case 1273:
05681       return 18;
05682        case 1318:
05683       return 19;
05684        case 1365:
05685       return 20;
05686        case 1413:
05687       return 21;
05688        case 1462:
05689       return 22;
05690        case 1514:
05691       return 23;
05692        case 1567:
05693       return 24;
05694        case 1622:
05695       return 25;
05696        case 1679:
05697       return 26;
05698        case 1738:
05699       return 27;
05700        case 1799:
05701       return 28;
05702        case 1862:
05703       return 29;
05704        case 1928:
05705       return 30;
05706        case 2035:
05707       return 31;
05708        case 2107:
05709       return 32;
05710        case 2181:
05711       return 33;
05712        case 2257:
05713       return 34;
05714        case 2336:
05715       return 35;
05716        case 2418:
05717       return 36;
05718        case 2503:
05719       return 37;
05720    }
05721    return -1;
05722 }

static int reload ( void   )  [static]

Definition at line 11680 of file app_rpt.c.

References reload(), and rpt_vars.

11682 {
11683 int   n;
11684 
11685    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
11686    return(0);
11687 }

static int retreive_memory ( struct rpt myrpt,
char *  memory 
) [static]

Definition at line 7552 of file app_rpt.c.

References ast_variable_retrieve(), rpt::cfg, rpt::freq, rpt::memory, rpt::offset, rpt::p, rpt::powerlevel, REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, REM_PLUS, REM_SIMPLEX, rpt::remmode, rpt::rxpl, rpt::rxplon, s, rpt::txpl, and rpt::txplon.

Referenced by function_remote(), and rpt_master().

07553 {
07554    char tmp[30], *s, *s1, *val;
07555 
07556    val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.memory, memory);
07557    if (!val){
07558       return -1;
07559    }        
07560    strncpy(tmp,val,sizeof(tmp) - 1);
07561    tmp[sizeof(tmp)-1] = 0;
07562 
07563    s = strchr(tmp,',');
07564    if (!s)
07565       return 1; 
07566    *s++ = 0;
07567    s1 = strchr(s,',');
07568    if (!s1)
07569       return 1;
07570    *s1++ = 0;
07571    strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1);
07572    strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1);
07573    strncpy(myrpt->txpl, s, sizeof(myrpt->rxpl) - 1);
07574    myrpt->remmode = REM_MODE_FM;
07575    myrpt->offset = REM_SIMPLEX;
07576    myrpt->powerlevel = REM_MEDPWR;
07577    myrpt->txplon = myrpt->rxplon = 0;
07578    while(*s1){
07579       switch(*s1++){
07580          case 'A':
07581          case 'a':
07582             strcpy(myrpt->rxpl, "100.0");
07583             strcpy(myrpt->txpl, "100.0");
07584             myrpt->remmode = REM_MODE_AM; 
07585             break;
07586          case 'B':
07587          case 'b':
07588             strcpy(myrpt->rxpl, "100.0");
07589             strcpy(myrpt->txpl, "100.0");
07590             myrpt->remmode = REM_MODE_LSB;
07591             break;
07592          case 'F':
07593             myrpt->remmode = REM_MODE_FM;
07594             break;
07595          case 'L':
07596          case 'l':
07597             myrpt->powerlevel = REM_LOWPWR;
07598             break;               
07599          case 'H':
07600          case 'h':
07601             myrpt->powerlevel = REM_HIPWR;
07602             break;
07603                
07604          case 'M':
07605          case 'm':
07606             myrpt->powerlevel = REM_MEDPWR;
07607             break;
07608                   
07609          case '-':
07610             myrpt->offset = REM_MINUS;
07611             break;
07612                   
07613          case '+':
07614             myrpt->offset = REM_PLUS;
07615             break;
07616                   
07617          case 'S':
07618          case 's':
07619             myrpt->offset = REM_SIMPLEX;
07620             break;
07621                   
07622          case 'T':
07623          case 't':
07624             myrpt->txplon = 1;
07625             break;
07626                   
07627          case 'R':
07628          case 'r':
07629             myrpt->rxplon = 1;
07630             break;
07631 
07632          case 'U':
07633          case 'u':
07634             strcpy(myrpt->rxpl, "100.0");
07635             strcpy(myrpt->txpl, "100.0");
07636             myrpt->remmode = REM_MODE_USB;
07637             break;
07638          default:
07639             return 1;
07640       }
07641    }
07642    return 0;
07643 }

static int retrieve_astcfgint ( struct rpt myrpt,
char *  category,
char *  name,
int  min,
int  max,
int  defl 
) [static]

Definition at line 1542 of file app_rpt.c.

References ast_variable_retrieve(), rpt::cfg, myatoi(), and var.

Referenced by get_wait_interval(), load_rpt_vars(), and telem_any().

01543 {
01544         char *var;
01545         int ret;
01546    char include_zero = 0;
01547 
01548    if(min < 0){ /* If min is negative, this means include 0 as a valid entry */
01549       min = -min;
01550       include_zero = 1;
01551    }           
01552                                                                      
01553         var = (char *) ast_variable_retrieve(myrpt->cfg, category, name);
01554         if(var){
01555                 ret = myatoi(var);
01556       if(include_zero && !ret)
01557          return 0;
01558                 if(ret < min)
01559                         ret = min;
01560                 if(ret > max)
01561                         ret = max;
01562         }
01563         else
01564                 ret = defl;
01565         return ret;
01566 }

static void* rpt ( void *  this  )  [static]

Definition at line 8650 of file app_rpt.c.

References __kickshort(), __mklinklist(), ast_channel::_state, sysstate::alternatetail, rpt::althangtime, ast_channel::appl, rpt::archivedir, ast_call(), ast_channel_setoption(), ast_check_hangup(), ast_closestream(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_FORMAT_SLINEAR, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_hangup(), ast_indicate(), ast_log(), AST_OPTION_RELAXDTMF, AST_OPTION_TONE_VERIFY, AST_PTHREADT_STOP, ast_read(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_BUSY, AST_STATE_UP, ast_variable_retrieve(), ast_verbose(), ast_waitfor_n(), ast_write(), ast_writefile(), ast_writestream(), attempt_reconnect(), rpt::callmode, rpt::cfg, rpt_link::chan, rpt_tele::chan, rpt::cmdnode, rpt::conf, CONNECTED, rpt_link::connected, rpt_link::connecttime, CONNFAIL, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, ast_frame::data, ast_channel::data, ast_frame::datalen, DISC_TIME, rpt_link::disced, rpt_link::disctime, rpt::disgorgetime, diskavail(), do_dtmf_local(), do_scheduler(), donodelog(), rpt::dtmf_local_timer, rpt::dtmf_time, DTMF_TIMEOUT, rpt::dtmfbuf, rpt_link::dtmfed, rpt::dtmfidx, rpt::duplex, rpt_link::elaptime, rpt::exten, rpt::exttx, ast_channel::fds, ast_frame::frametype, free, func_xlat(), handle_link_data(), handle_link_phone_dtmf(), rpt::hangtime, rpt_link::hasconnected, ID, IDTALKOVER, rpt::idtime, rpt::idtimer, rpt::inxlat, rpt_link::isremote, rpt::keyed, rpt_link::killme, rpt::lastdtmfcommand, rpt_link::lastf1, rpt::lastf1, rpt_link::lastf2, rpt::lastf2, rpt::lastnodewhichkeyedusup, rpt_link::lastrx, rpt_link::lastrx1, rpt_link::lasttx, LINKLISTTIME, rpt_link::linklisttimer, rpt::links, rpt::linktolink, LINKUNKEY, load_rpt_vars(), local_dtmf_helper(), rpt::localtx, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macrobuf, MACROPTIME, MACROTIME, rpt::macrotimer, ast_frame::mallocd, rpt_link::max_retries, MAXCONNECTTIME, MAXLINKLIST, MAXMACRO, rpt_link::mode, rpt_tele::mode, rpt::monchannel, rpt::monminblocks, rpt::monstream, MSWAIT, rpt::mustid, rpt_link::name, rpt::name, rpt_link::next, rpt_tele::next, rpt::notelemtx, ast_frame::offset, option_verbose, rpt_link::outbound, rpt::p, rpt_link::pchan, rpt::pchannel, rpt_link::phonemode, rpt::politeid, rpt_link::prev, queue_id(), rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, REMDISC, rpt_link::rerxtimer, rpt::rerxtimer, rpt_link::retries, RETRY_TIMER_MS, rpt_link::retrytimer, rpt_link::retxtimer, rpt::retxtimer, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, rpt::rxchannel, s, rpt::s, ast_frame::samples, rpt::scram, rpt::skedtimer, START_DELAY, rpt::startupmacro, ast_frame::subclass, rpt::sysstate_cur, rpt::tailevent, rpt::tailid, rpt::tailmessages, rpt::tailmessagetime, TAILMSG, rpt::tailtimer, rpt::tele, rpt_link::thisconnected, TIMEOUT, rpt::timeouts, rpt::tmsgtimer, rpt::tonotify, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, sysstate::totdisable, rpt::totime, rpt::totimer, rpt::tounkeyed, rpt::txchanname, rpt::txchannel, rpt::txconf, sysstate::txdisable, rpt::txpchannel, UNKEY, VERBOSE_PREFIX_3, and ast_channel::whentohangup.

08651 {
08652 struct   rpt *myrpt = (struct rpt *)this;
08653 char *tele,*idtalkover,c;
08654 int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,othertelemqueued;
08655 int tailmessagequeued,ctqueued,dtmfed;
08656 struct ast_channel *who;
08657 ZT_CONFINFO ci;  /* conference info */
08658 time_t   t;
08659 struct rpt_link *l,*m;
08660 struct rpt_tele *telem;
08661 char tmpstr[300],lstr[MAXLINKLIST];
08662 
08663 
08664    if (myrpt->p.archivedir) mkdir(myrpt->p.archivedir,0600);
08665    sprintf(tmpstr,"%s/%s",myrpt->p.archivedir,myrpt->name);
08666    mkdir(tmpstr,0600);
08667    rpt_mutex_lock(&myrpt->lock);
08668 
08669    telem = myrpt->tele.next;
08670    while(telem != &myrpt->tele)
08671    {
08672       ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV);
08673       telem = telem->next;
08674    }
08675    rpt_mutex_unlock(&myrpt->lock);
08676    /* find our index, and load the vars initially */
08677    for(i = 0; i < nrpts; i++)
08678    {
08679       if (&rpt_vars[i] == myrpt)
08680       {
08681          load_rpt_vars(i,0);
08682          break;
08683       }
08684    }
08685    rpt_mutex_lock(&myrpt->lock);
08686    strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1);
08687    tele = strchr(tmpstr,'/');
08688    if (!tele)
08689    {
08690       fprintf(stderr,"rpt:Rxchannel Dial number (%s) must be in format tech/number\n",myrpt->rxchanname);
08691       rpt_mutex_unlock(&myrpt->lock);
08692       myrpt->rpt_thread = AST_PTHREADT_STOP;
08693       pthread_exit(NULL);
08694    }
08695    *tele++ = 0;
08696    myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL);
08697    if (myrpt->rxchannel)
08698    {
08699       if (myrpt->rxchannel->_state == AST_STATE_BUSY)
08700       {
08701          fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
08702          rpt_mutex_unlock(&myrpt->lock);
08703          ast_hangup(myrpt->rxchannel);
08704          myrpt->rpt_thread = AST_PTHREADT_STOP;
08705          pthread_exit(NULL);
08706       }
08707       ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
08708       ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
08709       myrpt->rxchannel->whentohangup = 0;
08710       myrpt->rxchannel->appl = "Apprpt";
08711       myrpt->rxchannel->data = "(Repeater Rx)";
08712       if (option_verbose > 2)
08713          ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
08714             tmpstr,tele,myrpt->rxchannel->name);
08715       ast_call(myrpt->rxchannel,tele,999);
08716       if (myrpt->rxchannel->_state != AST_STATE_UP)
08717       {
08718          rpt_mutex_unlock(&myrpt->lock);
08719          ast_hangup(myrpt->rxchannel);
08720          myrpt->rpt_thread = AST_PTHREADT_STOP;
08721          pthread_exit(NULL);
08722       }
08723    }
08724    else
08725    {
08726       fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
08727       rpt_mutex_unlock(&myrpt->lock);
08728       myrpt->rpt_thread = AST_PTHREADT_STOP;
08729       pthread_exit(NULL);
08730    }
08731    if (myrpt->txchanname)
08732    {
08733       strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1);
08734       tele = strchr(tmpstr,'/');
08735       if (!tele)
08736       {
08737          fprintf(stderr,"rpt:Txchannel Dial number (%s) must be in format tech/number\n",myrpt->txchanname);
08738          rpt_mutex_unlock(&myrpt->lock);
08739          ast_hangup(myrpt->rxchannel);
08740          myrpt->rpt_thread = AST_PTHREADT_STOP;
08741          pthread_exit(NULL);
08742       }
08743       *tele++ = 0;
08744       myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL);
08745       if (myrpt->txchannel)
08746       {
08747          if (myrpt->txchannel->_state == AST_STATE_BUSY)
08748          {
08749             fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
08750             rpt_mutex_unlock(&myrpt->lock);
08751             ast_hangup(myrpt->txchannel);
08752             ast_hangup(myrpt->rxchannel);
08753             myrpt->rpt_thread = AST_PTHREADT_STOP;
08754             pthread_exit(NULL);
08755          }        
08756          ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
08757          ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
08758          myrpt->txchannel->whentohangup = 0;
08759          myrpt->txchannel->appl = "Apprpt";
08760          myrpt->txchannel->data = "(Repeater Tx)";
08761          if (option_verbose > 2)
08762             ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
08763                tmpstr,tele,myrpt->txchannel->name);
08764          ast_call(myrpt->txchannel,tele,999);
08765          if (myrpt->rxchannel->_state != AST_STATE_UP)
08766          {
08767             rpt_mutex_unlock(&myrpt->lock);
08768             ast_hangup(myrpt->rxchannel);
08769             ast_hangup(myrpt->txchannel);
08770             myrpt->rpt_thread = AST_PTHREADT_STOP;
08771             pthread_exit(NULL);
08772          }
08773       }
08774       else
08775       {
08776          fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
08777          rpt_mutex_unlock(&myrpt->lock);
08778          ast_hangup(myrpt->rxchannel);
08779          myrpt->rpt_thread = AST_PTHREADT_STOP;
08780          pthread_exit(NULL);
08781       }
08782    }
08783    else
08784    {
08785       myrpt->txchannel = myrpt->rxchannel;
08786    }
08787    ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
08788    ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
08789    /* allocate a pseudo-channel thru asterisk */
08790    myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
08791    if (!myrpt->pchannel)
08792    {
08793       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
08794       rpt_mutex_unlock(&myrpt->lock);
08795       if (myrpt->txchannel != myrpt->rxchannel) 
08796          ast_hangup(myrpt->txchannel);
08797       ast_hangup(myrpt->rxchannel);
08798       myrpt->rpt_thread = AST_PTHREADT_STOP;
08799       pthread_exit(NULL);
08800    }
08801    /* allocate a pseudo-channel thru asterisk */
08802    myrpt->monchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
08803    if (!myrpt->monchannel)
08804    {
08805       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
08806       rpt_mutex_unlock(&myrpt->lock);
08807       if (myrpt->txchannel != myrpt->rxchannel) 
08808          ast_hangup(myrpt->txchannel);
08809       ast_hangup(myrpt->rxchannel);
08810       myrpt->rpt_thread = AST_PTHREADT_STOP;
08811       pthread_exit(NULL);
08812    }
08813    ast_set_read_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
08814    ast_set_write_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
08815    /* make a conference for the tx */
08816    ci.chan = 0;
08817    ci.confno = -1; /* make a new conf */
08818    ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER;
08819    /* first put the channel on the conference in proper mode */
08820    if (ioctl(myrpt->txchannel->fds[0],ZT_SETCONF,&ci) == -1)
08821    {
08822       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
08823       rpt_mutex_unlock(&myrpt->lock);
08824       ast_hangup(myrpt->pchannel);
08825       ast_hangup(myrpt->monchannel);
08826       if (myrpt->txchannel != myrpt->rxchannel) 
08827          ast_hangup(myrpt->txchannel);
08828       ast_hangup(myrpt->rxchannel);
08829       myrpt->rpt_thread = AST_PTHREADT_STOP;
08830       pthread_exit(NULL);
08831    }
08832    /* save tx conference number */
08833    myrpt->txconf = ci.confno;
08834    /* make a conference for the pseudo */
08835    ci.chan = 0;
08836    ci.confno = -1; /* make a new conf */
08837    ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON :
08838       (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER);
08839    /* first put the channel on the conference in announce mode */
08840    if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
08841    {
08842       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
08843       rpt_mutex_unlock(&myrpt->lock);
08844       ast_hangup(myrpt->pchannel);
08845       ast_hangup(myrpt->monchannel);
08846       if (myrpt->txchannel != myrpt->rxchannel) 
08847          ast_hangup(myrpt->txchannel);
08848       ast_hangup(myrpt->rxchannel);
08849       myrpt->rpt_thread = AST_PTHREADT_STOP;
08850       pthread_exit(NULL);
08851    }
08852    /* save pseudo channel conference number */
08853    myrpt->conf = ci.confno;
08854    /* make a conference for the pseudo */
08855    ci.chan = 0;
08856    if (strstr(myrpt->txchannel->name,"pseudo") == NULL)
08857    {
08858       /* get tx channel's port number */
08859       if (ioctl(myrpt->txchannel->fds[0],ZT_CHANNO,&ci.confno) == -1)
08860       {
08861          ast_log(LOG_WARNING, "Unable to set tx channel's chan number\n");
08862          rpt_mutex_unlock(&myrpt->lock);
08863          ast_hangup(myrpt->pchannel);
08864          ast_hangup(myrpt->monchannel);
08865          if (myrpt->txchannel != myrpt->rxchannel) 
08866             ast_hangup(myrpt->txchannel);
08867          ast_hangup(myrpt->rxchannel);
08868          myrpt->rpt_thread = AST_PTHREADT_STOP;
08869          pthread_exit(NULL);
08870       }
08871       ci.confmode = ZT_CONF_MONITORTX;
08872    }
08873    else
08874    {
08875       ci.confno = myrpt->txconf;
08876       ci.confmode = ZT_CONF_CONFANNMON;
08877    }
08878    /* first put the channel on the conference in announce mode */
08879    if (ioctl(myrpt->monchannel->fds[0],ZT_SETCONF,&ci) == -1)
08880    {
08881       ast_log(LOG_WARNING, "Unable to set conference mode for monitor\n");
08882       rpt_mutex_unlock(&myrpt->lock);
08883       ast_hangup(myrpt->pchannel);
08884       ast_hangup(myrpt->monchannel);
08885       if (myrpt->txchannel != myrpt->rxchannel) 
08886          ast_hangup(myrpt->txchannel);
08887       ast_hangup(myrpt->rxchannel);
08888       myrpt->rpt_thread = AST_PTHREADT_STOP;
08889       pthread_exit(NULL);
08890    }
08891    /* allocate a pseudo-channel thru asterisk */
08892    myrpt->txpchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
08893    if (!myrpt->txpchannel)
08894    {
08895       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
08896       rpt_mutex_unlock(&myrpt->lock);
08897       ast_hangup(myrpt->pchannel);
08898       ast_hangup(myrpt->monchannel);
08899       if (myrpt->txchannel != myrpt->rxchannel) 
08900          ast_hangup(myrpt->txchannel);
08901       ast_hangup(myrpt->rxchannel);
08902       myrpt->rpt_thread = AST_PTHREADT_STOP;
08903       pthread_exit(NULL);
08904    }
08905    /* make a conference for the tx */
08906    ci.chan = 0;
08907    ci.confno = myrpt->txconf;
08908    ci.confmode = ZT_CONF_CONF | ZT_CONF_TALKER ;
08909    /* first put the channel on the conference in proper mode */
08910    if (ioctl(myrpt->txpchannel->fds[0],ZT_SETCONF,&ci) == -1)
08911    {
08912       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
08913       rpt_mutex_unlock(&myrpt->lock);
08914       ast_hangup(myrpt->txpchannel);
08915       ast_hangup(myrpt->monchannel);
08916       if (myrpt->txchannel != myrpt->rxchannel) 
08917          ast_hangup(myrpt->txchannel);
08918       ast_hangup(myrpt->rxchannel);
08919       myrpt->rpt_thread = AST_PTHREADT_STOP;
08920       pthread_exit(NULL);
08921    }
08922    /* Now, the idea here is to copy from the physical rx channel buffer
08923       into the pseudo tx buffer, and from the pseudo rx buffer into the 
08924       tx channel buffer */
08925    myrpt->links.next = &myrpt->links;
08926    myrpt->links.prev = &myrpt->links;
08927    myrpt->tailtimer = 0;
08928    myrpt->totimer = 0;
08929    myrpt->tmsgtimer = myrpt->p.tailmessagetime;
08930    myrpt->idtimer = myrpt->p.politeid;
08931    myrpt->mustid = myrpt->tailid = 0;
08932    myrpt->callmode = 0;
08933    myrpt->tounkeyed = 0;
08934    myrpt->tonotify = 0;
08935    myrpt->retxtimer = 0;
08936    myrpt->rerxtimer = 0;
08937    myrpt->skedtimer = 0;
08938    myrpt->tailevent = 0;
08939    lasttx = 0;
08940    myrpt->keyed = 0;
08941    idtalkover = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "idtalkover");
08942    myrpt->dtmfidx = -1;
08943    myrpt->dtmfbuf[0] = 0;
08944    myrpt->rem_dtmfidx = -1;
08945    myrpt->rem_dtmfbuf[0] = 0;
08946    myrpt->dtmf_time = 0;
08947    myrpt->rem_dtmf_time = 0;
08948    myrpt->disgorgetime = 0;
08949    myrpt->lastnodewhichkeyedusup[0] = '\0';
08950    myrpt->dailytxtime = 0;
08951    myrpt->totaltxtime = 0;
08952    myrpt->dailykeyups = 0;
08953    myrpt->totalkeyups = 0;
08954    myrpt->dailykerchunks = 0;
08955    myrpt->totalkerchunks = 0;
08956    myrpt->dailyexecdcommands = 0;
08957    myrpt->totalexecdcommands = 0;
08958    myrpt->timeouts = 0;
08959    myrpt->exten[0] = '\0';
08960    myrpt->lastdtmfcommand[0] = '\0';
08961    if (myrpt->p.startupmacro)
08962    {
08963       snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro);
08964    }
08965    rpt_mutex_unlock(&myrpt->lock);
08966    val = 1;
08967    ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0);
08968    val = 1;
08969    ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
08970    if (myrpt->p.archivedir) donodelog(myrpt,"STARTUP");
08971    dtmfed = 0;
08972    while (ms >= 0)
08973    {
08974       struct ast_frame *f,*f1,*f2;
08975       struct ast_channel *cs[300],*cs1[300];
08976       int totx=0,elap=0,n,x,toexit=0;
08977 
08978       /* DEBUG Dump */
08979       if((myrpt->disgorgetime) && (time(NULL) >= myrpt->disgorgetime)){
08980          struct rpt_link *zl;
08981          struct rpt_tele *zt;
08982 
08983          myrpt->disgorgetime = 0;
08984          ast_log(LOG_NOTICE,"********** Variable Dump Start (app_rpt) **********\n");
08985          ast_log(LOG_NOTICE,"totx = %d\n",totx);
08986          ast_log(LOG_NOTICE,"remrx = %d\n",remrx);
08987          ast_log(LOG_NOTICE,"lasttx = %d\n",lasttx);
08988          ast_log(LOG_NOTICE,"elap = %d\n",elap);
08989          ast_log(LOG_NOTICE,"toexit = %d\n",toexit);
08990 
08991          ast_log(LOG_NOTICE,"myrpt->keyed = %d\n",myrpt->keyed);
08992          ast_log(LOG_NOTICE,"myrpt->localtx = %d\n",myrpt->localtx);
08993          ast_log(LOG_NOTICE,"myrpt->callmode = %d\n",myrpt->callmode);
08994          ast_log(LOG_NOTICE,"myrpt->mustid = %d\n",myrpt->mustid);
08995          ast_log(LOG_NOTICE,"myrpt->tounkeyed = %d\n",myrpt->tounkeyed);
08996          ast_log(LOG_NOTICE,"myrpt->tonotify = %d\n",myrpt->tonotify);
08997          ast_log(LOG_NOTICE,"myrpt->retxtimer = %ld\n",myrpt->retxtimer);
08998          ast_log(LOG_NOTICE,"myrpt->totimer = %d\n",myrpt->totimer);
08999          ast_log(LOG_NOTICE,"myrpt->tailtimer = %d\n",myrpt->tailtimer);
09000          ast_log(LOG_NOTICE,"myrpt->tailevent = %d\n",myrpt->tailevent);
09001 
09002          zl = myrpt->links.next;
09003                   while(zl != &myrpt->links){
09004             ast_log(LOG_NOTICE,"*** Link Name: %s ***\n",zl->name);
09005             ast_log(LOG_NOTICE,"        link->lasttx %d\n",zl->lasttx);
09006             ast_log(LOG_NOTICE,"        link->lastrx %d\n",zl->lastrx);
09007             ast_log(LOG_NOTICE,"        link->connected %d\n",zl->connected);
09008             ast_log(LOG_NOTICE,"        link->hasconnected %d\n",zl->hasconnected);
09009             ast_log(LOG_NOTICE,"        link->outbound %d\n",zl->outbound);
09010             ast_log(LOG_NOTICE,"        link->disced %d\n",zl->disced);
09011             ast_log(LOG_NOTICE,"        link->killme %d\n",zl->killme);
09012             ast_log(LOG_NOTICE,"        link->disctime %ld\n",zl->disctime);
09013             ast_log(LOG_NOTICE,"        link->retrytimer %ld\n",zl->retrytimer);
09014             ast_log(LOG_NOTICE,"        link->retries = %d\n",zl->retries);
09015             ast_log(LOG_NOTICE,"        link->reconnects = %d\n",zl->reconnects);
09016                            zl = zl->next;
09017                   }
09018                                                                                                                                
09019          zt = myrpt->tele.next;
09020          if(zt != &myrpt->tele)
09021             ast_log(LOG_NOTICE,"*** Telemetry Queue ***\n");
09022                   while(zt != &myrpt->tele){
09023             ast_log(LOG_NOTICE,"        Telemetry mode: %d\n",zt->mode);
09024                            zt = zt->next;
09025                   }
09026          ast_log(LOG_NOTICE,"******* Variable Dump End (app_rpt) *******\n");
09027 
09028       }  
09029 
09030 
09031       if (myrpt->reload)
09032       {
09033          struct rpt_tele *telem;
09034 
09035          rpt_mutex_lock(&myrpt->lock);
09036          telem = myrpt->tele.next;
09037          while(telem != &myrpt->tele)
09038          {
09039             ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV);
09040             telem = telem->next;
09041          }
09042          myrpt->reload = 0;
09043          rpt_mutex_unlock(&myrpt->lock);
09044          usleep(10000);
09045          /* find our index, and load the vars */
09046          for(i = 0; i < nrpts; i++)
09047          {
09048             if (&rpt_vars[i] == myrpt)
09049             {
09050                load_rpt_vars(i,0);
09051                break;
09052             }
09053          }
09054       }
09055 
09056       rpt_mutex_lock(&myrpt->lock);
09057       if (ast_check_hangup(myrpt->rxchannel)) break;
09058       if (ast_check_hangup(myrpt->txchannel)) break;
09059       if (ast_check_hangup(myrpt->pchannel)) break;
09060       if (ast_check_hangup(myrpt->monchannel)) break;
09061       if (ast_check_hangup(myrpt->txpchannel)) break;
09062 
09063       /* Set local tx with keyed */
09064       myrpt->localtx = myrpt->keyed;
09065       /* If someone's connected, and they're transmitting from their end to us, set remrx true */
09066       l = myrpt->links.next;
09067       remrx = 0;
09068       while(l != &myrpt->links)
09069       {
09070          if (l->lastrx){
09071             remrx = 1;
09072             if(l->name[0] != '0') /* Ignore '0' nodes */
09073                strcpy(myrpt->lastnodewhichkeyedusup, l->name); /* Note the node which is doing the key up */
09074          }
09075          l = l->next;
09076       }
09077       /* Create a "must_id" flag for the cleanup ID */      
09078       if(myrpt->p.idtime) /* ID time must be non-zero */
09079          myrpt->mustid |= (myrpt->idtimer) && (myrpt->keyed || remrx) ;
09080       /* Build a fresh totx from myrpt->keyed and autopatch activated */
09081       totx = myrpt->callmode;
09082       /* If full duplex, add local tx to totx */
09083       if (myrpt->p.duplex > 1) 
09084       {
09085          totx = totx || myrpt->localtx;
09086       }
09087       /* Traverse the telemetry list to see what's queued */
09088       identqueued = 0;
09089       othertelemqueued = 0;
09090       tailmessagequeued = 0;
09091       ctqueued = 0;
09092       telem = myrpt->tele.next;
09093       while(telem != &myrpt->tele)
09094       {
09095          if((telem->mode == ID) || (telem->mode == IDTALKOVER)){
09096             identqueued = 1; /* Identification telemetry */
09097          }
09098          else if(telem->mode == TAILMSG)
09099          {
09100             tailmessagequeued = 1; /* Tail message telemetry */
09101          }
09102          else
09103          {
09104             if ((telem->mode != UNKEY) && (telem->mode != LINKUNKEY))
09105                othertelemqueued = 1;  /* Other telemetry */
09106             else
09107                ctqueued = 1; /* Courtesy tone telemetry */
09108          }
09109          telem = telem->next;
09110       }
09111    
09112       /* Add in any "other" telemetry, unless specified otherwise */
09113       if (!myrpt->p.notelemtx) totx = totx || othertelemqueued;
09114       /* Update external (to links) transmitter PTT state with everything but ID, CT, and tailmessage telemetry */
09115       myrpt->exttx = totx;
09116       totx = totx || myrpt->dtmf_local_timer;
09117       /* If half or 3/4 duplex, add localtx to external link tx */
09118       if (myrpt->p.duplex < 2) myrpt->exttx = myrpt->exttx || myrpt->localtx;
09119       /* Add in ID telemetry to local transmitter */
09120       totx = totx || remrx;
09121       /* If 3/4 or full duplex, add in ident and CT telemetry */
09122       if (myrpt->p.duplex > 0)
09123          totx = totx || identqueued || ctqueued;
09124       /* If full duplex, add local dtmf stuff active */
09125       if (myrpt->p.duplex > 1) 
09126       {
09127          totx = totx || (myrpt->dtmfidx > -1) ||
09128             myrpt->cmdnode[0];
09129       }
09130       /* Reset time out timer variables if there is no activity */
09131       if (!totx) 
09132       {
09133          myrpt->totimer = myrpt->p.totime;
09134          myrpt->tounkeyed = 0;
09135          myrpt->tonotify = 0;
09136       }
09137       else{
09138          myrpt->tailtimer = myrpt->p.s[myrpt->p.sysstate_cur].alternatetail ?
09139             myrpt->p.althangtime : /* Initialize tail timer */
09140             myrpt->p.hangtime;
09141       }
09142       /* Disable the local transmitter if we are timed out */
09143       totx = totx && myrpt->totimer;
09144       /* if timed-out and not said already, say it */
09145       if ((!myrpt->totimer) && (!myrpt->tonotify))
09146       {
09147          myrpt->tonotify = 1;
09148          myrpt->timeouts++;
09149          rpt_mutex_unlock(&myrpt->lock);
09150          rpt_telemetry(myrpt,TIMEOUT,NULL);
09151          rpt_mutex_lock(&myrpt->lock);
09152       }
09153 
09154       /* If unkey and re-key, reset time out timer */
09155       if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!myrpt->keyed))
09156       {
09157          myrpt->tounkeyed = 1;
09158       }
09159       if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->keyed)
09160       {
09161          myrpt->totimer = myrpt->p.totime;
09162          myrpt->tounkeyed = 0;
09163          myrpt->tonotify = 0;
09164          rpt_mutex_unlock(&myrpt->lock);
09165          continue;
09166       }
09167       /* if timed-out and in circuit busy after call */
09168       if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4))
09169       {
09170          myrpt->callmode = 0;
09171       }
09172       /* get rid of tail if timed out */
09173       if (!myrpt->totimer) myrpt->tailtimer = 0;
09174       /* if not timed-out, add in tail */
09175       if (myrpt->totimer) totx = totx || myrpt->tailtimer;
09176       /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */
09177       /* If tail message, kill the message if someone keys up over it */ 
09178       if ((myrpt->keyed || remrx) && ((identqueued && idtalkover) || (tailmessagequeued))) {
09179          int hasid = 0,hastalkover = 0;
09180 
09181          telem = myrpt->tele.next;
09182          while(telem != &myrpt->tele){
09183             if(telem->mode == ID){
09184                if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
09185                hasid = 1;
09186             }
09187             if(telem->mode == TAILMSG){
09188                                         if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
09189                                 }
09190             if (telem->mode == IDTALKOVER) hastalkover = 1;
09191             telem = telem->next;
09192          }
09193          rpt_mutex_unlock(&myrpt->lock);
09194          if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */
09195          rpt_mutex_lock(&myrpt->lock);
09196       }
09197       /* Try to be polite */
09198       /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/
09199       /* If within 30 seconds of the time to ID, try do it in the tail */
09200       /* else if at ID time limit, do it right over the top of them */
09201       /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */
09202       if(myrpt->mustid && (!myrpt->idtimer))
09203          queue_id(myrpt);
09204 
09205       if ((myrpt->p.idtime && totx && (!myrpt->exttx) &&
09206           (myrpt->idtimer <= myrpt->p.politeid) && myrpt->tailtimer)) /* ID time must be non-zero */ 
09207          {
09208             myrpt->tailid = 1;
09209          }
09210 
09211       /* If tail timer expires, then check for tail messages */
09212 
09213       if(myrpt->tailevent){
09214          myrpt->tailevent = 0;
09215          if(myrpt->tailid){
09216             totx = 1;
09217             queue_id(myrpt);
09218          }
09219          else if ((myrpt->p.tailmessages[0]) &&
09220             (myrpt->p.tailmessagetime) && (myrpt->tmsgtimer == 0)){
09221                totx = 1;
09222                myrpt->tmsgtimer = myrpt->p.tailmessagetime; 
09223                rpt_mutex_unlock(&myrpt->lock);
09224                rpt_telemetry(myrpt, TAILMSG, NULL);
09225                rpt_mutex_lock(&myrpt->lock);
09226          }  
09227       }
09228 
09229       /* Main TX control */
09230 
09231       /* let telemetry transmit anyway (regardless of timeout) */
09232       if (myrpt->p.duplex > 0) totx = totx || (myrpt->tele.next != &myrpt->tele);
09233       if (totx && (!lasttx))
09234       {
09235          char mydate[100],myfname[100];
09236          time_t myt;
09237 
09238          if (myrpt->monstream) ast_closestream(myrpt->monstream);
09239          if (myrpt->p.archivedir)
09240          {
09241             long blocksleft;
09242 
09243             time(&myt);
09244             strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S",
09245                localtime(&myt));
09246             sprintf(myfname,"%s/%s/%s",myrpt->p.archivedir,
09247                myrpt->name,mydate);
09248             myrpt->monstream = ast_writefile(myfname,"wav49",
09249                "app_rpt Air Archive",O_CREAT | O_APPEND,0,0600);
09250             if (myrpt->p.monminblocks)
09251             {
09252                blocksleft = diskavail(myrpt);
09253                if (blocksleft >= myrpt->p.monminblocks)
09254                   donodelog(myrpt,"TXKEY,MAIN");
09255             } else donodelog(myrpt,"TXKEY,MAIN");
09256          }
09257          lasttx = 1;
09258          myrpt->dailykeyups++;
09259          myrpt->totalkeyups++;
09260          rpt_mutex_unlock(&myrpt->lock);
09261          ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
09262          rpt_mutex_lock(&myrpt->lock);
09263       }
09264       totx = totx && !myrpt->p.s[myrpt->p.sysstate_cur].txdisable;
09265       if ((!totx) && lasttx)
09266       {
09267          if (myrpt->monstream) ast_closestream(myrpt->monstream);
09268          myrpt->monstream = NULL;
09269 
09270          lasttx = 0;
09271          rpt_mutex_unlock(&myrpt->lock);
09272          ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
09273          rpt_mutex_lock(&myrpt->lock);
09274          donodelog(myrpt,"TXUNKEY,MAIN");
09275       }
09276       time(&t);
09277       /* if DTMF timeout */
09278       if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((myrpt->dtmf_time + DTMF_TIMEOUT) < t))
09279       {
09280          myrpt->dtmfidx = -1;
09281          myrpt->dtmfbuf[0] = 0;
09282       }        
09283       /* if remote DTMF timeout */
09284       if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t))
09285       {
09286          myrpt->rem_dtmfidx = -1;
09287          myrpt->rem_dtmfbuf[0] = 0;
09288       }  
09289 
09290       /* Reconnect */
09291    
09292       l = myrpt->links.next;
09293       while(l != &myrpt->links)
09294       {
09295          if (l->killme)
09296          {
09297             /* remove from queue */
09298             remque((struct qelem *) l);
09299             if (!strcmp(myrpt->cmdnode,l->name))
09300                myrpt->cmdnode[0] = 0;
09301             rpt_mutex_unlock(&myrpt->lock);
09302             /* hang-up on call to device */
09303             if (l->chan) ast_hangup(l->chan);
09304             ast_hangup(l->pchan);
09305             free(l);
09306             rpt_mutex_lock(&myrpt->lock);
09307             /* re-start link traversal */
09308             l = myrpt->links.next;
09309             continue;
09310          }
09311          l = l->next;
09312       }
09313       n = 0;
09314       cs[n++] = myrpt->rxchannel;
09315       cs[n++] = myrpt->pchannel;
09316       cs[n++] = myrpt->monchannel;
09317       cs[n++] = myrpt->txpchannel;
09318       if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel;
09319       l = myrpt->links.next;
09320       while(l != &myrpt->links)
09321       {
09322          if ((!l->killme) && (!l->disctime) && l->chan)
09323          {
09324             cs[n++] = l->chan;
09325             cs[n++] = l->pchan;
09326          }
09327          l = l->next;
09328       }
09329       rpt_mutex_unlock(&myrpt->lock);
09330       ms = MSWAIT;
09331       for(x = 0; x < n; x++)
09332       {
09333          int s = -(-x - myrpt->scram - 1) % n;
09334          cs1[x] = cs[s];
09335       }
09336       myrpt->scram++;
09337       who = ast_waitfor_n(cs1,n,&ms);
09338       if (who == NULL) ms = 0;
09339       elap = MSWAIT - ms;
09340       rpt_mutex_lock(&myrpt->lock);
09341       l = myrpt->links.next;
09342       while(l != &myrpt->links)
09343       {
09344          if (l->linklisttimer)
09345          {
09346             l->linklisttimer -= elap;
09347             if (l->linklisttimer < 0) l->linklisttimer = 0;
09348          }
09349          if ((!l->linklisttimer) && (l->name[0] != '0') && (!l->isremote))
09350          {
09351             struct   ast_frame lf;
09352 
09353             memset(&lf,0,sizeof(lf));
09354             lf.frametype = AST_FRAME_TEXT;
09355             lf.subclass = 0;
09356             lf.offset = 0;
09357             lf.mallocd = 0;
09358             lf.samples = 0;
09359             l->linklisttimer = LINKLISTTIME;
09360             strcpy(lstr,"L ");
09361             __mklinklist(myrpt,l,lstr + 2);
09362             if (l->chan)
09363             {
09364                lf.datalen = strlen(lstr) + 1;
09365                lf.data = lstr;
09366                ast_write(l->chan,&lf);
09367                if (debug > 6) ast_log(LOG_NOTICE,
09368                   "@@@@ node %s sent node string %s to node %s\n",
09369                      myrpt->name,lstr,l->name);
09370             }
09371          }
09372 #ifndef  OLDKEY
09373          if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME)
09374          {
09375             l->retxtimer = 0;
09376             if (l->chan && l->phonemode == 0) 
09377             {
09378                if (l->lasttx)
09379                   ast_indicate(l->chan,AST_CONTROL_RADIO_KEY);
09380                else
09381                   ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY);
09382             }
09383          }
09384          if ((l->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 5))
09385          {
09386             if (debug == 7) printf("@@@@ rx un-key\n");
09387             l->lastrx = 0;
09388             l->rerxtimer = 0;
09389             if(myrpt->p.duplex) 
09390                rpt_telemetry(myrpt,LINKUNKEY,l);
09391             if (myrpt->p.archivedir)
09392             {
09393                char str[100];
09394 
09395                l->lastrx1 = 0;
09396                sprintf(str,"RXUNKEY(T),%s",l->name);
09397                donodelog(myrpt,str);
09398             }
09399          }
09400 #endif
09401          if (l->disctime) /* Disconnect timer active on a channel ? */
09402          {
09403             l->disctime -= elap;
09404             if (l->disctime <= 0) /* Disconnect timer expired on inbound channel ? */
09405                l->disctime = 0; /* Yep */
09406          }
09407 
09408          if (l->retrytimer)
09409          {
09410             l->retrytimer -= elap;
09411             if (l->retrytimer < 0) l->retrytimer = 0;
09412          }
09413 
09414          /* Tally connect time */
09415          l->connecttime += elap;
09416 
09417          /* ignore non-timing channels */
09418          if (l->elaptime < 0)
09419          {
09420             l = l->next;
09421             continue;
09422          }
09423          l->elaptime += elap;
09424          /* if connection has taken too long */
09425          if ((l->elaptime > MAXCONNECTTIME) && 
09426             ((!l->chan) || (l->chan->_state != AST_STATE_UP)))
09427          {
09428             l->elaptime = 0;
09429             rpt_mutex_unlock(&myrpt->lock);
09430             if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
09431             rpt_mutex_lock(&myrpt->lock);
09432             break;
09433          }
09434          if ((!l->chan) && (!l->retrytimer) && l->outbound && 
09435             (l->retries++ < l->max_retries) && (l->hasconnected))
09436          {
09437             if (l->chan) ast_hangup(l->chan);
09438             l->chan = 0;
09439             rpt_mutex_unlock(&myrpt->lock);
09440             if ((l->name[0] != '0') && (!l->isremote))
09441             {
09442                if (attempt_reconnect(myrpt,l) == -1)
09443                {
09444                   l->retrytimer = RETRY_TIMER_MS;
09445                } 
09446             }
09447             else 
09448             {
09449                l->retrytimer = l->max_retries + 1;
09450             }
09451 
09452             rpt_mutex_lock(&myrpt->lock);
09453             break;
09454          }
09455          if ((!l->chan) && (!l->retrytimer) && l->outbound &&
09456             (l->retries >= l->max_retries))
09457          {
09458             /* remove from queue */
09459             remque((struct qelem *) l);
09460             if (!strcmp(myrpt->cmdnode,l->name))
09461                myrpt->cmdnode[0] = 0;
09462             rpt_mutex_unlock(&myrpt->lock);
09463             if (l->name[0] != '0')
09464             {
09465                if (!l->hasconnected)
09466                   rpt_telemetry(myrpt,CONNFAIL,l);
09467                else rpt_telemetry(myrpt,REMDISC,l);
09468             }
09469             if (myrpt->p.archivedir)
09470             {
09471                char str[100];
09472 
09473                if (!l->hasconnected)
09474                   sprintf(str,"LINKFAIL,%s",l->name);
09475                else
09476                   sprintf(str,"LINKDISC,%s",l->name);
09477                donodelog(myrpt,str);
09478             }
09479             /* hang-up on call to device */
09480             ast_hangup(l->pchan);
09481             free(l);
09482                                 rpt_mutex_lock(&myrpt->lock);
09483             break;
09484          }
09485                         if ((!l->chan) && (!l->disctime) && (!l->outbound))
09486                         {
09487                                 /* remove from queue */
09488                                 remque((struct qelem *) l);
09489                                 if (!strcmp(myrpt->cmdnode,l->name))
09490                                         myrpt->cmdnode[0] = 0;
09491                                 rpt_mutex_unlock(&myrpt->lock);
09492             if (l->name[0] != '0') 
09493             {
09494                                    rpt_telemetry(myrpt,REMDISC,l);
09495             }
09496             if (myrpt->p.archivedir)
09497             {
09498                char str[100];
09499 
09500                sprintf(str,"LINKDISC,%s",l->name);
09501                donodelog(myrpt,str);
09502             }
09503                                 /* hang-up on call to device */
09504                                 ast_hangup(l->pchan);
09505                                 free(l);
09506                                 rpt_mutex_lock(&myrpt->lock);
09507                                 break;
09508                         }
09509          l = l->next;
09510       }
09511       if(totx){
09512          myrpt->dailytxtime += elap;
09513          myrpt->totaltxtime += elap;
09514       }
09515       i = myrpt->tailtimer;
09516       if (myrpt->tailtimer) myrpt->tailtimer -= elap;
09517       if (myrpt->tailtimer < 0) myrpt->tailtimer = 0;
09518       if((i) && (myrpt->tailtimer == 0))
09519          myrpt->tailevent = 1;
09520       if ((!myrpt->p.s[myrpt->p.sysstate_cur].totdisable) && myrpt->totimer) myrpt->totimer -= elap;
09521       if (myrpt->totimer < 0) myrpt->totimer = 0;
09522       if (myrpt->idtimer) myrpt->idtimer -= elap;
09523       if (myrpt->idtimer < 0) myrpt->idtimer = 0;
09524       if (myrpt->tmsgtimer) myrpt->tmsgtimer -= elap;
09525       if (myrpt->tmsgtimer < 0) myrpt->tmsgtimer = 0;
09526       /* do macro timers */
09527       if (myrpt->macrotimer) myrpt->macrotimer -= elap;
09528       if (myrpt->macrotimer < 0) myrpt->macrotimer = 0;
09529       /* do local dtmf timer */
09530       if (myrpt->dtmf_local_timer)
09531       {
09532          if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap;
09533          if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1;
09534       }
09535       do_dtmf_local(myrpt,0);
09536       /* Execute scheduler appx. every 2 tenths of a second */
09537       if (myrpt->skedtimer <= 0){
09538          myrpt->skedtimer = 200;
09539          do_scheduler(myrpt);
09540       }
09541       else
09542          myrpt->skedtimer -=elap;
09543       if (!ms) 
09544       {
09545          rpt_mutex_unlock(&myrpt->lock);
09546          continue;
09547       }
09548       c = myrpt->macrobuf[0];
09549       time(&t);
09550       if (c && (!myrpt->macrotimer) && 
09551          starttime && (t > (starttime + START_DELAY)))
09552       {
09553          myrpt->macrotimer = MACROTIME;
09554          memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1);
09555          if ((c == 'p') || (c == 'P'))
09556             myrpt->macrotimer = MACROPTIME;
09557          rpt_mutex_unlock(&myrpt->lock);
09558          if (myrpt->p.archivedir)
09559          {
09560             char str[100];
09561 
09562             sprintf(str,"DTMF(M),MAIN,%c",c);
09563             donodelog(myrpt,str);
09564          }
09565          local_dtmf_helper(myrpt,c);
09566       } else rpt_mutex_unlock(&myrpt->lock);
09567       if (who == myrpt->rxchannel) /* if it was a read from rx */
09568       {
09569          int ismuted;
09570 
09571          f = ast_read(myrpt->rxchannel);
09572          if (!f)
09573          {
09574             if (debug) printf("@@@@ rpt:Hung Up\n");
09575             break;
09576          }
09577          if (f->frametype == AST_FRAME_VOICE)
09578          {
09579 #ifdef   _MDC_DECODE_H_
09580             unsigned char ubuf[2560];
09581             short *sp;
09582             int n;
09583 #endif
09584 
09585             if ((!myrpt->localtx) && (!myrpt->p.linktolink)) {
09586                memset(f->data,0,f->datalen);
09587             }
09588 
09589 #ifdef   _MDC_DECODE_H_
09590             sp = (short *) f->data;
09591             /* convert block to unsigned char */
09592             for(n = 0; n < f->datalen / 2; n++)
09593             {
09594                ubuf[n] = (*sp++ >> 8) + 128;
09595             }
09596             n = mdc_decoder_process_samples(myrpt->mdc,ubuf,f->datalen / 2);
09597             if (n == 1)
09598             {
09599                   unsigned char op,arg;
09600                   unsigned short unitID;
09601 
09602                   mdc_decoder_get_packet(myrpt->mdc,&op,&arg,&unitID);
09603                   if (debug > 2)
09604                   {
09605                      ast_log(LOG_NOTICE,"Got (single-length) packet:\n");
09606                      ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n",
09607                         op & 255,arg & 255,unitID);
09608                   }
09609                   if ((op == 1) && (arg == 0))
09610                   {
09611                      myrpt->lastunit = unitID;
09612                   }
09613             }
09614             if ((debug > 2) && (i == 2))
09615             {
09616                unsigned char op,arg,ex1,ex2,ex3,ex4;
09617                unsigned short unitID;
09618 
09619                mdc_decoder_get_double_packet(myrpt->mdc,&op,&arg,&unitID,
09620                   &ex1,&ex2,&ex3,&ex4);
09621                ast_log(LOG_NOTICE,"Got (double-length) packet:\n");
09622                ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n",
09623                   op & 255,arg & 255,unitID);
09624                ast_log(LOG_NOTICE,"ex1: %02x, ex2: %02x, ex3: %02x, ex4: %02x\n",
09625                   ex1 & 255, ex2 & 255, ex3 & 255, ex4 & 255);
09626             }
09627 #endif
09628 #ifdef   __RPT_NOTCH
09629             /* apply inbound filters, if any */
09630             rpt_filter(myrpt,f->data,f->datalen / 2);
09631 #endif
09632             if (ioctl(myrpt->rxchannel->fds[0], ZT_GETCONFMUTE, &ismuted) == -1)
09633             {
09634                ismuted = 0;
09635             }
09636             if (dtmfed) ismuted = 1;
09637             dtmfed = 0;
09638             if (ismuted)
09639             {
09640                memset(f->data,0,f->datalen);
09641                if (myrpt->lastf1)
09642                   memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
09643                if (myrpt->lastf2)
09644                   memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
09645             } 
09646             if (f) f2 = ast_frdup(f);
09647             else f2 = NULL;
09648             f1 = myrpt->lastf2;
09649             myrpt->lastf2 = myrpt->lastf1;
09650             myrpt->lastf1 = f2;
09651             if (ismuted)
09652             {
09653                if (myrpt->lastf1)
09654                   memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
09655                if (myrpt->lastf2)
09656                   memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
09657             }
09658             if (f1)
09659             {
09660                ast_write(myrpt->pchannel,f1);
09661                ast_frfree(f1);
09662             }
09663          }
09664 #ifndef  OLD_ASTERISK
09665          else if (f->frametype == AST_FRAME_DTMF_BEGIN)
09666          {
09667             if (myrpt->lastf1)
09668                memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
09669             if (myrpt->lastf2)
09670                memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
09671             dtmfed = 1;
09672          }
09673 #endif
09674          else if (f->frametype == AST_FRAME_DTMF)
09675          {
09676             c = (char) f->subclass; /* get DTMF char */
09677             ast_frfree(f);
09678             if (myrpt->lastf1)
09679                memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
09680             if (myrpt->lastf2)
09681                memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
09682             dtmfed = 1;
09683             if (!myrpt->keyed) continue;
09684             c = func_xlat(myrpt,c,&myrpt->p.inxlat);
09685             if (c) local_dtmf_helper(myrpt,c);
09686             continue;
09687          }                 
09688          else if (f->frametype == AST_FRAME_CONTROL)
09689          {
09690             if (f->subclass == AST_CONTROL_HANGUP)
09691             {
09692                if (debug) printf("@@@@ rpt:Hung Up\n");
09693                ast_frfree(f);
09694                break;
09695             }
09696             /* if RX key */
09697             if (f->subclass == AST_CONTROL_RADIO_KEY)
09698             {
09699                if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink)) 
09700                {
09701                   if (debug == 7) printf("@@@@ rx key\n");
09702                   myrpt->keyed = 1;
09703                }
09704                if (myrpt->p.archivedir)
09705                {
09706                   donodelog(myrpt,"RXKEY,MAIN");
09707                }
09708             }
09709             /* if RX un-key */
09710             if (f->subclass == AST_CONTROL_RADIO_UNKEY)
09711             {
09712                if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink))
09713                {
09714                   if (debug == 7) printf("@@@@ rx un-key\n");
09715                   if(myrpt->p.duplex && myrpt->keyed) {
09716                      rpt_telemetry(myrpt,UNKEY,NULL);
09717                   }
09718                }
09719                myrpt->keyed = 0;
09720                if (myrpt->p.archivedir)
09721                {
09722                   donodelog(myrpt,"RXUNKEY,MAIN");
09723                }
09724             }
09725          }
09726          ast_frfree(f);
09727          continue;
09728       }
09729       if (who == myrpt->pchannel) /* if it was a read from pseudo */
09730       {
09731          f = ast_read(myrpt->pchannel);
09732          if (!f)
09733          {
09734             if (debug) printf("@@@@ rpt:Hung Up\n");
09735             break;
09736          }
09737          if (f->frametype == AST_FRAME_VOICE)
09738          {
09739             ast_write(myrpt->txpchannel,f);
09740          }
09741          if (f->frametype == AST_FRAME_CONTROL)
09742          {
09743             if (f->subclass == AST_CONTROL_HANGUP)
09744             {
09745                if (debug) printf("@@@@ rpt:Hung Up\n");
09746                ast_frfree(f);
09747                break;
09748             }
09749          }
09750          ast_frfree(f);
09751          continue;
09752       }
09753       if (who == myrpt->txchannel) /* if it was a read from tx */
09754       {
09755          f = ast_read(myrpt->txchannel);
09756          if (!f)
09757          {
09758             if (debug) printf("@@@@ rpt:Hung Up\n");
09759             break;
09760          }
09761          if (f->frametype == AST_FRAME_CONTROL)
09762          {
09763             if (f->subclass == AST_CONTROL_HANGUP)
09764             {
09765                if (debug) printf("@@@@ rpt:Hung Up\n");
09766                ast_frfree(f);
09767                break;
09768             }
09769          }
09770          ast_frfree(f);
09771          continue;
09772       }
09773       toexit = 0;
09774       rpt_mutex_lock(&myrpt->lock);
09775       l = myrpt->links.next;
09776       while(l != &myrpt->links)
09777       {
09778          if (l->disctime)
09779          {
09780             l = l->next;
09781             continue;
09782          }
09783          if (who == l->chan) /* if it was a read from rx */
09784          {
09785             int remnomute;
09786 
09787             remrx = 0;
09788             /* see if any other links are receiving */
09789             m = myrpt->links.next;
09790             while(m != &myrpt->links)
09791             {
09792                /* if not us, count it */
09793                if ((m != l) && (m->lastrx)) remrx = 1;
09794                m = m->next;
09795             }
09796             rpt_mutex_unlock(&myrpt->lock);
09797             remnomute = myrpt->localtx && 
09798                 (!(myrpt->cmdnode[0] || 
09799                (myrpt->dtmfidx > -1)));
09800             totx = (((l->isremote) ? (remnomute) : 
09801                myrpt->exttx) || remrx) && l->mode;
09802             if (l->phonemode == 0 && l->chan && (l->lasttx != totx))
09803             {
09804                if (totx)
09805                {
09806                   ast_indicate(l->chan,AST_CONTROL_RADIO_KEY);
09807                }
09808                else
09809                {
09810                   ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY);
09811                }
09812                if (myrpt->p.archivedir)
09813                {
09814                   char str[100];
09815 
09816                   if (totx)
09817                      sprintf(str,"TXKEY,%s",l->name);
09818                   else
09819                      sprintf(str,"TXUNKEY,%s",l->name);
09820                   donodelog(myrpt,str);
09821                }
09822             }
09823             l->lasttx = totx;
09824             f = ast_read(l->chan);
09825             if (!f)
09826             {
09827                rpt_mutex_lock(&myrpt->lock);
09828                __kickshort(myrpt);
09829                rpt_mutex_unlock(&myrpt->lock);
09830                if ((!l->disced) && (!l->outbound))
09831                {
09832                   if ((l->name[0] == '0') || l->isremote)
09833                      l->disctime = 1;
09834                   else
09835                      l->disctime = DISC_TIME;
09836                   rpt_mutex_lock(&myrpt->lock);
09837                   ast_hangup(l->chan);
09838                   l->chan = 0;
09839                   break;
09840                }
09841 
09842                if (l->retrytimer) 
09843                {
09844                   ast_hangup(l->chan);
09845                   l->chan = 0;
09846                   rpt_mutex_lock(&myrpt->lock);
09847                   break; 
09848                }
09849                if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected))
09850                {
09851                   rpt_mutex_lock(&myrpt->lock);
09852                   if (l->chan) ast_hangup(l->chan);
09853                   l->chan = 0;
09854                   l->hasconnected = 1;
09855                   l->retrytimer = RETRY_TIMER_MS;
09856                   l->elaptime = 0;
09857                   l->connecttime = 0;
09858                   l->thisconnected = 0;
09859                   break;
09860                }
09861                rpt_mutex_lock(&myrpt->lock);
09862                /* remove from queue */
09863                remque((struct qelem *) l);
09864                if (!strcmp(myrpt->cmdnode,l->name))
09865                   myrpt->cmdnode[0] = 0;
09866                __kickshort(myrpt);
09867                rpt_mutex_unlock(&myrpt->lock);
09868                if (!l->hasconnected)
09869                   rpt_telemetry(myrpt,CONNFAIL,l);
09870                else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l);
09871                if (myrpt->p.archivedir)
09872                {
09873                   char str[100];
09874 
09875                   if (!l->hasconnected)
09876                      sprintf(str,"LINKFAIL,%s",l->name);
09877                   else
09878                      sprintf(str,"LINKDISC,%s",l->name);
09879                   donodelog(myrpt,str);
09880                }
09881                if (l->lastf1) ast_frfree(l->lastf1);
09882                l->lastf1 = NULL;
09883                if (l->lastf2) ast_frfree(l->lastf2);
09884                l->lastf2 = NULL;
09885                /* hang-up on call to device */
09886                ast_hangup(l->chan);
09887                ast_hangup(l->pchan);
09888                free(l);
09889                rpt_mutex_lock(&myrpt->lock);
09890                break;
09891             }
09892             if (f->frametype == AST_FRAME_VOICE)
09893             {
09894                int ismuted;
09895 
09896                if (l->phonemode)
09897                {
09898                   if (ioctl(l->chan->fds[0], ZT_GETCONFMUTE, &ismuted) == -1)
09899                   {
09900                      ismuted = 0;
09901                   }
09902                   /* if not receiving, zero-out audio */
09903                   ismuted |= (!l->lastrx);
09904                   if (l->dtmfed && l->phonemode) ismuted = 1;
09905                   l->dtmfed = 0;
09906                   if (ismuted)
09907                   {
09908                      memset(f->data,0,f->datalen);
09909                      if (l->lastf1)
09910                         memset(l->lastf1->data,0,l->lastf1->datalen);
09911                      if (l->lastf2)
09912                         memset(l->lastf2->data,0,l->lastf2->datalen);
09913                   } 
09914                   if (f) f2 = ast_frdup(f);
09915                   else f2 = NULL;
09916                   f1 = l->lastf2;
09917                   l->lastf2 = l->lastf1;
09918                   l->lastf1 = f2;
09919                   if (ismuted)
09920                   {
09921                      if (l->lastf1)
09922                         memset(l->lastf1->data,0,l->lastf1->datalen);
09923                      if (l->lastf2)
09924                         memset(l->lastf2->data,0,l->lastf2->datalen);
09925                   }
09926                   if (f1)
09927                   {
09928                      ast_write(l->pchan,f1);
09929                      ast_frfree(f1);
09930                   }
09931                }
09932                else
09933                {
09934                   if (!l->lastrx)
09935                      memset(f->data,0,f->datalen);
09936                   ast_write(l->pchan,f);
09937                }
09938             }
09939 #ifndef  OLD_ASTERISK
09940             else if (f->frametype == AST_FRAME_DTMF_BEGIN)
09941             {
09942                if (l->lastf1)
09943                   memset(l->lastf1->data,0,l->lastf1->datalen);
09944                if (l->lastf2)
09945                   memset(l->lastf2->data,0,l->lastf2->datalen);
09946                l->dtmfed = 1;
09947             }
09948 #endif
09949 
09950             if (f->frametype == AST_FRAME_TEXT)
09951             {
09952                handle_link_data(myrpt,l,f->data);
09953             }
09954             if (f->frametype == AST_FRAME_DTMF)
09955             {
09956                if (l->lastf1)
09957                   memset(l->lastf1->data,0,l->lastf1->datalen);
09958                if (l->lastf2)
09959                   memset(l->lastf2->data,0,l->lastf2->datalen);
09960                l->dtmfed = 1;
09961                handle_link_phone_dtmf(myrpt,l,f->subclass);
09962             }
09963             if (f->frametype == AST_FRAME_CONTROL)
09964             {
09965                if (f->subclass == AST_CONTROL_ANSWER)
09966                {
09967                   char lconnected = l->connected;
09968 
09969                   __kickshort(myrpt);
09970                   l->connected = 1;
09971                   l->hasconnected = 1;
09972                   l->thisconnected = 1;
09973                   l->elaptime = -1;
09974                   if (!l->isremote) l->retries = 0;
09975                   if (!lconnected) 
09976                   {
09977                      rpt_telemetry(myrpt,CONNECTED,l);
09978                      if (myrpt->p.archivedir)
09979                      {
09980                         char str[100];
09981 
09982                         if (l->mode)
09983                            sprintf(str,"LINKTRX,%s",l->name);
09984                         else
09985                            sprintf(str,"LINKMONITOR,%s",l->name);
09986                         donodelog(myrpt,str);
09987                      }
09988                   }     
09989                   else
09990                      l->reconnects++;
09991                }
09992                /* if RX key */
09993                if (f->subclass == AST_CONTROL_RADIO_KEY)
09994                {
09995                   if (debug == 7 ) printf("@@@@ rx key\n");
09996                   l->lastrx = 1;
09997                   l->rerxtimer = 0;
09998                   if (myrpt->p.archivedir && (!l->lastrx1))
09999                   {
10000                      char str[100];
10001 
10002                      l->lastrx1 = 1;
10003                      sprintf(str,"RXKEY,%s",l->name);
10004                      donodelog(myrpt,str);
10005                   }
10006                }
10007                /* if RX un-key */
10008                if (f->subclass == AST_CONTROL_RADIO_UNKEY)
10009                {
10010                   if (debug == 7) printf("@@@@ rx un-key\n");
10011                   l->lastrx = 0;
10012                   l->rerxtimer = 0;
10013                   if(myrpt->p.duplex) 
10014                      rpt_telemetry(myrpt,LINKUNKEY,l);
10015                   if (myrpt->p.archivedir && (l->lastrx1))
10016                   {
10017                      char str[100];
10018 
10019                      l->lastrx1 = 0;
10020                      sprintf(str,"RXUNKEY,%s",l->name);
10021                      donodelog(myrpt,str);
10022                   }
10023                }
10024                if (f->subclass == AST_CONTROL_HANGUP)
10025                {
10026                   ast_frfree(f);
10027                   rpt_mutex_lock(&myrpt->lock);
10028                   __kickshort(myrpt);
10029                   rpt_mutex_unlock(&myrpt->lock);
10030                   if ((!l->outbound) && (!l->disced))
10031                   {
10032                      if ((l->name[0] == '0') || l->isremote)
10033                         l->disctime = 1;
10034                      else
10035                         l->disctime = DISC_TIME;
10036                      rpt_mutex_lock(&myrpt->lock);
10037                      ast_hangup(l->chan);
10038                      l->chan = 0;
10039                      break;
10040                   }
10041                   if (l->retrytimer) 
10042                   {
10043                      if (l->chan) ast_hangup(l->chan);
10044                      l->chan = 0;
10045                      rpt_mutex_lock(&myrpt->lock);
10046                      break;
10047                   }
10048                   if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected))
10049                   {
10050                      rpt_mutex_lock(&myrpt->lock);
10051                      if (l->chan) ast_hangup(l->chan);
10052                      l->chan = 0;
10053                      l->hasconnected = 1;
10054                      l->elaptime = 0;
10055                      l->retrytimer = RETRY_TIMER_MS;
10056                      l->connecttime = 0;
10057                      l->thisconnected = 0;
10058                      break;
10059                   }
10060                   rpt_mutex_lock(&myrpt->lock);
10061                   /* remove from queue */
10062                   remque((struct qelem *) l);
10063                   if (!strcmp(myrpt->cmdnode,l->name))
10064                      myrpt->cmdnode[0] = 0;
10065                   __kickshort(myrpt);
10066                   rpt_mutex_unlock(&myrpt->lock);
10067                   if (!l->hasconnected)
10068                      rpt_telemetry(myrpt,CONNFAIL,l);
10069                   else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l);
10070                   if (myrpt->p.archivedir)
10071                   {
10072                      char str[100];
10073 
10074                      if (!l->hasconnected)
10075                         sprintf(str,"LINKFAIL,%s",l->name);
10076                      else
10077                         sprintf(str,"LINKDISC,%s",l->name);
10078                      donodelog(myrpt,str);
10079                   }
10080                   if (l->lastf1) ast_frfree(l->lastf1);
10081                   l->lastf1 = NULL;
10082                   if (l->lastf2) ast_frfree(l->lastf2);
10083                   l->lastf2 = NULL;
10084                   /* hang-up on call to device */
10085                   ast_hangup(l->chan);
10086                   ast_hangup(l->pchan);
10087                   free(l);
10088                   rpt_mutex_lock(&myrpt->lock);
10089                   break;
10090                }
10091             }
10092             ast_frfree(f);
10093             rpt_mutex_lock(&myrpt->lock);
10094             break;
10095          }
10096          if (who == l->pchan) 
10097          {
10098             rpt_mutex_unlock(&myrpt->lock);
10099             f = ast_read(l->pchan);
10100             if (!f)
10101             {
10102                if (debug) printf("@@@@ rpt:Hung Up\n");
10103                toexit = 1;
10104                rpt_mutex_lock(&myrpt->lock);
10105                break;
10106             }
10107             if (f->frametype == AST_FRAME_VOICE)
10108             {
10109                if (l->chan) ast_write(l->chan,f);
10110             }
10111             if (f->frametype == AST_FRAME_CONTROL)
10112             {
10113                if (f->subclass == AST_CONTROL_HANGUP)
10114                {
10115                   if (debug) printf("@@@@ rpt:Hung Up\n");
10116                   ast_frfree(f);
10117                   toexit = 1;
10118                   rpt_mutex_lock(&myrpt->lock);
10119                   break;
10120                }
10121             }
10122             ast_frfree(f);
10123             rpt_mutex_lock(&myrpt->lock);
10124             break;
10125          }
10126          l = l->next;
10127       }
10128       rpt_mutex_unlock(&myrpt->lock);
10129       if (toexit) break;
10130       if (who == myrpt->monchannel) 
10131       {
10132          f = ast_read(myrpt->monchannel);
10133          if (!f)
10134          {
10135             if (debug) printf("@@@@ rpt:Hung Up\n");
10136             break;
10137          }
10138          if (f->frametype == AST_FRAME_VOICE)
10139          {
10140             if (myrpt->monstream) 
10141                ast_writestream(myrpt->monstream,f);
10142          }
10143          if (f->frametype == AST_FRAME_CONTROL)
10144          {
10145             if (f->subclass == AST_CONTROL_HANGUP)
10146             {
10147                if (debug) printf("@@@@ rpt:Hung Up\n");
10148                ast_frfree(f);
10149                break;
10150             }
10151          }
10152          ast_frfree(f);
10153          continue;
10154       }
10155       if (who == myrpt->txpchannel) /* if it was a read from remote tx */
10156       {
10157          f = ast_read(myrpt->txpchannel);
10158          if (!f)
10159          {
10160             if (debug) printf("@@@@ rpt:Hung Up\n");
10161             break;
10162          }
10163          if (f->frametype == AST_FRAME_CONTROL)
10164          {
10165             if (f->subclass == AST_CONTROL_HANGUP)
10166             {
10167                if (debug) printf("@@@@ rpt:Hung Up\n");
10168                ast_frfree(f);
10169                break;
10170             }
10171          }
10172          ast_frfree(f);
10173          continue;
10174       }
10175    }
10176    usleep(100000);
10177    ast_hangup(myrpt->pchannel);
10178    ast_hangup(myrpt->monchannel);
10179    ast_hangup(myrpt->txpchannel);
10180    if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel);
10181    if (myrpt->lastf1) ast_frfree(myrpt->lastf1);
10182    myrpt->lastf1 = NULL;
10183    if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
10184    myrpt->lastf2 = NULL;
10185    ast_hangup(myrpt->rxchannel);
10186    rpt_mutex_lock(&myrpt->lock);
10187    l = myrpt->links.next;
10188    while(l != &myrpt->links)
10189    {
10190       struct rpt_link *ll = l;
10191       /* remove from queue */
10192       remque((struct qelem *) l);
10193       /* hang-up on call to device */
10194       if (l->chan) ast_hangup(l->chan);
10195       ast_hangup(l->pchan);
10196       l = l->next;
10197       free(ll);
10198    }
10199    rpt_mutex_unlock(&myrpt->lock);
10200    if (debug) printf("@@@@ rpt:Hung up channel\n");
10201    myrpt->rpt_thread = AST_PTHREADT_STOP;
10202    pthread_exit(NULL); 
10203    return NULL;
10204 }

static void* rpt_call ( void *  this  )  [static]

Definition at line 4110 of file app_rpt.c.

References rpt::acctcode, ast_callerid_parse(), ast_cdr_setaccount(), ast_channel_undefer_dtmf(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, ast_hangup(), ast_log(), ast_pbx_start(), ast_queue_frame(), ast_request(), ast_safe_sleep(), ast_senddigit(), ast_softhangup(), AST_SOFTHANGUP_DEV, rpt::callmode, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, rpt::cidx, rpt::conf, ast_channel::context, rpt::duplex, rpt::exten, ast_channel::exten, ast_channel::fds, free, rpt::lock, LOG_WARNING, MSWAIT, rpt::mydtmf, name, rpt::ourcallerid, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchquiet, ast_channel::pbx, rpt::pchannel, ast_channel::priority, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), strdup, ast_frame::subclass, TERM, and rpt::tonezone.

Referenced by function_autopatchup(), and local_dtmf_helper().

04111 {
04112 ZT_CONFINFO ci;  /* conference info */
04113 struct   rpt *myrpt = (struct rpt *)this;
04114 int   res;
04115 int stopped,congstarted,dialtimer,lastcidx,aborted;
04116 struct ast_channel *mychannel,*genchannel;
04117 
04118 
04119    myrpt->mydtmf = 0;
04120    /* allocate a pseudo-channel thru asterisk */
04121    mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
04122    if (!mychannel)
04123    {
04124       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
04125       pthread_exit(NULL);
04126    }
04127    ci.chan = 0;
04128    ci.confno = myrpt->conf; /* use the pseudo conference */
04129    ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER
04130       | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 
04131    /* first put the channel on the conference */
04132    if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
04133    {
04134       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04135       ast_hangup(mychannel);
04136       myrpt->callmode = 0;
04137       pthread_exit(NULL);
04138    }
04139    /* allocate a pseudo-channel thru asterisk */
04140    genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
04141    if (!genchannel)
04142    {
04143       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
04144       ast_hangup(mychannel);
04145       pthread_exit(NULL);
04146    }
04147    ci.chan = 0;
04148    ci.confno = myrpt->conf;
04149    ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER
04150       | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 
04151    /* first put the channel on the conference */
04152    if (ioctl(genchannel->fds[0],ZT_SETCONF,&ci) == -1)
04153    {
04154       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04155       ast_hangup(mychannel);
04156       ast_hangup(genchannel);
04157       myrpt->callmode = 0;
04158       pthread_exit(NULL);
04159    }
04160    if (myrpt->p.tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->p.tonezone) == -1))
04161    {
04162       ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone);
04163       ast_hangup(mychannel);
04164       ast_hangup(genchannel);
04165       myrpt->callmode = 0;
04166       pthread_exit(NULL);
04167    }
04168    if (myrpt->p.tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->p.tonezone) == -1))
04169    {
04170       ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone);
04171       ast_hangup(mychannel);
04172       ast_hangup(genchannel);
04173       myrpt->callmode = 0;
04174       pthread_exit(NULL);
04175    }
04176    /* start dialtone if patchquiet is 0. Special patch modes don't send dial tone */
04177    if ((!myrpt->patchquiet) && (tone_zone_play_tone(mychannel->fds[0],ZT_TONE_DIALTONE) < 0))
04178    {
04179       ast_log(LOG_WARNING, "Cannot start dialtone\n");
04180       ast_hangup(mychannel);
04181       ast_hangup(genchannel);
04182       myrpt->callmode = 0;
04183       pthread_exit(NULL);
04184    }
04185    stopped = 0;
04186    congstarted = 0;
04187    dialtimer = 0;
04188    lastcidx = 0;
04189    aborted = 0;
04190 
04191 
04192    while ((myrpt->callmode == 1) || (myrpt->callmode == 4))
04193    {
04194 
04195       if((myrpt->patchdialtime)&&(myrpt->callmode == 1)&&(myrpt->cidx != lastcidx)){
04196          dialtimer = 0;
04197          lastcidx = myrpt->cidx;
04198       }     
04199 
04200       if((myrpt->patchdialtime)&&(dialtimer >= myrpt->patchdialtime)){ 
04201          rpt_mutex_lock(&myrpt->lock);
04202          aborted = 1;
04203          myrpt->callmode = 0;
04204          rpt_mutex_unlock(&myrpt->lock);
04205          break;
04206       }
04207    
04208       if ((!myrpt->patchquiet) && (!stopped) && (myrpt->callmode == 1) && (myrpt->cidx > 0))
04209       {
04210          stopped = 1;
04211          /* stop dial tone */
04212          tone_zone_play_tone(mychannel->fds[0],-1);
04213       }
04214       if (myrpt->callmode == 4)
04215       {
04216          if(!congstarted){
04217             congstarted = 1;
04218             /* start congestion tone */
04219             tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION);
04220          }
04221       }
04222       res = ast_safe_sleep(mychannel, MSWAIT);
04223       if (res < 0)
04224       {
04225          ast_hangup(mychannel);
04226          ast_hangup(genchannel);
04227          rpt_mutex_lock(&myrpt->lock);
04228          myrpt->callmode = 0;
04229          rpt_mutex_unlock(&myrpt->lock);
04230          pthread_exit(NULL);
04231       }
04232       dialtimer += MSWAIT;
04233    }
04234    /* stop any tone generation */
04235    tone_zone_play_tone(mychannel->fds[0],-1);
04236    /* end if done */
04237    if (!myrpt->callmode)
04238    {
04239       ast_hangup(mychannel);
04240       ast_hangup(genchannel);
04241       rpt_mutex_lock(&myrpt->lock);
04242       myrpt->callmode = 0;
04243       rpt_mutex_unlock(&myrpt->lock);
04244       if((!myrpt->patchquiet) && aborted)
04245          rpt_telemetry(myrpt, TERM, NULL);
04246       pthread_exit(NULL);        
04247    }
04248 
04249    if (myrpt->p.ourcallerid && *myrpt->p.ourcallerid){
04250       char *name, *loc, *instr;
04251       instr = strdup(myrpt->p.ourcallerid);
04252       if(instr){
04253          ast_callerid_parse(instr, &name, &loc);
04254          if(loc){
04255             if(mychannel->cid.cid_num)
04256                free(mychannel->cid.cid_num);
04257             mychannel->cid.cid_num = strdup(loc);
04258          }
04259          if(name){
04260             if(mychannel->cid.cid_name)
04261                free(mychannel->cid.cid_name);
04262             mychannel->cid.cid_name = strdup(name);
04263          }
04264          free(instr);
04265       }
04266    }
04267 
04268    ast_copy_string(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1);
04269    ast_copy_string(mychannel->context, myrpt->patchcontext, sizeof(mychannel->context) - 1);
04270    
04271    if (myrpt->p.acctcode)
04272       ast_cdr_setaccount(mychannel,myrpt->p.acctcode);
04273    mychannel->priority = 1;
04274    ast_channel_undefer_dtmf(mychannel);
04275    if (ast_pbx_start(mychannel) < 0)
04276    {
04277       ast_log(LOG_WARNING, "Unable to start PBX!!\n");
04278       ast_hangup(mychannel);
04279       ast_hangup(genchannel);
04280       rpt_mutex_lock(&myrpt->lock);
04281       myrpt->callmode = 0;
04282       rpt_mutex_unlock(&myrpt->lock);
04283       pthread_exit(NULL);
04284    }
04285    usleep(10000);
04286    rpt_mutex_lock(&myrpt->lock);
04287    myrpt->callmode = 3;
04288    /* set appropriate conference for the pseudo */
04289    ci.chan = 0;
04290    ci.confno = myrpt->conf;
04291    ci.confmode = (myrpt->p.duplex == 2) ? ZT_CONF_CONFANNMON :
04292       (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER);
04293    /* first put the channel on the conference in announce mode */
04294    if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
04295    {
04296       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04297       ast_hangup(mychannel);
04298       ast_hangup(genchannel);
04299       myrpt->callmode = 0;
04300       pthread_exit(NULL);
04301    }
04302    while(myrpt->callmode)
04303    {
04304       if ((!mychannel->pbx) && (myrpt->callmode != 4))
04305       {
04306          if(myrpt->patchfarenddisconnect){ /* If patch is setup for far end disconnect */
04307             myrpt->callmode = 0;
04308             if(!myrpt->patchquiet){
04309                rpt_mutex_unlock(&myrpt->lock);
04310                rpt_telemetry(myrpt, TERM, NULL);
04311                rpt_mutex_lock(&myrpt->lock);
04312             }
04313          }
04314          else{ /* Send congestion until patch is downed by command */
04315             myrpt->callmode = 4;
04316             rpt_mutex_unlock(&myrpt->lock);
04317             /* start congestion tone */
04318             tone_zone_play_tone(genchannel->fds[0],ZT_TONE_CONGESTION);
04319             rpt_mutex_lock(&myrpt->lock);
04320          }
04321       }
04322       if (myrpt->mydtmf)
04323       {
04324          struct ast_frame wf = {AST_FRAME_DTMF, } ;
04325          wf.subclass = myrpt->mydtmf;
04326          rpt_mutex_unlock(&myrpt->lock);
04327          ast_queue_frame(mychannel,&wf);
04328          ast_senddigit(genchannel,myrpt->mydtmf);
04329          rpt_mutex_lock(&myrpt->lock);
04330          myrpt->mydtmf = 0;
04331       }
04332       rpt_mutex_unlock(&myrpt->lock);
04333       usleep(MSWAIT * 1000);
04334       rpt_mutex_lock(&myrpt->lock);
04335    }
04336    rpt_mutex_unlock(&myrpt->lock);
04337    tone_zone_play_tone(genchannel->fds[0],-1);
04338    if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV);
04339    ast_hangup(genchannel);
04340    rpt_mutex_lock(&myrpt->lock);
04341    myrpt->callmode = 0;
04342    rpt_mutex_unlock(&myrpt->lock);
04343    /* set appropriate conference for the pseudo */
04344    ci.chan = 0;
04345    ci.confno = myrpt->conf;
04346    ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON :
04347       (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER);
04348    /* first put the channel on the conference in announce mode */
04349    if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
04350    {
04351       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04352    }
04353    pthread_exit(NULL);
04354 }

static int rpt_do_debug ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1919 of file app_rpt.c.

References ast_cli(), myatoi(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01920 {
01921    int newlevel;
01922 
01923         if (argc != 4)
01924                 return RESULT_SHOWUSAGE;
01925         newlevel = myatoi(argv[3]);
01926         if((newlevel < 0) || (newlevel > 7))
01927                 return RESULT_SHOWUSAGE;
01928         if(newlevel)
01929                 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
01930         else
01931                 ast_cli(fd, "app_rpt Debugging disabled\n");
01932 
01933         debug = newlevel;                                                                                                                          
01934         return RESULT_SUCCESS;
01935 }

static int rpt_do_dump ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1941 of file app_rpt.c.

References ast_cli(), rpt::disgorgetime, name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and rpt_vars.

01942 {
01943    int i;
01944 
01945         if (argc != 3)
01946                 return RESULT_SHOWUSAGE;
01947 
01948    for(i = 0; i < nrpts; i++)
01949    {
01950       if (!strcmp(argv[2],rpt_vars[i].name))
01951       {
01952          rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
01953               ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]);
01954               return RESULT_SUCCESS;
01955       }
01956    }
01957    return RESULT_FAILURE;
01958 }

static int rpt_do_fun ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 2361 of file app_rpt.c.

References ast_cli(), busy, rpt::lock, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, name, RESULT_FAILURE, RESULT_SHOWUSAGE, rpt_mutex_lock, rpt_mutex_unlock, and rpt_vars.

02362 {
02363    int   i,busy=0;
02364 
02365         if (argc != 4) return RESULT_SHOWUSAGE;
02366 
02367    for(i = 0; i < nrpts; i++){
02368       if(!strcmp(argv[2], rpt_vars[i].name)){
02369          struct rpt *myrpt = &rpt_vars[i];
02370          rpt_mutex_lock(&myrpt->lock);
02371          if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(argv[3])){
02372             rpt_mutex_unlock(&myrpt->lock);
02373             busy=1;
02374          }
02375          if(!busy){
02376             myrpt->macrotimer = MACROTIME;
02377             strncat(myrpt->macrobuf,argv[3],MAXMACRO - 1);
02378          }
02379          rpt_mutex_unlock(&myrpt->lock);
02380       }
02381    }
02382    if(busy){
02383       ast_cli(fd, "Function decoder busy");
02384    }
02385    return RESULT_FAILURE;
02386 }

static int rpt_do_lstats ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 2189 of file app_rpt.c.

References ast_cli(), ast_log(), rpt_link::chan, rpt_link::chan_stat, rpt_lstat::chan_stat, rpt_link::connecttime, rpt_lstat::connecttime, free, rpt::links, rpt::lock, LOG_ERROR, malloc, MAXPEERSTR, MAXREMSTR, rpt_link::mode, rpt_lstat::mode, rpt_lstat::name, rpt_link::name, name, rpt_link::next, rpt_lstat::next, NRPTSTAT, rpt_link::outbound, rpt_lstat::outbound, pbx_substitute_variables_helper(), rpt_lstat::peer, rpt_lstat::prev, rpt_link::reconnects, rpt_lstat::reconnects, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, s, rpt_link::thisconnected, and rpt_lstat::thisconnected.

02190 {
02191    int i,j;
02192    char *connstate;
02193    struct rpt *myrpt;
02194    struct rpt_link *l;
02195    struct rpt_lstat *s,*t;
02196    struct rpt_lstat s_head;
02197    if(argc != 3)
02198       return RESULT_SHOWUSAGE;
02199 
02200    s = NULL;
02201    s_head.next = &s_head;
02202    s_head.prev = &s_head;
02203 
02204    for(i = 0; i < nrpts; i++)
02205    {
02206       if (!strcmp(argv[2],rpt_vars[i].name)){
02207          /* Make a copy of all stat variables while locked */
02208          myrpt = &rpt_vars[i];
02209          rpt_mutex_lock(&myrpt->lock); /* LOCK */
02210          /* Traverse the list of connected nodes */
02211          j = 0;
02212          l = myrpt->links.next;
02213          while(l && (l != &myrpt->links)){
02214             if (l->name[0] == '0'){ /* Skip '0' nodes */
02215                l = l->next;
02216                continue;
02217             }
02218             if((s = (struct rpt_lstat *) malloc(sizeof(struct rpt_lstat))) == NULL){
02219                ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n");
02220                rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02221                return RESULT_FAILURE;
02222             }
02223             memset(s, 0, sizeof(struct rpt_lstat));
02224             strncpy(s->name, l->name, MAXREMSTR - 1);
02225             if (l->chan) pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1);
02226             else strcpy(s->peer,"(none)");
02227             s->mode = l->mode;
02228             s->outbound = l->outbound;
02229             s->reconnects = l->reconnects;
02230             s->connecttime = l->connecttime;
02231             s->thisconnected = l->thisconnected;
02232             memcpy(s->chan_stat,l->chan_stat,NRPTSTAT * sizeof(struct rpt_chan_stat));
02233             insque((struct qelem *) s, (struct qelem *) s_head.next);
02234             memset(l->chan_stat,0,NRPTSTAT * sizeof(struct rpt_chan_stat));
02235             l = l->next;
02236          }
02237          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02238          ast_cli(fd, "NODE      PEER                RECONNECTS  DIRECTION  CONNECT TIME        CONNECT STATE\n");
02239          ast_cli(fd, "----      ----                ----------  ---------  ------------        -------------\n");
02240 
02241          for(s = s_head.next; s != &s_head; s = s->next){
02242             int hours, minutes, seconds;
02243             long long connecttime = s->connecttime;
02244             char conntime[21];
02245             hours = (int) connecttime/3600000;
02246             connecttime %= 3600000;
02247             minutes = (int) connecttime/60000;
02248             connecttime %= 60000;
02249             seconds = (int)  connecttime/1000;
02250             connecttime %= 1000;
02251             snprintf(conntime, 20, "%02d:%02d:%02d.%d",
02252                hours, minutes, seconds, (int) connecttime);
02253             conntime[20] = 0;
02254             if(s->thisconnected)
02255                connstate  = "ESTABLISHED";
02256             else
02257                connstate = "CONNECTING";
02258             ast_cli(fd, "%-10s%-20s%-12d%-11s%-20s%-20s\n",
02259                s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime, connstate);
02260          }  
02261          /* destroy our local link queue */
02262          s = s_head.next;
02263          while(s != &s_head){
02264             t = s;
02265             s = s->next;
02266             remque((struct qelem *)t);
02267             free(t);
02268          }        
02269          return RESULT_SUCCESS;
02270       }
02271    }
02272    return RESULT_FAILURE;
02273 }

static int rpt_do_nodes ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 2279 of file app_rpt.c.

References __mklinklist(), ast_cli(), finddelim(), rpt::lock, MAXLINKLIST, mycompar(), name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, and rpt_vars.

02280 {
02281    int i,j;
02282    char ns;
02283    char lbuf[MAXLINKLIST],*strs[MAXLINKLIST];
02284    struct rpt *myrpt;
02285    if(argc != 3)
02286       return RESULT_SHOWUSAGE;
02287 
02288    for(i = 0; i < nrpts; i++)
02289    {
02290       if (!strcmp(argv[2],rpt_vars[i].name)){
02291          /* Make a copy of all stat variables while locked */
02292          myrpt = &rpt_vars[i];
02293          rpt_mutex_lock(&myrpt->lock); /* LOCK */
02294          __mklinklist(myrpt,NULL,lbuf);
02295          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02296          /* parse em */
02297          ns = finddelim(lbuf,strs,MAXLINKLIST);
02298          /* sort em */
02299          if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar);
02300          ast_cli(fd,"\n");
02301          ast_cli(fd, "************************* CONNECTED NODES *************************\n\n");
02302          for(j = 0 ;; j++){
02303             if(!strs[j]){
02304                if(!j){
02305                   ast_cli(fd,"<NONE>");
02306                }
02307                break;
02308             }
02309             ast_cli(fd, "%s", strs[j]);
02310             if(j % 8 == 7){
02311                ast_cli(fd, "\n");
02312             }
02313             else{
02314                if(strs[j + 1])
02315                   ast_cli(fd, ", ");
02316             }
02317          }
02318          ast_cli(fd,"\n\n");
02319          return RESULT_SUCCESS;
02320       }
02321    }
02322    return RESULT_FAILURE;
02323 }

static int rpt_do_reload ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 2329 of file app_rpt.c.

References reload(), RESULT_FAILURE, RESULT_SHOWUSAGE, and rpt_vars.

02330 {
02331 int   n;
02332 
02333         if (argc > 2) return RESULT_SHOWUSAGE;
02334 
02335    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
02336 
02337    return RESULT_FAILURE;
02338 }

static int rpt_do_restart ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 2344 of file app_rpt.c.

References ast_softhangup(), AST_SOFTHANGUP_DEV, RESULT_FAILURE, RESULT_SHOWUSAGE, rpt_vars, and rpt::rxchannel.

02345 {
02346 int   i;
02347 
02348         if (argc > 2) return RESULT_SHOWUSAGE;
02349    for(i = 0; i < nrpts; i++)
02350    {
02351       if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV);
02352    }
02353    return RESULT_FAILURE;
02354 }

static int rpt_do_stats ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1964 of file app_rpt.c.

References sysstate::alternatetail, ast_cli(), ast_strdupa, sysstate::autopatchdisable, rpt::callmode, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, rpt::exten, rpt::keyed, rpt::lastdtmfcommand, rpt::lastnodewhichkeyedusup, sysstate::linkfundisable, rpt::links, rpt::lock, MAX_STAT_LINKS, rpt::mustid, rpt::name, rpt_link::name, name, rpt_link::next, rpt::p, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, rpt::s, sysstate::schedulerdisable, rpt::sysstate_cur, rpt::tailid, rpt::timeouts, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, sysstate::totdisable, rpt::totime, rpt::totimer, sysstate::txdisable, and sysstate::userfundisable.

01965 {
01966    int i,j;
01967    int dailytxtime, dailykerchunks;
01968    int totalkerchunks, dailykeyups, totalkeyups, timeouts;
01969    int totalexecdcommands, dailyexecdcommands, hours, minutes, seconds;
01970    long long totaltxtime;
01971    struct   rpt_link *l;
01972    char *listoflinks[MAX_STAT_LINKS];  
01973    char *lastnodewhichkeyedusup, *lastdtmfcommand;
01974    char *tot_state, *ider_state, *patch_state;
01975    char *reverse_patch_state, *sys_ena, *tot_ena, *link_ena, *patch_ena;
01976    char *sch_ena, *input_signal, *called_number, *user_funs, *tail_type;
01977    struct rpt *myrpt;
01978 
01979    static char *not_applicable = "N/A";
01980 
01981    if(argc != 3)
01982       return RESULT_SHOWUSAGE;
01983 
01984    for(i = 0 ; i < MAX_STAT_LINKS; i++)
01985       listoflinks[i] = NULL;
01986 
01987    tot_state = ider_state = 
01988    patch_state = reverse_patch_state = 
01989    input_signal = called_number = 
01990    lastdtmfcommand = not_applicable;
01991 
01992    for(i = 0; i < nrpts; i++)
01993    {
01994       if (!strcmp(argv[2],rpt_vars[i].name)){
01995          /* Make a copy of all stat variables while locked */
01996          myrpt = &rpt_vars[i];
01997          rpt_mutex_lock(&myrpt->lock); /* LOCK */
01998 
01999          dailytxtime = myrpt->dailytxtime;
02000          totaltxtime = myrpt->totaltxtime;
02001          dailykeyups = myrpt->dailykeyups;
02002          totalkeyups = myrpt->totalkeyups;
02003          dailykerchunks = myrpt->dailykerchunks;
02004          totalkerchunks = myrpt->totalkerchunks;
02005          dailyexecdcommands = myrpt->dailyexecdcommands;
02006          totalexecdcommands = myrpt->totalexecdcommands;
02007          timeouts = myrpt->timeouts;
02008 
02009          /* Traverse the list of connected nodes */
02010          reverse_patch_state = "DOWN";
02011          j = 0;
02012          l = myrpt->links.next;
02013          while(l && (l != &myrpt->links)){
02014             if (l->name[0] == '0'){ /* Skip '0' nodes */
02015                reverse_patch_state = "UP";
02016                l = l->next;
02017                continue;
02018             }
02019             listoflinks[j] = ast_strdupa(l->name);
02020             if(listoflinks[j])
02021                j++;
02022             l = l->next;
02023          }
02024 
02025          lastnodewhichkeyedusup = ast_strdupa(myrpt->lastnodewhichkeyedusup);       
02026          if((!lastnodewhichkeyedusup) || (!strlen(lastnodewhichkeyedusup)))
02027             lastnodewhichkeyedusup = not_applicable;
02028 
02029          if(myrpt->keyed)
02030             input_signal = "YES";
02031          else
02032             input_signal = "NO";
02033 
02034          if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable)
02035             sys_ena = "DISABLED";
02036          else
02037             sys_ena = "ENABLED";
02038 
02039          if(myrpt->p.s[myrpt->p.sysstate_cur].totdisable)
02040             tot_ena = "DISABLED";
02041          else
02042             tot_ena = "ENABLED";
02043 
02044          if(myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable)
02045             link_ena = "DISABLED";
02046          else
02047             link_ena = "ENABLED";
02048 
02049          if(myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
02050             patch_ena = "DISABLED";
02051          else
02052             patch_ena = "ENABLED";
02053 
02054          if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable)
02055             sch_ena = "DISABLED";
02056          else
02057             sch_ena = "ENABLED";
02058 
02059          if(myrpt->p.s[myrpt->p.sysstate_cur].userfundisable)
02060             user_funs = "DISABLED";
02061          else
02062             user_funs = "ENABLED";
02063 
02064          if(myrpt->p.s[myrpt->p.sysstate_cur].alternatetail)
02065             tail_type = "ALTERNATE";
02066          else
02067             tail_type = "STANDARD";
02068 
02069          if(!myrpt->totimer)
02070             tot_state = "TIMED OUT!";
02071          else if(myrpt->totimer != myrpt->p.totime)
02072             tot_state = "ARMED";
02073          else
02074             tot_state = "RESET";
02075 
02076          if(myrpt->tailid)
02077             ider_state = "QUEUED IN TAIL";
02078          else if(myrpt->mustid)
02079             ider_state = "QUEUED FOR CLEANUP";
02080          else
02081             ider_state = "CLEAN";
02082 
02083          switch(myrpt->callmode){
02084             case 1:
02085                patch_state = "DIALING";
02086                break;
02087             case 2:
02088                patch_state = "CONNECTING";
02089                break;
02090             case 3:
02091                patch_state = "UP";
02092                break;
02093 
02094             case 4:
02095                patch_state = "CALL FAILED";
02096                break;
02097 
02098             default:
02099                patch_state = "DOWN";
02100          }
02101 
02102          if(strlen(myrpt->exten)){
02103             called_number = ast_strdupa(myrpt->exten);
02104             if(!called_number)
02105                called_number = not_applicable;
02106          }
02107 
02108          if(strlen(myrpt->lastdtmfcommand)){
02109             lastdtmfcommand = ast_strdupa(myrpt->lastdtmfcommand);
02110             if(!lastdtmfcommand)
02111                lastdtmfcommand = not_applicable;
02112          }
02113 
02114          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02115 
02116          ast_cli(fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name);
02117          ast_cli(fd, "Selected system state............................: %d\n", myrpt->p.sysstate_cur);
02118          ast_cli(fd, "Signal on input..................................: %s\n", input_signal);
02119          ast_cli(fd, "System...........................................: %s\n", sys_ena);
02120          ast_cli(fd, "Scheduler........................................: %s\n", sch_ena);
02121          ast_cli(fd, "Tail Time........................................: %s\n", tail_type);
02122          ast_cli(fd, "Time out timer...................................: %s\n", tot_ena);
02123          ast_cli(fd, "Time out timer state.............................: %s\n", tot_state);
02124          ast_cli(fd, "Time outs since system initialization............: %d\n", timeouts);
02125          ast_cli(fd, "Identifier state.................................: %s\n", ider_state);
02126          ast_cli(fd, "Kerchunks today..................................: %d\n", dailykerchunks);
02127          ast_cli(fd, "Kerchunks since system initialization............: %d\n", totalkerchunks);
02128          ast_cli(fd, "Keyups today.....................................: %d\n", dailykeyups);
02129          ast_cli(fd, "Keyups since system initialization...............: %d\n", totalkeyups);
02130          ast_cli(fd, "DTMF commands today..............................: %d\n", dailyexecdcommands);
02131          ast_cli(fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands);
02132          ast_cli(fd, "Last DTMF command executed.......................: %s\n", lastdtmfcommand);
02133          hours = dailytxtime/3600000;
02134          dailytxtime %= 3600000;
02135          minutes = dailytxtime/60000;
02136          dailytxtime %= 60000;
02137          seconds = dailytxtime/1000;
02138          dailytxtime %= 1000;
02139 
02140          ast_cli(fd, "TX time today ...................................: %02d:%02d:%02d.%d\n",
02141             hours, minutes, seconds, dailytxtime);
02142 
02143          hours = (int) totaltxtime/3600000;
02144          totaltxtime %= 3600000;
02145          minutes = (int) totaltxtime/60000;
02146          totaltxtime %= 60000;
02147          seconds = (int)  totaltxtime/1000;
02148          totaltxtime %= 1000;
02149 
02150          ast_cli(fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n",
02151              hours, minutes, seconds, (int) totaltxtime);
02152          ast_cli(fd, "Nodes currently connected to us..................: ");
02153          for(j = 0 ;; j++){
02154             if(!listoflinks[j]){
02155                if(!j){
02156                   ast_cli(fd,"<NONE>");
02157                }
02158                break;
02159             }
02160             ast_cli(fd, "%s", listoflinks[j]);
02161             if(j % 4 == 3){
02162                ast_cli(fd, "\n");
02163                ast_cli(fd, "                                                 : ");
02164             }
02165             else{
02166                if(listoflinks[j + 1])
02167                   ast_cli(fd, ", ");
02168             }
02169          }
02170          ast_cli(fd,"\n");
02171 
02172          ast_cli(fd, "Last node which transmitted to us................: %s\n", lastnodewhichkeyedusup);
02173          ast_cli(fd, "Autopatch........................................: %s\n", patch_ena);
02174          ast_cli(fd, "Autopatch state..................................: %s\n", patch_state);
02175          ast_cli(fd, "Autopatch called number..........................: %s\n", called_number);
02176          ast_cli(fd, "Reverse patch/IAXRPT connected...................: %s\n", reverse_patch_state);
02177          ast_cli(fd, "User linking commands............................: %s\n", link_ena);
02178          ast_cli(fd, "User functions...................................: %s\n\n", user_funs);
02179               return RESULT_SUCCESS;
02180       }
02181    }
02182    return RESULT_FAILURE;
02183 }

static int rpt_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 10371 of file app_rpt.c.

References __kickshort(), ast_channel::_state, ACT_TIMEOUT_WARNING, ahp, ast_channel::appl, rpt::archivedir, ast_answer(), ast_call(), ast_callerid_parse(), ast_channel_setoption(), ast_check_hangup(), ast_cli_command(), AST_CONTROL_BUSY, AST_CONTROL_HANGUP, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_exists_extension(), AST_FORMAT_SLINEAR, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_TEXT, AST_FRAME_VOICE, ast_frdup(), ast_frfree(), ast_gethostbyname(), ast_hangup(), ast_indicate(), ast_inet_ntoa(), ast_log(), ast_masq_park_call(), AST_OPTION_TONE_VERIFY, AST_PBX_KEEPALIVE, ast_read(), ast_request(), ast_safe_sleep(), ast_say_character_str(), ast_set_callerid(), ast_set_read_format(), ast_set_write_format(), ast_shrink_phone_number(), AST_STATE_UP, ast_strlen_zero(), ast_verbose(), ast_waitfor_n(), ast_write(), rpt::authlevel, AUTHLOGOUTTIME, AUTHTELLTIME, rpt::authtelltimer, rpt::authtimer, AUTHTXTIME, rpt::callmode, check_tx_freq(), ast_channel::cid, ast_callerid::cid_num, closerem(), rpt::conf, ast_channel::context, context, ast_frame::data, ast_channel::data, ast_frame::datalen, rpt_link::disced, diskavail(), do_dtmf_local(), donodelog(), rpt::dtmf_local_timer, rpt::dtmf_time_rem, rpt::dtmfbuf, rpt::dtmfidx, ast_channel::exten, exten, ast_channel::fds, ast_frame::frametype, free, handle_remote_data(), handle_remote_dtmf_digit(), handle_remote_phone_dtmf(), rpt::hfscanmode, rpt::hfscanstatus, hp, rpt::iobase, rpt::iofd, rpt::ioport, rpt_link::killme, rpt::last_activity_time, rpt::lastf1, rpt::lastf2, rpt::links, load_rpt_vars(), rpt::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, rpt::loginlevel, LOGINREQ, rpt::loginuser, rpt::macrobuf, MACROPTIME, MACROTIME, rpt::macrotimer, malloc, MAX_RETRIES, rpt_link::max_retries, MAXMACRO, MAXNODESTR, rpt_tele::mode, MONITOR_DISK_BLOCKS_PER_MINUTE, rpt::monminblocks, MSWAIT, rpt_link::name, rpt::name, name, rpt_tele::next, rpt_link::next, rpt::nobusyout, node_lookup(), openserial(), option_verbose, rpt::p, pbx_substitute_variables_helper(), rpt::pchannel, rpt_tele::prev, ast_channel::priority, rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, REM_MODE_FM, REM_SCANTIME, rpt::remmode, rpt::remote, rpt::remoteinacttimeout, rpt::remoteon, rpt::remoterx, rpt::remotetimeout, rpt::remotetimeoutwarning, rpt::remotetimeoutwarningfreq, rpt::remotetx, rpt::remtxfreqok, rpt::rerxtimer, rpt_link::retries, rpt::retxtimer, REV_PATCH, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt_vars, rpt::rxchanname, rpt::rxchannel, s, rpt::s, sayfile(), SCAN, rpt::scantimer, setrem(), SETREMOTE, START_DELAY, rpt::start_time, rpt::startupmacro, strsep(), ast_frame::subclass, rpt::sysstate_cur, rpt::tele, TIMEOUT_WARNING, TUNE, rpt::tunerequest, rpt::txchanname, rpt::txchannel, rpt::txconf, sysstate::txdisable, UNAUTHTX, VERBOSE_PREFIX_3, and ast_channel::whentohangup.

Referenced by load_module().

10372 {
10373    int res=-1,i,rem_totx,rem_rx,remkeyed,n,phone_mode = 0;
10374    int iskenwood_pci4,authtold,authreq,setting,notremming,reming;
10375    int ismuted,dtmfed;
10376 #ifdef   OLD_ASTERISK
10377    struct localuser *u;
10378 #endif
10379    char tmp[256], keyed = 0,keyed1 = 0;
10380    char *options,*stringp,*tele,c;
10381    struct   rpt *myrpt;
10382    struct ast_frame *f,*f1,*f2;
10383    struct ast_channel *who;
10384    struct ast_channel *cs[20];
10385    struct   rpt_link *l;
10386    ZT_CONFINFO ci;  /* conference info */
10387    ZT_PARAMS par;
10388    int ms,elap,nullfd;
10389    time_t t,last_timeout_warning;
10390    struct   zt_radio_param z;
10391    struct rpt_tele *telem;
10392 
10393    nullfd = open("/dev/null",O_RDWR);
10394    if (ast_strlen_zero(data)) {
10395       ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n");
10396       return -1;
10397    }
10398    strncpy(tmp, (char *)data, sizeof(tmp)-1);
10399    time(&t);
10400    /* if time has externally shifted negative, screw it */
10401    if (t < starttime) t = starttime + START_DELAY;
10402    if ((!starttime) || (t < (starttime + START_DELAY)))
10403    {
10404       ast_log(LOG_NOTICE,"Node %s rejecting call: too soon!\n",tmp);
10405       ast_safe_sleep(chan,3000);
10406       return -1;
10407    }
10408    stringp=tmp;
10409    strsep(&stringp, "|");
10410    options = stringp;
10411    myrpt = NULL;
10412    /* see if we can find our specified one */
10413    for(i = 0; i < nrpts; i++)
10414    {
10415       /* if name matches, assign it and exit loop */
10416       if (!strcmp(tmp,rpt_vars[i].name))
10417       {
10418          myrpt = &rpt_vars[i];
10419          break;
10420       }
10421    }
10422    if (myrpt == NULL)
10423    {
10424       ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp);
10425       return -1;
10426    }
10427    
10428    if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable){ /* Do not allow incoming connections if disabled */
10429       ast_log(LOG_NOTICE, "Connect attempt to node %s  with tx disabled", myrpt->name);
10430       return -1;
10431    }
10432 
10433    /* if not phone access, must be an IAX connection */
10434    if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R')))
10435    {
10436       int val;
10437 
10438       phone_mode = 1;
10439       if (*options == 'D') phone_mode = 2;
10440       ast_set_callerid(chan,"0","app_rpt user","0");
10441       val = 1;
10442       ast_channel_setoption(chan,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
10443    }
10444    else
10445    {
10446       if (strncmp(chan->name,"IAX2",4))
10447       {
10448          ast_log(LOG_WARNING, "We only accept links via IAX2!!\n");
10449          return -1;
10450       }
10451    }
10452    if (options && (*options == 'R'))
10453    {
10454 
10455       /* Parts of this section taken from app_parkandannounce */
10456       char *return_context;
10457       int l, m, lot, timeout = 0;
10458       char tmp[256],*template;
10459       char *working, *context, *exten, *priority;
10460       char *s,*orig_s;
10461 
10462 
10463       rpt_mutex_lock(&myrpt->lock);
10464       m = myrpt->callmode;
10465       rpt_mutex_unlock(&myrpt->lock);
10466 
10467       if ((!myrpt->p.nobusyout) && m)
10468       {
10469          if (chan->_state != AST_STATE_UP)
10470          {
10471             ast_indicate(chan,AST_CONTROL_BUSY);
10472          }
10473          while(ast_safe_sleep(chan,10000) != -1);
10474          return -1;
10475       }
10476 
10477       if (chan->_state != AST_STATE_UP)
10478       {
10479          ast_answer(chan);
10480       }
10481 
10482       l=strlen(options)+2;
10483       orig_s=malloc(l);
10484       if(!orig_s) {
10485          ast_log(LOG_WARNING, "Out of memory\n");
10486          return -1;
10487       }
10488       s=orig_s;
10489       strncpy(s,options,l);
10490 
10491       template=strsep(&s,"|");
10492       if(!template) {
10493          ast_log(LOG_WARNING, "An announce template must be defined\n");
10494          free(orig_s);
10495          return -1;
10496       } 
10497   
10498       if(s) {
10499          timeout = atoi(strsep(&s, "|"));
10500          timeout *= 1000;
10501       }
10502    
10503       return_context = s;
10504   
10505       if(return_context != NULL) {
10506          /* set the return context. Code borrowed from the Goto builtin */
10507     
10508          working = return_context;
10509          context = strsep(&working, "|");
10510          exten = strsep(&working, "|");
10511          if(!exten) {
10512             /* Only a priority in this one */
10513             priority = context;
10514             exten = NULL;
10515             context = NULL;
10516          } else {
10517             priority = strsep(&working, "|");
10518             if(!priority) {
10519                /* Only an extension and priority in this one */
10520                priority = exten;
10521                exten = context;
10522                context = NULL;
10523          }
10524       }
10525       if(atoi(priority) < 0) {
10526          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
10527          free(orig_s);
10528          return -1;
10529       }
10530       /* At this point we have a priority and maybe an extension and a context */
10531       chan->priority = atoi(priority);
10532 #ifdef OLD_ASTERISK
10533       if(exten && strcasecmp(exten, "BYEXTENSION"))
10534 #else
10535       if(exten)
10536 #endif
10537          strncpy(chan->exten, exten, sizeof(chan->exten)-1);
10538       if(context)
10539          strncpy(chan->context, context, sizeof(chan->context)-1);
10540       } else {  /* increment the priority by default*/
10541          chan->priority++;
10542       }
10543 
10544       if(option_verbose > 2) {
10545          ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num);
10546          if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
10547             ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
10548          }
10549       }
10550   
10551       /* we are using masq_park here to protect * from touching the channel once we park it.  If the channel comes out of timeout
10552       before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
10553 
10554       ast_masq_park_call(chan, NULL, timeout, &lot);
10555 
10556       if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
10557 
10558       snprintf(tmp,sizeof(tmp) - 1,"%d,%s",lot,template + 1);
10559 
10560       rpt_telemetry(myrpt,REV_PATCH,tmp);
10561 
10562       free(orig_s);
10563 
10564       return 0;
10565 
10566    }
10567 
10568    if (!options)
10569    {
10570                 struct ast_hostent ahp;
10571                 struct hostent *hp;
10572       struct in_addr ia;
10573       char hisip[100],nodeip[100],*val, *s, *s1, *s2, *b,*b1;
10574 
10575       /* look at callerid to see what node this comes from */
10576       if (!chan->cid.cid_num) /* if doesn't have caller id */
10577       {
10578          ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
10579          return -1;
10580       }
10581 
10582       /* get his IP from IAX2 module */
10583       memset(hisip,0,sizeof(hisip));
10584       pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
10585       if (!hisip[0])
10586       {
10587          ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n");
10588          return -1;
10589       }
10590       
10591       ast_callerid_parse(chan->cid.cid_num,&b,&b1);
10592       ast_shrink_phone_number(b1);
10593       if (!strcmp(myrpt->name,b1))
10594       {
10595          ast_log(LOG_WARNING, "Trying to link to self!!\n");
10596          return -1;
10597       }
10598 
10599       if (*b1 < '1')
10600       {
10601          ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1);
10602          return -1;
10603       }
10604 
10605 
10606       /* look for his reported node string */
10607       val = node_lookup(myrpt,b1);
10608       if (!val)
10609       {
10610          ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1);
10611          return -1;
10612       }
10613       strncpy(tmp,val,sizeof(tmp) - 1);
10614       s = tmp;
10615       s1 = strsep(&s,",");
10616       s2 = strsep(&s,",");
10617       if (!s2)
10618       {
10619          ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1);
10620          return -1;
10621       }
10622                 if (strcmp(s2,"NONE")) {
10623          hp = ast_gethostbyname(s2, &ahp);
10624          if (!hp)
10625          {
10626             ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2);
10627             return -1;
10628          }
10629          memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
10630 #ifdef   OLD_ASTERISK
10631          ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia);
10632 #else
10633          strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1);
10634 #endif
10635          if (strcmp(hisip,nodeip))
10636          {
10637             char *s3 = strchr(s1,'@');
10638             if (s3) s1 = s3 + 1;
10639             s3 = strchr(s1,'/');
10640             if (s3) *s3 = 0;
10641             hp = ast_gethostbyname(s1, &ahp);
10642             if (!hp)
10643             {
10644                ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1);
10645                return -1;
10646             }
10647             memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
10648 #ifdef   OLD_ASTERISK
10649             ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia);
10650 #else
10651             strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1);
10652 #endif
10653             if (strcmp(hisip,nodeip))
10654             {
10655                ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip);
10656                return -1;
10657             }
10658          }
10659       }
10660    }
10661 
10662    /* if is not a remote */
10663    if (!myrpt->remote)
10664    {
10665 
10666       char *b,*b1;
10667       int reconnects = 0;
10668 
10669       /* look at callerid to see what node this comes from */
10670       if (!chan->cid.cid_num) /* if doesn't have caller id */
10671       {
10672          ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
10673          return -1;
10674       }
10675 
10676       ast_callerid_parse(chan->cid.cid_num,&b,&b1);
10677       ast_shrink_phone_number(b1);
10678       if (!strcmp(myrpt->name,b1))
10679       {
10680          ast_log(LOG_WARNING, "Trying to link to self!!\n");
10681          return -1;
10682       }
10683       rpt_mutex_lock(&myrpt->lock);
10684       l = myrpt->links.next;
10685       /* try to find this one in queue */
10686       while(l != &myrpt->links)
10687       {
10688          if (l->name[0] == '0') 
10689          {
10690             l = l->next;
10691             continue;
10692          }
10693          /* if found matching string */
10694          if (!strcmp(l->name,b1)) break;
10695          l = l->next;
10696       }
10697       /* if found */
10698       if (l != &myrpt->links) 
10699       {
10700          l->killme = 1;
10701          l->retries = l->max_retries + 1;
10702          l->disced = 2;
10703          reconnects = l->reconnects;
10704          reconnects++;
10705                         rpt_mutex_unlock(&myrpt->lock);
10706          usleep(500000);   
10707       } else 
10708          rpt_mutex_unlock(&myrpt->lock);
10709       /* establish call in tranceive mode */
10710       l = malloc(sizeof(struct rpt_link));
10711       if (!l)
10712       {
10713          ast_log(LOG_WARNING, "Unable to malloc\n");
10714          pthread_exit(NULL);
10715       }
10716       /* zero the silly thing */
10717       memset((char *)l,0,sizeof(struct rpt_link));
10718       l->mode = 1;
10719       strncpy(l->name,b1,MAXNODESTR - 1);
10720       l->isremote = 0;
10721       l->chan = chan;
10722       l->connected = 1;
10723       l->thisconnected = 1;
10724       l->hasconnected = 1;
10725       l->reconnects = reconnects;
10726       l->phonemode = phone_mode;
10727       l->lastf1 = NULL;
10728       l->lastf2 = NULL;
10729       l->dtmfed = 0;
10730       ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
10731       ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
10732       /* allocate a pseudo-channel thru asterisk */
10733       l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
10734       if (!l->pchan)
10735       {
10736          fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
10737          pthread_exit(NULL);
10738       }
10739       ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
10740       ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
10741       /* make a conference for the tx */
10742       ci.chan = 0;
10743       ci.confno = myrpt->conf;
10744       ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER;
10745       /* first put the channel on the conference in proper mode */
10746       if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1)
10747       {
10748          ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
10749          pthread_exit(NULL);
10750       }
10751       rpt_mutex_lock(&myrpt->lock);
10752       if (phone_mode > 1) l->lastrx = 1;
10753       l->max_retries = MAX_RETRIES;
10754       /* insert at end of queue */
10755       insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
10756       __kickshort(myrpt);
10757       rpt_mutex_unlock(&myrpt->lock);
10758       if (chan->_state != AST_STATE_UP) {
10759          ast_answer(chan);
10760       }
10761       if (myrpt->p.archivedir)
10762       {
10763          char str[100];
10764 
10765          if (l->phonemode)
10766             sprintf(str,"LINK(P),%s",l->name);
10767          else
10768             sprintf(str,"LINK,%s",l->name);
10769          donodelog(myrpt,str);
10770       }
10771       return AST_PBX_KEEPALIVE;
10772    }
10773    /* well, then it is a remote */
10774    rpt_mutex_lock(&myrpt->lock);
10775    /* if remote, error if anyone else already linked */
10776    if (myrpt->remoteon)
10777    {
10778       rpt_mutex_unlock(&myrpt->lock);
10779       usleep(500000);
10780       if (myrpt->remoteon)
10781       {
10782          ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp);
10783          return -1;
10784       }     
10785       rpt_mutex_lock(&myrpt->lock);
10786    }
10787    if ((!strcmp(myrpt->remote, remote_rig_rbi)) &&
10788      (ioperm(myrpt->p.iobase,1,1) == -1))
10789    {
10790       rpt_mutex_unlock(&myrpt->lock);
10791       ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase);
10792       return -1;
10793    }
10794    myrpt->remoteon = 1;
10795 #ifdef   OLD_ASTERISK
10796    LOCAL_USER_ADD(u);
10797 #endif
10798    rpt_mutex_unlock(&myrpt->lock);
10799    /* find our index, and load the vars initially */
10800    for(i = 0; i < nrpts; i++)
10801    {
10802       if (&rpt_vars[i] == myrpt)
10803       {
10804          load_rpt_vars(i,0);
10805          break;
10806       }
10807    }
10808    rpt_mutex_lock(&myrpt->lock);
10809    tele = strchr(myrpt->rxchanname,'/');
10810    if (!tele)
10811    {
10812       fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
10813       rpt_mutex_unlock(&myrpt->lock);
10814       pthread_exit(NULL);
10815    }
10816    *tele++ = 0;
10817    myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL);
10818    if (myrpt->rxchannel)
10819    {
10820       ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
10821       ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
10822       myrpt->rxchannel->whentohangup = 0;
10823       myrpt->rxchannel->appl = "Apprpt";
10824       myrpt->rxchannel->data = "(Link Rx)";
10825       if (option_verbose > 2)
10826          ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
10827             myrpt->rxchanname,tele,myrpt->rxchannel->name);
10828       rpt_mutex_unlock(&myrpt->lock);
10829       ast_call(myrpt->rxchannel,tele,999);
10830       rpt_mutex_lock(&myrpt->lock);
10831    }
10832    else
10833    {
10834       fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
10835       rpt_mutex_unlock(&myrpt->lock);
10836       pthread_exit(NULL);
10837    }
10838    *--tele = '/';
10839    if (myrpt->txchanname)
10840    {
10841       tele = strchr(myrpt->txchanname,'/');
10842       if (!tele)
10843       {
10844          fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
10845          rpt_mutex_unlock(&myrpt->lock);
10846          ast_hangup(myrpt->rxchannel);
10847          pthread_exit(NULL);
10848       }
10849       *tele++ = 0;
10850       myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL);
10851       if (myrpt->txchannel)
10852       {
10853          ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
10854          ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
10855          myrpt->txchannel->whentohangup = 0;
10856          myrpt->txchannel->appl = "Apprpt";
10857          myrpt->txchannel->data = "(Link Tx)";
10858          if (option_verbose > 2)
10859             ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
10860                myrpt->txchanname,tele,myrpt->txchannel->name);
10861          rpt_mutex_unlock(&myrpt->lock);
10862          ast_call(myrpt->txchannel,tele,999);
10863          rpt_mutex_lock(&myrpt->lock);
10864       }
10865       else
10866       {
10867          fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
10868          rpt_mutex_unlock(&myrpt->lock);
10869          ast_hangup(myrpt->rxchannel);
10870          pthread_exit(NULL);
10871       }
10872       *--tele = '/';
10873    }
10874    else
10875    {
10876       myrpt->txchannel = myrpt->rxchannel;
10877    }
10878    /* allocate a pseudo-channel thru asterisk */
10879    myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
10880    if (!myrpt->pchannel)
10881    {
10882       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
10883       rpt_mutex_unlock(&myrpt->lock);
10884       if (myrpt->txchannel != myrpt->rxchannel) 
10885          ast_hangup(myrpt->txchannel);
10886       ast_hangup(myrpt->rxchannel);
10887       pthread_exit(NULL);
10888    }
10889    ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
10890    ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
10891    /* make a conference for the pseudo */
10892    ci.chan = 0;
10893    ci.confno = -1; /* make a new conf */
10894    ci.confmode = ZT_CONF_CONFANNMON ;
10895    /* first put the channel on the conference in announce/monitor mode */
10896    if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1)
10897    {
10898       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
10899       rpt_mutex_unlock(&myrpt->lock);
10900       ast_hangup(myrpt->pchannel);
10901       if (myrpt->txchannel != myrpt->rxchannel) 
10902          ast_hangup(myrpt->txchannel);
10903       ast_hangup(myrpt->rxchannel);
10904       pthread_exit(NULL);
10905    }
10906    /* if serial io port, open it */
10907    myrpt->iofd = -1;
10908    if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt->p.ioport)) == -1))
10909    {
10910       rpt_mutex_unlock(&myrpt->lock);
10911       ast_hangup(myrpt->pchannel);
10912       if (myrpt->txchannel != myrpt->rxchannel) 
10913          ast_hangup(myrpt->txchannel);
10914       ast_hangup(myrpt->rxchannel);
10915       pthread_exit(NULL);
10916    }
10917    iskenwood_pci4 = 0;
10918    memset(&z,0,sizeof(z));
10919    if (myrpt->iofd < 1)
10920    {
10921       z.radpar = ZT_RADPAR_REMMODE;
10922       z.data = ZT_RADPAR_REM_NONE;
10923       res = ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z);
10924       /* if PCIRADIO and kenwood selected */
10925       if ((!res) && (!strcmp(myrpt->remote,remote_rig_kenwood)))
10926       {
10927          z.radpar = ZT_RADPAR_UIOMODE;
10928          z.data = 1;
10929          if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
10930          {
10931             ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
10932             return -1;
10933          }
10934          z.radpar = ZT_RADPAR_UIODATA;
10935          z.data = 3;
10936          if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
10937          {
10938             ast_log(LOG_ERROR,"Cannot set UIODATA\n");
10939             return -1;
10940          }
10941          i = ZT_OFFHOOK;
10942          if (ioctl(myrpt->txchannel->fds[0],ZT_HOOK,&i) == -1)
10943          {
10944             ast_log(LOG_ERROR,"Cannot set hook\n");
10945             return -1;
10946          }
10947          iskenwood_pci4 = 1;
10948       }
10949    }
10950    i = ZT_ONHOOK;
10951    ioctl(myrpt->txchannel->fds[0],ZT_HOOK,&i);
10952    /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */
10953    if ((myrpt->iofd < 1) && (!res) &&
10954       (!strcmp(myrpt->remote,remote_rig_ft897) ||
10955          (!strcmp(myrpt->remote,remote_rig_ic706))))
10956    {
10957       z.radpar = ZT_RADPAR_UIOMODE;
10958       z.data = 1;
10959       if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
10960       {
10961          ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
10962          return -1;
10963       }
10964       z.radpar = ZT_RADPAR_UIODATA;
10965       z.data = 3;
10966       if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
10967       {
10968          ast_log(LOG_ERROR,"Cannot set UIODATA\n");
10969          return -1;
10970       }
10971    }
10972    /* save pseudo channel conference number */
10973    myrpt->conf = myrpt->txconf = ci.confno;
10974    myrpt->remoterx = 0;
10975    myrpt->remotetx = 0;
10976    myrpt->retxtimer = 0;
10977    myrpt->rerxtimer = 0;
10978    myrpt->remoteon = 1;
10979    myrpt->dtmfidx = -1;
10980    myrpt->dtmfbuf[0] = 0;
10981    myrpt->dtmf_time_rem = 0;
10982    myrpt->hfscanmode = 0;
10983    myrpt->hfscanstatus = 0;
10984    if (myrpt->p.startupmacro)
10985    {
10986       snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro);
10987    }
10988    time(&myrpt->start_time);
10989    myrpt->last_activity_time = myrpt->start_time;
10990    last_timeout_warning = 0;
10991    myrpt->reload = 0;
10992    myrpt->tele.next = &myrpt->tele;
10993    myrpt->tele.prev = &myrpt->tele;
10994    rpt_mutex_unlock(&myrpt->lock);
10995    ast_set_write_format(chan, AST_FORMAT_SLINEAR);
10996    ast_set_read_format(chan, AST_FORMAT_SLINEAR);
10997    rem_rx = 0;
10998    remkeyed = 0;
10999    /* if we are on 2w loop and are a remote, turn EC on */
11000    if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel))
11001    {
11002       i = 128;
11003       ioctl(myrpt->rxchannel->fds[0],ZT_ECHOCANCEL,&i);
11004    }
11005    if (chan->_state != AST_STATE_UP) {
11006       ast_answer(chan);
11007    }
11008 
11009    if (ioctl(myrpt->rxchannel->fds[0],ZT_GET_PARAMS,&par) != -1)
11010    {
11011       if (par.rxisoffhook)
11012       {
11013          ast_indicate(chan,AST_CONTROL_RADIO_KEY);
11014          myrpt->remoterx = 1;
11015          remkeyed = 1;
11016       }
11017    }
11018    if (myrpt->p.archivedir)
11019    {
11020       char mycmd[100],mydate[100],*b,*b1;
11021       time_t myt;
11022       long blocksleft;
11023 
11024 
11025       mkdir(myrpt->p.archivedir,0600);
11026       sprintf(mycmd,"%s/%s",myrpt->p.archivedir,myrpt->name);
11027       mkdir(mycmd,0600);
11028       time(&myt);
11029       strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S",
11030          localtime(&myt));
11031       sprintf(mycmd,"mixmonitor start %s %s/%s/%s.wav49 a",chan->name,
11032          myrpt->p.archivedir,myrpt->name,mydate);
11033       if (myrpt->p.monminblocks)
11034       {
11035          blocksleft = diskavail(myrpt);
11036          if (myrpt->p.remotetimeout)
11037          {
11038             blocksleft -= (myrpt->p.remotetimeout *
11039                MONITOR_DISK_BLOCKS_PER_MINUTE) / 60;
11040          }
11041          if (blocksleft >= myrpt->p.monminblocks)
11042             ast_cli_command(nullfd,mycmd);
11043       } else ast_cli_command(nullfd,mycmd);
11044       /* look at callerid to see what node this comes from */
11045       if (!chan->cid.cid_num) /* if doesn't have caller id */
11046       {
11047          b1 = "0";
11048       } else {
11049          ast_callerid_parse(chan->cid.cid_num,&b,&b1);
11050          ast_shrink_phone_number(b1);
11051       }
11052       sprintf(mycmd,"CONNECT,%s",b1);
11053       donodelog(myrpt,mycmd);
11054    }
11055    myrpt->loginuser[0] = 0;
11056    myrpt->loginlevel[0] = 0;
11057    myrpt->authtelltimer = 0;
11058    myrpt->authtimer = 0;
11059    authtold = 0;
11060    authreq = 0;
11061    if (myrpt->p.authlevel > 1) authreq = 1;
11062    setrem(myrpt); 
11063    n = 0;
11064    dtmfed = 0;
11065    cs[n++] = chan;
11066    cs[n++] = myrpt->rxchannel;
11067    cs[n++] = myrpt->pchannel;
11068    if (myrpt->rxchannel != myrpt->txchannel)
11069       cs[n++] = myrpt->txchannel;
11070    /* start un-locked */
11071    for(;;) 
11072    {
11073       if (ast_check_hangup(chan)) break;
11074       if (ast_check_hangup(myrpt->rxchannel)) break;
11075       notremming = 0;
11076       setting = 0;
11077       reming = 0;
11078       telem = myrpt->tele.next;
11079       while(telem != &myrpt->tele)
11080       {
11081          if (telem->mode == SETREMOTE) setting = 1;
11082          if ((telem->mode == SETREMOTE) ||
11083              (telem->mode == SCAN) ||
11084             (telem->mode == TUNE))  reming = 1;
11085          else notremming = 1;
11086          telem = telem->next;
11087       }
11088       if (myrpt->reload)
11089       {
11090          myrpt->reload = 0;
11091          /* find our index, and load the vars */
11092          for(i = 0; i < nrpts; i++)
11093          {
11094             if (&rpt_vars[i] == myrpt)
11095             {
11096                load_rpt_vars(i,0);
11097                break;
11098             }
11099          }
11100       }
11101       time(&t);
11102       if (myrpt->p.remotetimeout)
11103       { 
11104          time_t r;
11105 
11106          r = (t - myrpt->start_time);
11107          if (r >= myrpt->p.remotetimeout)
11108          {
11109             sayfile(chan,"rpt/node");
11110             ast_say_character_str(chan,myrpt->name,NULL,chan->language);
11111             sayfile(chan,"rpt/timeout");
11112             ast_safe_sleep(chan,1000);
11113             break;
11114          }
11115          if ((myrpt->p.remotetimeoutwarning) && 
11116              (r >= (myrpt->p.remotetimeout -
11117             myrpt->p.remotetimeoutwarning)) &&
11118                 (r <= (myrpt->p.remotetimeout - 
11119                   myrpt->p.remotetimeoutwarningfreq)))
11120          {
11121             if (myrpt->p.remotetimeoutwarningfreq)
11122             {
11123                 if ((t - last_timeout_warning) >=
11124                myrpt->p.remotetimeoutwarningfreq)
11125                 {
11126                time(&last_timeout_warning);
11127                rpt_telemetry(myrpt,TIMEOUT_WARNING,0);
11128                 }
11129             }
11130             else
11131             {
11132                 if (!last_timeout_warning)
11133                 {
11134                time(&last_timeout_warning);
11135                rpt_telemetry(myrpt,TIMEOUT_WARNING,0);
11136                 }
11137             }
11138          }
11139       }
11140       if (myrpt->p.remoteinacttimeout && myrpt->last_activity_time)
11141       { 
11142          time_t r;
11143 
11144          r = (t - myrpt->last_activity_time);
11145          if (r >= myrpt->p.remoteinacttimeout)
11146          {
11147             sayfile(chan,"rpt/node");
11148             ast_say_character_str(chan,myrpt->name,NULL,chan->language);
11149             sayfile(chan,"rpt/timeout");
11150             ast_safe_sleep(chan,1000);
11151             break;
11152          }
11153          if ((myrpt->p.remotetimeoutwarning) && 
11154              (r >= (myrpt->p.remoteinacttimeout -
11155             myrpt->p.remotetimeoutwarning)) &&
11156                 (r <= (myrpt->p.remoteinacttimeout - 
11157                   myrpt->p.remotetimeoutwarningfreq)))
11158          {
11159             if (myrpt->p.remotetimeoutwarningfreq)
11160             {
11161                 if ((t - last_timeout_warning) >=
11162                myrpt->p.remotetimeoutwarningfreq)
11163                 {
11164                time(&last_timeout_warning);
11165                rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0);
11166                 }
11167             }
11168             else
11169             {
11170                 if (!last_timeout_warning)
11171                 {
11172                time(&last_timeout_warning);
11173                rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0);
11174                 }
11175             }
11176          }
11177       }
11178       ms = MSWAIT;
11179       who = ast_waitfor_n(cs,n,&ms);
11180       if (who == NULL) ms = 0;
11181       elap = MSWAIT - ms;
11182       if (myrpt->macrotimer) myrpt->macrotimer -= elap;
11183       if (myrpt->macrotimer < 0) myrpt->macrotimer = 0;
11184       if (!ms) continue;
11185       /* do local dtmf timer */
11186       if (myrpt->dtmf_local_timer)
11187       {
11188          if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap;
11189          if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1;
11190       }
11191       rpt_mutex_lock(&myrpt->lock);
11192       do_dtmf_local(myrpt,0);
11193       rpt_mutex_unlock(&myrpt->lock);
11194       rem_totx =  myrpt->dtmf_local_timer && (!phone_mode);
11195       rem_totx |= keyed && (!myrpt->tunerequest);
11196       rem_rx = (remkeyed && (!setting)) || (myrpt->tele.next != &myrpt->tele);
11197       if(!strcmp(myrpt->remote, remote_rig_ic706))
11198          rem_totx |= myrpt->tunerequest;
11199       if (keyed && (!keyed1))
11200       {
11201          keyed1 = 1;
11202       }
11203 
11204       if (!keyed && (keyed1))
11205       {
11206          time_t myt;
11207 
11208          keyed1 = 0;
11209          time(&myt);
11210          /* if login necessary, and not too soon */
11211          if ((myrpt->p.authlevel) && 
11212              (!myrpt->loginlevel[0]) &&
11213             (myt > (t + 3)))
11214          {
11215             authreq = 1;
11216             authtold = 0;
11217             myrpt->authtelltimer = AUTHTELLTIME - AUTHTXTIME;
11218          }
11219       }
11220 
11221 
11222       if (rem_rx && (!myrpt->remoterx))
11223       {
11224          myrpt->remoterx = 1;
11225          ast_indicate(chan,AST_CONTROL_RADIO_KEY);
11226       }
11227       if ((!rem_rx) && (myrpt->remoterx))
11228       {
11229          myrpt->remoterx = 0;
11230          ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
11231       }
11232       /* if auth requested, and not authed yet */
11233       if (authreq && (!myrpt->loginlevel[0]))
11234       {
11235          if ((!authtold) && ((myrpt->authtelltimer += elap)
11236              >= AUTHTELLTIME))
11237          {
11238             authtold = 1;
11239             rpt_telemetry(myrpt,LOGINREQ,NULL);
11240          }
11241          if ((myrpt->authtimer += elap) >= AUTHLOGOUTTIME)
11242          {
11243             break; /* if not logged in, hang up after a time */
11244          }
11245       }
11246 #ifndef  OLDKEY
11247       if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME)
11248       {
11249          myrpt->retxtimer = 0;
11250          if ((myrpt->remoterx) && (!myrpt->remotetx))
11251             ast_indicate(chan,AST_CONTROL_RADIO_KEY);
11252          else
11253             ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
11254       }
11255 
11256       if ((myrpt->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 2))
11257       {
11258          keyed = 0;
11259          myrpt->rerxtimer = 0;
11260       }
11261 #endif
11262       if (rem_totx && (!myrpt->remotetx))
11263       {
11264          /* if not authed, and needed, dont transmit */
11265          if ((!myrpt->p.authlevel) || myrpt->loginlevel[0])
11266          {
11267             myrpt->remotetx = 1;
11268             if((myrpt->remtxfreqok = check_tx_freq(myrpt)))
11269             {
11270                time(&myrpt->last_activity_time);
11271                if (iskenwood_pci4)
11272                {
11273                   z.radpar = ZT_RADPAR_UIODATA;
11274                   z.data = 1;
11275                   if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
11276                   {
11277                      ast_log(LOG_ERROR,"Cannot set UIODATA\n");
11278                      return -1;
11279                   }
11280                }
11281                else
11282                {
11283                   ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
11284                }
11285                if (myrpt->p.archivedir) donodelog(myrpt,"TXKEY");
11286             }
11287          }
11288       }
11289       if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */
11290       {
11291          myrpt->remotetx = 0;
11292          if(!myrpt->remtxfreqok){
11293             rpt_telemetry(myrpt,UNAUTHTX,NULL);
11294          }
11295          if (iskenwood_pci4)
11296          {
11297             z.radpar = ZT_RADPAR_UIODATA;
11298             z.data = 3;
11299             if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
11300             {
11301                ast_log(LOG_ERROR,"Cannot set UIODATA\n");
11302                return -1;
11303             }
11304          }
11305          else
11306          {
11307             ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
11308          }
11309          if (myrpt->p.archivedir) donodelog(myrpt,"TXUNKEY");
11310       }
11311       if (myrpt->hfscanmode){
11312          myrpt->scantimer -= elap;
11313          if(myrpt->scantimer <= 0){
11314             if (!reming)
11315             {
11316                myrpt->scantimer = REM_SCANTIME;
11317                rpt_telemetry(myrpt,SCAN,0);
11318             } else myrpt->scantimer = 1;
11319          }
11320       }
11321       rpt_mutex_lock(&myrpt->lock);
11322       c = myrpt->macrobuf[0];
11323       if (c && (!myrpt->macrotimer))
11324       {
11325          myrpt->macrotimer = MACROTIME;
11326          memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1);
11327          if ((c == 'p') || (c == 'P'))
11328             myrpt->macrotimer = MACROPTIME;
11329          rpt_mutex_unlock(&myrpt->lock);
11330          if (myrpt->p.archivedir)
11331          {
11332             char str[100];
11333                sprintf(str,"DTMF(M),%c",c);
11334             donodelog(myrpt,str);
11335          }
11336          if (handle_remote_dtmf_digit(myrpt,c,&keyed,0) == -1) break;
11337          continue;
11338       } else rpt_mutex_unlock(&myrpt->lock);
11339       if (who == chan) /* if it was a read from incomming */
11340       {
11341          f = ast_read(chan);
11342          if (!f)
11343          {
11344             if (debug) printf("@@@@ link:Hung Up\n");
11345             break;
11346          }
11347          if (f->frametype == AST_FRAME_VOICE)
11348          {
11349             if (ioctl(chan->fds[0], ZT_GETCONFMUTE, &ismuted) == -1)
11350             {
11351                ismuted = 0;
11352             }
11353             /* if not transmitting, zero-out audio */
11354             ismuted |= (!myrpt->remotetx);
11355             if (dtmfed && phone_mode) ismuted = 1;
11356             dtmfed = 0;
11357             if (ismuted)
11358             {
11359                memset(f->data,0,f->datalen);
11360                if (myrpt->lastf1)
11361                   memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
11362                if (myrpt->lastf2)
11363                   memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
11364             } 
11365             if (f) f2 = ast_frdup(f);
11366             else f2 = NULL;
11367             f1 = myrpt->lastf2;
11368             myrpt->lastf2 = myrpt->lastf1;
11369             myrpt->lastf1 = f2;
11370             if (ismuted)
11371             {
11372                if (myrpt->lastf1)
11373                   memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
11374                if (myrpt->lastf2)
11375                   memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
11376             }
11377             if (f1)
11378             {
11379                if (phone_mode)
11380                   ast_write(myrpt->txchannel,f1);
11381                else
11382                   ast_write(myrpt->txchannel,f);
11383                ast_frfree(f1);
11384             }
11385          }
11386 #ifndef  OLD_ASTERISK
11387          else if (f->frametype == AST_FRAME_DTMF_BEGIN)
11388          {
11389             if (myrpt->lastf1)
11390                memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
11391             if (myrpt->lastf2)
11392                memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
11393             dtmfed = 1;
11394          }
11395 #endif
11396          if (f->frametype == AST_FRAME_DTMF)
11397          {
11398             if (myrpt->lastf1)
11399                memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
11400             if (myrpt->lastf2)
11401                memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
11402             dtmfed = 1;
11403             if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1)
11404             {
11405                if (debug) printf("@@@@ rpt:Hung Up\n");
11406                ast_frfree(f);
11407                break;
11408             }
11409          }
11410          if (f->frametype == AST_FRAME_TEXT)
11411          {
11412             if (handle_remote_data(myrpt,f->data) == -1)
11413             {
11414                if (debug) printf("@@@@ rpt:Hung Up\n");
11415                ast_frfree(f);
11416                break;
11417             }
11418          }
11419          if (f->frametype == AST_FRAME_CONTROL)
11420          {
11421             if (f->subclass == AST_CONTROL_HANGUP)
11422             {
11423                if (debug) printf("@@@@ rpt:Hung Up\n");
11424                ast_frfree(f);
11425                break;
11426             }
11427             /* if RX key */
11428             if (f->subclass == AST_CONTROL_RADIO_KEY)
11429             {
11430                if (debug == 7) printf("@@@@ rx key\n");
11431                keyed = 1;
11432                myrpt->rerxtimer = 0;
11433             }
11434             /* if RX un-key */
11435             if (f->subclass == AST_CONTROL_RADIO_UNKEY)
11436             {
11437                myrpt->rerxtimer = 0;
11438                if (debug == 7) printf("@@@@ rx un-key\n");
11439                keyed = 0;
11440             }
11441          }
11442          ast_frfree(f);
11443          continue;
11444       }
11445       if (who == myrpt->rxchannel) /* if it was a read from radio */
11446       {
11447          f = ast_read(myrpt->rxchannel);
11448          if (!f)
11449          {
11450             if (debug) printf("@@@@ link:Hung Up\n");
11451             break;
11452          }
11453          if (f->frametype == AST_FRAME_VOICE)
11454          {
11455             int myreming = 0;
11456 
11457             if(!strcmp(myrpt->remote, remote_rig_kenwood))
11458                myreming = reming;
11459 
11460             if (myreming || (!remkeyed) ||
11461             ((myrpt->remote) && (myrpt->remotetx)) ||
11462               ((myrpt->remmode != REM_MODE_FM) &&
11463                 notremming))
11464                memset(f->data,0,f->datalen); 
11465              ast_write(myrpt->pchannel,f);
11466          }
11467          else if (f->frametype == AST_FRAME_CONTROL)
11468          {
11469             if (f->subclass == AST_CONTROL_HANGUP)
11470             {
11471                if (debug) printf("@@@@ rpt:Hung Up\n");
11472                ast_frfree(f);
11473                break;
11474             }
11475             /* if RX key */
11476             if (f->subclass == AST_CONTROL_RADIO_KEY)
11477             {
11478                if (debug == 7) printf("@@@@ remote rx key\n");
11479                if (!myrpt->remotetx)
11480                {
11481                   remkeyed = 1;
11482                }
11483             }
11484             /* if RX un-key */
11485             if (f->subclass == AST_CONTROL_RADIO_UNKEY)
11486             {
11487                if (debug == 7) printf("@@@@ remote rx un-key\n");
11488                if (!myrpt->remotetx) 
11489                {
11490                   remkeyed = 0;
11491                }
11492             }
11493          }
11494          ast_frfree(f);
11495          continue;
11496       }
11497       if (who == myrpt->pchannel) /* if is remote mix output */
11498       {
11499          f = ast_read(myrpt->pchannel);
11500          if (!f)
11501          {
11502             if (debug) printf("@@@@ link:Hung Up\n");
11503             break;
11504          }
11505          if (f->frametype == AST_FRAME_VOICE)
11506          {
11507             ast_write(chan,f);
11508          }
11509          if (f->frametype == AST_FRAME_CONTROL)
11510          {
11511             if (f->subclass == AST_CONTROL_HANGUP)
11512             {
11513                if (debug) printf("@@@@ rpt:Hung Up\n");
11514                ast_frfree(f);
11515                break;
11516             }
11517          }
11518          ast_frfree(f);
11519          continue;
11520       }
11521       if ((myrpt->rxchannel != myrpt->txchannel) && 
11522          (who == myrpt->txchannel)) /* do this cuz you have to */
11523       {
11524          f = ast_read(myrpt->txchannel);
11525          if (!f)
11526          {
11527             if (debug) printf("@@@@ link:Hung Up\n");
11528             break;
11529          }
11530          if (f->frametype == AST_FRAME_CONTROL)
11531          {
11532             if (f->subclass == AST_CONTROL_HANGUP)
11533             {
11534                if (debug) printf("@@@@ rpt:Hung Up\n");
11535                ast_frfree(f);
11536                break;
11537             }
11538          }
11539          ast_frfree(f);
11540          continue;
11541       }
11542    }
11543    if (myrpt->p.archivedir)
11544    {
11545       char mycmd[100],*b,*b1;
11546 
11547       /* look at callerid to see what node this comes from */
11548       if (!chan->cid.cid_num) /* if doesn't have caller id */
11549       {
11550          b1 = "0";
11551       } else {
11552          ast_callerid_parse(chan->cid.cid_num,&b,&b1);
11553          ast_shrink_phone_number(b1);
11554       }
11555       sprintf(mycmd,"DISCONNECT,%s",b1);
11556       donodelog(myrpt,mycmd);
11557    }
11558    /* wait for telem to be done */
11559    while(myrpt->tele.next != &myrpt->tele) usleep(100000);
11560    sprintf(tmp,"mixmonitor stop %s",chan->name);
11561    ast_cli_command(nullfd,tmp);
11562    close(nullfd);
11563    rpt_mutex_lock(&myrpt->lock);
11564    myrpt->hfscanmode = 0;
11565    myrpt->hfscanstatus = 0;
11566    myrpt->remoteon = 0;
11567    rpt_mutex_unlock(&myrpt->lock);
11568    if (myrpt->lastf1) ast_frfree(myrpt->lastf1);
11569    myrpt->lastf1 = NULL;
11570    if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
11571    myrpt->lastf2 = NULL;
11572    if (iskenwood_pci4)
11573    {
11574       z.radpar = ZT_RADPAR_UIOMODE;
11575       z.data = 3;
11576       if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
11577       {
11578          ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
11579          return -1;
11580       }
11581       z.radpar = ZT_RADPAR_UIODATA;
11582       z.data = 3;
11583       if (ioctl(myrpt->txchannel->fds[0],ZT_RADIO_SETPARAM,&z) == -1)
11584       {
11585          ast_log(LOG_ERROR,"Cannot set UIODATA\n");
11586          return -1;
11587       }
11588       i = ZT_OFFHOOK;
11589       if (ioctl(myrpt->txchannel->fds[0],ZT_HOOK,&i) == -1)
11590       {
11591          ast_log(LOG_ERROR,"Cannot set hook\n");
11592          return -1;
11593       }
11594    }
11595    if (myrpt->iofd) close(myrpt->iofd);
11596    myrpt->iofd = -1;
11597    ast_hangup(myrpt->pchannel);
11598    if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel);
11599    ast_hangup(myrpt->rxchannel);
11600    closerem(myrpt);
11601 #ifdef   OLD_ASTERISK
11602    LOCAL_USER_REMOVE(u);
11603 #endif
11604    return res;
11605 }

static void rpt_localtime ( time_t *  t,
struct tm *  lt 
) [static]

Definition at line 1531 of file app_rpt.c.

References ast_localtime(), and localtime_r.

Referenced by do_scheduler(), and rpt_tele_thread().

01532 {
01533 #ifdef OLD_ASTERISK
01534    localtime_r(t, lt);
01535 #else
01536    ast_localtime(t, lt, NULL);
01537 #endif
01538 }

static void* rpt_master ( void *  ignore  )  [static]

Definition at line 10207 of file app_rpt.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_variable_retrieve(), rpt::cfg, free, rpt::ident, rpt::lastthreadrestarttime, load_rpt_vars(), lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, name, rpt::name, nodelog::next, rpt_tele::next, rpt::offset, rpt::powerlevel, rpt_tele::prev, REM_MEDPWR, REM_MODE_FM, REM_SIMPLEX, rpt::remmode, rpt::remote, retreive_memory(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, space, strdup, rpt::tailmessagen, rpt::tele, rpt::threadrestarts, and rpt::txchanname.

Referenced by load_module().

10208 {
10209 int   i,n;
10210 pthread_attr_t attr;
10211 struct ast_config *cfg;
10212 char *this,*val;
10213 
10214    /* init nodelog queue */
10215    nodelog.next = nodelog.prev = &nodelog;
10216    /* go thru all the specified repeaters */
10217    this = NULL;
10218    n = 0;
10219    rpt_vars[n].cfg = ast_config_load("rpt.conf");
10220    cfg = rpt_vars[n].cfg;
10221    if (!cfg) {
10222       ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf.  Radio Repeater disabled.\n");
10223       pthread_exit(NULL);
10224    }
10225    while((this = ast_category_browse(cfg,this)) != NULL)
10226    {
10227       for(i = 0 ; i < strlen(this) ; i++){
10228          if((this[i] < '0') || (this[i] > '9'))
10229             break;
10230       }
10231       if(i != strlen(this)) continue; /* Not a node defn */
10232       memset(&rpt_vars[n],0,sizeof(rpt_vars[n]));
10233       rpt_vars[n].name = strdup(this);
10234       val = (char *) ast_variable_retrieve(cfg,this,"rxchannel");
10235       if (val) rpt_vars[n].rxchanname = strdup(val);
10236       val = (char *) ast_variable_retrieve(cfg,this,"txchannel");
10237       if (val) rpt_vars[n].txchanname = strdup(val);
10238       val = (char *) ast_variable_retrieve(cfg,this,"remote");
10239       if (val) rpt_vars[n].remote = strdup(val);
10240       ast_mutex_init(&rpt_vars[n].lock);
10241       ast_mutex_init(&rpt_vars[n].remlock);
10242       rpt_vars[n].tele.next = &rpt_vars[n].tele;
10243       rpt_vars[n].tele.prev = &rpt_vars[n].tele;
10244       rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
10245       rpt_vars[n].tailmessagen = 0;
10246 #ifdef   _MDC_DECODE_H_
10247       rpt_vars[n].mdc = mdc_decoder_new(8000);
10248 #endif
10249       n++;
10250    }
10251    nrpts = n;
10252    ast_config_destroy(cfg);
10253 
10254    /* start em all */
10255    for(i = 0; i < n; i++)
10256    {
10257       load_rpt_vars(i,1);
10258 
10259       /* if is a remote, dont start one for it */
10260       if (rpt_vars[i].remote)
10261       {
10262          if(retreive_memory(&rpt_vars[i],"init")){ /* Try to retreive initial memory channel */
10263             strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1);
10264             strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1);
10265 
10266             strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1);
10267             rpt_vars[i].remmode = REM_MODE_FM;
10268             rpt_vars[i].offset = REM_SIMPLEX;
10269             rpt_vars[i].powerlevel = REM_MEDPWR;
10270          }
10271          continue;
10272       }
10273       if (!rpt_vars[i].p.ident)
10274       {
10275          ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name);
10276          ast_config_destroy(cfg);
10277          pthread_exit(NULL);
10278       }
10279            pthread_attr_init(&attr);
10280            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
10281       ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
10282    }
10283    usleep(500000);
10284    time(&starttime);
10285    for(;;)
10286    {
10287       /* Now monitor each thread, and restart it if necessary */
10288       for(i = 0; i < n; i++)
10289       { 
10290          int rv;
10291          if (rpt_vars[i].remote) continue;
10292          if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP) 
10293             rv = -1;
10294          else
10295             rv = pthread_kill(rpt_vars[i].rpt_thread,0);
10296          if (rv)
10297          {
10298             if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15)
10299             {
10300                if(rpt_vars[i].threadrestarts >= 5)
10301                {
10302                   ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n");
10303                   exit(1); /* Stuck in a restart loop, kill Asterisk and start over */
10304                }
10305                else
10306                {
10307                   ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name);
10308                   rpt_vars[i].threadrestarts++;
10309                }
10310             }
10311             else
10312                rpt_vars[i].threadrestarts = 0;
10313 
10314             rpt_vars[i].lastthreadrestarttime = time(NULL);
10315                  pthread_attr_init(&attr);
10316                  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
10317             ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
10318             ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name);
10319          }
10320 
10321       }
10322       for(;;)
10323       {
10324          struct nodelog *nodep;
10325          char *space,datestr[100],fname[300];
10326          int fd;
10327 
10328          ast_mutex_lock(&nodeloglock);
10329          nodep = nodelog.next;
10330          if(nodep == &nodelog) /* if nothing in queue */
10331          {
10332             ast_mutex_unlock(&nodeloglock);
10333             break;
10334          }
10335          remque((struct qelem *)nodep);
10336          ast_mutex_unlock(&nodeloglock);
10337          space = strchr(nodep->str,' ');
10338          if (!space) 
10339          {
10340             free(nodep);
10341             continue;
10342          }
10343          *space = 0;
10344          strftime(datestr,sizeof(datestr) - 1,"%Y%m%d",
10345             localtime(&nodep->timestamp));
10346          sprintf(fname,"%s/%s/%s.txt",nodep->archivedir,
10347             nodep->str,datestr);
10348          fd = open(fname,O_WRONLY | O_CREAT | O_APPEND,0600);
10349          if (fd == -1)
10350          {
10351             ast_log(LOG_ERROR,"Cannot open node log file %s for write",space + 1);
10352             free(nodep);
10353             continue;
10354          }
10355          if (write(fd,space + 1,strlen(space + 1)) !=
10356             strlen(space + 1))
10357          {
10358             ast_log(LOG_ERROR,"Cannot write node log file %s for write",space + 1);
10359             free(nodep);
10360             continue;
10361          }
10362          close(fd);
10363          free(nodep);
10364       }
10365       usleep(2000000);
10366    }
10367    ast_config_destroy(cfg);
10368    pthread_exit(NULL);
10369 }

static void* rpt_tele_thread ( void *  this  )  [static]

Definition at line 2857 of file app_rpt.c.

References __mklinklist(), ACT_TIMEOUT_WARNING, ARB_ALPHA, AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_safe_sleep(), ast_say_character_str(), ast_say_digits(), ast_say_number(), ast_say_time, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_tonepair_start(), ast_variable_retrieve(), ast_waitstream(), rpt_tele::chan, COMPLETE, CONNECTED, CONNFAIL, DLY_CALLTERM, DLY_COMP, DLY_ID, DLY_LINKUNKEY, DLY_TELEM, DLY_UNKEY, ast_channel::fds, finddelim(), free, FULLSTATUS, ast_channel::generatordata, get_wait_interval(), rpt_link::hasconnected, ID, ID1, IDTALKOVER, INVFREQ, rpt_link::isremote, LASTNODEKEY, LINKUNKEY, rpt_link::linkunkeytocttimer, LOG_ERROR, LOG_NOTICE, LOG_WARNING, LOGINREQ, MACRO_BUSY, MACRO_NOTFOUND, malloc, MAXLINKLIST, MAXREMSTR, MEMNOTFOUND, rpt_link::mode, rpt_tele::mode, multimode_capable(), mycompar(), rpt_tele::mylink, rpt_link::name, rpt_link::next, rpt_tele::next, rpt_tele::param, play_tone(), rpt_link::prev, PROC, REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, REM_PLUS, REM_SIMPLEX, REMALREADY, REMDISC, REMGO, REMLOGIN, REMLONGSTATUS, REMMODE, REMNOTFOUND, REMSHORTSTATUS, REMXXX, REV_PATCH, rpt_tele::rpt, rpt_localtime(), rpt_mutex_lock, rpt_mutex_unlock, s, saycharstr(), sayfile(), saynum(), SCAN, SCANSTAT, service_scan(), set_ft897(), set_ic706(), set_mode_ft897(), set_mode_ic706(), setkenwood(), setrbi(), SETREMOTE, simple_command_ft897(), split_freq(), STATS_TIME, STATS_VERSION, STATUS, strsep(), rpt_tele::submode, TAILMSG, telem_any(), telem_lookup(), TERM, TEST_TONE, rpt_link::thisconnected, TIMEOUT, TIMEOUT_WARNING, TUNE, UNAUTHTX, UNKEY, and wait_interval().

Referenced by rpt_telemetry().

02858 {
02859 ZT_CONFINFO ci;  /* conference info */
02860 int   res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x;
02861 struct   rpt_tele *mytele = (struct rpt_tele *)this;
02862 struct  rpt_tele *tlist;
02863 struct   rpt *myrpt;
02864 struct   rpt_link *l,*l1,linkbase;
02865 struct   ast_channel *mychannel;
02866 int vmajor, vminor, m;
02867 char *p,*ct,*ct_copy,*ident, *nodename,*cp;
02868 time_t t;
02869 struct tm localtm;
02870 char lbuf[MAXLINKLIST],*strs[MAXLINKLIST];
02871 int   i,ns,rbimode;
02872 char mhz[MAXREMSTR];
02873 char decimals[MAXREMSTR];
02874 struct zt_params par;
02875 
02876 
02877    /* get a pointer to myrpt */
02878    myrpt = mytele->rpt;
02879 
02880    /* Snag copies of a few key myrpt variables */
02881    rpt_mutex_lock(&myrpt->lock);
02882    nodename = ast_strdupa(myrpt->name);
02883    if (myrpt->p.ident) ident = ast_strdupa(myrpt->p.ident);
02884    else ident = "";
02885    rpt_mutex_unlock(&myrpt->lock);
02886    
02887    /* allocate a pseudo-channel thru asterisk */
02888    mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
02889    if (!mychannel)
02890    {
02891       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
02892       rpt_mutex_lock(&myrpt->lock);
02893       remque((struct qelem *)mytele);
02894       ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
02895       rpt_mutex_unlock(&myrpt->lock);
02896       free(mytele);     
02897       pthread_exit(NULL);
02898    }
02899    rpt_mutex_lock(&myrpt->lock);
02900    mytele->chan = mychannel;
02901    rpt_mutex_unlock(&myrpt->lock);
02902    /* make a conference for the tx */
02903    ci.chan = 0;
02904    /* If there's an ID queued, or tail message queued, */
02905    /* only connect the ID audio to the local tx conference so */
02906    /* linked systems can't hear it */
02907    ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) || 
02908       (mytele->mode == TAILMSG) || (mytele->mode == LINKUNKEY)) || (mytele->mode == TIMEOUT) ?
02909          myrpt->txconf : myrpt->conf);
02910    ci.confmode = ZT_CONF_CONFANN;
02911    /* first put the channel on the conference in announce mode */
02912    if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
02913    {
02914       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
02915       rpt_mutex_lock(&myrpt->lock);
02916       remque((struct qelem *)mytele);
02917       rpt_mutex_unlock(&myrpt->lock);
02918       ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
02919       free(mytele);     
02920       ast_hangup(mychannel);
02921       pthread_exit(NULL);
02922    }
02923    ast_stopstream(mychannel);
02924    switch(mytele->mode)
02925    {
02926        case ID:
02927        case ID1:
02928       /* wait a bit */
02929       wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel);
02930       res = telem_any(myrpt,mychannel, ident); 
02931       imdone=1;   
02932       break;
02933       
02934        case TAILMSG:
02935       res = ast_streamfile(mychannel, myrpt->p.tailmessages[myrpt->tailmessagen], mychannel->language); 
02936       break;
02937       
02938        case IDTALKOVER:
02939          p = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "idtalkover");
02940          if(p)
02941          res = telem_any(myrpt,mychannel, p); 
02942       imdone=1;   
02943          break;
02944             
02945        case PROC:
02946       /* wait a little bit longer */
02947       wait_interval(myrpt, DLY_TELEM, mychannel);
02948       res = telem_lookup(myrpt, mychannel, myrpt->name, "patchup");
02949       if(res < 0){ /* Then default message */
02950          res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language);
02951       }
02952       break;
02953        case TERM:
02954       /* wait a little bit longer */
02955       wait_interval(myrpt, DLY_CALLTERM, mychannel);
02956       res = telem_lookup(myrpt, mychannel, myrpt->name, "patchdown");
02957       if(res < 0){ /* Then default message */
02958          res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language);
02959       }
02960       break;
02961        case COMPLETE:
02962       /* wait a little bit */
02963       wait_interval(myrpt, DLY_TELEM, mychannel);
02964       res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
02965       break;
02966        case MACRO_NOTFOUND:
02967       /* wait a little bit */
02968       wait_interval(myrpt, DLY_TELEM, mychannel);
02969       res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language);
02970       break;
02971        case MACRO_BUSY:
02972       /* wait a little bit */
02973       wait_interval(myrpt, DLY_TELEM, mychannel);
02974       res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language);
02975       break;
02976        case UNKEY:
02977       if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */
02978          imdone = 1;
02979          break;
02980       }
02981          
02982       /*
02983       * Reset the Unkey to CT timer
02984       */
02985 
02986       x = get_wait_interval(myrpt, DLY_UNKEY);
02987       rpt_mutex_lock(&myrpt->lock);
02988       myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */
02989       rpt_mutex_unlock(&myrpt->lock);
02990 
02991       /*
02992       * If there's one already queued, don't do another
02993       */
02994 
02995       tlist = myrpt->tele.next;
02996       unkeys_queued = 0;
02997                 if (tlist != &myrpt->tele)
02998                 {
02999                         rpt_mutex_lock(&myrpt->lock);
03000                         while(tlist != &myrpt->tele){
03001                                 if (tlist->mode == UNKEY) unkeys_queued++;
03002                                 tlist = tlist->next;
03003                         }
03004                         rpt_mutex_unlock(&myrpt->lock);
03005       }
03006       if( unkeys_queued > 1){
03007          imdone = 1;
03008          break;
03009       }
03010 
03011       /* Wait for the telemetry timer to expire */
03012       /* Periodically check the timer since it can be re-initialized above */
03013       while(myrpt->unkeytocttimer)
03014       {
03015          int ctint;
03016          if(myrpt->unkeytocttimer > 100)
03017             ctint = 100;
03018          else
03019             ctint = myrpt->unkeytocttimer;
03020          ast_safe_sleep(mychannel, ctint);
03021          rpt_mutex_lock(&myrpt->lock);
03022          if(myrpt->unkeytocttimer < ctint)
03023             myrpt->unkeytocttimer = 0;
03024          else
03025             myrpt->unkeytocttimer -= ctint;
03026          rpt_mutex_unlock(&myrpt->lock);
03027       }
03028    
03029       /*
03030       * Now, the carrier on the rptr rx should be gone. 
03031       * If it re-appeared, then forget about sending the CT
03032       */
03033       if(myrpt->keyed){
03034          imdone = 1;
03035          break;
03036       }
03037       
03038       rpt_mutex_lock(&myrpt->lock); /* Update the kerchunk counters */
03039       myrpt->dailykerchunks++;
03040       myrpt->totalkerchunks++;
03041       rpt_mutex_unlock(&myrpt->lock);
03042    
03043       haslink = 0;
03044       hastx = 0;
03045       hasremote = 0;    
03046       l = myrpt->links.next;
03047       if (l != &myrpt->links)
03048       {
03049          rpt_mutex_lock(&myrpt->lock);
03050          while(l != &myrpt->links)
03051          {
03052             if (l->name[0] == '0')
03053             {
03054                l = l->next;
03055                continue;
03056             }
03057             haslink = 1;
03058             if (l->mode) {
03059                hastx++;
03060                if (l->isremote) hasremote++;
03061             }
03062             l = l->next;
03063          }
03064          rpt_mutex_unlock(&myrpt->lock);
03065       }
03066       if (haslink)
03067       {
03068 
03069          res = telem_lookup(myrpt,mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx");
03070          if(res)
03071             ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name);
03072          
03073       
03074          /* if in remote cmd mode, indicate it */
03075          if (myrpt->cmdnode[0])
03076          {
03077             ast_safe_sleep(mychannel,200);
03078             res = telem_lookup(myrpt,mychannel, myrpt->name, "cmdmode");
03079             if(res)
03080                ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name);
03081             ast_stopstream(mychannel);
03082          }
03083       }
03084       else if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */
03085          ct_copy = ast_strdupa(ct);
03086          res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
03087          if(res)
03088             ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);     
03089       }  
03090       if (hasremote && (!myrpt->cmdnode[0]))
03091       {
03092          /* set for all to hear */
03093          ci.chan = 0;
03094          ci.confno = myrpt->conf;
03095          ci.confmode = ZT_CONF_CONFANN;
03096          /* first put the channel on the conference in announce mode */
03097          if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
03098          {
03099             ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
03100             rpt_mutex_lock(&myrpt->lock);
03101             remque((struct qelem *)mytele);
03102             rpt_mutex_unlock(&myrpt->lock);
03103             ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
03104             free(mytele);     
03105             ast_hangup(mychannel);
03106             pthread_exit(NULL);
03107          }
03108          if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */
03109             ast_safe_sleep(mychannel,200);
03110             ct_copy = ast_strdupa(ct);
03111             res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
03112             if(res)
03113                ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);     
03114          }  
03115       }
03116 #ifdef   _MDC_DECODE_H_
03117       if (myrpt->lastunit)
03118       {
03119          char mystr[10];
03120 
03121          ast_safe_sleep(mychannel,200);
03122          /* set for all to hear */
03123          ci.chan = 0;
03124          ci.confno = myrpt->txconf;
03125          ci.confmode = ZT_CONF_CONFANN;
03126          /* first put the channel on the conference in announce mode */
03127          if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1)
03128          {
03129             ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
03130             rpt_mutex_lock(&myrpt->lock);
03131             remque((struct qelem *)mytele);
03132             rpt_mutex_unlock(&myrpt->lock);
03133             ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
03134             free(mytele);     
03135             ast_hangup(mychannel);
03136             pthread_exit(NULL);
03137          }
03138          sprintf(mystr,"%04x",myrpt->lastunit);
03139          myrpt->lastunit = 0;
03140          ast_say_character_str(mychannel,mystr,NULL,mychannel->language);
03141          break;
03142       }
03143 #endif
03144       imdone = 1;
03145       break;
03146        case LINKUNKEY:
03147       if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */
03148          imdone = 1;
03149          break;
03150       }
03151          
03152       /*
03153       * Reset the Unkey to CT timer
03154       */
03155 
03156       x = get_wait_interval(myrpt, DLY_LINKUNKEY);
03157       mytele->mylink.linkunkeytocttimer = x; /* Must be protected as it is changed below */
03158 
03159       /*
03160       * If there's one already queued, don't do another
03161       */
03162 
03163       tlist = myrpt->tele.next;
03164       unkeys_queued = 0;
03165                 if (tlist != &myrpt->tele)
03166                 {
03167                         rpt_mutex_lock(&myrpt->lock);
03168                         while(tlist != &myrpt->tele){
03169                                 if (tlist->mode == LINKUNKEY) unkeys_queued++;
03170                                 tlist = tlist->next;
03171                         }
03172                         rpt_mutex_unlock(&myrpt->lock);
03173       }
03174       if( unkeys_queued > 1){
03175          imdone = 1;
03176          break;
03177       }
03178 
03179       /* Wait for the telemetry timer to expire */
03180       /* Periodically check the timer since it can be re-initialized above */
03181       while(mytele->mylink.linkunkeytocttimer)
03182       {
03183          int ctint;
03184          if(mytele->mylink.linkunkeytocttimer > 100)
03185             ctint = 100;
03186          else
03187             ctint = mytele->mylink.linkunkeytocttimer;
03188          ast_safe_sleep(mychannel, ctint);
03189          rpt_mutex_lock(&myrpt->lock);
03190          if(mytele->mylink.linkunkeytocttimer < ctint)
03191             mytele->mylink.linkunkeytocttimer = 0;
03192          else
03193             mytele->mylink.linkunkeytocttimer -= ctint;
03194          rpt_mutex_unlock(&myrpt->lock);
03195       }
03196    
03197       if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "linkunkeyct"))){ /* Unlinked Courtesy Tone */
03198          ct_copy = ast_strdupa(ct);
03199          res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
03200          if(res)
03201             ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);     
03202       }  
03203       imdone = 1;
03204       break;
03205        case REMDISC:
03206       /* wait a little bit */
03207       wait_interval(myrpt, DLY_TELEM, mychannel);
03208       l = myrpt->links.next;
03209       haslink = 0;
03210       /* dont report if a link for this one still on system */
03211       if (l != &myrpt->links)
03212       {
03213          rpt_mutex_lock(&myrpt->lock);
03214          while(l != &myrpt->links)
03215          {
03216             if (l->name[0] == '0')
03217             {
03218                l = l->next;
03219                continue;
03220             }
03221             if (!strcmp(l->name,mytele->mylink.name))
03222             {
03223                haslink = 1;
03224                break;
03225             }
03226             l = l->next;
03227          }
03228          rpt_mutex_unlock(&myrpt->lock);
03229       }
03230       if (haslink)
03231       {
03232          imdone = 1;
03233          break;
03234       }
03235       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03236       if (!res) 
03237          res = ast_waitstream(mychannel, "");
03238       else
03239           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03240       ast_stopstream(mychannel);
03241       ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
03242       res = ast_streamfile(mychannel, ((mytele->mylink.hasconnected) ? 
03243          "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language);
03244       break;
03245        case REMALREADY:
03246       /* wait a little bit */
03247       wait_interval(myrpt, DLY_TELEM, mychannel);
03248       res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language);
03249       break;
03250        case REMNOTFOUND:
03251       /* wait a little bit */
03252       wait_interval(myrpt, DLY_TELEM, mychannel);
03253       res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language);
03254       break;
03255        case REMGO:
03256       /* wait a little bit */
03257       wait_interval(myrpt, DLY_TELEM, mychannel);
03258       res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language);
03259       break;
03260        case CONNECTED:
03261       /* wait a little bit */
03262       wait_interval(myrpt, DLY_TELEM,  mychannel);
03263       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03264       if (!res) 
03265          res = ast_waitstream(mychannel, "");
03266       else
03267           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03268       ast_stopstream(mychannel);
03269       ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
03270       res = ast_streamfile(mychannel, "rpt/connected", mychannel->language);
03271       if (!res) 
03272          res = ast_waitstream(mychannel, "");
03273       else
03274           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03275       ast_stopstream(mychannel);
03276       res = ast_streamfile(mychannel, "digits/2", mychannel->language);
03277       if (!res) 
03278          res = ast_waitstream(mychannel, "");
03279       else
03280           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03281       ast_stopstream(mychannel);
03282       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03283       if (!res) 
03284          res = ast_waitstream(mychannel, "");
03285       else
03286           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03287       ast_stopstream(mychannel);
03288       ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
03289       imdone = 1;
03290       break;
03291        case CONNFAIL:
03292       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03293       if (!res) 
03294          res = ast_waitstream(mychannel, "");
03295       else
03296           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03297       ast_stopstream(mychannel);
03298       ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language);
03299       res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language);
03300       break;
03301        case MEMNOTFOUND:
03302       /* wait a little bit */
03303       wait_interval(myrpt, DLY_TELEM, mychannel);
03304       res = ast_streamfile(mychannel, "rpt/memory_notfound", mychannel->language);
03305       break;
03306        case SETREMOTE:
03307       ast_mutex_lock(&myrpt->remlock);
03308       res = 0;
03309       if(!strcmp(myrpt->remote, remote_rig_ft897))
03310       {
03311          res = set_ft897(myrpt);
03312       }
03313       if(!strcmp(myrpt->remote, remote_rig_ic706))
03314       {
03315          res = set_ic706(myrpt);
03316       }
03317       else if(!strcmp(myrpt->remote, remote_rig_rbi))
03318       {
03319          if (ioperm(myrpt->p.iobase,1,1) == -1)
03320          {
03321             rpt_mutex_unlock(&myrpt->lock);
03322             ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase);
03323             res = -1;
03324          }
03325          else res = setrbi(myrpt);
03326       }
03327       else if(!strcmp(myrpt->remote, remote_rig_kenwood))
03328       {
03329          res = setkenwood(myrpt);
03330          if (ast_safe_sleep(mychannel,200) == -1)
03331          {
03332             ast_mutex_unlock(&myrpt->remlock);
03333             res = -1;
03334             break;
03335          }
03336          i = ZT_FLUSH_EVENT;
03337          if (ioctl(myrpt->txchannel->fds[0],ZT_FLUSH,&i) == -1)
03338          {
03339             ast_mutex_unlock(&myrpt->remlock);
03340             ast_log(LOG_ERROR,"Cant flush events");
03341             res = -1;
03342             break;
03343          }
03344          if (ioctl(myrpt->rxchannel->fds[0],ZT_GET_PARAMS,&par) == -1)
03345          {
03346             ast_mutex_unlock(&myrpt->remlock);
03347             ast_log(LOG_ERROR,"Cant get params");
03348             res = -1;
03349             break;
03350          }
03351          myrpt->remoterx = 
03352             (par.rxisoffhook || (myrpt->tele.next != &myrpt->tele));
03353       }
03354       ast_mutex_unlock(&myrpt->remlock);
03355       if (!res)
03356       {
03357          imdone = 1;
03358          break;
03359       }
03360       /* fall thru to invalid freq */
03361        case INVFREQ:
03362       /* wait a little bit */
03363       wait_interval(myrpt, DLY_TELEM, mychannel);
03364       res = ast_streamfile(mychannel, "rpt/invalid-freq", mychannel->language);
03365       break;
03366        case REMMODE:
03367       cp = 0;
03368       wait_interval(myrpt, DLY_TELEM, mychannel);
03369       switch(myrpt->remmode)
03370       {
03371           case REM_MODE_FM:
03372          saycharstr(mychannel,"FM");
03373          break;
03374           case REM_MODE_USB:
03375          saycharstr(mychannel,"USB");
03376          break;
03377           case REM_MODE_LSB:
03378          saycharstr(mychannel,"LSB");
03379          break;
03380           case REM_MODE_AM:
03381          saycharstr(mychannel,"AM");
03382          break;
03383       }
03384       wait_interval(myrpt, DLY_COMP, mychannel);
03385       if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
03386       break;
03387        case LOGINREQ:
03388       wait_interval(myrpt, DLY_TELEM, mychannel);
03389       sayfile(mychannel,"rpt/login");
03390       saycharstr(mychannel,myrpt->name);
03391       break;
03392        case REMLOGIN:
03393       wait_interval(myrpt, DLY_TELEM, mychannel);
03394       saycharstr(mychannel,myrpt->loginuser);
03395       sayfile(mychannel,"rpt/node");
03396       saycharstr(mychannel,myrpt->name);
03397       wait_interval(myrpt, DLY_COMP, mychannel);
03398       if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
03399       break;
03400        case REMXXX:
03401       wait_interval(myrpt, DLY_TELEM, mychannel);
03402       res = 0;
03403       switch(mytele->submode)
03404       {
03405           case 100: /* RX PL Off */
03406          sayfile(mychannel, "rpt/rxpl");
03407          sayfile(mychannel, "rpt/off");
03408          break;
03409           case 101: /* RX PL On */
03410          sayfile(mychannel, "rpt/rxpl");
03411          sayfile(mychannel, "rpt/on");
03412          break;
03413           case 102: /* TX PL Off */
03414          sayfile(mychannel, "rpt/txpl");
03415          sayfile(mychannel, "rpt/off");
03416          break;
03417           case 103: /* TX PL On */
03418          sayfile(mychannel, "rpt/txpl");
03419          sayfile(mychannel, "rpt/on");
03420          break;
03421           case 104: /* Low Power */
03422          sayfile(mychannel, "rpt/lopwr");
03423          break;
03424           case 105: /* Medium Power */
03425          sayfile(mychannel, "rpt/medpwr");
03426          break;
03427           case 106: /* Hi Power */
03428          sayfile(mychannel, "rpt/hipwr");
03429          break;
03430           case 113: /* Scan down slow */
03431          sayfile(mychannel,"rpt/down");
03432          sayfile(mychannel, "rpt/slow");
03433          break;
03434           case 114: /* Scan down quick */
03435          sayfile(mychannel,"rpt/down");
03436          sayfile(mychannel, "rpt/quick");
03437          break;
03438           case 115: /* Scan down fast */
03439          sayfile(mychannel,"rpt/down");
03440          sayfile(mychannel, "rpt/fast");
03441          break;
03442           case 116: /* Scan up slow */
03443          sayfile(mychannel,"rpt/up");
03444          sayfile(mychannel, "rpt/slow");
03445          break;
03446           case 117: /* Scan up quick */
03447          sayfile(mychannel,"rpt/up");
03448          sayfile(mychannel, "rpt/quick");
03449          break;
03450           case 118: /* Scan up fast */
03451          sayfile(mychannel,"rpt/up");
03452          sayfile(mychannel, "rpt/fast");
03453          break;
03454           default:
03455          res = -1;
03456       }
03457       wait_interval(myrpt, DLY_COMP, mychannel);
03458       if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
03459       break;
03460        case SCAN:
03461       ast_mutex_lock(&myrpt->remlock);
03462       if (myrpt->hfscanstop)
03463       {
03464          myrpt->hfscanstatus = 0;
03465          myrpt->hfscanmode = 0;
03466          myrpt->hfscanstop = 0;
03467          mytele->mode = SCANSTAT;
03468          ast_mutex_unlock(&myrpt->remlock);
03469          if (ast_safe_sleep(mychannel,1000) == -1) break;
03470          sayfile(mychannel, "rpt/stop"); 
03471          imdone = 1;
03472          break;
03473       }
03474       if (myrpt->hfscanstatus > -2) service_scan(myrpt);
03475       i = myrpt->hfscanstatus;
03476       myrpt->hfscanstatus = 0;
03477       if (i) mytele->mode = SCANSTAT;
03478       ast_mutex_unlock(&myrpt->remlock);
03479       if (i < 0) sayfile(mychannel, "rpt/stop"); 
03480       else if (i > 0) saynum(mychannel,i);
03481       imdone = 1;
03482       break;
03483        case TUNE:
03484       ast_mutex_lock(&myrpt->remlock);
03485       if (!strcmp(myrpt->remote,remote_rig_ic706))
03486       {
03487          set_mode_ic706(myrpt, REM_MODE_AM);
03488          if(play_tone(mychannel, 800, 6000, 8192) == -1) break;
03489          ast_safe_sleep(mychannel,500);
03490          set_mode_ic706(myrpt, myrpt->remmode);
03491          myrpt->tunerequest = 0;
03492          ast_mutex_unlock(&myrpt->remlock);
03493          imdone = 1;
03494          break;
03495       }
03496       set_mode_ft897(myrpt, REM_MODE_AM);
03497       simple_command_ft897(myrpt, 8);
03498       if(play_tone(mychannel, 800, 6000, 8192) == -1) break;
03499       simple_command_ft897(myrpt, 0x88);
03500       ast_safe_sleep(mychannel,500);
03501       set_mode_ft897(myrpt, myrpt->remmode);
03502       myrpt->tunerequest = 0;
03503       ast_mutex_unlock(&myrpt->remlock);
03504       imdone = 1;
03505       break;
03506        case REMSHORTSTATUS:
03507        case REMLONGSTATUS: 
03508       wait_interval(myrpt, DLY_TELEM, mychannel);
03509       res = sayfile(mychannel,"rpt/node");
03510       if(!res)
03511          res = saycharstr(mychannel, myrpt->name);
03512       if(!res)
03513          res = sayfile(mychannel,"rpt/frequency");
03514       if(!res)
03515          res = split_freq(mhz, decimals, myrpt->freq);
03516       if (!multimode_capable(myrpt)) decimals[3] = 0;
03517       if(!res){
03518          m = atoi(mhz);
03519          if(m < 100)
03520             res = saynum(mychannel, m);
03521          else
03522             res = saycharstr(mychannel, mhz);
03523       }
03524       if(!res)
03525          res = sayfile(mychannel, "letters/dot");
03526       if(!res)
03527          res = saycharstr(mychannel, decimals);
03528    
03529       if(res)  break;
03530       if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */
03531          switch(myrpt->offset){
03532    
03533             case REM_MINUS:
03534                res = sayfile(mychannel,"rpt/minus");
03535                break;
03536             
03537             case REM_SIMPLEX:
03538                res = sayfile(mychannel,"rpt/simplex");
03539                break;
03540                
03541             case REM_PLUS:
03542                res = sayfile(mychannel,"rpt/plus");
03543                break;
03544                
03545             default:
03546                break;
03547          }
03548       }
03549       else{ /* Must be USB, LSB, or AM */
03550          switch(myrpt->remmode){
03551 
03552             case REM_MODE_USB:
03553                res = saycharstr(mychannel, "USB");
03554                break;
03555 
03556             case REM_MODE_LSB:
03557                res = saycharstr(mychannel, "LSB");
03558                break;
03559 
03560             case REM_MODE_AM:
03561                res = saycharstr(mychannel, "AM");
03562                break;
03563 
03564 
03565             default:
03566                break;
03567          }
03568       }
03569 
03570       if (res == -1) break;
03571 
03572       if(mytele->mode == REMSHORTSTATUS){ /* Short status? */
03573          wait_interval(myrpt, DLY_COMP, mychannel);
03574          if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
03575          break;
03576       }
03577 
03578       if (strcmp(myrpt->remote,remote_rig_ic706))
03579       {
03580          switch(myrpt->powerlevel){
03581 
03582             case REM_LOWPWR:
03583                res = sayfile(mychannel,"rpt/lopwr") ;
03584                break;
03585             case REM_MEDPWR:
03586                res = sayfile(mychannel,"rpt/medpwr");
03587                break;
03588             case REM_HIPWR:
03589                res = sayfile(mychannel,"rpt/hipwr"); 
03590                break;
03591             }
03592       }
03593 
03594       rbimode = ((!strncmp(myrpt->remote,remote_rig_rbi,3))
03595         || (!strncmp(myrpt->remote,remote_rig_ic706,3)));
03596       if (res || (sayfile(mychannel,"rpt/rxpl") == -1)) break;
03597       if (rbimode && (sayfile(mychannel,"rpt/txpl") == -1)) break;
03598       if ((sayfile(mychannel,"rpt/frequency") == -1) ||
03599          (saycharstr(mychannel,myrpt->rxpl) == -1)) break;
03600       if ((!rbimode) && ((sayfile(mychannel,"rpt/txpl") == -1) ||
03601          (sayfile(mychannel,"rpt/frequency") == -1) ||
03602          (saycharstr(mychannel,myrpt->txpl) == -1))) break;
03603       if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */
03604          if ((sayfile(mychannel,"rpt/rxpl") == -1) ||
03605             (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1) ||
03606             (sayfile(mychannel,"rpt/txpl") == -1) ||
03607             (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1))
03608             {
03609                break;
03610             }
03611       }
03612       wait_interval(myrpt, DLY_COMP, mychannel);
03613       if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
03614       break;
03615        case STATUS:
03616       /* wait a little bit */
03617       wait_interval(myrpt, DLY_TELEM, mychannel);
03618       hastx = 0;
03619       linkbase.next = &linkbase;
03620       linkbase.prev = &linkbase;
03621       rpt_mutex_lock(&myrpt->lock);
03622       /* make our own list of links */
03623       l = myrpt->links.next;
03624       while(l != &myrpt->links)
03625       {
03626          if (l->name[0] == '0')
03627          {
03628             l = l->next;
03629             continue;
03630          }
03631          l1 = malloc(sizeof(struct rpt_link));
03632          if (!l1)
03633          {
03634             ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name);
03635             remque((struct qelem *)mytele);
03636             rpt_mutex_unlock(&myrpt->lock);
03637             ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
03638             free(mytele);     
03639             ast_hangup(mychannel);
03640             pthread_exit(NULL);
03641          }
03642          memcpy(l1,l,sizeof(struct rpt_link));
03643          l1->next = l1->prev = NULL;
03644          insque((struct qelem *)l1,(struct qelem *)linkbase.next);
03645          l = l->next;
03646       }
03647       rpt_mutex_unlock(&myrpt->lock);
03648       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03649       if (!res) 
03650          res = ast_waitstream(mychannel, "");
03651       else
03652           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03653       ast_stopstream(mychannel);
03654       ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
03655       if (!res) 
03656          res = ast_waitstream(mychannel, "");
03657       else
03658           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03659       ast_stopstream(mychannel);
03660       if (myrpt->callmode)
03661       {
03662          hastx = 1;
03663          res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language);
03664          if (!res) 
03665             res = ast_waitstream(mychannel, "");
03666          else
03667              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03668          ast_stopstream(mychannel);
03669       }
03670       l = linkbase.next;
03671       while(l != &linkbase)
03672       {
03673          char *s;
03674 
03675          hastx = 1;
03676          res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03677          if (!res) 
03678             res = ast_waitstream(mychannel, "");
03679          else
03680             ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03681          ast_stopstream(mychannel);
03682          ast_say_character_str(mychannel,l->name,NULL,mychannel->language);
03683          if (!res) 
03684             res = ast_waitstream(mychannel, "");
03685          else
03686              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03687          ast_stopstream(mychannel);
03688          s = "rpt/tranceive";
03689          if (!l->mode) s = "rpt/monitor";
03690          if (!l->thisconnected) s = "rpt/connecting";
03691          res = ast_streamfile(mychannel, s, mychannel->language);
03692          if (!res) 
03693             res = ast_waitstream(mychannel, "");
03694          else
03695             ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03696          ast_stopstream(mychannel);
03697          l = l->next;
03698       }        
03699       if (!hastx)
03700       {
03701          res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language);
03702          if (!res) 
03703             res = ast_waitstream(mychannel, "");
03704          else
03705              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03706          ast_stopstream(mychannel);
03707       }
03708       /* destroy our local link queue */
03709       l = linkbase.next;
03710       while(l != &linkbase)
03711       {
03712          l1 = l;
03713          l = l->next;
03714          remque((struct qelem *)l1);
03715          free(l1);
03716       }        
03717       imdone = 1;
03718       break;
03719        case FULLSTATUS:
03720       rpt_mutex_lock(&myrpt->lock);
03721       /* get all the nodes */
03722       __mklinklist(myrpt,NULL,lbuf);
03723       rpt_mutex_unlock(&myrpt->lock);
03724       /* parse em */
03725       ns = finddelim(lbuf,strs,MAXLINKLIST);
03726       /* sort em */
03727       if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar);
03728       /* wait a little bit */
03729       wait_interval(myrpt, DLY_TELEM, mychannel);
03730       hastx = 0;
03731       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03732       if (!res) 
03733          res = ast_waitstream(mychannel, "");
03734       else
03735           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03736       ast_stopstream(mychannel);
03737       ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
03738       if (!res) 
03739          res = ast_waitstream(mychannel, "");
03740       else
03741           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03742       ast_stopstream(mychannel);
03743       if (myrpt->callmode)
03744       {
03745          hastx = 1;
03746          res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language);
03747          if (!res) 
03748             res = ast_waitstream(mychannel, "");
03749          else
03750              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03751          ast_stopstream(mychannel);
03752       }
03753       /* go thru all the nodes in list */
03754       for(i = 0; i < ns; i++)
03755       {
03756          char *s,mode = 'T';
03757 
03758          /* if a mode spec at first, handle it */
03759          if ((*strs[i] < '0') || (*strs[i] > '9'))
03760          {
03761             mode = *strs[i];
03762             strs[i]++;
03763          }
03764 
03765          hastx = 1;
03766          res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03767          if (!res) 
03768             res = ast_waitstream(mychannel, "");
03769          else
03770             ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03771          ast_stopstream(mychannel);
03772          ast_say_character_str(mychannel,strs[i],NULL,mychannel->language);
03773          if (!res) 
03774             res = ast_waitstream(mychannel, "");
03775          else
03776              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03777          ast_stopstream(mychannel);
03778          s = "rpt/tranceive";
03779          if (mode == 'R') s = "rpt/monitor";
03780          if (mode == 'C') s = "rpt/connecting";
03781          res = ast_streamfile(mychannel, s, mychannel->language);
03782          if (!res) 
03783             res = ast_waitstream(mychannel, "");
03784          else
03785             ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03786          ast_stopstream(mychannel);
03787       }        
03788       if (!hastx)
03789       {
03790          res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language);
03791          if (!res) 
03792             res = ast_waitstream(mychannel, "");
03793          else
03794              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03795          ast_stopstream(mychannel);
03796       }
03797       imdone = 1;
03798       break;
03799 
03800        case LASTNODEKEY: /* Identify last node which keyed us up */
03801       rpt_mutex_lock(&myrpt->lock);
03802       if(myrpt->lastnodewhichkeyedusup)
03803          p = ast_strdupa(myrpt->lastnodewhichkeyedusup); /* Make a local copy of the node name */
03804       else
03805          p = NULL;
03806       rpt_mutex_unlock(&myrpt->lock);
03807       if(!p){
03808          imdone = 1; /* no node previously keyed us up, or the node which did has been disconnected */
03809          break;
03810       }
03811       wait_interval(myrpt, DLY_TELEM, mychannel);
03812       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03813       if (!res) 
03814          res = ast_waitstream(mychannel, "");
03815       else
03816           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03817       ast_stopstream(mychannel);
03818       ast_say_character_str(mychannel, p, NULL, mychannel->language);
03819       if (!res) 
03820          res = ast_waitstream(mychannel, "");
03821       else
03822          ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03823       ast_stopstream(mychannel);
03824       imdone = 1;
03825       break;      
03826 
03827        case UNAUTHTX: /* Say unauthorized transmit frequency */
03828       wait_interval(myrpt, DLY_TELEM, mychannel);
03829       res = ast_streamfile(mychannel, "rpt/unauthtx", mychannel->language);
03830       if (!res) 
03831          res = ast_waitstream(mychannel, "");
03832       else
03833           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03834       ast_stopstream(mychannel);
03835       imdone = 1;
03836       break;
03837       
03838 
03839        case TIMEOUT:
03840       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03841       if (!res) 
03842          res = ast_waitstream(mychannel, "");
03843       else
03844           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03845       ast_stopstream(mychannel);
03846       ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
03847       res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language);
03848       break;
03849       
03850        case TIMEOUT_WARNING:
03851       time(&t);
03852       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03853       if (!res) 
03854          res = ast_waitstream(mychannel, "");
03855       else
03856           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03857       ast_stopstream(mychannel);
03858       ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
03859       res = ast_streamfile(mychannel, "rpt/timeout-warning", mychannel->language);
03860       if (!res) 
03861          res = ast_waitstream(mychannel, "");
03862       else
03863           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03864       ast_stopstream(mychannel);
03865       if(!res) /* Say number of seconds */
03866          ast_say_number(mychannel, myrpt->p.remotetimeout - 
03867              (t - myrpt->last_activity_time), 
03868             "", mychannel->language, (char *) NULL);
03869       if (!res) 
03870          res = ast_waitstream(mychannel, "");
03871       ast_stopstream(mychannel); 
03872       res = ast_streamfile(mychannel, "queue-seconds", mychannel->language);
03873       break;
03874 
03875        case ACT_TIMEOUT_WARNING:
03876       time(&t);
03877       res = ast_streamfile(mychannel, "rpt/node", mychannel->language);
03878       if (!res) 
03879          res = ast_waitstream(mychannel, "");
03880       else
03881           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03882       ast_stopstream(mychannel);
03883       ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language);
03884       res = ast_streamfile(mychannel, "rpt/act-timeout-warning", mychannel->language);
03885       if (!res) 
03886          res = ast_waitstream(mychannel, "");
03887       else
03888           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03889       ast_stopstream(mychannel);
03890       if(!res) /* Say number of seconds */
03891          ast_say_number(mychannel, myrpt->p.remoteinacttimeout - 
03892              (t - myrpt->last_activity_time), 
03893             "", mychannel->language, (char *) NULL);
03894       if (!res) 
03895          res = ast_waitstream(mychannel, "");
03896       ast_stopstream(mychannel); 
03897       res = ast_streamfile(mychannel, "queue-seconds", mychannel->language);
03898       break;
03899       
03900        case STATS_TIME:
03901          wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
03902       t = time(NULL);
03903       rpt_localtime(&t, &localtm);
03904       /* Say the phase of the day is before the time */
03905       if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12))
03906          p = "rpt/goodmorning";
03907       else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18))
03908          p = "rpt/goodafternoon";
03909       else
03910          p = "rpt/goodevening";
03911       if (sayfile(mychannel,p) == -1)
03912       {
03913          imdone = 1;
03914          break;
03915       }
03916       /* Say the time is ... */     
03917       if (sayfile(mychannel,"rpt/thetimeis") == -1)
03918       {
03919          imdone = 1;
03920          break;
03921       }
03922       /* Say the time */            
03923          res = ast_say_time(mychannel, t, "", mychannel->language);
03924       if (!res) 
03925          res = ast_waitstream(mychannel, "");
03926       ast_stopstream(mychannel);    
03927       imdone = 1;
03928          break;
03929        case STATS_VERSION:
03930       p = strstr(tdesc, "version"); 
03931       if(!p)
03932          break;   
03933       if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2)
03934          break;
03935          wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
03936       /* Say "version" */
03937       if (sayfile(mychannel,"rpt/version") == -1)
03938       {
03939          imdone = 1;
03940          break;
03941       }
03942       if(!res) /* Say "X" */
03943          ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL);
03944       if (!res) 
03945          res = ast_waitstream(mychannel, "");
03946       ast_stopstream(mychannel); 
03947       if (saycharstr(mychannel,".") == -1)
03948       {
03949          imdone = 1;
03950          break;
03951       }
03952       if(!res) /* Say "Y" */
03953          ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL);
03954       if (!res){
03955          res = ast_waitstream(mychannel, "");
03956          ast_stopstream(mychannel);
03957       }  
03958       else
03959           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03960       imdone = 1;
03961          break;
03962        case ARB_ALPHA:
03963          wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
03964          if(mytele->param)
03965             saycharstr(mychannel, mytele->param);
03966          imdone = 1;
03967       break;
03968        case REV_PATCH:
03969          wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
03970          if(mytele->param) {
03971 
03972          /* Parts of this section taken from app_parkandannounce */
03973          char *tpl_working, *tpl_current;
03974          char *tmp[100], *myparm;
03975          int looptemp=0,i=0, dres = 0;
03976    
03977 
03978          tpl_working = strdupa(mytele->param);
03979          myparm = strsep(&tpl_working,",");
03980          tpl_current=strsep(&tpl_working, ":");
03981 
03982          while(tpl_current && looptemp < sizeof(tmp)) {
03983             tmp[looptemp]=tpl_current;
03984             looptemp++;
03985             tpl_current=strsep(&tpl_working,":");
03986          }
03987 
03988          for(i=0; i<looptemp; i++) {
03989             if(!strcmp(tmp[i], "PARKED")) {
03990                ast_say_digits(mychannel, atoi(myparm), "", mychannel->language);
03991             } else if(!strcmp(tmp[i], "NODE")) {
03992                ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language);
03993             } else {
03994                dres = ast_streamfile(mychannel, tmp[i], mychannel->language);
03995                if(!dres) {
03996                   dres = ast_waitstream(mychannel, "");
03997                } else {
03998                   ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name);
03999                   dres = 0;
04000                }
04001             }
04002          }
04003       }
04004          imdone = 1;
04005       break;
04006        case TEST_TONE:
04007       imdone = 1;
04008       if (myrpt->stopgen) break;
04009       myrpt->stopgen = -1;
04010            if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0))) 
04011       {
04012          myrpt->stopgen = 0;
04013          break;
04014       }
04015            while(mychannel->generatordata && (myrpt->stopgen <= 0)) {
04016          if (ast_safe_sleep(mychannel,1)) break;
04017             imdone = 1;
04018          }
04019       myrpt->stopgen = 0;
04020       break;
04021        default:
04022          break;
04023    }
04024    if (!imdone)
04025    {
04026       if (!res) 
04027          res = ast_waitstream(mychannel, "");
04028       else {
04029          ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04030          res = 0;
04031       }
04032    }
04033    ast_stopstream(mychannel);
04034    rpt_mutex_lock(&myrpt->lock);
04035    if (mytele->mode == TAILMSG)
04036    {
04037       if (!res)
04038       {
04039          myrpt->tailmessagen++;
04040          if(myrpt->tailmessagen >= myrpt->p.tailmessagemax) myrpt->tailmessagen = 0;
04041       }
04042       else
04043       {
04044          myrpt->tmsgtimer = myrpt->p.tailsquashedtime;
04045       }
04046    }
04047    remque((struct qelem *)mytele);
04048    rpt_mutex_unlock(&myrpt->lock);
04049    free(mytele);     
04050    ast_hangup(mychannel);
04051 #ifdef  APP_RPT_LOCK_DEBUG
04052    {
04053       struct lockthread *t;
04054 
04055       sleep(5);
04056       ast_mutex_lock(&locklock);
04057       t = get_lockthread(pthread_self());
04058       if (t) memset(t,0,sizeof(struct lockthread));
04059       ast_mutex_unlock(&locklock);
04060    }        
04061 #endif
04062    pthread_exit(NULL);
04063 }

static void rpt_telemetry ( struct rpt myrpt,
int  mode,
void *  data 
) [static]

Definition at line 4065 of file app_rpt.c.

References ARB_ALPHA, ast_log(), ast_pthread_create, CONNECTED, CONNFAIL, LINKUNKEY, rpt::lock, LOG_WARNING, malloc, rpt_tele::next, REMDISC, REMXXX, REV_PATCH, rpt_mutex_lock, rpt_mutex_unlock, rpt_tele_thread(), rpt::tele, and TELEPARAMSIZE.

Referenced by function_autopatchdn(), function_cop(), function_ilink(), function_macro(), function_remote(), function_status(), handle_link_data(), handle_link_phone_dtmf(), handle_remote_data(), handle_remote_phone_dtmf(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_exec(), setrem(), and stop_scan().

04066 {
04067 struct rpt_tele *tele;
04068 struct rpt_link *mylink = (struct rpt_link *) data;
04069 int res;
04070 pthread_attr_t attr;
04071 
04072    tele = malloc(sizeof(struct rpt_tele));
04073    if (!tele)
04074    {
04075       ast_log(LOG_WARNING, "Unable to allocate memory\n");
04076       pthread_exit(NULL);
04077       return;
04078    }
04079    /* zero it out */
04080    memset((char *)tele,0,sizeof(struct rpt_tele));
04081    tele->rpt = myrpt;
04082    tele->mode = mode;
04083    rpt_mutex_lock(&myrpt->lock);
04084    if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED) ||
04085        (mode == LINKUNKEY)){
04086       memset(&tele->mylink,0,sizeof(struct rpt_link));
04087       if (mylink){
04088          memcpy(&tele->mylink,mylink,sizeof(struct rpt_link));
04089       }
04090    }
04091    else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) {
04092       strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
04093       tele->param[TELEPARAMSIZE - 1] = 0;
04094    }
04095    if (mode == REMXXX) tele->submode = (int) data;
04096    insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next);
04097    rpt_mutex_unlock(&myrpt->lock);
04098         pthread_attr_init(&attr);
04099         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04100    res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele);
04101    if(res < 0){
04102       rpt_mutex_lock(&myrpt->lock);
04103       remque((struct qlem *) tele); /* We don't like stuck transmitters, remove it from the queue */
04104       rpt_mutex_unlock(&myrpt->lock);  
04105       ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res));
04106    }
04107    return;
04108 }

static int saycharstr ( struct ast_channel mychannel,
char *  str 
) [static]

Definition at line 2641 of file app_rpt.c.

References ast_log(), ast_say_character_str(), ast_stopstream(), ast_waitstream(), and LOG_WARNING.

Referenced by rpt_tele_thread().

02642 {
02643 int   res;
02644 
02645    res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
02646    if (!res) 
02647       res = ast_waitstream(mychannel, "");
02648    else
02649        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02650    ast_stopstream(mychannel);
02651    return res;
02652 }

static int sayfile ( struct ast_channel mychannel,
char *  fname 
) [static]

Definition at line 2628 of file app_rpt.c.

References ast_log(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and LOG_WARNING.

Referenced by rpt_exec(), rpt_tele_thread(), and telem_any().

02629 {
02630 int   res;
02631 
02632    res = ast_streamfile(mychannel, fname, mychannel->language);
02633    if (!res) 
02634       res = ast_waitstream(mychannel, "");
02635    else
02636        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02637    ast_stopstream(mychannel);
02638    return res;
02639 }

static int saynum ( struct ast_channel mychannel,
int  num 
) [static]

Definition at line 2654 of file app_rpt.c.

References ast_log(), ast_say_number(), ast_stopstream(), ast_waitstream(), and LOG_WARNING.

Referenced by rpt_tele_thread().

02655 {
02656    int res;
02657    res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL);
02658    if(!res)
02659       res = ast_waitstream(mychannel, "");
02660    else
02661       ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02662    ast_stopstream(mychannel);
02663    return res;
02664 }

static int select_mem_ic706 ( struct rpt myrpt,
int  slot 
) [static]

Definition at line 7105 of file app_rpt.c.

References civ_cmd(), rpt::civaddr, and rpt::p.

Referenced by set_ic706().

07106 {
07107    unsigned char cmdstr[10];
07108    
07109    cmdstr[0] = cmdstr[1] = 0xfe;
07110    cmdstr[2] = myrpt->p.civaddr;
07111    cmdstr[3] = 0xe0;
07112    cmdstr[4] = 8;
07113    cmdstr[5] = 0;
07114    cmdstr[6] = ((slot / 10) << 4) + (slot % 10);
07115    cmdstr[7] = 0xfd;
07116 
07117    return(civ_cmd(myrpt,cmdstr,8));
07118 }

static void send_link_dtmf ( struct rpt myrpt,
char  c 
) [static]

Definition at line 4356 of file app_rpt.c.

References AST_FRAME_TEXT, ast_write(), rpt_link::chan, rpt::cmdnode, ast_frame::data, ast_frame::datalen, rpt::dtmfidx, ast_frame::frametype, rpt::links, ast_frame::mallocd, rpt_link::name, rpt::name, rpt_link::next, ast_frame::offset, ast_frame::samples, and ast_frame::subclass.

Referenced by handle_link_phone_dtmf(), and local_dtmf_helper().

04357 {
04358 char  str[300];
04359 struct   ast_frame wf;
04360 struct   rpt_link *l;
04361 
04362    snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c);
04363    wf.frametype = AST_FRAME_TEXT;
04364    wf.subclass = 0;
04365    wf.offset = 0;
04366    wf.mallocd = 0;
04367    wf.datalen = strlen(str) + 1;
04368    wf.samples = 0;
04369    l = myrpt->links.next;
04370    /* first, see if our dude is there */
04371    while(l != &myrpt->links)
04372    {
04373       if (l->name[0] == '0') 
04374       {
04375          l = l->next;
04376          continue;
04377       }
04378       /* if we found it, write it and were done */
04379       if (!strcmp(l->name,myrpt->cmdnode))
04380       {
04381          wf.data = str;
04382          if (l->chan) ast_write(l->chan,&wf);
04383          return;
04384       }
04385       l = l->next;
04386    }
04387    l = myrpt->links.next;
04388    /* if not, give it to everyone */
04389    while(l != &myrpt->links)
04390    {
04391       wf.data = str;
04392       if (l->chan) ast_write(l->chan,&wf);
04393       l = l->next;
04394    }
04395    return;
04396 }

static int send_morse ( struct ast_channel chan,
char *  string,
int  speed,
int  freq,
int  amplitude 
) [static]

Definition at line 2415 of file app_rpt.c.

References ast_safe_sleep(), ast_stopstream(), ast_waitstream(), morse_bits::ddcomb, ast_channel::fds, morse_bits::len, play_silence(), and play_tone().

Referenced by telem_any().

02416 {
02417 
02418 static struct morse_bits mbits[] = {
02419       {0, 0}, /* SPACE */
02420       {0, 0}, 
02421       {6, 18},/* " */
02422       {0, 0},
02423       {7, 72},/* $ */
02424       {0, 0},
02425       {0, 0},
02426       {6, 30},/* ' */
02427       {5, 13},/* ( */
02428       {6, 29},/* ) */
02429       {0, 0},
02430       {5, 10},/* + */
02431       {6, 51},/* , */
02432       {6, 33},/* - */
02433       {6, 42},/* . */
02434       {5, 9}, /* / */
02435       {5, 31},/* 0 */
02436       {5, 30},/* 1 */
02437       {5, 28},/* 2 */
02438       {5, 24},/* 3 */
02439       {5, 16},/* 4 */
02440       {5, 0}, /* 5 */
02441       {5, 1}, /* 6 */
02442       {5, 3}, /* 7 */
02443       {5, 7}, /* 8 */
02444       {5, 15},/* 9 */
02445       {6, 7}, /* : */
02446       {6, 21},/* ; */
02447       {0, 0},
02448       {5, 33},/* = */
02449       {0, 0},
02450       {6, 12},/* ? */
02451       {0, 0},
02452          {2, 2}, /* A */
02453       {4, 1}, /* B */
02454       {4, 5}, /* C */
02455       {3, 1}, /* D */
02456       {1, 0}, /* E */
02457       {4, 4}, /* F */
02458       {3, 3}, /* G */
02459       {4, 0}, /* H */
02460       {2, 0}, /* I */
02461       {4, 14},/* J */
02462       {3, 5}, /* K */
02463       {4, 2}, /* L */
02464       {2, 3}, /* M */
02465       {2, 1}, /* N */
02466       {3, 7}, /* O */
02467       {4, 6}, /* P */
02468       {4, 11},/* Q */
02469       {3, 2}, /* R */
02470       {3, 0}, /* S */
02471       {1, 1}, /* T */
02472       {3, 4}, /* U */
02473       {4, 8}, /* V */
02474       {3, 6}, /* W */
02475       {4, 9}, /* X */
02476       {4, 13},/* Y */
02477       {4, 3}  /* Z */
02478    };
02479 
02480 
02481    int dottime;
02482    int dashtime;
02483    int intralettertime;
02484    int interlettertime;
02485    int interwordtime;
02486    int len, ddcomb;
02487    int res;
02488    int c;
02489    int i;
02490    int flags;
02491          
02492    res = 0;
02493    
02494    /* Approximate the dot time from the speed arg. */
02495    
02496    dottime = 900/speed;
02497    
02498    /* Establish timing releationships */
02499    
02500    dashtime = 3 * dottime;
02501    intralettertime = dottime;
02502    interlettertime = dottime * 4 ;
02503    interwordtime = dottime * 7;
02504    
02505    for(;(*string) && (!res); string++){
02506    
02507       c = *string;
02508       
02509       /* Convert lower case to upper case */
02510       
02511       if((c >= 'a') && (c <= 'z'))
02512          c -= 0x20;
02513       
02514       /* Can't deal with any char code greater than Z, skip it */
02515       
02516       if(c  > 'Z')
02517          continue;
02518       
02519       /* If space char, wait the inter word time */
02520                
02521       if(c == ' '){
02522          if(!res)
02523             res = play_silence(chan, interwordtime);
02524          continue;
02525       }
02526       
02527       /* Subtract out control char offset to match our table */
02528       
02529       c -= 0x20;
02530       
02531       /* Get the character data */
02532       
02533       len = mbits[c].len;
02534       ddcomb = mbits[c].ddcomb;
02535       
02536       /* Send the character */
02537       
02538       for(; len ; len--){
02539          if(!res)
02540             res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude);
02541          if(!res)
02542             res = play_silence(chan, intralettertime);
02543          ddcomb >>= 1;
02544       }
02545       
02546       /* Wait the interletter time */
02547       
02548       if(!res)
02549          res = play_silence(chan, interlettertime - intralettertime);
02550    }
02551    
02552    /* Wait for all the frames to be sent */
02553    
02554    if (!res) 
02555       res = ast_waitstream(chan, "");
02556    ast_stopstream(chan);
02557    
02558    /*
02559    * Wait for the zaptel driver to physically write the tone blocks to the hardware
02560    */
02561 
02562    for(i = 0; i < 20 ; i++){
02563       flags =  ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT; 
02564       res = ioctl(chan->fds[0], ZT_IOMUX, &flags);
02565       if(flags & ZT_IOMUX_WRITEEMPTY)
02566          break;
02567       if( ast_safe_sleep(chan, 50)){
02568          res = -1;
02569          break;
02570       }
02571    }
02572 
02573    
02574    return res;
02575 }

static int send_tone_telemetry ( struct ast_channel chan,
char *  tonestring 
) [static]

Definition at line 2577 of file app_rpt.c.

References ast_safe_sleep(), ast_stopstream(), ast_strdupa, ast_waitstream(), ast_channel::fds, play_tone_pair(), and strsep().

Referenced by telem_any().

02578 {
02579    char *stringp;
02580    char *tonesubset;
02581    int f1,f2;
02582    int duration;
02583    int amplitude;
02584    int res;
02585    int i;
02586    int flags;
02587    
02588    res = 0;
02589    
02590    stringp = ast_strdupa(tonestring);
02591 
02592    for(;tonestring;){
02593       tonesubset = strsep(&stringp,")");
02594       if(!tonesubset)
02595          break;
02596       if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &amplitude) != 4)
02597          break;
02598       res = play_tone_pair(chan, f1, f2, duration, amplitude);
02599       if(res)
02600          break;
02601    }
02602    if(!res)
02603       res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */
02604    
02605    if (!res) 
02606       res = ast_waitstream(chan, "");
02607    ast_stopstream(chan);
02608 
02609    /*
02610    * Wait for the zaptel driver to physically write the tone blocks to the hardware
02611    */
02612 
02613    for(i = 0; i < 20 ; i++){
02614       flags =  ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT; 
02615       res = ioctl(chan->fds[0], ZT_IOMUX, &flags);
02616       if(flags & ZT_IOMUX_WRITEEMPTY)
02617          break;
02618       if( ast_safe_sleep(chan, 50)){
02619          res = -1;
02620          break;
02621       }
02622    }
02623       
02624    return res;
02625       
02626 }

static int sendkenwood ( struct rpt myrpt,
char *  txstr,
char *  rxstr 
) [static]

Definition at line 5876 of file app_rpt.c.

References serial_remote_io().

Referenced by sendrxkenwood().

05877 {
05878 int   i;
05879 
05880    if (debug) printf("Send to kenwood: %s\n",txstr);
05881    i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr), 
05882       (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3);
05883    if (i < 0) return -1;
05884    if ((i > 0) && (rxstr[i - 1] == '\r'))
05885       rxstr[i-- - 1] = 0;
05886    if (debug) printf("Got from kenwood: %s\n",rxstr);
05887    return(i);
05888 }

static int sendrxkenwood ( struct rpt myrpt,
char *  txstr,
char *  rxstr,
char *  cmpstr 
) [static]

Definition at line 5982 of file app_rpt.c.

References KENWOOD_RETRIES, and sendkenwood().

Referenced by setkenwood().

05984 {
05985 int   i,j;
05986 
05987    for(i = 0;i < KENWOOD_RETRIES;i++)
05988    {
05989       j = sendkenwood(myrpt,txstr,rxstr);
05990       if (j < 0) return(j);
05991       if (j == 0) continue;
05992       if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0);
05993    }
05994    return(-1);
05995 }     

static int serial_remote_io ( struct rpt myrpt,
unsigned char *  txbuf,
int  txbytes,
unsigned char *  rxbuf,
int  rxmaxbytes,
int  asciiflag 
) [static]

Definition at line 5776 of file app_rpt.c.

References ast_channel::fds, rpt::iofd, and rpt::rxchannel.

Referenced by civ_cmd(), multimode_bump_freq_ic706(), sendkenwood(), set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), and simple_command_ft897().

05778 {
05779    int i,j,index,oldmode,olddata;
05780    struct zt_radio_param prm;
05781    char c;
05782 
05783    if(debug){
05784       printf("String output was: ");
05785       for(i = 0; i < txbytes; i++)
05786          printf("%02X ", (unsigned char ) txbuf[i]);
05787       printf("\n");
05788    }
05789    if (myrpt->iofd > 0)  /* if to do out a serial port */
05790    {
05791       if (rxmaxbytes && rxbuf) tcflush(myrpt->iofd,TCIFLUSH);     
05792       if (write(myrpt->iofd,txbuf,txbytes) != txbytes) return -1;
05793       if ((!rxmaxbytes) || (rxbuf == NULL)) return(0);
05794       memset(rxbuf,0,rxmaxbytes);
05795       for(i = 0; i < rxmaxbytes; i++)
05796       {
05797          j = read(myrpt->iofd,&c,1);
05798          if (j < 1) return(i);
05799          rxbuf[i] = c;
05800          if (asciiflag & 1)
05801          {
05802             rxbuf[i + 1] = 0;
05803             if (c == '\r') break;
05804          }
05805       }              
05806    if(debug){
05807       printf("String returned was: ");
05808       for(j = 0; j < i; j++)
05809          printf("%02X ", (unsigned char ) rxbuf[j]);
05810       printf("\n");
05811    }
05812       return(i);
05813    }
05814    
05815    prm.radpar = ZT_RADPAR_UIOMODE;
05816    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
05817    oldmode = prm.data;
05818    prm.radpar = ZT_RADPAR_UIODATA;
05819    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
05820    olddata = prm.data;
05821         prm.radpar = ZT_RADPAR_REMMODE;
05822         if (asciiflag & 1)  prm.data = ZT_RADPAR_REM_SERIAL_ASCII;
05823         else prm.data = ZT_RADPAR_REM_SERIAL;
05824    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05825    if (asciiflag & 2)
05826    {
05827       i = ZT_ONHOOK;
05828       if (ioctl(myrpt->rxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
05829       usleep(100000);
05830    }
05831         prm.radpar = ZT_RADPAR_REMCOMMAND;
05832         prm.data = rxmaxbytes;
05833         memcpy(prm.buf,txbuf,txbytes);
05834         prm.index = txbytes;
05835    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05836         if (rxbuf)
05837         {
05838                 *rxbuf = 0;
05839                 memcpy(rxbuf,prm.buf,prm.index);
05840         }
05841    index = prm.index;
05842         prm.radpar = ZT_RADPAR_REMMODE;
05843         prm.data = ZT_RADPAR_REM_NONE;
05844    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05845    if (asciiflag & 2)
05846    {
05847       i = ZT_OFFHOOK;
05848       if (ioctl(myrpt->rxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
05849    }
05850    prm.radpar = ZT_RADPAR_UIOMODE;
05851    prm.data = oldmode;
05852    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05853    prm.radpar = ZT_RADPAR_UIODATA;
05854    prm.data = olddata;
05855    if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05856         return(index);
05857 }

static int service_scan ( struct rpt myrpt  )  [static]

Definition at line 7481 of file app_rpt.c.

References rpt::freq, HF_SCAN_DOWN_FAST, HF_SCAN_DOWN_QUICK, HF_SCAN_DOWN_SLOW, HF_SCAN_UP_FAST, HF_SCAN_UP_QUICK, HF_SCAN_UP_SLOW, rpt::hfscanmode, rpt::hfscanstatus, MAXREMSTR, multimode_bump_freq(), and split_freq().

Referenced by rpt_tele_thread().

07482 {
07483    int res, interval;
07484    char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0;
07485 
07486    switch(myrpt->hfscanmode){
07487 
07488       case HF_SCAN_DOWN_SLOW:
07489          interval = -10; /* 100Hz /sec */
07490          break;
07491 
07492       case HF_SCAN_DOWN_QUICK:
07493          interval = -50; /* 500Hz /sec */
07494          break;
07495 
07496       case HF_SCAN_DOWN_FAST:
07497          interval = -200; /* 2KHz /sec */
07498          break;
07499 
07500       case HF_SCAN_UP_SLOW:
07501          interval = 10; /* 100Hz /sec */
07502          break;
07503 
07504       case HF_SCAN_UP_QUICK:
07505          interval = 50; /* 500 Hz/sec */
07506          break;
07507 
07508       case HF_SCAN_UP_FAST:
07509          interval = 200; /* 2KHz /sec */
07510          break;
07511 
07512       default:
07513          myrpt->hfscanmode = 0; /* Huh? */
07514          return -1;
07515    }
07516 
07517    res = split_freq(mhz, decimals, myrpt->freq);
07518       
07519    if(!res){
07520       k100 =decimals[0];
07521       k10 = decimals[1];
07522       res = multimode_bump_freq(myrpt, interval);
07523    }
07524 
07525    if(!res)
07526       res = split_freq(mhz, decimals, myrpt->freq);
07527 
07528 
07529    if(res){
07530       myrpt->hfscanmode = 0;
07531       myrpt->hfscanstatus = -2;
07532       return -1;
07533    }
07534 
07535    /* Announce 10KHz boundaries */
07536    if(k10 != decimals[1]){
07537       int myhund = (interval < 0) ? k100 : decimals[0];
07538       int myten = (interval < 0) ? k10 : decimals[1];
07539       myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10;
07540    } else myrpt->hfscanstatus = 0;
07541    return res;
07542 
07543 }

static int set_ctcss_freq_ft897 ( struct rpt myrpt,
char *  txtone,
char *  rxtone 
) [static]

Definition at line 6541 of file app_rpt.c.

References MAXREMSTR, serial_remote_io(), and split_ctcss_freq().

Referenced by set_ft897().

06542 {
06543    unsigned char cmdstr[5];
06544    char hertz[MAXREMSTR],decimal[MAXREMSTR];
06545    int h,d; 
06546 
06547    memset(cmdstr, 0, 5);
06548 
06549    if(split_ctcss_freq(hertz, decimal, txtone))
06550       return -1; 
06551 
06552    h = atoi(hertz);
06553    d = atoi(decimal);
06554    
06555    cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10;
06556    cmdstr[1] = ((h % 10) << 4) + (d % 10);
06557    
06558    if(rxtone){
06559    
06560       if(split_ctcss_freq(hertz, decimal, rxtone))
06561          return -1; 
06562 
06563       h = atoi(hertz);
06564       d = atoi(decimal);
06565    
06566       cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10;
06567       cmdstr[3] = ((h % 10) << 4) + (d % 10);
06568    }
06569    cmdstr[4] = 0x0B; 
06570 
06571    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06572 }  

static int set_ctcss_mode_ft897 ( struct rpt myrpt,
char  txplon,
char  rxplon 
) [static]

Definition at line 6518 of file app_rpt.c.

References serial_remote_io().

Referenced by set_ft897().

06519 {
06520    unsigned char cmdstr[5];
06521    
06522    memset(cmdstr, 0, 5);
06523    
06524    if(rxplon && txplon)
06525       cmdstr[0] = 0x2A; /* Encode and Decode */
06526    else if (!rxplon && txplon)
06527       cmdstr[0] = 0x4A; /* Encode only */
06528    else if (rxplon && !txplon)
06529       cmdstr[0] = 0x3A; /* Encode only */
06530    else
06531       cmdstr[0] = 0x8A; /* OFF */
06532 
06533    cmdstr[4] = 0x0A; 
06534 
06535    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06536 }

static int set_ctcss_mode_ic706 ( struct rpt myrpt,
char  txplon,
char  rxplon 
) [static]

Definition at line 7003 of file app_rpt.c.

References civ_cmd(), rpt::civaddr, and rpt::p.

Referenced by set_ic706().

07004 {
07005    unsigned char cmdstr[10];
07006    int rv;
07007 
07008    cmdstr[0] = cmdstr[1] = 0xfe;
07009    cmdstr[2] = myrpt->p.civaddr;
07010    cmdstr[3] = 0xe0;
07011    cmdstr[4] = 0x16;
07012    cmdstr[5] = 0x42;
07013    cmdstr[6] = (txplon != 0);
07014    cmdstr[7] = 0xfd;
07015 
07016    rv = civ_cmd(myrpt,cmdstr,8);
07017    if (rv) return(-1);
07018 
07019    cmdstr[0] = cmdstr[1] = 0xfe;
07020    cmdstr[2] = myrpt->p.civaddr;
07021    cmdstr[3] = 0xe0;
07022    cmdstr[4] = 0x16;
07023    cmdstr[5] = 0x43;
07024    cmdstr[6] = (rxplon != 0);
07025    cmdstr[7] = 0xfd;
07026 
07027    return(civ_cmd(myrpt,cmdstr,8));
07028 }

static int set_freq_ft897 ( struct rpt myrpt,
char *  newfreq 
) [static]

Definition at line 6410 of file app_rpt.c.

References MAXREMSTR, serial_remote_io(), and split_freq().

Referenced by multimode_bump_freq_ft897(), and set_ft897().

06411 {
06412    unsigned char cmdstr[5];
06413    int fd,m,d;
06414    char mhz[MAXREMSTR];
06415    char decimals[MAXREMSTR];
06416 
06417    fd = 0;
06418    if(debug) 
06419       printf("New frequency: %s\n",newfreq);
06420 
06421    if(split_freq(mhz, decimals, newfreq))
06422       return -1; 
06423 
06424    m = atoi(mhz);
06425    d = atoi(decimals);
06426 
06427    /* The FT-897 likes packed BCD frequencies */
06428 
06429    cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10);        /* 100MHz 10Mhz */
06430    cmdstr[1] = ((m % 10) << 4) + (d / 10000);         /* 1MHz 100KHz */
06431    cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100);  /* 10KHz 1KHz */
06432    cmdstr[3] = (((d % 100)/10) << 4) + (d % 10);         /* 100Hz 10Hz */
06433    cmdstr[4] = 0x01;                /* command */
06434 
06435    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06436 
06437 }

static int set_freq_ic706 ( struct rpt myrpt,
char *  newfreq 
) [static]

Definition at line 6913 of file app_rpt.c.

References civ_cmd(), rpt::civaddr, MAXREMSTR, rpt::p, and split_freq().

Referenced by set_ic706().

06914 {
06915    unsigned char cmdstr[20];
06916    char mhz[MAXREMSTR], decimals[MAXREMSTR];
06917    int fd,m,d;
06918 
06919    fd = 0;
06920    if(debug) 
06921       printf("New frequency: %s\n",newfreq);
06922 
06923    if(split_freq(mhz, decimals, newfreq))
06924       return -1; 
06925 
06926    m = atoi(mhz);
06927    d = atoi(decimals);
06928 
06929    /* The ic-706 likes packed BCD frequencies */
06930 
06931    cmdstr[0] = cmdstr[1] = 0xfe;
06932    cmdstr[2] = myrpt->p.civaddr;
06933    cmdstr[3] = 0xe0;
06934    cmdstr[4] = 5;
06935    cmdstr[5] = ((d % 10) << 4);
06936    cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10);
06937    cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000);
06938    cmdstr[8] = (((m % 100)/10) << 4) + (m % 10);
06939    cmdstr[9] = (m / 100);
06940    cmdstr[10] = 0xfd;
06941 
06942    return(civ_cmd(myrpt,cmdstr,11));
06943 }

static int set_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6576 of file app_rpt.c.

References rpt::freq, rpt::offset, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, rpt::remmode, rpt::rxpl, rpt::rxplon, set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), simple_command_ft897(), rpt::txpl, and rpt::txplon.

Referenced by rpt_tele_thread().

06577 {
06578    int res;
06579    
06580    if(debug)
06581       printf("@@@@ lock on\n");
06582 
06583    res = simple_command_ft897(myrpt, 0x00);  /* LOCK on */  
06584 
06585    if(debug)
06586       printf("@@@@ ptt off\n");
06587 
06588    if(!res)
06589       res = simple_command_ft897(myrpt, 0x88);     /* PTT off */
06590 
06591    if(debug)
06592       printf("Modulation mode\n");
06593 
06594    if(!res)
06595       res = set_mode_ft897(myrpt, myrpt->remmode);    /* Modulation mode */
06596 
06597    if(debug)
06598       printf("Split off\n");
06599 
06600    if(!res)
06601       simple_command_ft897(myrpt, 0x82);        /* Split off */
06602 
06603    if(debug)
06604       printf("Frequency\n");
06605 
06606    if(!res)
06607       res = set_freq_ft897(myrpt, myrpt->freq);    /* Frequency */
06608    if((myrpt->remmode == REM_MODE_FM)){
06609       if(debug)
06610          printf("Offset\n");
06611       if(!res)
06612          res = set_offset_ft897(myrpt, myrpt->offset);   /* Offset if FM */
06613       if((!res)&&(myrpt->rxplon || myrpt->txplon)){
06614          if(debug)
06615             printf("CTCSS tone freqs.\n");
06616          res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */
06617       }
06618       if(!res){
06619          if(debug)
06620             printf("CTCSS mode\n");
06621          res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */
06622       }
06623    }
06624    if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){
06625       if(debug)
06626          printf("Clarifier off\n");
06627       simple_command_ft897(myrpt, 0x85);        /* Clarifier off if LSB or USB */
06628    }
06629    return res;
06630 }

static int set_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7120 of file app_rpt.c.

References rpt::freq, IC706_PL_MEMORY_OFFSET, ic706_pltocode(), mem2vfo_ic706(), rpt::offset, REM_MODE_FM, rpt::remmode, rpt::rxpl, rpt::rxplon, select_mem_ic706(), set_ctcss_mode_ic706(), set_freq_ic706(), set_mode_ic706(), set_offset_ic706(), simple_command_ic706(), rpt::txplon, and vfo_ic706().

Referenced by rpt_tele_thread().

07121 {
07122    int res = 0,i;
07123    
07124    if(debug)
07125       printf("Set to VFO A\n");
07126 
07127    if (!res)
07128       res = simple_command_ic706(myrpt,7,0);
07129 
07130 
07131    if((myrpt->remmode == REM_MODE_FM))
07132    {
07133       i = ic706_pltocode(myrpt->rxpl);
07134       if (i == -1) return -1;
07135       if(debug)
07136          printf("Select memory number\n");
07137       if (!res)
07138          res = select_mem_ic706(myrpt,i + IC706_PL_MEMORY_OFFSET);
07139       if(debug)
07140          printf("Transfer memory to VFO\n");
07141       if (!res)
07142          res = mem2vfo_ic706(myrpt);
07143    }
07144       
07145    if(debug)
07146       printf("Set to VFO\n");
07147 
07148    if (!res)
07149       res = vfo_ic706(myrpt);
07150 
07151    if(debug)
07152       printf("Modulation mode\n");
07153 
07154    if (!res)
07155       res = set_mode_ic706(myrpt, myrpt->remmode);    /* Modulation mode */
07156 
07157    if(debug)
07158       printf("Split off\n");
07159 
07160    if(!res)
07161       simple_command_ic706(myrpt, 0x82,0);         /* Split off */
07162 
07163    if(debug)
07164       printf("Frequency\n");
07165 
07166    if(!res)
07167       res = set_freq_ic706(myrpt, myrpt->freq);    /* Frequency */
07168    if((myrpt->remmode == REM_MODE_FM)){
07169       if(debug)
07170          printf("Offset\n");
07171       if(!res)
07172          res = set_offset_ic706(myrpt, myrpt->offset);   /* Offset if FM */
07173       if(!res){
07174          if(debug)
07175             printf("CTCSS mode\n");
07176          res = set_ctcss_mode_ic706(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */
07177       }
07178    }
07179    return res;
07180 }

static int set_mode_ft897 ( struct rpt myrpt,
char  newmode 
) [static]

Definition at line 6485 of file app_rpt.c.

References REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, and serial_remote_io().

Referenced by rpt_tele_thread(), and set_ft897().

06486 {
06487    unsigned char cmdstr[5];
06488    
06489    memset(cmdstr, 0, 5);
06490    
06491    switch(newmode){
06492       case  REM_MODE_FM:
06493          cmdstr[0] = 0x08;
06494          break;
06495 
06496       case  REM_MODE_USB:
06497          cmdstr[0] = 0x01;
06498          break;
06499 
06500       case  REM_MODE_LSB:
06501          cmdstr[0] = 0x00;
06502          break;
06503 
06504       case  REM_MODE_AM:
06505          cmdstr[0] = 0x04;
06506          break;
06507       
06508       default:
06509          return -1;
06510    }
06511    cmdstr[4] = 0x07; 
06512 
06513    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06514 }

static int set_mode_ic706 ( struct rpt myrpt,
char  newmode 
) [static]

Definition at line 6974 of file app_rpt.c.

References REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, and simple_command_ic706().

Referenced by rpt_tele_thread(), and set_ic706().

06975 {
06976    unsigned char c;
06977    
06978    switch(newmode){
06979       case  REM_MODE_FM:
06980          c = 5;
06981          break;
06982 
06983       case  REM_MODE_USB:
06984          c = 1;
06985          break;
06986 
06987       case  REM_MODE_LSB:
06988          c = 0;
06989          break;
06990 
06991       case  REM_MODE_AM:
06992          c = 2;
06993          break;
06994       
06995       default:
06996          return -1;
06997    }
06998    return simple_command_ic706(myrpt,6,c);
06999 }

static int set_offset_ft897 ( struct rpt myrpt,
char  offset 
) [static]

Definition at line 6455 of file app_rpt.c.

References REM_MINUS, REM_PLUS, REM_SIMPLEX, and serial_remote_io().

Referenced by set_ft897().

06456 {
06457    unsigned char cmdstr[5];
06458    
06459    memset(cmdstr, 0, 5);
06460 
06461    switch(offset){
06462       case  REM_SIMPLEX:
06463          cmdstr[0] = 0x89;
06464          break;
06465 
06466       case  REM_MINUS:
06467          cmdstr[0] = 0x09;
06468          break;
06469       
06470       case  REM_PLUS:
06471          cmdstr[0] = 0x49;
06472          break;   
06473 
06474       default:
06475          return -1;
06476    }
06477 
06478    cmdstr[4] = 0x09; 
06479 
06480    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06481 }

static int set_offset_ic706 ( struct rpt myrpt,
char  offset 
) [static]

Definition at line 6947 of file app_rpt.c.

References REM_MINUS, REM_PLUS, REM_SIMPLEX, and simple_command_ic706().

Referenced by set_ic706().

06948 {
06949    unsigned char c;
06950 
06951    switch(offset){
06952       case  REM_SIMPLEX:
06953          c = 0x10;
06954          break;
06955 
06956       case  REM_MINUS:
06957          c = 0x11;
06958          break;
06959       
06960       case  REM_PLUS:
06961          c = 0x12;
06962          break;   
06963 
06964       default:
06965          return -1;
06966    }
06967 
06968    return simple_command_ic706(myrpt,0x0f,c);
06969 
06970 }

static int setkenwood ( struct rpt myrpt  )  [static]

Definition at line 5997 of file app_rpt.c.

References rpt::freq, kenwood_pltocode(), MAXREMSTR, rpt::offset, offset, rpt::powerlevel, rpt::rxpl, rpt::rxplon, sendrxkenwood(), split_freq(), rpt::txpl, and rpt::txplon.

Referenced by rpt_tele_thread().

05998 {
05999 char rxstr[RAD_SERIAL_BUFLEN],txstr[RAD_SERIAL_BUFLEN],freq[20];
06000 char mhz[MAXREMSTR],offset[20],band,decimals[MAXREMSTR],band1,band2;
06001    
06002 int offsets[] = {0,2,1};
06003 int powers[] = {2,1,0};
06004 
06005    if (sendrxkenwood(myrpt,"VMC 0,0\r",rxstr,"VMC") < 0) return -1;
06006    split_freq(mhz, decimals, myrpt->freq);
06007    if (atoi(mhz) > 400)
06008    {
06009       band = '6';
06010       band1 = '1';
06011       band2 = '5';
06012       strcpy(offset,"005000000");
06013    }
06014    else
06015    {
06016       band = '2';
06017       band1 = '0';
06018       band2 = '2';
06019       strcpy(offset,"000600000");
06020    }
06021    strcpy(freq,"000000");
06022    strncpy(freq,decimals,strlen(decimals));
06023    sprintf(txstr,"VW %c,%05d%s,0,%d,0,%d,%d,,%02d,,%02d,%s\r",
06024       band,atoi(mhz),freq,offsets[(int)myrpt->offset],
06025       (myrpt->txplon != 0),(myrpt->rxplon != 0),
06026       kenwood_pltocode(myrpt->txpl),kenwood_pltocode(myrpt->rxpl),
06027       offset);
06028    if (sendrxkenwood(myrpt,txstr,rxstr,"VW") < 0) return -1;
06029    sprintf(txstr,"RBN %c\r",band2);
06030    if (sendrxkenwood(myrpt,txstr,rxstr,"RBN") < 0) return -1;
06031    sprintf(txstr,"PC %c,%d\r",band1,powers[(int)myrpt->powerlevel]);
06032    if (sendrxkenwood(myrpt,txstr,rxstr,"PC") < 0) return -1;
06033    return 0;
06034 }

static int setrbi ( struct rpt myrpt  )  [static]

Definition at line 6036 of file app_rpt.c.

References rpt::freq, MAXREMSTR, rpt::offset, rpt::powerlevel, rbi_mhztoband(), rbi_out(), rbi_pltocode(), REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_PLUS, REM_SIMPLEX, rpt::remote, rpt::rxpl, rpt::rxplon, s, setrbi_check(), and rpt::txplon.

Referenced by rpt_tele_thread().

06037 {
06038 char tmp[MAXREMSTR] = "",*s;
06039 unsigned char rbicmd[5];
06040 int   band,txoffset = 0,txpower = 0,rxpl;
06041 
06042    /* must be a remote system */
06043    if (!myrpt->remote) return(0);
06044    /* must have rbi hardware */
06045    if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0);
06046    if (setrbi_check(myrpt) == -1) return(-1);
06047    strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
06048    s = strchr(tmp,'.');
06049    /* if no decimal, is invalid */
06050    
06051    if (s == NULL){
06052       if(debug)
06053          printf("@@@@ Frequency needs a decimal\n");
06054       return -1;
06055    }
06056    
06057    *s++ = 0;
06058    if (strlen(tmp) < 2){
06059       if(debug)
06060          printf("@@@@ Bad MHz digits: %s\n", tmp);
06061       return -1;
06062    }
06063     
06064    if (strlen(s) < 3){
06065       if(debug)
06066          printf("@@@@ Bad KHz digits: %s\n", s);
06067       return -1;
06068    }
06069 
06070    if ((s[2] != '0') && (s[2] != '5')){
06071       if(debug)
06072          printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
06073       return -1;
06074    }
06075     
06076    band = rbi_mhztoband(tmp);
06077    if (band == -1){
06078       if(debug)
06079          printf("@@@@ Bad Band: %s\n", tmp);
06080       return -1;
06081    }
06082    
06083    rxpl = rbi_pltocode(myrpt->rxpl);
06084    
06085    if (rxpl == -1){
06086       if(debug)
06087          printf("@@@@ Bad TX PL: %s\n", myrpt->rxpl);
06088       return -1;
06089    }
06090 
06091    
06092    switch(myrpt->offset)
06093    {
06094        case REM_MINUS:
06095       txoffset = 0;
06096       break;
06097        case REM_PLUS:
06098       txoffset = 0x10;
06099       break;
06100        case REM_SIMPLEX:
06101       txoffset = 0x20;
06102       break;
06103    }
06104    switch(myrpt->powerlevel)
06105    {
06106        case REM_LOWPWR:
06107       txpower = 0;
06108       break;
06109        case REM_MEDPWR:
06110       txpower = 0x20;
06111       break;
06112        case REM_HIPWR:
06113       txpower = 0x10;
06114       break;
06115    }
06116    rbicmd[0] = 0;
06117    rbicmd[1] = band | txpower | 0xc0;
06118    rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80;
06119    if (s[2] == '5') rbicmd[2] |= 0x40;
06120    rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0');
06121    rbicmd[4] = rxpl;
06122    if (myrpt->txplon) rbicmd[4] |= 0x40;
06123    if (myrpt->rxplon) rbicmd[4] |= 0x80;
06124    rbi_out(myrpt,rbicmd);
06125    return 0;
06126 }

static int setrbi_check ( struct rpt myrpt  )  [static]

Definition at line 6128 of file app_rpt.c.

References rpt::freq, MAXREMSTR, rbi_mhztoband(), rbi_pltocode(), rpt::remote, s, and rpt::txpl.

Referenced by setrbi(), and setrem().

06129 {
06130 char tmp[MAXREMSTR] = "",*s;
06131 int   band,txpl;
06132 
06133    /* must be a remote system */
06134    if (!myrpt->remote) return(0);
06135    /* must have rbi hardware */
06136    if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0);
06137    strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
06138    s = strchr(tmp,'.');
06139    /* if no decimal, is invalid */
06140    
06141    if (s == NULL){
06142       if(debug)
06143          printf("@@@@ Frequency needs a decimal\n");
06144       return -1;
06145    }
06146    
06147    *s++ = 0;
06148    if (strlen(tmp) < 2){
06149       if(debug)
06150          printf("@@@@ Bad MHz digits: %s\n", tmp);
06151       return -1;
06152    }
06153     
06154    if (strlen(s) < 3){
06155       if(debug)
06156          printf("@@@@ Bad KHz digits: %s\n", s);
06157       return -1;
06158    }
06159 
06160    if ((s[2] != '0') && (s[2] != '5')){
06161       if(debug)
06162          printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
06163       return -1;
06164    }
06165     
06166    band = rbi_mhztoband(tmp);
06167    if (band == -1){
06168       if(debug)
06169          printf("@@@@ Bad Band: %s\n", tmp);
06170       return -1;
06171    }
06172    
06173    txpl = rbi_pltocode(myrpt->txpl);
06174    
06175    if (txpl == -1){
06176       if(debug)
06177          printf("@@@@ Bad TX PL: %s\n", myrpt->txpl);
06178       return -1;
06179    }
06180    return 0;
06181 }

static int setrem ( struct rpt myrpt  )  [static]

Definition at line 7246 of file app_rpt.c.

References rpt::archivedir, ast_log(), donodelog(), rpt::freq, LOG_ERROR, modes, rpt::name, rpt::offset, rpt::p, rpt::powerlevel, rpt::remmode, rpt::remote, rpt_telemetry(), rpt::rxpl, rpt::rxplon, setrbi_check(), SETREMOTE, rpt::txpl, and rpt::txplon.

Referenced by function_remote(), and rpt_exec().

07247 {
07248 char  str[300];
07249 char  *offsets[] = {"MINUS","SIMPLEX","PLUS"};
07250 char  *powerlevels[] = {"LOW","MEDIUM","HIGH"};
07251 char  *modes[] = {"FM","USB","LSB","AM"};
07252 int   res = -1;
07253 
07254    if (myrpt->p.archivedir)
07255    {
07256       sprintf(str,"FREQ,%s,%s,%s,%s,%s,%s,%d,%d",myrpt->freq,
07257          modes[(int)myrpt->remmode],
07258          myrpt->txpl,myrpt->rxpl,offsets[(int)myrpt->offset],
07259          powerlevels[(int)myrpt->powerlevel],myrpt->txplon,
07260          myrpt->rxplon);
07261       donodelog(myrpt,str);
07262    }
07263    if(!strcmp(myrpt->remote, remote_rig_ft897))
07264    {
07265       rpt_telemetry(myrpt,SETREMOTE,NULL);
07266       res = 0;
07267    }
07268    if(!strcmp(myrpt->remote, remote_rig_ic706))
07269    {
07270       rpt_telemetry(myrpt,SETREMOTE,NULL);
07271       res = 0;
07272    }
07273    else if(!strcmp(myrpt->remote, remote_rig_rbi))
07274    {
07275       res = setrbi_check(myrpt);
07276       if (!res)
07277       {
07278          rpt_telemetry(myrpt,SETREMOTE,NULL);
07279          res = 0;
07280       }
07281    }
07282    else if(!strcmp(myrpt->remote, remote_rig_kenwood)) {
07283       rpt_telemetry(myrpt,SETREMOTE,NULL);
07284       res = 0;
07285    }
07286    else
07287       res = 0;
07288 
07289    if (res < 0) ast_log(LOG_ERROR,"Unable to send remote command on node %s\n",myrpt->name);
07290 
07291    return res;
07292 }

static int simple_command_ft897 ( struct rpt myrpt,
char  command 
) [static]

Definition at line 6441 of file app_rpt.c.

References serial_remote_io().

Referenced by closerem_ft897(), rpt_tele_thread(), and set_ft897().

06442 {
06443    unsigned char cmdstr[5];
06444    
06445    memset(cmdstr, 0, 5);
06446 
06447    cmdstr[4] = command; 
06448 
06449    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06450 
06451 }

static int simple_command_ic706 ( struct rpt myrpt,
char  command,
char  subcommand 
) [static]

Definition at line 6895 of file app_rpt.c.

References civ_cmd(), rpt::civaddr, and rpt::p.

Referenced by set_ic706(), set_mode_ic706(), and set_offset_ic706().

06896 {
06897    unsigned char cmdstr[10];
06898    
06899    cmdstr[0] = cmdstr[1] = 0xfe;
06900    cmdstr[2] = myrpt->p.civaddr;
06901    cmdstr[3] = 0xe0;
06902    cmdstr[4] = command;
06903    cmdstr[5] = subcommand;
06904    cmdstr[6] = 0xfd;
06905 
06906    return(civ_cmd(myrpt,cmdstr,7));
06907 }

static char* skipchars ( char *  string,
char *  charlist 
) [static]

Definition at line 1449 of file app_rpt.c.

Referenced by function_autopatchup().

01450 {
01451 int i;   
01452    while(*string){
01453       for(i = 0; charlist[i] ; i++){
01454          if(*string == charlist[i]){
01455             string++;
01456             break;
01457          }
01458       }
01459       if(!charlist[i])
01460          return string;
01461    }
01462    return string;
01463 }  

static int split_ctcss_freq ( char *  hertz,
char *  decimal,
char *  freq 
) [static]

Definition at line 6294 of file app_rpt.c.

References MAXREMSTR.

Referenced by set_ctcss_freq_ft897().

06295 {
06296    char freq_copy[MAXREMSTR];
06297    char *decp;
06298 
06299    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
06300    if(decp){
06301       *decp++ = 0;
06302       strncpy(hertz, freq_copy, MAXREMSTR);
06303       strncpy(decimal, decp, strlen(decp));
06304       decimal[strlen(decp)] = '\0';
06305       return 0;
06306    }
06307    else
06308       return -1;
06309 }

static int split_freq ( char *  mhz,
char *  decimals,
char *  freq 
) [static]

Definition at line 6271 of file app_rpt.c.

References MAXREMSTR.

Referenced by check_tx_freq(), function_remote(), multimode_bump_freq_ft897(), multimode_bump_freq_ic706(), rpt_tele_thread(), service_scan(), set_freq_ft897(), set_freq_ic706(), and setkenwood().

06272 {
06273    char freq_copy[MAXREMSTR];
06274    char *decp;
06275 
06276    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
06277    if(decp){
06278       *decp++ = 0;
06279       strncpy(mhz, freq_copy, MAXREMSTR);
06280       strcpy(decimals, "00000");
06281       strncpy(decimals, decp, strlen(decp));
06282       decimals[5] = 0;
06283       return 0;
06284    }
06285    else
06286       return -1;
06287 
06288 }

static void stop_scan ( struct rpt myrpt  )  [static]

Definition at line 7470 of file app_rpt.c.

References rpt::hfscanstop, rpt_telemetry(), and SCAN.

Referenced by handle_remote_dtmf_digit().

07471 {
07472    myrpt->hfscanstop = 1;
07473    rpt_telemetry(myrpt,SCAN,0);
07474 }

static int telem_any ( struct rpt myrpt,
struct ast_channel chan,
char *  entry 
) [static]

Definition at line 2667 of file app_rpt.c.

References MORSE, retrieve_astcfgint(), sayfile(), send_morse(), and send_tone_telemetry().

Referenced by rpt_tele_thread(), and telem_lookup().

02668 {
02669    int res;
02670    char c;
02671    
02672    static int morsespeed;
02673    static int morsefreq;
02674    static int morseampl;
02675    static int morseidfreq = 0;
02676    static int morseidampl;
02677    static char mcat[] = MORSE;
02678    
02679    res = 0;
02680    
02681    if(!morseidfreq){ /* Get the morse parameters if not already loaded */
02682       morsespeed = retrieve_astcfgint(myrpt, mcat, "speed", 5, 20, 20);
02683          morsefreq = retrieve_astcfgint(myrpt, mcat, "frequency", 300, 3000, 800);
02684          morseampl = retrieve_astcfgint(myrpt, mcat, "amplitude", 200, 8192, 4096);
02685       morseidampl = retrieve_astcfgint(myrpt, mcat, "idamplitude", 200, 8192, 2048);
02686       morseidfreq = retrieve_astcfgint(myrpt, mcat, "idfrequency", 300, 3000, 330); 
02687    }
02688    
02689    /* Is it a file, or a tone sequence? */
02690          
02691    if(entry[0] == '|'){
02692       c = entry[1];
02693       if((c >= 'a')&&(c <= 'z'))
02694          c -= 0x20;
02695    
02696       switch(c){
02697          case 'I': /* Morse ID */
02698             res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl);
02699             break;
02700          
02701          case 'M': /* Morse Message */
02702             res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl);
02703             break;
02704          
02705          case 'T': /* Tone sequence */
02706             res = send_tone_telemetry(chan, entry + 2);
02707             break;
02708          default:
02709             res = -1;
02710       }
02711    }
02712    else
02713       res = sayfile(chan, entry); /* File */
02714    return res;
02715 }

static int telem_lookup ( struct rpt myrpt,
struct ast_channel chan,
char *  node,
char *  name 
) [static]

Definition at line 2723 of file app_rpt.c.

References ast_log(), ast_strdupa, ast_variable_retrieve(), rpt::cfg, LOG_WARNING, telem_any(), and TELEMETRY.

Referenced by rpt_tele_thread().

02724 {
02725    
02726    int res;
02727    int i;
02728    char *entry;
02729    char *telemetry;
02730    char *telemetry_save;
02731 
02732    res = 0;
02733    telemetry_save = NULL;
02734    entry = NULL;
02735    
02736    /* Retrieve the section name for telemetry from the node section */
02737    telemetry = (char *) ast_variable_retrieve(myrpt->cfg, node, TELEMETRY);
02738    if(telemetry ){
02739       telemetry_save = ast_strdupa(telemetry);
02740       if(!telemetry_save){
02741          ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n");
02742          return res;
02743       }
02744       entry = (char *) ast_variable_retrieve(myrpt->cfg, telemetry_save, name);
02745    }
02746    
02747    /* Try to look up the telemetry name */   
02748 
02749    if(!entry){
02750       /* Telemetry name wasn't found in the config file, use the default */
02751       for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
02752          if(!strcasecmp(tele_defs[i].name, name))
02753             entry = tele_defs[i].value;
02754       }
02755    }
02756    if(entry){  
02757       if(strlen(entry))
02758          telem_any(myrpt,chan, entry);
02759    }
02760    else{
02761       res = -1;
02762    }
02763    return res;
02764 }

static int unload_module ( void   )  [static]

Definition at line 11610 of file app_rpt.c.

References ast_cli_unregister(), ast_mutex_destroy(), ast_unregister_application(), lock, name, rpt::nodes, and rpt_vars.

11612 {
11613    int i;
11614 
11615 #ifdef   OLD_ASTERISK
11616    STANDARD_HANGUP_LOCALUSERS;
11617 #endif
11618    for(i = 0; i < nrpts; i++) {
11619       if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue;
11620                 ast_mutex_destroy(&rpt_vars[i].lock);
11621                 ast_mutex_destroy(&rpt_vars[i].remlock);
11622    }
11623    i = ast_unregister_application(app);
11624 
11625    /* Unregister cli extensions */
11626    ast_cli_unregister(&cli_debug);
11627    ast_cli_unregister(&cli_dump);
11628    ast_cli_unregister(&cli_stats);
11629    ast_cli_unregister(&cli_lstats);
11630    ast_cli_unregister(&cli_nodes);
11631    ast_cli_unregister(&cli_reload);
11632    ast_cli_unregister(&cli_restart);
11633    ast_cli_unregister(&cli_fun);
11634 
11635    return i;
11636 }

static int vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7079 of file app_rpt.c.

References civ_cmd(), rpt::civaddr, and rpt::p.

Referenced by set_ic706().

07080 {
07081    unsigned char cmdstr[10];
07082    
07083    cmdstr[0] = cmdstr[1] = 0xfe;
07084    cmdstr[2] = myrpt->p.civaddr;
07085    cmdstr[3] = 0xe0;
07086    cmdstr[4] = 7;
07087    cmdstr[5] = 0xfd;
07088 
07089    return(civ_cmd(myrpt,cmdstr,6));
07090 }

static void wait_interval ( struct rpt myrpt,
int  type,
struct ast_channel chan 
) [static]

Definition at line 2842 of file app_rpt.c.

References ast_log(), ast_safe_sleep(), get_wait_interval(), and LOG_NOTICE.

Referenced by rpt_tele_thread().

02843 {
02844    int interval;
02845    interval = get_wait_interval(myrpt, type);
02846    if(debug)
02847       ast_log(LOG_NOTICE," Delay interval = %d\n", interval);
02848    if(interval)
02849       ast_safe_sleep(chan,interval);
02850    if(debug)
02851       ast_log(LOG_NOTICE,"Delay complete\n");
02852    return;
02853 }


Variable Documentation

char* app = "Rpt" [static]

Definition at line 313 of file app_rpt.c.

struct ast_cli_entry cli_debug [static]

Initial value:

        { { "rpt", "debug", "level" }, rpt_do_debug, 
      "Enable app_rpt debugging", debug_usage }

Definition at line 934 of file app_rpt.c.

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 938 of file app_rpt.c.

struct ast_cli_entry cli_fun [static]

Initial value:

        { { "rpt", "fun" }, rpt_do_fun,
      "Execute a DTMF function", fun_usage }

Definition at line 962 of file app_rpt.c.

struct ast_cli_entry cli_lstats [static]

Initial value:

        { { "rpt", "lstats" }, rpt_do_lstats,
      "Dump link statistics", dump_lstats }

Definition at line 950 of file app_rpt.c.

struct ast_cli_entry cli_nodes [static]

Initial value:

        { { "rpt", "nodes" }, rpt_do_nodes,
      "Dump node list", dump_nodes }

Definition at line 946 of file app_rpt.c.

struct ast_cli_entry cli_reload [static]

Initial value:

        { { "rpt", "reload" }, rpt_do_reload,
      "Reload app_rpt config", reload_usage }

Definition at line 954 of file app_rpt.c.

struct ast_cli_entry cli_restart [static]

Initial value:

        { { "rpt", "restart" }, rpt_do_restart,
      "Restart app_rpt", restart_usage }

Definition at line 958 of file app_rpt.c.

struct ast_cli_entry cli_stats [static]

Initial value:

        { { "rpt", "stats" }, rpt_do_stats,
      "Dump node statistics", dump_stats }

Definition at line 942 of file app_rpt.c.

int debug = 0 [static]

Definition at line 352 of file app_rpt.c.

Referenced by add_sdp(), add_t38_sdp(), aji_load_config(), check_user_full(), dladdr(), dlclose(), dlsymIntern(), error(), findFile(), get_mach_header_from_NSModule(), getSearchPath(), handle_request(), insertStatus(), loadModule(), lookupStatus(), process_sdp(), promoteLocalToGlobal(), reference(), search_linked_libs(), set_destination(), and sip_sendtext().

char debug_usage[] [static]

Initial value:

"Usage: rpt debug level {0-7}\n"
"       Enables debug messages in app_rpt\n"

Definition at line 901 of file app_rpt.c.

char* descrip [static]

Definition at line 317 of file app_rpt.c.

char* discstr = "!!DISCONNECT!!"

Definition at line 372 of file app_rpt.c.

char dump_lstats[] [static]

Initial value:

"Usage: rpt lstats <nodename>\n"
"       Dumps link statistics to console\n"

Definition at line 913 of file app_rpt.c.

char dump_nodes[] [static]

Initial value:

"Usage: rpt nodes <nodename>\n"
"       Dumps a list of directly and indirectly connected nodes to the console\n"

Definition at line 917 of file app_rpt.c.

char dump_stats[] [static]

Initial value:

"Usage: rpt stats <nodename>\n"
"       Dumps node statistics to console\n"

Definition at line 909 of file app_rpt.c.

char dump_usage[] [static]

Initial value:

"Usage: rpt dump <nodename>\n"
"       Dumps struct debug info to log\n"

Definition at line 905 of file app_rpt.c.

char fun_usage[] [static]

Initial value:

"Usage: rpt fun <nodename> <command>\n"
"       Send a DTMF function to a node\n"

Definition at line 929 of file app_rpt.c.

struct function_table_tag function_table[] [static]

Definition at line 1013 of file app_rpt.c.

int max_chan_stat[] = {22000,1000,22000,100,22000,2000,22000}

Definition at line 359 of file app_rpt.c.

int nrpts = 0 [static]

Definition at line 353 of file app_rpt.c.

char reload_usage[] [static]

Initial value:

"Usage: rpt reload\n"
"       Reloads app_rpt running config parameters\n"

Definition at line 921 of file app_rpt.c.

char remdtmfstr[] = "0123456789*#ABCD" [static]

Definition at line 355 of file app_rpt.c.

char* remote_rig_ft897 = "ft897" [static]

Definition at line 373 of file app_rpt.c.

char* remote_rig_ic706 = "ic706" [static]

Definition at line 376 of file app_rpt.c.

char* remote_rig_kenwood = "kenwood" [static]

Definition at line 375 of file app_rpt.c.

char* remote_rig_rbi = "rbi" [static]

Definition at line 374 of file app_rpt.c.

char restart_usage[] [static]

Initial value:

"Usage: rpt restart\n"
"       Restarts app_rpt\n"

Definition at line 925 of file app_rpt.c.

pthread_t rpt_master_thread [static]

Definition at line 409 of file app_rpt.c.

struct rpt rpt_vars[MAXRPTS] [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]

Definition at line 407 of file app_rpt.c.

Referenced by tzparse(), and wait_for_answer().

char* synopsis = "Radio Repeater/Remote Base Control System" [static]

Definition at line 315 of file app_rpt.c.

char* tdesc = "Radio Repeater / Remote Base version 0.70 07/22/2007" [static]

Definition at line 311 of file app_rpt.c.

struct telem_defaults tele_defs[] [static]

Definition at line 971 of file app_rpt.c.


Generated on Wed Aug 15 01:24:38 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3