Fri Sep 25 19:28:19 2009

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 <zaptel/zaptel.h>
#include <zaptel/tonezone.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
#include "asterisk/cdr.h"
#include <termios.h>

Include dependency graph for app_rpt.c:

Go to the source code of this file.

Data Structures

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

Defines

#define ACTIONSIZE   32
#define 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.

Referenced by rpt_exec().

#define AUTHTELLTIME   7000

Definition at line 165 of file app_rpt.c.

Referenced by rpt_exec().

#define AUTHTXTIME   1000

Definition at line 166 of file app_rpt.c.

Referenced by rpt_exec().

#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 392 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 386 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 388 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(), and rpt_exec().

#define MACROTIME   100

Definition at line 160 of file app_rpt.c.

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

#define MAX_RETRIES   5

Definition at line 174 of file app_rpt.c.

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

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

Referenced by rpt_do_stats().

#define MAX_SYSSTATES   10

Definition at line 397 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

#define MAXLINKLIST   512

#define MAXMACRO   2048

Definition at line 156 of file app_rpt.c.

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

#define MAXNODESTR   300

Definition at line 214 of file app_rpt.c.

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

#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

#define MAXRPTS   20

Definition at line 389 of file app_rpt.c.

#define MAXXLAT   20

Definition at line 394 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXXLATTIME   3

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

Referenced by rpt_exec().

#define MORSE   "morse"

Definition at line 203 of file app_rpt.c.

Referenced by telem_any().

#define MSWAIT   200

Definition at line 385 of file app_rpt.c.

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

#define NODES   "nodes"

Definition at line 197 of file app_rpt.c.

Referenced by load_rpt_vars().

#define NRPTSTAT   7

Definition at line 363 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 391 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(), and rpt_exec().

#define REM_SCANTIME   100

Definition at line 222 of file app_rpt.c.

Referenced by function_remote(), and rpt_exec().

#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)

#define rpt_mutex_unlock (  )     ast_mutex_unlock(x)

#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 387 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 359 of file app_rpt.c.


Function Documentation

static void __kickshort ( struct rpt myrpt  )  [static]

Definition at line 1397 of file app_rpt.c.

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

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

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

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

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

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

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

AST_MUTEX_DEFINE_STATIC ( nodelookuplock   ) 

AST_MUTEX_DEFINE_STATIC ( nodeloglock   ) 

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

Definition at line 212 of file indications.c.

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

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 8408 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().

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

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

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

07408 {
07409    if(!strcmp(myrpt->remote, remote_rig_ft897))
07410       return check_freq_ft897(m, d, defmode);
07411    else if(!strcmp(myrpt->remote, remote_rig_ic706))
07412       return check_freq_ic706(m, d, defmode);
07413    else if(!strcmp(myrpt->remote, remote_rig_rbi))
07414       return check_freq_rbi(m, d, defmode);
07415    else if(!strcmp(myrpt->remote, remote_rig_kenwood))
07416       return check_freq_kenwood(m, d, defmode);
07417    else
07418       return -1;
07419 }

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

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

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

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

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

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

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

Definition at line 6284 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

06285 {
06286    int dflmd = REM_MODE_FM;
06287 
06288    if (m == 144){ /* 2 meters */
06289       if(d < 10100)
06290          return -1;
06291    }
06292    else if((m >= 145) && (m < 148)){
06293       ;
06294    }
06295    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
06296       ;
06297    }
06298    else
06299       return -1;
06300    
06301    if(defmode)
06302       *defmode = dflmd; 
06303 
06304 
06305    return 0;
06306 }

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

Definition at line 6312 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

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

static char check_tx_freq ( struct rpt myrpt  )  [static]

Definition at line 7425 of file app_rpt.c.

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

Referenced by rpt_exec().

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

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

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

05961 {
05962 unsigned char rxbuf[100];
05963 int   i,rv ;
05964 
05965    rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0);
05966    if (rv == -1) return(-1);
05967    if (rv != (cmdlen + 6)) return(1);
05968    for(i = 0; i < 6; i++)
05969       if (rxbuf[i] != cmd[i]) return(1);
05970    if (rxbuf[cmdlen] != 0xfe) return(1);
05971    if (rxbuf[cmdlen + 1] != 0xfe) return(1);
05972    if (rxbuf[cmdlen + 4] != 0xfb) return(1);
05973    if (rxbuf[cmdlen + 5] != 0xfd) return(1);
05974    return(0);
05975 }

static int closerem ( struct rpt myrpt  )  [static]

Definition at line 7395 of file app_rpt.c.

