Fri Aug 24 02:22:54 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)
 Start a tone-list going.
void ast_playtones_stop (struct ast_channel *chan)
 Stop the tones from playing.
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 218 of file app_rpt.c.

#define AUTHLOGOUTTIME   25000

Definition at line 167 of file app_rpt.c.

#define AUTHTELLTIME   7000

Definition at line 165 of file app_rpt.c.

#define AUTHTXTIME   1000

Definition at line 166 of file app_rpt.c.

#define DEFAULT_CIV_ADDR   0x58

Definition at line 210 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_IOBASE   0x378

Definition at line 208 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_MONITOR_MIN_DISK_BLOCKS   10000

Definition at line 191 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_INACT_TIMEOUT   (15 * 60)

Definition at line 192 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT   (60 * 60)

Definition at line 193 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING   (3 * 60)

Definition at line 194 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ   30

Definition at line 195 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DELIMCHR   ','

Definition at line 186 of file app_rpt.c.

Referenced by finddelim().

#define DISC_TIME   10000

Definition at line 173 of file app_rpt.c.

Referenced by rpt().

#define DTMF_LOCAL_STARTTIME   500

Definition at line 225 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_LOCAL_TIME   250

Definition at line 224 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_TIMEOUT   3

Definition at line 162 of file app_rpt.c.

Referenced by handle_remote_dtmf_digit(), and rpt().

#define ENDCHAR   '#'

Definition at line 205 of file app_rpt.c.

Referenced by load_rpt_vars().

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

Definition at line 206 of file app_rpt.c.

Referenced by load_rpt_vars().

#define EXTNODES   "extnodes"

Definition at line 198 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCCHAR   '*'

Definition at line 204 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCTDELAY   1500

Definition at line 389 of file app_rpt.c.

#define FUNCTIONS   "functions"

Definition at line 201 of file app_rpt.c.

Referenced by load_rpt_vars().

#define HANGTIME   5000

Definition at line 383 of file app_rpt.c.

Referenced by load_rpt_vars().

#define IC706_PL_MEMORY_OFFSET   50

Definition at line 227 of file app_rpt.c.

Referenced by set_ic706().

#define IDTIME   300000

Definition at line 385 of file app_rpt.c.

Referenced by load_rpt_vars().

#define KENWOOD_RETRIES   5

Definition at line 163 of file app_rpt.c.

Referenced by sendrxkenwood().

#define LINKLISTSHORTTIME   200

Definition at line 159 of file app_rpt.c.

Referenced by __kickshort().

#define LINKLISTTIME   10000

Definition at line 158 of file app_rpt.c.

Referenced by rpt().

#define MACRO   "macro"

Definition at line 200 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MACROPTIME   500

Definition at line 161 of file app_rpt.c.

Referenced by rpt().

#define MACROTIME   100

Definition at line 160 of file app_rpt.c.

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

#define MAX_RETRIES   5

Definition at line 174 of file app_rpt.c.

Referenced by connect_link(), and function_ilink().

#define MAX_RETRIES_PERM   1000000000

Definition at line 175 of file app_rpt.c.

Referenced by connect_link().

#define MAX_STAT_LINKS   32

Definition at line 387 of file app_rpt.c.

Referenced by rpt_do_stats().

#define MAX_SYSSTATES   10

Definition at line 394 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXCONNECTTIME   5000

Definition at line 212 of file app_rpt.c.

Referenced by rpt().

#define MAXDTMF   32

Definition at line 155 of file app_rpt.c.

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

#define MAXLINKLIST   512

Definition at line 157 of file app_rpt.c.

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

#define MAXMACRO   2048

Definition at line 156 of file app_rpt.c.

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

#define MAXNODESTR   300

Definition at line 214 of file app_rpt.c.

Referenced by connect_link(), and function_ilink().

#define MAXPATCHCONTEXT   100

Definition at line 216 of file app_rpt.c.

Referenced by function_autopatchup(), and local_dtmf_helper().

#define MAXPEERSTR   31

