Mon Nov 24 15:34:23 2008

Asterisk developer's documentation


app_rpt.c File Reference

Radio Repeater / Remote Base program version 0.73 09/04/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 <netinet/in.h>
#include <arpa/inet.h>
#include <termios.h>
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
#include "asterisk/cdr.h"
#include "asterisk/dahdi_compat.h"
#include "asterisk/tonezone_compat.h"

Go to the source code of this file.

Data Structures

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

Defines

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

Enumerations

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

Functions

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

Variables

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


Detailed Description

Radio Repeater / Remote Base program version 0.73 09/04/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 ALLOW_LOCAL_CHANNELS

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

Referenced by rpt_do_stats().

#define MAX_SYSSTATES   10

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

#define MAXXLAT   20

Definition at line 390 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXXLATTIME   3

Definition at line 391 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 381 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 359 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 387 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 867 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 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 START_DELAY   2

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 383 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 231 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 233 of file app_rpt.c.

anonymous enum

Enumerator:
REM_SIMPLEX 
REM_MINUS 
REM_PLUS 

Definition at line 242 of file app_rpt.c.

anonymous enum

Enumerator:
REM_LOWPWR 
REM_MEDPWR 
REM_HIPWR 

Definition at line 244 of file app_rpt.c.

anonymous enum

Enumerator:
DC_INDETERMINATE 
DC_REQ_FLUSH 
DC_ERROR 
DC_COMPLETE 
DC_COMPLETEQUIET 
DC_DOKEY 

Definition at line 246 of file app_rpt.c.

anonymous enum

Enumerator:
SOURCE_RPT 
SOURCE_LNK 
SOURCE_RMT 
SOURCE_PHONE 
SOURCE_DPHONE 

Definition at line 248 of file app_rpt.c.

anonymous enum

Enumerator:
DLY_TELEM 
DLY_ID 
DLY_UNKEY 
DLY_CALLTERM 
DLY_COMP 
DLY_LINKUNKEY 

Definition at line 250 of file app_rpt.c.

anonymous enum

Enumerator:
REM_MODE_FM 
REM_MODE_USB 
REM_MODE_LSB 
REM_MODE_AM 

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

anonymous enum

Enumerator:
TOP_TOP 
TOP_WON 
WON_BEFREAD 
BEFREAD_AFTERREAD 

Definition at line 355 of file app_rpt.c.


Function Documentation

static void __kickshort ( struct rpt myrpt  )  [static]

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

01394 {
01395 struct rpt_link *l;
01396 
01397    for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
01398    {
01399       /* if is not a real link, ignore it */
01400       if (l->name[0] == '0') continue;
01401       l->linklisttimer = LINKLISTSHORTTIME;
01402    }
01403    return;
01404 }

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

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

01345 {
01346 struct rpt_link *l;
01347 char mode;
01348 int   i,spos;
01349 
01350    buf[0] = 0; /* clear output buffer */
01351    /* go thru all links */
01352    for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
01353    {
01354       /* if is not a real link, ignore it */
01355       if (l->name[0] == '0') continue;
01356       /* dont count our stuff */
01357       if (l == mylink) continue;
01358       if (mylink && (!strcmp(l->name,mylink->name))) continue;
01359       /* figure out mode to report */
01360       mode = 'T'; /* use Tranceive by default */
01361       if (!l->mode) mode = 'R'; /* indicate RX for our mode */
01362       if (!l->thisconnected)  mode = 'C'; /* indicate connecting */
01363       spos = strlen(buf); /* current buf size (b4 we add our stuff) */
01364       if (spos)
01365       {
01366          strcat(buf,",");
01367          spos++;
01368       }
01369       /* add nodes into buffer */
01370       if (l->linklist[0])
01371       {
01372          snprintf(buf + spos,MAXLINKLIST - spos,
01373             "%c%s,%s",mode,l->name,l->linklist);
01374       }
01375       else /* if no nodes, add this node into buffer */
01376       {
01377          snprintf(buf + spos,MAXLINKLIST - spos,
01378             "%c%s",mode,l->name);
01379       }
01380       /* if we are in tranceive mode, let all modes stand */
01381       if (mode == 'T') continue;
01382       /* downgrade everyone on this node if appropriate */
01383       for(i = spos; buf[i]; i++)
01384       {
01385          if (buf[i] == 'T') buf[i] = mode;
01386          if ((buf[i] == 'R') && (mode == 'C')) buf[i] = mode;
01387       }
01388    }
01389    return;
01390 }

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

AST_MUTEX_DEFINE_STATIC ( nodelookuplock   ) 

AST_MUTEX_DEFINE_STATIC ( nodeloglock   ) 

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

Definition at line 212 of file indications.c.

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

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

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

void ast_playtones_stop ( struct ast_channel chan  ) 

Stop the tones from playing

Definition at line 325 of file indications.c.

References ast_deactivate_generator().

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

00326 {
00327    ast_deactivate_generator(chan);
00328 }

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

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

08401 {
08402    char *val, *s, *s1, *s2, *tele;
08403    char tmp[300], deststr[300] = "";
08404 
08405    val = node_lookup(myrpt,l->name);
08406    if (!val)
08407    {
08408       fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name);
08409       return -1;
08410    }
08411 
08412    rpt_mutex_lock(&myrpt->lock);
08413    /* remove from queue */
08414    remque((struct qelem *) l);
08415    rpt_mutex_unlock(&myrpt->lock);
08416    strncpy(tmp,val,sizeof(tmp) - 1);
08417    s = tmp;
08418    s1 = strsep(&s,",");
08419    s2 = strsep(&s,",");
08420    snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
08421    tele = strchr(deststr, '/');
08422    if (!tele) {
08423       fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr);
08424       return -1;
08425    }
08426    *tele++ = 0;
08427    l->elaptime = 0;
08428    l->connecttime = 0;
08429    l->thisconnected = 0;
08430    l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
08431    if (l->chan){
08432       ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
08433       ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
08434       l->chan->whentohangup = 0;
08435       l->chan->appl = "Apprpt";
08436       l->chan->data = "(Remote Rx)";
08437       if (option_verbose > 2)
08438          ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n",
08439             deststr, tele, l->chan->name);
08440       if(l->chan->cid.cid_num)
08441          free(l->chan->cid.cid_num);
08442       l->chan->cid.cid_num = strdup(myrpt->name);
08443                 ast_call(l->chan,tele,999); 
08444 
08445    }
08446    else 
08447    {
08448       if (option_verbose > 2)
08449          ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n",
08450             deststr,tele,l->chan->name);
08451       return -1;
08452    }
08453    rpt_mutex_lock(&myrpt->lock);
08454    /* put back in queue */
08455    insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
08456    rpt_mutex_unlock(&myrpt->lock);
08457    ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name);
08458    return 0;
08459 }

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

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

07400 {
07401    if(!strcmp(myrpt->remote, remote_rig_ft897))
07402       return check_freq_ft897(m, d, defmode);
07403    else if(!strcmp(myrpt->remote, remote_rig_ic706))
07404       return check_freq_ic706(m, d, defmode);
07405    else if(!strcmp(myrpt->remote, remote_rig_rbi))
07406       return check_freq_rbi(m, d, defmode);
07407    else if(!strcmp(myrpt->remote, remote_rig_kenwood))
07408       return check_freq_kenwood(m, d, defmode);
07409    else
07410       return -1;
07411 }

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

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

06415 {
06416    int dflmd = REM_MODE_FM;
06417 
06418    if(m == 1){ /* 160 meters */
06419       dflmd =  REM_MODE_LSB; 
06420       if(d < 80000)
06421          return -1;
06422    }
06423    else if(m == 3){ /* 80 meters */
06424       dflmd = REM_MODE_LSB;
06425       if(d < 50000)
06426          return -1;
06427    }
06428    else if(m == 7){ /* 40 meters */
06429       dflmd = REM_MODE_LSB;
06430       if(d > 30000)
06431          return -1;
06432    }
06433    else if(m == 14){ /* 20 meters */
06434       dflmd = REM_MODE_USB;
06435       if(d > 35000)
06436          return -1;
06437    }
06438    else if(m == 18){ /* 17 meters */
06439       dflmd = REM_MODE_USB;
06440       if((d < 6800) || (d > 16800))
06441          return -1;
06442    }
06443    else if(m == 21){ /* 15 meters */
06444       dflmd = REM_MODE_USB;
06445       if((d < 20000) || (d > 45000))
06446          return -1;
06447    }
06448    else if(m == 24){ /* 12 meters */
06449       dflmd = REM_MODE_USB;
06450       if((d < 89000) || (d > 99000))
06451          return -1;
06452    }
06453    else if(m == 28){ /* 10 meters */
06454       dflmd = REM_MODE_USB;
06455    }
06456    else if(m == 29){ 
06457       if(d >= 51000)
06458          dflmd = REM_MODE_FM;
06459       else
06460          dflmd = REM_MODE_USB;
06461       if(d > 70000)
06462          return -1;
06463    }
06464    else if(m == 50){ /* 6 meters */
06465       if(d >= 30000)
06466          dflmd = REM_MODE_FM;
06467       else
06468          dflmd = REM_MODE_USB;
06469 
06470    }
06471    else if((m >= 51) && ( m < 54)){
06472       dflmd = REM_MODE_FM;
06473    }
06474    else if(m == 144){ /* 2 meters */
06475       if(d >= 30000)
06476          dflmd = REM_MODE_FM;
06477       else
06478          dflmd = REM_MODE_USB;
06479    }
06480    else if((m >= 145) && (m < 148)){
06481       dflmd = REM_MODE_FM;
06482    }
06483    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06484       if(m  < 438)
06485          dflmd = REM_MODE_USB;
06486       else
06487          dflmd = REM_MODE_FM;
06488       ;
06489    }
06490    else
06491       return -1;
06492 
06493    if(defmode)
06494       *defmode = dflmd;
06495 
06496    return 0;
06497 }

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

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

06786 {
06787    int dflmd = REM_MODE_FM;
06788 
06789    if(m == 1){ /* 160 meters */
06790       dflmd =  REM_MODE_LSB; 
06791       if(d < 80000)
06792          return -1;
06793    }
06794    else if(m == 3){ /* 80 meters */
06795       dflmd = REM_MODE_LSB;
06796       if(d < 50000)
06797          return -1;
06798    }
06799    else if(m == 7){ /* 40 meters */
06800       dflmd = REM_MODE_LSB;
06801       if(d > 30000)
06802          return -1;
06803    }
06804    else if(m == 14){ /* 20 meters */
06805       dflmd = REM_MODE_USB;
06806       if(d > 35000)
06807          return -1;
06808    }
06809    else if(m == 18){ /* 17 meters */
06810       dflmd = REM_MODE_USB;
06811       if((d < 6800) || (d > 16800))
06812          return -1;
06813    }
06814    else if(m == 21){ /* 15 meters */
06815       dflmd = REM_MODE_USB;
06816       if((d < 20000) || (d > 45000))
06817          return -1;
06818    }
06819    else if(m == 24){ /* 12 meters */
06820       dflmd = REM_MODE_USB;
06821       if((d < 89000) || (d > 99000))
06822          return -1;
06823    }
06824    else if(m == 28){ /* 10 meters */
06825       dflmd = REM_MODE_USB;
06826    }
06827    else if(m == 29){ 
06828       if(d >= 51000)
06829          dflmd = REM_MODE_FM;
06830       else
06831          dflmd = REM_MODE_USB;
06832       if(d > 70000)
06833          return -1;
06834    }
06835    else if(m == 50){ /* 6 meters */
06836       if(d >= 30000)
06837          dflmd = REM_MODE_FM;
06838       else
06839          dflmd = REM_MODE_USB;
06840 
06841    }
06842    else if((m >= 51) && ( m < 54)){
06843       dflmd = REM_MODE_FM;
06844    }
06845    else if(m == 144){ /* 2 meters */
06846       if(d >= 30000)
06847          dflmd = REM_MODE_FM;
06848       else
06849          dflmd = REM_MODE_USB;
06850    }
06851    else if((m >= 145) && (m < 148)){
06852       dflmd = REM_MODE_FM;
06853    }
06854    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06855       if(m  < 438)
06856          dflmd = REM_MODE_USB;
06857       else
06858          dflmd = REM_MODE_FM;
06859       ;
06860    }
06861    else
06862       return -1;
06863 
06864    if(defmode)
06865       *defmode = dflmd;
06866 
06867    return 0;
06868 }

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

Definition at line 6276 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

06277 {
06278    int dflmd = REM_MODE_FM;
06279 
06280    if (m == 144){ /* 2 meters */
06281       if(d < 10100)
06282          return -1;
06283    }
06284    else if((m >= 145) && (m < 148)){
06285       ;
06286    }
06287    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06288       ;
06289    }
06290    else
06291       return -1;
06292    
06293    if(defmode)
06294       *defmode = dflmd; 
06295 
06296 
06297    return 0;
06298 }

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

Definition at line 6304 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

06305 {
06306    int dflmd = REM_MODE_FM;
06307 
06308    if(m == 50){ /* 6 meters */
06309       if(d < 10100)
06310          return -1;
06311    }
06312    else if((m >= 51) && ( m < 54)){
06313                 ;
06314    }
06315    else if(m == 144){ /* 2 meters */
06316       if(d < 10100)
06317          return -1;
06318    }
06319    else if((m >= 145) && (m < 148)){
06320       ;
06321    }
06322    else if((m >= 222) && (m < 225)){ /* 1.25 meters */
06323       ;
06324    }
06325    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06326       ;
06327    }
06328    else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */
06329       ;
06330    }
06331    else
06332       return -1;
06333    
06334    if(defmode)
06335       *defmode = dflmd; 
06336 
06337 
06338    return 0;
06339 }

static char check_tx_freq ( struct rpt myrpt  )  [static]

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

07418 {
07419    int i;
07420    int radio_mhz, radio_decimals, ulimit_mhz, ulimit_decimals, llimit_mhz, llimit_decimals;
07421    char radio_mhz_char[MAXREMSTR];
07422    char radio_decimals_char[MAXREMSTR];
07423    char limit_mhz_char[MAXREMSTR];
07424    char limit_decimals_char[MAXREMSTR];
07425    char limits[256];
07426    char *limit_ranges[40];
07427    struct ast_variable *limitlist;
07428    
07429 
07430    /* Must have user logged in and tx_limits defined */
07431 
07432    if(!myrpt->p.txlimitsstanzaname || !myrpt->loginuser[0] || !myrpt->loginlevel[0]){
07433       if(debug > 3){
07434          ast_log(LOG_NOTICE, "No tx band table defined, or no user logged in\n");
07435       }
07436       return 1; /* Assume it's ok otherwise */
07437    }
07438 
07439    /* Retrieve the band table for the loginlevel */
07440    limitlist = ast_variable_browse(myrpt->cfg, myrpt->p.txlimitsstanzaname);
07441 
07442    if(!limitlist){
07443       ast_log(LOG_WARNING, "No entries in %s band table stanza\n", myrpt->p.txlimitsstanzaname);
07444       return 0;
07445    }
07446 
07447    split_freq(radio_mhz_char, radio_decimals_char, myrpt->freq);
07448    radio_mhz = atoi(radio_mhz_char);
07449    radio_decimals = decimals2int(radio_decimals_char);
07450 
07451 
07452    if(debug > 3){
07453       ast_log(LOG_NOTICE, "Login User = %s, login level = %s\n", myrpt->loginuser, myrpt->loginlevel);
07454    }
07455 
07456    /* Find our entry */
07457 
07458    for(;limitlist; limitlist=limitlist->next){
07459       if(!strcmp(limitlist->name, myrpt->loginlevel))
07460          break;
07461    }
07462 
07463    if(!limitlist){
07464       ast_log(LOG_WARNING, "Can't find %s entry in band table stanza %s\n", myrpt->loginlevel, myrpt->p.txlimitsstanzaname);
07465       return 0;
07466    }
07467    
07468    if(debug > 3){
07469       ast_log(LOG_NOTICE, "Auth %s = %s\n", limitlist->name, limitlist->value);
07470    }
07471 
07472    /* Parse the limits */
07473 
07474    strncpy(limits, limitlist->value, 256);
07475    limits[255] = 0;
07476    finddelim(limits, limit_ranges, 40);
07477    for(i = 0; i < 40 && limit_ranges[i] ; i++){
07478       char range[40];
07479       char *r,*s;
07480       strncpy(range, limit_ranges[i], 40);
07481       range[39] = 0;
07482                 if(debug > 3){
07483          ast_log(LOG_NOTICE, "Checking to see if %s is within limits of %s\n", myrpt->freq, range);
07484                 }        
07485    
07486       r = strchr(range, '-');
07487       if(!r){
07488          ast_log(LOG_WARNING, "Malformed range in %s tx band table entry\n", limitlist->name);
07489          return 0;
07490       }
07491       *r++ = 0;
07492       s = eatwhite(range);
07493       r = eatwhite(r);
07494       split_freq(limit_mhz_char, limit_decimals_char, s);
07495       llimit_mhz = atoi(limit_mhz_char);
07496       llimit_decimals = decimals2int(limit_decimals_char);
07497       split_freq(limit_mhz_char, limit_decimals_char, r);
07498       ulimit_mhz = atoi(limit_mhz_char);
07499       ulimit_decimals = decimals2int(limit_decimals_char);
07500          
07501       if((radio_mhz >= llimit_mhz) && (radio_mhz <= ulimit_mhz)){
07502          if(radio_mhz == llimit_mhz){ /* CASE 1: TX freq is in llimit mhz portion of band */
07503             if(radio_decimals >= llimit_decimals){ /* Cannot be below llimit decimals */
07504                if(llimit_mhz == ulimit_mhz){ /* If bandwidth < 1Mhz, check ulimit decimals */
07505                   if(radio_decimals <= ulimit_decimals){
07506                      return 1;
07507                   }
07508                   else{
07509                      if(debug > 3)
07510                         ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 1\n");
07511                      return 0;
07512                   }
07513                }
07514                else{
07515                   return 1;
07516                }
07517             }
07518             else{ /* Is below llimit decimals */
07519                if(debug > 3)
07520                   ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 2\n");
07521                return 0;
07522             }
07523          }
07524          else if(radio_mhz == ulimit_mhz){ /* CASE 2: TX freq not in llimit mhz portion of band */
07525             if(radio_decimals <= ulimit_decimals){
07526                return 1;
07527             }
07528             else{ /* Is above ulimit decimals */
07529                if(debug > 3)
07530                   ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 3\n");
07531                return 0;
07532             }
07533          }
07534          else /* CASE 3: TX freq within a multi-Mhz band and ok */
07535             return 1; 
07536       }
07537    }
07538    if(debug > 3) /* No match found in TX band table */
07539       ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 4\n");
07540    return 0;
07541 }

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

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

05953 {
05954 unsigned char rxbuf[100];
05955 int   i,rv ;
05956 
05957    rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0);
05958    if (rv == -1) return(-1);
05959    if (rv != (cmdlen + 6)) return(1);
05960    for(i = 0; i < 6; i++)
05961       if (rxbuf[i] != cmd[i]) return(1);
05962    if (rxbuf[cmdlen] != 0xfe) return(1);
05963    if (rxbuf[cmdlen + 1] != 0xfe) return(1);
05964    if (rxbuf[cmdlen + 4] != 0xfb) return(1);
05965    if (rxbuf[cmdlen + 5] != 0xfd) return(1);
05966    return(0);
05967 }

static int closerem ( struct rpt myrpt  )  [static]

Definition at line 7387 of file app_rpt.c.

References closerem_ft897(), and rpt::remote.

07388 {
07389    if(!strcmp(myrpt->remote, remote_rig_ft897))
07390       return closerem_ft897(myrpt);
07391    else
07392       return 0;
07393 }

static int closerem_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6725 of file app_rpt.c.

References simple_command_ft897().

Referenced by closerem().

06726 {
06727    simple_command_ft897(myrpt, 0x88); /* PTT off */
06728    return 0;
06729 }  

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

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

05224 {
05225    int i;
05226    char *stringp,*action,*param,*functiondigits;
05227    char function_table_name[30] = "";
05228    char workstring[200];
05229    
05230    struct ast_variable *vp;
05231    
05232    if(debug)   
05233       printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source);
05234    
05235    if (command_source == SOURCE_DPHONE) {
05236       if (!myrpt->p.dphone_functions) return DC_INDETERMINATE;
05237       strncpy(function_table_name, myrpt->p.dphone_functions, sizeof(function_table_name) - 1);
05238       }
05239    else if (command_source == SOURCE_PHONE) {
05240       if (!myrpt->p.phone_functions) return DC_INDETERMINATE;
05241       strncpy(function_table_name, myrpt->p.phone_functions, sizeof(function_table_name) - 1);
05242       }
05243    else if (command_source == SOURCE_LNK)
05244       strncpy(function_table_name, myrpt->p.link_functions, sizeof(function_table_name) - 1);
05245    else
05246       strncpy(function_table_name, myrpt->p.functions, sizeof(function_table_name) - 1);
05247    vp = ast_variable_browse(myrpt->cfg, function_table_name);
05248    while(vp) {
05249       if(!strncasecmp(vp->name, digits, strlen(vp->name)))
05250          break;
05251       vp = vp->next;
05252    }  
05253    if(!vp) {
05254       int n;
05255 
05256       n = myrpt->longestfunc;
05257       if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc;
05258       else 
05259       if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc;
05260       else 
05261       if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc;
05262       
05263       if(strlen(digits) >= n)
05264          return DC_ERROR;
05265       else
05266          return DC_INDETERMINATE;
05267    }  
05268    /* Found a match, retrieve value part and parse */
05269    strncpy(workstring, vp->value, sizeof(workstring) - 1 );
05270    stringp = workstring;
05271    action = strsep(&stringp, ",");
05272    param = stringp;
05273    if(debug)
05274       printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)");
05275    /* Look up the action */
05276    for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){
05277       if(!strncasecmp(action, function_table[i].action, strlen(action)))
05278          break;
05279    }
05280    if(debug)
05281       printf("@@@@ table index i = %d\n",i);
05282    if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){
05283       /* Error, action not in table */
05284       return DC_ERROR;
05285    }
05286    if(function_table[i].function == NULL){
05287       /* Error, function undefined */
05288       if(debug)
05289          printf("@@@@ NULL for action: %s\n",action);
05290       return DC_ERROR;
05291    }
05292    functiondigits = digits + strlen(vp->name);
05293    return (*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink);
05294 }

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

Definition at line 4462 of file app_rpt.c.

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

Referenced by function_ilink().

04463 {
04464    char *val, *s, *s1, *s2, *tele;
04465    char lstr[MAXLINKLIST],*strs[MAXLINKLIST];
04466    char tmp[300], deststr[300] = "",modechange = 0;
04467    struct rpt_link *l;
04468    int reconnects = 0;
04469    int i,n;
04470    DAHDI_CONFINFO ci;  /* conference info */
04471 
04472    val = node_lookup(myrpt,node);
04473    if (!val){
04474       if(strlen(node) >= myrpt->longestnode)
04475          return -1; /* No such node */
04476       return 1; /* No match yet */
04477    }
04478    if(debug > 3){
04479       ast_log(LOG_NOTICE,"Connect attempt to node %s\n", node);
04480       ast_log(LOG_NOTICE,"Mode: %s\n",(mode)?"Transceive":"Monitor");
04481       ast_log(LOG_NOTICE,"Connection type: %s\n",(perma)?"Permalink":"Normal");
04482    }
04483 
04484    strncpy(tmp,val,sizeof(tmp) - 1);
04485    s = tmp;
04486    s1 = strsep(&s,",");
04487    s2 = strsep(&s,",");
04488    rpt_mutex_lock(&myrpt->lock);
04489    l = myrpt->links.next;
04490    /* try to find this one in queue */
04491    while(l != &myrpt->links){
04492       if (l->name[0] == '0') 
04493       {
04494          l = l->next;
04495          continue;
04496       }
04497    /* if found matching string */
04498       if (!strcmp(l->name, node))
04499          break;
04500       l = l->next;
04501    }
04502    /* if found */
04503    if (l != &myrpt->links){ 
04504    /* if already in this mode, just ignore */
04505       if ((l->mode) || (!l->chan)) {
04506          rpt_mutex_unlock(&myrpt->lock);
04507          return 2; /* Already linked */
04508       }
04509       reconnects = l->reconnects;
04510       rpt_mutex_unlock(&myrpt->lock);
04511       if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV);
04512       l->retries = l->max_retries + 1;
04513       l->disced = 2;
04514       modechange = 1;
04515    } else
04516    {
04517       __mklinklist(myrpt,NULL,lstr);
04518       rpt_mutex_unlock(&myrpt->lock);
04519       n = finddelim(lstr,strs,MAXLINKLIST);
04520       for(i = 0; i < n; i++)
04521       {
04522          if ((*strs[i] < '0') || 
04523              (*strs[i] > '9')) strs[i]++;
04524          if (!strcmp(strs[i],node))
04525          {
04526             return 2; /* Already linked */
04527          }
04528       }
04529    }
04530    strncpy(myrpt->lastlinknode,node,MAXNODESTR - 1);
04531    /* establish call */
04532    l = malloc(sizeof(struct rpt_link));
04533    if (!l)
04534    {
04535       ast_log(LOG_WARNING, "Unable to malloc\n");
04536       return -1;
04537    }
04538    /* zero the silly thing */
04539    memset((char *)l,0,sizeof(struct rpt_link));
04540    l->mode = mode;
04541    l->outbound = 1;
04542    l->thisconnected = 0;
04543    strncpy(l->name, node, MAXNODESTR - 1);
04544    l->isremote = (s && ast_true(s));
04545    if (modechange) l->connected = 1;
04546    l->hasconnected = l->perma = perma;
04547 #ifdef ALLOW_LOCAL_CHANNELS
04548    if ((strncasecmp(s1,"iax2/", 5) == 0) || (strncasecmp(s1, "local/", 6) == 0))
04549          strncpy(deststr, s1, sizeof(deststr));
04550    else
04551            snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
04552 #else
04553    snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
04554 #endif
04555    tele = strchr(deststr, '/');
04556    if (!tele){
04557       ast_log(LOG_WARNING,"link3:Dial number (%s) must be in format tech/number\n",deststr);
04558       free(l);
04559       return -1;
04560    }
04561    *tele++ = 0;
04562    l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
04563    if (l->chan){
04564       ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
04565       ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
04566 #ifdef   AST_CDR_FLAG_POST_DISABLED
04567       ast_set_flag(l->chan->cdr,AST_CDR_FLAG_POST_DISABLED);
04568 #endif
04569       l->chan->whentohangup = 0;
04570       l->chan->appl = "Apprpt";
04571       l->chan->data = "(Remote Rx)";
04572       if (debug > 3)
04573          ast_log(LOG_NOTICE, "rpt (remote) initiating call to %s/%s on %s\n",
04574       deststr, tele, l->chan->name);
04575       if(l->chan->cid.cid_num)
04576          free(l->chan->cid.cid_num);
04577       l->chan->cid.cid_num = strdup(myrpt->name);
04578       ast_call(l->chan,tele,999);
04579    }
04580    else {
04581       if(debug > 3) 
04582          ast_log(LOG_NOTICE, "Unable to place call to %s/%s on %s\n",
04583       deststr,tele,l->chan->name);
04584       if (myrpt->p.archivedir)
04585       {
04586          char str[100];
04587          sprintf(str,"LINKFAIL,%s",l->name);
04588          donodelog(myrpt,str);
04589       }
04590       free(l);
04591       return -1;
04592    }
04593    /* allocate a pseudo-channel thru asterisk */
04594    l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
04595    if (!l->pchan){
04596       ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n");
04597       ast_hangup(l->chan);
04598       free(l);
04599       return -1;
04600    }
04601    ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR);
04602    ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR);
04603 #ifdef   AST_CDR_FLAG_POST_DISABLED
04604    ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
04605 #endif
04606    /* make a conference for the tx */
04607    ci.chan = 0;
04608    ci.confno = myrpt->conf;
04609    ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER;
04610    /* first put the channel on the conference in proper mode */
04611    if (ioctl(l->pchan->fds[0], DAHDI_SETCONF, &ci) == -1)
04612    {
04613       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04614       ast_hangup(l->chan);
04615       ast_hangup(l->pchan);
04616       free(l);
04617       return -1;
04618    }
04619    rpt_mutex_lock(&myrpt->lock);
04620    l->reconnects = reconnects;
04621    /* insert at end of queue */
04622    l->max_retries = MAX_RETRIES;
04623    if (perma)
04624       l->max_retries = MAX_RETRIES_PERM;
04625    if (l->isremote) l->retries = l->max_retries + 1;
04626    insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
04627    __kickshort(myrpt);
04628    rpt_mutex_unlock(&myrpt->lock);
04629    return 0;
04630 }

static int decimals2int ( char *  fraction  )  [static]

Definition at line 6345 of file app_rpt.c.

Referenced by check_tx_freq().