References closerem_ft897(), and rpt::remote.

Referenced by rpt_exec().

07396 {
07397    if(!strcmp(myrpt->remote, remote_rig_ft897))
07398       return closerem_ft897(myrpt);
07399    else
07400       return 0;
07401 }

static int closerem_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6733 of file app_rpt.c.

References simple_command_ft897().

Referenced by closerem().

06734 {
06735    simple_command_ft897(myrpt, 0x88); /* PTT off */
06736    return 0;
06737 }  

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

Definition at line 5230 of file app_rpt.c.

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

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

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

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

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

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

static int decimals2int ( char *  fraction  )  [static]

Definition at line 6353 of file app_rpt.c.

Referenced by check_tx_freq().

06354 {
06355    int i;
06356    char len = strlen(fraction);
06357    int multiplier = 100000;
06358    int res = 0;
06359 
06360    if(!len)
06361       return 0;
06362    for( i = 0 ; i < len ; i++, multiplier /= 10)
06363       res += (fraction[i] - '0') * multiplier;
06364    return res;
06365 }

static long diskavail ( struct rpt myrpt  )  [static]

Definition at line 1025 of file app_rpt.c.

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

Referenced by rpt(), and rpt_exec().

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

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

Definition at line 1090 of file app_rpt.c.

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

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

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

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

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

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

static void do_scheduler ( struct rpt myrpt  )  [static]

Definition at line 8643 of file app_rpt.c.

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

Referenced by rpt().

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

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

Definition at line 1065 of file app_rpt.c.

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

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

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

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

Definition at line 1288 of file app_rpt.c.

Referenced by check_tx_freq().

01289 {
01290    while((*s == ' ') || (*s == 0x09)){ /* get rid of any leading white space */
01291       if(!*s)
01292          break;
01293       s++;
01294    }
01295    return s;
01296 }

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

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

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

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

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

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

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

Definition at line 5001 of file app_rpt.c.

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

05002 {
05003    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
05004       return DC_ERROR;
05005    
05006    if(debug)
05007       printf("@@@@ Autopatch down\n");
05008       
05009    rpt_mutex_lock(&myrpt->lock);
05010    
05011    if (!myrpt->callmode){
05012       rpt_mutex_unlock(&myrpt->lock);
05013       return DC_COMPLETE;
05014    }
05015    
05016    myrpt->callmode = 0;
05017    rpt_mutex_unlock(&myrpt->lock);
05018    rpt_telemetry(myrpt, TERM, NULL);
05019    return DC_COMPLETE;
05020 }

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

Definition at line 4904 of file app_rpt.c.

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

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

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

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

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

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

Definition at line 4646 of file app_rpt.c.

References AST_FRAME_TEXT, ast_log(), ast_safe_sleep(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt_link::chan, rpt::cmdnode, COMPLETE, connect_link(), CONNFAIL, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt_link::disced, do_dtmf_local(), finddelim(), ast_frame::frametype, FULLSTATUS, rpt::lastlinknode, LASTNODEKEY, sysstate::linkfundisable, rpt::links, rpt::lock, LOG_NOTICE, rpt::longestnode, ast_frame::mallocd, MAX_RETRIES, rpt_link::max_retries, MAXLINKLIST, MAXNODESTR, 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, rpt::sysstate_cur, and sysstate::txdisable.

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

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

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

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

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

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

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

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

Definition at line 5026 of file app_rpt.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

Referenced by rpt_exec().

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

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

Definition at line 8224 of file app_rpt.c.

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

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

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

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

Definition at line 8383 of file app_rpt.c.

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

Referenced by rpt_exec().

08384 {
08385 int   res;
08386 
08387 
08388    if (keyed && *keyed && (c == myrpt->p.endchar))
08389    {
08390       *keyed = 0;
08391       return DC_INDETERMINATE;
08392    }
08393 
08394    if (myrpt->p.archivedir)
08395    {
08396       char str[100];
08397 
08398       sprintf(str,"DTMF(P),%c",c);
08399       donodelog(myrpt,str);
08400    }
08401    res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode);
08402    if (res != 1)
08403       return res;
08404    rpt_telemetry(myrpt,COMPLETE,NULL);
08405    return 0;
08406 }

static int ic706_pltocode ( char *  str  )  [static]

Definition at line 6879 of file app_rpt.c.

References s.

Referenced by set_ic706().

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

static int kenwood_pltocode ( char *  str  )  [static]

Definition at line 5992 of file app_rpt.c.

References s.

Referenced by setkenwood().

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

