Fri Apr 24 16:26:09 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 <stdint.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/io.h>
#include <sys/vfs.h>
#include <math.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <termios.h>
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
#include "asterisk/cdr.h"
#include "asterisk/dahdi_compat.h"
#include "asterisk/tonezone_compat.h"

Go to the source code of this file.

Data Structures

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

Defines

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

Enumerations

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

Functions

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

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Radio Repeater/Remote Base Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, }
static char * app = "Rpt"
static const struct ast_module_infoast_module_info = &__mod_info
static struct ast_cli_entry cli_debug
static struct ast_cli_entry cli_dump
static struct ast_cli_entry cli_fun
static struct ast_cli_entry cli_lstats
static struct ast_cli_entry cli_nodes
static struct ast_cli_entry cli_reload
static struct ast_cli_entry cli_restart
static struct ast_cli_entry cli_stats
static int debug = 0
static char debug_usage []
static char * descrip
char * discstr = "!!DISCONNECT!!"
static char dump_lstats []
static char dump_nodes []
static char dump_stats []
static char dump_usage []
static char fun_usage []
static struct function_table_tag function_table []
int max_chan_stat [] = {22000,1000,22000,100,22000,2000,22000}
static ast_mutex_t nodeloglock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static ast_mutex_t nodelookuplock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static int nrpts = 0
static char reload_usage []
static char remdtmfstr [] = "0123456789*#ABCD"
static char * remote_rig_ft897 = "ft897"
static char * remote_rig_ic706 = "ic706"
static char * remote_rig_kenwood = "kenwood"
static char * remote_rig_rbi = "rbi"
static char restart_usage []
static pthread_t rpt_master_thread
static struct rpt rpt_vars [MAXRPTS]
static time_t starttime = 0
static char * synopsis = "Radio Repeater/Remote Base Control System"
static char * tdesc = "Radio Repeater / Remote Base version 0.73 09/04/2007"
static struct telem_defaults tele_defs []


Detailed Description

Radio Repeater / Remote Base program version 0.73 09/04/07.

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

Repeater / Remote Functions: "Simple" Mode: * - autopatch access, # - autopatch hangup Normal mode: See the function list in rpt.conf (autopatchup, autopatchdn) autopatchup can optionally take comma delimited setting=value pairs:

context=string : Override default context with "string" dialtime=ms : Specify the max number of milliseconds between phone number digits (1000 milliseconds = 1 second) farenddisconnect=1 : Automatically disconnect when called party hangs up noct=1 : Don't send repeater courtesy tone during autopatch calls quiet=1 : Don't send dial tone, or connect messages. Do not send patch down message when called party hangs up

Example: 123=autopatchup,dialtime=20000,noct=1,farenddisconnect=1

To send an asterisk (*) while dialing or talking on phone, use the autopatch acess code.

status cmds:

1 - Force ID 2 - Give Time of Day 3 - Give software Version

cop (control operator) cmds:

1 - System warm boot 2 - System enable 3 - System disable 4 - Test Tone On/Off 5 - Dump System Variables on Console (debug) 6 - PTT (phone mode only) 7 - Time out timer enable 8 - Time out timer disable 9 - Autopatch enable 10 - Autopatch disable 11 - Link enable 12 - Link disable 13 - Query System State 14 - Change System State 15 - Scheduler Enable 16 - Scheduler Disable 17 - User functions (time, id, etc) enable 18 - User functions (time, id, etc) disable 19 - Select alternate hang timer 20 - Select standard hang timer

ilink cmds:

1 - Disconnect specified link 2 - Connect specified link -- monitor only 3 - Connect specified link -- tranceive 4 - Enter command mode on specified link 5 - System status 6 - Disconnect all links 11 - Disconnect a previously permanently connected link 12 - Permanently connect specified link -- monitor only 13 - Permanently connect specified link -- tranceive 15 - Full system status (all nodes) 16 - Reconnect links disconnected with "disconnect all links" 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)

remote cmds:

1 - Recall Memory MM (*000-*099) (Gets memory from rpt.conf) 2 - Set VFO MMMMM*KKK*O (Mhz digits, Khz digits, Offset) 3 - Set Rx PL Tone HHH*D* 4 - Set Tx PL Tone HHH*D* (Not currently implemented with DHE RBI-1) 5 - Link Status (long) 6 - Set operating mode M (FM, USB, LSB, AM, etc) 100 - RX PL off (Default) 101 - RX PL On 102 - TX PL Off (Default) 103 - TX PL On 104 - Low Power 105 - Med Power 106 - Hi Power 107 - Bump Down 20 Hz 108 - Bump Down 100 Hz 109 - Bump Down 500 Hz 110 - Bump Up 20 Hz 111 - Bump Up 100 Hz 112 - Bump Up 500 Hz 113 - Scan Down Slow 114 - Scan Down Medium 115 - Scan Down Fast 116 - Scan Up Slow 117 - Scan Up Medium 118 - Scan Up Fast 119 - Transmit allowing auto-tune 140 - Link Status (brief) 200 thru 215 - (Send DTMF 0-9,*,#,A-D) (200=0, 201=1, 210=*, etc)

'duplex' modes: (defaults to duplex=2)

0 - Only remote links key Tx and no main repeat audio. 1 - Everything other then main Rx keys Tx, no main repeat audio. 2 - Normal mode 3 - Normal except no main repeat audio. 4 - Normal except no main repeat audio during autopatch only

Definition in file app_rpt.c.


Define Documentation

#define ACTIONSIZE   32

Definition at line 218 of file app_rpt.c.

#define ALLOW_LOCAL_CHANNELS

Definition at line 229 of file app_rpt.c.

#define AUTHLOGOUTTIME   25000

Definition at line 167 of file app_rpt.c.

#define AUTHTELLTIME   7000

Definition at line 165 of file app_rpt.c.

#define AUTHTXTIME   1000

Definition at line 166 of file app_rpt.c.

#define DEFAULT_CIV_ADDR   0x58

Definition at line 210 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_IOBASE   0x378

Definition at line 208 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_MONITOR_MIN_DISK_BLOCKS   10000

Definition at line 191 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_INACT_TIMEOUT   (15 * 60)

Definition at line 192 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT   (60 * 60)

Definition at line 193 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING   (3 * 60)

Definition at line 194 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ   30

Definition at line 195 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DELIMCHR   ','

Definition at line 186 of file app_rpt.c.

Referenced by finddelim().

#define DISC_TIME   10000

Definition at line 173 of file app_rpt.c.

Referenced by rpt().

#define DTMF_LOCAL_STARTTIME   500

Definition at line 225 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_LOCAL_TIME   250

Definition at line 224 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_TIMEOUT   3

Definition at line 162 of file app_rpt.c.

Referenced by handle_remote_dtmf_digit(), and rpt().

#define ENDCHAR   '#'

Definition at line 205 of file app_rpt.c.

Referenced by load_rpt_vars().

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

Definition at line 206 of file app_rpt.c.

Referenced by load_rpt_vars().

#define EXTNODES   "extnodes"

Definition at line 198 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCCHAR   '*'

Definition at line 204 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCTDELAY   1500

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

Referenced by load_rpt_vars().

#define KENWOOD_RETRIES   5

Definition at line 163 of file app_rpt.c.

Referenced by sendrxkenwood().

#define LINKLISTSHORTTIME   200

Definition at line 159 of file app_rpt.c.

Referenced by __kickshort().

#define LINKLISTTIME   10000

Definition at line 158 of file app_rpt.c.

Referenced by rpt().

#define MACRO   "macro"

Definition at line 200 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MACROPTIME   500

Definition at line 161 of file app_rpt.c.

Referenced by rpt().

#define MACROTIME   100

Definition at line 160 of file app_rpt.c.

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

#define MAX_RETRIES   5

Definition at line 174 of file app_rpt.c.

Referenced by connect_link(), and function_ilink().

#define MAX_RETRIES_PERM   1000000000

Definition at line 175 of file app_rpt.c.

Referenced by connect_link().

#define MAX_STAT_LINKS   32

Definition at line 389 of file app_rpt.c.

Referenced by rpt_do_stats().

#define MAX_SYSSTATES   10

Definition at line 396 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXCONNECTTIME   5000

Definition at line 212 of file app_rpt.c.

Referenced by rpt().

#define MAXDTMF   32

Definition at line 155 of file app_rpt.c.

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

#define MAXLINKLIST   512

Definition at line 157 of file app_rpt.c.

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

#define MAXMACRO   2048

Definition at line 156 of file app_rpt.c.

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

#define MAXNODESTR   300

Definition at line 214 of file app_rpt.c.

Referenced by connect_link(), and function_ilink().

#define MAXPATCHCONTEXT   100

Definition at line 216 of file app_rpt.c.

Referenced by function_autopatchup(), and local_dtmf_helper().

#define MAXPEERSTR   31

Definition at line 183 of file app_rpt.c.

Referenced by rpt_do_lstats().

#define MAXREMSTR   15

Definition at line 184 of file app_rpt.c.

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

#define MAXRPTS   20

Definition at line 388 of file app_rpt.c.

#define MAXXLAT   20

Definition at line 393 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXXLATTIME   3

Definition at line 394 of file app_rpt.c.

Referenced by func_xlat().

#define MEMORY   "memory"

Definition at line 199 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MONITOR_DISK_BLOCKS_PER_MINUTE   38

Definition at line 189 of file app_rpt.c.

#define MORSE   "morse"

Definition at line 203 of file app_rpt.c.

Referenced by telem_any().

#define MSWAIT   200

Definition at line 384 of file app_rpt.c.

Referenced by rpt(), and rpt_call().

#define NODES   "nodes"

Definition at line 197 of file app_rpt.c.

Referenced by load_rpt_vars().

#define NRPTSTAT   7

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

Referenced by load_rpt_vars().

#define QUOTECHR   34

Definition at line 187 of file app_rpt.c.

Referenced by finddelim().

#define REDUNDANT_TX_TIME   2000

Definition at line 177 of file app_rpt.c.

Referenced by rpt().

#define REM_SCANTIME   100

Definition at line 222 of file app_rpt.c.

Referenced by function_remote().

#define RETRY_TIMER_MS   5000

Definition at line 179 of file app_rpt.c.

Referenced by rpt().

#define rpt_mutex_lock (  )     ast_mutex_lock(x)

Definition at line 870 of file app_rpt.c.

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

#define rpt_mutex_unlock (  )     ast_mutex_unlock(x)

Definition at line 871 of file app_rpt.c.

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

#define START_DELAY   2

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


Function Documentation

static void __kickshort ( struct rpt myrpt  )  [static]

Definition at line 1396 of file app_rpt.c.

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

Referenced by connect_link(), and rpt().

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

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

Definition at line 1347 of file app_rpt.c.

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

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

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

static void __reg_module ( void   )  [static]

Definition at line 11930 of file app_rpt.c.

static void __unreg_module ( void   )  [static]

Definition at line 11930 of file app_rpt.c.

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

Definition at line 212 of file indications.c.

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

Referenced by ast_app_dtget(), ast_indicate_data(), ast_senddigit_begin(), dialtone_indicate(), do_dtmf_local(), handle_playtones(), 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 8407 of file app_rpt.c.

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

Referenced by rpt().

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

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

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

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

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

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

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

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

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

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

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

Definition at line 6282 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

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

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

Definition at line 6310 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

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

static char check_tx_freq ( struct rpt myrpt  )  [static]

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

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

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

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

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

static int closerem ( struct rpt myrpt  )  [static]

Definition at line 7393 of file app_rpt.c.

References closerem_ft897(), and rpt::remote.

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

static int closerem_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6731 of file app_rpt.c.

References simple_command_ft897().

Referenced by closerem().

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

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

Definition at line 5228 of file app_rpt.c.

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

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

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

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

Definition at line 4467 of file app_rpt.c.

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

Referenced by function_ilink().

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

static int decimals2int ( char *  fraction  )  [static]

Definition at line 6351 of file app_rpt.c.

Referenced by check_tx_freq().

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

static long diskavail ( struct rpt myrpt  )  [static]

Definition at line 1024 of file app_rpt.c.

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

Referenced by rpt().

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

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

Definition at line 1089 of file app_rpt.c.

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

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

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

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

Definition at line 1038 of file app_rpt.c.

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

Referenced by handle_link_data(), and local_dtmf_helper().

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

static void do_scheduler ( struct rpt myrpt  )  [static]

Definition at line 8642 of file app_rpt.c.

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

Referenced by rpt().

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

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

Definition at line 1064 of file app_rpt.c.

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

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

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

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

Definition at line 1287 of file app_rpt.c.

Referenced by check_tx_freq().

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

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

Definition at line 1307 of file app_rpt.c.

References DELIMCHR, and QUOTECHR.

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

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

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

Definition at line 1242 of file app_rpt.c.

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

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

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

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

Definition at line 4998 of file app_rpt.c.

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

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

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

Definition at line 4901 of file app_rpt.c.

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

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

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

Definition at line 5099 of file app_rpt.c.

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

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

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

Definition at line 4643 of file app_rpt.c.

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

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

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

Definition at line 5054 of file app_rpt.c.

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

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

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

Definition at line 7750 of file app_rpt.c.

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

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

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

Definition at line 5023 of file app_rpt.c.

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

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

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

Definition at line 2818 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and wait_interval().

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

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

Definition at line 5303 of file app_rpt.c.

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

Referenced by rpt().

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

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

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

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

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

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

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

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

Definition at line 8223 of file app_rpt.c.

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

Referenced by handle_remote_data(), and handle_remote_phone_dtmf().

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

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

Definition at line 8382 of file app_rpt.c.

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

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

static int ic706_pltocode ( char *  str  )  [static]

Definition at line 6877 of file app_rpt.c.

References s.

Referenced by set_ic706().

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

static int kenwood_pltocode ( char *  str  )  [static]

Definition at line 5990 of file app_rpt.c.

References s.

Referenced by setkenwood().

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

static int load_module ( void   )  [static]

Definition at line 11876 of file app_rpt.c.

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

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

Definition at line 1621 of file app_rpt.c.

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

Referenced by rpt(), and rpt_master().

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

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

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

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

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

Definition at line 1477 of file app_rpt.c.

Referenced by function_autopatchup().

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

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

Definition at line 1191 of file app_rpt.c.

References ast_verbose(), and rpt::name.

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

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

static int mem2vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7191 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 7554 of file app_rpt.c.

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

Referenced by function_remote(), and service_scan().

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

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

Definition at line 6743 of file app_rpt.c.

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

Referenced by multimode_bump_freq().

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

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

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

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

static int multimode_capable ( struct rpt myrpt  )  [static]

Definition at line 879 of file app_rpt.c.

References rpt::remote.

Referenced by function_remote(), and rpt_tele_thread().

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

static int myatoi ( char *  str  )  [static]

Definition at line 1519 of file app_rpt.c.

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

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

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

Definition at line 1529 of file app_rpt.c.

Referenced by rpt_do_nodes(), and rpt_tele_thread().

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

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

Definition at line 1409 of file app_rpt.c.

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

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

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

static int openserial ( char *  fname  )  [static]

Definition at line 1155 of file app_rpt.c.

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

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

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

Definition at line 2457 of file app_rpt.c.

References play_tone_pair().

Referenced by send_morse().

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

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

Definition at line 2452 of file app_rpt.c.

References play_tone_pair().

Referenced by rpt_tele_thread(), and send_morse().

02453 {
02454    return play_tone_pair(chan, freq, 0, duration, amplitude);
02455 }

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

Definition at line 2438 of file app_rpt.c.

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

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

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

static void queue_id ( struct rpt myrpt  )  [static]

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

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

static int rbi_mhztoband ( char *  str  )  [static]

Definition at line 5691 of file app_rpt.c.

Referenced by setrbi(), and setrbi_check().

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

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

Definition at line 5850 of file app_rpt.c.

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

Referenced by setrbi().

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

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

Definition at line 5822 of file app_rpt.c.

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

Referenced by rbi_out().

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

static int rbi_pltocode ( char *  str  )  [static]

Definition at line 5727 of file app_rpt.c.

References s.

Referenced by setrbi(), and setrbi_check().

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

static int reload ( void   )  [static]

Definition at line 11915 of file app_rpt.c.

References reload(), and rpt_vars.

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

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

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

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

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

Definition at line 1594 of file app_rpt.c.

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

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

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

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

Definition at line 8762 of file app_rpt.c.

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

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

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

Definition at line 4163 of file app_rpt.c.

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

Referenced by function_autopatchup(), and local_dtmf_helper().

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

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

Definition at line 1967 of file app_rpt.c.

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

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

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

Definition at line 1989 of file app_rpt.c.

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

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

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

Definition at line 2409 of file app_rpt.c.

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

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

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

Definition at line 2237 of file app_rpt.c.

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

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

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

Definition at line 2327 of file app_rpt.c.

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

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

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

Definition at line 2377 of file app_rpt.c.

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

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

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

Definition at line 2392 of file app_rpt.c.

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

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

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

Definition at line 2012 of file app_rpt.c.

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

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

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

Definition at line 10559 of file app_rpt.c.

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

Referenced by load_module().

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

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

Definition at line 1583 of file app_rpt.c.

References ast_localtime(), and localtime_r.

Referenced by do_scheduler(), and rpt_tele_thread().

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

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

Definition at line 10392 of file app_rpt.c.

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

Referenced by load_module().

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

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

Definition at line 2905 of file app_rpt.c.

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

Referenced by rpt_telemetry().

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

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

Definition at line 4118 of file app_rpt.c.

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

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

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

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

Definition at line 2689 of file app_rpt.c.

References ast_log(), ast_say_character_str(), ast_stopstream(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.

Referenced by rpt_tele_thread().

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

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

Definition at line 2676 of file app_rpt.c.

References ast_log(), ast_stopstream(), ast_streamfile(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.

Referenced by rpt_tele_thread(), and telem_any().

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

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

Definition at line 2702 of file app_rpt.c.

References ast_log(), ast_say_number(), ast_stopstream(), ast_waitstream(), ast_channel::language, LOG_WARNING, and ast_channel::name.

Referenced by rpt_tele_thread().

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

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

Definition at line 7204 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 4415 of file app_rpt.c.

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

Referenced by handle_link_phone_dtmf(), and local_dtmf_helper().

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

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

Definition at line 2463 of file app_rpt.c.

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

Referenced by telem_any().

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

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

Definition at line 2625 of file app_rpt.c.

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

Referenced by telem_any().

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

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

Definition at line 5975 of file app_rpt.c.

References serial_remote_io().

Referenced by sendrxkenwood().

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

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

Definition at line 6081 of file app_rpt.c.

References KENWOOD_RETRIES, and sendkenwood().

Referenced by setkenwood().

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

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

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

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

static int service_scan ( struct rpt myrpt  )  [static]

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

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

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

Definition at line 6640 of file app_rpt.c.

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

Referenced by set_ft897().

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

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

Definition at line 6617 of file app_rpt.c.

References serial_remote_io().

Referenced by set_ft897().

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

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

Definition at line 7102 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 6509 of file app_rpt.c.

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

Referenced by multimode_bump_freq_ft897(), and set_ft897().

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

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

Definition at line 7012 of file app_rpt.c.

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

Referenced by set_ic706().

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

static int set_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6675 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

static int set_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7219 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

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

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

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

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

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

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

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

Definition at line 6554 of file app_rpt.c.

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

Referenced by set_ft897().

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

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

Definition at line 7046 of file app_rpt.c.

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

Referenced by set_ic706().

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

static int setkenwood ( struct rpt myrpt  )  [static]

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

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

static int setrbi ( struct rpt myrpt  )  [static]

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

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

static int setrbi_check ( struct rpt myrpt  )  [static]

Definition at line 6227 of file app_rpt.c.

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

Referenced by setrbi(), and setrem().

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

static int setrem ( struct rpt myrpt  )  [static]

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

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

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

Definition at line 6540 of file app_rpt.c.

References serial_remote_io().

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

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

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

Definition at line 6994 of file app_rpt.c.

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

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

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

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

Definition at line 1501 of file app_rpt.c.

Referenced by function_autopatchup().

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

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

Definition at line 6393 of file app_rpt.c.

References MAXREMSTR.

Referenced by set_ctcss_freq_ft897().

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

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

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

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

static void stop_scan ( struct rpt myrpt  )  [static]

Definition at line 7569 of file app_rpt.c.

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

Referenced by handle_remote_dtmf_digit().

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

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

Definition at line 2715 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and telem_lookup().

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

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

Definition at line 2771 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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

static int unload_module ( void   )  [static]

Definition at line 11845 of file app_rpt.c.

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

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

static int vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7178 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 2890 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

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


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Radio Repeater/Remote Base Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 11930 of file app_rpt.c.

char* app = "Rpt" [static]

Definition at line 314 of file app_rpt.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

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

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_dump [static]

Initial value:

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

Definition at line 939 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_fun [static]

Initial value:

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

Definition at line 963 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_lstats [static]

Initial value:

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

Definition at line 951 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_nodes [static]

Initial value:

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

Definition at line 947 of file app_rpt.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_reload [static]

Initial value:

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

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

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_stats [static]

Initial value:

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

Definition at line 943 of file app_rpt.c.

Referenced by load_module(), and unload_module().

int debug = 0 [static]

Definition at line 353 of file app_rpt.c.

Referenced by add_sdp(), add_t38_sdp(), aji_load_config(), check_user_full(), handle_pri_show_debug(), handle_request(), process_sdp(), set_destination(), and sip_sendtext().

char debug_usage[] [static]

Initial value:

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

Definition at line 902 of file app_rpt.c.

char* descrip [static]

Definition at line 318 of file app_rpt.c.

char* discstr = "!!DISCONNECT!!"

Definition at line 373 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 914 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 918 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 910 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 906 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 930 of file app_rpt.c.

struct function_table_tag function_table[] [static]

Definition at line 1014 of file app_rpt.c.

Referenced by collect_function_digits().

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

Definition at line 360 of file app_rpt.c.

ast_mutex_t nodeloglock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 688 of file app_rpt.c.

Referenced by donodelog(), and rpt_master().

ast_mutex_t nodelookuplock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 690 of file app_rpt.c.

Referenced by node_lookup().

int nrpts = 0 [static]

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

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

Definition at line 356 of file app_rpt.c.

char* remote_rig_ft897 = "ft897" [static]

Definition at line 374 of file app_rpt.c.

char* remote_rig_ic706 = "ic706" [static]

Definition at line 377 of file app_rpt.c.

char* remote_rig_kenwood = "kenwood" [static]

Definition at line 376 of file app_rpt.c.

char* remote_rig_rbi = "rbi" [static]

Definition at line 375 of file app_rpt.c.

char restart_usage[] [static]

Initial value:

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

Definition at line 926 of file app_rpt.c.

pthread_t rpt_master_thread [static]

Definition at line 410 of file app_rpt.c.

struct rpt rpt_vars[MAXRPTS] [static]

Referenced by load_rpt_vars(), reload(), rpt(), rpt_do_dump(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_reload(), rpt_do_restart(), rpt_do_stats(), rpt_exec(), rpt_master(), and unload_module().

time_t starttime = 0 [static]

Definition at line 408 of file app_rpt.c.

Referenced by tzparse(), and wait_for_answer().

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

Definition at line 316 of file app_rpt.c.

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

Definition at line 312 of file app_rpt.c.

struct telem_defaults tele_defs[] [static]

Definition at line 972 of file app_rpt.c.

Referenced by telem_lookup().


Generated on Fri Apr 24 16:26:10 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7