06346 {
06347    int i;
06348    char len = strlen(fraction);
06349    int multiplier = 100000;
06350    int res = 0;
06351 
06352    if(!len)
06353       return 0;
06354    for( i = 0 ; i < len ; i++, multiplier /= 10)
06355       res += (fraction[i] - '0') * multiplier;
06356    return res;
06357 }

static long diskavail ( struct rpt myrpt  )  [static]

Definition at line 1021 of file app_rpt.c.

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

Referenced by rpt().

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

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

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

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

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

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

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

static void do_scheduler ( struct rpt myrpt  )  [static]

Definition at line 8635 of file app_rpt.c.

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

Referenced by rpt().

08636 {
08637    int i,res;
08638    struct tm tmnow;
08639    struct ast_variable *skedlist;
08640    char *strs[5],*vp,*val,value[100];
08641 
08642    memcpy(&myrpt->lasttv, &myrpt->curtv, sizeof(struct timeval));
08643    
08644    if( (res = gettimeofday(&myrpt->curtv, NULL)) < 0)
08645       ast_log(LOG_NOTICE, "Scheduler gettime of day returned: %s\n", strerror(res));
08646 
08647    /* Try to get close to a 1 second resolution */
08648    
08649    if(myrpt->lasttv.tv_sec == myrpt->curtv.tv_sec)
08650       return;
08651 
08652    rpt_localtime(&myrpt->curtv.tv_sec, &tmnow);
08653 
08654    /* If midnight, then reset all daily statistics */
08655    
08656    if((tmnow.tm_hour == 0)&&(tmnow.tm_min == 0)&&(tmnow.tm_sec == 0)){
08657       myrpt->dailykeyups = 0;
08658       myrpt->dailytxtime = 0;
08659       myrpt->dailykerchunks = 0;
08660       myrpt->dailyexecdcommands = 0;
08661    }
08662 
08663    if(tmnow.tm_sec != 0)
08664       return;
08665 
08666    /* Code below only executes once per minute */
08667 
08668 
08669    /* Don't schedule if remote */
08670 
08671         if (myrpt->remote)
08672                 return;
08673 
08674    /* Don't schedule if disabled */
08675 
08676         if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable){
08677       if(debug > 6)
08678          ast_log(LOG_NOTICE, "Scheduler disabled\n");
08679       return;
08680    }
08681 
08682    if(!myrpt->p.skedstanzaname){ /* No stanza means we do nothing */
08683       if(debug > 6)
08684          ast_log(LOG_NOTICE,"No stanza for scheduler in rpt.conf\n");
08685       return;
08686    }
08687 
08688         /* get pointer to linked list of scheduler entries */
08689         skedlist = ast_variable_browse(myrpt->cfg, myrpt->p.skedstanzaname);
08690 
08691    if(debug > 6){
08692       ast_log(LOG_NOTICE, "Time now: %02d:%02d %02d %02d %02d\n",
08693          tmnow.tm_hour,tmnow.tm_min,tmnow.tm_mday,tmnow.tm_mon + 1, tmnow.tm_wday); 
08694    }
08695    /* walk the list */
08696    for(; skedlist; skedlist = skedlist->next){
08697       if(debug > 6)
08698          ast_log(LOG_NOTICE, "Scheduler entry %s = %s being considered\n",skedlist->name, skedlist->value);
08699       strncpy(value,skedlist->value,99);
08700       value[99] = 0;
08701       /* point to the substrings for minute, hour, dom, month, and dow */
08702       for( i = 0, vp = value ; i < 5; i++){
08703          if(!*vp)
08704             break;
08705          while((*vp == ' ') || (*vp == 0x09)) /* get rid of any leading white space */
08706             vp++;
08707          strs[i] = vp; /* save pointer to beginning of substring */
08708          while((*vp != ' ') && (*vp != 0x09) && (*vp != 0)) /* skip over substring */
08709             vp++;
08710          if(*vp)
08711             *vp++ = 0; /* mark end of substring */
08712       }
08713       if(debug > 6)
08714          ast_log(LOG_NOTICE, "i = %d, min = %s, hour = %s, mday=%s, mon=%s, wday=%s\n",i,
08715             strs[0], strs[1], strs[2], strs[3], strs[4]); 
08716       if(i == 5){
08717          if((*strs[0] != '*')&&(atoi(strs[0]) != tmnow.tm_min))
08718             continue;
08719          if((*strs[1] != '*')&&(atoi(strs[1]) != tmnow.tm_hour))
08720             continue;
08721          if((*strs[2] != '*')&&(atoi(strs[2]) != tmnow.tm_mday))
08722             continue;
08723          if((*strs[3] != '*')&&(atoi(strs[3]) != tmnow.tm_mon + 1))
08724             continue;
08725          if(atoi(strs[4]) == 7)
08726             strs[4] = "0";
08727          if((*strs[4] != '*')&&(atoi(strs[4]) != tmnow.tm_wday))
08728             continue;
08729          if(debug)
08730             ast_log(LOG_NOTICE, "Executing scheduler entry %s = %s\n", skedlist->name, skedlist->value);
08731          if(atoi(skedlist->name) == 0)
08732             return; /* Zero is reserved for the startup macro */
08733          val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, skedlist->name);
08734          if (!val){
08735             ast_log(LOG_WARNING,"Scheduler could not find macro %s\n",skedlist->name);
08736             return; /* Macro not found */
08737          }
08738          if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)){
08739             ast_log(LOG_WARNING, "Scheduler could not execute macro %s: Macro buffer full\n",
08740                skedlist->name);
08741             return; /* Macro buffer full */
08742          }
08743          myrpt->macrotimer = MACROTIME;
08744          strncat(myrpt->macrobuf,val,MAXMACRO - strlen(myrpt->macrobuf) - 1);
08745       }
08746       else{
08747          ast_log(LOG_WARNING,"Malformed scheduler entry in rpt.conf: %s = %s\n",
08748             skedlist->name, skedlist->value);
08749       }
08750    }
08751 
08752 }

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

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

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

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

Definition at line 1284 of file app_rpt.c.

Referenced by check_tx_freq().

01285 {
01286    while((*s == ' ') || (*s == 0x09)){ /* get rid of any leading white space */
01287       if(!*s)
01288          break;
01289       s++;
01290    }
01291    return s;
01292 }

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

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

01305 {
01306 int     i,l,inquo;
01307 
01308         inquo = 0;
01309         i = 0;
01310         strp[i++] = str;
01311         if (!*str)
01312            {
01313                 strp[0] = 0;
01314                 return(0);
01315            }
01316         for(l = 0; *str && (l < limit) ; str++)
01317            {
01318                 if (*str == QUOTECHR)
01319                    {
01320                         if (inquo)
01321                            {
01322                                 *str = 0;
01323                                 inquo = 0;
01324                            }
01325                         else
01326                            {
01327                                 strp[i - 1] = str + 1;
01328                                 inquo = 1;
01329                            }
01330       }
01331                 if ((*str == DELIMCHR) && (!inquo))
01332                 {
01333                         *str = 0;
01334          l++;
01335                         strp[i++] = str + 1;
01336                 }
01337            }
01338         strp[i] = 0;
01339         return(i);
01340 
01341 }

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

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

01240 {
01241 time_t   now;
01242 int   gotone;
01243 
01244    time(&now);
01245    gotone = 0;
01246    /* if too much time, reset the skate machine */
01247    if ((now - xlat->lastone) > MAXXLATTIME)
01248    {
01249       xlat->funcindex = xlat->endindex = 0;
01250    }
01251    if (xlat->funccharseq[0] && (c == xlat->funccharseq[xlat->funcindex++]))
01252    {
01253       time(&xlat->lastone);
01254       gotone = 1;
01255       if (!xlat->funccharseq[xlat->funcindex])
01256       {
01257          xlat->funcindex = xlat->endindex = 0;
01258          return(myrpt->p.funcchar);
01259       }
01260    } else xlat->funcindex = 0;
01261    if (xlat->endcharseq[0] && (c == xlat->endcharseq[xlat->endindex++]))
01262    {
01263       time(&xlat->lastone);
01264       gotone = 1;
01265       if (!xlat->endcharseq[xlat->endindex])
01266       {
01267          xlat->funcindex = xlat->endindex = 0;
01268          return(myrpt->p.endchar);
01269       }
01270    } else xlat->endindex = 0;
01271    /* if in middle of decode seq, send nothing back */
01272    if (gotone) return(0);
01273    /* if no pass chars specified, return em all */
01274    if (!xlat->passchars[0]) return(c);
01275    /* if a "pass char", pass it */
01276    if (strchr(xlat->passchars,c)) return(c);
01277    return(0);
01278 }

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

Definition at line 4993 of file app_rpt.c.

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

04994 {
04995    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
04996       return DC_ERROR;
04997    
04998    if(debug)
04999       printf("@@@@ Autopatch down\n");
05000       
05001    rpt_mutex_lock(&myrpt->lock);
05002    
05003    if (!myrpt->callmode){
05004       rpt_mutex_unlock(&myrpt->lock);
05005       return DC_COMPLETE;
05006    }
05007    
05008    myrpt->callmode = 0;
05009    rpt_mutex_unlock(&myrpt->lock);
05010    rpt_telemetry(myrpt, TERM, NULL);
05011    return DC_COMPLETE;
05012 }

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

Definition at line 4896 of file app_rpt.c.

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

04897 {
04898    pthread_attr_t attr;
04899    int i, index, paramlength;
04900    char *lparam;
04901    char *value = NULL;
04902    char *paramlist[20];
04903 
04904    static char *keywords[] = {
04905    "context",
04906    "dialtime",
04907    "farenddisconnect",
04908    "noct",
04909    "quiet",
04910    NULL
04911    };
04912       
04913    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
04914       return DC_ERROR;
04915       
04916    if(debug)
04917       printf("@@@@ Autopatch up\n");
04918 
04919    if(!myrpt->callmode){
04920       /* Set defaults */
04921       myrpt->patchnoct = 0;
04922       myrpt->patchdialtime = 0;
04923       myrpt->patchfarenddisconnect = 0;
04924       myrpt->patchquiet = 0;
04925       strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT);
04926 
04927       if(param){
04928          /* Process parameter list */
04929          lparam = ast_strdupa(param);
04930          if(!lparam){
04931             ast_log(LOG_ERROR,"App_rpt out of memory on line %d\n",__LINE__);
04932             return DC_ERROR;  
04933          }
04934          paramlength = finddelim(lparam, paramlist, 20);          
04935          for(i = 0; i < paramlength; i++){
04936             index = matchkeyword(paramlist[i], &value, keywords);
04937             if(value)
04938                value = skipchars(value, "= ");
04939             switch(index){
04940 
04941                case 1: /* context */
04942                   strncpy(myrpt->patchcontext, value, MAXPATCHCONTEXT - 1) ;
04943                   break;
04944                   
04945                case 2: /* dialtime */
04946                   myrpt->patchdialtime = atoi(value);
04947                   break;
04948 
04949                case 3: /* farenddisconnect */
04950                   myrpt->patchfarenddisconnect = atoi(value);
04951                   break;
04952 
04953                case 4:  /* noct */
04954                   myrpt->patchnoct = atoi(value);
04955                   break;
04956 
04957                case 5: /* quiet */
04958                   myrpt->patchquiet = atoi(value);
04959                   break;
04960                            
04961                default:
04962                   break;
04963             }
04964          }
04965       }
04966    }
04967                
04968    rpt_mutex_lock(&myrpt->lock);
04969 
04970    /* if on call, force * into current audio stream */
04971    
04972    if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){
04973       myrpt->mydtmf = myrpt->p.endchar;
04974    }
04975    if (myrpt->callmode){
04976       rpt_mutex_unlock(&myrpt->lock);
04977       return DC_COMPLETE;
04978    }
04979    myrpt->callmode = 1;
04980    myrpt->cidx = 0;
04981    myrpt->exten[myrpt->cidx] = 0;
04982    rpt_mutex_unlock(&myrpt->lock);
04983    pthread_attr_init(&attr);
04984    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04985    ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt);
04986    return DC_COMPLETE;
04987 }

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

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

05095 {
05096    char string[16];
05097 
05098    if(!param)
05099       return DC_ERROR;
05100    
05101    switch(myatoi(param)){
05102       case 1: /* System reset */
05103          system("killall -9 asterisk");
05104          return DC_COMPLETE;
05105 
05106       case 2:
05107          myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 0;
05108          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA");
05109          return DC_COMPLETE;
05110          
05111       case 3:
05112          myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 1;
05113          return DC_COMPLETE;
05114          
05115       case 4: /* test tone on */
05116          if (myrpt->stopgen < 0) 
05117          {
05118             myrpt->stopgen = 1;
05119          }
05120          else 
05121          {
05122             myrpt->stopgen = 0;
05123             rpt_telemetry(myrpt, TEST_TONE, NULL);
05124          }
05125          return DC_COMPLETE;
05126 
05127       case 5: /* Disgorge variables to log for debug purposes */
05128          myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
05129          return DC_COMPLETE;
05130 
05131       case 6: /* Simulate COR being activated (phone only) */
05132          if (command_source != SOURCE_PHONE) return DC_INDETERMINATE;
05133          return DC_DOKEY;  
05134 
05135 
05136       case 7: /* Time out timer enable */
05137          myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 0;
05138          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTENA");
05139          return DC_COMPLETE;
05140          
05141       case 8: /* Time out timer disable */
05142          myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 1;
05143          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTDIS");
05144          return DC_COMPLETE;
05145 
05146                 case 9: /* Autopatch enable */
05147                         myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 0;
05148                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APENA");
05149                         return DC_COMPLETE;
05150 
05151                 case 10: /* Autopatch disable */
05152                         myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 1;
05153                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APDIS");
05154                         return DC_COMPLETE;
05155 
05156                 case 11: /* Link Enable */
05157                         myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 0;
05158                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKENA");
05159                         return DC_COMPLETE;
05160 
05161                 case 12: /* Link Disable */
05162                         myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 1;
05163                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKDIS");
05164                         return DC_COMPLETE;
05165 
05166       case 13: /* Query System State */
05167          string[0] = string[1] = 'S';
05168          string[2] = myrpt->p.sysstate_cur + '0';
05169          string[3] = '\0';
05170          rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
05171          return DC_COMPLETE;
05172 
05173       case 14: /* Change System State */
05174          if(strlen(digitbuf) == 0)
05175             break;
05176          if((digitbuf[0] < '0') || (digitbuf[0] > '9'))
05177             return DC_ERROR;
05178          myrpt->p.sysstate_cur = digitbuf[0] - '0';
05179                         string[0] = string[1] = 'S';
05180                         string[2] = myrpt->p.sysstate_cur + '0';
05181                         string[3] = '\0';
05182                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
05183                         return DC_COMPLETE;
05184 
05185                 case 15: /* Scheduler Enable */
05186                         myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 0;
05187                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKENA");
05188                         return DC_COMPLETE;
05189 
05190                 case 16: /* Scheduler Disable */
05191                         myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 1;
05192                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKDIS");
05193                         return DC_COMPLETE;
05194 
05195                 case 17: /* User functions Enable */
05196                         myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 0;
05197                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFENA");
05198                         return DC_COMPLETE;
05199 
05200                 case 18: /* User Functions Disable */
05201                         myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 1;
05202                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFDIS");
05203                         return DC_COMPLETE;
05204 
05205                 case 19: /* Alternate Tail Enable */
05206                         myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 1;
05207                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATENA");
05208                         return DC_COMPLETE;
05209 
05210                 case 20: /* Alternate Tail Disable */
05211                         myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 0;
05212                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATDIS");
05213                         return DC_COMPLETE;
05214    }  
05215    return DC_INDETERMINATE;
05216 }

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

Definition at line 4638 of file app_rpt.c.

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

04639 {
04640 
04641    char *val, *s, *s1, *s2;
04642    char tmp[300];
04643    char digitbuf[MAXNODESTR],*strs[MAXLINKLIST];
04644    char mode,perma;
04645    struct rpt_link *l;
04646    int i,r;
04647 
04648    if(!param)
04649       return DC_ERROR;
04650       
04651          
04652    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable )
04653       return DC_ERROR;
04654 
04655    strncpy(digitbuf,digits,MAXNODESTR - 1);
04656 
04657    if(debug > 6)
04658       printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
04659       
04660    switch(myatoi(param)){
04661       case 11: /* Perm Link off */
04662       case 1: /* Link off */
04663          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
04664             strcpy(digitbuf,myrpt->lastlinknode);
04665          val = node_lookup(myrpt,digitbuf);
04666          if (!val){
04667             if(strlen(digitbuf) >= myrpt->longestnode)
04668                return DC_ERROR;
04669             break;
04670          }
04671          strncpy(tmp,val,sizeof(tmp) - 1);
04672          s = tmp;
04673          s1 = strsep(&s,",");
04674          s2 = strsep(&s,",");
04675          rpt_mutex_lock(&myrpt->lock);
04676          l = myrpt->links.next;
04677          /* try to find this one in queue */
04678          while(l != &myrpt->links){
04679             if (l->name[0] == '0') 
04680             {
04681                l = l->next;
04682                continue;
04683             }
04684             /* if found matching string */
04685             if (!strcmp(l->name, digitbuf))
04686                break;
04687             l = l->next;
04688          }
04689          if (l != &myrpt->links){ /* if found */
04690             struct   ast_frame wf;
04691 
04692             /* must use perm command on perm link */
04693             if ((myatoi(param) < 10) && 
04694                 (l->max_retries > MAX_RETRIES))
04695             {
04696                rpt_mutex_unlock(&myrpt->lock);
04697                return DC_COMPLETE;
04698             }
04699             strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1);
04700             l->retries = l->max_retries + 1;
04701             l->disced = 1;
04702             rpt_mutex_unlock(&myrpt->lock);
04703             wf.frametype = AST_FRAME_TEXT;
04704             wf.subclass = 0;
04705             wf.offset = 0;
04706             wf.mallocd = 0;
04707             wf.datalen = strlen(discstr) + 1;
04708             wf.samples = 0;
04709             wf.data = discstr;
04710             if (l->chan)
04711             {
04712                ast_write(l->chan,&wf);
04713                if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR;
04714                ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
04715             }
04716             rpt_telemetry(myrpt, COMPLETE, NULL);
04717             return DC_COMPLETE;
04718          }
04719          rpt_mutex_unlock(&myrpt->lock);  
04720          return DC_COMPLETE;
04721       case 2: /* Link Monitor */
04722       case 3: /* Link transceive */
04723       case 12: /* Link Monitor permanent */
04724       case 13: /* Link transceive permanent */
04725          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
04726             strcpy(digitbuf,myrpt->lastlinknode);
04727          /* Attempt connection  */
04728          perma = (atoi(param) > 10) ? 1 : 0;
04729          mode = (atoi(param) & 1) ? 1 : 0;
04730          r = connect_link(myrpt, digitbuf, mode, perma);
04731          switch(r){
04732             case 0:
04733                rpt_telemetry(myrpt, COMPLETE, NULL);
04734                return DC_COMPLETE;
04735 
04736             case 1:
04737                break;
04738             
04739             case 2:
04740                rpt_telemetry(myrpt, REMALREADY, NULL);
04741                return DC_COMPLETE;
04742             
04743             default:
04744                rpt_telemetry(myrpt, CONNFAIL, NULL);
04745                return DC_COMPLETE;
04746          }
04747          break;
04748 
04749       case 4: /* Enter Command Mode */
04750       
04751          /* if doesnt allow link cmd, or no links active, return */
04752          if (((command_source != SOURCE_RPT) && 
04753             (command_source != SOURCE_PHONE) &&
04754             (command_source != SOURCE_DPHONE)) ||
04755              (myrpt->links.next == &myrpt->links))
04756             return DC_COMPLETE;
04757          
04758          /* if already in cmd mode, or selected self, fughetabahtit */
04759          if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){
04760          
04761             rpt_telemetry(myrpt, REMALREADY, NULL);
04762             return DC_COMPLETE;
04763          }
04764          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
04765             strcpy(digitbuf,myrpt->lastlinknode);
04766          /* node must at least exist in list */
04767          val = node_lookup(myrpt,digitbuf);
04768          if (!val){
04769             if(strlen(digitbuf) >= myrpt->longestnode)
04770                return DC_ERROR;
04771             break;
04772          
04773          }
04774          rpt_mutex_lock(&myrpt->lock);
04775          strcpy(myrpt->lastlinknode,digitbuf);
04776          strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1);
04777          rpt_mutex_unlock(&myrpt->lock);
04778          rpt_telemetry(myrpt, REMGO, NULL);  
04779          return DC_COMPLETE;
04780          
04781       case 5: /* Status */
04782          rpt_telemetry(myrpt, STATUS, NULL);
04783          return DC_COMPLETE;
04784 
04785       case 15: /* Full Status */
04786          rpt_telemetry(myrpt, FULLSTATUS, NULL);
04787          return DC_COMPLETE;
04788          
04789          
04790       case 6: /* All Links Off, including permalinks */
04791                        rpt_mutex_lock(&myrpt->lock);
04792          myrpt->savednodes[0] = 0;
04793                         l = myrpt->links.next;
04794                         /* loop through all links */
04795                         while(l != &myrpt->links){
04796             struct   ast_frame wf;
04797                                 if (l->name[0] == '0') /* Skip any IAXRPT monitoring */
04798                                 {
04799                                         l = l->next;
04800                                         continue;
04801                                 }
04802             /* Make a string of disconnected nodes for possible restoration */
04803             sprintf(tmp,"%c%c%s",(l->mode) ? 'X' : 'M',(l->perma) ? 'P':'T',l->name);
04804             if(strlen(tmp) + strlen(myrpt->savednodes) + 1 < MAXNODESTR){ 
04805                if(myrpt->savednodes[0])
04806                   strcat(myrpt->savednodes, ",");
04807                strcat(myrpt->savednodes, tmp);
04808             }
04809                               l->retries = l->max_retries + 1;
04810                                 l->disced = 2; /* Silently disconnect */
04811                                 rpt_mutex_unlock(&myrpt->lock);
04812             /* ast_log(LOG_NOTICE,"dumping link %s\n",l->name); */
04813                                 
04814                                 wf.frametype = AST_FRAME_TEXT;
04815                                 wf.subclass = 0;
04816                                 wf.offset = 0;
04817                                 wf.mallocd = 0;
04818                                 wf.datalen = strlen(discstr) + 1;
04819                                 wf.samples = 0;
04820                                 wf.data = discstr;
04821                                 if (l->chan)
04822                                 {
04823                                         ast_write(l->chan,&wf);
04824                                         ast_safe_sleep(l->chan,250); /* It's dead already, why check the return value? */
04825                                         ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
04826                                 }
04827             rpt_mutex_lock(&myrpt->lock);
04828                                 l = l->next;
04829                         }
04830          rpt_mutex_unlock(&myrpt->lock);
04831          if(debug > 3)
04832             ast_log(LOG_NOTICE,"Nodes disconnected: %s\n",myrpt->savednodes);
04833                         rpt_telemetry(myrpt, COMPLETE, NULL);
04834          return DC_COMPLETE;
04835 
04836       case 7: /* Identify last node which keyed us up */
04837          rpt_telemetry(myrpt, LASTNODEKEY, NULL);
04838          break;
04839 
04840 
04841 #ifdef   _MDC_DECODE_H_
04842       case 8:
04843          myrpt->lastunit = 0xd00d; 
04844          mdc1200_notify(myrpt,NULL,myrpt->lastunit);
04845          mdc1200_send(myrpt,myrpt->lastunit);
04846          break;
04847 #endif
04848 
04849       case 16: /* Restore links disconnected with "disconnect all links" command */
04850          strcpy(tmp, myrpt->savednodes); /* Make a copy */
04851          finddelim(tmp, strs, MAXLINKLIST); /* convert into substrings */
04852          for(i = 0; tmp[0] && strs[i] != NULL && i < MAXLINKLIST; i++){
04853             s1 = strs[i];
04854             mode = (s1[0] == 'X') ? 1 : 0;
04855             perma = (s1[1] == 'P') ? 1 : 0;
04856             connect_link(myrpt, s1 + 2, mode, perma); /* Try to reconnect */
04857          }
04858                         rpt_telemetry(myrpt, COMPLETE, NULL);
04859          break;
04860    
04861       case 200:
04862       case 201:
04863       case 202:
04864       case 203:
04865       case 204:
04866       case 205:
04867       case 206:
04868       case 207:
04869       case 208:
04870       case 209:
04871       case 210:
04872       case 211:
04873       case 212:
04874       case 213:
04875       case 214:
04876       case 215:
04877          if (((myrpt->p.propagate_dtmf) && 
04878               (command_source == SOURCE_LNK)) ||
04879              ((myrpt->p.propagate_phonedtmf) &&
04880             ((command_source == SOURCE_PHONE) ||
04881                 (command_source == SOURCE_DPHONE))))
04882                do_dtmf_local(myrpt,
04883                   remdtmfstr[myatoi(param) - 200]);
04884       default:
04885          return DC_ERROR;
04886          
04887    }
04888    
04889    return DC_INDETERMINATE;
04890 }  

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

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

05050 {
05051 
05052 char  *val;
05053 int   i;
05054    if (myrpt->remote)
05055       return DC_ERROR;
05056 
05057    if(debug) 
05058       printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
05059    
05060    if(strlen(digitbuf) < 1) /* needs 1 digit */
05061       return DC_INDETERMINATE;
05062          
05063    for(i = 0 ; i < digitbuf[i] ; i++) {
05064       if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
05065          return DC_ERROR;
05066    }
05067    
05068    if (*digitbuf == '0') val = myrpt->p.startupmacro;
05069    else val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, digitbuf);
05070    /* param was 1 for local buf */
05071    if (!val){
05072                 if (strlen(digitbuf) < myrpt->macro_longest)
05073                         return DC_INDETERMINATE;
05074       rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL);
05075       return DC_COMPLETE;
05076    }        
05077    rpt_mutex_lock(&myrpt->lock);
05078    if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val))
05079    {
05080       rpt_mutex_unlock(&myrpt->lock);
05081       rpt_telemetry(myrpt, MACRO_BUSY, NULL);
05082       return DC_ERROR;
05083    }
05084    myrpt->macrotimer = MACROTIME;
05085    strncat(myrpt->macrobuf, val, MAXMACRO - strlen(myrpt->macrobuf) - 1);
05086    rpt_mutex_unlock(&myrpt->lock);
05087    return DC_COMPLETE;  
05088 }

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

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