static int load_module ( void   )  [static]

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

Definition at line 1622 of file app_rpt.c.

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

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

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

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

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

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

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

Definition at line 1478 of file app_rpt.c.

Referenced by function_autopatchup().

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

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

Definition at line 1192 of file app_rpt.c.

References ast_verbose(), and rpt::name.

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

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

static int mem2vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7193 of file app_rpt.c.

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

Referenced by set_ic706().

07194 {
07195    unsigned char cmdstr[10];
07196    
07197    cmdstr[0] = cmdstr[1] = 0xfe;
07198    cmdstr[2] = myrpt->p.civaddr;
07199    cmdstr[3] = 0xe0;
07200    cmdstr[4] = 0x0a;
07201    cmdstr[5] = 0xfd;
07202 
07203    return(civ_cmd(myrpt,cmdstr,6));
07204 }

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

Definition at line 7556 of file app_rpt.c.

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

Referenced by function_remote(), and service_scan().

07557 {
07558    if(!strcmp(myrpt->remote, remote_rig_ft897))
07559       return multimode_bump_freq_ft897(myrpt, interval);
07560    else if(!strcmp(myrpt->remote, remote_rig_ic706))
07561       return multimode_bump_freq_ic706(myrpt, interval);
07562    else
07563       return -1;
07564 }

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

Definition at line 6745 of file app_rpt.c.

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

Referenced by multimode_bump_freq().

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

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

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

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

static int multimode_capable ( struct rpt myrpt  )  [static]

Definition at line 880 of file app_rpt.c.

References rpt::remote.

Referenced by function_remote(), and rpt_tele_thread().

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

static int myatoi ( char *  str  )  [static]

Definition at line 1520 of file app_rpt.c.

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

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

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

Definition at line 1530 of file app_rpt.c.

Referenced by rpt_do_nodes(), and rpt_tele_thread().

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

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

Definition at line 1410 of file app_rpt.c.

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

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

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

static int openserial ( char *  fname  )  [static]

Definition at line 1156 of file app_rpt.c.

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

Referenced by rpt_exec().

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

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

Definition at line 2462 of file app_rpt.c.

References play_tone_pair().

Referenced by send_morse().

02463 {
02464    return play_tone_pair(chan, 0, 0, duration, 0);
02465 }

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

Definition at line 2457 of file app_rpt.c.

References play_tone_pair().

Referenced by rpt_tele_thread(), and send_morse().

02458 {
02459    return play_tone_pair(chan, freq, 0, duration, amplitude);
02460 }

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

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

02444 {
02445    int res;
02446 
02447         if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude)))
02448                 return res;
02449                                                                                                                                             
02450         while(chan->generatordata) {
02451       if (ast_safe_sleep(chan,1)) return -1;
02452    }
02453 
02454         return 0;
02455 }

static void queue_id ( struct rpt myrpt  )  [static]

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

08630 {
08631    if(myrpt->p.idtime){ /* ID time must be non-zero */
08632       myrpt->mustid = myrpt->tailid = 0;
08633       myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */
08634       rpt_mutex_unlock(&myrpt->lock);
08635       rpt_telemetry(myrpt,ID,NULL);
08636       rpt_mutex_lock(&myrpt->lock);
08637    }
08638 }

static int rbi_mhztoband ( char *  str  )  [static]

Definition at line 5693 of file app_rpt.c.

Referenced by setrbi(), and setrbi_check().

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

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

Definition at line 5852 of file app_rpt.c.

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

Referenced by setrbi().

05853 {
05854 struct zt_radio_param r;
05855 
05856    memset(&r,0,sizeof(struct zt_radio_param));
05857    r.radpar = ZT_RADPAR_REMMODE;
05858    r.data = ZT_RADPAR_REM_RBI1;
05859    /* if setparam ioctl fails, its probably not a pciradio card */
05860    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
05861    {
05862       rbi_out_parallel(myrpt,data);
05863       return;
05864    }
05865    r.radpar = ZT_RADPAR_REMCOMMAND;
05866    memcpy(&r.data,data,5);
05867    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1)
05868    {
05869       ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->zaprxchannel->name);
05870       return;
05871    }
05872 }

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

Definition at line 5824 of file app_rpt.c.

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

Referenced by rbi_out().

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

static int rbi_pltocode ( char *  str  )  [static]

Definition at line 5729 of file app_rpt.c.

References s.

Referenced by setrbi(), and setrbi_check().

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

static int reload ( void   )  [static]

Definition at line 11914 of file app_rpt.c.

