Sat Aug 6 00:39:36 2011

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 = "361d7bb937402d51e4658efb5b4d76e4" , .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 11942 of file app_rpt.c.

static void __unreg_module ( void   )  [static]

Definition at line 11942 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(), milliwatt_exec(), 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, "%30d+%30d/%30d", &freq1, &freq2, &time) == 3) {
00240          /* f1+f2/time format */
00241       } else if (sscanf(s, "%30d+%30d", &freq1, &freq2) == 2) {
00242          /* f1+f2 format */
00243          time = 0;
00244       } else if (sscanf(s, "%30d*%30d/%30d", &freq1, &freq2, &time) == 3) {
00245          /* f1*f2/time format */
00246          modulate = 1;
00247       } else if (sscanf(s, "%30d*%30d", &freq1, &freq2) == 2) {
00248          /* f1*f2 format */
00249          time = 0;
00250          modulate = 1;
00251       } else if (sscanf(s, "%30d/%30d", &freq1, &time) == 2) {
00252          /* f1/time format */
00253          freq2 = 0;
00254       } else if (sscanf(s, "%30d", &freq1) == 1) {
00255          /* f1 format */
00256          freq2 = 0;
00257          time = 0;
00258       } else if (sscanf(s, "M%30d+M%30d/%30d", &freq1, &freq2, &time) == 3) {
00259          /* Mf1+Mf2/time format */
00260          midinote = 1;
00261       } else if (sscanf(s, "M%30d+M%30d", &freq1, &freq2) == 2) {
00262          /* Mf1+Mf2 format */
00263          time = 0;
00264          midinote = 1;
00265       } else if (sscanf(s, "M%30d*M%30d/%30d", &freq1, &freq2, &time) == 3) {
00266          /* Mf1*Mf2/time format */
00267          modulate = 1;
00268          midinote = 1;
00269       } else if (sscanf(s, "M%30d*M%30d", &freq1, &freq2) == 2) {
00270          /* Mf1*Mf2 format */
00271          time = 0;
00272          modulate = 1;
00273          midinote = 1;
00274       } else if (sscanf(s, "M%30d/%30d", &freq1, &time) == 2) {
00275          /* Mf1/time format */
00276          freq2 = -1;
00277          midinote = 1;
00278       } else if (sscanf(s, "M%30d", &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 8419 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().

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

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

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

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

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

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

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

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

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

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

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

Definition at line 6288 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

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

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

Definition at line 6316 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

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

static char check_tx_freq ( struct rpt myrpt  )  [static]

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

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

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

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

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

static int closerem ( struct rpt myrpt  )  [static]

Definition at line 7399 of file app_rpt.c.

References closerem_ft897(), and rpt::remote.

07400 {
07401    if(!strcmp(myrpt->remote, remote_rig_ft897))
07402       return closerem_ft897(myrpt);
07403    else
07404       return 0;
07405 }

static int closerem_ft897 ( struct rpt myrpt  )  [static]

Definition at line 6737 of file app_rpt.c.

References simple_command_ft897().

Referenced by closerem().

06738 {
06739    simple_command_ft897(myrpt, 0x88); /* PTT off */
06740    return 0;
06741 }  

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

Referenced by check_tx_freq().

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

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

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

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 7756 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.

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

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

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

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

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

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

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

08340 {
08341 /* XXX ATTENTION: if you change the size of these arrays you MUST
08342  * change the limits in corresponding sscanf() calls below. */
08343 char  tmp[300],cmd[300],dest[300],src[300],c;
08344 int   seq,res;
08345 
08346    /* put string in our buffer */
08347    strncpy(tmp,str,sizeof(tmp) - 1);
08348    if (!strcmp(tmp,discstr)) return 0;
08349 
08350 #ifndef  DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES
08351    if (tmp[0] == 'I')
08352    {
08353       /* XXX WARNING: be very careful with the limits on the folowing
08354        * sscanf() call, make sure they match the values defined above */
08355       if (sscanf(tmp,"%299s %299s %30x",cmd,src,&seq) != 3)
08356       {
08357          ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
08358          return 0;
08359       }
08360       mdc1200_notify(myrpt,src,seq);
08361       return 0;
08362    }
08363 #endif
08364    /* XXX WARNING: be very careful with the limits on the folowing
08365     * sscanf() call, make sure they match the values defined above */
08366    if (sscanf(tmp,"%299s %299s %299s %30d %1c",cmd,dest,src,&seq,&c) != 5)
08367    {
08368       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
08369       return 0;
08370    }
08371    if (strcmp(cmd,"D"))
08372    {
08373       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
08374       return 0;
08375    }
08376    /* if not for me, ignore */
08377    if (strcmp(dest,myrpt->name)) return 0;
08378    if (myrpt->p.archivedir)
08379    {
08380       char str[100];
08381 
08382       sprintf(str,"DTMF,%c",c);
08383       donodelog(myrpt,str);
08384    }
08385    c = func_xlat(myrpt,c,&myrpt->p.outxlat);
08386    if (!c) return(0);
08387    res = handle_remote_dtmf_digit(myrpt,c, NULL, 0);
08388    if (res != 1)
08389       return res;
08390    rpt_telemetry(myrpt,COMPLETE,NULL);
08391    return 0;
08392 }

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

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

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

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

Definition at line 8394 of file app_rpt.c.

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

08395 {
08396 int   res;
08397 
08398 
08399    if (keyed && *keyed && (c == myrpt->p.endchar))
08400    {
08401       *keyed = 0;
08402       return DC_INDETERMINATE;
08403    }
08404 
08405    if (myrpt->p.archivedir)
08406    {
08407       char str[100];
08408 
08409       sprintf(str,"DTMF(P),%c",c);
08410       donodelog(myrpt,str);
08411    }
08412    res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode);
08413    if (res != 1)
08414       return res;
08415    rpt_telemetry(myrpt,COMPLETE,NULL);
08416    return 0;
08417 }

static int ic706_pltocode ( char *  str  )  [static]

Definition at line 6883 of file app_rpt.c.

References s.

Referenced by set_ic706().

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

static int kenwood_pltocode ( char *  str  )  [static]

Definition at line 5996 of file app_rpt.c.

References s.

Referenced by setkenwood().

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

static int load_module ( void   )  [static]

Definition at line 11888 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,"%30i",&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 8481 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().

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

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

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

Referenced by set_ic706().

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

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

Definition at line 7560 of file app_rpt.c.

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

Referenced by function_remote(), and service_scan().

07561 {
07562    if(!strcmp(myrpt->remote, remote_rig_ft897))
07563       return multimode_bump_freq_ft897(myrpt, interval);
07564    else if(!strcmp(myrpt->remote, remote_rig_ic706))
07565       return multimode_bump_freq_ic706(myrpt, interval);
07566    else
07567       return -1;
07568 }

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

Definition at line 6749 of file app_rpt.c.

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

Referenced by multimode_bump_freq().

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

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

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

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

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,"%30i",&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 8640 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().

08641 {
08642    if(myrpt->p.idtime){ /* ID time must be non-zero */
08643       myrpt->mustid = myrpt->tailid = 0;
08644       myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */
08645       rpt_mutex_unlock(&myrpt->lock);
08646       rpt_telemetry(myrpt,ID,NULL);
08647       rpt_mutex_lock(&myrpt->lock);
08648    }
08649 }

static int rbi_mhztoband ( char *  str  )  [static]

Definition at line 5697 of file app_rpt.c.

Referenced by setrbi(), and setrbi_check().

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

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

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

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

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

Definition at line 5828 of file app_rpt.c.

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

Referenced by rbi_out().

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

static int rbi_pltocode ( char *  str  )  [static]

Definition at line 5733 of file app_rpt.c.

References s.

Referenced by setrbi(), and setrbi_check().

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

static int reload ( void   )  [static]

Definition at line 11927 of file app_rpt.c.

References reload(), and rpt_vars.

11929 {
11930 int   n;
11931 
11932    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
11933    return(0);
11934 }

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

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

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

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 8774 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.

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

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

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

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

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

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 %30d.%30d", &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 7210 of file app_rpt.c.

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

Referenced by set_ic706().

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

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,"(%30d,%30d,%30d,%30d", &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 5981 of file app_rpt.c.

References serial_remote_io().

Referenced by sendrxkenwood().

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

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

Definition at line 6087 of file app_rpt.c.

References KENWOOD_RETRIES, and sendkenwood().

Referenced by setkenwood().

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

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

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

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

static int service_scan ( struct rpt myrpt  )  [static]

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

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

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

Definition at line 6646 of file app_rpt.c.

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

Referenced by set_ft897().

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

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

Definition at line 6623 of file app_rpt.c.

References serial_remote_io().

Referenced by set_ft897().

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

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

Definition at line 7108 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 6515 of file app_rpt.c.

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

Referenced by multimode_bump_freq_ft897(), and set_ft897().

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

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

Definition at line 7018 of file app_rpt.c.

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

Referenced by set_ic706().

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

static int set_ft897 ( struct rpt myrpt  )  [static]

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

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

static int set_ic706 ( struct rpt myrpt  )  [static]

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

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

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

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

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

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

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

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

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

Definition at line 6560 of file app_rpt.c.

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

Referenced by set_ft897().

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

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

Definition at line 7052 of file app_rpt.c.

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

Referenced by set_ic706().

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

static int setkenwood ( struct rpt myrpt  )  [static]

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

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

static int setrbi ( struct rpt myrpt  )  [static]

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

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

static int setrbi_check ( struct rpt myrpt  )  [static]

Definition at line 6233 of file app_rpt.c.

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

Referenced by setrbi(), and setrem().

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

static int setrem ( struct rpt myrpt  )  [static]

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

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

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

Definition at line 6546 of file app_rpt.c.

References serial_remote_io().

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

06547 {
06548    unsigned char cmdstr[5];
06549    
06550    memset(cmdstr, 0, 5);
06551 
06552    cmdstr[4] = command; 
06553 
06554    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
06555 
06556 }

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

Definition at line 7000 of file app_rpt.c.

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

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

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

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

References MAXREMSTR.

Referenced by set_ctcss_freq_ft897().

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

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

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

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

static void stop_scan ( struct rpt myrpt  )  [static]

Definition at line 7575 of file app_rpt.c.

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

Referenced by handle_remote_dtmf_digit().

07576 {
07577    myrpt->hfscanstop = 1;
07578    rpt_telemetry(myrpt,SCAN,0);
07579 }

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 11857 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.

11859 {
11860    int i;
11861 
11862 #ifdef   OLD_ASTERISK
11863    STANDARD_HANGUP_LOCALUSERS;
11864 #endif
11865    for(i = 0; i < nrpts; i++) {
11866       if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue;
11867                 ast_mutex_destroy(&rpt_vars[i].lock);
11868                 ast_mutex_destroy(&rpt_vars[i].remlock);
11869    }
11870    i = ast_unregister_application(app);
11871 
11872    /* Unregister cli extensions */
11873    ast_cli_unregister(&cli_debug);
11874    ast_cli_unregister(&cli_dump);
11875    ast_cli_unregister(&cli_stats);
11876    ast_cli_unregister(&cli_lstats);
11877    ast_cli_unregister(&cli_nodes);
11878    ast_cli_unregister(&cli_reload);
11879    ast_cli_unregister(&cli_restart);
11880    ast_cli_unregister(&cli_fun);
11881 
11882    return i;
11883 }

static int vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 7184 of file app_rpt.c.

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

Referenced by set_ic706().

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

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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 11942 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 11942 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(), aji_load_config(), check_user_full(), handle_pri_show_debug(), handle_request(), process_sdp(), process_sdp_a_audio(), process_sdp_a_video(), 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 Sat Aug 6 00:39:37 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7