07745 {
07746    char *s,*s1,*s2;
07747    int i,j,p,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode;
07748    char multimode = 0;
07749    char oc,*cp,*cp1,*cp2;
07750    char tmp[20], freq[20] = "", savestr[20] = "";
07751    char mhz[MAXREMSTR], decimals[MAXREMSTR];
07752 
07753    if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK))
07754       return DC_ERROR;
07755       
07756    p = myatoi(param);
07757 
07758    if ((p != 99) && (p != 5) && (p != 140) && myrpt->p.authlevel && 
07759       (!myrpt->loginlevel[0])) return DC_ERROR;
07760    multimode = multimode_capable(myrpt);
07761 
07762    switch(p){
07763 
07764       case 1:  /* retrieve memory */
07765          if(strlen(digitbuf) < 2) /* needs 2 digits */
07766             break;
07767          
07768          for(i = 0 ; i < 2 ; i++){
07769             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
07770                return DC_ERROR;
07771          }
07772        
07773          r = retreive_memory(myrpt, digitbuf);
07774          if (r < 0){
07775             rpt_telemetry(myrpt,MEMNOTFOUND,NULL);
07776             return DC_COMPLETE;
07777          }
07778          if (r > 0){
07779             return DC_ERROR;
07780          }
07781          if (setrem(myrpt) == -1) return DC_ERROR;
07782          return DC_COMPLETE;  
07783          
07784       case 2:  /* set freq and offset */
07785       
07786          
07787             for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */
07788             if(digitbuf[i] == '*'){
07789                j++;
07790                continue;
07791             }
07792             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
07793                goto invalid_freq;
07794             else{
07795                if(j == 0)
07796                   l++; /* # of digits before first * */
07797                if(j == 1)
07798                   k++; /* # of digits after first * */
07799             }
07800          }
07801       
07802          i = strlen(digitbuf) - 1;
07803          if(multimode){
07804             if((j > 2) || (l > 3) || (k > 6))
07805                goto invalid_freq; /* &^@#! */
07806          }
07807          else{
07808             if((j > 2) || (l > 4) || (k > 3))
07809                goto invalid_freq; /* &^@#! */
07810          }
07811 
07812          /* Wait for M+*K+* */
07813 
07814          if(j < 2)
07815             break; /* Not yet */
07816 
07817          /* We have a frequency */
07818 
07819          strncpy(tmp, digitbuf ,sizeof(tmp) - 1);
07820          
07821          s = tmp;
07822          s1 = strsep(&s, "*"); /* Pick off MHz */
07823          s2 = strsep(&s,"*"); /* Pick off KHz and Hz */
07824          ls2 = strlen(s2); 
07825          
07826          switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */
07827             case 1:
07828                ht = 0;
07829                k = 100 * atoi(s2);
07830                break;
07831             
07832             case 2:
07833                ht = 0;
07834                k = 10 * atoi(s2);
07835                break;
07836                
07837             case 3:
07838                if(!multimode){
07839                   if((s2[2] != '0')&&(s2[2] != '5'))
07840                      goto invalid_freq;
07841                }
07842                ht = 0;
07843                k = atoi(s2);
07844                   break;
07845             case 4:
07846                k = atoi(s2)/10;
07847                ht = 10 * (atoi(s2+(ls2-1)));
07848                break;
07849 
07850             case 5:
07851                k = atoi(s2)/100;
07852                ht = (atoi(s2+(ls2-2)));
07853                break;
07854                
07855             default:
07856                goto invalid_freq;
07857          }
07858 
07859          /* Check frequency for validity and establish a default mode */
07860          
07861          snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht);
07862 
07863          if(debug)
07864             printf("New frequency: %s\n", freq);      
07865    
07866          split_freq(mhz, decimals, freq);
07867          m = atoi(mhz);
07868          d = atoi(decimals);
07869 
07870                         if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */
07871                                 goto invalid_freq;
07872 
07873 
07874          if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */
07875             break; /* Not yet */
07876 
07877 
07878          offset = REM_SIMPLEX; /* Assume simplex */
07879 
07880          if(defmode == REM_MODE_FM){
07881             oc = *s; /* Pick off offset */
07882          
07883             if (oc){
07884                switch(oc){
07885                   case '1':
07886                      offset = REM_MINUS;
07887                      break;
07888                   
07889                   case '2':
07890                      offset = REM_SIMPLEX;
07891                   break;
07892                   
07893                   case '3':
07894                      offset = REM_PLUS;
07895                      break;
07896                   
07897                   default:
07898                      goto invalid_freq;
07899                } 
07900             } 
07901          }  
07902          offsave = myrpt->offset;
07903          modesave = myrpt->remmode;
07904          strncpy(savestr, myrpt->freq, sizeof(savestr) - 1);
07905          strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1);
07906          myrpt->offset = offset;
07907          myrpt->remmode = defmode;
07908 
07909          if (setrem(myrpt) == -1){
07910             myrpt->offset = offsave;
07911             myrpt->remmode = modesave;
07912             strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1);
07913             goto invalid_freq;
07914          }
07915 
07916          return DC_COMPLETE;
07917 
07918 invalid_freq:
07919          rpt_telemetry(myrpt,INVFREQ,NULL);
07920          return DC_ERROR; 
07921       
07922       case 3: /* set rx PL tone */
07923             for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
07924             if(digitbuf[i] == '*'){
07925                j++;
07926                continue;
07927             }
07928             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
07929                return DC_ERROR;
07930             else{
07931                if(j)
07932                   l++;
07933                else
07934                   k++;
07935             }
07936          }
07937          if((j > 1) || (k > 3) || (l > 1))
07938             return DC_ERROR; /* &$@^! */
07939          i = strlen(digitbuf) - 1;
07940          if((j != 1) || (k < 2)|| (l != 1))
07941             break; /* Not yet */
07942          if(debug)
07943             printf("PL digits entered %s\n", digitbuf);
07944             
07945          strncpy(tmp, digitbuf, sizeof(tmp) - 1);
07946          /* see if we have at least 1 */
07947          s = strchr(tmp,'*');
07948          if(s)
07949             *s = '.';
07950          strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1);
07951          strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1);
07952          if(!strcmp(myrpt->remote, remote_rig_rbi))
07953          {
07954             strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1);
07955          }
07956          if (setrem(myrpt) == -1){
07957             strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1);
07958             return DC_ERROR;
07959          }
07960       
07961       
07962          return DC_COMPLETE;
07963       
07964       case 4: /* set tx PL tone */
07965          /* cant set tx tone on RBI (rx tone does both) */
07966          if(!strcmp(myrpt->remote, remote_rig_rbi))
07967             return DC_ERROR;
07968          if(!strcmp(myrpt->remote, remote_rig_ic706))
07969             return DC_ERROR;
07970             for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
07971             if(digitbuf[i] == '*'){
07972                j++;
07973                continue;
07974             }
07975             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
07976                return DC_ERROR;
07977             else{
07978                if(j)
07979                   l++;
07980                else
07981                   k++;
07982             }
07983          }
07984          if((j > 1) || (k > 3) || (l > 1))
07985             return DC_ERROR; /* &$@^! */
07986          i = strlen(digitbuf) - 1;
07987          if((j != 1) || (k < 2)|| (l != 1))
07988             break; /* Not yet */
07989          if(debug)
07990             printf("PL digits entered %s\n", digitbuf);
07991             
07992          strncpy(tmp, digitbuf, sizeof(tmp) - 1);
07993          /* see if we have at least 1 */
07994          s = strchr(tmp,'*');
07995          if(s)
07996             *s = '.';
07997          strncpy(savestr, myrpt->txpl, sizeof(savestr) - 1);
07998          strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1);
07999          
08000          if (setrem(myrpt) == -1){
08001             strncpy(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1);
08002             return DC_ERROR;
08003          }
08004       
08005       
08006          return DC_COMPLETE;
08007       
08008 
08009       case 6: /* MODE (FM,USB,LSB,AM) */
08010          if(strlen(digitbuf) < 1)
08011             break;
08012 
08013          if(!multimode)
08014             return DC_ERROR; /* Multimode radios only */
08015 
08016          switch(*digitbuf){
08017             case '1':
08018                split_freq(mhz, decimals, myrpt->freq); 
08019                m=atoi(mhz);
08020                if(m < 29) /* No FM allowed below 29MHz! */
08021                   return DC_ERROR;
08022                myrpt->remmode = REM_MODE_FM;
08023                
08024                rpt_telemetry(myrpt,REMMODE,NULL);
08025                break;
08026 
08027             case '2':
08028                myrpt->remmode = REM_MODE_USB;
08029                rpt_telemetry(myrpt,REMMODE,NULL);
08030                break;   
08031 
08032             case '3':
08033                myrpt->remmode = REM_MODE_LSB;
08034                rpt_telemetry(myrpt,REMMODE,NULL);
08035                break;
08036             
08037             case '4':
08038                myrpt->remmode = REM_MODE_AM;
08039                rpt_telemetry(myrpt,REMMODE,NULL);
08040                break;
08041       
08042             default:
08043                return DC_ERROR;
08044          }
08045 
08046          if(setrem(myrpt))
08047             return DC_ERROR;
08048          return DC_COMPLETEQUIET;
08049       case 99:
08050          /* cant log in when logged in */
08051          if (myrpt->loginlevel[0]) 
08052             return DC_ERROR;
08053          *myrpt->loginuser = 0;
08054          myrpt->loginlevel[0] = 0;
08055          cp = strdup(param);
08056          cp1 = strchr(cp,',');
08057          ast_mutex_lock(&myrpt->lock);
08058          if (cp1) 
08059          {
08060             *cp1 = 0;
08061             cp2 = strchr(cp1 + 1,',');
08062             if (cp2) 
08063             {
08064                *cp2 = 0;
08065                strncpy(myrpt->loginlevel,cp2 + 1,
08066                   sizeof(myrpt->loginlevel) - 1);
08067             }
08068             strncpy(myrpt->loginuser,cp1 + 1,sizeof(myrpt->loginuser));
08069             ast_mutex_unlock(&myrpt->lock);
08070             if (myrpt->p.archivedir)
08071             {
08072                char str[100];
08073 
08074                sprintf(str,"LOGIN,%s,%s",
08075                    myrpt->loginuser,myrpt->loginlevel);
08076                donodelog(myrpt,str);
08077             }
08078             if (debug) 
08079                printf("loginuser %s level %s\n",myrpt->loginuser,myrpt->loginlevel);
08080             rpt_telemetry(myrpt,REMLOGIN,NULL);
08081          }
08082          free(cp);
08083          return DC_COMPLETEQUIET;
08084       case 100: /* RX PL Off */
08085          myrpt->rxplon = 0;
08086          setrem(myrpt);
08087          rpt_telemetry(myrpt,REMXXX,(void *)p);
08088          return DC_COMPLETEQUIET;
08089       case 101: /* RX PL On */
08090          myrpt->rxplon = 1;
08091          setrem(myrpt);
08092          rpt_telemetry(myrpt,REMXXX,(void *)p);
08093          return DC_COMPLETEQUIET;
08094       case 102: /* TX PL Off */
08095          myrpt->txplon = 0;
08096          setrem(myrpt);
08097          rpt_telemetry(myrpt,REMXXX,(void *)p);
08098          return DC_COMPLETEQUIET;
08099       case 103: /* TX PL On */
08100          myrpt->txplon = 1;
08101          setrem(myrpt);
08102          rpt_telemetry(myrpt,REMXXX,(void *)p);
08103          return DC_COMPLETEQUIET;
08104       case 104: /* Low Power */
08105          if(!strcmp(myrpt->remote, remote_rig_ic706))
08106             return DC_ERROR;
08107          myrpt->powerlevel = REM_LOWPWR;
08108          setrem(myrpt);
08109          rpt_telemetry(myrpt,REMXXX,(void *)p);
08110          return DC_COMPLETEQUIET;
08111       case 105: /* Medium Power */
08112          if(!strcmp(myrpt->remote, remote_rig_ic706))
08113             return DC_ERROR;
08114          myrpt->powerlevel = REM_MEDPWR;
08115          setrem(myrpt);
08116          rpt_telemetry(myrpt,REMXXX,(void *)p);
08117          return DC_COMPLETEQUIET;
08118       case 106: /* Hi Power */
08119          if(!strcmp(myrpt->remote, remote_rig_ic706))
08120             return DC_ERROR;
08121          myrpt->powerlevel = REM_HIPWR;
08122          setrem(myrpt);
08123          rpt_telemetry(myrpt,REMXXX,(void *)p);
08124          return DC_COMPLETEQUIET;
08125       case 107: /* Bump down 20Hz */
08126          multimode_bump_freq(myrpt, -20);
08127          return DC_COMPLETE;
08128       case 108: /* Bump down 100Hz */
08129          multimode_bump_freq(myrpt, -100);
08130          return DC_COMPLETE;
08131       case 109: /* Bump down 500Hz */
08132          multimode_bump_freq(myrpt, -500);
08133          return DC_COMPLETE;
08134       case 110: /* Bump up 20Hz */
08135          multimode_bump_freq(myrpt, 20);
08136          return DC_COMPLETE;
08137       case 111: /* Bump up 100Hz */
08138          multimode_bump_freq(myrpt, 100);
08139          return DC_COMPLETE;
08140       case 112: /* Bump up 500Hz */
08141          multimode_bump_freq(myrpt, 500);
08142          return DC_COMPLETE;
08143       case 113: /* Scan down slow */
08144          myrpt->scantimer = REM_SCANTIME;
08145          myrpt->hfscanmode = HF_SCAN_DOWN_SLOW;
08146          rpt_telemetry(myrpt,REMXXX,(void *)p);
08147          return DC_COMPLETEQUIET;
08148       case 114: /* Scan down quick */
08149          myrpt->scantimer = REM_SCANTIME;
08150          myrpt->hfscanmode = HF_SCAN_DOWN_QUICK;
08151          rpt_telemetry(myrpt,REMXXX,(void *)p);
08152          return DC_COMPLETEQUIET;
08153       case 115: /* Scan down fast */
08154          myrpt->scantimer = REM_SCANTIME;
08155          myrpt->hfscanmode = HF_SCAN_DOWN_FAST;
08156          rpt_telemetry(myrpt,REMXXX,(void *)p);
08157          return DC_COMPLETEQUIET;
08158       case 116: /* Scan up slow */
08159          myrpt->scantimer = REM_SCANTIME;
08160          myrpt->hfscanmode = HF_SCAN_UP_SLOW;
08161          rpt_telemetry(myrpt,REMXXX,(void *)p);
08162          return DC_COMPLETEQUIET;
08163       case 117: /* Scan up quick */
08164          myrpt->scantimer = REM_SCANTIME;
08165          myrpt->hfscanmode = HF_SCAN_UP_QUICK;
08166          rpt_telemetry(myrpt,REMXXX,(void *)p);
08167          return DC_COMPLETEQUIET;
08168       case 118: /* Scan up fast */
08169          myrpt->scantimer = REM_SCANTIME;
08170          myrpt->hfscanmode = HF_SCAN_UP_FAST;
08171          rpt_telemetry(myrpt,REMXXX,(void *)p);
08172          return DC_COMPLETEQUIET;
08173       case 119: /* Tune Request */
08174          /* if not currently going, and valid to do */
08175          if((!myrpt->tunerequest) && 
08176              ((!strcmp(myrpt->remote, remote_rig_ft897) || 
08177             !strcmp(myrpt->remote, remote_rig_ic706)) )) { 
08178             myrpt->remotetx = 0;
08179             ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
08180             myrpt->tunerequest = 1;
08181             rpt_telemetry(myrpt,TUNE,NULL);
08182             return DC_COMPLETEQUIET;
08183          }
08184          return DC_ERROR;        
08185       case 5: /* Long Status */
08186          rpt_telemetry(myrpt,REMLONGSTATUS,NULL);
08187          return DC_COMPLETEQUIET;
08188       case 140: /* Short Status */
08189          rpt_telemetry(myrpt,REMSHORTSTATUS,NULL);
08190          return DC_COMPLETEQUIET;
08191       case 200:
08192       case 201:
08193       case 202:
08194       case 203:
08195       case 204:
08196       case 205:
08197       case 206:
08198       case 207:
08199       case 208:
08200       case 209:
08201       case 210:
08202       case 211:
08203       case 212:
08204       case 213:
08205       case 214:
08206       case 215:
08207          do_dtmf_local(myrpt,remdtmfstr[p - 200]);
08208          return DC_COMPLETEQUIET;
08209       default:
08210          break;
08211    }
08212    return DC_INDETERMINATE;
08213 }

static int function_status ( 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 DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, ID1, myatoi(), rpt::p, rpt_telemetry(), rpt::s, STATS_TIME, STATS_VERSION, and rpt::sysstate_cur.

05019 {
05020 
05021    if (!param)
05022       return DC_ERROR;
05023 
05024    if ((myrpt->p.s[myrpt->p.sysstate_cur].txdisable) || (myrpt->p.s[myrpt->p.sysstate_cur].userfundisable))
05025       return DC_ERROR;
05026 
05027    if(debug)
05028       printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
05029    
05030    switch(myatoi(param)){
05031       case 1: /* System ID */
05032          rpt_telemetry(myrpt, ID1, NULL);
05033          return DC_COMPLETE;
05034       case 2: /* System Time */
05035          rpt_telemetry(myrpt, STATS_TIME, NULL);
05036          return DC_COMPLETE;
05037       case 3: /* app_rpt.c version */
05038          rpt_telemetry(myrpt, STATS_VERSION, NULL);
05039       default:
05040          return DC_ERROR;
05041    }
05042    return DC_INDETERMINATE;
05043 }

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

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

02816 {
02817         int interval;
02818         char *wait_times;
02819         char *wait_times_save;
02820                                                                                                                   
02821         wait_times_save = NULL;
02822         wait_times = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "wait_times");
02823                                                                                                                   
02824         if(wait_times){
02825                 wait_times_save = ast_strdupa(wait_times);
02826                 if(!wait_times_save){
02827                         ast_log(LOG_WARNING, "Out of memory in wait_interval()\n");
02828                         wait_times = NULL;
02829                 }
02830         }
02831                                                                                                                   
02832         switch(type){
02833                 case DLY_TELEM:
02834                         if(wait_times)
02835                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "telemwait", 500, 5000, 1000);
02836                         else
02837                                 interval = 1000;
02838                         break;
02839                                                                                                                   
02840                 case DLY_ID:
02841                         if(wait_times)
02842                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "idwait",250,5000,500);
02843                         else
02844                                 interval = 500;
02845                         break;
02846                                                                                                                   
02847                 case DLY_UNKEY:
02848                         if(wait_times)
02849                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "unkeywait",500,5000,1000);
02850                         else
02851                                 interval = 1000;
02852                         break;
02853                                                                                                                   
02854                 case DLY_LINKUNKEY:
02855                         if(wait_times)
02856                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "linkunkeywait",500,5000,1000);
02857                         else
02858                                 interval = 1000;
02859                         break;
02860                                                                                                                   
02861                 case DLY_CALLTERM:
02862                         if(wait_times)
02863                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "calltermwait",500,5000,1500);
02864                         else
02865                                 interval = 1500;
02866                         break;
02867                                                                                                                   
02868                 case DLY_COMP:
02869                         if(wait_times)
02870                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "compwait",500,5000,200);
02871                         else
02872                                 interval = 200;
02873                         break;
02874                                                                                                                   
02875                 default:
02876                         return 0;
02877         }
02878    return interval;
02879 }                                                                                                                  

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

Definition at line 5297 of file app_rpt.c.

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

Referenced by rpt().

05299 {
05300 char  tmp[512],cmd[300] = "",dest[300],src[300],c;
05301 int   seq, res;
05302 struct rpt_link *l;
05303 struct   ast_frame wf;
05304 
05305    wf.frametype = AST_FRAME_TEXT;
05306    wf.subclass = 0;
05307    wf.offset = 0;
05308    wf.mallocd = 0;
05309    wf.datalen = strlen(str) + 1;
05310    wf.samples = 0;
05311    /* put string in our buffer */
05312    strncpy(tmp,str,sizeof(tmp) - 1);
05313 
05314         if (!strcmp(tmp,discstr))
05315         {
05316                 mylink->disced = 1;
05317       mylink->retries = mylink->max_retries + 1;
05318                 ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV);
05319                 return;
05320         }
05321    if (tmp[0] == 'L')
05322    {
05323       rpt_mutex_lock(&myrpt->lock);
05324       strcpy(mylink->linklist,tmp + 2);
05325       time(&mylink->linklistreceived);
05326       rpt_mutex_unlock(&myrpt->lock);
05327       if (debug > 6) ast_log(LOG_NOTICE,"@@@@ node %s recieved node list %s from node %s\n",
05328          myrpt->name,tmp,mylink->name);
05329       return;
05330    }
05331    if (tmp[0] == 'I')
05332    {
05333       if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3)
05334       {
05335          ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
05336          return;
05337       }
05338       mdc1200_notify(myrpt,src,seq);
05339       strcpy(dest,"*");
05340    }
05341    else
05342    {
05343       if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
05344       {
05345          ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
05346          return;
05347       }
05348       if (strcmp(cmd,"D"))
05349       {
05350          ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
05351          return;
05352       }
05353    }
05354    if (dest[0] == '0')
05355    {
05356       strcpy(dest,myrpt->name);
05357    }     
05358 
05359    /* if not for me, redistribute to all links */
05360    if (strcmp(dest,myrpt->name))
05361    {
05362       l = myrpt->links.next;
05363       /* see if this is one in list */
05364       while(l != &myrpt->links)
05365       {
05366          if (l->name[0] == '0') 
05367          {
05368             l = l->next;
05369             continue;
05370          }
05371          /* dont send back from where it came */
05372          if ((l == mylink) || (!strcmp(l->name,mylink->name)))
05373          {
05374             l = l->next;
05375             continue;
05376          }
05377          /* if it is, send it and we're done */
05378          if (!strcmp(l->name,dest))
05379          {
05380             /* send, but not to src */
05381             if (strcmp(l->name,src)) {
05382                wf.data = str;
05383                if (l->chan) ast_write(l->chan,&wf);
05384             }
05385             return;
05386          }
05387          l = l->next;
05388       }
05389       l = myrpt->links.next;
05390       /* otherwise, send it to all of em */
05391       while(l != &myrpt->links)
05392       {
05393          if (l->name[0] == '0') 
05394          {
05395             l = l->next;
05396             continue;
05397          }
05398          /* dont send back from where it came */
05399          if ((l == mylink) || (!strcmp(l->name,mylink->name)))
05400          {
05401             l = l->next;
05402             continue;
05403          }
05404          /* send, but not to src */
05405          if (strcmp(l->name,src)) {
05406             wf.data = str;
05407             if (l->chan) ast_write(l->chan,&wf); 
05408          }
05409          l = l->next;
05410       }
05411       return;
05412    }
05413    if (myrpt->p.archivedir)
05414    {
05415       char str[100];
05416 
05417       sprintf(str,"DTMF,%s,%c",mylink->name,c);
05418       donodelog(myrpt,str);
05419    }
05420    c = func_xlat(myrpt,c,&myrpt->p.outxlat);
05421    if (!c) return;
05422    rpt_mutex_lock(&myrpt->lock);
05423    if (c == myrpt->p.endchar) myrpt->stopgen = 1;
05424    if (myrpt->callmode == 1)
05425    {
05426       myrpt->exten[myrpt->cidx++] = c;
05427       myrpt->exten[myrpt->cidx] = 0;
05428       /* if this exists */
05429       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
05430       {
05431          myrpt->callmode = 2;
05432          if(!myrpt->patchquiet){
05433             rpt_mutex_unlock(&myrpt->lock);
05434             rpt_telemetry(myrpt,PROC,NULL); 
05435             rpt_mutex_lock(&myrpt->lock);
05436          }
05437       }
05438       /* if can continue, do so */
05439       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 
05440       {
05441          /* call has failed, inform user */
05442          myrpt->callmode = 4;
05443       }
05444    }
05445    if (c == myrpt->p.funcchar)
05446    {
05447       myrpt->rem_dtmfidx = 0;
05448       myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
05449       time(&myrpt->rem_dtmf_time);
05450       rpt_mutex_unlock(&myrpt->lock);
05451       return;
05452    } 
05453    else if (myrpt->rem_dtmfidx < 0)
05454    {
05455       if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
05456       {
05457          myrpt->mydtmf = c;
05458       }
05459       if (myrpt->p.propagate_dtmf) do_dtmf_local(myrpt,c);
05460       if (myrpt->p.propagate_phonedtmf) do_dtmf_phone(myrpt,mylink,c);
05461       rpt_mutex_unlock(&myrpt->lock);
05462       return;
05463    }
05464    else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0))
05465    {
05466       time(&myrpt->rem_dtmf_time);
05467       if (myrpt->rem_dtmfidx < MAXDTMF)
05468       {
05469          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
05470          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
05471          
05472          rpt_mutex_unlock(&myrpt->lock);
05473          strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
05474          res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink);
05475          rpt_mutex_lock(&myrpt->lock);
05476          
05477          switch(res){
05478 
05479             case DC_INDETERMINATE:
05480                break;
05481             
05482             case DC_REQ_FLUSH:
05483                myrpt->rem_dtmfidx = 0;
05484                myrpt->rem_dtmfbuf[0] = 0;
05485                break;
05486             
05487             
05488             case DC_COMPLETE:
05489             case DC_COMPLETEQUIET:
05490                myrpt->totalexecdcommands++;
05491                myrpt->dailyexecdcommands++;
05492                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
05493                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
05494                myrpt->rem_dtmfbuf[0] = 0;
05495                myrpt->rem_dtmfidx = -1;
05496                myrpt->rem_dtmf_time = 0;
05497                break;
05498             
05499             case DC_ERROR:
05500             default:
05501                myrpt->rem_dtmfbuf[0] = 0;
05502                myrpt->rem_dtmfidx = -1;
05503                myrpt->rem_dtmf_time = 0;
05504                break;
05505          }
05506       }
05507 
05508    }
05509    rpt_mutex_unlock(&myrpt->lock);
05510    return;
05511 }

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

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

05515 {
05516 
05517 char  cmd[300];
05518 int   res;
05519 
05520    if (myrpt->p.archivedir)
05521    {
05522       char str[100];
05523 
05524       sprintf(str,"DTMF(P),%s,%c",mylink->name,c);
05525       donodelog(myrpt,str);
05526    }
05527    rpt_mutex_lock(&myrpt->lock);
05528    if (c == myrpt->p.endchar)
05529    {
05530       if (mylink->lastrx)
05531       {
05532          mylink->lastrx = 0;
05533          rpt_mutex_unlock(&myrpt->lock);
05534          return;
05535       }
05536       myrpt->stopgen = 1;
05537       if (myrpt->cmdnode[0])
05538       {
05539          myrpt->cmdnode[0] = 0;
05540          myrpt->dtmfidx = -1;
05541          myrpt->dtmfbuf[0] = 0;
05542          rpt_mutex_unlock(&myrpt->lock);
05543          rpt_telemetry(myrpt,COMPLETE,NULL);
05544          return;
05545       }
05546    }
05547    if (myrpt->cmdnode[0])
05548    {
05549       rpt_mutex_unlock(&myrpt->lock);
05550       send_link_dtmf(myrpt,c);
05551       return;
05552    }
05553    if (myrpt->callmode == 1)
05554    {
05555       myrpt->exten[myrpt->cidx++] = c;
05556       myrpt->exten[myrpt->cidx] = 0;
05557       /* if this exists */
05558       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
05559       {
05560          myrpt->callmode = 2;
05561          if(!myrpt->patchquiet){
05562             rpt_mutex_unlock(&myrpt->lock);
05563             rpt_telemetry(myrpt,PROC,NULL); 
05564             rpt_mutex_lock(&myrpt->lock);
05565          }
05566       }
05567       /* if can continue, do so */
05568       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 
05569       {
05570          /* call has failed, inform user */
05571          myrpt->callmode = 4;
05572       }
05573    }
05574    if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
05575    {
05576       myrpt->mydtmf = c;
05577    }
05578    if (c == myrpt->p.funcchar)
05579    {
05580       myrpt->rem_dtmfidx = 0;
05581       myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
05582       time(&myrpt->rem_dtmf_time);
05583       rpt_mutex_unlock(&myrpt->lock);
05584       return;
05585    } 
05586    else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0))
05587    {
05588       time(&myrpt->rem_dtmf_time);
05589       if (myrpt->rem_dtmfidx < MAXDTMF)
05590       {
05591          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
05592          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
05593          
05594          rpt_mutex_unlock(&myrpt->lock);
05595          strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
05596          switch(mylink->phonemode)
05597          {
05598              case 1:
05599             res = collect_function_digits(myrpt, cmd, 
05600                SOURCE_PHONE, mylink);
05601             break;
05602              case 2:
05603             res = collect_function_digits(myrpt, cmd, 
05604                SOURCE_DPHONE,mylink);
05605             break;
05606              default:
05607             res = collect_function_digits(myrpt, cmd, 
05608                SOURCE_LNK, mylink);
05609             break;
05610          }
05611 
05612          rpt_mutex_lock(&myrpt->lock);
05613          
05614          switch(res){
05615 
05616             case DC_INDETERMINATE:
05617                break;
05618             
05619             case DC_DOKEY:
05620                mylink->lastrx = 1;
05621                break;
05622             
05623             case DC_REQ_FLUSH:
05624                myrpt->rem_dtmfidx = 0;
05625                myrpt->rem_dtmfbuf[0] = 0;
05626                break;
05627             
05628             
05629             case DC_COMPLETE:
05630             case DC_COMPLETEQUIET:
05631                myrpt->totalexecdcommands++;
05632                myrpt->dailyexecdcommands++;
05633                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
05634                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
05635                myrpt->rem_dtmfbuf[0] = 0;
05636                myrpt->rem_dtmfidx = -1;
05637                myrpt->rem_dtmf_time = 0;
05638                break;
05639             
05640             case DC_ERROR:
05641             default:
05642                myrpt->rem_dtmfbuf[0] = 0;
05643                myrpt->rem_dtmfidx = -1;
05644                myrpt->rem_dtmf_time = 0;
05645                break;
05646          }
05647       }
05648 
05649    }
05650    rpt_mutex_unlock(&myrpt->lock);
05651    return;
05652 }

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

Definition at line 8326 of file app_rpt.c.

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

08327 {
08328 char  tmp[300],cmd[300],dest[300],src[300],c;
08329 int   seq,res;
08330 
08331    /* put string in our buffer */
08332    strncpy(tmp,str,sizeof(tmp) - 1);
08333    if (!strcmp(tmp,discstr)) return 0;
08334 
08335 #ifndef  DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES
08336    if (tmp[0] == 'I')
08337    {
08338       if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3)
08339       {
08340          ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
08341          return 0;
08342       }
08343       mdc1200_notify(myrpt,src,seq);
08344       return 0;
08345    }
08346 #endif
08347    if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
08348    {
08349       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
08350       return 0;
08351    }
08352    if (strcmp(cmd,"D"))
08353    {
08354       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
08355       return 0;
08356    }
08357    /* if not for me, ignore */
08358    if (strcmp(dest,myrpt->name)) return 0;
08359    if (myrpt->p.archivedir)
08360    {
08361       char str[100];
08362 
08363       sprintf(str,"DTMF,%c",c);
08364       donodelog(myrpt,str);
08365    }
08366    c = func_xlat(myrpt,c,&myrpt->p.outxlat);
08367    if (!c) return(0);
08368    res = handle_remote_dtmf_digit(myrpt,c, NULL, 0);
08369    if (res != 1)
08370       return res;
08371    rpt_telemetry(myrpt,COMPLETE,NULL);
08372    return 0;
08373 }

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

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