References reload(), and rpt_vars.

11916 {
11917 int   n;
11918 
11919    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
11920    return(0);
11921 }

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

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

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

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

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

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

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

Definition at line 8763 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, ast_channel::fds, ast_frame::frametype, free, func_xlat(), handle_link_data(), handle_link_phone_dtmf(), rpt::hangtime, rpt_link::hasconnected, ID, IDTALKOVER, rpt::idtime, rpt::idtimer, rpt::inxlat, rpt_link::isremote, rpt::keyed, rpt_link::killme, rpt::lastdtmfcommand, rpt_link::lastf1, rpt::lastf1, rpt_link::lastf2, rpt::lastf2, rpt::lastnodewhichkeyedusup, rpt_link::lastrx, rpt_link::lastrx1, rpt_link::lasttx, LINKLISTTIME, rpt_link::linklisttimer, rpt::links, rpt::linktolink, LINKUNKEY, load_rpt_vars(), local_dtmf_helper(), rpt::localtx, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macrobuf, MACROPTIME, MACROTIME, rpt::macrotimer, ast_frame::mallocd, rpt_link::max_retries, MAXCONNECTTIME, MAXLINKLIST, MAXMACRO, 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, ast_frame::offset, option_verbose, rpt_link::outbound, rpt::p, rpt_link::pchan, rpt::pchannel, rpt_link::phonemode, rpt::politeid, rpt_link::prev, queue_id(), rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, REMDISC, rpt_link::rerxtimer, rpt::rerxtimer, rpt_link::retries, RETRY_TIMER_MS, rpt_link::retrytimer, rpt_link::retxtimer, rpt::retxtimer, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, rpt::rxchannel, s, rpt::s, ast_frame::samples, rpt::scram, rpt::skedtimer, START_DELAY, rpt::startupmacro, ast_frame::subclass, rpt::sysstate_cur, rpt::tailevent, rpt::tailid, rpt::tailmessages, rpt::tailmessagetime, TAILMSG, rpt::tailtimer, rpt::tele, rpt_link::thisconnected, TIMEOUT, rpt::timeouts, rpt::tmsgtimer, rpt::tonotify, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, sysstate::totdisable, rpt::totime, rpt::totimer, rpt::tounkeyed, rpt::txchanname, rpt::txchannel, rpt::txconf, sysstate::txdisable, rpt::txpchannel, UNKEY, VERBOSE_PREFIX_3, ast_channel::whentohangup, rpt::zaprxchannel, and rpt::zaptxchannel.

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

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

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

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

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

Definition at line 1972 of file app_rpt.c.

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

01973 {
01974    int newlevel;
01975 
01976         if (argc != 4)
01977                 return RESULT_SHOWUSAGE;
01978         newlevel = myatoi(argv[3]);
01979         if((newlevel < 0) || (newlevel > 7))
01980                 return RESULT_SHOWUSAGE;
01981         if(newlevel)
01982                 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
01983         else
01984                 ast_cli(fd, "app_rpt Debugging disabled\n");
01985 
01986         debug = newlevel;                                                                                                                          
01987         return RESULT_SUCCESS;
01988 }

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

Definition at line 1994 of file app_rpt.c.

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

01995 {
01996    int i;
01997 
01998         if (argc != 3)
01999                 return RESULT_SHOWUSAGE;
02000 
02001    for(i = 0; i < nrpts; i++)
02002    {
02003       if (!strcmp(argv[2],rpt_vars[i].name))
02004       {
02005          rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
02006               ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]);
02007               return RESULT_SUCCESS;
02008       }
02009    }
02010    return RESULT_FAILURE;
02011 }

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

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

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

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

Definition at line 2242 of file app_rpt.c.

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

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

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

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

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

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

Definition at line 2382 of file app_rpt.c.

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

02383 {
02384 int   n;
02385 
02386         if (argc > 2) return RESULT_SHOWUSAGE;
02387 
02388    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
02389 
02390    return RESULT_FAILURE;
02391 }

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

Definition at line 2397 of file app_rpt.c.

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

02398 {
02399 int   i;
02400 
02401         if (argc > 2) return RESULT_SHOWUSAGE;
02402    for(i = 0; i < nrpts; i++)
02403    {
02404       if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV);
02405    }
02406    return RESULT_FAILURE;
02407 }

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

Definition at line 2017 of file app_rpt.c.

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

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

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

Definition at line 10560 of file app_rpt.c.

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

Referenced by load_module().

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

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

Definition at line 1584 of file app_rpt.c.

References ast_localtime(), and localtime_r.