Definition at line 183 of file app_rpt.c.

Referenced by rpt_do_lstats().

#define MAXREMSTR   15

Definition at line 184 of file app_rpt.c.

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

#define MAXRPTS   20

Definition at line 386 of file app_rpt.c.

#define MAXXLAT   20

Definition at line 391 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXXLATTIME   3

Definition at line 392 of file app_rpt.c.

Referenced by func_xlat().

#define MEMORY   "memory"

Definition at line 199 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MONITOR_DISK_BLOCKS_PER_MINUTE   38

Definition at line 189 of file app_rpt.c.

#define MORSE   "morse"

Definition at line 203 of file app_rpt.c.

Referenced by telem_any().

#define MSWAIT   200

Definition at line 382 of file app_rpt.c.

Referenced by rpt(), and rpt_call().

#define NODES   "nodes"

Definition at line 197 of file app_rpt.c.

Referenced by load_rpt_vars().

#define NRPTSTAT   7

Definition at line 360 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 388 of file app_rpt.c.

Referenced by load_rpt_vars().

#define QUOTECHR   34

Definition at line 187 of file app_rpt.c.

Referenced by finddelim().

#define REDUNDANT_TX_TIME   2000

Definition at line 177 of file app_rpt.c.

Referenced by rpt().

#define REM_SCANTIME   100

Definition at line 222 of file app_rpt.c.

Referenced by function_remote().

#define RETRY_TIMER_MS   5000

Definition at line 179 of file app_rpt.c.

Referenced by rpt().

#define rpt_mutex_lock (  )     ast_mutex_lock(x)

Definition at line 868 of file app_rpt.c.

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

#define rpt_mutex_unlock (  )     ast_mutex_unlock(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_tele_thread(), and rpt_telemetry().

#define START_DELAY   10

Definition at line 181 of file app_rpt.c.

Referenced by rpt(), and rpt_exec().

#define TELEMETRY   "telemetry"

Definition at line 202 of file app_rpt.c.

Referenced by telem_lookup().

#define TELEPARAMSIZE   256

Definition at line 220 of file app_rpt.c.

Referenced by rpt_telemetry().

#define TOTIME   180000

Definition at line 384 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 229 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 231 of file app_rpt.c.

anonymous enum

Enumerator:
REM_SIMPLEX 
REM_MINUS 
REM_PLUS 

Definition at line 240 of file app_rpt.c.

anonymous enum

Enumerator:
REM_LOWPWR 
REM_MEDPWR 
REM_HIPWR 

Definition at line 242 of file app_rpt.c.

anonymous enum

Enumerator:
DC_INDETERMINATE 
DC_REQ_FLUSH 
DC_ERROR 
DC_COMPLETE 
DC_COMPLETEQUIET 
DC_DOKEY 

Definition at line 244 of file app_rpt.c.

anonymous enum

Enumerator:
SOURCE_RPT 
SOURCE_LNK 
SOURCE_RMT 
SOURCE_PHONE 
SOURCE_DPHONE 

Definition at line 246 of file app_rpt.c.

anonymous enum

Enumerator:
DLY_TELEM 
DLY_ID 
DLY_UNKEY 
DLY_CALLTERM 
DLY_COMP 
DLY_LINKUNKEY 

Definition at line 248 of file app_rpt.c.

anonymous enum

Enumerator:
REM_MODE_FM 
REM_MODE_USB 
REM_MODE_LSB 
REM_MODE_AM 

Definition at line 250 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 252 of file app_rpt.c.

anonymous enum

Enumerator:
TOP_TOP 
TOP_WON 
WON_BEFREAD 
BEFREAD_AFTERREAD 

Definition at line 356 of file app_rpt.c.


Function Documentation

static void __kickshort ( struct rpt myrpt  )  [static]

Definition at line 1343 of file app_rpt.c.

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

Referenced by connect_link(), and rpt().

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

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

Definition at line 1294 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().

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

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 
)

Start a tone-list going.