08217 {
08218 time_t   now;
08219 int   ret,res = 0,src;
08220 
08221    time(&myrpt->last_activity_time);
08222    /* Stop scan mode if in scan mode */
08223    if(myrpt->hfscanmode){
08224       stop_scan(myrpt);
08225       return 0;
08226    }
08227 
08228    time(&now);
08229    /* if timed-out */
08230    if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now)
08231    {
08232       myrpt->dtmfidx = -1;
08233       myrpt->dtmfbuf[0] = 0;
08234       myrpt->dtmf_time_rem = 0;
08235    }
08236    /* if decode not active */
08237    if (myrpt->dtmfidx == -1)
08238    {
08239       /* if not lead-in digit, dont worry */
08240       if (c != myrpt->p.funcchar)
08241       {
08242          if (!myrpt->p.propagate_dtmf)
08243          {
08244             rpt_mutex_lock(&myrpt->lock);
08245             do_dtmf_local(myrpt,c);
08246             rpt_mutex_unlock(&myrpt->lock);
08247          }
08248          return 0;
08249       }
08250       myrpt->dtmfidx = 0;
08251       myrpt->dtmfbuf[0] = 0;
08252       myrpt->dtmf_time_rem = now;
08253       return 0;
08254    }
08255    /* if too many in buffer, start over */
08256    if (myrpt->dtmfidx >= MAXDTMF)
08257    {
08258       myrpt->dtmfidx = 0;
08259       myrpt->dtmfbuf[0] = 0;
08260       myrpt->dtmf_time_rem = now;
08261    }
08262    if (c == myrpt->p.funcchar)
08263    {
08264       /* if star at beginning, or 2 together, erase buffer */
08265       if ((myrpt->dtmfidx < 1) || 
08266          (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->p.funcchar))
08267       {
08268          myrpt->dtmfidx = 0;
08269          myrpt->dtmfbuf[0] = 0;
08270          myrpt->dtmf_time_rem = now;
08271          return 0;
08272       }
08273    }
08274    myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
08275    myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
08276    myrpt->dtmf_time_rem = now;
08277    
08278    
08279    src = SOURCE_RMT;
08280    if (phonemode > 1) src = SOURCE_DPHONE;
08281    else if (phonemode) src = SOURCE_PHONE;
08282    ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL);
08283    
08284    switch(ret){
08285    
08286       case DC_INDETERMINATE:
08287          res = 0;
08288          break;
08289             
08290       case DC_DOKEY:
08291          if (keyed) *keyed = 1;
08292          res = 0;
08293          break;
08294             
08295       case DC_REQ_FLUSH:
08296          myrpt->dtmfidx = 0;
08297          myrpt->dtmfbuf[0] = 0;
08298          res = 0;
08299          break;
08300             
08301             
08302       case DC_COMPLETE:
08303          res = 1;
08304       case DC_COMPLETEQUIET:
08305          myrpt->totalexecdcommands++;
08306          myrpt->dailyexecdcommands++;
08307          strncpy(myrpt->lastdtmfcommand, myrpt->dtmfbuf, MAXDTMF-1);
08308          myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
08309          myrpt->dtmfbuf[0] = 0;
08310          myrpt->dtmfidx = -1;
08311          myrpt->dtmf_time_rem = 0;
08312          break;
08313             
08314       case DC_ERROR:
08315       default:
08316          myrpt->dtmfbuf[0] = 0;
08317          myrpt->dtmfidx = -1;
08318          myrpt->dtmf_time_rem = 0;
08319          res = 0;
08320          break;
08321    }
08322 
08323    return res;
08324 }

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

Definition at line 8375 of file app_rpt.c.

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

08376 {
08377 int   res;
08378 
08379 
08380    if (keyed && *keyed && (c == myrpt->p.endchar))
08381    {
08382       *keyed = 0;
08383       return DC_INDETERMINATE;
08384    }
08385 
08386    if (myrpt->p.archivedir)
08387    {
08388       char str[100];
08389 
08390       sprintf(str,"DTMF(P),%c",c);
08391       donodelog(myrpt,str);
08392    }
08393    res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode);
08394    if (res != 1)
08395       return res;
08396    rpt_telemetry(myrpt,COMPLETE,NULL);
08397    return 0;
08398 }

static int ic706_pltocode ( char *  str  )  [static]

Definition at line 6871 of file app_rpt.c.

References s.

Referenced by set_ic706().

06872 {
06873 int i;
06874 char *s;
06875 
06876    s = strchr(str,'.');
06877    i = 0;
06878    if (s) i = atoi(s + 1);
06879    i += atoi(str) * 10;
06880    switch(i)
06881    {
06882        case 670:
06883       return 0;
06884        case 693:
06885       return 1;
06886        case 719:
06887       return 2;
06888        case 744:
06889       return 3;
06890        case 770:
06891       return 4;
06892        case 797:
06893       return 5;
06894        case 825:
06895       return 6;
06896        case 854:
06897       return 7;
06898        case 885:
06899       return 8;
06900        case 915:
06901       return 9;
06902        case 948:
06903       return 10;
06904        case 974:
06905       return 11;
06906        case 1000:
06907       return 12;
06908        case 1035:
06909       return 13;
06910        case 1072:
06911       return 14;
06912        case 1109:
06913       return 15;
06914        case 1148:
06915       return 16;
06916        case 1188:
06917       return 17;
06918        case 1230:
06919       return 18;
06920        case 1273:
06921       return 19;
06922        case 1318:
06923       return 20;
06924        case 1365:
06925       return 21;
06926        case 1413:
06927       return 22;
06928        case 1462:
06929       return 23;
06930        case 1514:
06931       return 24;
06932        case 1567:
06933       return 25;
06934        case 1598:
06935       return 26;
06936        case 1622:
06937       return 27;
06938        case 1655:
06939       return 28;     
06940        case 1679:
06941       return 29;
06942        case 1713:
06943       return 30;
06944        case 1738:
06945       return 31;
06946        case 1773:
06947       return 32;
06948        case 1799:
06949       return 33;
06950             case 1835:
06951       return 34;
06952        case 1862:
06953       return 35;
06954        case 1899:
06955       return 36;
06956        case 1928:
06957       return 37;
06958        case 1966:
06959       return 38;
06960        case 1995:
06961       return 39;
06962        case 2035:
06963       return 40;
06964        case 2065:
06965       return 41;
06966        case 2107:
06967       return 42;
06968        case 2181:
06969       return 43;
06970        case 2257:
06971       return 44;
06972        case 2291:
06973       return 45;
06974        case 2336:
06975       return 46;
06976        case 2418:
06977       return 47;
06978        case 2503:
06979       return 48;
06980        case 2541:
06981       return 49;
06982    }
06983    return -1;
06984 }

static int kenwood_pltocode ( char *  str  )  [static]

Definition at line 5984 of file app_rpt.c.

References s.

Referenced by setkenwood().

05985 {
05986 int i;
05987 char *s;
05988 
05989    s = strchr(str,'.');
05990    i = 0;
05991    if (s) i = atoi(s + 1);
05992    i += atoi(str) * 10;
05993    switch(i)
05994    {
05995        case 670:
05996       return 1;
05997        case 719:
05998       return 3;
05999        case 744:
06000       return 4;
06001        case 770:
06002       return 5;
06003        case 797:
06004       return 6;
06005        case 825:
06006       return 7;
06007        case 854:
06008       return 8;
06009        case 885:
06010       return 9;
06011        case 915:
06012       return 10;
06013        case 948:
06014       return 11;
06015        case 974:
06016       return 12;
06017        case 1000:
06018       return 13;
06019        case 1035:
06020       return 14;
06021        case 1072:
06022       return 15;
06023        case 1109:
06024       return 16;
06025        case 1148:
06026       return 17;
06027        case 1188:
06028       return 18;
06029        case 1230:
06030       return 19;
06031        case 1273:
06032       return 20;
06033        case 1318:
06034       return 21;
06035        case 1365:
06036       return 22;
06037        case 1413:
06038       return 23;
06039        case 1462:
06040       return 24;
06041        case 1514:
06042       return 25;
06043        case 1567:
06044       return 26;
06045        case 1622:
06046       return 27;
06047        case 1679:
06048       return 28;
06049        case 1738:
06050       return 29;
06051        case 1799:
06052       return 30;
06053        case 1862:
06054       return 31;
06055        case 1928:
06056       return 32;
06057        case 2035:
06058       return 33;
06059        case 2107:
06060       return 34;
06061        case 2181:
06062       return 35;
06063        case 2257:
06064       return 36;
06065        case 2336:
06066       return 37;
06067        case 2418:
06068       return 38;
06069        case 2503:
06070       return 39;
06071    }
06072    return -1;
06073 }

static int load_module ( void   )  [static]

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

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

Referenced by rpt(), and rpt_master().

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

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

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

08463 {
08464 int   res;
08465 pthread_attr_t attr;
08466 char  cmd[MAXDTMF+1] = "";
08467 
08468    if (myrpt->p.archivedir)
08469    {
08470       char str[100];
08471 
08472       sprintf(str,"DTMF,MAIN,%c",c);
08473       donodelog(myrpt,str);
08474    }
08475    if (c == myrpt->p.endchar)
08476    {
08477    /* if in simple mode, kill autopatch */
08478       if (myrpt->p.simple && myrpt->callmode)
08479       {
08480          rpt_mutex_lock(&myrpt->lock);
08481          myrpt->callmode = 0;
08482          rpt_mutex_unlock(&myrpt->lock);
08483          rpt_telemetry(myrpt,TERM,NULL);
08484          return;
08485       }
08486       rpt_mutex_lock(&myrpt->lock);
08487       myrpt->stopgen = 1;
08488       if (myrpt->cmdnode[0])
08489       {
08490          myrpt->cmdnode[0] = 0;
08491          myrpt->dtmfidx = -1;
08492          myrpt->dtmfbuf[0] = 0;
08493          rpt_mutex_unlock(&myrpt->lock);
08494          rpt_telemetry(myrpt,COMPLETE,NULL);
08495       } 
08496       else
08497                 {
08498                         rpt_mutex_unlock(&myrpt->lock);
08499                         if (myrpt->p.propagate_phonedtmf)
08500                                do_dtmf_phone(myrpt,NULL,c);
08501                 }
08502       return;
08503    }
08504    rpt_mutex_lock(&myrpt->lock);
08505    if (myrpt->cmdnode[0])
08506    {
08507       rpt_mutex_unlock(&myrpt->lock);
08508       send_link_dtmf(myrpt,c);
08509       return;
08510    }
08511    if (!myrpt->p.simple)
08512    {
08513       if (c == myrpt->p.funcchar)
08514       {
08515          myrpt->dtmfidx = 0;
08516          myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
08517          rpt_mutex_unlock(&myrpt->lock);
08518          time(&myrpt->dtmf_time);
08519          return;
08520       } 
08521       else if ((c != myrpt->p.endchar) && (myrpt->dtmfidx >= 0))
08522       {
08523          time(&myrpt->dtmf_time);
08524          
08525          if (myrpt->dtmfidx < MAXDTMF)
08526          {
08527             myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
08528             myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
08529             
08530             strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1);
08531             
08532             rpt_mutex_unlock(&myrpt->lock);
08533             res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL);
08534             rpt_mutex_lock(&myrpt->lock);
08535             switch(res){
08536                 case DC_INDETERMINATE:
08537                break;
08538                 case DC_REQ_FLUSH:
08539                myrpt->dtmfidx = 0;
08540                myrpt->dtmfbuf[0] = 0;
08541                break;
08542                 case DC_COMPLETE:
08543                 case DC_COMPLETEQUIET:
08544                myrpt->totalexecdcommands++;
08545                myrpt->dailyexecdcommands++;
08546                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
08547                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
08548                myrpt->dtmfbuf[0] = 0;
08549                myrpt->dtmfidx = -1;
08550                myrpt->dtmf_time = 0;
08551                break;
08552 
08553                 case DC_ERROR:
08554                 default:
08555                myrpt->dtmfbuf[0] = 0;
08556                myrpt->dtmfidx = -1;
08557                myrpt->dtmf_time = 0;
08558                break;
08559             }
08560             if(res != DC_INDETERMINATE) {
08561                rpt_mutex_unlock(&myrpt->lock);
08562                return;
08563             }
08564          } 
08565       }
08566    }
08567    else /* if simple */
08568    {
08569       if ((!myrpt->callmode) && (c == myrpt->p.funcchar))
08570       {
08571          myrpt->callmode = 1;
08572          myrpt->patchnoct = 0;
08573          myrpt->patchquiet = 0;
08574          myrpt->patchfarenddisconnect = 0;
08575          myrpt->patchdialtime = 0;
08576          strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT);
08577          myrpt->cidx = 0;
08578          myrpt->exten[myrpt->cidx] = 0;
08579          rpt_mutex_unlock(&myrpt->lock);
08580               pthread_attr_init(&attr);
08581               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08582          ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt);
08583          return;
08584       }
08585    }
08586    if (myrpt->callmode == 1)
08587    {
08588       myrpt->exten[myrpt->cidx++] = c;
08589       myrpt->exten[myrpt->cidx] = 0;
08590       /* if this exists */
08591       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
08592       {
08593          myrpt->callmode = 2;
08594          rpt_mutex_unlock(&myrpt->lock);
08595          if(!myrpt->patchquiet)
08596             rpt_telemetry(myrpt,PROC,NULL); 
08597          return;
08598       }
08599       /* if can continue, do so */
08600       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
08601       {
08602          /* call has failed, inform user */
08603          myrpt->callmode = 4;
08604       }
08605       rpt_mutex_unlock(&myrpt->lock);
08606       return;
08607    }
08608    if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
08609    {
08610       myrpt->mydtmf = c;
08611    }
08612    rpt_mutex_unlock(&myrpt->lock);
08613    if ((myrpt->dtmfidx < 0) && myrpt->p.propagate_phonedtmf)
08614       do_dtmf_phone(myrpt,NULL,c);
08615    return;
08616 }

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

Definition at line 1474 of file app_rpt.c.

Referenced by function_autopatchup().

01475 {
01476 int   i,ls;
01477    for( i = 0 ; keywords[i] ; i++){
01478       ls = strlen(keywords[i]);
01479       if(!ls){
01480          *param = NULL;
01481          return 0;
01482       }
01483       if(!strncmp(string, keywords[i], ls)){
01484          if(param)
01485             *param = string + ls;
01486          return i + 1; 
01487       }
01488    }
01489    param = NULL;
01490    return 0;
01491 }

static void mdc1200_notify ( struct rpt myrpt,
char *  fromnode,
unsigned int  unit 
) [static]

Definition at line 1188 of file app_rpt.c.

References ast_verbose(), and rpt::name.

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

01189 {
01190    if (!fromnode)
01191    {
01192       ast_verbose("Got MDC-1200 ID %04X from local system (%s)\n",
01193          unit,myrpt->name);
01194    }
01195    else
01196    {
01197       ast_verbose("Got MDC-1200 ID %04X from node %s (%s)\n",
01198          unit,fromnode,myrpt->name);
01199    }
01200 }

static int mem2vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7185 of file app_rpt.c.

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

Referenced by set_ic706().

07186 {
07187    unsigned char cmdstr[10];
07188    
07189    cmdstr[0] = cmdstr[1] = 0xfe;
07190    cmdstr[2] = myrpt->p.civaddr;
07191    cmdstr[3] = 0xe0;
07192    cmdstr[4] = 0x0a;
07193    cmdstr[5] = 0xfd;
07194 
07195    return(civ_cmd(myrpt,cmdstr,6));
07196 }

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

Definition at line 7548 of file app_rpt.c.

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

Referenced by function_remote(), and service_scan().

07549 {
07550    if(!strcmp(myrpt->remote, remote_rig_ft897))
07551       return multimode_bump_freq_ft897(myrpt, interval);
07552    else if(!strcmp(myrpt->remote, remote_rig_ic706))
07553       return multimode_bump_freq_ic706(myrpt, interval);
07554    else
07555       return -1;
07556 }

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

Definition at line 6737 of file app_rpt.c.

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

Referenced by multimode_bump_freq().

06738 {
06739    int m,d;
06740    char mhz[MAXREMSTR], decimals[MAXREMSTR];
06741 
06742    if(debug)
06743       printf("Before bump: %s\n", myrpt->freq);
06744 
06745    if(split_freq(mhz, decimals, myrpt->freq))
06746       return -1;
06747    
06748    m = atoi(mhz);
06749    d = atoi(decimals);
06750 
06751    d += (interval / 10); /* 10Hz resolution */
06752    if(d < 0){
06753       m--;
06754       d += 100000;
06755    }
06756    else if(d >= 100000){
06757       m++;
06758       d -= 100000;
06759    }
06760 
06761    if(check_freq_ft897(m, d, NULL)){
06762       if(debug)
06763          printf("Bump freq invalid\n");
06764       return -1;
06765    }
06766 
06767    snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d);
06768 
06769    if(debug)
06770       printf("After bump: %s\n", myrpt->freq);
06771 
06772    return set_freq_ft897(myrpt, myrpt->freq);   
06773 }

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

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

07282 {
07283    int m,d;
07284    char mhz[MAXREMSTR], decimals[MAXREMSTR];
07285    unsigned char cmdstr[20];
07286 
07287    if(debug)
07288       printf("Before bump: %s\n", myrpt->freq);
07289 
07290    if(split_freq(mhz, decimals, myrpt->freq))
07291       return -1;
07292    
07293    m = atoi(mhz);
07294    d = atoi(decimals);
07295 
07296    d += (interval / 10); /* 10Hz resolution */
07297    if(d < 0){
07298       m--;
07299       d += 100000;
07300    }
07301    else if(d >= 100000){
07302       m++;
07303       d -= 100000;
07304    }
07305 
07306    if(check_freq_ic706(m, d, NULL)){
07307       if(debug)
07308          printf("Bump freq invalid\n");
07309       return -1;
07310    }
07311 
07312    snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d);
07313 
07314    if(debug)
07315       printf("After bump: %s\n", myrpt->freq);
07316 
07317    /* The ic-706 likes packed BCD frequencies */
07318 
07319    cmdstr[0] = cmdstr[1] = 0xfe;
07320    cmdstr[2] = myrpt->p.civaddr;
07321    cmdstr[3] = 0xe0;
07322    cmdstr[4] = 0;
07323    cmdstr[5] = ((d % 10) << 4);
07324    cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10);
07325    cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000);
07326    cmdstr[8] = (((m % 100)/10) << 4) + (m % 10);
07327    cmdstr[9] = (m / 100);
07328    cmdstr[10] = 0xfd;
07329 
07330    return(serial_remote_io(myrpt,cmdstr,11,NULL,0,0));
07331 }

static int multimode_capable ( struct rpt myrpt  )  [static]

Definition at line 876 of file app_rpt.c.

References rpt::remote.

Referenced by function_remote(), and rpt_tele_thread().

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

static int myatoi ( char *  str  )  [static]

Definition at line 1516 of file app_rpt.c.

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

01517 {
01518 int   ret;
01519 
01520    if (str == NULL) return -1;
01521    /* leave this %i alone, non-base-10 input is useful here */
01522    if (sscanf(str,"%i",&ret) != 1) return -1;
01523    return ret;
01524 }

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

Definition at line 1526 of file app_rpt.c.

Referenced by rpt_do_nodes(), and rpt_tele_thread().

01527 {
01528 char  **x = (char **) a;
01529 char  **y = (char **) b;
01530 int   xoff,yoff;
01531 
01532    if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0;
01533    if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0;
01534    return(strcmp((*x) + xoff,(*y) + yoff));
01535 }

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

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

01407 {
01408 
01409 char *val;
01410 int longestnode,j;
01411 struct stat mystat;
01412 static time_t last = 0;
01413 static struct ast_config *ourcfg = NULL;
01414 struct ast_variable *vp;
01415 
01416    /* try to look it up locally first */
01417    val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf);
01418    if (val) return(val);
01419    ast_mutex_lock(&nodelookuplock);
01420    /* if file does not exist */
01421    if (stat(myrpt->p.extnodefile,&mystat) == -1)
01422    {
01423       if (ourcfg) ast_config_destroy(ourcfg);
01424       ourcfg = NULL;
01425       ast_mutex_unlock(&nodelookuplock);
01426       return(NULL);
01427    }
01428    /* if we need to reload */
01429    if (mystat.st_mtime > last)
01430    {
01431       if (ourcfg) ast_config_destroy(ourcfg);
01432       ourcfg = ast_config_load(myrpt->p.extnodefile);
01433       /* if file not there, just bail */
01434       if (!ourcfg)
01435       {
01436          ast_mutex_unlock(&nodelookuplock);
01437          return(NULL);
01438       }
01439       /* reset "last" time */
01440       last = mystat.st_mtime;
01441 
01442       /* determine longest node length again */    
01443       longestnode = 0;
01444       vp = ast_variable_browse(myrpt->cfg, myrpt->p.nodes);
01445       while(vp){
01446          j = strlen(vp->name);
01447          if (j > longestnode)
01448             longestnode = j;
01449          vp = vp->next;
01450       }
01451 
01452       vp = ast_variable_browse(ourcfg, myrpt->p.extnodes);
01453       while(vp){
01454          j = strlen(vp->name);
01455          if (j > longestnode)
01456             longestnode = j;
01457          vp = vp->next;
01458       }
01459 
01460       myrpt->longestnode = longestnode;
01461    }
01462    val = NULL;
01463    if (ourcfg)
01464       val = (char *) ast_variable_retrieve(ourcfg, myrpt->p.extnodes, digitbuf);
01465    ast_mutex_unlock(&nodelookuplock);
01466    return(val);
01467 }

static int openserial ( char *  fname  )  [static]

Definition at line 1152 of file app_rpt.c.

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

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

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

Definition at line 2454 of file app_rpt.c.

References play_tone_pair().

Referenced by send_morse().

02455 {
02456    return play_tone_pair(chan, 0, 0, duration, 0);
02457 }

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

Definition at line 2449 of file app_rpt.c.

References play_tone_pair().

Referenced by rpt_tele_thread(), and send_morse().

02450 {
02451    return play_tone_pair(chan, freq, 0, duration, amplitude);
02452 }

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

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

02436 {
02437    int res;
02438 
02439         if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude)))
02440                 return res;
02441                                                                                                                                             
02442         while(chan->generatordata) {
02443       if (ast_safe_sleep(chan,1)) return -1;
02444    }
02445 
02446         return 0;
02447 }

static void queue_id ( struct rpt myrpt  )  [static]

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

08622 {
08623    if(myrpt->p.idtime){ /* ID time must be non-zero */
08624       myrpt->mustid = myrpt->tailid = 0;
08625       myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */
08626       rpt_mutex_unlock(&myrpt->lock);
08627       rpt_telemetry(myrpt,ID,NULL);
08628       rpt_mutex_lock(&myrpt->lock);
08629    }
08630 }

static int rbi_mhztoband ( char *  str  )  [static]

Definition at line 5685 of file app_rpt.c.

Referenced by setrbi(), and setrbi_check().

05686 {
05687 int   i;
05688 
05689    i = atoi(str) / 10; /* get the 10's of mhz */
05690    switch(i)
05691    {
05692        case 2:
05693       return 10;
05694        case 5:
05695       return 11;
05696        case 14:
05697       return 2;
05698        case 22:
05699       return 3;
05700        case 44:
05701       return 4;
05702        case 124:
05703       return 0;
05704        case 125:
05705       return 1;
05706        case 126:
05707       return 8;
05708        case 127:
05709       return 5;
05710        case 128:
05711       return 6;
05712        case 129:
05713       return 7;
05714        default:
05715       break;
05716    }
05717    return -1;
05718 }

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

Definition at line 5844 of file app_rpt.c.

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

Referenced by setrbi().

05845 {
05846 struct dahdi_radio_param r;
05847 
05848    memset(&r,0,sizeof(struct dahdi_radio_param));
05849    r.radpar = DAHDI_RADPAR_REMMODE;
05850    r.data = DAHDI_RADPAR_REM_RBI1;
05851    /* if setparam ioctl fails, its probably not a pciradio card */
05852    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&r) == -1)
05853    {
05854       rbi_out_parallel(myrpt,data);
05855       return;
05856    }
05857    r.radpar = DAHDI_RADPAR_REMCOMMAND;
05858    memcpy(&r.data,data,5);
05859    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&r) == -1)
05860    {
05861       ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->zaprxchannel->name);
05862       return;
05863    }
05864 }

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

Definition at line 5816 of file app_rpt.c.

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

Referenced by rbi_out().

05817     {
05818 #ifdef __i386__
05819     int i,j;
05820     unsigned char od,d;
05821     static volatile long long delayvar;
05822 
05823     for(i = 0 ; i < 5 ; i++){
05824         od = *data++; 
05825         for(j = 0 ; j < 8 ; j++){
05826             d = od & 1;
05827             outb(d,myrpt->p.iobase);
05828        /* >= 15 us */
05829        for(delayvar = 1; delayvar < 15000; delayvar++); 
05830             od >>= 1;
05831             outb(d | 2,myrpt->p.iobase);
05832        /* >= 30 us */
05833        for(delayvar = 1; delayvar < 30000; delayvar++); 
05834             outb(d,myrpt->p.iobase);
05835        /* >= 10 us */
05836        for(delayvar = 1; delayvar < 10000; delayvar++); 
05837             }
05838         }
05839    /* >= 50 us */
05840         for(delayvar = 1; delayvar < 50000; delayvar++); 
05841 #endif
05842     }

static int rbi_pltocode ( char *  str  )  [static]

Definition at line 5721 of file app_rpt.c.

References s.

Referenced by setrbi(), and setrbi_check().

05722 {
05723 int i;
05724 char *s;
05725 
05726    s = strchr(str,'.');
05727    i = 0;
05728    if (s) i = atoi(s + 1);
05729    i += atoi(str) * 10;
05730    switch(i)
05731    {
05732        case 670:
05733       return 0;
05734        case 719:
05735       return 1;
05736        case 744:
05737       return 2;
05738        case 770:
05739       return 3;
05740        case 797:
05741       return 4;
05742        case 825:
05743       return 5;
05744        case 854:
05745       return 6;
05746        case 885:
05747       return 7;
05748        case 915:
05749       return 8;
05750        case 948:
05751       return 9;
05752        case 974:
05753       return 10;
05754        case 1000:
05755       return 11;
05756        case 1035:
05757       return 12;
05758        case 1072:
05759       return 13;
05760        case 1109:
05761       return 14;
05762        case 1148:
05763       return 15;
05764        case 1188:
05765       return 16;
05766        case 1230:
05767       return 17;
05768        case 1273:
05769       return 18;
05770        case 1318:
05771       return 19;
05772        case 1365:
05773       return 20;
05774        case 1413:
05775       return 21;
05776        case 1462:
05777       return 22;
05778        case 1514:
05779       return 23;
05780        case 1567:
05781       return 24;
05782        case 1622:
05783       return 25;
05784        case 1679:
05785       return 26;
05786        case 1738:
05787       return 27;
05788        case 1799:
05789       return 28;
05790        case 1862:
05791       return 29;
05792        case 1928:
05793       return 30;
05794        case 2035:
05795       return 31;
05796        case 2107:
05797       return 32;
05798        case 2181:
05799       return 33;
05800        case 2257:
05801       return 34;
05802        case 2336:
05803       return 35;
05804        case 2418:
05805       return 36;
05806        case 2503:
05807       return 37;
05808    }
05809    return -1;
05810 }

static int reload ( void   )  [static]

Definition at line 11906 of file app_rpt.c.

References reload(), and rpt_vars.

11908 {
11909 int   n;
11910 
11911    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
11912    return(0);
11913 }

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

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