Referenced by do_scheduler(), and rpt_tele_thread().

01585 {
01586 #ifdef OLD_ASTERISK
01587    localtime_r(t, lt);
01588 #else
01589    ast_localtime(t, lt, NULL);
01590 #endif
01591 }

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

Definition at line 10393 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, nodelog::next, rpt_tele::next, rpt::offset, rpt::powerlevel, rpt_tele::prev, REM_MEDPWR, REM_MODE_FM, REM_SIMPLEX, rpt::remmode, rpt::remote, retreive_memory(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, space, strdup, rpt::tailmessagen, rpt::tele, rpt::threadrestarts, and rpt::txchanname.

Referenced by load_module().

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

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

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

Referenced by rpt_telemetry().

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

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

Definition at line 4121 of file app_rpt.c.

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

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

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

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

Definition at line 2694 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

02695 {
02696 int   res;
02697 
02698    res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
02699    if (!res) 
02700       res = ast_waitstream(mychannel, "");
02701    else
02702        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02703    ast_stopstream(mychannel);
02704    return res;
02705 }

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

Definition at line 2681 of file app_rpt.c.

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

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

02682 {
02683 int   res;
02684 
02685    res = ast_streamfile(mychannel, fname, mychannel->language);
02686    if (!res) 
02687       res = ast_waitstream(mychannel, "");
02688    else
02689        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02690    ast_stopstream(mychannel);
02691    return res;
02692 }

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

Definition at line 2707 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

02708 {
02709    int res;
02710    res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL);
02711    if(!res)
02712       res = ast_waitstream(mychannel, "");
02713    else
02714       ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
02715    ast_stopstream(mychannel);
02716    return res;
02717 }

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

Definition at line 7206 of file app_rpt.c.

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

Referenced by set_ic706().

07207 {
07208    unsigned char cmdstr[10];
07209    
07210    cmdstr[0] = cmdstr[1] = 0xfe;
07211    cmdstr[2] = myrpt->p.civaddr;
07212    cmdstr[3] = 0xe0;
07213    cmdstr[4] = 8;
07214    cmdstr[5] = 0;
07215    cmdstr[6] = ((slot / 10) << 4) + (slot % 10);
07216    cmdstr[7] = 0xfd;
07217 
07218    return(civ_cmd(myrpt,cmdstr,8));
07219 }

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

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

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

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

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

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

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

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

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

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

Definition at line 5977 of file app_rpt.c.

References serial_remote_io().

Referenced by sendrxkenwood().

05978 {
05979 int   i;
05980 
05981    if (debug) printf("Send to kenwood: %s\n",txstr);
05982    i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr), 
05983       (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3);
05984    if (i < 0) return -1;
05985    if ((i > 0) && (rxstr[i - 1] == '\r'))
05986       rxstr[i-- - 1] = 0;
05987    if (debug) printf("Got from kenwood: %s\n",rxstr);
05988    return(i);
05989 }

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

Definition at line 6083 of file app_rpt.c.

References KENWOOD_RETRIES, and sendkenwood().

Referenced by setkenwood().

06085 {
06086 int   i,j;
06087 
06088    for(i = 0;i < KENWOOD_RETRIES;i++)
06089    {
06090       j = sendkenwood(myrpt,txstr,rxstr);
06091       if (j < 0) return(j);
06092       if (j == 0) continue;
06093       if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0);
06094    }
06095    return(-1);
06096 }     

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

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