Definition at line 212 of file indications.c.

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

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dialtone_indicate(), do_dtmf_local(), handle_playtones(), play_dialtone(), playtone(), read_exec(), and send_digit_to_chan().

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

void ast_playtones_stop ( struct ast_channel chan  ) 

Stop the tones from playing.

Stop the tones from playing

Definition at line 325 of file indications.c.

References ast_deactivate_generator().

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_end(), disa_exec(), handle_stopplaytones(), playtone(), read_exec(), and stop_indicate().

00326 {
00327    ast_deactivate_generator(chan);
00328 }

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

Definition at line 8293 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().

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

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

Definition at line 7305 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().

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

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

Definition at line 6320 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().

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

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

Definition at line 6691 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().

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

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

Definition at line 6182 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

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

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

Definition at line 6210 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

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

static char check_tx_freq ( struct rpt myrpt  )  [static]

Definition at line 7323 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.

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

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

Definition at line 5858 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().

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

static int closerem ( struct rpt myrpt  )  [static]

Definition at line 7293 of file app_rpt.c.

References closerem_ft897(), and rpt::remote.

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

static int closerem_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6631 of file app_rpt.c.

References simple_command_ft897().

Referenced by closerem().

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

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

Definition at line 5146 of file app_rpt.c.

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

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

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

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

Definition at line 4407 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().

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

static int decimals2int ( char *  fraction  )  [static]

Definition at line 6251 of file app_rpt.c.

Referenced by check_tx_freq().

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

static long diskavail ( struct rpt myrpt  )  [static]

Definition at line 1022 of file app_rpt.c.

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

Referenced by rpt().

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

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

Definition at line 1087 of file app_rpt.c.

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

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

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

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

Definition at line 1036 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().

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

static void do_scheduler ( struct rpt myrpt  )  [static]

Definition at line 8528 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().

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

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

Definition at line 1062 of file app_rpt.c.

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

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

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

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

Definition at line 1234 of file app_rpt.c.

Referenced by check_tx_freq().

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

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

Definition at line 1254 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().

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

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

Definition at line 1189 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().

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

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

Definition at line 4917 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.

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

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

Definition at line 4820 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.

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

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

Definition at line 5018 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.

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

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

Definition at line 4570 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.

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

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

Definition at line 4973 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.

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

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

Definition at line 7650 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.

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

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

Definition at line 4942 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.

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

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

Definition at line 2769 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().

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

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

Definition at line 5221 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().

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

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

Definition at line 5424 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().

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

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

Definition at line 8232 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.

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

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

Definition at line 8122 of file app_rpt.c.

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

Referenced by handle_remote_data(), and handle_remote_phone_dtmf().

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

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

Definition at line 8268 of file app_rpt.c.

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

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

static int ic706_pltocode ( char *  str  )  [static]

Definition at line 6777 of file app_rpt.c.

References s.

Referenced by set_ic706().

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

static int kenwood_pltocode ( char *  str  )  [static]

Definition at line 5890 of file app_rpt.c.

References s.

Referenced by setkenwood().

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

static int load_module ( void   )  [static]

Definition at line 11640 of file app_rpt.c.

References ast_cli_register(), ast_pthread_create, ast_register_application(), cli_debug, cli_dump, cli_fun, cli_lstats, cli_nodes, cli_reload, cli_restart, cli_stats, rpt_exec(), and rpt_master().

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

Definition at line 1568 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(), and rpt_master().

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

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

Definition at line 8355 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().

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

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

Definition at line 1424 of file app_rpt.c.

Referenced by function_autopatchup().

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

static int mem2vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7091 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 7454 of file app_rpt.c.

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

Referenced by function_remote(), and service_scan().

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

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

Definition at line 6643 of file app_rpt.c.

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

Referenced by multimode_bump_freq().

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

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

Definition at line 7187 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().

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

static int multimode_capable ( struct rpt myrpt  )  [static]

Definition at line 877 of file app_rpt.c.

References rpt::remote.

Referenced by function_remote(), and rpt_tele_thread().

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