07646 {
07647    char tmp[30], *s, *s1, *val;
07648 
07649    val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.memory, memory);
07650    if (!val){
07651       return -1;
07652    }        
07653    strncpy(tmp,val,sizeof(tmp) - 1);
07654    tmp[sizeof(tmp)-1] = 0;
07655 
07656    s = strchr(tmp,',');
07657    if (!s)
07658       return 1; 
07659    *s++ = 0;
07660    s1 = strchr(s,',');
07661    if (!s1)
07662       return 1;
07663    *s1++ = 0;
07664    strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1);
07665    strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1);
07666    strncpy(myrpt->txpl, s, sizeof(myrpt->rxpl) - 1);
07667    myrpt->remmode = REM_MODE_FM;
07668    myrpt->offset = REM_SIMPLEX;
07669    myrpt->powerlevel = REM_MEDPWR;
07670    myrpt->txplon = myrpt->rxplon = 0;
07671    while(*s1){
07672       switch(*s1++){
07673          case 'A':
07674          case 'a':
07675             strcpy(myrpt->rxpl, "100.0");
07676             strcpy(myrpt->txpl, "100.0");
07677             myrpt->remmode = REM_MODE_AM; 
07678             break;
07679          case 'B':
07680          case 'b':
07681             strcpy(myrpt->rxpl, "100.0");
07682             strcpy(myrpt->txpl, "100.0");
07683             myrpt->remmode = REM_MODE_LSB;
07684             break;
07685          case 'F':
07686             myrpt->remmode = REM_MODE_FM;
07687             break;
07688          case 'L':
07689          case 'l':
07690             myrpt->powerlevel = REM_LOWPWR;
07691             break;               
07692          case 'H':
07693          case 'h':
07694             myrpt->powerlevel = REM_HIPWR;
07695             break;
07696                
07697          case 'M':
07698          case 'm':
07699             myrpt->powerlevel = REM_MEDPWR;
07700             break;
07701                   
07702          case '-':
07703             myrpt->offset = REM_MINUS;
07704             break;
07705                   
07706          case '+':
07707             myrpt->offset = REM_PLUS;
07708             break;
07709                   
07710          case 'S':
07711          case 's':
07712             myrpt->offset = REM_SIMPLEX;
07713             break;
07714                   
07715          case 'T':
07716          case 't':
07717             myrpt->txplon = 1;
07718             break;
07719                   
07720          case 'R':
07721          case 'r':
07722             myrpt->rxplon = 1;
07723             break;
07724 
07725          case 'U':
07726          case 'u':
07727             strcpy(myrpt->rxpl, "100.0");
07728             strcpy(myrpt->txpl, "100.0");
07729             myrpt->remmode = REM_MODE_USB;
07730             break;
07731          default:
07732             return 1;
07733       }
07734    }
07735    return 0;
07736 }

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

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

01592 {
01593         char *var;
01594         int ret;
01595    char include_zero = 0;
01596 
01597    if(min < 0){ /* If min is negative, this means include 0 as a valid entry */
01598       min = -min;
01599       include_zero = 1;
01600    }           
01601                                                                      
01602         var = (char *) ast_variable_retrieve(myrpt->cfg, category, name);
01603         if(var){
01604                 ret = myatoi(var);
01605       if(include_zero && !ret)
01606          return 0;
01607                 if(ret < min)
01608                         ret = min;
01609                 if(ret > max)
01610                         ret = max;
01611         }
01612         else
01613                 ret = defl;
01614         return ret;
01615 }

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

Definition at line 8755 of file app_rpt.c.

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

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

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

Definition at line 4158 of file app_rpt.c.

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

Referenced by function_autopatchup(), and local_dtmf_helper().

04159 {
04160 DAHDI_CONFINFO ci;  /* conference info */
04161 struct   rpt *myrpt = (struct rpt *)this;
04162 int   res;
04163 int stopped,congstarted,dialtimer,lastcidx,aborted;
04164 struct ast_channel *mychannel,*genchannel;
04165 
04166 
04167    myrpt->mydtmf = 0;
04168    /* allocate a pseudo-channel thru asterisk */
04169    mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
04170    if (!mychannel)
04171    {
04172       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
04173       pthread_exit(NULL);
04174    }
04175 #ifdef   AST_CDR_FLAG_POST_DISABLED
04176    ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED);
04177 #endif
04178    ci.chan = 0;
04179    ci.confno = myrpt->conf; /* use the pseudo conference */
04180    ci.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER
04181       | DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 
04182    /* first put the channel on the conference */
04183    if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1)
04184    {
04185       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04186       ast_hangup(mychannel);
04187       myrpt->callmode = 0;
04188       pthread_exit(NULL);
04189    }
04190    /* allocate a pseudo-channel thru asterisk */
04191    genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
04192    if (!genchannel)
04193    {
04194       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
04195       ast_hangup(mychannel);
04196       pthread_exit(NULL);
04197    }
04198 #ifdef   AST_CDR_FLAG_POST_DISABLED
04199    ast_set_flag(genchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
04200 #endif
04201    ci.chan = 0;
04202    ci.confno = myrpt->conf;
04203    ci.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER
04204       | DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 
04205    /* first put the channel on the conference */
04206    if (ioctl(genchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
04207    {
04208       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04209       ast_hangup(mychannel);
04210       ast_hangup(genchannel);
04211       myrpt->callmode = 0;
04212       pthread_exit(NULL);
04213    }
04214    if (myrpt->p.tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->p.tonezone) == -1))
04215    {
04216       ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone);
04217       ast_hangup(mychannel);
04218       ast_hangup(genchannel);
04219       myrpt->callmode = 0;
04220       pthread_exit(NULL);
04221    }
04222    if (myrpt->p.tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->p.tonezone) == -1))
04223    {
04224       ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone);
04225       ast_hangup(mychannel);
04226       ast_hangup(genchannel);
04227       myrpt->callmode = 0;
04228       pthread_exit(NULL);
04229    }
04230    /* start dialtone if patchquiet is 0. Special patch modes don't send dial tone */
04231    if ((!myrpt->patchquiet) && (tone_zone_play_tone(mychannel->fds[0],DAHDI_TONE_DIALTONE) < 0))
04232    {
04233       ast_log(LOG_WARNING, "Cannot start dialtone\n");
04234       ast_hangup(mychannel);
04235       ast_hangup(genchannel);
04236       myrpt->callmode = 0;
04237       pthread_exit(NULL);
04238    }
04239    stopped = 0;
04240    congstarted = 0;
04241    dialtimer = 0;
04242    lastcidx = 0;
04243    aborted = 0;
04244 
04245 
04246    while ((myrpt->callmode == 1) || (myrpt->callmode == 4))
04247    {
04248 
04249       if((myrpt->patchdialtime)&&(myrpt->callmode == 1)&&(myrpt->cidx != lastcidx)){
04250          dialtimer = 0;
04251          lastcidx = myrpt->cidx;
04252       }     
04253 
04254       if((myrpt->patchdialtime)&&(dialtimer >= myrpt->patchdialtime)){ 
04255          rpt_mutex_lock(&myrpt->lock);
04256          aborted = 1;
04257          myrpt->callmode = 0;
04258          rpt_mutex_unlock(&myrpt->lock);
04259          break;
04260       }
04261    
04262       if ((!myrpt->patchquiet) && (!stopped) && (myrpt->callmode == 1) && (myrpt->cidx > 0))
04263       {
04264          stopped = 1;
04265          /* stop dial tone */
04266          tone_zone_play_tone(mychannel->fds[0],-1);
04267       }
04268       if (myrpt->callmode == 4)
04269       {
04270          if(!congstarted){
04271             congstarted = 1;
04272             /* start congestion tone */
04273             tone_zone_play_tone(mychannel->fds[0],DAHDI_TONE_CONGESTION);
04274          }
04275       }
04276       res = ast_safe_sleep(mychannel, MSWAIT);
04277       if (res < 0)
04278       {
04279          ast_hangup(mychannel);
04280          ast_hangup(genchannel);
04281          rpt_mutex_lock(&myrpt->lock);
04282          myrpt->callmode = 0;
04283          rpt_mutex_unlock(&myrpt->lock);
04284          pthread_exit(NULL);
04285       }
04286       dialtimer += MSWAIT;
04287    }
04288    /* stop any tone generation */
04289    tone_zone_play_tone(mychannel->fds[0],-1);
04290    /* end if done */
04291    if (!myrpt->callmode)
04292    {
04293       ast_hangup(mychannel);
04294       ast_hangup(genchannel);
04295       rpt_mutex_lock(&myrpt->lock);
04296       myrpt->callmode = 0;
04297       rpt_mutex_unlock(&myrpt->lock);
04298       if((!myrpt->patchquiet) && aborted)
04299          rpt_telemetry(myrpt, TERM, NULL);
04300       pthread_exit(NULL);        
04301    }
04302 
04303    if (myrpt->p.ourcallerid && *myrpt->p.ourcallerid){
04304       char *name, *loc, *instr;
04305       instr = strdup(myrpt->p.ourcallerid);
04306       if(instr){
04307          ast_callerid_parse(instr, &name, &loc);
04308          if(loc){
04309             if(mychannel->cid.cid_num)
04310                free(mychannel->cid.cid_num);
04311             mychannel->cid.cid_num = strdup(loc);
04312          }
04313          if(name){
04314             if(mychannel->cid.cid_name)
04315                free(mychannel->cid.cid_name);
04316             mychannel->cid.cid_name = strdup(name);
04317          }
04318          free(instr);
04319       }
04320    }
04321 
04322    ast_copy_string(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1);
04323    ast_copy_string(mychannel->context, myrpt->patchcontext, sizeof(mychannel->context) - 1);
04324    
04325    if (myrpt->p.acctcode)
04326       ast_cdr_setaccount(mychannel,myrpt->p.acctcode);
04327    mychannel->priority = 1;
04328    ast_channel_undefer_dtmf(mychannel);
04329    if (ast_pbx_start(mychannel) < 0)
04330    {
04331       ast_log(LOG_WARNING, "Unable to start PBX!!\n");
04332       ast_hangup(mychannel);
04333       ast_hangup(genchannel);
04334       rpt_mutex_lock(&myrpt->lock);
04335       myrpt->callmode = 0;
04336       rpt_mutex_unlock(&myrpt->lock);
04337       pthread_exit(NULL);
04338    }
04339    usleep(10000);
04340    rpt_mutex_lock(&myrpt->lock);
04341    myrpt->callmode = 3;
04342    /* set appropriate conference for the pseudo */
04343    ci.chan = 0;
04344    ci.confno = myrpt->conf;
04345    ci.confmode = (myrpt->p.duplex == 2) ? DAHDI_CONF_CONFANNMON :
04346       (DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER);
04347    /* first put the channel on the conference in announce mode */
04348    if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
04349    {
04350       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04351       ast_hangup(mychannel);
04352       ast_hangup(genchannel);
04353       myrpt->callmode = 0;
04354       pthread_exit(NULL);
04355    }
04356    while(myrpt->callmode)
04357    {
04358       if ((!mychannel->pbx) && (myrpt->callmode != 4))
04359       {
04360          if(myrpt->patchfarenddisconnect){ /* If patch is setup for far end disconnect */
04361             myrpt->callmode = 0;
04362             if(!myrpt->patchquiet){
04363                rpt_mutex_unlock(&myrpt->lock);
04364                rpt_telemetry(myrpt, TERM, NULL);
04365                rpt_mutex_lock(&myrpt->lock);
04366             }
04367          }
04368          else{ /* Send congestion until patch is downed by command */
04369             myrpt->callmode = 4;
04370             rpt_mutex_unlock(&myrpt->lock);
04371             /* start congestion tone */
04372             tone_zone_play_tone(genchannel->fds[0],DAHDI_TONE_CONGESTION);
04373             rpt_mutex_lock(&myrpt->lock);
04374          }
04375       }
04376       if (myrpt->mydtmf)
04377       {
04378          struct ast_frame wf = {AST_FRAME_DTMF, } ;
04379          wf.subclass = myrpt->mydtmf;
04380          rpt_mutex_unlock(&myrpt->lock);
04381          ast_queue_frame(mychannel,&wf);
04382          ast_senddigit(genchannel,myrpt->mydtmf);
04383          rpt_mutex_lock(&myrpt->lock);
04384          myrpt->mydtmf = 0;
04385       }
04386       rpt_mutex_unlock(&myrpt->lock);
04387       usleep(MSWAIT * 1000);
04388       rpt_mutex_lock(&myrpt->lock);
04389    }
04390    rpt_mutex_unlock(&myrpt->lock);
04391    tone_zone_play_tone(genchannel->fds[0],-1);
04392    if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV);
04393    ast_hangup(genchannel);
04394    rpt_mutex_lock(&myrpt->lock);
04395    myrpt->callmode = 0;
04396    rpt_mutex_unlock(&myrpt->lock);
04397    /* set appropriate conference for the pseudo */
04398    ci.chan = 0;
04399    ci.confno = myrpt->conf;
04400    ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? DAHDI_CONF_CONFANNMON :
04401       (DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER);
04402    /* first put the channel on the conference in announce mode */
04403    if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
04404    {
04405       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04406    }
04407    pthread_exit(NULL);
04408 }

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

Definition at line 1964 of file app_rpt.c.

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

01965 {
01966    int newlevel;
01967 
01968         if (argc != 4)
01969                 return RESULT_SHOWUSAGE;
01970         newlevel = myatoi(argv[3]);
01971         if((newlevel < 0) || (newlevel > 7))
01972                 return RESULT_SHOWUSAGE;
01973         if(newlevel)
01974                 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
01975         else
01976                 ast_cli(fd, "app_rpt Debugging disabled\n");
01977 
01978         debug = newlevel;                                                                                                                          
01979         return RESULT_SUCCESS;
01980 }

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

Definition at line 1986 of file app_rpt.c.

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

01987 {
01988    int i;
01989 
01990         if (argc != 3)
01991                 return RESULT_SHOWUSAGE;
01992 
01993    for(i = 0; i < nrpts; i++)
01994    {
01995       if (!strcmp(argv[2],rpt_vars[i].name))
01996       {
01997          rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
01998               ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]);
01999               return RESULT_SUCCESS;
02000       }
02001    }
02002    return RESULT_FAILURE;
02003 }

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

Definition at line 2406 of file app_rpt.c.

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

02407 {
02408    int   i,busy=0;
02409 
02410         if (argc != 4) return RESULT_SHOWUSAGE;
02411 
02412    for(i = 0; i < nrpts; i++){
02413       if(!strcmp(argv[2], rpt_vars[i].name)){
02414          struct rpt *myrpt = &rpt_vars[i];
02415          rpt_mutex_lock(&myrpt->lock);
02416          if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(argv[3])){
02417             rpt_mutex_unlock(&myrpt->lock);
02418             busy=1;
02419          }
02420          if(!busy){
02421             myrpt->macrotimer = MACROTIME;
02422             strncat(myrpt->macrobuf, argv[3], MAXMACRO - strlen(myrpt->macrobuf) - 1);
02423          }
02424          rpt_mutex_unlock(&myrpt->lock);
02425       }
02426    }
02427    if(busy){
02428       ast_cli(fd, "Function decoder busy");
02429    }
02430    return RESULT_FAILURE;
02431 }

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

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

02235 {
02236    int i,j;
02237    char *connstate;
02238    struct rpt *myrpt;
02239    struct rpt_link *l;
02240    struct rpt_lstat *s,*t;
02241    struct rpt_lstat s_head;
02242    if(argc != 3)
02243       return RESULT_SHOWUSAGE;
02244 
02245    s = NULL;
02246    s_head.next = &s_head;
02247    s_head.prev = &s_head;
02248 
02249    for(i = 0; i < nrpts; i++)
02250    {
02251       if (!strcmp(argv[2],rpt_vars[i].name)){
02252          /* Make a copy of all stat variables while locked */
02253          myrpt = &rpt_vars[i];
02254          rpt_mutex_lock(&myrpt->lock); /* LOCK */
02255          /* Traverse the list of connected nodes */
02256          j = 0;
02257          l = myrpt->links.next;
02258          while(l && (l != &myrpt->links)){
02259             if (l->name[0] == '0'){ /* Skip '0' nodes */
02260                l = l->next;
02261                continue;
02262             }
02263             if((s = (struct rpt_lstat *) malloc(sizeof(struct rpt_lstat))) == NULL){
02264                ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n");
02265                rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02266                return RESULT_FAILURE;
02267             }
02268             memset(s, 0, sizeof(struct rpt_lstat));
02269             strncpy(s->name, l->name, MAXREMSTR - 1);
02270             if (l->chan) pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1);
02271             else strcpy(s->peer,"(none)");
02272             s->mode = l->mode;
02273             s->outbound = l->outbound;
02274             s->reconnects = l->reconnects;
02275             s->connecttime = l->connecttime;
02276             s->thisconnected = l->thisconnected;
02277             memcpy(s->chan_stat,l->chan_stat,NRPTSTAT * sizeof(struct rpt_chan_stat));
02278             insque((struct qelem *) s, (struct qelem *) s_head.next);
02279             memset(l->chan_stat,0,NRPTSTAT * sizeof(struct rpt_chan_stat));
02280             l = l->next;
02281          }
02282          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02283          ast_cli(fd, "NODE      PEER                RECONNECTS  DIRECTION  CONNECT TIME        CONNECT STATE\n");
02284          ast_cli(fd, "----      ----                ----------  ---------  ------------        -------------\n");
02285 
02286          for(s = s_head.next; s != &s_head; s = s->next){
02287             int hours, minutes, seconds;
02288             long long connecttime = s->connecttime;
02289             char conntime[21];
02290             hours = (int) connecttime/3600000;
02291             connecttime %= 3600000;
02292             minutes = (int) connecttime/60000;
02293             connecttime %= 60000;
02294             seconds = (int)  connecttime/1000;
02295             connecttime %= 1000;
02296             snprintf(conntime, 20, "%02d:%02d:%02d.%d",
02297                hours, minutes, seconds, (int) connecttime);
02298             conntime[20] = 0;
02299             if(s->thisconnected)
02300                connstate  = "ESTABLISHED";
02301             else
02302                connstate = "CONNECTING";
02303             ast_cli(fd, "%-10s%-20s%-12d%-11s%-20s%-20s\n",
02304                s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime, connstate);
02305          }  
02306          /* destroy our local link queue */
02307          s = s_head.next;
02308          while(s != &s_head){
02309             t = s;
02310             s = s->next;
02311             remque((struct qelem *)t);
02312             free(t);
02313          }        
02314          return RESULT_SUCCESS;
02315       }
02316    }
02317    return RESULT_FAILURE;
02318 }

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

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

02325 {
02326    int i,j;
02327    char ns;
02328    char lbuf[MAXLINKLIST],*strs[MAXLINKLIST];
02329    struct rpt *myrpt;
02330    if(argc != 3)
02331       return RESULT_SHOWUSAGE;
02332 
02333    for(i = 0; i < nrpts; i++)
02334    {
02335       if (!strcmp(argv[2],rpt_vars[i].name)){
02336          /* Make a copy of all stat variables while locked */
02337          myrpt = &rpt_vars[i];
02338          rpt_mutex_lock(&myrpt->lock); /* LOCK */
02339          __mklinklist(myrpt,NULL,lbuf);
02340          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02341          /* parse em */
02342          ns = finddelim(lbuf,strs,MAXLINKLIST);
02343          /* sort em */
02344          if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar);
02345          ast_cli(fd,"\n");
02346          ast_cli(fd, "************************* CONNECTED NODES *************************\n\n");
02347          for(j = 0 ;; j++){
02348             if(!strs[j]){
02349                if(!j){
02350                   ast_cli(fd,"<NONE>");
02351                }
02352                break;
02353             }
02354             ast_cli(fd, "%s", strs[j]);
02355             if(j % 8 == 7){
02356                ast_cli(fd, "\n");
02357             }
02358             else{
02359                if(strs[j + 1])
02360                   ast_cli(fd, ", ");
02361             }
02362          }
02363          ast_cli(fd,"\n\n");
02364          return RESULT_SUCCESS;
02365       }
02366    }
02367    return RESULT_FAILURE;
02368 }

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

Definition at line 2374 of file app_rpt.c.

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

02375 {
02376 int   n;
02377 
02378         if (argc > 2) return RESULT_SHOWUSAGE;
02379 
02380    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
02381 
02382    return RESULT_FAILURE;
02383 }

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

Definition at line 2389 of file app_rpt.c.

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

02390 {
02391 int   i;
02392 
02393         if (argc > 2) return RESULT_SHOWUSAGE;
02394    for(i = 0; i < nrpts; i++)
02395    {
02396       if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV);
02397    }
02398    return RESULT_FAILURE;
02399 }

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

Definition at line 2009 of file app_rpt.c.

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

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

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

Definition at line 10552 of file app_rpt.c.

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

Referenced by load_module().