05876 {
05877    int i,j,index,oldmode,olddata;
05878    struct zt_radio_param prm;
05879    char c;
05880 
05881    if(debug){
05882       printf("String output was: ");
05883       for(i = 0; i < txbytes; i++)
05884          printf("%02X ", (unsigned char ) txbuf[i]);
05885       printf("\n");
05886    }
05887    if (myrpt->iofd > 0)  /* if to do out a serial port */
05888    {
05889       if (rxmaxbytes && rxbuf) tcflush(myrpt->iofd,TCIFLUSH);     
05890       if (write(myrpt->iofd,txbuf,txbytes) != txbytes) return -1;
05891       if ((!rxmaxbytes) || (rxbuf == NULL)) return(0);
05892       memset(rxbuf,0,rxmaxbytes);
05893       for(i = 0; i < rxmaxbytes; i++)
05894       {
05895          j = read(myrpt->iofd,&c,1);
05896          if (j < 1) return(i);
05897          rxbuf[i] = c;
05898          if (asciiflag & 1)
05899          {
05900             rxbuf[i + 1] = 0;
05901             if (c == '\r') break;
05902          }
05903       }              
05904       if(debug){
05905          printf("String returned was: ");
05906          for(j = 0; j < i; j++)
05907             printf("%02X ", (unsigned char ) rxbuf[j]);
05908          printf("\n");
05909       }
05910       return(i);
05911    }
05912 
05913    /* if not a zap channel, cant use pciradio stuff */
05914    if (myrpt->rxchannel != myrpt->zaprxchannel) return -1;  
05915 
05916    prm.radpar = ZT_RADPAR_UIOMODE;
05917    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
05918    oldmode = prm.data;
05919    prm.radpar = ZT_RADPAR_UIODATA;
05920    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_GETPARAM,&prm) == -1) return -1;
05921    olddata = prm.data;
05922         prm.radpar = ZT_RADPAR_REMMODE;
05923         if (asciiflag & 1)  prm.data = ZT_RADPAR_REM_SERIAL_ASCII;
05924         else prm.data = ZT_RADPAR_REM_SERIAL;
05925    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05926    if (asciiflag & 2)
05927    {
05928       i = ZT_ONHOOK;
05929       if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
05930       usleep(100000);
05931    }
05932         prm.radpar = ZT_RADPAR_REMCOMMAND;
05933         prm.data = rxmaxbytes;
05934         memcpy(prm.buf,txbuf,txbytes);
05935         prm.index = txbytes;
05936    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05937         if (rxbuf)
05938         {
05939                 *rxbuf = 0;
05940                 memcpy(rxbuf,prm.buf,prm.index);
05941         }
05942    index = prm.index;
05943         prm.radpar = ZT_RADPAR_REMMODE;
05944         prm.data = ZT_RADPAR_REM_NONE;
05945    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05946    if (asciiflag & 2)
05947    {
05948       i = ZT_OFFHOOK;
05949       if (ioctl(myrpt->zaprxchannel->fds[0],ZT_HOOK,&i) == -1) return -1;
05950    }
05951    prm.radpar = ZT_RADPAR_UIOMODE;
05952    prm.data = oldmode;
05953    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05954    prm.radpar = ZT_RADPAR_UIODATA;
05955    prm.data = olddata;
05956    if (ioctl(myrpt->zaprxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1;
05957         return(index);
05958 }

static int service_scan ( struct rpt myrpt  )  [static]

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

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

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

Definition at line 6642 of file app_rpt.c.

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

Referenced by set_ft897().

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

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

Definition at line 6619 of file app_rpt.c.

References serial_remote_io().

Referenced by set_ft897().

06620 {
06621    unsigned char cmdstr[5];
06622    
06623    memset(cmdstr, 0, 5);
06624    
06625    if(rxplon && txplon)
06626       cmdstr[0] = 0x2A; /* Encode and Decode */
06627    else if (!rxplon && txplon)
06628       cmdstr[0] = 0x4A; /* Encode only */
06629    else if (rxplon && !txplon)
06630       cmdstr[0] = 0x3A; /* Encode only */
06631    else
06632       cmdstr[0] = 0x8A; /* OFF */
06633 
06634    cmdstr[4] = 0x0A; 
06635 
06636    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06637 }

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

Definition at line 7104 of file app_rpt.c.

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

Referenced by set_ic706().

07105 {
07106    unsigned char cmdstr[10];
07107    int rv;
07108 
07109    cmdstr[0] = cmdstr[1] = 0xfe;
07110    cmdstr[2] = myrpt->p.civaddr;
07111    cmdstr[3] = 0xe0;
07112    cmdstr[4] = 0x16;
07113    cmdstr[5] = 0x42;
07114    cmdstr[6] = (txplon != 0);
07115    cmdstr[7] = 0xfd;
07116 
07117    rv = civ_cmd(myrpt,cmdstr,8);
07118    if (rv) return(-1);
07119 
07120    cmdstr[0] = cmdstr[1] = 0xfe;
07121    cmdstr[2] = myrpt->p.civaddr;
07122    cmdstr[3] = 0xe0;
07123    cmdstr[4] = 0x16;
07124    cmdstr[5] = 0x43;
07125    cmdstr[6] = (rxplon != 0);
07126    cmdstr[7] = 0xfd;
07127 
07128    return(civ_cmd(myrpt,cmdstr,8));
07129 }

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

Definition at line 6511 of file app_rpt.c.

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

Referenced by multimode_bump_freq_ft897(), and set_ft897().

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

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

Definition at line 7014 of file app_rpt.c.

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

Referenced by set_ic706().

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

static int set_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6677 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

static int set_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7221 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

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

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

06587 {
06588    unsigned char cmdstr[5];
06589    
06590    memset(cmdstr, 0, 5);
06591    
06592    switch(newmode){
06593       case  REM_MODE_FM:
06594          cmdstr[0] = 0x08;
06595          break;
06596 
06597       case  REM_MODE_USB:
06598          cmdstr[0] = 0x01;
06599          break;
06600 
06601       case  REM_MODE_LSB:
06602          cmdstr[0] = 0x00;
06603          break;
06604 
06605       case  REM_MODE_AM:
06606          cmdstr[0] = 0x04;
06607          break;
06608       
06609       default:
06610          return -1;
06611    }
06612    cmdstr[4] = 0x07; 
06613 
06614    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06615 }

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

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

07076 {
07077    unsigned char c;
07078    
07079    switch(newmode){
07080       case  REM_MODE_FM:
07081          c = 5;
07082          break;
07083 
07084       case  REM_MODE_USB:
07085          c = 1;
07086          break;
07087 
07088       case  REM_MODE_LSB:
07089          c = 0;
07090          break;
07091 
07092       case  REM_MODE_AM:
07093          c = 2;
07094          break;
07095       
07096       default:
07097          return -1;
07098    }
07099    return simple_command_ic706(myrpt,6,c);
07100 }

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

Definition at line 6556 of file app_rpt.c.

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

Referenced by set_ft897().

06557 {
06558    unsigned char cmdstr[5];
06559    
06560    memset(cmdstr, 0, 5);
06561 
06562    switch(offset){
06563       case  REM_SIMPLEX:
06564          cmdstr[0] = 0x89;
06565          break;
06566 
06567       case  REM_MINUS:
06568          cmdstr[0] = 0x09;
06569          break;
06570       
06571       case  REM_PLUS:
06572          cmdstr[0] = 0x49;
06573          break;   
06574 
06575       default:
06576          return -1;
06577    }
06578 
06579    cmdstr[4] = 0x09; 
06580 
06581    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06582 }

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

Definition at line 7048 of file app_rpt.c.

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

Referenced by set_ic706().

07049 {
07050    unsigned char c;
07051 
07052    switch(offset){
07053       case  REM_SIMPLEX:
07054          c = 0x10;
07055          break;
07056 
07057       case  REM_MINUS:
07058          c = 0x11;
07059          break;
07060       
07061       case  REM_PLUS:
07062          c = 0x12;
07063          break;   
07064 
07065       default:
07066          return -1;
07067    }
07068 
07069    return simple_command_ic706(myrpt,0x0f,c);
07070 
07071 }

static int setkenwood ( struct rpt myrpt  )  [static]

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

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

static int setrbi ( struct rpt myrpt  )  [static]

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

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

static int setrbi_check ( struct rpt myrpt  )  [static]

Definition at line 6229 of file app_rpt.c.

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

Referenced by setrbi(), and setrem().

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

static int setrem ( struct rpt myrpt  )  [static]

Definition at line 7347 of file app_rpt.c.

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

Referenced by function_remote(), and rpt_exec().

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

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

Definition at line 6542 of file app_rpt.c.

References serial_remote_io().

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

06543 {
06544    unsigned char cmdstr[5];
06545    
06546    memset(cmdstr, 0, 5);
06547 
06548    cmdstr[4] = command; 
06549 
06550    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06551 
06552 }

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

Definition at line 6996 of file app_rpt.c.

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

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

06997 {
06998    unsigned char cmdstr[10];
06999    
07000    cmdstr[0] = cmdstr[1] = 0xfe;
07001    cmdstr[2] = myrpt->p.civaddr;
07002    cmdstr[3] = 0xe0;
07003    cmdstr[4] = command;
07004    cmdstr[5] = subcommand;
07005    cmdstr[6] = 0xfd;
07006 
07007    return(civ_cmd(myrpt,cmdstr,7));
07008 }

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

Definition at line 1502 of file app_rpt.c.

Referenced by function_autopatchup().

01503 {
01504 int i;   
01505    while(*string){
01506       for(i = 0; charlist[i] ; i++){
01507          if(*string == charlist[i]){
01508             string++;
01509             break;
01510          }
01511       }
01512       if(!charlist[i])
01513          return string;
01514    }
01515    return string;
01516 }  

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

Definition at line 6395 of file app_rpt.c.

References MAXREMSTR.

Referenced by set_ctcss_freq_ft897().

06396 {
06397    char freq_copy[MAXREMSTR];
06398    char *decp;
06399 
06400    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
06401    if(decp){
06402       *decp++ = 0;
06403       strncpy(hertz, freq_copy, MAXREMSTR);
06404       strncpy(decimal, decp, strlen(decp));
06405       decimal[strlen(decp)] = '\0';
06406       return 0;
06407    }
06408    else
06409       return -1;
06410 }

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

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

06373 {
06374    char freq_copy[MAXREMSTR];
06375    char *decp;
06376 
06377    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
06378    if(decp){
06379       *decp++ = 0;
06380       strncpy(mhz, freq_copy, MAXREMSTR);
06381       strcpy(decimals, "00000");
06382       strncpy(decimals, decp, strlen(decp));
06383       decimals[5] = 0;
06384       return 0;
06385    }
06386    else
06387       return -1;
06388 
06389 }

static void stop_scan ( struct rpt myrpt  )  [static]

Definition at line 7571 of file app_rpt.c.

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

Referenced by handle_remote_dtmf_digit().

07572 {
07573    myrpt->hfscanstop = 1;
07574    rpt_telemetry(myrpt,SCAN,0);
07575 }

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

Definition at line 2720 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and telem_lookup().

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

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

Definition at line 2776 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

static int unload_module ( void   )  [static]

Definition at line 11844 of file app_rpt.c.

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

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

static int vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7180 of file app_rpt.c.

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

Referenced by set_ic706().

07181 {
07182    unsigned char cmdstr[10];
07183    
07184    cmdstr[0] = cmdstr[1] = 0xfe;
07185    cmdstr[2] = myrpt->p.civaddr;
07186    cmdstr[3] = 0xe0;
07187    cmdstr[4] = 7;
07188    cmdstr[5] = 0xfd;
07189 
07190    return(civ_cmd(myrpt,cmdstr,6));
07191 }

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

Definition at line 2895 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

02896 {
02897    int interval;
02898    interval = get_wait_interval(myrpt, type);
02899    if(debug)
02900       ast_log(LOG_NOTICE," Delay interval = %d\n", interval);
02901    if(interval)
02902       ast_safe_sleep(chan,interval);
02903    if(debug)
02904       ast_log(LOG_NOTICE,"Delay complete\n");
02905    return;
02906 }


Variable Documentation

char* app = "Rpt" [static]

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

struct ast_cli_entry cli_dump [static]

Initial value:

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

Definition at line 940 of file app_rpt.c.

struct ast_cli_entry cli_fun [static]

Initial value:

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

Definition at line 964 of file app_rpt.c.

struct ast_cli_entry cli_lstats [static]

Initial value:

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

Definition at line 952 of file app_rpt.c.

struct ast_cli_entry cli_nodes [static]

Initial value:

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

Definition at line 948 of file app_rpt.c.

struct ast_cli_entry cli_reload [static]

Initial value:

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

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

struct ast_cli_entry cli_stats [static]

Initial value:

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

Definition at line 944 of file app_rpt.c.

int debug = 0 [static]

char debug_usage[] [static]

Initial value:

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

Definition at line 903 of file app_rpt.c.

char* descrip [static]

Definition at line 319 of file app_rpt.c.

char* discstr = "!!DISCONNECT!!"

Definition at line 374 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 915 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 919 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 911 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 907 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 931 of file app_rpt.c.

Definition at line 1015 of file app_rpt.c.

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

Definition at line 361 of file app_rpt.c.

int nrpts = 0 [static]

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

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

Definition at line 357 of file app_rpt.c.

char* remote_rig_ft897 = "ft897" [static]

Definition at line 375 of file app_rpt.c.

char* remote_rig_ic706 = "ic706" [static]

Definition at line 378 of file app_rpt.c.

char* remote_rig_kenwood = "kenwood" [static]

Definition at line 377 of file app_rpt.c.

char* remote_rig_rbi = "rbi" [static]

Definition at line 376 of file app_rpt.c.

char restart_usage[] [static]

Initial value:

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

Definition at line 927 of file app_rpt.c.

pthread_t rpt_master_thread [static]

Definition at line 411 of file app_rpt.c.

struct rpt rpt_vars[MAXRPTS] [static]

time_t starttime = 0 [static]

Definition at line 409 of file app_rpt.c.

Referenced by tzparse(), and wait_for_answer().

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

Definition at line 317 of file app_rpt.c.

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

Definition at line 313 of file app_rpt.c.

struct telem_defaults tele_defs[] [static]

Definition at line 973 of file app_rpt.c.


Generated on Fri Sep 25 19:28:20 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.5