static int myatoi ( char *  str  )  [static]

Definition at line 1466 of file app_rpt.c.

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

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

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

Definition at line 1476 of file app_rpt.c.

Referenced by rpt_do_nodes(), and rpt_tele_thread().

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

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

Definition at line 1356 of file app_rpt.c.

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

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

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

static int openserial ( char *  fname  )  [static]

Definition at line 1153 of file app_rpt.c.

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

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

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

Definition at line 2408 of file app_rpt.c.

References play_tone_pair().

Referenced by send_morse().

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

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

Definition at line 2403 of file app_rpt.c.

References play_tone_pair().

Referenced by rpt_tele_thread(), and send_morse().

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

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

Definition at line 2389 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().

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

static void queue_id ( struct rpt myrpt  )  [static]

Definition at line 8514 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().

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

static int rbi_mhztoband ( char *  str  )  [static]

Definition at line 5596 of file app_rpt.c.

Referenced by setrbi(), and setrbi_check().

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

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

Definition at line 5753 of file app_rpt.c.

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

Referenced by setrbi().

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

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

Definition at line 5727 of file app_rpt.c.

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

Referenced by rbi_out().

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

static int rbi_pltocode ( char *  str  )  [static]

Definition at line 5632 of file app_rpt.c.

References s.

Referenced by setrbi(), and setrbi_check().

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

static int reload ( void   )  [static]

Definition at line 11679 of file app_rpt.c.

References reload(), and rpt_vars.

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

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

Definition at line 7551 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().

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

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

Definition at line 1541 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().

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

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

Definition at line 8649 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, f, ast_channel::fds, free, func_xlat(), handle_link_data(), handle_link_phone_dtmf(), rpt::hangtime, rpt_link::hasconnected, ID, IDTALKOVER, rpt::idtime, rpt::idtimer, rpt::inxlat, rpt_link::isremote, rpt::keyed, rpt_link::killme, rpt::lastdtmfcommand, rpt_link::lastf1, rpt::lastf1, rpt_link::lastf2, rpt::lastf2, rpt::lastnodewhichkeyedusup, rpt_link::lastrx, rpt_link::lastrx1, rpt_link::lasttx, LINKLISTTIME, rpt_link::linklisttimer, rpt::links, rpt::linktolink, LINKUNKEY, load_rpt_vars(), local_dtmf_helper(), rpt::localtx, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macrobuf, MACROPTIME, MACROTIME, rpt::macrotimer, rpt_link::max_retries, MAXCONNECTTIME, MAXLINKLIST, MAXMACRO, rpt_link::mode, rpt_tele::mode, rpt::monchannel, rpt::monminblocks, rpt::monstream, MSWAIT, rpt::mustid, rpt_link::name, rpt::name, rpt_link::next, rpt_tele::next, rpt::notelemtx, option_verbose, rpt_link::outbound, rpt::p, rpt_link::pchan, rpt::pchannel, rpt_link::phonemode, rpt::politeid, rpt_link::prev, queue_id(), rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, REMDISC, rpt_link::rerxtimer, rpt::rerxtimer, rpt_link::retries, RETRY_TIMER_MS, rpt_link::retrytimer, rpt_link::retxtimer, rpt::retxtimer, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, rpt::rxchannel, s, rpt::s, rpt::scram, rpt::skedtimer, START_DELAY, rpt::startupmacro, rpt::sysstate_cur, t, rpt::tailevent, rpt::tailid, rpt::tailmessages, rpt::tailmessagetime, TAILMSG, rpt::tailtimer, rpt::tele, rpt_link::thisconnected, TIMEOUT, rpt::timeouts, rpt::tmsgtimer, rpt::tonotify, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, 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.

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

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

Definition at line 4109 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().

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

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

Definition at line 1918 of file app_rpt.c.

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

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

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

Definition at line 1940 of file app_rpt.c.

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

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

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

Definition at line 2360 of file app_rpt.c.

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

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

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

Definition at line 2188 of file app_rpt.c.

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

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

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