10553 {
10554    int res=-1,i,rem_totx,rem_rx,remkeyed,n,phone_mode = 0;
10555    int iskenwood_pci4,authtold,authreq,setting,notremming,reming;
10556    int ismuted,dtmfed;
10557 #ifdef   OLD_ASTERISK
10558    struct localuser *u;
10559 #endif
10560    char tmp[256], keyed = 0,keyed1 = 0;
10561    char *options,*stringp,*tele,c;
10562    struct   rpt *myrpt;
10563    struct ast_frame *f,*f1,*f2;
10564    struct ast_channel *who;
10565    struct ast_channel *cs[20];
10566    struct   rpt_link *l;
10567    DAHDI_CONFINFO ci;  /* conference info */
10568    DAHDI_PARAMS par;
10569    int ms,elap,nullfd;
10570    time_t t,last_timeout_warning;
10571    struct   dahdi_radio_param z;
10572    struct rpt_tele *telem;
10573 
10574    nullfd = open("/dev/null",O_RDWR);
10575    if (ast_strlen_zero(data)) {
10576       ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n");
10577       return -1;
10578    }
10579 
10580    strncpy(tmp, (char *)data, sizeof(tmp)-1);
10581    time(&t);
10582    /* if time has externally shifted negative, screw it */
10583    if (t < starttime) t = starttime + START_DELAY;
10584    if ((!starttime) || (t < (starttime + START_DELAY)))
10585    {
10586       ast_log(LOG_NOTICE,"Node %s rejecting call: too soon!\n",tmp);
10587       ast_safe_sleep(chan,3000);
10588       return -1;
10589    }
10590    stringp=tmp;
10591    strsep(&stringp, "|");
10592    options = stringp;
10593    myrpt = NULL;
10594    /* see if we can find our specified one */
10595    for(i = 0; i < nrpts; i++)
10596    {
10597       /* if name matches, assign it and exit loop */
10598       if (!strcmp(tmp,rpt_vars[i].name))
10599       {
10600          myrpt = &rpt_vars[i];
10601          break;
10602       }
10603    }
10604    if (myrpt == NULL)
10605    {
10606       ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp);
10607       return -1;
10608    }
10609    
10610    if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable){ /* Do not allow incoming connections if disabled */
10611       ast_log(LOG_NOTICE, "Connect attempt to node %s  with tx disabled", myrpt->name);
10612       return -1;
10613    }
10614 
10615    /* if not phone access, must be an IAX connection */
10616    if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R')))
10617    {
10618       int val;
10619 
10620       phone_mode = 1;
10621       if (*options == 'D') phone_mode = 2;
10622       ast_set_callerid(chan,"0","app_rpt user","0");
10623       val = 1;
10624       ast_channel_setoption(chan,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
10625    }
10626    else
10627    {
10628 #ifdef ALLOW_LOCAL_CHANNELS
10629            /* Check to insure the connection is IAX2 or Local*/
10630            if ( (strncmp(chan->name,"IAX2",4)) && (strncmp(chan->name,"Local",5)) ) {
10631                ast_log(LOG_WARNING, "We only accept links via IAX2 or Local!!\n");
10632                return -1;
10633            }
10634 #else
10635       if (strncmp(chan->name,"IAX2",4))
10636       {
10637          ast_log(LOG_WARNING, "We only accept links via IAX2!!\n");
10638          return -1;
10639       }
10640 #endif
10641    }
10642    if (options && (*options == 'R'))
10643    {
10644 
10645       /* Parts of this section taken from app_parkandannounce */
10646       char *return_context;
10647       int l, m, lot, timeout = 0;
10648       char tmp[256],*template;
10649       char *working, *context, *exten, *priority;
10650       char *s,*orig_s;
10651 
10652 
10653       rpt_mutex_lock(&myrpt->lock);
10654       m = myrpt->callmode;
10655       rpt_mutex_unlock(&myrpt->lock);
10656 
10657       if ((!myrpt->p.nobusyout) && m)
10658       {
10659          if (chan->_state != AST_STATE_UP)
10660          {
10661             ast_indicate(chan,AST_CONTROL_BUSY);
10662          }
10663          while(ast_safe_sleep(chan,10000) != -1);
10664          return -1;
10665       }
10666 
10667       if (chan->_state != AST_STATE_UP)
10668       {
10669          ast_answer(chan);
10670       }
10671 
10672       l=strlen(options)+2;
10673       orig_s=malloc(l);
10674       if(!orig_s) {
10675          ast_log(LOG_WARNING, "Out of memory\n");
10676          return -1;
10677       }
10678       s=orig_s;
10679       strncpy(s,options,l);
10680 
10681       template=strsep(&s,"|");
10682       if(!template) {
10683          ast_log(LOG_WARNING, "An announce template must be defined\n");
10684          free(orig_s);
10685          return -1;
10686       } 
10687   
10688       if(s) {
10689          timeout = atoi(strsep(&s, "|"));
10690          timeout *= 1000;
10691       }
10692    
10693       return_context = s;
10694   
10695       if(return_context != NULL) {
10696          /* set the return context. Code borrowed from the Goto builtin */
10697     
10698          working = return_context;
10699          context = strsep(&working, "|");
10700          exten = strsep(&working, "|");
10701          if(!exten) {
10702             /* Only a priority in this one */
10703             priority = context;
10704             exten = NULL;
10705             context = NULL;
10706          } else {
10707             priority = strsep(&working, "|");
10708             if(!priority) {
10709                /* Only an extension and priority in this one */
10710                priority = exten;
10711                exten = context;
10712                context = NULL;
10713          }
10714       }
10715       if(atoi(priority) < 0) {
10716          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
10717          free(orig_s);
10718          return -1;
10719       }
10720       /* At this point we have a priority and maybe an extension and a context */
10721       chan->priority = atoi(priority);
10722 #ifdef OLD_ASTERISK
10723       if(exten && strcasecmp(exten, "BYEXTENSION"))
10724 #else
10725       if(exten)
10726 #endif
10727          strncpy(chan->exten, exten, sizeof(chan->exten)-1);
10728       if(context)
10729          strncpy(chan->context, context, sizeof(chan->context)-1);
10730       } else {  /* increment the priority by default*/
10731          chan->priority++;
10732       }
10733 
10734       if(option_verbose > 2) {
10735          ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num);
10736          if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
10737             ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
10738          }
10739       }
10740   
10741       /* we are using masq_park here to protect * from touching the channel once we park it.  If the channel comes out of timeout
10742       before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
10743 
10744       ast_masq_park_call(chan, NULL, timeout, &lot);
10745 
10746       if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
10747 
10748       snprintf(tmp,sizeof(tmp) - 1,"%d,%s",lot,template + 1);
10749 
10750       rpt_telemetry(myrpt,REV_PATCH,tmp);
10751 
10752       free(orig_s);
10753 
10754       return 0;
10755 
10756    }
10757 
10758    if (!options)
10759    {
10760                 struct ast_hostent ahp;
10761                 struct hostent *hp;
10762       struct in_addr ia;
10763       char hisip[100],nodeip[100],*val, *s, *s1, *s2, *b,*b1;
10764 
10765       /* look at callerid to see what node this comes from */
10766       if (!chan->cid.cid_num) /* if doesn't have caller id */
10767       {
10768          ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
10769          return -1;
10770       }
10771 
10772       /* get his IP from IAX2 module */
10773       memset(hisip,0,sizeof(hisip));
10774 #ifdef ALLOW_LOCAL_CHANNELS
10775            /* set IP address if this is a local connection*/
10776            if (strncmp(chan->name,"Local",5)==0) {
10777                strcpy(hisip,"127.0.0.1");
10778            } else {
10779          pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
10780       }
10781 #else
10782       pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
10783 #endif
10784 
10785       if (!hisip[0])
10786       {
10787          ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n");
10788          return -1;
10789       }
10790       
10791       ast_callerid_parse(chan->cid.cid_num,&b,&b1);
10792       ast_shrink_phone_number(b1);
10793       if (!strcmp(myrpt->name,b1))
10794       {
10795          ast_log(LOG_WARNING, "Trying to link to self!!\n");
10796          return -1;
10797       }
10798 
10799       if (*b1 < '1')
10800       {
10801          ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1);
10802          return -1;
10803       }
10804 
10805 
10806       /* look for his reported node string */
10807       val = node_lookup(myrpt,b1);
10808       if (!val)
10809       {
10810          ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1);
10811          return -1;
10812       }
10813       strncpy(tmp,val,sizeof(tmp) - 1);
10814       s = tmp;
10815       s1 = strsep(&s,",");
10816       s2 = strsep(&s,",");
10817       if (!s2)
10818       {
10819          ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1);
10820          return -1;
10821       }
10822                 if (strcmp(s2,"NONE")) {
10823          hp = ast_gethostbyname(s2, &ahp);
10824          if (!hp)
10825          {
10826             ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2);
10827             return -1;
10828          }
10829          memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
10830 #ifdef   OLD_ASTERISK
10831          ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia);
10832 #else
10833          strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1);
10834 #endif
10835          if (strcmp(hisip,nodeip))
10836          {
10837             char *s3 = strchr(s1,'@');
10838             if (s3) s1 = s3 + 1;
10839             s3 = strchr(s1,'/');
10840             if (s3) *s3 = 0;
10841             hp = ast_gethostbyname(s1, &ahp);
10842             if (!hp)
10843             {
10844                ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1);
10845                return -1;
10846             }
10847             memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
10848 #ifdef   OLD_ASTERISK
10849             ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia);
10850 #else
10851             strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1);
10852 #endif
10853             if (strcmp(hisip,nodeip))
10854             {
10855                ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip);
10856                return -1;
10857             }
10858          }
10859       }
10860    }
10861 
10862    /* if is not a remote */
10863    if (!myrpt->remote)
10864    {
10865 
10866       char *b,*b1;
10867       int reconnects = 0;
10868 
10869       /* look at callerid to see what node this comes from */
10870       if (!chan->cid.cid_num) /* if doesn't have caller id */
10871       {
10872          ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
10873          return -1;
10874       }
10875 
10876       ast_callerid_parse(chan->cid.cid_num,&b,&b1);
10877       ast_shrink_phone_number(b1);
10878       if (!strcmp(myrpt->name,b1))
10879       {
10880          ast_log(LOG_WARNING, "Trying to link to self!!\n");
10881          return -1;
10882       }
10883       rpt_mutex_lock(&myrpt->lock);
10884       l = myrpt->links.next;
10885       /* try to find this one in queue */
10886       while(l != &myrpt->links)
10887       {
10888          if (l->name[0] == '0') 
10889          {
10890             l = l->next;
10891             continue;
10892          }
10893          /* if found matching string */
10894          if (!strcmp(l->name,b1)) break;
10895          l = l->next;
10896       }
10897       /* if found */
10898       if (l != &myrpt->links) 
10899       {
10900          l->killme = 1;
10901          l->retries = l->max_retries + 1;
10902          l->disced = 2;
10903          reconnects = l->reconnects;
10904          reconnects++;
10905                         rpt_mutex_unlock(&myrpt->lock);
10906          usleep(500000);   
10907       } else 
10908          rpt_mutex_unlock(&myrpt->lock);
10909       /* establish call in tranceive mode */
10910       l = malloc(sizeof(struct rpt_link));
10911       if (!l)
10912       {
10913          ast_log(LOG_WARNING, "Unable to malloc\n");
10914          pthread_exit(NULL);
10915       }
10916       /* zero the silly thing */
10917       memset((char *)l,0,sizeof(struct rpt_link));
10918       l->mode = 1;
10919       strncpy(l->name,b1,MAXNODESTR - 1);
10920       l->isremote = 0;
10921       l->chan = chan;
10922       l->connected = 1;
10923       l->thisconnected = 1;
10924       l->hasconnected = 1;
10925       l->reconnects = reconnects;
10926       l->phonemode = phone_mode;
10927       l->lastf1 = NULL;
10928       l->lastf2 = NULL;
10929       l->dtmfed = 0;
10930       ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
10931       ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
10932       /* allocate a pseudo-channel thru asterisk */
10933       l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
10934       if (!l->pchan)
10935       {
10936          fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
10937          pthread_exit(NULL);
10938       }
10939       ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
10940       ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
10941 #ifdef   AST_CDR_FLAG_POST_DISABLED
10942       ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
10943 #endif
10944       /* make a conference for the tx */
10945       ci.chan = 0;
10946       ci.confno = myrpt->conf;
10947       ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER;
10948       /* first put the channel on the conference in proper mode */
10949       if (ioctl(l->pchan->fds[0],DAHDI_SETCONF,&ci) == -1)
10950       {
10951          ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
10952          pthread_exit(NULL);
10953       }
10954       rpt_mutex_lock(&myrpt->lock);
10955       if (phone_mode > 1) l->lastrx = 1;
10956       l->max_retries = MAX_RETRIES;
10957       /* insert at end of queue */
10958       insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
10959       __kickshort(myrpt);
10960       rpt_mutex_unlock(&myrpt->lock);
10961       if (chan->_state != AST_STATE_UP) {
10962          ast_answer(chan);
10963       }
10964       if (myrpt->p.archivedir)
10965       {
10966          char str[100];
10967 
10968          if (l->phonemode)
10969             sprintf(str,"LINK(P),%s",l->name);
10970          else
10971             sprintf(str,"LINK,%s",l->name);
10972          donodelog(myrpt,str);
10973       }
10974       return AST_PBX_KEEPALIVE;
10975    }
10976    /* well, then it is a remote */
10977    rpt_mutex_lock(&myrpt->lock);
10978    /* if remote, error if anyone else already linked */
10979    if (myrpt->remoteon)
10980    {
10981       rpt_mutex_unlock(&myrpt->lock);
10982       usleep(500000);
10983       if (myrpt->remoteon)
10984       {
10985          ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp);
10986          return -1;
10987       }     
10988       rpt_mutex_lock(&myrpt->lock);
10989    }
10990    if ((!strcmp(myrpt->remote, remote_rig_rbi)) &&
10991      (ioperm(myrpt->p.iobase,1,1) == -1))
10992    {
10993       rpt_mutex_unlock(&myrpt->lock);
10994       ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase);
10995       return -1;
10996    }
10997    myrpt->remoteon = 1;
10998 #ifdef   OLD_ASTERISK
10999    LOCAL_USER_ADD(u);
11000 #endif
11001    rpt_mutex_unlock(&myrpt->lock);
11002    /* find our index, and load the vars initially */
11003    for(i = 0; i < nrpts; i++)
11004    {
11005       if (&rpt_vars[i] == myrpt)
11006       {
11007          load_rpt_vars(i,0);
11008          break;
11009       }
11010    }
11011    rpt_mutex_lock(&myrpt->lock);
11012    tele = strchr(myrpt->rxchanname,'/');
11013    if (!tele)
11014    {
11015       fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
11016       rpt_mutex_unlock(&myrpt->lock);
11017       pthread_exit(NULL);
11018    }
11019    *tele++ = 0;
11020    myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL);
11021    myrpt->zaprxchannel = NULL;
11022    if (!strcasecmp(myrpt->rxchanname,"Zap"))
11023       myrpt->zaprxchannel = myrpt->rxchannel;
11024    if (myrpt->rxchannel)
11025    {
11026       ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
11027       ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
11028 #ifdef   AST_CDR_FLAG_POST_DISABLED
11029       ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
11030 #endif
11031       myrpt->rxchannel->whentohangup = 0;
11032       myrpt->rxchannel->appl = "Apprpt";
11033       myrpt->rxchannel->data = "(Link Rx)";
11034       if (option_verbose > 2)
11035          ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
11036             myrpt->rxchanname,tele,myrpt->rxchannel->name);
11037       rpt_mutex_unlock(&myrpt->lock);
11038       ast_call(myrpt->rxchannel,tele,999);
11039       rpt_mutex_lock(&myrpt->lock);
11040    }
11041    else
11042    {
11043       fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
11044       rpt_mutex_unlock(&myrpt->lock);
11045       pthread_exit(NULL);
11046    }
11047    *--tele = '/';
11048    myrpt->zaptxchannel = NULL;
11049    if (myrpt->txchanname)
11050    {
11051       tele = strchr(myrpt->txchanname,'/');
11052       if (!tele)
11053       {
11054          fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
11055          rpt_mutex_unlock(&myrpt->lock);
11056          ast_hangup(myrpt->rxchannel);
11057          pthread_exit(NULL);
11058       }
11059       *tele++ = 0;
11060       myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL);
11061       if (!strcasecmp(myrpt->txchanname,"Zap"))
11062          myrpt->zaptxchannel = myrpt->txchannel;
11063       if (myrpt->txchannel)
11064       {
11065          ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
11066          ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
11067 #ifdef   AST_CDR_FLAG_POST_DISABLED
11068          ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
11069 #endif
11070          myrpt->txchannel->whentohangup = 0;
11071          myrpt->txchannel->appl = "Apprpt";
11072          myrpt->txchannel->data = "(Link Tx)";
11073          if (option_verbose > 2)
11074             ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
11075                myrpt->txchanname,tele,myrpt->txchannel->name);
11076          rpt_mutex_unlock(&myrpt->lock);
11077          ast_call(myrpt->txchannel,tele,999);
11078          rpt_mutex_lock(&myrpt->lock);
11079       }
11080       else
11081       {
11082          fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
11083          rpt_mutex_unlock(&myrpt->lock);
11084          ast_hangup(myrpt->rxchannel);
11085          pthread_exit(NULL);
11086       }
11087       *--tele = '/';
11088    }
11089    else
11090    {
11091       myrpt->txchannel = myrpt->rxchannel;
11092    }
11093    /* allocate a pseudo-channel thru asterisk */
11094    myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL);
11095    if (!myrpt->pchannel)
11096    {
11097       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
11098       rpt_mutex_unlock(&myrpt->lock);
11099       if (myrpt->txchannel != myrpt->rxchannel) 
11100          ast_hangup(myrpt->txchannel);
11101       ast_hangup(myrpt->rxchannel);
11102       pthread_exit(NULL);
11103    }
11104    ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
11105    ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
11106 #ifdef   AST_CDR_FLAG_POST_DISABLED
11107    ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
11108 #endif
11109    if (!myrpt->zaprxchannel) myrpt->zaprxchannel = myrpt->pchannel;
11110    if (!myrpt->zaptxchannel) myrpt->zaptxchannel = myrpt->pchannel;
11111    /* make a conference for the pseudo */
11112    ci.chan = 0;
11113    ci.confno = -1; /* make a new conf */
11114    ci.confmode = DAHDI_CONF_CONFANNMON ;
11115    /* first put the channel on the conference in announce/monitor mode */
11116    if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
11117    {
11118       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
11119       rpt_mutex_unlock(&myrpt->lock);
11120       ast_hangup(myrpt->pchannel);
11121       if (myrpt->txchannel != myrpt->rxchannel) 
11122          ast_hangup(myrpt->txchannel);
11123       ast_hangup(myrpt->rxchannel);
11124       pthread_exit(NULL);
11125    }
11126    /* save pseudo channel conference number */
11127    myrpt->conf = myrpt->txconf = ci.confno;
11128    /* if serial io port, open it */
11129    myrpt->iofd = -1;
11130    if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt->p.ioport)) == -1))
11131    {
11132       rpt_mutex_unlock(&myrpt->lock);
11133       ast_hangup(myrpt->pchannel);
11134       if (myrpt->txchannel != myrpt->rxchannel) 
11135          ast_hangup(myrpt->txchannel);
11136       ast_hangup(myrpt->rxchannel);
11137       pthread_exit(NULL);
11138    }
11139    iskenwood_pci4 = 0;
11140    memset(&z,0,sizeof(z));
11141    if ((myrpt->iofd < 1) && (myrpt->txchannel == myrpt->zaptxchannel))
11142    {
11143       z.radpar = DAHDI_RADPAR_REMMODE;
11144       z.data = DAHDI_RADPAR_REM_NONE;
11145       res = ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z);
11146       /* if PCIRADIO and kenwood selected */
11147       if ((!res) && (!strcmp(myrpt->remote,remote_rig_kenwood)))
11148       {
11149          z.radpar = DAHDI_RADPAR_UIOMODE;
11150          z.data = 1;
11151          if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
11152          {
11153             ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
11154             return -1;
11155          }
11156          z.radpar = DAHDI_RADPAR_UIODATA;
11157          z.data = 3;
11158          if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
11159          {
11160             ast_log(LOG_ERROR,"Cannot set UIODATA\n");
11161             return -1;
11162          }
11163          i = DAHDI_OFFHOOK;
11164          if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_HOOK,&i) == -1)
11165          {
11166             ast_log(LOG_ERROR,"Cannot set hook\n");
11167             return -1;
11168          }
11169          iskenwood_pci4 = 1;
11170       }
11171    }
11172    if (myrpt->txchannel == myrpt->zaptxchannel)
11173    {
11174       i = DAHDI_ONHOOK;
11175       ioctl(myrpt->zaptxchannel->fds[0],DAHDI_HOOK,&i);
11176       /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */
11177       if ((myrpt->iofd < 1) && (!res) &&
11178          (!strcmp(myrpt->remote,remote_rig_ft897) ||
11179             (!strcmp(myrpt->remote,remote_rig_ic706))))
11180       {
11181          z.radpar = DAHDI_RADPAR_UIOMODE;
11182          z.data = 1;
11183          if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
11184          {
11185             ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
11186             return -1;
11187          }
11188          z.radpar = DAHDI_RADPAR_UIODATA;
11189          z.data = 3;
11190          if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
11191          {
11192             ast_log(LOG_ERROR,"Cannot set UIODATA\n");
11193             return -1;
11194          }
11195       }
11196    }
11197    myrpt->remoterx = 0;
11198    myrpt->remotetx = 0;
11199    myrpt->retxtimer = 0;
11200    myrpt->rerxtimer = 0;
11201    myrpt->remoteon = 1;
11202    myrpt->dtmfidx = -1;
11203    myrpt->dtmfbuf[0] = 0;
11204    myrpt->dtmf_time_rem = 0;
11205    myrpt->hfscanmode = 0;
11206    myrpt->hfscanstatus = 0;
11207    if (myrpt->p.startupmacro)
11208    {
11209       snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro);
11210    }
11211    time(&myrpt->start_time);
11212    myrpt->last_activity_time = myrpt->start_time;
11213    last_timeout_warning = 0;
11214    myrpt->reload = 0;
11215    myrpt->tele.next = &myrpt->tele;
11216    myrpt->tele.prev = &myrpt->tele;
11217    rpt_mutex_unlock(&myrpt->lock);
11218    ast_set_write_format(chan, AST_FORMAT_SLINEAR);
11219    ast_set_read_format(chan, AST_FORMAT_SLINEAR);
11220    rem_rx = 0;
11221    remkeyed = 0;
11222    /* if we are on 2w loop and are a remote, turn EC on */
11223    if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel))
11224    {
11225       i = 128;
11226       ioctl(myrpt->zaprxchannel->fds[0],DAHDI_ECHOCANCEL,&i);
11227    }
11228    if (chan->_state != AST_STATE_UP) {
11229       ast_answer(chan);
11230    }
11231 
11232    if (myrpt->rxchannel == myrpt->zaprxchannel)
11233    {
11234       if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_GET_PARAMS,&par) != -1)
11235       {
11236          if (par.rxisoffhook)
11237          {
11238             ast_indicate(chan,AST_CONTROL_RADIO_KEY);
11239             myrpt->remoterx = 1;
11240             remkeyed = 1;
11241          }
11242       }
11243    }
11244    if (myrpt->p.archivedir)
11245    {
11246       char mycmd[100],mydate[100],*b,*b1;
11247       time_t myt;
11248       long blocksleft;
11249 
11250 
11251       mkdir(myrpt->p.archivedir,0600);
11252       sprintf(mycmd,"%s/%s",myrpt->p.archivedir,myrpt->name);
11253       mkdir(mycmd,0600);
11254       time(&myt);
11255       strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S",
11256          localtime(&myt));
11257       sprintf(mycmd,"mixmonitor start %s %s/%s/%s.wav49 a",chan->name,
11258          myrpt->p.archivedir,myrpt->name,mydate);
11259       if (myrpt->p.monminblocks)
11260       {
11261          blocksleft = diskavail(myrpt);
11262          if (myrpt->p.remotetimeout)
11263          {
11264             blocksleft -= (myrpt->p.remotetimeout *
11265                MONITOR_DISK_BLOCKS_PER_MINUTE) / 60;
11266          }
11267          if (blocksleft >= myrpt->p.monminblocks)
11268             ast_cli_command(nullfd,mycmd);
11269       } else ast_cli_command(nullfd,mycmd);
11270       /* look at callerid to see what node this comes from */
11271       if (!chan->cid.cid_num) /* if doesn't have caller id */
11272       {
11273          b1 = "0";
11274       } else {
11275          ast_callerid_parse(chan->cid.cid_num,&b,&b1);
11276          ast_shrink_phone_number(b1);
11277       }
11278       sprintf(mycmd,"CONNECT,%s",b1);
11279       donodelog(myrpt,mycmd);
11280    }
11281    myrpt->loginuser[0] = 0;
11282    myrpt->loginlevel[0] = 0;
11283    myrpt->authtelltimer = 0;
11284    myrpt->authtimer = 0;
11285    authtold = 0;
11286    authreq = 0;
11287    if (myrpt->p.authlevel > 1) authreq = 1;
11288    setrem(myrpt); 
11289    n = 0;
11290    dtmfed = 0;
11291    cs[n++] = chan;
11292    cs[n++] = myrpt->rxchannel;
11293    cs[n++] = myrpt->pchannel;
11294    if (myrpt->rxchannel != myrpt->txchannel)
11295       cs[n++] = myrpt->txchannel;
11296    /* start un-locked */
11297    for(;;) 
11298    {
11299       if (ast_check_hangup(chan)) break;
11300       if (ast_check_hangup(myrpt->rxchannel)) break;
11301       notremming = 0;
11302       setting = 0;
11303       reming = 0;
11304       telem = myrpt->tele.next;
11305       while(telem != &myrpt->tele)
11306       {
11307          if (telem->mode == SETREMOTE) setting = 1;
11308          if ((telem->mode == SETREMOTE) ||
11309              (telem->mode == SCAN) ||
11310             (telem->mode == TUNE))  reming = 1;
11311          else notremming = 1;
11312          telem = telem->next;
11313       }
11314       if (myrpt->reload)
11315       {
11316          myrpt->reload = 0;
11317          /* find our index, and load the vars */
11318          for(i = 0; i < nrpts; i++)
11319          {
11320             if (&rpt_vars[i] == myrpt)
11321             {
11322                load_rpt_vars(i,0);
11323                break;
11324             }
11325          }
11326       }
11327       time(&t);
11328       if (myrpt->p.remotetimeout)
11329       { 
11330          time_t r;
11331 
11332          r = (t - myrpt->start_time);
11333          if (r >= myrpt->p.remotetimeout)
11334          {
11335             sayfile(chan,"rpt/node");
11336             ast_say_character_str(chan,myrpt->name,NULL,chan->language);
11337             sayfile(chan,"rpt/timeout");
11338             ast_safe_sleep(chan,1000);
11339             break;
11340          }
11341          if ((myrpt->p.remotetimeoutwarning) && 
11342              (r >= (myrpt->p.remotetimeout -
11343             myrpt->p.remotetimeoutwarning)) &&
11344                 (r <= (myrpt->p.remotetimeout - 
11345                   myrpt->p.remotetimeoutwarningfreq)))
11346          {
11347             if (myrpt->p.remotetimeoutwarningfreq)
11348             {
11349                 if ((t - last_timeout_warning) >=
11350                myrpt->p.remotetimeoutwarningfreq)
11351                 {
11352                time(&last_timeout_warning);
11353                rpt_telemetry(myrpt,TIMEOUT_WARNING,0);
11354                 }
11355             }
11356             else
11357             {
11358                 if (!last_timeout_warning)
11359                 {
11360                time(&last_timeout_warning);
11361                rpt_telemetry(myrpt,TIMEOUT_WARNING,0);
11362                 }
11363             }
11364          }
11365       }
11366       if (myrpt->p.remoteinacttimeout && myrpt->last_activity_time)
11367       { 
11368          time_t r;
11369 
11370          r = (t - myrpt->last_activity_time);
11371          if (r >= myrpt->p.remoteinacttimeout)
11372          {
11373             sayfile(chan,"rpt/node");
11374             ast_say_character_str(chan,myrpt->name,NULL,chan->language);
11375             sayfile(chan,"rpt/timeout");
11376             ast_safe_sleep(chan,1000);
11377             break;
11378          }
11379          if ((myrpt->p.remotetimeoutwarning) && 
11380              (r >= (myrpt->p.remoteinacttimeout -
11381             myrpt->p.remotetimeoutwarning)) &&
11382                 (r <= (myrpt->p.remoteinacttimeout - 
11383                   myrpt->p.remotetimeoutwarningfreq)))
11384          {
11385             if (myrpt->p.remotetimeoutwarningfreq)
11386             {
11387                 if ((t - last_timeout_warning) >=
11388                myrpt->p.remotetimeoutwarningfreq)
11389                 {
11390                time(&last_timeout_warning);
11391                rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0);
11392                 }
11393             }
11394             else
11395             {
11396                 if (!last_timeout_warning)
11397                 {
11398                time(&last_timeout_warning);
11399                rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0);
11400                 }
11401             }
11402          }
11403       }
11404       ms = MSWAIT;
11405       who = ast_waitfor_n(cs,n,&ms);
11406       if (who == NULL) ms = 0;
11407       elap = MSWAIT - ms;
11408       if (myrpt->macrotimer) myrpt->macrotimer -= elap;
11409       if (myrpt->macrotimer < 0) myrpt->macrotimer = 0;
11410       if (!ms) continue;
11411       /* do local dtmf timer */
11412       if (myrpt->dtmf_local_timer)
11413       {
11414          if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap;
11415          if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1;
11416       }
11417       rpt_mutex_lock(&myrpt->lock);
11418       do_dtmf_local(myrpt,0);
11419       rpt_mutex_unlock(&myrpt->lock);
11420       rem_totx =  myrpt->dtmf_local_timer && (!phone_mode);
11421       rem_totx |= keyed && (!myrpt->tunerequest);
11422       rem_rx = (remkeyed && (!setting)) || (myrpt->tele.next != &myrpt->tele);
11423       if(!strcmp(myrpt->remote, remote_rig_ic706))
11424          rem_totx |= myrpt->tunerequest;
11425       if (keyed && (!keyed1))
11426       {
11427          keyed1 = 1;
11428       }
11429 
11430       if (!keyed && (keyed1))
11431       {
11432          time_t myt;
11433 
11434          keyed1 = 0;
11435          time(&myt);
11436          /* if login necessary, and not too soon */
11437          if ((myrpt->p.authlevel) && 
11438              (!myrpt->loginlevel[0]) &&
11439             (myt > (t + 3)))
11440          {
11441             authreq = 1;
11442             authtold = 0;
11443             myrpt->authtelltimer = AUTHTELLTIME - AUTHTXTIME;
11444          }
11445       }
11446 
11447 
11448       if (rem_rx && (!myrpt->remoterx))
11449       {
11450          myrpt->remoterx = 1;
11451          ast_indicate(chan,AST_CONTROL_RADIO_KEY);
11452       }
11453       if ((!rem_rx) && (myrpt->remoterx))
11454       {
11455          myrpt->remoterx = 0;
11456          ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
11457       }
11458       /* if auth requested, and not authed yet */
11459       if (authreq && (!myrpt->loginlevel[0]))
11460       {
11461          if ((!authtold) && ((myrpt->authtelltimer += elap)
11462              >= AUTHTELLTIME))
11463          {
11464             authtold = 1;
11465             rpt_telemetry(myrpt,LOGINREQ,NULL);
11466          }
11467          if ((myrpt->authtimer += elap) >= AUTHLOGOUTTIME)
11468          {
11469             break; /* if not logged in, hang up after a time */
11470          }
11471       }
11472 #ifndef  OLDKEY
11473       if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME)
11474       {
11475          myrpt->retxtimer = 0;
11476          if ((myrpt->remoterx) && (!myrpt->remotetx))
11477             ast_indicate(chan,AST_CONTROL_RADIO_KEY);
11478          else
11479             ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
11480       }
11481 
11482       if ((myrpt->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 2))
11483       {
11484          keyed = 0;
11485          myrpt->rerxtimer = 0;
11486       }
11487 #endif
11488       if (rem_totx && (!myrpt->remotetx))
11489       {
11490          /* if not authed, and needed, dont transmit */
11491          if ((!myrpt->p.authlevel) || myrpt->loginlevel[0])
11492          {
11493             myrpt->remotetx = 1;
11494             if((myrpt->remtxfreqok = check_tx_freq(myrpt)))
11495             {
11496                time(&myrpt->last_activity_time);
11497                if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
11498                {
11499                   z.radpar = DAHDI_RADPAR_UIODATA;
11500                   z.data = 1;
11501                   if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
11502                   {
11503                      ast_log(LOG_ERROR,"Cannot set UIODATA\n");
11504                      return -1;
11505                   }
11506                }
11507                else
11508                {
11509                   ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
11510                }
11511                if (myrpt->p.archivedir) donodelog(myrpt,"TXKEY");
11512             }
11513          }
11514       }
11515       if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */
11516       {
11517          myrpt->remotetx = 0;
11518          if(!myrpt->remtxfreqok){
11519             rpt_telemetry(myrpt,UNAUTHTX,NULL);
11520          }
11521          if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
11522          {
11523             z.radpar = DAHDI_RADPAR_UIODATA;
11524             z.data = 3;
11525             if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
11526             {
11527                ast_log(LOG_ERROR,"Cannot set UIODATA\n");
11528                return -1;
11529             }
11530          }
11531          else
11532          {
11533             ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
11534          }
11535          if (myrpt->p.archivedir) donodelog(myrpt,"TXUNKEY");
11536       }
11537       if (myrpt->hfscanmode){
11538          myrpt->scantimer -= elap;
11539          if(myrpt->scantimer <= 0){
11540             if (!reming)
11541             {
11542                myrpt->scantimer = REM_SCANTIME;
11543                rpt_telemetry(myrpt,SCAN,0);
11544             } else myrpt->scantimer = 1;
11545          }
11546       }
11547       rpt_mutex_lock(&myrpt->lock);
11548       c = myrpt->macrobuf[0];
11549       if (c && (!myrpt->macrotimer))
11550       {
11551          myrpt->macrotimer = MACROTIME;
11552          memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1);
11553          if ((c == 'p') || (c == 'P'))
11554             myrpt->macrotimer = MACROPTIME;
11555          rpt_mutex_unlock(&myrpt->lock);
11556          if (myrpt->p.archivedir)
11557          {
11558             char str[100];
11559                sprintf(str,"DTMF(M),%c",c);
11560             donodelog(myrpt,str);
11561          }
11562          if (handle_remote_dtmf_digit(myrpt,c,&keyed,0) == -1) break;
11563          continue;
11564       } else rpt_mutex_unlock(&myrpt->lock);
11565       if (who == chan) /* if it was a read from incomming */
11566       {
11567          f = ast_read(chan);
11568          if (!f)
11569          {
11570             if (debug) printf("@@@@ link:Hung Up\n");
11571             break;
11572          }
11573          if (f->frametype == AST_FRAME_VOICE)
11574          {
11575             if (ioctl(chan->fds[0], DAHDI_GETCONFMUTE, &ismuted) == -1)
11576             {
11577                ismuted = 0;
11578             }
11579             /* if not transmitting, zero-out audio */
11580             ismuted |= (!myrpt->remotetx);
11581             if (dtmfed && phone_mode) ismuted = 1;
11582             dtmfed = 0;
11583             if (ismuted)
11584             {
11585                memset(f->data,0,f->datalen);
11586                if (myrpt->lastf1)
11587                   memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
11588                if (myrpt->lastf2)
11589                   memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
11590             } 
11591             if (f) f2 = ast_frdup(f);
11592             else f2 = NULL;
11593             f1 = myrpt->lastf2;
11594             myrpt->lastf2 = myrpt->lastf1;
11595             myrpt->lastf1 = f2;
11596             if (ismuted)
11597             {
11598                if (myrpt->lastf1)
11599                   memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
11600                if (myrpt->lastf2)
11601                   memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
11602             }
11603             if (f1)
11604             {
11605                if (phone_mode)
11606                   ast_write(myrpt->txchannel,f1);
11607                else
11608                   ast_write(myrpt->txchannel,f);
11609                ast_frfree(f1);
11610             }
11611          }
11612 #ifndef  OLD_ASTERISK
11613          else if (f->frametype == AST_FRAME_DTMF_BEGIN)
11614          {
11615             if (myrpt->lastf1)
11616                memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
11617             if (myrpt->lastf2)
11618                memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
11619             dtmfed = 1;
11620          }
11621 #endif
11622          if (f->frametype == AST_FRAME_DTMF)
11623          {
11624             if (myrpt->lastf1)
11625                memset(myrpt->lastf1->data,0,myrpt->lastf1->datalen);
11626             if (myrpt->lastf2)
11627                memset(myrpt->lastf2->data,0,myrpt->lastf2->datalen);
11628             dtmfed = 1;
11629             if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1)
11630             {
11631                if (debug) printf("@@@@ rpt:Hung Up\n");
11632                ast_frfree(f);
11633                break;
11634             }
11635          }
11636          if (f->frametype == AST_FRAME_TEXT)
11637          {
11638             if (handle_remote_data(myrpt,f->data) == -1)
11639             {
11640                if (debug) printf("@@@@ rpt:Hung Up\n");
11641                ast_frfree(f);
11642                break;
11643             }
11644          }
11645          if (f->frametype == AST_FRAME_CONTROL)
11646          {
11647             if (f->subclass == AST_CONTROL_HANGUP)
11648             {
11649                if (debug) printf("@@@@ rpt:Hung Up\n");
11650                ast_frfree(f);
11651                break;
11652             }
11653             /* if RX key */
11654             if (f->subclass == AST_CONTROL_RADIO_KEY)
11655             {
11656                if (debug == 7) printf("@@@@ rx key\n");
11657                keyed = 1;
11658                myrpt->rerxtimer = 0;
11659             }
11660             /* if RX un-key */
11661             if (f->subclass == AST_CONTROL_RADIO_UNKEY)
11662             {
11663                myrpt->rerxtimer = 0;
11664                if (debug == 7) printf("@@@@ rx un-key\n");
11665                keyed = 0;
11666             }
11667          }
11668          ast_frfree(f);
11669          continue;
11670       }
11671       if (who == myrpt->rxchannel) /* if it was a read from radio */
11672       {
11673          f = ast_read(myrpt->rxchannel);
11674          if (!f)
11675          {
11676             if (debug) printf("@@@@ link:Hung Up\n");
11677             break;
11678          }
11679          if (f->frametype == AST_FRAME_VOICE)
11680          {
11681             int myreming = 0;
11682 
11683             if(!strcmp(myrpt->remote, remote_rig_kenwood))
11684                myreming = reming;
11685 
11686             if (myreming || (!remkeyed) ||
11687             ((myrpt->remote) && (myrpt->remotetx)) ||
11688               ((myrpt->remmode != REM_MODE_FM) &&
11689                 notremming))
11690                memset(f->data,0,f->datalen); 
11691              ast_write(myrpt->pchannel,f);
11692          }
11693          else if (f->frametype == AST_FRAME_CONTROL)
11694          {
11695             if (f->subclass == AST_CONTROL_HANGUP)
11696             {
11697                if (debug) printf("@@@@ rpt:Hung Up\n");
11698                ast_frfree(f);
11699                break;
11700             }
11701             /* if RX key */
11702             if (f->subclass == AST_CONTROL_RADIO_KEY)
11703             {
11704                if (debug == 7) printf("@@@@ remote rx key\n");
11705                if (!myrpt->remotetx)
11706                {
11707                   remkeyed = 1;
11708                }
11709             }
11710             /* if RX un-key */
11711             if (f->subclass == AST_CONTROL_RADIO_UNKEY)
11712             {
11713                if (debug == 7) printf("@@@@ remote rx un-key\n");
11714                if (!myrpt->remotetx) 
11715                {
11716                   remkeyed = 0;
11717                }
11718             }
11719          }
11720          ast_frfree(f);
11721          continue;
11722       }
11723       if (who == myrpt->pchannel) /* if is remote mix output */
11724       {
11725          f = ast_read(myrpt->pchannel);
11726          if (!f)
11727          {
11728             if (debug) printf("@@@@ link:Hung Up\n");
11729             break;
11730          }
11731          if (f->frametype == AST_FRAME_VOICE)
11732          {
11733             ast_write(chan,f);
11734          }
11735          if (f->frametype == AST_FRAME_CONTROL)
11736          {
11737             if (f->subclass == AST_CONTROL_HANGUP)
11738             {
11739                if (debug) printf("@@@@ rpt:Hung Up\n");
11740                ast_frfree(f);
11741                break;
11742             }
11743          }
11744          ast_frfree(f);
11745          continue;
11746       }
11747       if ((myrpt->rxchannel != myrpt->txchannel) && 
11748          (who == myrpt->txchannel)) /* do this cuz you have to */
11749       {
11750          f = ast_read(myrpt->txchannel);
11751          if (!f)
11752          {
11753             if (debug) printf("@@@@ link:Hung Up\n");
11754             break;
11755          }
11756          if (f->frametype == AST_FRAME_CONTROL)
11757          {
11758             if (f->subclass == AST_CONTROL_HANGUP)
11759             {
11760                if (debug) printf("@@@@ rpt:Hung Up\n");
11761                ast_frfree(f);
11762                break;
11763             }
11764          }
11765          ast_frfree(f);
11766          continue;
11767       }
11768    }
11769    if (myrpt->p.archivedir)
11770    {
11771       char mycmd[100],*b,*b1;
11772 
11773       /* look at callerid to see what node this comes from */
11774       if (!chan->cid.cid_num) /* if doesn't have caller id */
11775       {
11776          b1 = "0";
11777       } else {
11778          ast_callerid_parse(chan->cid.cid_num,&b,&b1);
11779          ast_shrink_phone_number(b1);
11780       }
11781       sprintf(mycmd,"DISCONNECT,%s",b1);
11782       donodelog(myrpt,mycmd);
11783    }
11784    /* wait for telem to be done */
11785    while(myrpt->tele.next != &myrpt->tele) usleep(100000);
11786    sprintf(tmp,"mixmonitor stop %s",chan->name);
11787    ast_cli_command(nullfd,tmp);
11788    close(nullfd);
11789    rpt_mutex_lock(&myrpt->lock);
11790    myrpt->hfscanmode = 0;
11791    myrpt->hfscanstatus = 0;
11792    myrpt->remoteon = 0;
11793    rpt_mutex_unlock(&myrpt->lock);
11794    if (myrpt->lastf1) ast_frfree(myrpt->lastf1);
11795    myrpt->lastf1 = NULL;
11796    if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
11797    myrpt->lastf2 = NULL;
11798    if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->zaptxchannel))
11799    {
11800       z.radpar = DAHDI_RADPAR_UIOMODE;
11801       z.data = 3;
11802       if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
11803       {
11804          ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
11805          return -1;
11806       }
11807       z.radpar = DAHDI_RADPAR_UIODATA;
11808       z.data = 3;
11809       if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
11810       {
11811          ast_log(LOG_ERROR,"Cannot set UIODATA\n");
11812          return -1;
11813       }
11814       i = DAHDI_OFFHOOK;
11815       if (ioctl(myrpt->zaptxchannel->fds[0],DAHDI_HOOK,&i) == -1)
11816       {
11817          ast_log(LOG_ERROR,"Cannot set hook\n");
11818          return -1;
11819       }
11820    }
11821    if (myrpt->iofd) close(myrpt->iofd);
11822    myrpt->iofd = -1;
11823    ast_hangup(myrpt->pchannel);
11824    if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel);
11825    ast_hangup(myrpt->rxchannel);
11826    closerem(myrpt);
11827 #ifdef   OLD_ASTERISK
11828    LOCAL_USER_REMOVE(u);
11829 #endif
11830    return res;
11831 }

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

Definition at line 1580 of file app_rpt.c.

References ast_localtime(), and localtime_r.

Referenced by do_scheduler(), and rpt_tele_thread().

01581 {
01582 #ifdef OLD_ASTERISK
01583    localtime_r(t, lt);
01584 #else
01585    ast_localtime(t, lt, NULL);
01586 #endif
01587 }

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

Definition at line 10385 of file app_rpt.c.

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

Referenced by load_module().

10386 {
10387 int   i,n;
10388 pthread_attr_t attr;
10389 struct ast_config *cfg;
10390 char *this,*val;
10391 
10392    /* init nodelog queue */
10393    nodelog.next = nodelog.prev = &nodelog;
10394    /* go thru all the specified repeaters */
10395    this = NULL;
10396    n = 0;
10397    /* wait until asterisk starts */
10398         while(!ast_test_flag(&ast_options,AST_OPT_FLAG_FULLY_BOOTED))
10399                 usleep(250000);
10400    rpt_vars[n].cfg = ast_config_load("rpt.conf");
10401    cfg = rpt_vars[n].cfg;
10402    if (!cfg) {
10403       ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf.  Radio Repeater disabled.\n");
10404       pthread_exit(NULL);
10405    }
10406    while((this = ast_category_browse(cfg,this)) != NULL)
10407    {
10408       for(i = 0 ; i < strlen(this) ; i++){
10409          if((this[i] < '0') || (this[i] > '9'))
10410             break;
10411       }
10412       if(i != strlen(this)) continue; /* Not a node defn */
10413       memset(&rpt_vars[n],0,sizeof(rpt_vars[n]));
10414       rpt_vars[n].name = strdup(this);
10415       val = (char *) ast_variable_retrieve(cfg,this,"rxchannel");
10416       if (val) rpt_vars[n].rxchanname = strdup(val);
10417       val = (char *) ast_variable_retrieve(cfg,this,"txchannel");
10418       if (val) rpt_vars[n].txchanname = strdup(val);
10419       val = (char *) ast_variable_retrieve(cfg,this,"remote");
10420       if (val) rpt_vars[n].remote = strdup(val);
10421       ast_mutex_init(&rpt_vars[n].lock);
10422       ast_mutex_init(&rpt_vars[n].remlock);
10423       rpt_vars[n].tele.next = &rpt_vars[n].tele;
10424       rpt_vars[n].tele.prev = &rpt_vars[n].tele;
10425       rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
10426       rpt_vars[n].tailmessagen = 0;
10427 #ifdef   _MDC_DECODE_H_
10428       rpt_vars[n].mdc = mdc_decoder_new(8000);
10429 #endif
10430       n++;
10431    }
10432    nrpts = n;
10433    ast_config_destroy(cfg);
10434 
10435    /* start em all */
10436    for(i = 0; i < n; i++)
10437    {
10438       load_rpt_vars(i,1);
10439 
10440       /* if is a remote, dont start one for it */
10441       if (rpt_vars[i].remote)
10442       {
10443          if(retreive_memory(&rpt_vars[i],"init")){ /* Try to retreive initial memory channel */
10444             strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1);
10445             strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1);
10446 
10447             strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1);
10448             rpt_vars[i].remmode = REM_MODE_FM;
10449             rpt_vars[i].offset = REM_SIMPLEX;
10450             rpt_vars[i].powerlevel = REM_MEDPWR;
10451          }
10452          continue;
10453       }
10454       if (!rpt_vars[i].p.ident)
10455       {
10456          ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name);
10457          ast_config_destroy(cfg);
10458          pthread_exit(NULL);
10459       }
10460            pthread_attr_init(&attr);
10461            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
10462       ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
10463    }
10464    usleep(500000);
10465    time(&starttime);
10466    for(;;)
10467    {
10468       /* Now monitor each thread, and restart it if necessary */
10469       for(i = 0; i < n; i++)
10470       { 
10471          int rv;
10472          if (rpt_vars[i].remote) continue;
10473          if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP) 
10474             rv = -1;
10475          else
10476             rv = pthread_kill(rpt_vars[i].rpt_thread,0);
10477          if (rv)
10478          {
10479             if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15)
10480             {
10481                if(rpt_vars[i].threadrestarts >= 5)
10482                {
10483                   ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n");
10484                   exit(1); /* Stuck in a restart loop, kill Asterisk and start over */
10485                }
10486                else
10487                {
10488                   ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name);
10489                   rpt_vars[i].threadrestarts++;
10490                }
10491             }
10492             else
10493                rpt_vars[i].threadrestarts = 0;
10494 
10495             rpt_vars[i].lastthreadrestarttime = time(NULL);
10496                  pthread_attr_init(&attr);
10497                  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
10498             ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
10499             ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name);
10500          }
10501 
10502       }
10503       for(;;)
10504       {
10505          struct nodelog *nodep;
10506          char *space,datestr[100],fname[300];
10507          int fd;
10508 
10509          ast_mutex_lock(&nodeloglock);
10510          nodep = nodelog.next;
10511          if(nodep == &nodelog) /* if nothing in queue */
10512          {
10513             ast_mutex_unlock(&nodeloglock);
10514             break;
10515          }
10516          remque((struct qelem *)nodep);
10517          ast_mutex_unlock(&nodeloglock);
10518          space = strchr(nodep->str,' ');
10519          if (!space) 
10520          {
10521             free(nodep);
10522             continue;
10523          }
10524          *space = 0;
10525          strftime(datestr,sizeof(datestr) - 1,"%Y%m%d",
10526             localtime(&nodep->timestamp));
10527          sprintf(fname,"%s/%s/%s.txt",nodep->archivedir,
10528             nodep->str,datestr);
10529          fd = open(fname,O_WRONLY | O_CREAT | O_APPEND,0600);
10530          if (fd == -1)
10531          {
10532             ast_log(LOG_ERROR,"Cannot open node log file %s for write",space + 1);
10533             free(nodep);
10534             continue;
10535          }
10536          if (write(fd,space + 1,strlen(space + 1)) !=
10537             strlen(space + 1))
10538          {
10539             ast_log(LOG_ERROR,"Cannot write node log file %s for write",space + 1);
10540             free(nodep);
10541             continue;
10542          }
10543          close(fd);
10544          free(nodep);
10545       }
10546       sleep(2);
10547    }
10548    ast_config_destroy(cfg);
10549    pthread_exit(NULL);
10550 }

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

Definition at line 2902 of file app_rpt.c.

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

Referenced by rpt_telemetry().

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

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

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

04114 {
04115 struct rpt_tele *tele;
04116 struct rpt_link *mylink = (struct rpt_link *) data;
04117 int res;
04118 pthread_attr_t attr;
04119 
04120    tele = malloc(sizeof(struct rpt_tele));
04121    if (!tele)
04122    {
04123       ast_log(LOG_WARNING, "Unable to allocate memory\n");
04124       pthread_exit(NULL);
04125       return;
04126    }
04127    /* zero it out */
04128    memset((char *)tele,0,sizeof(struct rpt_tele));
04129    tele->rpt = myrpt;
04130    tele->mode = mode;
04131    rpt_mutex_lock(&myrpt->lock);
04132    if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED) ||
04133        (mode == LINKUNKEY)){
04134       memset(&tele->mylink,0,sizeof(struct rpt_link));
04135       if (mylink){
04136          memcpy(&tele->mylink,mylink,sizeof(struct rpt_link));
04137       }
04138    }
04139    else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) {
04140       strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
04141       tele->param[TELEPARAMSIZE - 1] = 0;
04142    }
04143    if (mode == REMXXX) tele->submode = (int) data;
04144    insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next);
04145    rpt_mutex_unlock(&myrpt->lock);
04146         pthread_attr_init(&attr);
04147         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
04148    res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele);
04149    if(res < 0){
04150       rpt_mutex_lock(&myrpt->lock);
04151       remque((struct qlem *) tele); /* We don't like stuck transmitters, remove it from the queue */
04152       rpt_mutex_unlock(&myrpt->lock);  
04153       ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res));
04154    }
04155    return;
04156 }

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

Definition at line 2686 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

02687 {
02688 int   res;
02689 
02690    res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
02691    if (!res) 
02692       res = ast_waitstream(mychannel, "");
02693    else
02694        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02695    ast_stopstream(mychannel);
02696    return res;
02697 }

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

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

02674 {
02675 int   res;
02676 
02677    res = ast_streamfile(mychannel, fname, mychannel->language);
02678    if (!res) 
02679       res = ast_waitstream(mychannel, "");
02680    else
02681        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02682    ast_stopstream(mychannel);
02683    return res;
02684 }

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

Definition at line 2699 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

02700 {
02701    int res;
02702    res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL);
02703    if(!res)
02704       res = ast_waitstream(mychannel, "");
02705    else
02706       ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02707    ast_stopstream(mychannel);
02708    return res;
02709 }

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

Definition at line 7198 of file app_rpt.c.

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

Referenced by set_ic706().

07199 {
07200    unsigned char cmdstr[10];
07201    
07202    cmdstr[0] = cmdstr[1] = 0xfe;
07203    cmdstr[2] = myrpt->p.civaddr;
07204    cmdstr[3] = 0xe0;
07205    cmdstr[4] = 8;
07206    cmdstr[5] = 0;
07207    cmdstr[6] = ((slot / 10) << 4) + (slot % 10);
07208    cmdstr[7] = 0xfd;
07209 
07210    return(civ_cmd(myrpt,cmdstr,8));
07211 }

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

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

04411 {
04412 char  str[300];
04413 struct   ast_frame wf;
04414 struct   rpt_link *l;
04415 
04416    snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c);
04417    wf.frametype = AST_FRAME_TEXT;
04418    wf.subclass = 0;
04419    wf.offset = 0;
04420    wf.mallocd = 0;
04421    wf.datalen = strlen(str) + 1;
04422    wf.samples = 0;
04423    l = myrpt->links.next;
04424    /* first, see if our dude is there */
04425    while(l != &myrpt->links)
04426    {
04427       if (l->name[0] == '0') 
04428       {
04429          l = l->next;
04430          continue;
04431       }
04432       /* if we found it, write it and were done */
04433       if (!strcmp(l->name,myrpt->cmdnode))
04434       {
04435          wf.data = str;
04436          if (l->chan) ast_write(l->chan,&wf);
04437          return;
04438       }
04439       l = l->next;
04440    }
04441    l = myrpt->links.next;
04442    /* if not, give it to everyone */
04443    while(l != &myrpt->links)
04444    {
04445       wf.data = str;
04446       if (l->chan) ast_write(l->chan,&wf);
04447       l = l->next;
04448    }
04449    return;
04450 }

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

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

02461 {
02462 
02463 static struct morse_bits mbits[] = {
02464       {0, 0}, /* SPACE */
02465       {0, 0}, 
02466       {6, 18},/* " */
02467       {0, 0},
02468       {7, 72},/* $ */
02469       {0, 0},
02470       {0, 0},
02471       {6, 30},/* ' */
02472       {5, 13},/* ( */
02473       {6, 29},/* ) */
02474       {0, 0},
02475       {5, 10},/* + */
02476       {6, 51},/* , */
02477       {6, 33},/* - */
02478       {6, 42},/* . */
02479       {5, 9}, /* / */
02480       {5, 31},/* 0 */
02481       {5, 30},/* 1 */
02482       {5, 28},/* 2 */
02483       {5, 24},/* 3 */
02484       {5, 16},/* 4 */
02485       {5, 0}, /* 5 */
02486       {5, 1}, /* 6 */
02487       {5, 3}, /* 7 */
02488       {5, 7}, /* 8 */
02489       {5, 15},/* 9 */
02490       {6, 7}, /* : */
02491       {6, 21},/* ; */
02492       {0, 0},
02493       {5, 33},/* = */
02494       {0, 0},
02495       {6, 12},/* ? */
02496       {0, 0},
02497          {2, 2}, /* A */
02498       {4, 1}, /* B */
02499       {4, 5}, /* C */
02500       {3, 1}, /* D */
02501       {1, 0}, /* E */
02502       {4, 4}, /* F */
02503       {3, 3}, /* G */
02504       {4, 0}, /* H */
02505       {2, 0}, /* I */
02506       {4, 14},/* J */
02507       {3, 5}, /* K */
02508       {4, 2}, /* L */
02509       {2, 3}, /* M */
02510       {2, 1}, /* N */
02511       {3, 7}, /* O */
02512       {4, 6}, /* P */
02513       {4, 11},/* Q */
02514       {3, 2}, /* R */
02515       {3, 0}, /* S */
02516       {1, 1}, /* T */
02517       {3, 4}, /* U */
02518       {4, 8}, /* V */
02519       {3, 6}, /* W */
02520       {4, 9}, /* X */
02521       {4, 13},/* Y */
02522       {4, 3}  /* Z */
02523    };
02524 
02525 
02526    int dottime;
02527    int dashtime;
02528    int intralettertime;
02529    int interlettertime;
02530    int interwordtime;
02531    int len, ddcomb;
02532    int res;
02533    int c;
02534    int i;
02535    int flags;
02536          
02537    res = 0;
02538    
02539    /* Approximate the dot time from the speed arg. */
02540    
02541    dottime = 900/speed;
02542    
02543    /* Establish timing releationships */
02544    
02545    dashtime = 3 * dottime;
02546    intralettertime = dottime;
02547    interlettertime = dottime * 4 ;
02548    interwordtime = dottime * 7;
02549    
02550    for(;(*string) && (!res); string++){
02551    
02552       c = *string;
02553       
02554       /* Convert lower case to upper case */
02555       
02556       if((c >= 'a') && (c <= 'z'))
02557          c -= 0x20;
02558       
02559       /* Can't deal with any char code greater than Z, skip it */
02560       
02561       if(c  > 'Z')
02562          continue;
02563       
02564       /* If space char, wait the inter word time */
02565                
02566       if(c == ' '){
02567          if(!res)
02568             res = play_silence(chan, interwordtime);
02569          continue;
02570       }
02571       
02572       /* Subtract out control char offset to match our table */
02573       
02574       c -= 0x20;
02575       
02576       /* Get the character data */
02577       
02578       len = mbits[c].len;
02579       ddcomb = mbits[c].ddcomb;
02580       
02581       /* Send the character */
02582       
02583       for(; len ; len--){
02584          if(!res)
02585             res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude);
02586          if(!res)
02587             res = play_silence(chan, intralettertime);
02588          ddcomb >>= 1;
02589       }
02590       
02591       /* Wait the interletter time */
02592       
02593       if(!res)
02594          res = play_silence(chan, interlettertime - intralettertime);
02595    }
02596    
02597    /* Wait for all the frames to be sent */
02598    
02599    if (!res) 
02600       res = ast_waitstream(chan, "");
02601    ast_stopstream(chan);
02602    
02603    /*
02604    * Wait for the zaptel driver to physically write the tone blocks to the hardware
02605    */
02606 
02607    for(i = 0; i < 20 ; i++){
02608       flags =  DAHDI_IOMUX_WRITEEMPTY | DAHDI_IOMUX_NOWAIT; 
02609       res = ioctl(chan->fds[0], DAHDI_IOMUX, &flags);
02610       if(flags & DAHDI_IOMUX_WRITEEMPTY)
02611          break;
02612       if( ast_safe_sleep(chan, 50)){
02613          res = -1;
02614          break;
02615       }
02616    }
02617 
02618    
02619    return res;
02620 }

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

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

02623 {
02624    char *stringp;
02625    char *tonesubset;
02626    int f1,f2;
02627    int duration;
02628    int amplitude;
02629    int res;
02630    int i;
02631    int flags;
02632    
02633    res = 0;
02634    
02635    stringp = ast_strdupa(tonestring);
02636 
02637    for(;tonestring;){
02638       tonesubset = strsep(&stringp,")");
02639       if(!tonesubset)
02640          break;
02641       if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &amplitude) != 4)
02642          break;
02643       res = play_tone_pair(chan, f1, f2, duration, amplitude);
02644       if(res)
02645          break;
02646    }
02647    if(!res)
02648       res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */
02649    
02650    if (!res) 
02651       res = ast_waitstream(chan, "");
02652    ast_stopstream(chan);
02653 
02654    /*
02655    * Wait for the zaptel driver to physically write the tone blocks to the hardware
02656    */
02657 
02658    for(i = 0; i < 20 ; i++){
02659       flags =  DAHDI_IOMUX_WRITEEMPTY | DAHDI_IOMUX_NOWAIT; 
02660       res = ioctl(chan->fds[0], DAHDI_IOMUX, &flags);
02661       if(flags & DAHDI_IOMUX_WRITEEMPTY)
02662          break;
02663       if( ast_safe_sleep(chan, 50)){
02664          res = -1;
02665          break;
02666       }
02667    }
02668       
02669    return res;
02670       
02671 }

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

Definition at line 5969 of file app_rpt.c.

References serial_remote_io().

Referenced by sendrxkenwood().

05970 {
05971 int   i;
05972 
05973    if (debug) printf("Send to kenwood: %s\n",txstr);
05974    i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr), 
05975       (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3);
05976    if (i < 0) return -1;
05977    if ((i > 0) && (rxstr[i - 1] == '\r'))
05978       rxstr[i-- - 1] = 0;
05979    if (debug) printf("Got from kenwood: %s\n",rxstr);
05980    return(i);
05981 }

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

Definition at line 6075 of file app_rpt.c.

References KENWOOD_RETRIES, and sendkenwood().

Referenced by setkenwood().

06077 {
06078 int   i,j;
06079 
06080    for(i = 0;i < KENWOOD_RETRIES;i++)
06081    {
06082       j = sendkenwood(myrpt,txstr,rxstr);
06083       if (j < 0) return(j);
06084       if (j == 0) continue;
06085       if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0);
06086    }
06087    return(-1);
06088 }     

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

Definition at line 5866 of file app_rpt.c.

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

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

05868 {
05869    int i,j,index,oldmode,olddata;
05870    struct dahdi_radio_param prm;
05871    char c;
05872 
05873    if(debug){
05874       printf("String output was: ");
05875       for(i = 0; i < txbytes; i++)
05876          printf("%02X ", (unsigned char ) txbuf[i]);
05877       printf("\n");
05878    }
05879    if (myrpt->iofd > 0)  /* if to do out a serial port */
05880    {
05881       if (rxmaxbytes && rxbuf) tcflush(myrpt->iofd,TCIFLUSH);     
05882       if (write(myrpt->iofd,txbuf,txbytes) != txbytes) return -1;
05883       if ((!rxmaxbytes) || (rxbuf == NULL)) return(0);
05884       memset(rxbuf,0,rxmaxbytes);
05885       for(i = 0; i < rxmaxbytes; i++)
05886       {
05887          j = read(myrpt->iofd,&c,1);
05888          if (j < 1) return(i);
05889          rxbuf[i] = c;
05890          if (asciiflag & 1)
05891          {
05892             rxbuf[i + 1] = 0;
05893             if (c == '\r') break;
05894          }
05895       }              
05896       if(debug){
05897          printf("String returned was: ");
05898          for(j = 0; j < i; j++)
05899             printf("%02X ", (unsigned char ) rxbuf[j]);
05900          printf("\n");
05901       }
05902       return(i);
05903    }
05904 
05905    /* if not a zap channel, cant use pciradio stuff */
05906    if (myrpt->rxchannel != myrpt->zaprxchannel) return -1;  
05907 
05908    prm.radpar = DAHDI_RADPAR_UIOMODE;
05909    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_GETPARAM,&prm) == -1) return -1;
05910    oldmode = prm.data;
05911    prm.radpar = DAHDI_RADPAR_UIODATA;
05912    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_GETPARAM,&prm) == -1) return -1;
05913    olddata = prm.data;
05914         prm.radpar = DAHDI_RADPAR_REMMODE;
05915         if (asciiflag & 1)  prm.data = DAHDI_RADPAR_REM_SERIAL_ASCII;
05916         else prm.data = DAHDI_RADPAR_REM_SERIAL;
05917    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
05918    if (asciiflag & 2)
05919    {
05920       i = DAHDI_ONHOOK;
05921       if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_HOOK,&i) == -1) return -1;
05922       usleep(100000);
05923    }
05924         prm.radpar = DAHDI_RADPAR_REMCOMMAND;
05925         prm.data = rxmaxbytes;
05926         memcpy(prm.buf,txbuf,txbytes);
05927         prm.index = txbytes;
05928    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
05929         if (rxbuf)
05930         {
05931                 *rxbuf = 0;
05932                 memcpy(rxbuf,prm.buf,prm.index);
05933         }
05934    index = prm.index;
05935         prm.radpar = DAHDI_RADPAR_REMMODE;
05936         prm.data = DAHDI_RADPAR_REM_NONE;
05937    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
05938    if (asciiflag & 2)
05939    {
05940       i = DAHDI_OFFHOOK;
05941       if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_HOOK,&i) == -1) return -1;
05942    }
05943    prm.radpar = DAHDI_RADPAR_UIOMODE;
05944    prm.data = oldmode;
05945    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
05946    prm.radpar = DAHDI_RADPAR_UIODATA;
05947    prm.data = olddata;
05948    if (ioctl(myrpt->zaprxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
05949         return(index);
05950 }

static int service_scan ( struct rpt myrpt  )  [static]

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

07575 {
07576    int res, interval;
07577    char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0;
07578 
07579    switch(myrpt->hfscanmode){
07580 
07581       case HF_SCAN_DOWN_SLOW:
07582          interval = -10; /* 100Hz /sec */
07583          break;
07584 
07585       case HF_SCAN_DOWN_QUICK:
07586          interval = -50; /* 500Hz /sec */
07587          break;
07588 
07589       case HF_SCAN_DOWN_FAST:
07590          interval = -200; /* 2KHz /sec */
07591          break;
07592 
07593       case HF_SCAN_UP_SLOW:
07594          interval = 10; /* 100Hz /sec */
07595          break;
07596 
07597       case HF_SCAN_UP_QUICK:
07598          interval = 50; /* 500 Hz/sec */
07599          break;
07600 
07601       case HF_SCAN_UP_FAST:
07602          interval = 200; /* 2KHz /sec */
07603          break;
07604 
07605       default:
07606          myrpt->hfscanmode = 0; /* Huh? */
07607          return -1;
07608    }
07609 
07610    res = split_freq(mhz, decimals, myrpt->freq);
07611       
07612    if(!res){
07613       k100 =decimals[0];
07614       k10 = decimals[1];
07615       res = multimode_bump_freq(myrpt, interval);
07616    }
07617 
07618    if(!res)
07619       res = split_freq(mhz, decimals, myrpt->freq);
07620 
07621 
07622    if(res){
07623       myrpt->hfscanmode = 0;
07624       myrpt->hfscanstatus = -2;
07625       return -1;
07626    }
07627 
07628    /* Announce 10KHz boundaries */
07629    if(k10 != decimals[1]){
07630       int myhund = (interval < 0) ? k100 : decimals[0];
07631       int myten = (interval < 0) ? k10 : decimals[1];
07632       myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10;
07633    } else myrpt->hfscanstatus = 0;
07634    return res;
07635 
07636 }

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

Definition at line 6634 of file app_rpt.c.

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

Referenced by set_ft897().

06635 {
06636    unsigned char cmdstr[5];
06637    char hertz[MAXREMSTR],decimal[MAXREMSTR];
06638    int h,d; 
06639 
06640    memset(cmdstr, 0, 5);
06641 
06642    if(split_ctcss_freq(hertz, decimal, txtone))
06643       return -1; 
06644 
06645    h = atoi(hertz);
06646    d = atoi(decimal);
06647    
06648    cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10;
06649    cmdstr[1] = ((h % 10) << 4) + (d % 10);
06650    
06651    if(rxtone){
06652    
06653       if(split_ctcss_freq(hertz, decimal, rxtone))
06654          return -1; 
06655 
06656       h = atoi(hertz);
06657       d = atoi(decimal);
06658    
06659       cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10;
06660       cmdstr[3] = ((h % 10) << 4) + (d % 10);
06661    }
06662    cmdstr[4] = 0x0B; 
06663 
06664    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06665 }  

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

Definition at line 6611 of file app_rpt.c.

References serial_remote_io().

Referenced by set_ft897().

06612 {
06613    unsigned char cmdstr[5];
06614    
06615    memset(cmdstr, 0, 5);
06616    
06617    if(rxplon && txplon)
06618       cmdstr[0] = 0x2A; /* Encode and Decode */
06619    else if (!rxplon && txplon)
06620       cmdstr[0] = 0x4A; /* Encode only */
06621    else if (rxplon && !txplon)
06622       cmdstr[0] = 0x3A; /* Encode only */
06623    else
06624       cmdstr[0] = 0x8A; /* OFF */
06625 
06626    cmdstr[4] = 0x0A; 
06627 
06628    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06629 }

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

Definition at line 7096 of file app_rpt.c.

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

Referenced by set_ic706().

07097 {
07098    unsigned char cmdstr[10];
07099    int rv;
07100 
07101    cmdstr[0] = cmdstr[1] = 0xfe;
07102    cmdstr[2] = myrpt->p.civaddr;
07103    cmdstr[3] = 0xe0;
07104    cmdstr[4] = 0x16;
07105    cmdstr[5] = 0x42;
07106    cmdstr[6] = (txplon != 0);
07107    cmdstr[7] = 0xfd;
07108 
07109    rv = civ_cmd(myrpt,cmdstr,8);
07110    if (rv) return(-1);
07111 
07112    cmdstr[0] = cmdstr[1] = 0xfe;
07113    cmdstr[2] = myrpt->p.civaddr;
07114    cmdstr[3] = 0xe0;
07115    cmdstr[4] = 0x16;
07116    cmdstr[5] = 0x43;
07117    cmdstr[6] = (rxplon != 0);
07118    cmdstr[7] = 0xfd;
07119 
07120    return(civ_cmd(myrpt,cmdstr,8));
07121 }

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

Definition at line 6503 of file app_rpt.c.

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

Referenced by multimode_bump_freq_ft897(), and set_ft897().

06504 {
06505    unsigned char cmdstr[5];
06506    int fd,m,d;
06507    char mhz[MAXREMSTR];
06508    char decimals[MAXREMSTR];
06509 
06510    fd = 0;
06511    if(debug) 
06512       printf("New frequency: %s\n",newfreq);
06513 
06514    if(split_freq(mhz, decimals, newfreq))
06515       return -1; 
06516 
06517    m = atoi(mhz);
06518    d = atoi(decimals);
06519 
06520    /* The FT-897 likes packed BCD frequencies */
06521 
06522    cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10);        /* 100MHz 10Mhz */
06523    cmdstr[1] = ((m % 10) << 4) + (d / 10000);         /* 1MHz 100KHz */
06524    cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100);  /* 10KHz 1KHz */
06525    cmdstr[3] = (((d % 100)/10) << 4) + (d % 10);         /* 100Hz 10Hz */
06526    cmdstr[4] = 0x01;                /* command */
06527 
06528    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06529 
06530 }

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