Definition at line 2278 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.

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

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

Definition at line 2328 of file app_rpt.c.

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

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

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

Definition at line 2343 of file app_rpt.c.

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

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

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

Definition at line 1963 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.

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

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

Definition at line 10370 of file app_rpt.c.

References ast_log(), ast_safe_sleep(), ast_strlen_zero(), rpt_tele::chan, f, LOG_NOTICE, LOG_WARNING, rpt::name, name, rpt::p, rpt_vars, rpt::s, START_DELAY, strsep(), rpt::sysstate_cur, t, and sysstate::txdisable.

Referenced by load_module().

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

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

Definition at line 1530 of file app_rpt.c.

References ast_localtime(), and localtime_r.

Referenced by do_scheduler(), and rpt_tele_thread().

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

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

Definition at line 10206 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, 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().

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

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

Definition at line 2856 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, get_wait_interval(), rpt_link::hasconnected, ID, ID1, IDTALKOVER, INVFREQ, rpt_link::isremote, LASTNODEKEY, LINKUNKEY, rpt_link::linkunkeytocttimer, LOG_ERROR, LOG_NOTICE, LOG_WARNING, LOGINREQ, MACRO_BUSY, MACRO_NOTFOUND, malloc, MAXLINKLIST, MAXREMSTR, MEMNOTFOUND, rpt_link::mode, rpt_tele::mode, multimode_capable(), mycompar(), rpt_tele::mylink, rpt_link::name, rpt_link::next, rpt_tele::next, rpt_tele::param, play_tone(), rpt_link::prev, PROC, REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, REM_PLUS, REM_SIMPLEX, REMALREADY, REMDISC, REMGO, REMLOGIN, REMLONGSTATUS, REMMODE, REMNOTFOUND, REMSHORTSTATUS, REMXXX, REV_PATCH, rpt_tele::rpt, rpt_localtime(), rpt_mutex_lock, rpt_mutex_unlock, s, saycharstr(), sayfile(), saynum(), SCAN, SCANSTAT, service_scan(), set_ft897(), set_ic706(), set_mode_ft897(), set_mode_ic706(), setkenwood(), setrbi(), SETREMOTE, simple_command_ft897(), split_freq(), STATS_TIME, STATS_VERSION, STATUS, strsep(), rpt_tele::submode, t, TAILMSG, telem_any(), telem_lookup(), TERM, TEST_TONE, rpt_link::thisconnected, TIMEOUT, TIMEOUT_WARNING, TUNE, UNAUTHTX, UNKEY, and wait_interval().

Referenced by rpt_telemetry().

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

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

Definition at line 4064 of file app_rpt.c.

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

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

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

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

Definition at line 2640 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

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

Definition at line 2627 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and telem_any().

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

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

Definition at line 2653 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

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

Definition at line 7104 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 4355 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().

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

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

Definition at line 2414 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().

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

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

Definition at line 2576 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().

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

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

Definition at line 5875 of file app_rpt.c.

References serial_remote_io().

Referenced by sendrxkenwood().

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

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

Definition at line 5981 of file app_rpt.c.

References KENWOOD_RETRIES, and sendkenwood().

Referenced by setkenwood().

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

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

Definition at line 5775 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().

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

static int service_scan ( struct rpt myrpt  )  [static]

Definition at line 7480 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().

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

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

Definition at line 6540 of file app_rpt.c.

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

Referenced by set_ft897().

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

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

Definition at line 6517 of file app_rpt.c.

References serial_remote_io().

Referenced by set_ft897().

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

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

Definition at line 7002 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 6409 of file app_rpt.c.

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

Referenced by multimode_bump_freq_ft897(), and set_ft897().

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

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

Definition at line 6912 of file app_rpt.c.

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

Referenced by set_ic706().

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

static int set_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6575 of file app_rpt.c.

References REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, rpt::remmode, set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), and simple_command_ft897().

Referenced by rpt_tele_thread().

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

static int set_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7119 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

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

Definition at line 6484 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().

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

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