Definition at line 7006 of file app_rpt.c.

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

Referenced by set_ic706().

07007 {
07008    unsigned char cmdstr[20];
07009    char mhz[MAXREMSTR], decimals[MAXREMSTR];
07010    int fd,m,d;
07011 
07012    fd = 0;
07013    if(debug) 
07014       printf("New frequency: %s\n",newfreq);
07015 
07016    if(split_freq(mhz, decimals, newfreq))
07017       return -1; 
07018 
07019    m = atoi(mhz);
07020    d = atoi(decimals);
07021 
07022    /* The ic-706 likes packed BCD frequencies */
07023 
07024    cmdstr[0] = cmdstr[1] = 0xfe;
07025    cmdstr[2] = myrpt->p.civaddr;
07026    cmdstr[3] = 0xe0;
07027    cmdstr[4] = 5;
07028    cmdstr[5] = ((d % 10) << 4);
07029    cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10);
07030    cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000);
07031    cmdstr[8] = (((m % 100)/10) << 4) + (m % 10);
07032    cmdstr[9] = (m / 100);
07033    cmdstr[10] = 0xfd;
07034 
07035    return(civ_cmd(myrpt,cmdstr,11));
07036 }

static int set_ft897 ( struct rpt myrpt  )  [static]

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

06670 {
06671    int res;
06672    
06673    if(debug)
06674       printf("@@@@ lock on\n");
06675 
06676    res = simple_command_ft897(myrpt, 0x00);  /* LOCK on */  
06677 
06678    if(debug)
06679       printf("@@@@ ptt off\n");
06680 
06681    if(!res)
06682       res = simple_command_ft897(myrpt, 0x88);     /* PTT off */
06683 
06684    if(debug)
06685       printf("Modulation mode\n");
06686 
06687    if(!res)
06688       res = set_mode_ft897(myrpt, myrpt->remmode);    /* Modulation mode */
06689 
06690    if(debug)
06691       printf("Split off\n");
06692 
06693    if(!res)
06694       simple_command_ft897(myrpt, 0x82);        /* Split off */
06695 
06696    if(debug)
06697       printf("Frequency\n");
06698 
06699    if(!res)
06700       res = set_freq_ft897(myrpt, myrpt->freq);    /* Frequency */
06701    if((myrpt->remmode == REM_MODE_FM)){
06702       if(debug)
06703          printf("Offset\n");
06704       if(!res)
06705          res = set_offset_ft897(myrpt, myrpt->offset);   /* Offset if FM */
06706       if((!res)&&(myrpt->rxplon || myrpt->txplon)){
06707          if(debug)
06708             printf("CTCSS tone freqs.\n");
06709          res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */
06710       }
06711       if(!res){
06712          if(debug)
06713             printf("CTCSS mode\n");
06714          res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */
06715       }
06716    }
06717    if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){
06718       if(debug)
06719          printf("Clarifier off\n");
06720       simple_command_ft897(myrpt, 0x85);        /* Clarifier off if LSB or USB */
06721    }
06722    return res;
06723 }

static int set_ic706 ( struct rpt myrpt  )  [static]

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

07214 {
07215    int res = 0,i;
07216    
07217    if(debug)
07218       printf("Set to VFO A\n");
07219 
07220    if (!res)
07221       res = simple_command_ic706(myrpt,7,0);
07222 
07223 
07224    if((myrpt->remmode == REM_MODE_FM))
07225    {
07226       i = ic706_pltocode(myrpt->rxpl);
07227       if (i == -1) return -1;
07228       if(debug)
07229          printf("Select memory number\n");
07230       if (!res)
07231          res = select_mem_ic706(myrpt,i + IC706_PL_MEMORY_OFFSET);
07232       if(debug)
07233          printf("Transfer memory to VFO\n");
07234       if (!res)
07235          res = mem2vfo_ic706(myrpt);
07236    }
07237       
07238    if(debug)
07239       printf("Set to VFO\n");
07240 
07241    if (!res)
07242       res = vfo_ic706(myrpt);
07243 
07244    if(debug)
07245       printf("Modulation mode\n");
07246 
07247    if (!res)
07248       res = set_mode_ic706(myrpt, myrpt->remmode);    /* Modulation mode */
07249 
07250    if(debug)
07251       printf("Split off\n");
07252 
07253    if(!res)
07254       simple_command_ic706(myrpt, 0x82,0);         /* Split off */
07255 
07256    if(debug)
07257       printf("Frequency\n");
07258 
07259    if(!res)
07260       res = set_freq_ic706(myrpt, myrpt->freq);    /* Frequency */
07261    if((myrpt->remmode == REM_MODE_FM)){
07262       if(debug)
07263          printf("Offset\n");
07264       if(!res)
07265          res = set_offset_ic706(myrpt, myrpt->offset);   /* Offset if FM */
07266       if(!res){
07267          if(debug)
07268             printf("CTCSS mode\n");
07269          res = set_ctcss_mode_ic706(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */
07270       }
07271    }
07272    return res;
07273 }

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

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

06579 {
06580    unsigned char cmdstr[5];
06581    
06582    memset(cmdstr, 0, 5);
06583    
06584    switch(newmode){
06585       case  REM_MODE_FM:
06586          cmdstr[0] = 0x08;
06587          break;
06588 
06589       case  REM_MODE_USB:
06590          cmdstr[0] = 0x01;
06591          break;
06592 
06593       case  REM_MODE_LSB:
06594          cmdstr[0] = 0x00;
06595          break;
06596 
06597       case  REM_MODE_AM:
06598          cmdstr[0] = 0x04;
06599          break;
06600       
06601       default:
06602          return -1;
06603    }
06604    cmdstr[4] = 0x07; 
06605 
06606    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06607 }

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

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

07068 {
07069    unsigned char c;
07070    
07071    switch(newmode){
07072       case  REM_MODE_FM:
07073          c = 5;
07074          break;
07075 
07076       case  REM_MODE_USB:
07077          c = 1;
07078          break;
07079 
07080       case  REM_MODE_LSB:
07081          c = 0;
07082          break;
07083 
07084       case  REM_MODE_AM:
07085          c = 2;
07086          break;
07087       
07088       default:
07089          return -1;
07090    }
07091    return simple_command_ic706(myrpt,6,c);
07092 }

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

Definition at line 6548 of file app_rpt.c.

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

Referenced by set_ft897().

06549 {
06550    unsigned char cmdstr[5];
06551    
06552    memset(cmdstr, 0, 5);
06553 
06554    switch(offset){
06555       case  REM_SIMPLEX:
06556          cmdstr[0] = 0x89;
06557          break;
06558 
06559       case  REM_MINUS:
06560          cmdstr[0] = 0x09;
06561          break;
06562       
06563       case  REM_PLUS:
06564          cmdstr[0] = 0x49;
06565          break;   
06566 
06567       default:
06568          return -1;
06569    }
06570 
06571    cmdstr[4] = 0x09; 
06572 
06573    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06574 }

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

Definition at line 7040 of file app_rpt.c.

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

Referenced by set_ic706().

07041 {
07042    unsigned char c;
07043 
07044    switch(offset){
07045       case  REM_SIMPLEX:
07046          c = 0x10;
07047          break;
07048 
07049       case  REM_MINUS:
07050          c = 0x11;
07051          break;
07052       
07053       case  REM_PLUS:
07054          c = 0x12;
07055          break;   
07056 
07057       default:
07058          return -1;
07059    }
07060 
07061    return simple_command_ic706(myrpt,0x0f,c);
07062 
07063 }

static int setkenwood ( struct rpt myrpt  )  [static]

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

06091 {
06092 char rxstr[RAD_SERIAL_BUFLEN],txstr[RAD_SERIAL_BUFLEN],freq[20];
06093 char mhz[MAXREMSTR],offset[20],band,decimals[MAXREMSTR],band1,band2;
06094    
06095 int offsets[] = {0,2,1};
06096 int powers[] = {2,1,0};
06097 
06098    if (sendrxkenwood(myrpt,"VMC 0,0\r",rxstr,"VMC") < 0) return -1;
06099    split_freq(mhz, decimals, myrpt->freq);
06100    if (atoi(mhz) > 400)
06101    {
06102       band = '6';
06103       band1 = '1';
06104       band2 = '5';
06105       strcpy(offset,"005000000");
06106    }
06107    else
06108    {
06109       band = '2';
06110       band1 = '0';
06111       band2 = '2';
06112       strcpy(offset,"000600000");
06113    }
06114    strcpy(freq,"000000");
06115    strncpy(freq,decimals,strlen(decimals));
06116    sprintf(txstr,"VW %c,%05d%s,0,%d,0,%d,%d,,%02d,,%02d,%s\r",
06117       band,atoi(mhz),freq,offsets[(int)myrpt->offset],
06118       (myrpt->txplon != 0),(myrpt->rxplon != 0),
06119       kenwood_pltocode(myrpt->txpl),kenwood_pltocode(myrpt->rxpl),
06120       offset);
06121    if (sendrxkenwood(myrpt,txstr,rxstr,"VW") < 0) return -1;
06122    sprintf(txstr,"RBN %c\r",band2);
06123    if (sendrxkenwood(myrpt,txstr,rxstr,"RBN") < 0) return -1;
06124    sprintf(txstr,"PC %c,%d\r",band1,powers[(int)myrpt->powerlevel]);
06125    if (sendrxkenwood(myrpt,txstr,rxstr,"PC") < 0) return -1;
06126    return 0;
06127 }

static int setrbi ( struct rpt myrpt  )  [static]

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

06130 {
06131 char tmp[MAXREMSTR] = "",*s;
06132 unsigned char rbicmd[5];
06133 int   band,txoffset = 0,txpower = 0,rxpl;
06134 
06135    /* must be a remote system */
06136    if (!myrpt->remote) return(0);
06137    /* must have rbi hardware */
06138    if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0);
06139    if (setrbi_check(myrpt) == -1) return(-1);
06140    strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
06141    s = strchr(tmp,'.');
06142    /* if no decimal, is invalid */
06143    
06144    if (s == NULL){
06145       if(debug)
06146          printf("@@@@ Frequency needs a decimal\n");
06147       return -1;
06148    }
06149    
06150    *s++ = 0;
06151    if (strlen(tmp) < 2){
06152       if(debug)
06153          printf("@@@@ Bad MHz digits: %s\n", tmp);
06154       return -1;
06155    }
06156     
06157    if (strlen(s) < 3){
06158       if(debug)
06159          printf("@@@@ Bad KHz digits: %s\n", s);
06160       return -1;
06161    }
06162 
06163    if ((s[2] != '0') && (s[2] != '5')){
06164       if(debug)
06165          printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
06166       return -1;
06167    }
06168     
06169    band = rbi_mhztoband(tmp);
06170    if (band == -1){
06171       if(debug)
06172          printf("@@@@ Bad Band: %s\n", tmp);
06173       return -1;
06174    }
06175    
06176    rxpl = rbi_pltocode(myrpt->rxpl);
06177    
06178    if (rxpl == -1){
06179       if(debug)
06180          printf("@@@@ Bad TX PL: %s\n", myrpt->rxpl);
06181       return -1;
06182    }
06183 
06184    
06185    switch(myrpt->offset)
06186    {
06187        case REM_MINUS:
06188       txoffset = 0;
06189       break;
06190        case REM_PLUS:
06191       txoffset = 0x10;
06192       break;
06193        case REM_SIMPLEX:
06194       txoffset = 0x20;
06195       break;
06196    }
06197    switch(myrpt->powerlevel)
06198    {
06199        case REM_LOWPWR:
06200       txpower = 0;
06201       break;
06202        case REM_MEDPWR:
06203       txpower = 0x20;
06204       break;
06205        case REM_HIPWR:
06206       txpower = 0x10;
06207       break;
06208    }
06209    rbicmd[0] = 0;
06210    rbicmd[1] = band | txpower | 0xc0;
06211    rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80;
06212    if (s[2] == '5') rbicmd[2] |= 0x40;
06213    rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0');
06214    rbicmd[4] = rxpl;
06215    if (myrpt->txplon) rbicmd[4] |= 0x40;
06216    if (myrpt->rxplon) rbicmd[4] |= 0x80;
06217    rbi_out(myrpt,rbicmd);
06218    return 0;
06219 }

static int setrbi_check ( struct rpt myrpt  )  [static]

Definition at line 6221 of file app_rpt.c.

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

Referenced by setrbi(), and setrem().

06222 {
06223 char tmp[MAXREMSTR] = "",*s;
06224 int   band,txpl;
06225 
06226    /* must be a remote system */
06227    if (!myrpt->remote) return(0);
06228    /* must have rbi hardware */
06229    if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0);
06230    strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
06231    s = strchr(tmp,'.');
06232    /* if no decimal, is invalid */
06233    
06234    if (s == NULL){
06235       if(debug)
06236          printf("@@@@ Frequency needs a decimal\n");
06237       return -1;
06238    }
06239    
06240    *s++ = 0;
06241    if (strlen(tmp) < 2){
06242       if(debug)
06243          printf("@@@@ Bad MHz digits: %s\n", tmp);
06244       return -1;
06245    }
06246     
06247    if (strlen(s) < 3){
06248       if(debug)
06249          printf("@@@@ Bad KHz digits: %s\n", s);
06250       return -1;
06251    }
06252 
06253    if ((s[2] != '0') && (s[2] != '5')){
06254       if(debug)
06255          printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
06256       return -1;
06257    }
06258     
06259    band = rbi_mhztoband(tmp);
06260    if (band == -1){
06261       if(debug)
06262          printf("@@@@ Bad Band: %s\n", tmp);
06263       return -1;
06264    }
06265    
06266    txpl = rbi_pltocode(myrpt->txpl);
06267    
06268    if (txpl == -1){
06269       if(debug)
06270          printf("@@@@ Bad TX PL: %s\n", myrpt->txpl);
06271       return -1;
06272    }
06273    return 0;
06274 }

static int setrem ( struct rpt myrpt  )  [static]

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

07340 {
07341 char  str[300];
07342 char  *offsets[] = {"MINUS","SIMPLEX","PLUS"};
07343 char  *powerlevels[] = {"LOW","MEDIUM","HIGH"};
07344 char  *modes[] = {"FM","USB","LSB","AM"};
07345 int   res = -1;
07346 
07347    if (myrpt->p.archivedir)
07348    {
07349       sprintf(str,"FREQ,%s,%s,%s,%s,%s,%s,%d,%d",myrpt->freq,
07350          modes[(int)myrpt->remmode],
07351          myrpt->txpl,myrpt->rxpl,offsets[(int)myrpt->offset],
07352          powerlevels[(int)myrpt->powerlevel],myrpt->txplon,
07353          myrpt->rxplon);
07354       donodelog(myrpt,str);
07355    }
07356    if(!strcmp(myrpt->remote, remote_rig_ft897))
07357    {
07358       rpt_telemetry(myrpt,SETREMOTE,NULL);
07359       res = 0;
07360    }
07361    if(!strcmp(myrpt->remote, remote_rig_ic706))
07362    {
07363       rpt_telemetry(myrpt,SETREMOTE,NULL);
07364       res = 0;
07365    }
07366    else if(!strcmp(myrpt->remote, remote_rig_rbi))
07367    {
07368       res = setrbi_check(myrpt);
07369       if (!res)
07370       {
07371          rpt_telemetry(myrpt,SETREMOTE,NULL);
07372          res = 0;
07373       }
07374    }
07375    else if(!strcmp(myrpt->remote, remote_rig_kenwood)) {
07376       rpt_telemetry(myrpt,SETREMOTE,NULL);
07377       res = 0;
07378    }
07379    else
07380       res = 0;
07381 
07382    if (res < 0) ast_log(LOG_ERROR,"Unable to send remote command on node %s\n",myrpt->name);
07383 
07384    return res;
07385 }

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

Definition at line 6534 of file app_rpt.c.

References serial_remote_io().

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

06535 {
06536    unsigned char cmdstr[5];
06537    
06538    memset(cmdstr, 0, 5);
06539 
06540    cmdstr[4] = command; 
06541 
06542    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06543 
06544 }

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

Definition at line 6988 of file app_rpt.c.

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

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

06989 {
06990    unsigned char cmdstr[10];
06991    
06992    cmdstr[0] = cmdstr[1] = 0xfe;
06993    cmdstr[2] = myrpt->p.civaddr;
06994    cmdstr[3] = 0xe0;
06995    cmdstr[4] = command;
06996    cmdstr[5] = subcommand;
06997    cmdstr[6] = 0xfd;
06998 
06999    return(civ_cmd(myrpt,cmdstr,7));
07000 }

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

Definition at line 1498 of file app_rpt.c.

Referenced by function_autopatchup().

01499 {
01500 int i;   
01501    while(*string){
01502       for(i = 0; charlist[i] ; i++){
01503          if(*string == charlist[i]){
01504             string++;
01505             break;
01506          }
01507       }
01508       if(!charlist[i])
01509          return string;
01510    }
01511    return string;
01512 }  

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

Definition at line 6387 of file app_rpt.c.

References MAXREMSTR.

Referenced by set_ctcss_freq_ft897().

06388 {
06389    char freq_copy[MAXREMSTR];
06390    char *decp;
06391 
06392    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
06393    if(decp){
06394       *decp++ = 0;
06395       strncpy(hertz, freq_copy, MAXREMSTR);
06396       strncpy(decimal, decp, strlen(decp));
06397       decimal[strlen(decp)] = '\0';
06398       return 0;
06399    }
06400    else
06401       return -1;
06402 }

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

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

06365 {
06366    char freq_copy[MAXREMSTR];
06367    char *decp;
06368 
06369    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
06370    if(decp){
06371       *decp++ = 0;
06372       strncpy(mhz, freq_copy, MAXREMSTR);
06373       strcpy(decimals, "00000");
06374       strncpy(decimals, decp, strlen(decp));
06375       decimals[5] = 0;
06376       return 0;
06377    }
06378    else
06379       return -1;
06380 
06381 }

static void stop_scan ( struct rpt myrpt  )  [static]

Definition at line 7563 of file app_rpt.c.

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

Referenced by handle_remote_dtmf_digit().

07564 {
07565    myrpt->hfscanstop = 1;
07566    rpt_telemetry(myrpt,SCAN,0);
07567 }

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

Definition at line 2712 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and telem_lookup().

02713 {
02714    int res;
02715    char c;
02716    
02717    static int morsespeed;
02718    static int morsefreq;
02719    static int morseampl;
02720    static int morseidfreq = 0;
02721    static int morseidampl;
02722    static char mcat[] = MORSE;
02723    
02724    res = 0;
02725    
02726    if(!morseidfreq){ /* Get the morse parameters if not already loaded */
02727       morsespeed = retrieve_astcfgint(myrpt, mcat, "speed", 5, 20, 20);
02728          morsefreq = retrieve_astcfgint(myrpt, mcat, "frequency", 300, 3000, 800);
02729          morseampl = retrieve_astcfgint(myrpt, mcat, "amplitude", 200, 8192, 4096);
02730       morseidampl = retrieve_astcfgint(myrpt, mcat, "idamplitude", 200, 8192, 2048);
02731       morseidfreq = retrieve_astcfgint(myrpt, mcat, "idfrequency", 300, 3000, 330); 
02732    }
02733    
02734    /* Is it a file, or a tone sequence? */
02735          
02736    if(entry[0] == '|'){
02737       c = entry[1];
02738       if((c >= 'a')&&(c <= 'z'))
02739          c -= 0x20;
02740    
02741       switch(c){
02742          case 'I': /* Morse ID */
02743             res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl);
02744             break;
02745          
02746          case 'M': /* Morse Message */
02747             res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl);
02748             break;
02749          
02750          case 'T': /* Tone sequence */
02751             res = send_tone_telemetry(chan, entry + 2);
02752             break;
02753          default:
02754             res = -1;
02755       }
02756    }
02757    else
02758       res = sayfile(chan, entry); /* File */
02759    return res;
02760 }

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

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

02769 {
02770    
02771    int res;
02772    int i;
02773    char *entry;
02774    char *telemetry;
02775    char *telemetry_save;
02776 
02777    res = 0;
02778    telemetry_save = NULL;
02779    entry = NULL;
02780    
02781    /* Retrieve the section name for telemetry from the node section */
02782    telemetry = (char *) ast_variable_retrieve(myrpt->cfg, node, TELEMETRY);
02783    if(telemetry ){
02784       telemetry_save = ast_strdupa(telemetry);
02785       if(!telemetry_save){
02786          ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n");
02787          return res;
02788       }
02789       entry = (char *) ast_variable_retrieve(myrpt->cfg, telemetry_save, name);
02790    }
02791    
02792    /* Try to look up the telemetry name */   
02793 
02794    if(!entry){
02795       /* Telemetry name wasn't found in the config file, use the default */
02796       for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
02797          if(!strcasecmp(tele_defs[i].name, name))
02798             entry = tele_defs[i].value;
02799       }
02800    }
02801    if(entry){  
02802       if(strlen(entry))
02803          telem_any(myrpt,chan, entry);
02804    }
02805    else{
02806       res = -1;
02807    }
02808    return res;
02809 }

static int unload_module ( void   )  [static]

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

11838 {
11839    int i;
11840 
11841 #ifdef   OLD_ASTERISK
11842    STANDARD_HANGUP_LOCALUSERS;
11843 #endif
11844    for(i = 0; i < nrpts; i++) {
11845       if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue;
11846                 ast_mutex_destroy(&rpt_vars[i].lock);
11847                 ast_mutex_destroy(&rpt_vars[i].remlock);
11848    }
11849    i = ast_unregister_application(app);
11850 
11851    /* Unregister cli extensions */
11852    ast_cli_unregister(&cli_debug);
11853    ast_cli_unregister(&cli_dump);
11854    ast_cli_unregister(&cli_stats);
11855    ast_cli_unregister(&cli_lstats);
11856    ast_cli_unregister(&cli_nodes);
11857    ast_cli_unregister(&cli_reload);
11858    ast_cli_unregister(&cli_restart);
11859    ast_cli_unregister(&cli_fun);
11860 
11861    return i;
11862 }

static int vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7172 of file app_rpt.c.

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

Referenced by set_ic706().

07173 {
07174    unsigned char cmdstr[10];
07175    
07176    cmdstr[0] = cmdstr[1] = 0xfe;
07177    cmdstr[2] = myrpt->p.civaddr;
07178    cmdstr[3] = 0xe0;
07179    cmdstr[4] = 7;
07180    cmdstr[5] = 0xfd;
07181 
07182    return(civ_cmd(myrpt,cmdstr,6));
07183 }

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

Definition at line 2887 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

02888 {
02889    int interval;
02890    interval = get_wait_interval(myrpt, type);
02891    if(debug)
02892       ast_log(LOG_NOTICE," Delay interval = %d\n", interval);
02893    if(interval)
02894       ast_safe_sleep(chan,interval);
02895    if(debug)
02896       ast_log(LOG_NOTICE,"Delay complete\n");
02897    return;
02898 }


Variable Documentation

char* app = "Rpt" [static]

Definition at line 311 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 932 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 936 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 960 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 948 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 944 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 952 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 956 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 940 of file app_rpt.c.

Referenced by load_module(), and unload_module().

int debug = 0 [static]

Definition at line 350 of file app_rpt.c.

Referenced by add_sdp(), add_t38_sdp(), aji_load_config(), check_user_full(), handle_request(), process_sdp(), 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 899 of file app_rpt.c.

char* descrip [static]

Definition at line 315 of file app_rpt.c.

char* discstr = "!!DISCONNECT!!"

Definition at line 370 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 911 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 915 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 907 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 903 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 927 of file app_rpt.c.

struct function_table_tag function_table[] [static]

Definition at line 1011 of file app_rpt.c.

Referenced by collect_function_digits().

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

Definition at line 357 of file app_rpt.c.

int nrpts = 0 [static]

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

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

Definition at line 353 of file app_rpt.c.

char* remote_rig_ft897 = "ft897" [static]

Definition at line 371 of file app_rpt.c.

char* remote_rig_ic706 = "ic706" [static]

Definition at line 374 of file app_rpt.c.

char* remote_rig_kenwood = "kenwood" [static]

Definition at line 373 of file app_rpt.c.

char* remote_rig_rbi = "rbi" [static]

Definition at line 372 of file app_rpt.c.

char restart_usage[] [static]

Initial value:

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

Definition at line 923 of file app_rpt.c.

pthread_t rpt_master_thread [static]

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

Referenced by tzparse(), and wait_for_answer().

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

Definition at line 313 of file app_rpt.c.

char* tdesc = "Radio Repeater / Remote Base version 0.73 09/04/2007" [static]

Definition at line 309 of file app_rpt.c.

struct telem_defaults tele_defs[] [static]

Definition at line 969 of file app_rpt.c.

Referenced by telem_lookup().


Generated on Mon Nov 24 15:34:24 2008 for Asterisk - the Open Source PBX by  doxygen 1.4.7