Definition at line 6973 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().

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

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

Definition at line 6454 of file app_rpt.c.

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

Referenced by set_ft897().

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

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

Definition at line 6946 of file app_rpt.c.

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

Referenced by set_ic706().

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

static int setkenwood ( struct rpt myrpt  )  [static]

Definition at line 5996 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().

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

static int setrbi ( struct rpt myrpt  )  [static]

Definition at line 6035 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().

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

static int setrbi_check ( struct rpt myrpt  )  [static]

Definition at line 6127 of file app_rpt.c.

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

Referenced by setrbi(), and setrem().

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

static int setrem ( struct rpt myrpt  )  [static]

Definition at line 7245 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().

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

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

Definition at line 6440 of file app_rpt.c.

References serial_remote_io().

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

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

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

Definition at line 6894 of file app_rpt.c.

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

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

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

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

Definition at line 1448 of file app_rpt.c.

Referenced by function_autopatchup().

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

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

Definition at line 6293 of file app_rpt.c.

References MAXREMSTR.

Referenced by set_ctcss_freq_ft897().

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

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

Definition at line 6270 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().

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

static void stop_scan ( struct rpt myrpt  )  [static]

Definition at line 7469 of file app_rpt.c.

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

Referenced by handle_remote_dtmf_digit().

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

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

Definition at line 2666 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and telem_lookup().

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

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

Definition at line 2722 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

static int unload_module ( void   )  [static]

Definition at line 11609 of file app_rpt.c.

References ast_cli_unregister(), ast_mutex_destroy(), ast_unregister_application(), cli_debug, cli_dump, cli_fun, cli_lstats, cli_nodes, cli_reload, cli_restart, cli_stats, lock, name, rpt::nodes, and rpt_vars.

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

static int vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7078 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 2841 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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


Variable Documentation

char* app = "Rpt" [static]

Definition at line 312 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 933 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_dump [static]

Initial value:

        { { "rpt", "dump" }, rpt_do_dump,
      "Dump app_rpt structs for debugging", dump_usage }

Definition at line 937 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_fun [static]

Initial value:

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

Definition at line 961 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_lstats [static]

Initial value:

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

Definition at line 949 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_nodes [static]

Initial value:

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

Definition at line 945 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_reload [static]

Initial value:

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

Definition at line 953 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 957 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_stats [static]

Initial value:

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

Definition at line 941 of file app_rpt.c.

Referenced by load_module(), and unload_module().

int debug = 0 [static]

Definition at line 351 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 900 of file app_rpt.c.

char* descrip [static]

Definition at line 316 of file app_rpt.c.

char* discstr = "!!DISCONNECT!!"

Definition at line 371 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 912 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 916 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 908 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 904 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 928 of file app_rpt.c.

struct function_table_tag function_table[] [static]

Definition at line 1012 of file app_rpt.c.

Referenced by collect_function_digits().

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

Definition at line 358 of file app_rpt.c.

int nrpts = 0 [static]

Definition at line 352 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 920 of file app_rpt.c.

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

Definition at line 354 of file app_rpt.c.

char* remote_rig_ft897 = "ft897" [static]

Definition at line 372 of file app_rpt.c.

char* remote_rig_ic706 = "ic706" [static]

Definition at line 375 of file app_rpt.c.

char* remote_rig_kenwood = "kenwood" [static]

Definition at line 374 of file app_rpt.c.

char* remote_rig_rbi = "rbi" [static]

Definition at line 373 of file app_rpt.c.

char restart_usage[] [static]

Initial value:

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

Definition at line 924 of file app_rpt.c.

pthread_t rpt_master_thread [static]

Definition at line 408 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 406 of file app_rpt.c.

Referenced by tzparse(), and wait_for_answer().

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

Definition at line 314 of file app_rpt.c.

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

Definition at line 310 of file app_rpt.c.

struct telem_defaults tele_defs[] [static]

Definition at line 970 of file app_rpt.c.

Referenced by telem_lookup().


Generated on Fri Aug 24 02:22:56 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1