Fri Jul 24 00:41:12 2009

Asterisk developer's documentation


app_rpt.c File Reference

Radio Repeater / Remote Base program version 0.115 5/12/08 2055 EDT. 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 <dahdi/user.h>
#include <dahdi/tonezone.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
#include "asterisk/cdr.h"
#include "asterisk/manager.h"
#include "asterisk/app.h"
#include <termios.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_cmd_struct
struct  rpt_link
struct  rpt_lstat
struct  rpt_tele
struct  rpt_topkey
struct  rpt_xlat
struct  sysstate
struct  telem_defaults
struct  vox

Defines

#define ACTIONSIZE   32
#define ALLOW_LOCAL_CHANNELS
#define AUTHLOGOUTTIME   25000
#define AUTHTELLTIME   7000
#define AUTHTXTIME   1000
#define CMD_DEPTH   1
#define CMD_STATE_BUSY   1
#define CMD_STATE_EXECUTING   3
#define CMD_STATE_IDLE   0
#define CMD_STATE_READY   2
#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 IS_XPMR(x)   (!strncasecmp(x->rxchanname,"rad",3))
#define ISRIG_RTX(x)   ((!strcmp(x,remote_rig_rtx150)) || (!strcmp(x,remote_rig_rtx450)))
#define KENWOOD_RETRIES   5
#define KEYPOSTSHORTTIME   200
#define KEYPOSTTIME   30000
#define LINKLISTSHORTTIME   200
#define LINKLISTTIME   10000
#define LINKPOSTSHORTTIME   200
#define LINKPOSTTIME   30000
#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 MAXIDENTLEN   32
#define MAXLINKLIST   512
#define MAXMACRO   2048
#define MAXNODELEN   16
#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 mymax(x, y)   ((x > y) ? x : y)
#define mymin(x, y)   ((x < y) ? x : y)
#define NEW_ASTERISK
#define NODENAMES   "rpt/nodenames"
#define NODES   "nodes"
#define NRPTSTAT   7
#define PARROTFILE   "/tmp/parrot_%s_%u"
#define PARROTTIME   1000
#define PATCH_DIALPLAN_TIMEOUT   1500
#define POLITEID   30000
#define QUOTECHR   34
#define REDUNDANT_TX_TIME   2000
#define REM_SCANTIME   100
#define RETRY_TIMER_MS   5000
#define RPT_LOCKOUT_SECS   10
#define rpt_mutex_lock(x)   ast_mutex_lock(x)
#define rpt_mutex_unlock(x)   ast_mutex_unlock(x)
#define SIMPLEX_PATCH_DELAY   25
#define SIMPLEX_PHONE_DELAY   25
#define START_DELAY   2
#define STATPOST_PROGRAM   "/usr/bin/wget,-q,--output-document=/dev/null,--no-check-certificate"
#define TELEMETRY   "telemetry"
#define TELEPARAMSIZE   256
#define TONEMACRO   "tonemacro"
#define TOPKEYMAXSTR   30
#define TOPKEYN   32
#define TOPKEYWAIT   3
#define TOTIME   180000
#define VOX_MAX_THRESHOLD   10000.0
#define VOX_MIN_THRESHOLD   3000.0
#define VOX_OFF_DEBOUNCE_COUNT   20
#define VOX_ON_DEBOUNCE_COUNT   3
#define VOX_RECOVER_MS   500
#define VOX_TIMEOUT_MS   5000

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, PLAYBACK,
  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, TOPKEY, TIMEOUT_WARNING,
  ACT_TIMEOUT_WARNING, LINKUNKEY, UNAUTHTX, PARROT,
  STATS_TIME_LOCAL
}
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, SOURCE_ALT
}
enum  {
  DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM,
  DLY_COMP, DLY_LINKUNKEY, DLY_PARROT
}
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)
 Start a tone-list going.
void ast_playtones_stop (struct ast_channel *chan)
 Stop the tones from playing.
static int attempt_reconnect (struct rpt *myrpt, struct rpt_link *l)
static void birdbath (struct rpt *myrpt)
static int channel_revert (struct rpt *myrpt)
static int channel_steer (struct rpt *myrpt, char *data)
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, char mars)
static int check_freq_kenwood (int m, int d, int *defmode)
static int check_freq_rbi (int m, int d, int *defmode)
static int check_freq_rtx (int m, int d, int *defmode, struct rpt *myrpt)
static int check_freq_tm271 (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 int dovox (struct vox *v, short *buf, int bs)
static char * eatwhite (char *s)
static int finddelim (char *str, char *strp[], int limit)
static void flush_telem (struct rpt *myrpt)
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_playback (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_mem_set (struct rpt *myrpt, char *digitbuf)
static int get_wait_interval (struct rpt *myrpt, int type)
static char * handle_cli_cmd (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_dump (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_fun (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_fun1 (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_local_nodes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_lstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_nodes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_restart (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 linkcount (struct rpt *myrpt)
static int load_module (void)
static void load_rpt_vars (int n, int init)
static void local_dtmf_helper (struct rpt *myrpt, char c_in)
static int manager_rpt_local_nodes (struct mansession *s, const struct message *m)
static int manager_rpt_status (struct mansession *s, const struct message *m)
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 (struct rpt *myrpt, 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 int priority_jump (struct rpt *myrpt, struct ast_channel *chan)
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 char * res2cli (int r)
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_cmd (int fd, int argc, char *argv[])
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_fun1 (int fd, int argc, char *argv[])
static int rpt_do_local_nodes (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 ast_tm *lt)
static int rpt_manager_do_stats (struct mansession *s, const struct message *m, char *str)
static void rpt_manager_success (struct mansession *s, const struct message *m)
static void * rpt_master (void *ignore)
static int rpt_push_alt_macro (struct rpt *myrpt, char *sptr)
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 saynode (struct rpt *myrpt, struct ast_channel *mychannel, char *name)
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 void send_link_keyquery (struct rpt *myrpt)
static int send_morse (struct ast_channel *chan, char *string, int speed, int freq, int amplitude)
static void send_newkey (struct ast_channel *chan)
static int send_tone_telemetry (struct ast_channel *chan, char *tonestring)
static int send_usb_txt (struct rpt *myrpt, char *txt)
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 set_tm271 (struct rpt *myrpt)
static int setdtr (int fd, int enable)
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 setrtx (struct rpt *myrpt)
static int setrtx_check (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 statpost (struct rpt *myrpt, char *pairs)
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 topcompar (const void *a, const void *b)
static int unload_module (void)
static int vfo_ic706 (struct rpt *myrpt)
static void voxinit_link (struct rpt_link *mylink, char enable)
static void voxinit_rpt (struct rpt *myrpt, char enable)
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 , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, }
static char * app = "Rpt"
static struct ast_module_infoast_module_info = &__mod_info
static char cmd_usage []
ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }
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}
char * newkeystr = "!NEWKEY!"
static ast_mutex_t nodeloglock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
static ast_mutex_t nodelookuplock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
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_ppp16 = "ppp16"
static char * remote_rig_rbi = "rbi"
static char * remote_rig_rtx150 = "rtx150"
static char * remote_rig_rtx450 = "rtx450"
static char * remote_rig_tm271 = "tm271"
static char restart_usage []
static struct ast_cli_entry rpt_cli []
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.115 5/12/2008"
static struct telem_defaults tele_defs []
static char usage_local_nodes []


Detailed Description

Radio Repeater / Remote Base program version 0.115 5/12/08 2055 EDT.

Author:
Jim Dixon, WB6NIL <jim@lambdatel.com>
Note:
Serious contributions by Steve RoDgers, WA6ZFT <hwstar@rodgers.sdcoxmail.com>

Steven Henke, W9SH, <w9sh@arrl.net> added a few features here and there.

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 (global) 2 - Give Time of Day (global) 3 - Give software Version (global) 11 - Force ID (local only) 12 - Give Time of Day (local only)

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 21 - Enable Parrot Mode 22 - Disable Parrot Mode 23 - Birdbath (Current Parrot Cleanup/Flush) 24 - Flush all telemetry 25 - Query last node un-keyed 26 - Query all nodes keyed/unkeyed 30 - Recall Memory Setting in Attached Xcvr 31 - Channel Selector for Parallel Programmed Xcvr 32 - Touchtone pad test: command + Digit string + # to playback all digits pressed

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)

playback cmds: specify the name of the file to be played (for example, 25=rpt/foo)

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

#define ALLOW_LOCAL_CHANNELS

Definition at line 286 of file app_rpt.c.

#define AUTHLOGOUTTIME   25000

Definition at line 196 of file app_rpt.c.

#define AUTHTELLTIME   7000

Definition at line 194 of file app_rpt.c.

#define AUTHTXTIME   1000

Definition at line 195 of file app_rpt.c.

#define CMD_DEPTH   1

Definition at line 642 of file app_rpt.c.

#define CMD_STATE_BUSY   1

Definition at line 644 of file app_rpt.c.

Referenced by rpt_do_cmd().

#define CMD_STATE_EXECUTING   3

Definition at line 646 of file app_rpt.c.

Referenced by rpt().

#define CMD_STATE_IDLE   0

Definition at line 643 of file app_rpt.c.

Referenced by rpt(), and rpt_do_cmd().

#define CMD_STATE_READY   2

Definition at line 645 of file app_rpt.c.

Referenced by rpt(), and rpt_do_cmd().

#define DEFAULT_CIV_ADDR   0x58

Definition at line 252 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_IOBASE   0x378

Definition at line 250 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_MONITOR_MIN_DISK_BLOCKS   10000

Definition at line 228 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_INACT_TIMEOUT   (15 * 60)

Definition at line 229 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT   (60 * 60)

Definition at line 230 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING   (3 * 60)

Definition at line 231 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ   30

Definition at line 232 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DELIMCHR   ','

Definition at line 223 of file app_rpt.c.

#define DISC_TIME   10000

Definition at line 202 of file app_rpt.c.

Referenced by rpt().

#define DTMF_LOCAL_STARTTIME   500

Definition at line 271 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_LOCAL_TIME   250

Definition at line 270 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_TIMEOUT   3

Definition at line 188 of file app_rpt.c.

Referenced by handle_remote_dtmf_digit(), and rpt().

#define ENDCHAR   '#'

Definition at line 243 of file app_rpt.c.

Referenced by load_rpt_vars().

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

Definition at line 244 of file app_rpt.c.

Referenced by load_rpt_vars().

#define EXTNODES   "extnodes"

Definition at line 235 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCCHAR   '*'

Definition at line 242 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCTDELAY   1500

Definition at line 485 of file app_rpt.c.

#define FUNCTIONS   "functions"

Definition at line 238 of file app_rpt.c.

Referenced by load_rpt_vars().

#define HANGTIME   5000

Definition at line 479 of file app_rpt.c.

Referenced by load_rpt_vars().

#define IC706_PL_MEMORY_OFFSET   50

Definition at line 273 of file app_rpt.c.

Referenced by set_ic706().

#define IDTIME   300000

Definition at line 481 of file app_rpt.c.

Referenced by load_rpt_vars().

#define IS_XPMR (  )     (!strncasecmp(x->rxchanname,"rad",3))

Definition at line 471 of file app_rpt.c.

Referenced by setkenwood(), and setrtx().

#define ISRIG_RTX (  )     ((!strcmp(x,remote_rig_rtx150)) || (!strcmp(x,remote_rig_rtx450)))

Definition at line 470 of file app_rpt.c.

Referenced by check_freq(), function_remote(), rpt(), setrem(), and setrtx().

#define KENWOOD_RETRIES   5

Definition at line 189 of file app_rpt.c.

Referenced by sendrxkenwood().

#define KEYPOSTSHORTTIME   200

Definition at line 185 of file app_rpt.c.

Referenced by rpt().

#define KEYPOSTTIME   30000

Definition at line 184 of file app_rpt.c.

Referenced by rpt().

#define LINKLISTSHORTTIME   200

Definition at line 181 of file app_rpt.c.

Referenced by __kickshort().

#define LINKLISTTIME   10000

Definition at line 180 of file app_rpt.c.

Referenced by rpt().

#define LINKPOSTSHORTTIME   200

Definition at line 183 of file app_rpt.c.

Referenced by __kickshort().

#define LINKPOSTTIME   30000

Definition at line 182 of file app_rpt.c.

Referenced by rpt().

#define MACRO   "macro"

Definition at line 237 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MACROPTIME   500

Definition at line 187 of file app_rpt.c.

Referenced by rpt().

#define MACROTIME   100

Definition at line 186 of file app_rpt.c.

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

#define MAX_RETRIES   5

Definition at line 203 of file app_rpt.c.

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

#define MAX_RETRIES_PERM   1000000000

Definition at line 204 of file app_rpt.c.

Referenced by connect_link().

#define MAX_STAT_LINKS   32

Definition at line 483 of file app_rpt.c.

Referenced by linkcount(), rpt_do_stats(), and rpt_manager_do_stats().

#define MAX_SYSSTATES   10

Definition at line 490 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXCONNECTTIME   5000

Definition at line 254 of file app_rpt.c.

Referenced by rpt().

#define MAXDTMF   32

Definition at line 177 of file app_rpt.c.

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

#define MAXIDENTLEN   32

Definition at line 260 of file app_rpt.c.

#define MAXLINKLIST   512

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

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

#define MAXNODELEN   16

Definition at line 258 of file app_rpt.c.

#define MAXNODESTR   300

Definition at line 256 of file app_rpt.c.

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

#define MAXPATCHCONTEXT   100

Definition at line 262 of file app_rpt.c.

Referenced by function_autopatchup(), and local_dtmf_helper().

#define MAXPEERSTR   31

Definition at line 220 of file app_rpt.c.

Referenced by rpt_do_lstats().

#define MAXREMSTR   15

Definition at line 221 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(), set_tm271(), setkenwood(), setrbi(), setrbi_check(), setrtx(), setrtx_check(), split_ctcss_freq(), and split_freq().

#define MAXRPTS   20

Definition at line 482 of file app_rpt.c.

#define MAXXLAT   20

Definition at line 487 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXXLATTIME   3

Definition at line 488 of file app_rpt.c.

Referenced by func_xlat().

#define MEMORY   "memory"

Definition at line 236 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MONITOR_DISK_BLOCKS_PER_MINUTE   38

Definition at line 226 of file app_rpt.c.

#define MORSE   "morse"

Definition at line 240 of file app_rpt.c.

Referenced by telem_any().

#define MSWAIT   200

Definition at line 478 of file app_rpt.c.

Referenced by rpt(), and rpt_call().

#define mymax ( x,
 )     ((x > y) ? x : y)

Definition at line 502 of file app_rpt.c.

Referenced by dovox().

#define mymin ( x,
 )     ((x < y) ? x : y)

Definition at line 503 of file app_rpt.c.

Referenced by dovox().

#define NEW_ASTERISK

Definition at line 1 of file app_rpt.c.

#define NODENAMES   "rpt/nodenames"

Definition at line 245 of file app_rpt.c.

Referenced by saynode().

#define NODES   "nodes"

Definition at line 234 of file app_rpt.c.

Referenced by load_rpt_vars().

#define NRPTSTAT   7

Definition at line 448 of file app_rpt.c.

Referenced by rpt_do_lstats().

#define PARROTFILE   "/tmp/parrot_%s_%u"

Definition at line 246 of file app_rpt.c.

Referenced by rpt(), and rpt_tele_thread().

#define PARROTTIME   1000

Definition at line 248 of file app_rpt.c.

Referenced by load_rpt_vars().

#define PATCH_DIALPLAN_TIMEOUT   1500

Definition at line 210 of file app_rpt.c.

Referenced by rpt_call().

#define POLITEID   30000

Definition at line 484 of file app_rpt.c.

Referenced by load_rpt_vars().

#define QUOTECHR   34

Definition at line 224 of file app_rpt.c.

#define REDUNDANT_TX_TIME   2000

Definition at line 206 of file app_rpt.c.

Referenced by rpt().

#define REM_SCANTIME   100

Definition at line 268 of file app_rpt.c.

Referenced by function_remote().

#define RETRY_TIMER_MS   5000

Definition at line 208 of file app_rpt.c.

Referenced by rpt().

#define RPT_LOCKOUT_SECS   10

Definition at line 218 of file app_rpt.c.

Referenced by rpt(), and rpt_exec().

#define rpt_mutex_lock (  )     ast_mutex_lock(x)

Definition at line 1068 of file app_rpt.c.

Referenced by attempt_reconnect(), birdbath(), connect_link(), do_dtmf_local(), flush_telem(), 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_cmd(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rpt_exec(), rpt_manager_do_stats(), rpt_push_alt_macro(), rpt_tele_thread(), rpt_telemetry(), and send_link_keyquery().

#define rpt_mutex_unlock (  )     ast_mutex_unlock(x)

Definition at line 1069 of file app_rpt.c.

Referenced by attempt_reconnect(), birdbath(), connect_link(), do_dtmf_local(), flush_telem(), 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_cmd(), rpt_do_fun(), rpt_do_lstats(), rpt_do_nodes(), rpt_do_stats(), rpt_exec(), rpt_manager_do_stats(), rpt_push_alt_macro(), rpt_tele_thread(), rpt_telemetry(), and send_link_keyquery().

#define SIMPLEX_PATCH_DELAY   25

Definition at line 281 of file app_rpt.c.

Referenced by load_rpt_vars().

#define SIMPLEX_PHONE_DELAY   25

Definition at line 282 of file app_rpt.c.

Referenced by load_rpt_vars().

#define START_DELAY   2

Definition at line 215 of file app_rpt.c.

Referenced by rpt(), and rpt_exec().

#define STATPOST_PROGRAM   "/usr/bin/wget,-q,--output-document=/dev/null,--no-check-certificate"

Definition at line 284 of file app_rpt.c.

Referenced by load_rpt_vars().

#define TELEMETRY   "telemetry"

Definition at line 239 of file app_rpt.c.

Referenced by telem_lookup().

#define TELEPARAMSIZE   256

Definition at line 266 of file app_rpt.c.

Referenced by rpt_telemetry().

#define TONEMACRO   "tonemacro"

Definition at line 241 of file app_rpt.c.

Referenced by load_rpt_vars().

#define TOPKEYMAXSTR   30

Definition at line 192 of file app_rpt.c.

Referenced by handle_link_data().

#define TOPKEYN   32

Definition at line 190 of file app_rpt.c.

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

#define TOPKEYWAIT   3

Definition at line 191 of file app_rpt.c.

Referenced by rpt().

#define TOTIME   180000

Definition at line 480 of file app_rpt.c.

Referenced by load_rpt_vars().

#define VOX_MAX_THRESHOLD   10000.0

Definition at line 277 of file app_rpt.c.

Referenced by dovox().

#define VOX_MIN_THRESHOLD   3000.0

Definition at line 278 of file app_rpt.c.

Referenced by dovox().

#define VOX_OFF_DEBOUNCE_COUNT   20

Definition at line 276 of file app_rpt.c.

Referenced by voxinit_link(), and voxinit_rpt().

#define VOX_ON_DEBOUNCE_COUNT   3

Definition at line 275 of file app_rpt.c.

Referenced by voxinit_link(), and voxinit_rpt().

#define VOX_RECOVER_MS   500

Definition at line 280 of file app_rpt.c.

Referenced by load_rpt_vars().

#define VOX_TIMEOUT_MS   5000

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

anonymous enum

Enumerator:
ID 
PROC 
TERM 
COMPLETE 
UNKEY 
REMDISC 
REMALREADY 
REMNOTFOUND 
REMGO 
CONNECTED 
CONNFAIL 
STATUS 
TIMEOUT 
ID1 
STATS_TIME 
PLAYBACK 
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 
TOPKEY 
TIMEOUT_WARNING 
ACT_TIMEOUT_WARNING 
LINKUNKEY 
UNAUTHTX 
PARROT 
STATS_TIME_LOCAL 

Definition at line 290 of file app_rpt.c.

anonymous enum

Enumerator:
REM_SIMPLEX 
REM_MINUS 
REM_PLUS 

Definition at line 300 of file app_rpt.c.

anonymous enum

Enumerator:
REM_LOWPWR 
REM_MEDPWR 
REM_HIPWR 

Definition at line 302 of file app_rpt.c.

anonymous enum

Enumerator:
DC_INDETERMINATE 
DC_REQ_FLUSH 
DC_ERROR 
DC_COMPLETE 
DC_COMPLETEQUIET 
DC_DOKEY 

Definition at line 304 of file app_rpt.c.

anonymous enum

Enumerator:
SOURCE_RPT 
SOURCE_LNK 
SOURCE_RMT 
SOURCE_PHONE 
SOURCE_DPHONE 
SOURCE_ALT 

Definition at line 306 of file app_rpt.c.

anonymous enum

Enumerator:
DLY_TELEM 
DLY_ID 
DLY_UNKEY 
DLY_CALLTERM 
DLY_COMP 
DLY_LINKUNKEY 
DLY_PARROT 

Definition at line 308 of file app_rpt.c.

anonymous enum

Enumerator:
REM_MODE_FM 
REM_MODE_USB 
REM_MODE_LSB 
REM_MODE_AM 

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

anonymous enum

Enumerator:
TOP_TOP 
TOP_WON 
WON_BEFREAD 
BEFREAD_AFTERREAD 

Definition at line 444 of file app_rpt.c.


Function Documentation

static void __kickshort ( struct rpt myrpt  )  [static]

Definition at line 1935 of file app_rpt.c.

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

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

01936 {
01937 struct rpt_link *l;
01938 
01939    for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
01940    {
01941       /* if is not a real link, ignore it */
01942       if (l->name[0] == '0') continue;
01943       l->linklisttimer = LINKLISTSHORTTIME;
01944    }
01945    myrpt->linkposttimer = LINKPOSTSHORTTIME;
01946    return;
01947 }

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

Definition at line 1885 of file app_rpt.c.

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

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

01886 {
01887 struct rpt_link *l;
01888 char mode;
01889 int   i,spos;
01890 
01891    buf[0] = 0; /* clear output buffer */
01892    if (myrpt->remote) return;
01893    /* go thru all links */
01894    for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
01895    {
01896       /* if is not a real link, ignore it */
01897       if (l->name[0] == '0') continue;
01898       /* dont count our stuff */
01899       if (l == mylink) continue;
01900       if (mylink && (!strcmp(l->name,mylink->name))) continue;
01901       /* figure out mode to report */
01902       mode = 'T'; /* use Tranceive by default */
01903       if (!l->mode) mode = 'R'; /* indicate RX for our mode */
01904       if (!l->thisconnected)  mode = 'C'; /* indicate connecting */
01905       spos = strlen(buf); /* current buf size (b4 we add our stuff) */
01906       if (spos)
01907       {
01908          strcat(buf,",");
01909          spos++;
01910       }
01911       /* add nodes into buffer */
01912       if (l->linklist[0])
01913       {
01914          snprintf(buf + spos,MAXLINKLIST - spos,
01915             "%c%s,%s",mode,l->name,l->linklist);
01916       }
01917       else /* if no nodes, add this node into buffer */
01918       {
01919          snprintf(buf + spos,MAXLINKLIST - spos,
01920             "%c%s",mode,l->name);
01921       }
01922       /* if we are in tranceive mode, let all modes stand */
01923       if (mode == 'T') continue;
01924       /* downgrade everyone on this node if appropriate */
01925       for(i = spos; buf[i]; i++)
01926       {
01927          if (buf[i] == 'T') buf[i] = mode;
01928          if ((buf[i] == 'R') && (mode == 'C')) buf[i] = mode;
01929       }
01930    }
01931    return;
01932 }

static void __reg_module ( void   )  [static]

Definition at line 15212 of file app_rpt.c.

static void __unreg_module ( void   )  [static]

Definition at line 15212 of file app_rpt.c.

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

Start a tone-list going.

Definition at line 215 of file indications.c.

References ast_activate_generator(), ast_free, ast_log(), ast_realloc, ast_strdupa, chan, cos, playtones_item::duration, playtones_item::fac1, playtones_item::fac2, 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, strsep(), and playtones_def::vol.

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

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

void ast_playtones_stop ( struct ast_channel chan  ) 

Stop the tones from playing.

Stop the tones from playing

Definition at line 328 of file indications.c.

References ast_deactivate_generator(), and chan.

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

00329 {
00330    ast_deactivate_generator(chan);
00331 }

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

Definition at line 10330 of file app_rpt.c.

References ast_call(), AST_FORMAT_SLINEAR, ast_free, ast_log(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_strdup, ast_verbose, rpt::links, rpt::lock, LOG_WARNING, rpt::name, rpt_link::name, rpt_link::next, node_lookup(), option_verbose, rpt_mutex_lock, rpt_mutex_unlock, s, send_newkey(), strsep(), and VERBOSE_PREFIX_3.

Referenced by rpt().

10331 {
10332    char *val, *s, *s1, *s2, *tele;
10333    char tmp[300], deststr[300] = "";
10334    char sx[320],*sy;
10335 
10336 
10337    val = node_lookup(myrpt,l->name);
10338    if (!val)
10339    {
10340       fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name);
10341       return -1;
10342    }
10343 
10344    rpt_mutex_lock(&myrpt->lock);
10345    /* remove from queue */
10346    remque((struct qelem *) l);
10347    rpt_mutex_unlock(&myrpt->lock);
10348    strncpy(tmp,val,sizeof(tmp) - 1);
10349    s = tmp;
10350    s1 = strsep(&s,",");
10351    if (!strchr(s1,':') && strchr(s1,'/') && strncasecmp(s1, "local/", 6))
10352    {
10353       sy = strchr(s1,'/');    
10354       *sy = 0;
10355       sprintf(sx,"%s:4569/%s",s1,sy + 1);
10356       s1 = sx;
10357    }
10358    s2 = strsep(&s,",");
10359    snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
10360    tele = strchr(deststr, '/');
10361    if (!tele) {
10362       fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr);
10363       return -1;
10364    }
10365    *tele++ = 0;
10366    l->elaptime = 0;
10367    l->connecttime = 0;
10368    l->thisconnected = 0;
10369    l->newkey = 0;
10370    l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
10371    if (l->chan){
10372       ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
10373       ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
10374 #ifndef  NEW_ASTERISK
10375       l->chan->whentohangup = 0;
10376 #endif
10377       l->chan->appl = "Apprpt";
10378       l->chan->data = "(Remote Rx)";
10379       if (option_verbose > 2)
10380          ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n",
10381             deststr, tele, l->chan->name);
10382       if(l->chan->cid.cid_num)
10383          ast_free(l->chan->cid.cid_num);
10384       l->chan->cid.cid_num = ast_strdup(myrpt->name);
10385                 ast_call(l->chan,tele,999); 
10386 
10387    }
10388    else 
10389    {
10390       if (option_verbose > 2)
10391          ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n",
10392             deststr,tele,l->chan->name);
10393       return -1;
10394    }
10395    rpt_mutex_lock(&myrpt->lock);
10396    /* put back in queue */
10397    insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
10398    rpt_mutex_unlock(&myrpt->lock);
10399    ast_log(LOG_WARNING,"Reconnect Attempt to %s in process\n",l->name);
10400    if (!l->phonemode) send_newkey(l->chan);
10401    return 0;
10402 }

static void birdbath ( struct rpt myrpt  )  [static]

Definition at line 1509 of file app_rpt.c.

References ast_log(), ast_softhangup(), AST_SOFTHANGUP_DEV, rpt_tele::chan, rpt::lock, LOG_NOTICE, rpt_tele::mode, rpt_tele::next, PARROT, rpt_mutex_lock, rpt_mutex_unlock, and rpt::tele.

Referenced by function_cop().

01510 {
01511    struct rpt_tele *telem;
01512    if(debug > 2)
01513       ast_log(LOG_NOTICE, "birdbath!!");
01514    rpt_mutex_lock(&myrpt->lock);
01515    telem = myrpt->tele.next;
01516    while(telem != &myrpt->tele)
01517    {
01518       if (telem->mode == PARROT) ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV);
01519       telem = telem->next;
01520    }
01521    rpt_mutex_unlock(&myrpt->lock);
01522 }

static int channel_revert ( struct rpt myrpt  )  [static]

Definition at line 9618 of file app_rpt.c.

References ast_log(), channel_steer(), LOG_NOTICE, rpt::nowchan, rpt::remoterig, and rpt::waschan.

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

09619 {
09620    int res=0;
09621    if(debug)ast_log(LOG_NOTICE,"remoterig=%s, nowchan=%02d, waschan=%02d\n",myrpt->remoterig,myrpt->nowchan,myrpt->waschan);
09622    if (!myrpt->remoterig) return(0);
09623    if(myrpt->nowchan!=myrpt->waschan)
09624    {
09625       char data[8];
09626         if(debug)ast_log(LOG_NOTICE,"reverting.\n");
09627       sprintf(data,"%02d",myrpt->waschan);
09628       myrpt->nowchan=myrpt->waschan;
09629       channel_steer(myrpt,data);
09630       res=1;
09631    }
09632    return(res);
09633 }

static int channel_steer ( struct rpt myrpt,
char *  data 
) [static]

Definition at line 9589 of file app_rpt.c.

References ast_log(), get_mem_set(), LOG_NOTICE, rpt::nowchan, rpt::remoterig, and send_usb_txt().

Referenced by channel_revert(), function_cop(), and rpt_exec().

09590 {
09591    int res=0;
09592 
09593    if(debug)ast_log(LOG_NOTICE,"remoterig=%s, data=%s\n",myrpt->remoterig,data);
09594    if (!myrpt->remoterig) return(0);
09595    if(data<=0)
09596    {
09597       res=-1;
09598    }
09599    else
09600    {
09601       myrpt->nowchan=strtod(data,NULL);
09602       if(!strcmp(myrpt->remoterig, remote_rig_ppp16))
09603       {
09604          char string[16];
09605          sprintf(string,"SETCHAN %d ",myrpt->nowchan);
09606          send_usb_txt(myrpt,string);   
09607       }
09608       else
09609       {
09610          if(get_mem_set(myrpt, data))res=-1;
09611       }
09612    }
09613    if(debug)ast_log(LOG_NOTICE,"nowchan=%i  res=%i\n",myrpt->nowchan, res);
09614    return res;
09615 }

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

Definition at line 9313 of file app_rpt.c.

References check_freq_ft897(), check_freq_ic706(), check_freq_kenwood(), check_freq_rbi(), check_freq_rtx(), check_freq_tm271(), ISRIG_RTX, rpt::p, rpt::remote_mars, and rpt::remoterig.

Referenced by function_remote().

09314 {
09315    if(!strcmp(myrpt->remoterig, remote_rig_ft897))
09316       return check_freq_ft897(m, d, defmode);
09317    else if(!strcmp(myrpt->remoterig, remote_rig_ic706))
09318       return check_freq_ic706(m, d, defmode,myrpt->p.remote_mars);
09319    else if(!strcmp(myrpt->remoterig, remote_rig_rbi))
09320       return check_freq_rbi(m, d, defmode);
09321    else if(!strcmp(myrpt->remoterig, remote_rig_kenwood))
09322       return check_freq_kenwood(m, d, defmode);
09323    else if(!strcmp(myrpt->remoterig, remote_rig_tm271))
09324       return check_freq_tm271(m, d, defmode);
09325    else if(ISRIG_RTX(myrpt->remoterig))
09326       return check_freq_rtx(m, d, defmode, myrpt);
09327    else
09328       return -1;
09329 }

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

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

08275 {
08276    int dflmd = REM_MODE_FM;
08277 
08278    if(m == 1){ /* 160 meters */
08279       dflmd =  REM_MODE_LSB; 
08280       if(d < 80000)
08281          return -1;
08282    }
08283    else if(m == 3){ /* 80 meters */
08284       dflmd = REM_MODE_LSB;
08285       if(d < 50000)
08286          return -1;
08287    }
08288    else if(m == 7){ /* 40 meters */
08289       dflmd = REM_MODE_LSB;
08290       if(d > 30000)
08291          return -1;
08292    }
08293    else if(m == 14){ /* 20 meters */
08294       dflmd = REM_MODE_USB;
08295       if(d > 35000)
08296          return -1;
08297    }
08298    else if(m == 18){ /* 17 meters */
08299       dflmd = REM_MODE_USB;
08300       if((d < 6800) || (d > 16800))
08301          return -1;
08302    }
08303    else if(m == 21){ /* 15 meters */
08304       dflmd = REM_MODE_USB;
08305       if((d < 20000) || (d > 45000))
08306          return -1;
08307    }
08308    else if(m == 24){ /* 12 meters */
08309       dflmd = REM_MODE_USB;
08310       if((d < 89000) || (d > 99000))
08311          return -1;
08312    }
08313    else if(m == 28){ /* 10 meters */
08314       dflmd = REM_MODE_USB;
08315    }
08316    else if(m == 29){ 
08317       if(d >= 51000)
08318          dflmd = REM_MODE_FM;
08319       else
08320          dflmd = REM_MODE_USB;
08321       if(d > 70000)
08322          return -1;
08323    }
08324    else if(m == 50){ /* 6 meters */
08325       if(d >= 30000)
08326          dflmd = REM_MODE_FM;
08327       else
08328          dflmd = REM_MODE_USB;
08329 
08330    }
08331    else if((m >= 51) && ( m < 54)){
08332       dflmd = REM_MODE_FM;
08333    }
08334    else if(m == 144){ /* 2 meters */
08335       if(d >= 30000)
08336          dflmd = REM_MODE_FM;
08337       else
08338          dflmd = REM_MODE_USB;
08339    }
08340    else if((m >= 145) && (m < 148)){
08341       dflmd = REM_MODE_FM;
08342    }
08343    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
08344       if(m  < 438)
08345          dflmd = REM_MODE_USB;
08346       else
08347          dflmd = REM_MODE_FM;
08348       ;
08349    }
08350    else
08351       return -1;
08352 
08353    if(defmode)
08354       *defmode = dflmd;
08355 
08356    return 0;
08357 }

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

Definition at line 8644 of file app_rpt.c.

References ast_log(), LOG_NOTICE, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, and REM_MODE_USB.

Referenced by check_freq(), and multimode_bump_freq_ic706().

08645 {
08646    int dflmd = REM_MODE_FM;
08647    int rv=0;
08648 
08649    if(debug > 6)
08650       ast_log(LOG_NOTICE,"(%i,%i,%i,%i)\n",m,d,*defmode,mars);
08651 
08652    /* first test for standard amateur radio bands */
08653 
08654    if(m == 1){                /* 160 meters */
08655       dflmd =  REM_MODE_LSB; 
08656       if(d < 80000)rv=-1;
08657    }
08658    else if(m == 3){           /* 80 meters */
08659       dflmd = REM_MODE_LSB;
08660       if(d < 50000)rv=-1;
08661    }
08662    else if(m == 7){           /* 40 meters */
08663       dflmd = REM_MODE_LSB;
08664       if(d > 30000)rv=-1;
08665    }
08666    else if(m == 14){             /* 20 meters */
08667       dflmd = REM_MODE_USB;
08668       if(d > 35000)rv=-1;
08669    }
08670    else if(m == 18){                      /* 17 meters */
08671       dflmd = REM_MODE_USB;
08672       if((d < 6800) || (d > 16800))rv=-1;
08673    }
08674    else if(m == 21){ /* 15 meters */
08675       dflmd = REM_MODE_USB;
08676       if((d < 20000) || (d > 45000))rv=-1;
08677    }
08678    else if(m == 24){ /* 12 meters */
08679       dflmd = REM_MODE_USB;
08680       if((d < 89000) || (d > 99000))rv=-1;
08681    }
08682    else if(m == 28){                      /* 10 meters */
08683       dflmd = REM_MODE_USB;
08684    }
08685    else if(m == 29){ 
08686       if(d >= 51000)
08687          dflmd = REM_MODE_FM;
08688       else
08689          dflmd = REM_MODE_USB;
08690       if(d > 70000)rv=-1;
08691    }
08692    else if(m == 50){                      /* 6 meters */
08693       if(d >= 30000)
08694          dflmd = REM_MODE_FM;
08695       else
08696          dflmd = REM_MODE_USB;
08697    }
08698    else if((m >= 51) && ( m < 54)){
08699       dflmd = REM_MODE_FM;
08700    }
08701    else if(m == 144){ /* 2 meters */
08702       if(d >= 30000)
08703          dflmd = REM_MODE_FM;
08704       else
08705          dflmd = REM_MODE_USB;
08706    }
08707    else if((m >= 145) && (m < 148)){
08708       dflmd = REM_MODE_FM;
08709    }
08710    else if((m >= 430) && (m < 450)){         /* 70 centimeters */
08711       if(m  < 438)
08712          dflmd = REM_MODE_USB;
08713       else
08714          dflmd = REM_MODE_FM;
08715    }
08716 
08717    /* check expanded coverage */
08718    if(mars && rv<0){
08719       if((m >= 450) && (m < 470)){        /* LMR */
08720          dflmd = REM_MODE_FM;
08721          rv=0;
08722       }
08723       else if((m >= 148) && (m < 174)){      /* LMR */
08724          dflmd = REM_MODE_FM;
08725          rv=0;
08726       }
08727       else if((m >= 138) && (m < 144)){      /* VHF-AM AIRCRAFT */
08728          dflmd = REM_MODE_AM;
08729          rv=0;
08730       }
08731       else if((m >= 108) && (m < 138)){      /* VHF-AM AIRCRAFT */
08732          dflmd = REM_MODE_AM;
08733          rv=0;
08734       }
08735       else if( (m==0 && d>=55000) || (m==1 && d<=75000) ){  /* AM BCB*/
08736          dflmd = REM_MODE_AM;
08737          rv=0;
08738       }
08739       else if( (m == 1 && d>75000) || (m>1 && m<30) ){      /* HF SWL*/
08740          dflmd = REM_MODE_AM;
08741          rv=0;
08742       }
08743    }
08744 
08745    if(defmode)
08746       *defmode = dflmd;
08747 
08748    if(debug > 1)
08749       ast_log(LOG_NOTICE,"(%i,%i,%i,%i) returning %i\n",m,d,*defmode,mars,rv);
08750 
08751    return rv;
08752 }

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

Definition at line 8080 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

08081 {
08082    int dflmd = REM_MODE_FM;
08083 
08084    if (m == 144){ /* 2 meters */
08085       if(d < 10100)
08086          return -1;
08087    }
08088    else if((m >= 145) && (m < 148)){
08089       ;
08090    }
08091    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
08092       ;
08093    }
08094    else
08095       return -1;
08096    
08097    if(defmode)
08098       *defmode = dflmd; 
08099 
08100 
08101    return 0;
08102 }

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

Definition at line 8129 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

08130 {
08131    int dflmd = REM_MODE_FM;
08132 
08133    if(m == 50){ /* 6 meters */
08134       if(d < 10100)
08135          return -1;
08136    }
08137    else if((m >= 51) && ( m < 54)){
08138                 ;
08139    }
08140    else if(m == 144){ /* 2 meters */
08141       if(d < 10100)
08142          return -1;
08143    }
08144    else if((m >= 145) && (m < 148)){
08145       ;
08146    }
08147    else if((m >= 222) && (m < 225)){ /* 1.25 meters */
08148       ;
08149    }
08150    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
08151       ;
08152    }
08153    else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */
08154       ;
08155    }
08156    else
08157       return -1;
08158    
08159    if(defmode)
08160       *defmode = dflmd; 
08161 
08162 
08163    return 0;
08164 }

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

Definition at line 8169 of file app_rpt.c.

References REM_MODE_FM, and rpt::remoterig.

Referenced by check_freq().

08170 {
08171    int dflmd = REM_MODE_FM;
08172 
08173    if (!strcmp(myrpt->remoterig,remote_rig_rtx150))
08174    {
08175 
08176       if(m == 144){ /* 2 meters */
08177          if(d < 10100)
08178             return -1;
08179       }
08180       else if((m >= 145) && (m < 148)){
08181          ;
08182       }
08183       else
08184          return -1;
08185    }
08186    else 
08187    {
08188       if((m >= 430) && (m < 450)){ /* 70 centimeters */
08189          ;
08190       }
08191       else
08192          return -1;
08193    }
08194    if(defmode)
08195       *defmode = dflmd; 
08196 
08197 
08198    return 0;
08199 }

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

Definition at line 8105 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

08106 {
08107    int dflmd = REM_MODE_FM;
08108 
08109    if (m == 144){ /* 2 meters */
08110       if(d < 10100)
08111          return -1;
08112    }
08113    else if((m >= 145) && (m < 148)){
08114       ;
08115    }
08116       return -1;
08117    
08118    if(defmode)
08119       *defmode = dflmd; 
08120 
08121 
08122    return 0;
08123 }

static char check_tx_freq ( struct rpt myrpt  )  [static]

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

09337 {
09338    int i,rv=0;
09339    int radio_mhz, radio_decimals, ulimit_mhz, ulimit_decimals, llimit_mhz, llimit_decimals;
09340    char radio_mhz_char[MAXREMSTR];
09341    char radio_decimals_char[MAXREMSTR];
09342    char limit_mhz_char[MAXREMSTR];
09343    char limit_decimals_char[MAXREMSTR];
09344    char limits[256];
09345    char *limit_ranges[40];
09346    struct ast_variable *limitlist;
09347    
09348    if(debug > 3){
09349       ast_log(LOG_NOTICE, "myrpt->freq = %s\n", myrpt->freq);
09350    }
09351 
09352    /* Must have user logged in and tx_limits defined */
09353 
09354    if(!myrpt->p.txlimitsstanzaname || !myrpt->loginuser[0] || !myrpt->loginlevel[0]){
09355       if(debug > 3){
09356          ast_log(LOG_NOTICE, "No tx band table defined, or no user logged in. rv=1\n");
09357       }
09358       rv=1;
09359       return 1; /* Assume it's ok otherwise */
09360    }
09361 
09362    /* Retrieve the band table for the loginlevel */
09363    limitlist = ast_variable_browse(myrpt->cfg, myrpt->p.txlimitsstanzaname);
09364 
09365    if(!limitlist){
09366       ast_log(LOG_WARNING, "No entries in %s band table stanza. rv=0\n", myrpt->p.txlimitsstanzaname);
09367       rv=0;
09368       return 0;
09369    }
09370 
09371    split_freq(radio_mhz_char, radio_decimals_char, myrpt->freq);
09372    radio_mhz = atoi(radio_mhz_char);
09373    radio_decimals = decimals2int(radio_decimals_char);
09374 
09375    if(debug > 3){
09376       ast_log(LOG_NOTICE, "Login User = %s, login level = %s\n", myrpt->loginuser, myrpt->loginlevel);
09377    }
09378 
09379    /* Find our entry */
09380 
09381    for(;limitlist; limitlist=limitlist->next){
09382       if(!strcmp(limitlist->name, myrpt->loginlevel))
09383          break;
09384    }
09385 
09386    if(!limitlist){
09387       ast_log(LOG_WARNING, "Can't find %s entry in band table stanza %s. rv=0\n", myrpt->loginlevel, myrpt->p.txlimitsstanzaname);
09388       rv=0;
09389        return 0;
09390    }
09391    
09392    if(debug > 3){
09393       ast_log(LOG_NOTICE, "Auth: %s = %s\n", limitlist->name, limitlist->value);
09394    }
09395 
09396    /* Parse the limits */
09397 
09398    strncpy(limits, limitlist->value, 256);
09399    limits[255] = 0;
09400    finddelim(limits, limit_ranges, 40);
09401    for(i = 0; i < 40 && limit_ranges[i] ; i++){
09402       char range[40];
09403       char *r,*s;
09404       strncpy(range, limit_ranges[i], 40);
09405       range[39] = 0;
09406         if(debug > 3) 
09407          ast_log(LOG_NOTICE, "Check %s within %s\n", myrpt->freq, range);
09408    
09409       r = strchr(range, '-');
09410       if(!r){
09411          ast_log(LOG_WARNING, "Malformed range in %s tx band table entry. rv=0\n", limitlist->name);
09412          rv=0;
09413          break;
09414       }
09415       *r++ = 0;
09416       s = eatwhite(range);
09417       r = eatwhite(r);
09418       split_freq(limit_mhz_char, limit_decimals_char, s);
09419       llimit_mhz = atoi(limit_mhz_char);
09420       llimit_decimals = decimals2int(limit_decimals_char);
09421       split_freq(limit_mhz_char, limit_decimals_char, r);
09422       ulimit_mhz = atoi(limit_mhz_char);
09423       ulimit_decimals = decimals2int(limit_decimals_char);
09424          
09425       if((radio_mhz >= llimit_mhz) && (radio_mhz <= ulimit_mhz)){
09426          if(radio_mhz == llimit_mhz){ /* CASE 1: TX freq is in llimit mhz portion of band */
09427             if(radio_decimals >= llimit_decimals){ /* Cannot be below llimit decimals */
09428                if(llimit_mhz == ulimit_mhz){ /* If bandwidth < 1Mhz, check ulimit decimals */
09429                   if(radio_decimals <= ulimit_decimals){
09430                      rv=1;
09431                      break;
09432                   }
09433                   else{
09434                      if(debug > 3)
09435                         ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 1\n");
09436                      rv=0;
09437                      break;
09438                   }
09439                }
09440                else{
09441                   rv=1;
09442                   break;
09443                }
09444             }
09445             else{ /* Is below llimit decimals */
09446                if(debug > 3)
09447                   ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 2\n");
09448                rv=0;
09449                break;
09450             }
09451          }
09452          else if(radio_mhz == ulimit_mhz){ /* CASE 2: TX freq not in llimit mhz portion of band */
09453             if(radio_decimals <= ulimit_decimals){
09454                if(debug > 3)
09455                   ast_log(LOG_NOTICE, "radio_decimals <= ulimit_decimals\n");
09456                rv=1;
09457                break;
09458             }
09459             else{ /* Is above ulimit decimals */
09460                if(debug > 3)
09461                   ast_log(LOG_NOTICE, "Invalid TX frequency, debug msg 3\n");
09462                rv=0;
09463                break;
09464             }
09465          }
09466          else /* CASE 3: TX freq within a multi-Mhz band and ok */
09467             if(debug > 3)
09468                   ast_log(LOG_NOTICE, "Valid TX freq within a multi-Mhz band and ok.\n");
09469             rv=1;
09470             break;
09471       }
09472    }
09473    if(debug > 3)  
09474       ast_log(LOG_NOTICE, "rv=%i\n",rv);
09475 
09476    return rv;
09477 }

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

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

07506 {
07507 unsigned char rxbuf[100];
07508 int   i,rv ;
07509 
07510    rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0);
07511    if (rv == -1) return(-1);
07512    if (rv != (cmdlen + 6)) return(1);
07513    for(i = 0; i < 6; i++)
07514       if (rxbuf[i] != cmd[i]) return(1);
07515    if (rxbuf[cmdlen] != 0xfe) return(1);
07516    if (rxbuf[cmdlen + 1] != 0xfe) return(1);
07517    if (rxbuf[cmdlen + 4] != 0xfb) return(1);
07518    if (rxbuf[cmdlen + 5] != 0xfd) return(1);
07519    return(0);
07520 }

static int closerem ( struct rpt myrpt  )  [static]

Definition at line 9301 of file app_rpt.c.

References closerem_ft897(), and rpt::remoterig.

09302 {
09303    if(!strcmp(myrpt->remoterig, remote_rig_ft897))
09304       return closerem_ft897(myrpt);
09305    else
09306       return 0;
09307 }

static int closerem_ft897 ( struct rpt myrpt  )  [static]

Definition at line 8585 of file app_rpt.c.

References simple_command_ft897().

Referenced by closerem().

08586 {
08587    simple_command_ft897(myrpt, 0x88); /* PTT off */
08588    return 0;
08589 }  

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

Definition at line 6596 of file app_rpt.c.

References rpt::alt_functions, rpt::alt_longestfunc, ast_log(), 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, LOG_NOTICE, rpt::longestfunc, ast_variable::name, ast_variable::next, rpt::p, rpt::phone_functions, rpt::phone_longestfunc, SOURCE_ALT, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, strsep(), and ast_variable::value.

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

06598 {
06599    int i,rv;
06600    char *stringp,*action,*param,*functiondigits;
06601    char function_table_name[30] = "";
06602    char workstring[200];
06603    
06604    struct ast_variable *vp;
06605    
06606    if (debug > 6) ast_log(LOG_NOTICE,"digits=%s  source=%d\n",digits, command_source);
06607 
06608    //if(debug) 
06609    // printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source);
06610    
06611    if (command_source == SOURCE_DPHONE) {
06612       if (!myrpt->p.dphone_functions) return DC_INDETERMINATE;
06613       strncpy(function_table_name, myrpt->p.dphone_functions, sizeof(function_table_name) - 1);
06614       }
06615    else if (command_source == SOURCE_ALT) {
06616       if (!myrpt->p.alt_functions) return DC_INDETERMINATE;
06617       strncpy(function_table_name, myrpt->p.alt_functions, sizeof(function_table_name) - 1);
06618       }
06619    else if (command_source == SOURCE_PHONE) {
06620       if (!myrpt->p.phone_functions) return DC_INDETERMINATE;
06621       strncpy(function_table_name, myrpt->p.phone_functions, sizeof(function_table_name) - 1);
06622       }
06623    else if (command_source == SOURCE_LNK)
06624       strncpy(function_table_name, myrpt->p.link_functions, sizeof(function_table_name) - 1);
06625    else
06626       strncpy(function_table_name, myrpt->p.functions, sizeof(function_table_name) - 1);
06627     /* find context for function table in rpt.conf file */
06628    vp = ast_variable_browse(myrpt->cfg, function_table_name);
06629    while(vp) {
06630       if(!strncasecmp(vp->name, digits, strlen(vp->name)))
06631          break;
06632       vp = vp->next;
06633    }  
06634    /* if function context not found */
06635    if(!vp) {
06636       int n;
06637 
06638       n = myrpt->longestfunc;
06639       if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc;
06640       else 
06641       if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc;
06642       else 
06643       if (command_source == SOURCE_ALT) n = myrpt->alt_longestfunc;
06644       else 
06645       if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc;
06646       
06647       if(strlen(digits) >= n)
06648          return DC_ERROR;
06649       else
06650          return DC_INDETERMINATE;
06651    }  
06652    /* Found a match, retrieve value part and parse */
06653    strncpy(workstring, vp->value, sizeof(workstring) - 1 );
06654    stringp = workstring;
06655    action = strsep(&stringp, ",");
06656    param = stringp;
06657    if(debug)
06658       printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)");
06659    /* Look up the action */
06660    for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){
06661       if(!strncasecmp(action, function_table[i].action, strlen(action)))
06662          break;
06663    }
06664    if(debug)
06665       printf("@@@@ table index i = %d\n",i);
06666    if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){
06667       /* Error, action not in table */
06668       return DC_ERROR;
06669    }
06670    if(function_table[i].function == NULL){
06671       /* Error, function undefined */
06672       if(debug)
06673          printf("@@@@ NULL for action: %s\n",action);
06674       return DC_ERROR;
06675    }
06676    functiondigits = digits + strlen(vp->name);
06677    rv=(*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink);
06678    if (debug > 6) ast_log(LOG_NOTICE,"rv=%i\n",rv);
06679    return(rv);
06680 }

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

Definition at line 5685 of file app_rpt.c.

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

Referenced by function_ilink().

05686 {
05687    char *val, *s, *s1, *s2, *tele;
05688    char lstr[MAXLINKLIST],*strs[MAXLINKLIST];
05689    char tmp[300], deststr[300] = "",modechange = 0;
05690    char sx[320],*sy;
05691    struct rpt_link *l;
05692    int reconnects = 0;
05693    int i,n;
05694    struct dahdi_confinfo ci;  /* conference info */
05695 
05696    val = node_lookup(myrpt,node);
05697    if (!val){
05698       if(strlen(node) >= myrpt->longestnode)
05699          return -1; /* No such node */
05700       return 1; /* No match yet */
05701    }
05702 
05703    if(!strcmp(myrpt->name,node)) /* Do not allow connections to self */
05704       return -2;
05705       
05706    if(debug > 3){
05707       ast_log(LOG_NOTICE,"Connect attempt to node %s\n", node);
05708       ast_log(LOG_NOTICE,"Mode: %s\n",(mode)?"Transceive":"Monitor");
05709       ast_log(LOG_NOTICE,"Connection type: %s\n",(perma)?"Permalink":"Normal");
05710    }
05711 
05712    strncpy(tmp,val,sizeof(tmp) - 1);
05713    s = tmp;
05714    s1 = strsep(&s,",");
05715    if (!strchr(s1,':') && strchr(s1,'/') && strncasecmp(s1, "local/", 6))
05716    {
05717       sy = strchr(s1,'/');    
05718       *sy = 0;
05719       sprintf(sx,"%s:4569/%s",s1,sy + 1);
05720       s1 = sx;
05721    }
05722    s2 = strsep(&s,",");
05723    rpt_mutex_lock(&myrpt->lock);
05724    l = myrpt->links.next;
05725    /* try to find this one in queue */
05726    while(l != &myrpt->links){
05727       if (l->name[0] == '0') 
05728       {
05729          l = l->next;
05730          continue;
05731       }
05732    /* if found matching string */
05733       if (!strcmp(l->name, node))
05734          break;
05735       l = l->next;
05736    }
05737    /* if found */
05738    if (l != &myrpt->links){ 
05739    /* if already in this mode, just ignore */
05740       if ((l->mode) || (!l->chan)) {
05741          rpt_mutex_unlock(&myrpt->lock);
05742          return 2; /* Already linked */
05743       }
05744       reconnects = l->reconnects;
05745       rpt_mutex_unlock(&myrpt->lock);
05746       if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV);
05747       l->retries = l->max_retries + 1;
05748       l->disced = 2;
05749       modechange = 1;
05750    } else
05751    {
05752       __mklinklist(myrpt,NULL,lstr);
05753       rpt_mutex_unlock(&myrpt->lock);
05754       n = finddelim(lstr,strs,MAXLINKLIST);
05755       for(i = 0; i < n; i++)
05756       {
05757          if ((*strs[i] < '0') || 
05758              (*strs[i] > '9')) strs[i]++;
05759          if (!strcmp(strs[i],node))
05760          {
05761             return 2; /* Already linked */
05762          }
05763       }
05764    }
05765    strncpy(myrpt->lastlinknode,node,MAXNODESTR - 1);
05766    /* establish call */
05767    l = ast_malloc(sizeof(struct rpt_link));
05768    if (!l)
05769    {
05770       ast_log(LOG_WARNING, "Unable to malloc\n");
05771       return -1;
05772    }
05773    /* zero the silly thing */
05774    memset((char *)l,0,sizeof(struct rpt_link));
05775    l->mode = mode;
05776    l->outbound = 1;
05777    l->thisconnected = 0;
05778    voxinit_link(l,1);
05779    strncpy(l->name, node, MAXNODESTR - 1);
05780    l->isremote = (s && ast_true(s));
05781    if (modechange) l->connected = 1;
05782    l->hasconnected = l->perma = perma;
05783 #ifdef ALLOW_LOCAL_CHANNELS
05784    if ((strncasecmp(s1,"iax2/", 5) == 0) || (strncasecmp(s1, "local/", 6) == 0))
05785          strncpy(deststr, s1, sizeof(deststr));
05786    else
05787            snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
05788 #else
05789    snprintf(deststr, sizeof(deststr), "IAX2/%s", s1);
05790 #endif
05791    tele = strchr(deststr, '/');
05792    if (!tele){
05793       ast_log(LOG_WARNING,"link3:Dial number (%s) must be in format tech/number\n",deststr);
05794       ast_free(l);
05795       return -1;
05796    }
05797    *tele++ = 0;
05798    l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL);
05799    if (l->chan){
05800       ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
05801       ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
05802 #ifdef   AST_CDR_FLAG_POST_DISABLED
05803       if (l->chan->cdr)
05804          ast_set_flag(l->chan->cdr,AST_CDR_FLAG_POST_DISABLED);
05805 #endif
05806 #ifndef  NEW_ASTERISK
05807       l->chan->whentohangup = 0;
05808 #endif
05809       l->chan->appl = "Apprpt";
05810       l->chan->data = "(Remote Rx)";
05811       if (debug > 3)
05812          ast_log(LOG_NOTICE, "rpt (remote) initiating call to %s/%s on %s\n",
05813       deststr, tele, l->chan->name);
05814       if(l->chan->cid.cid_num)
05815          ast_free(l->chan->cid.cid_num);
05816       l->chan->cid.cid_num = ast_strdup(myrpt->name);
05817       ast_call(l->chan,tele,999);
05818    }
05819    else {
05820       if(debug > 3) 
05821          ast_log(LOG_NOTICE, "Unable to place call to %s/%s on %s\n",
05822       deststr,tele,l->chan->name);
05823       if (myrpt->p.archivedir)
05824       {
05825          char str[100];
05826          sprintf(str,"LINKFAIL,%s",l->name);
05827          donodelog(myrpt,str);
05828       }
05829       ast_free(l);
05830       return -1;
05831    }
05832    /* allocate a pseudo-channel thru asterisk */
05833    l->pchan = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
05834    if (!l->pchan){
05835       ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n");
05836       ast_hangup(l->chan);
05837       ast_free(l);
05838       return -1;
05839    }
05840    ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR);
05841    ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR);
05842 #ifdef   AST_CDR_FLAG_POST_DISABLED
05843    if (l->pchan->cdr)
05844       ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
05845 #endif
05846    /* make a conference for the tx */
05847    ci.chan = 0;
05848    ci.confno = myrpt->conf;
05849    ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER;
05850    /* first put the channel on the conference in proper mode */
05851    if (ioctl(l->pchan->fds[0], DAHDI_SETCONF, &ci) == -1)
05852    {
05853       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
05854       ast_hangup(l->chan);
05855       ast_hangup(l->pchan);
05856       ast_free(l);
05857       return -1;
05858    }
05859    rpt_mutex_lock(&myrpt->lock);
05860    l->reconnects = reconnects;
05861    /* insert at end of queue */
05862    l->max_retries = MAX_RETRIES;
05863    if (perma)
05864       l->max_retries = MAX_RETRIES_PERM;
05865    if (l->isremote) l->retries = l->max_retries + 1;
05866    insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
05867    __kickshort(myrpt);
05868    rpt_mutex_unlock(&myrpt->lock);
05869    if (!l->phonemode) send_newkey(l->chan);
05870    return 0;
05871 }

static int decimals2int ( char *  fraction  )  [static]

Definition at line 8205 of file app_rpt.c.

Referenced by check_tx_freq().

08206 {
08207    int i;
08208    char len = strlen(fraction);
08209    int multiplier = 100000;
08210    int res = 0;
08211 
08212    if(!len)
08213       return 0;
08214    for( i = 0 ; i < len ; i++, multiplier /= 10)
08215       res += (fraction[i] - '0') * multiplier;
08216    return res;
08217 }

static long diskavail ( struct rpt myrpt  )  [static]

Definition at line 1334 of file app_rpt.c.

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

Referenced by rpt().

01335 {
01336 struct   statfs statfsbuf;
01337 
01338    if (!myrpt->p.archivedir) return(0);
01339    if (statfs(myrpt->p.archivedir,&statfsbuf) == -1)
01340    {
01341       ast_log(LOG_WARNING,"Cannot get filesystem size for %s node %s\n",
01342          myrpt->p.archivedir,myrpt->name);
01343       return(-1);
01344    }
01345    return(statfsbuf.f_bavail);
01346 }

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

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

01580 {
01581 int   i;
01582 char  digit;
01583 static const char* dtmf_tones[] = {
01584    "!941+1336/200,!0/200", /* 0 */
01585    "!697+1209/200,!0/200", /* 1 */
01586    "!697+1336/200,!0/200", /* 2 */
01587    "!697+1477/200,!0/200", /* 3 */
01588    "!770+1209/200,!0/200", /* 4 */
01589    "!770+1336/200,!0/200", /* 5 */
01590    "!770+1477/200,!0/200", /* 6 */
01591    "!852+1209/200,!0/200", /* 7 */
01592    "!852+1336/200,!0/200", /* 8 */
01593    "!852+1477/200,!0/200", /* 9 */
01594    "!697+1633/200,!0/200", /* A */
01595    "!770+1633/200,!0/200", /* B */
01596    "!852+1633/200,!0/200", /* C */
01597    "!941+1633/200,!0/200", /* D */
01598    "!941+1209/200,!0/200", /* * */
01599    "!941+1477/200,!0/200" };  /* # */
01600 
01601 
01602    if (c)
01603    {
01604       snprintf(myrpt->dtmf_local_str + strlen(myrpt->dtmf_local_str),sizeof(myrpt->dtmf_local_str) - 1,"%c",c);
01605       if (!myrpt->dtmf_local_timer) 
01606           myrpt->dtmf_local_timer = DTMF_LOCAL_STARTTIME;
01607    }
01608    /* if at timeout */
01609    if (myrpt->dtmf_local_timer == 1)
01610    {
01611       if(debug > 6)
01612          ast_log(LOG_NOTICE,"time out dtmf_local_timer=%i\n",myrpt->dtmf_local_timer);
01613 
01614       /* if anything in the string */
01615       if (myrpt->dtmf_local_str[0])
01616       {
01617          digit = myrpt->dtmf_local_str[0];
01618          myrpt->dtmf_local_str[0] = 0;
01619          for(i = 1; myrpt->dtmf_local_str[i]; i++)
01620          {
01621             myrpt->dtmf_local_str[i - 1] =
01622                myrpt->dtmf_local_str[i];
01623          }
01624          myrpt->dtmf_local_str[i - 1] = 0;
01625          myrpt->dtmf_local_timer = DTMF_LOCAL_TIME;
01626          rpt_mutex_unlock(&myrpt->lock);
01627          if (digit >= '0' && digit <='9')
01628             ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'0'], 0);
01629          else if (digit >= 'A' && digit <= 'D')
01630             ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[digit-'A'+10], 0);
01631          else if (digit == '*')
01632             ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[14], 0);
01633          else if (digit == '#')
01634             ast_playtones_start(myrpt->txchannel, 0, dtmf_tones[15], 0);
01635          else {
01636             /* not handled */
01637             ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, myrpt->txchannel->name);
01638          }
01639          rpt_mutex_lock(&myrpt->lock);
01640       }
01641       else
01642       {
01643          myrpt->dtmf_local_timer = 0;
01644       }
01645    }
01646 }

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

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

01525 {
01526 struct        rpt_link *l;
01527 
01528        l = myrpt->links.next;
01529        /* go thru all the links */
01530        while(l != &myrpt->links)
01531        {
01532                if (!l->phonemode)
01533                {
01534                        l = l->next;
01535                        continue;
01536                }
01537                /* dont send to self */
01538                if (mylink && (l == mylink))
01539                {
01540                        l = l->next;
01541                        continue;
01542                }
01543 #ifdef   NEW_ASTERISK
01544                if (l->chan) ast_senddigit(l->chan,c,0);
01545 #else
01546                if (l->chan) ast_senddigit(l->chan,c);
01547 #endif
01548                l = l->next;
01549        }
01550        return;
01551 }

static void do_scheduler ( struct rpt myrpt  )  [static]

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

10601 {
10602    int i,res;
10603 
10604 #ifdef   NEW_ASTERISK
10605    struct ast_tm tmnow;
10606 #else
10607    struct tm tmnow;
10608 #endif
10609    struct ast_variable *skedlist;
10610    char *strs[5],*vp,*val,value[100];
10611 
10612    memcpy(&myrpt->lasttv, &myrpt->curtv, sizeof(struct timeval));
10613    
10614    if( (res = gettimeofday(&myrpt->curtv, NULL)) < 0)
10615       ast_log(LOG_NOTICE, "Scheduler gettime of day returned: %s\n", strerror(res));
10616 
10617    /* Try to get close to a 1 second resolution */
10618    
10619    if(myrpt->lasttv.tv_sec == myrpt->curtv.tv_sec)
10620       return;
10621 
10622    rpt_localtime(&myrpt->curtv.tv_sec, &tmnow);
10623 
10624    /* If midnight, then reset all daily statistics */
10625    
10626    if((tmnow.tm_hour == 0)&&(tmnow.tm_min == 0)&&(tmnow.tm_sec == 0)){
10627       myrpt->dailykeyups = 0;
10628       myrpt->dailytxtime = 0;
10629       myrpt->dailykerchunks = 0;
10630       myrpt->dailyexecdcommands = 0;
10631    }
10632 
10633    if(tmnow.tm_sec != 0)
10634       return;
10635 
10636    /* Code below only executes once per minute */
10637 
10638 
10639    /* Don't schedule if remote */
10640 
10641         if (myrpt->remote)
10642                 return;
10643 
10644    /* Don't schedule if disabled */
10645 
10646         if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable){
10647       if(debug > 6)
10648          ast_log(LOG_NOTICE, "Scheduler disabled\n");
10649       return;
10650    }
10651 
10652    if(!myrpt->p.skedstanzaname){ /* No stanza means we do nothing */
10653       if(debug > 6)
10654          ast_log(LOG_NOTICE,"No stanza for scheduler in rpt.conf\n");
10655       return;
10656    }
10657 
10658     /* get pointer to linked list of scheduler entries */
10659     skedlist = ast_variable_browse(myrpt->cfg, myrpt->p.skedstanzaname);
10660 
10661    if(debug > 6){
10662       ast_log(LOG_NOTICE, "Time now: %02d:%02d %02d %02d %02d\n",
10663          tmnow.tm_hour,tmnow.tm_min,tmnow.tm_mday,tmnow.tm_mon + 1, tmnow.tm_wday); 
10664    }
10665    /* walk the list */
10666    for(; skedlist; skedlist = skedlist->next){
10667       if(debug > 6)
10668          ast_log(LOG_NOTICE, "Scheduler entry %s = %s being considered\n",skedlist->name, skedlist->value);
10669       strncpy(value,skedlist->value,99);
10670       value[99] = 0;
10671       /* point to the substrings for minute, hour, dom, month, and dow */
10672       for( i = 0, vp = value ; i < 5; i++){
10673          if(!*vp)
10674             break;
10675          while((*vp == ' ') || (*vp == 0x09)) /* get rid of any leading white space */
10676             vp++;
10677          strs[i] = vp; /* save pointer to beginning of substring */
10678          while((*vp != ' ') && (*vp != 0x09) && (*vp != 0)) /* skip over substring */
10679             vp++;
10680          if(*vp)
10681             *vp++ = 0; /* mark end of substring */
10682       }
10683       if(debug > 6)
10684          ast_log(LOG_NOTICE, "i = %d, min = %s, hour = %s, mday=%s, mon=%s, wday=%s\n",i,
10685             strs[0], strs[1], strs[2], strs[3], strs[4]); 
10686       if(i == 5){
10687          if((*strs[0] != '*')&&(atoi(strs[0]) != tmnow.tm_min))
10688             continue;
10689          if((*strs[1] != '*')&&(atoi(strs[1]) != tmnow.tm_hour))
10690             continue;
10691          if((*strs[2] != '*')&&(atoi(strs[2]) != tmnow.tm_mday))
10692             continue;
10693          if((*strs[3] != '*')&&(atoi(strs[3]) != tmnow.tm_mon + 1))
10694             continue;
10695          if(atoi(strs[4]) == 7)
10696             strs[4] = "0";
10697          if((*strs[4] != '*')&&(atoi(strs[4]) != tmnow.tm_wday))
10698             continue;
10699          if(debug)
10700             ast_log(LOG_NOTICE, "Executing scheduler entry %s = %s\n", skedlist->name, skedlist->value);
10701          if(atoi(skedlist->name) == 0)
10702             return; /* Zero is reserved for the startup macro */
10703          val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, skedlist->name);
10704          if (!val){
10705             ast_log(LOG_WARNING,"Scheduler could not find macro %s\n",skedlist->name);
10706             return; /* Macro not found */
10707          }
10708          if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)){
10709             ast_log(LOG_WARNING, "Scheduler could not execute macro %s: Macro buffer full\n",
10710                skedlist->name);
10711             return; /* Macro buffer full */
10712          }
10713          myrpt->macrotimer = MACROTIME;
10714          strncat(myrpt->macrobuf,val,MAXMACRO - 1);
10715       }
10716       else{
10717          ast_log(LOG_WARNING,"Malformed scheduler entry in rpt.conf: %s = %s\n",
10718             skedlist->name, skedlist->value);
10719       }
10720    }
10721 
10722 }

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

Definition at line 1554 of file app_rpt.c.

References nodelog::archivedir, rpt::archivedir, ast_log(), ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), LOG_ERROR, 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(), rpt_exec(), and setrem().

01555 {
01556 struct nodelog *nodep;
01557 char  datestr[100];
01558 
01559    if (!myrpt->p.archivedir) return;
01560    nodep = (struct nodelog *)ast_malloc(sizeof(struct nodelog));
01561    if (nodep == NULL)
01562    {
01563       ast_log(LOG_ERROR,"Cannot get memory for node log");
01564       return;
01565    }
01566    time(&nodep->timestamp);
01567    strncpy(nodep->archivedir,myrpt->p.archivedir,
01568       sizeof(nodep->archivedir) - 1);
01569    strftime(datestr,sizeof(datestr) - 1,"%Y%m%d%H%M%S",
01570       localtime(&nodep->timestamp));
01571    snprintf(nodep->str,sizeof(nodep->str) - 1,"%s %s,%s\n",
01572       myrpt->name,datestr,str);
01573    ast_mutex_lock(&nodeloglock);
01574    insque((struct qelem *) nodep, (struct qelem *) nodelog.prev);
01575    ast_mutex_unlock(&nodeloglock);
01576 }

static int dovox ( struct vox v,
short *  buf,
int  bs 
) [static]

Definition at line 1118 of file app_rpt.c.

References vox::enacount, vox::lastvox, mymax, mymin, vox::noise_energy, vox::offdebcnt, vox::ondebcnt, vox::speech_energy, VOX_MAX_THRESHOLD, VOX_MIN_THRESHOLD, and vox::voxena.

Referenced by rpt().

01119 {
01120 
01121    int i;
01122    float esquare = 0.0;
01123    float energy = 0.0;
01124    float threshold = 0.0;
01125    
01126    if (v->voxena < 0) return(v->lastvox);
01127    for(i = 0; i < bs; i++)
01128    {
01129       esquare += (float) buf[i] * (float) buf[i];
01130    }
01131    energy = sqrt(esquare);
01132 
01133    if (energy >= v->speech_energy)
01134       v->speech_energy += (energy - v->speech_energy) / 4;
01135    else
01136       v->speech_energy += (energy - v->speech_energy) / 64;
01137 
01138    if (energy >= v->noise_energy)
01139       v->noise_energy += (energy - v->noise_energy) / 64;
01140    else
01141       v->noise_energy += (energy - v->noise_energy) / 4;
01142    
01143    if (v->voxena) threshold = v->speech_energy / 8;
01144    else
01145    {
01146       threshold = mymax(v->speech_energy / 16,v->noise_energy * 2);
01147       threshold = mymin(threshold,VOX_MAX_THRESHOLD);
01148    }
01149    threshold = mymax(threshold,VOX_MIN_THRESHOLD);
01150    if (energy > threshold)
01151    {
01152       if (v->voxena) v->noise_energy *= 0.75;
01153       v->voxena = 1;
01154    } else   v->voxena = 0;
01155    if (v->lastvox != v->voxena)
01156    {
01157       if (v->enacount++ >= ((v->lastvox) ? v->offdebcnt : v->ondebcnt))
01158       {
01159          v->lastvox = v->voxena;
01160          v->enacount = 0;
01161       }
01162    } else v->enacount = 0;
01163    return(v->lastvox);
01164 }

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

Definition at line 1808 of file app_rpt.c.

Referenced by check_tx_freq().

01809 {
01810    while((*s == ' ') || (*s == 0x09)){ /* get rid of any leading white space */
01811       if(!*s)
01812          break;
01813       s++;
01814    }
01815    return s;
01816 }

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

Definition at line 1828 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(), rpt_tele_thread(), and statpost().

01829 {
01830 int     i,l,inquo;
01831 
01832         inquo = 0;
01833         i = 0;
01834         strp[i++] = str;
01835         if (!*str)
01836            {
01837                 strp[0] = 0;
01838                 return(0);
01839            }
01840         for(l = 0; *str && (l < limit) ; str++)
01841            {
01842                 if (*str == QUOTECHR)
01843                    {
01844                         if (inquo)
01845                            {
01846                                 *str = 0;
01847                                 inquo = 0;
01848                            }
01849                         else
01850                            {
01851                                 strp[i - 1] = str + 1;
01852                                 inquo = 1;
01853                            }
01854       }
01855                 if ((*str == DELIMCHR) && (!inquo))
01856                 {
01857                         *str = 0;
01858          l++;
01859                         strp[i++] = str + 1;
01860                 }
01861            }
01862         strp[i] = 0;
01863         return(i);
01864 
01865 }

static void flush_telem ( struct rpt myrpt  )  [static]

Definition at line 1348 of file app_rpt.c.

References ast_log(), ast_softhangup(), AST_SOFTHANGUP_DEV, rpt_tele::chan, rpt::lock, LOG_NOTICE, rpt_tele::mode, rpt_tele::next, rpt_mutex_lock, rpt_mutex_unlock, SETREMOTE, and rpt::tele.

Referenced by function_cop().

01349 {
01350    struct rpt_tele *telem;
01351    if(debug > 2)
01352       ast_log(LOG_NOTICE, "flush_telem()!!");
01353    rpt_mutex_lock(&myrpt->lock);
01354    telem = myrpt->tele.next;
01355    while(telem != &myrpt->tele)
01356    {
01357       if (telem->mode != SETREMOTE) ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV);
01358       telem = telem->next;
01359    }
01360    rpt_mutex_unlock(&myrpt->lock);
01361 }

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

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

01764 {
01765 time_t   now;
01766 int   gotone;
01767 
01768    time(&now);
01769    gotone = 0;
01770    /* if too much time, reset the skate machine */
01771    if ((now - xlat->lastone) > MAXXLATTIME)
01772    {
01773       xlat->funcindex = xlat->endindex = 0;
01774    }
01775    if (xlat->funccharseq[0] && (c == xlat->funccharseq[xlat->funcindex++]))
01776    {
01777       time(&xlat->lastone);
01778       gotone = 1;
01779       if (!xlat->funccharseq[xlat->funcindex])
01780       {
01781          xlat->funcindex = xlat->endindex = 0;
01782          return(myrpt->p.funcchar);
01783       }
01784    } else xlat->funcindex = 0;
01785    if (xlat->endcharseq[0] && (c == xlat->endcharseq[xlat->endindex++]))
01786    {
01787       time(&xlat->lastone);
01788       gotone = 1;
01789       if (!xlat->endcharseq[xlat->endindex])
01790       {
01791          xlat->funcindex = xlat->endindex = 0;
01792          return(myrpt->p.endchar);
01793       }
01794    } else xlat->endindex = 0;
01795    /* if in middle of decode seq, send nothing back */
01796    if (gotone) return(0);
01797    /* if no pass chars specified, return em all */
01798    if (!xlat->passchars[0]) return(c);
01799    /* if a "pass char", pass it */
01800    if (strchr(xlat->passchars,c)) return(c);
01801    return(0);
01802 }

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

Definition at line 6248 of file app_rpt.c.

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

06249 {
06250    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
06251       return DC_ERROR;
06252    
06253    if(debug)
06254       printf("@@@@ Autopatch down\n");
06255       
06256    rpt_mutex_lock(&myrpt->lock);
06257    
06258    myrpt->macropatch=0;
06259 
06260    if (!myrpt->callmode){
06261       rpt_mutex_unlock(&myrpt->lock);
06262       return DC_COMPLETE;
06263    }
06264    
06265    myrpt->callmode = 0;
06266    channel_revert(myrpt);
06267    rpt_mutex_unlock(&myrpt->lock);
06268    rpt_telemetry(myrpt, TERM, NULL);
06269    return DC_COMPLETE;
06270 }

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

Definition at line 6150 of file app_rpt.c.

References ast_free, ast_log(), ast_pthread_create, ast_strdup, 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.

06151 {
06152    pthread_attr_t attr;
06153    int i, idx, paramlength;
06154    char *lparam;
06155    char *value = NULL;
06156    char *paramlist[20];
06157 
06158    static char *keywords[] = {
06159    "context",
06160    "dialtime",
06161    "farenddisconnect",
06162    "noct",
06163    "quiet",
06164    NULL
06165    };
06166       
06167    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
06168       return DC_ERROR;
06169       
06170    if(debug)
06171       printf("@@@@ Autopatch up\n");
06172 
06173    if(!myrpt->callmode){
06174       /* Set defaults */
06175       myrpt->patchnoct = 0;
06176       myrpt->patchdialtime = 0;
06177       myrpt->patchfarenddisconnect = 0;
06178       myrpt->patchquiet = 0;
06179       strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT);
06180 
06181       if(param){
06182          /* Process parameter list */
06183          lparam = ast_strdup(param);
06184          if(!lparam){
06185             ast_log(LOG_ERROR,"App_rpt out of memory on line %d\n",__LINE__);
06186             return DC_ERROR;  
06187          }
06188          paramlength = finddelim(lparam, paramlist, 20);          
06189          for(i = 0; i < paramlength; i++){
06190             idx = matchkeyword(paramlist[i], &value, keywords);
06191             if(value)
06192                value = skipchars(value, "= ");
06193             switch(idx){
06194 
06195                case 1: /* context */
06196                   strncpy(myrpt->patchcontext, value, MAXPATCHCONTEXT - 1) ;
06197                   break;
06198                   
06199                case 2: /* dialtime */
06200                   myrpt->patchdialtime = atoi(value);
06201                   break;
06202 
06203                case 3: /* farenddisconnect */
06204                   myrpt->patchfarenddisconnect = atoi(value);
06205                   break;
06206 
06207                case 4:  /* noct */
06208                   myrpt->patchnoct = atoi(value);
06209                   break;
06210 
06211                case 5: /* quiet */
06212                   myrpt->patchquiet = atoi(value);
06213                   break;
06214                            
06215                default:
06216                   break;
06217             }
06218          }
06219       ast_free(lparam);
06220       }
06221    }
06222                
06223    rpt_mutex_lock(&myrpt->lock);
06224 
06225    /* if on call, force * into current audio stream */
06226    
06227    if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){
06228       myrpt->mydtmf = myrpt->p.endchar;
06229    }
06230    if (myrpt->callmode){
06231       rpt_mutex_unlock(&myrpt->lock);
06232       return DC_COMPLETE;
06233    }
06234    myrpt->callmode = 1;
06235    myrpt->cidx = 0;
06236    myrpt->exten[myrpt->cidx] = 0;
06237    rpt_mutex_unlock(&myrpt->lock);
06238    pthread_attr_init(&attr);
06239    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06240    ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt);
06241    return DC_COMPLETE;
06242 }

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

Definition at line 6376 of file app_rpt.c.

References sysstate::alternatetail, ARB_ALPHA, ast_log(), sysstate::autopatchdisable, birdbath(), channel_steer(), COMPLETE, DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, rpt::disgorgetime, flush_telem(), sysstate::linkfundisable, LOG_NOTICE, MEMNOTFOUND, myatoi(), rpt::p, rpt::parrotmode, retreive_memory(), rpt_telemetry(), rpt::s, sysstate::schedulerdisable, send_link_keyquery(), setrem(), SOURCE_PHONE, rpt::stopgen, rpt::sysstate_cur, TEST_TONE, rpt::topkeylong, sysstate::totdisable, sysstate::txdisable, and sysstate::userfundisable.

06377 {
06378    char string[16];
06379    int res;
06380 
06381    int i, r;
06382 
06383    if(!param)
06384       return DC_ERROR;
06385    
06386    switch(myatoi(param)){
06387       case 1: /* System reset */
06388          res = system("killall -9 asterisk");
06389          return DC_COMPLETE;
06390 
06391       case 2:
06392          myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 0;
06393          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA");
06394          return DC_COMPLETE;
06395          
06396       case 3:
06397          myrpt->p.s[myrpt->p.sysstate_cur].txdisable = 1;
06398          return DC_COMPLETE;
06399          
06400       case 4: /* test tone on */
06401          if (myrpt->stopgen < 0) 
06402          {
06403             myrpt->stopgen = 1;
06404          }
06405          else 
06406          {
06407             myrpt->stopgen = 0;
06408             rpt_telemetry(myrpt, TEST_TONE, NULL);
06409          }
06410          return DC_COMPLETE;
06411 
06412       case 5: /* Disgorge variables to log for debug purposes */
06413          myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
06414          return DC_COMPLETE;
06415 
06416       case 6: /* Simulate COR being activated (phone only) */
06417          if (command_source != SOURCE_PHONE) return DC_INDETERMINATE;
06418          return DC_DOKEY;  
06419 
06420 
06421       case 7: /* Time out timer enable */
06422          myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 0;
06423          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTENA");
06424          return DC_COMPLETE;
06425          
06426       case 8: /* Time out timer disable */
06427          myrpt->p.s[myrpt->p.sysstate_cur].totdisable = 1;
06428          rpt_telemetry(myrpt, ARB_ALPHA, (void *) "TOTDIS");
06429          return DC_COMPLETE;
06430 
06431                 case 9: /* Autopatch enable */
06432                         myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 0;
06433                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APENA");
06434                         return DC_COMPLETE;
06435 
06436                 case 10: /* Autopatch disable */
06437                         myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable = 1;
06438                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "APDIS");
06439                         return DC_COMPLETE;
06440 
06441                 case 11: /* Link Enable */
06442                         myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 0;
06443                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKENA");
06444                         return DC_COMPLETE;
06445 
06446                 case 12: /* Link Disable */
06447                         myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable = 1;
06448                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "LNKDIS");
06449                         return DC_COMPLETE;
06450 
06451       case 13: /* Query System State */
06452          string[0] = string[1] = 'S';
06453          string[2] = myrpt->p.sysstate_cur + '0';
06454          string[3] = '\0';
06455          rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
06456          return DC_COMPLETE;
06457 
06458       case 14: /* Change System State */
06459          if(strlen(digitbuf) == 0)
06460             break;
06461          if((digitbuf[0] < '0') || (digitbuf[0] > '9'))
06462             return DC_ERROR;
06463          myrpt->p.sysstate_cur = digitbuf[0] - '0';
06464                         string[0] = string[1] = 'S';
06465                         string[2] = myrpt->p.sysstate_cur + '0';
06466                         string[3] = '\0';
06467                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) string);
06468                         return DC_COMPLETE;
06469 
06470                 case 15: /* Scheduler Enable */
06471                         myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 0;
06472                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKENA");
06473                         return DC_COMPLETE;
06474 
06475                 case 16: /* Scheduler Disable */
06476                         myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable = 1;
06477                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "SKDIS");
06478                         return DC_COMPLETE;
06479 
06480                 case 17: /* User functions Enable */
06481                         myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 0;
06482                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFENA");
06483                         return DC_COMPLETE;
06484 
06485                 case 18: /* User Functions Disable */
06486                         myrpt->p.s[myrpt->p.sysstate_cur].userfundisable = 1;
06487                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "UFDIS");
06488                         return DC_COMPLETE;
06489 
06490                 case 19: /* Alternate Tail Enable */
06491                         myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 1;
06492                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATENA");
06493                         return DC_COMPLETE;
06494 
06495                 case 20: /* Alternate Tail Disable */
06496                         myrpt->p.s[myrpt->p.sysstate_cur].alternatetail = 0;
06497                         rpt_telemetry(myrpt, ARB_ALPHA, (void *) "ATDIS");
06498                         return DC_COMPLETE;
06499 
06500                 case 21: /* Parrot Mode Disable */
06501          birdbath(myrpt);
06502          if (myrpt->p.parrotmode < 2)
06503          {
06504             myrpt->p.parrotmode = 0;
06505             rpt_telemetry(myrpt,COMPLETE,NULL);
06506             return DC_COMPLETE;
06507          }
06508          break;
06509 
06510                 case 22: /* Parrot Mode Enable */
06511          birdbath(myrpt);
06512          if (myrpt->p.parrotmode < 2)
06513          {
06514             myrpt->p.parrotmode = 1;
06515             rpt_telemetry(myrpt,COMPLETE,NULL);
06516             return DC_COMPLETE;
06517          }
06518          break;
06519       case 23: /* flush parrot in progress */
06520          birdbath(myrpt);
06521          rpt_telemetry(myrpt,COMPLETE,NULL);
06522          return DC_COMPLETE;
06523       case 24: /* flush all telemetry */
06524          flush_telem(myrpt);
06525          rpt_telemetry(myrpt,COMPLETE,NULL);
06526          return DC_COMPLETE;
06527       case 25: /* request keying info (brief) */
06528          send_link_keyquery(myrpt);
06529          myrpt->topkeylong = 0;
06530          rpt_telemetry(myrpt,COMPLETE,NULL);
06531          return DC_COMPLETE;
06532       case 26: /* request keying info (full) */
06533          send_link_keyquery(myrpt);
06534          myrpt->topkeylong = 1;
06535          rpt_telemetry(myrpt,COMPLETE,NULL);
06536          return DC_COMPLETE;
06537 
06538       case 30: /* recall memory location on programmable radio */
06539 
06540          if(strlen(digitbuf) < 2) /* needs 2 digits */
06541             break;
06542          
06543          for(i = 0 ; i < 2 ; i++){
06544             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
06545                return DC_ERROR;
06546          }
06547        
06548          r = retreive_memory(myrpt, digitbuf);
06549          if (r < 0){
06550             rpt_telemetry(myrpt,MEMNOTFOUND,NULL);
06551             return DC_COMPLETE;
06552          }
06553          if (r > 0){
06554             return DC_ERROR;
06555          }
06556          if (setrem(myrpt) == -1) return DC_ERROR;
06557          return DC_COMPLETE;  
06558 
06559       case 31: 
06560           /* set channel. note that it's going to change channel 
06561              then confirm on the new channel! */
06562          if(strlen(digitbuf) < 2) /* needs 2 digits */
06563             break;
06564          
06565          for(i = 0 ; i < 2 ; i++){
06566             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
06567                return DC_ERROR;
06568          }
06569          channel_steer(myrpt,digitbuf);
06570          return DC_COMPLETE;  
06571 
06572       case 32: /* Touch Tone Pad Test */
06573          i = strlen(digitbuf);
06574          if(!i){
06575             if(debug > 3)
06576             ast_log(LOG_NOTICE,"Padtest entered");
06577             myrpt->inpadtest = 1;
06578          }
06579          else{
06580             if(debug > 3)
06581                ast_log(LOG_NOTICE,"Padtest len= %d digits=%s",i,digitbuf);
06582             if(digitbuf[i-1] != myrpt->p.endchar)
06583                break;
06584             rpt_telemetry(myrpt, ARB_ALPHA, digitbuf);
06585             myrpt->inpadtest = 0;
06586             if(debug > 3)
06587                ast_log(LOG_NOTICE,"Padtest exited");
06588             return DC_COMPLETE;
06589          }
06590    }  
06591    return DC_INDETERMINATE;
06592 }

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

Definition at line 5879 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, ast_frame::ptr, REMALREADY, REMGO, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::s, s, ast_frame::samples, rpt::savednodes, SOURCE_ALT, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, SOURCE_RPT, STATUS, strsep(), ast_frame::subclass, and rpt::sysstate_cur.

05880 {
05881 
05882    char *val, *s, *s1, *s2;
05883    char tmp[300];
05884    char digitbuf[MAXNODESTR],*strs[MAXLINKLIST];
05885    char mode,perma;
05886    char sx[320],*sy;
05887    struct rpt_link *l;
05888    int i,r;
05889 
05890    if(!param)
05891       return DC_ERROR;
05892       
05893          
05894    if (myrpt->p.s[myrpt->p.sysstate_cur].txdisable || myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable )
05895       return DC_ERROR;
05896 
05897    strncpy(digitbuf,digits,MAXNODESTR - 1);
05898 
05899    if(debug > 6)
05900       printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
05901       
05902    switch(myatoi(param)){
05903       case 11: /* Perm Link off */
05904       case 1: /* Link off */
05905          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
05906             strcpy(digitbuf,myrpt->lastlinknode);
05907          val = node_lookup(myrpt,digitbuf);
05908          if (!val){
05909             if(strlen(digitbuf) >= myrpt->longestnode)
05910                return DC_ERROR;
05911             break;
05912          }
05913          strncpy(tmp,val,sizeof(tmp) - 1);
05914          s = tmp;
05915          s1 = strsep(&s,",");
05916          if (!strchr(s1,':') && strchr(s1,'/') && strncasecmp(s1, "local/", 6))
05917          {
05918             sy = strchr(s1,'/');    
05919             *sy = 0;
05920             sprintf(sx,"%s:4569/%s",s1,sy + 1);
05921             s1 = sx;
05922          }
05923          s2 = strsep(&s,",");
05924          rpt_mutex_lock(&myrpt->lock);
05925          l = myrpt->links.next;
05926          /* try to find this one in queue */
05927          while(l != &myrpt->links){
05928             if (l->name[0] == '0') 
05929             {
05930                l = l->next;
05931                continue;
05932             }
05933             /* if found matching string */
05934             if (!strcmp(l->name, digitbuf))
05935                break;
05936             l = l->next;
05937          }
05938          if (l != &myrpt->links){ /* if found */
05939             struct   ast_frame wf;
05940 
05941             /* must use perm command on perm link */
05942             if ((myatoi(param) < 10) && 
05943                 (l->max_retries > MAX_RETRIES))
05944             {
05945                rpt_mutex_unlock(&myrpt->lock);
05946                return DC_COMPLETE;
05947             }
05948             strncpy(myrpt->lastlinknode,digitbuf,MAXNODESTR - 1);
05949             l->retries = l->max_retries + 1;
05950             l->disced = 1;
05951             rpt_mutex_unlock(&myrpt->lock);
05952             wf.frametype = AST_FRAME_TEXT;
05953             wf.subclass = 0;
05954             wf.offset = 0;
05955             wf.mallocd = 0;
05956             wf.datalen = strlen(discstr) + 1;
05957             wf.samples = 0;
05958             wf.data.ptr = discstr;
05959             if (l->chan)
05960             {
05961                ast_write(l->chan,&wf);
05962                if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR;
05963                ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
05964             }
05965             rpt_telemetry(myrpt, COMPLETE, NULL);
05966             return DC_COMPLETE;
05967          }
05968          rpt_mutex_unlock(&myrpt->lock);  
05969          return DC_COMPLETE;
05970       case 2: /* Link Monitor */
05971       case 3: /* Link transceive */
05972       case 12: /* Link Monitor permanent */
05973       case 13: /* Link transceive permanent */
05974          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
05975             strcpy(digitbuf,myrpt->lastlinknode);
05976          /* Attempt connection  */
05977          perma = (atoi(param) > 10) ? 1 : 0;
05978          mode = (atoi(param) & 1) ? 1 : 0;
05979          r = connect_link(myrpt, digitbuf, mode, perma);
05980          switch(r){
05981             case -2: /* Attempt to connect to self */
05982                return DC_COMPLETE; /* Silent error */
05983 
05984             case 0:
05985                rpt_telemetry(myrpt, COMPLETE, NULL);
05986                return DC_COMPLETE;
05987 
05988             case 1:
05989                break;
05990             
05991             case 2:
05992                rpt_telemetry(myrpt, REMALREADY, NULL);
05993                return DC_COMPLETE;
05994             
05995             default:
05996                rpt_telemetry(myrpt, CONNFAIL, NULL);
05997                return DC_COMPLETE;
05998          }
05999          break;
06000 
06001       case 4: /* Enter Command Mode */
06002       
06003          /* if doesnt allow link cmd, or no links active, return */
06004          if (((command_source != SOURCE_RPT) && 
06005             (command_source != SOURCE_PHONE) &&
06006             (command_source != SOURCE_ALT) &&
06007             (command_source != SOURCE_DPHONE)) ||
06008              (myrpt->links.next == &myrpt->links))
06009             return DC_COMPLETE;
06010          
06011          /* if already in cmd mode, or selected self, fughetabahtit */
06012          if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){
06013          
06014             rpt_telemetry(myrpt, REMALREADY, NULL);
06015             return DC_COMPLETE;
06016          }
06017          if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0]))
06018             strcpy(digitbuf,myrpt->lastlinknode);
06019          /* node must at least exist in list */
06020          val = node_lookup(myrpt,digitbuf);
06021          if (!val){
06022             if(strlen(digitbuf) >= myrpt->longestnode)
06023                return DC_ERROR;
06024             break;
06025          
06026          }
06027          rpt_mutex_lock(&myrpt->lock);
06028          strcpy(myrpt->lastlinknode,digitbuf);
06029          strncpy(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode) - 1);
06030          rpt_mutex_unlock(&myrpt->lock);
06031          rpt_telemetry(myrpt, REMGO, NULL);  
06032          return DC_COMPLETE;
06033          
06034       case 5: /* Status */
06035          rpt_telemetry(myrpt, STATUS, NULL);
06036          return DC_COMPLETE;
06037 
06038       case 15: /* Full Status */
06039          rpt_telemetry(myrpt, FULLSTATUS, NULL);
06040          return DC_COMPLETE;
06041          
06042          
06043       case 6: /* All Links Off, including permalinks */
06044                        rpt_mutex_lock(&myrpt->lock);
06045          myrpt->savednodes[0] = 0;
06046                         l = myrpt->links.next;
06047                         /* loop through all links */
06048                         while(l != &myrpt->links){
06049             struct   ast_frame wf;
06050                                 if (l->name[0] == '0') /* Skip any IAXRPT monitoring */
06051                                 {
06052                                         l = l->next;
06053                                         continue;
06054                                 }
06055             /* Make a string of disconnected nodes for possible restoration */
06056             sprintf(tmp,"%c%c%s",(l->mode) ? 'X' : 'M',(l->perma) ? 'P':'T',l->name);
06057             if(strlen(tmp) + strlen(myrpt->savednodes) + 1 < MAXNODESTR){ 
06058                if(myrpt->savednodes[0])
06059                   strcat(myrpt->savednodes, ",");
06060                strcat(myrpt->savednodes, tmp);
06061             }
06062                               l->retries = l->max_retries + 1;
06063                                 l->disced = 2; /* Silently disconnect */
06064                                 rpt_mutex_unlock(&myrpt->lock);
06065             /* ast_log(LOG_NOTICE,"dumping link %s\n",l->name); */
06066                                 
06067                                 wf.frametype = AST_FRAME_TEXT;
06068                                 wf.subclass = 0;
06069                                 wf.offset = 0;
06070                                 wf.mallocd = 0;
06071                                 wf.datalen = strlen(discstr) + 1;
06072                                 wf.samples = 0;
06073                                 wf.data.ptr = discstr;
06074                                 if (l->chan)
06075                                 {
06076                                         ast_write(l->chan,&wf);
06077                                         ast_safe_sleep(l->chan,250); /* It's dead already, why check the return value? */
06078                                         ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
06079                                 }
06080             rpt_mutex_lock(&myrpt->lock);
06081                                 l = l->next;
06082                         }
06083          rpt_mutex_unlock(&myrpt->lock);
06084          if(debug > 3)
06085             ast_log(LOG_NOTICE,"Nodes disconnected: %s\n",myrpt->savednodes);
06086                         rpt_telemetry(myrpt, COMPLETE, NULL);
06087          return DC_COMPLETE;
06088 
06089       case 7: /* Identify last node which keyed us up */
06090          rpt_telemetry(myrpt, LASTNODEKEY, NULL);
06091          break;
06092 
06093 
06094 #ifdef   _MDC_DECODE_H_
06095       case 8:
06096          myrpt->lastunit = 0xd00d; 
06097          mdc1200_notify(myrpt,NULL,myrpt->lastunit);
06098          mdc1200_send(myrpt,myrpt->lastunit);
06099          break;
06100 #endif
06101 
06102       case 16: /* Restore links disconnected with "disconnect all links" command */
06103          strcpy(tmp, myrpt->savednodes); /* Make a copy */
06104          finddelim(tmp, strs, MAXLINKLIST); /* convert into substrings */
06105          for(i = 0; tmp[0] && strs[i] != NULL && i < MAXLINKLIST; i++){
06106             s1 = strs[i];
06107             mode = (s1[0] == 'X') ? 1 : 0;
06108             perma = (s1[1] == 'P') ? 1 : 0;
06109             connect_link(myrpt, s1 + 2, mode, perma); /* Try to reconnect */
06110          }
06111                         rpt_telemetry(myrpt, COMPLETE, NULL);
06112          break;
06113    
06114       case 200:
06115       case 201:
06116       case 202:
06117       case 203:
06118       case 204:
06119       case 205:
06120       case 206:
06121       case 207:
06122       case 208:
06123       case 209:
06124       case 210:
06125       case 211:
06126       case 212:
06127       case 213:
06128       case 214:
06129       case 215:
06130          if (((myrpt->p.propagate_dtmf) && 
06131               (command_source == SOURCE_LNK)) ||
06132              ((myrpt->p.propagate_phonedtmf) &&
06133             ((command_source == SOURCE_PHONE) ||
06134               (command_source == SOURCE_ALT) ||
06135                 (command_source == SOURCE_DPHONE))))
06136                do_dtmf_local(myrpt,
06137                   remdtmfstr[myatoi(param) - 200]);
06138       default:
06139          return DC_ERROR;
06140          
06141    }
06142    
06143    return DC_INDETERMINATE;
06144 }  

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

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

06313 {
06314 char  *val;
06315 int   i;
06316    if (myrpt->remote)
06317       return DC_ERROR;
06318 
06319    if(debug) 
06320       printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
06321    
06322    if(strlen(digitbuf) < 1) /* needs 1 digit */
06323       return DC_INDETERMINATE;
06324          
06325    for(i = 0 ; i < digitbuf[i] ; i++) {
06326       if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
06327          return DC_ERROR;
06328    }
06329    
06330    if (*digitbuf == '0') val = myrpt->p.startupmacro;
06331    else val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, digitbuf);
06332    /* param was 1 for local buf */
06333    if (!val){
06334                 if (strlen(digitbuf) < myrpt->macro_longest)
06335                         return DC_INDETERMINATE;
06336       rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL);
06337       return DC_COMPLETE;
06338    }        
06339    rpt_mutex_lock(&myrpt->lock);
06340    if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val))
06341    {
06342       rpt_mutex_unlock(&myrpt->lock);
06343       rpt_telemetry(myrpt, MACRO_BUSY, NULL);
06344       return DC_ERROR;
06345    }
06346    myrpt->macrotimer = MACROTIME;
06347    strncat(myrpt->macrobuf,val,MAXMACRO - 1);
06348    rpt_mutex_unlock(&myrpt->lock);
06349    return DC_COMPLETE;  
06350 }

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

Definition at line 6356 of file app_rpt.c.

References ast_fileexists(), DC_COMPLETE, DC_ERROR, ast_channel::language, PLAYBACK, rpt::remote, rpt_telemetry(), and rpt::rxchannel.

06357 {
06358 
06359    if (myrpt->remote)
06360       return DC_ERROR;
06361 
06362    if(debug) 
06363       printf("@@@@ playback param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
06364    
06365    if (ast_fileexists(param,NULL,myrpt->rxchannel->language) <= 0)
06366       return DC_ERROR;
06367 
06368    rpt_telemetry(myrpt,PLAYBACK,param);
06369    return DC_COMPLETE;
06370 }

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

Definition at line 9638 of file app_rpt.c.

References rpt::archivedir, AST_CONTROL_RADIO_UNKEY, ast_free, ast_indicate(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, rpt::authlevel, check_freq(), DC_COMPLETE, DC_COMPLETEQUIET, DC_ERROR, DC_INDETERMINATE, do_dtmf_local(), donodelog(), rpt::freq, get_mem_set(), 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, ISRIG_RTX, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::loginlevel, rpt::loginuser, MAXREMSTR, MEMNOTFOUND, multimode_bump_freq(), multimode_capable(), myatoi(), rpt::name, 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_SCANTIME, REM_SIMPLEX, REMLOGIN, REMLONGSTATUS, REMMODE, rpt::remmode, rpt::remoterig, rpt::remotetx, REMSHORTSTATUS, REMXXX, rpt_telemetry(), rpt::rxpl, rpt::rxplon, s, rpt::scantimer, setrem(), SOURCE_LNK, SOURCE_RPT, split_freq(), strsep(), TUNE, rpt::tunerequest, rpt::txchannel, rpt::txpl, and rpt::txplon.

09639 {
09640    char *s,*s1,*s2;
09641    int i,j,r,ht,k,l,ls2,m,d,offset,offsave, modesave, defmode=0;
09642    intptr_t p;
09643    char multimode = 0;
09644    char oc,*cp,*cp1,*cp2;
09645    char tmp[20], freq[20] = "", savestr[20] = "";
09646    char mhz[MAXREMSTR], decimals[MAXREMSTR];
09647 
09648     if(debug > 6) {
09649       ast_log(LOG_NOTICE,"%s param=%s digitbuf=%s source=%i\n",myrpt->name,param,digitbuf,command_source);
09650    }
09651 
09652    if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK))
09653       return DC_ERROR;
09654       
09655    p = myatoi(param);
09656 
09657    if ((p != 99) && (p != 5) && (p != 140) && myrpt->p.authlevel && 
09658       (!myrpt->loginlevel[0])) return DC_ERROR;
09659    multimode = multimode_capable(myrpt);
09660 
09661    switch(p){
09662 
09663       case 1:  /* retrieve memory */
09664          if(strlen(digitbuf) < 2) /* needs 2 digits */
09665             break;
09666          
09667          for(i = 0 ; i < 2 ; i++){
09668             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
09669                return DC_ERROR;
09670          }
09671          r=get_mem_set(myrpt, digitbuf);
09672          if (r < 0){
09673             rpt_telemetry(myrpt,MEMNOTFOUND,NULL);
09674             return DC_COMPLETE;
09675          }
09676          else if (r > 0){
09677             return DC_ERROR;
09678          }
09679          return DC_COMPLETE;  
09680          
09681       case 2:  /* set freq and offset */
09682       
09683          
09684             for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */
09685             if(digitbuf[i] == '*'){
09686                j++;
09687                continue;
09688             }
09689             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
09690                goto invalid_freq;
09691             else{
09692                if(j == 0)
09693                   l++; /* # of digits before first * */
09694                if(j == 1)
09695                   k++; /* # of digits after first * */
09696             }
09697          }
09698       
09699          i = strlen(digitbuf) - 1;
09700          if(multimode){
09701             if((j > 2) || (l > 3) || (k > 6))
09702                goto invalid_freq; /* &^@#! */
09703          }
09704          else{
09705             if((j > 2) || (l > 4) || (k > 3))
09706                goto invalid_freq; /* &^@#! */
09707          }
09708 
09709          /* Wait for M+*K+* */
09710 
09711          if(j < 2)
09712             break; /* Not yet */
09713 
09714          /* We have a frequency */
09715 
09716          strncpy(tmp, digitbuf ,sizeof(tmp) - 1);
09717          
09718          s = tmp;
09719          s1 = strsep(&s, "*"); /* Pick off MHz */
09720          s2 = strsep(&s,"*"); /* Pick off KHz and Hz */
09721          ls2 = strlen(s2); 
09722          
09723          switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */
09724             case 1:
09725                ht = 0;
09726                k = 100 * atoi(s2);
09727                break;
09728             
09729             case 2:
09730                ht = 0;
09731                k = 10 * atoi(s2);
09732                break;
09733                
09734             case 3:
09735                if(!multimode){
09736                   if((s2[2] != '0')&&(s2[2] != '5'))
09737                      goto invalid_freq;
09738                }
09739                ht = 0;
09740                k = atoi(s2);
09741                   break;
09742             case 4:
09743                k = atoi(s2)/10;
09744                ht = 10 * (atoi(s2+(ls2-1)));
09745                break;
09746 
09747             case 5:
09748                k = atoi(s2)/100;
09749                ht = (atoi(s2+(ls2-2)));
09750                break;
09751                
09752             default:
09753                goto invalid_freq;
09754          }
09755 
09756          /* Check frequency for validity and establish a default mode */
09757          
09758          snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht);
09759 
09760          if(debug)
09761             ast_log(LOG_NOTICE, "New frequency: %s\n", freq);
09762    
09763          split_freq(mhz, decimals, freq);
09764          m = atoi(mhz);
09765          d = atoi(decimals);
09766 
09767          if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */
09768                  goto invalid_freq;
09769 
09770 
09771          if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */
09772             break; /* Not yet */
09773 
09774 
09775          offset = REM_SIMPLEX; /* Assume simplex */
09776 
09777          if(defmode == REM_MODE_FM){
09778             oc = *s; /* Pick off offset */
09779          
09780             if (oc){
09781                switch(oc){
09782                   case '1':
09783                      offset = REM_MINUS;
09784                      break;
09785                   
09786                   case '2':
09787                      offset = REM_SIMPLEX;
09788                   break;
09789                   
09790                   case '3':
09791                      offset = REM_PLUS;
09792                      break;
09793                   
09794                   default:
09795                      goto invalid_freq;
09796                } 
09797             } 
09798          }  
09799          offsave = myrpt->offset;
09800          modesave = myrpt->remmode;
09801          strncpy(savestr, myrpt->freq, sizeof(savestr) - 1);
09802          strncpy(myrpt->freq, freq, sizeof(myrpt->freq) - 1);
09803          myrpt->offset = offset;
09804          myrpt->remmode = defmode;
09805 
09806          if (setrem(myrpt) == -1){
09807             myrpt->offset = offsave;
09808             myrpt->remmode = modesave;
09809             strncpy(myrpt->freq, savestr, sizeof(myrpt->freq) - 1);
09810             goto invalid_freq;
09811          }
09812 
09813          return DC_COMPLETE;
09814 
09815 invalid_freq:
09816          rpt_telemetry(myrpt,INVFREQ,NULL);
09817          return DC_ERROR; 
09818       
09819       case 3: /* set rx PL tone */
09820             for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
09821             if(digitbuf[i] == '*'){
09822                j++;
09823                continue;
09824             }
09825             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
09826                return DC_ERROR;
09827             else{
09828                if(j)
09829                   l++;
09830                else
09831                   k++;
09832             }
09833          }
09834          if((j > 1) || (k > 3) || (l > 1))
09835             return DC_ERROR; /* &$@^! */
09836          i = strlen(digitbuf) - 1;
09837          if((j != 1) || (k < 2)|| (l != 1))
09838             break; /* Not yet */
09839          if(debug)
09840             printf("PL digits entered %s\n", digitbuf);
09841             
09842          strncpy(tmp, digitbuf, sizeof(tmp) - 1);
09843          /* see if we have at least 1 */
09844          s = strchr(tmp,'*');
09845          if(s)
09846             *s = '.';
09847          strncpy(savestr, myrpt->rxpl, sizeof(savestr) - 1);
09848          strncpy(myrpt->rxpl, tmp, sizeof(myrpt->rxpl) - 1);
09849          if(!strcmp(myrpt->remoterig, remote_rig_rbi))
09850          {
09851             strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1);
09852          }
09853          if (setrem(myrpt) == -1){
09854             strncpy(myrpt->rxpl, savestr, sizeof(myrpt->rxpl) - 1);
09855             return DC_ERROR;
09856          }
09857          return DC_COMPLETE;
09858       
09859       case 4: /* set tx PL tone */
09860          /* cant set tx tone on RBI (rx tone does both) */
09861          if(!strcmp(myrpt->remoterig, remote_rig_rbi))
09862             return DC_ERROR;
09863          /*  eventually for the ic706 instead of just throwing the exception
09864             we can check if we are in encode only mode and allow the tx
09865             ctcss code to be changed. but at least the warning message is
09866             issued for now.
09867          */
09868          if(!strcmp(myrpt->remoterig, remote_rig_ic706))
09869          {
09870             if(debug)
09871                ast_log(LOG_WARNING,"Setting IC706 Tx CTCSS Code Not Supported. Set Rx Code for both.\n");
09872             return DC_ERROR;
09873          }
09874          for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */
09875             if(digitbuf[i] == '*'){
09876                j++;
09877                continue;
09878             }
09879             if((digitbuf[i] < '0') || (digitbuf[i] > '9'))
09880                return DC_ERROR;
09881             else{
09882                if(j)
09883                   l++;
09884                else
09885                   k++;
09886             }
09887          }
09888          if((j > 1) || (k > 3) || (l > 1))
09889             return DC_ERROR; /* &$@^! */
09890          i = strlen(digitbuf) - 1;
09891          if((j != 1) || (k < 2)|| (l != 1))
09892             break; /* Not yet */
09893          if(debug)
09894             printf("PL digits entered %s\n", digitbuf);
09895             
09896          strncpy(tmp, digitbuf, sizeof(tmp) - 1);
09897          /* see if we have at least 1 */
09898          s = strchr(tmp,'*');
09899          if(s)
09900             *s = '.';
09901          strncpy(savestr, myrpt->txpl, sizeof(savestr) - 1);
09902          strncpy(myrpt->txpl, tmp, sizeof(myrpt->txpl) - 1);
09903          
09904          if (setrem(myrpt) == -1){
09905             strncpy(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1);
09906             return DC_ERROR;
09907          }
09908          return DC_COMPLETE;
09909       
09910 
09911       case 6: /* MODE (FM,USB,LSB,AM) */
09912          if(strlen(digitbuf) < 1)
09913             break;
09914 
09915          if(!multimode)
09916             return DC_ERROR; /* Multimode radios only */
09917 
09918          switch(*digitbuf){
09919             case '1':
09920                split_freq(mhz, decimals, myrpt->freq); 
09921                m=atoi(mhz);
09922                if(m < 29) /* No FM allowed below 29MHz! */
09923                   return DC_ERROR;
09924                myrpt->remmode = REM_MODE_FM;
09925                
09926                rpt_telemetry(myrpt,REMMODE,NULL);
09927                break;
09928 
09929             case '2':
09930                myrpt->remmode = REM_MODE_USB;
09931                rpt_telemetry(myrpt,REMMODE,NULL);
09932                break;   
09933 
09934             case '3':
09935                myrpt->remmode = REM_MODE_LSB;
09936                rpt_telemetry(myrpt,REMMODE,NULL);
09937                break;
09938             
09939             case '4':
09940                myrpt->remmode = REM_MODE_AM;
09941                rpt_telemetry(myrpt,REMMODE,NULL);
09942                break;
09943       
09944             default:
09945                return DC_ERROR;
09946          }
09947 
09948          if(setrem(myrpt))
09949             return DC_ERROR;
09950          return DC_COMPLETEQUIET;
09951       case 99:
09952          /* cant log in when logged in */
09953          if (myrpt->loginlevel[0]) 
09954             return DC_ERROR;
09955          *myrpt->loginuser = 0;
09956          myrpt->loginlevel[0] = 0;
09957          cp = ast_strdup(param);
09958          cp1 = strchr(cp,',');
09959          ast_mutex_lock(&myrpt->lock);
09960          if (cp1) 
09961          {
09962             *cp1 = 0;
09963             cp2 = strchr(cp1 + 1,',');
09964             if (cp2) 
09965             {
09966                *cp2 = 0;
09967                strncpy(myrpt->loginlevel,cp2 + 1,
09968                   sizeof(myrpt->loginlevel) - 1);
09969             }
09970             strncpy(myrpt->loginuser,cp1 + 1,sizeof(myrpt->loginuser));
09971             ast_mutex_unlock(&myrpt->lock);
09972             if (myrpt->p.archivedir)
09973             {
09974                char str[100];
09975 
09976                sprintf(str,"LOGIN,%s,%s",
09977                    myrpt->loginuser,myrpt->loginlevel);
09978                donodelog(myrpt,str);
09979             }
09980             if (debug) 
09981                printf("loginuser %s level %s\n",myrpt->loginuser,myrpt->loginlevel);
09982             rpt_telemetry(myrpt,REMLOGIN,NULL);
09983          }
09984          ast_free(cp);
09985          return DC_COMPLETEQUIET;
09986       case 100: /* RX PL Off */
09987          myrpt->rxplon = 0;
09988          setrem(myrpt);
09989          rpt_telemetry(myrpt,REMXXX,(void *)p);
09990          return DC_COMPLETEQUIET;
09991       case 101: /* RX PL On */
09992          myrpt->rxplon = 1;
09993          setrem(myrpt);
09994          rpt_telemetry(myrpt,REMXXX,(void *)p);
09995          return DC_COMPLETEQUIET;
09996       case 102: /* TX PL Off */
09997          myrpt->txplon = 0;
09998          setrem(myrpt);
09999          rpt_telemetry(myrpt,REMXXX,(void *)p);
10000          return DC_COMPLETEQUIET;
10001       case 103: /* TX PL On */
10002          myrpt->txplon = 1;
10003          setrem(myrpt);
10004          rpt_telemetry(myrpt,REMXXX,(void *)p);
10005          return DC_COMPLETEQUIET;
10006       case 104: /* Low Power */
10007          if(!strcmp(myrpt->remoterig, remote_rig_ic706))
10008             return DC_ERROR;
10009          myrpt->powerlevel = REM_LOWPWR;
10010          setrem(myrpt);
10011          rpt_telemetry(myrpt,REMXXX,(void *)p);
10012          return DC_COMPLETEQUIET;
10013       case 105: /* Medium Power */
10014          if(!strcmp(myrpt->remoterig, remote_rig_ic706))
10015             return DC_ERROR;
10016          if (ISRIG_RTX(myrpt->remoterig)) return DC_ERROR;
10017          myrpt->powerlevel = REM_MEDPWR;
10018          setrem(myrpt);
10019          rpt_telemetry(myrpt,REMXXX,(void *)p);
10020          return DC_COMPLETEQUIET;
10021       case 106: /* Hi Power */
10022          if(!strcmp(myrpt->remoterig, remote_rig_ic706))
10023             return DC_ERROR;
10024          myrpt->powerlevel = REM_HIPWR;
10025          setrem(myrpt);
10026          rpt_telemetry(myrpt,REMXXX,(void *)p);
10027          return DC_COMPLETEQUIET;
10028       case 107: /* Bump down 20Hz */
10029          multimode_bump_freq(myrpt, -20);
10030          return DC_COMPLETE;
10031       case 108: /* Bump down 100Hz */
10032          multimode_bump_freq(myrpt, -100);
10033          return DC_COMPLETE;
10034       case 109: /* Bump down 500Hz */
10035          multimode_bump_freq(myrpt, -500);
10036          return DC_COMPLETE;
10037       case 110: /* Bump up 20Hz */
10038          multimode_bump_freq(myrpt, 20);
10039          return DC_COMPLETE;
10040       case 111: /* Bump up 100Hz */
10041          multimode_bump_freq(myrpt, 100);
10042          return DC_COMPLETE;
10043       case 112: /* Bump up 500Hz */
10044          multimode_bump_freq(myrpt, 500);
10045          return DC_COMPLETE;
10046       case 113: /* Scan down slow */
10047          myrpt->scantimer = REM_SCANTIME;
10048          myrpt->hfscanmode = HF_SCAN_DOWN_SLOW;
10049          rpt_telemetry(myrpt,REMXXX,(void *)p);
10050          return DC_COMPLETEQUIET;
10051       case 114: /* Scan down quick */
10052          myrpt->scantimer = REM_SCANTIME;
10053          myrpt->hfscanmode = HF_SCAN_DOWN_QUICK;
10054          rpt_telemetry(myrpt,REMXXX,(void *)p);
10055          return DC_COMPLETEQUIET;
10056       case 115: /* Scan down fast */
10057          myrpt->scantimer = REM_SCANTIME;
10058          myrpt->hfscanmode = HF_SCAN_DOWN_FAST;
10059          rpt_telemetry(myrpt,REMXXX,(void *)p);
10060          return DC_COMPLETEQUIET;
10061       case 116: /* Scan up slow */
10062          myrpt->scantimer = REM_SCANTIME;
10063          myrpt->hfscanmode = HF_SCAN_UP_SLOW;
10064          rpt_telemetry(myrpt,REMXXX,(void *)p);
10065          return DC_COMPLETEQUIET;
10066       case 117: /* Scan up quick */
10067          myrpt->scantimer = REM_SCANTIME;
10068          myrpt->hfscanmode = HF_SCAN_UP_QUICK;
10069          rpt_telemetry(myrpt,REMXXX,(void *)p);
10070          return DC_COMPLETEQUIET;
10071       case 118: /* Scan up fast */
10072          myrpt->scantimer = REM_SCANTIME;
10073          myrpt->hfscanmode = HF_SCAN_UP_FAST;
10074          rpt_telemetry(myrpt,REMXXX,(void *)p);
10075          return DC_COMPLETEQUIET;
10076       case 119: /* Tune Request */
10077          if(debug > 3)
10078             ast_log(LOG_NOTICE,"TUNE REQUEST\n");
10079          /* if not currently going, and valid to do */
10080          if((!myrpt->tunerequest) && 
10081              ((!strcmp(myrpt->remoterig, remote_rig_ft897) || 
10082             !strcmp(myrpt->remoterig, remote_rig_ic706)) )) { 
10083             myrpt->remotetx = 0;
10084             ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
10085             myrpt->tunerequest = 1;
10086             rpt_telemetry(myrpt,TUNE,NULL);
10087             return DC_COMPLETEQUIET;
10088          }
10089          return DC_ERROR;        
10090       case 5: /* Long Status */
10091          rpt_telemetry(myrpt,REMLONGSTATUS,NULL);
10092          return DC_COMPLETEQUIET;
10093       case 140: /* Short Status */
10094          rpt_telemetry(myrpt,REMSHORTSTATUS,NULL);
10095          return DC_COMPLETEQUIET;
10096       case 200:
10097       case 201:
10098       case 202:
10099       case 203:
10100       case 204:
10101       case 205:
10102       case 206:
10103       case 207:
10104       case 208:
10105       case 209:
10106       case 210:
10107       case 211:
10108       case 212:
10109       case 213:
10110       case 214:
10111       case 215:
10112          do_dtmf_local(myrpt,remdtmfstr[p - 200]);
10113          return DC_COMPLETEQUIET;
10114       default:
10115          break;
10116    }
10117    return DC_INDETERMINATE;
10118 }

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

Definition at line 6276 of file app_rpt.c.

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

06277 {
06278 
06279    if (!param)
06280       return DC_ERROR;
06281 
06282    if ((myrpt->p.s[myrpt->p.sysstate_cur].txdisable) || (myrpt->p.s[myrpt->p.sysstate_cur].userfundisable))
06283       return DC_ERROR;
06284 
06285    if(debug)
06286       printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf);
06287    
06288    switch(myatoi(param)){
06289       case 1: /* System ID */
06290          rpt_telemetry(myrpt, ID1, NULL);
06291          return DC_COMPLETE;
06292       case 2: /* System Time */
06293          rpt_telemetry(myrpt, STATS_TIME, NULL);
06294          return DC_COMPLETE;
06295       case 3: /* app_rpt.c version */
06296          rpt_telemetry(myrpt, STATS_VERSION, NULL);
06297          return DC_COMPLETE;
06298       case 11: /* System ID (local only)*/
06299           rpt_telemetry(myrpt, ID , NULL);
06300             return DC_COMPLETE;
06301         case 12: /* System Time (local only)*/
06302             rpt_telemetry(myrpt, STATS_TIME_LOCAL, NULL);
06303             return DC_COMPLETE;
06304       default:
06305          return DC_ERROR;
06306    }
06307    return DC_INDETERMINATE;
06308 }

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

Definition at line 9576 of file app_rpt.c.

References ast_log(), rpt::freq, LOG_NOTICE, retreive_memory(), and setrem().

Referenced by channel_steer(), and function_remote().

09577 {
09578    int res=0;
09579    if(debug)ast_log(LOG_NOTICE," digitbuf=%s\n", digitbuf);
09580    res = retreive_memory(myrpt, digitbuf);
09581    if(!res)res=setrem(myrpt); 
09582    if(debug)ast_log(LOG_NOTICE," freq=%s  res=%i\n", myrpt->freq, res);
09583    return res;
09584 }

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

Definition at line 3840 of file app_rpt.c.

References ast_free, ast_strdup, ast_variable_retrieve(), rpt::cfg, DLY_CALLTERM, DLY_COMP, DLY_ID, DLY_LINKUNKEY, DLY_PARROT, DLY_TELEM, DLY_UNKEY, rpt::name, and retrieve_astcfgint().

Referenced by rpt_tele_thread(), and wait_interval().

03841 {
03842         int interval;
03843         char *wait_times;
03844         char *wait_times_save;
03845                                                                                                                   
03846         wait_times_save = NULL;
03847         wait_times = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "wait_times");
03848                                                                                                                   
03849         if(wait_times){
03850                 wait_times_save = ast_strdup(wait_times);
03851                 if(!wait_times_save)
03852          return 0;
03853                 
03854         }
03855                                                                                                                   
03856         switch(type){
03857                 case DLY_TELEM:
03858                         if(wait_times)
03859                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "telemwait", 500, 5000, 1000);
03860                         else
03861                                 interval = 1000;
03862                         break;
03863                                                                                                                   
03864                 case DLY_ID:
03865                         if(wait_times)
03866                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "idwait",250,5000,500);
03867                         else
03868                                 interval = 500;
03869                         break;
03870                                                                                                                   
03871                 case DLY_UNKEY:
03872                         if(wait_times)
03873                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "unkeywait",50,5000,1000);
03874                         else
03875                                 interval = 1000;
03876                         break;
03877                                                                                                                   
03878                 case DLY_LINKUNKEY:
03879                         if(wait_times)
03880                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "linkunkeywait",500,5000,1000);
03881                         else
03882                                 interval = 1000;
03883                         break;
03884                                                                                                                   
03885                 case DLY_CALLTERM:
03886                         if(wait_times)
03887                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "calltermwait",500,5000,1500);
03888                         else
03889                                 interval = 1500;
03890                         break;
03891                                                                                                                   
03892                 case DLY_COMP:
03893                         if(wait_times)
03894                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "compwait",500,5000,200);
03895                         else
03896                                 interval = 200;
03897                         break;
03898                                                                                                                   
03899                 case DLY_PARROT:
03900                         if(wait_times)
03901                                 interval = retrieve_astcfgint(myrpt,wait_times_save, "parrotwait",500,5000,200);
03902                         else
03903                                 interval = 200;
03904                         break;
03905                                                                                                                   
03906                 default:
03907          interval = 0;
03908          break;
03909         }
03910    if(wait_times_save)
03911             ast_free(wait_times_save);
03912    return interval;
03913 }                                                                                                                  

static char* handle_cli_cmd ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3429 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_cmd(), and ast_cli_entry::usage.

03431 {
03432         switch (cmd) {
03433         case CLI_INIT:
03434                 e->command = "rpt cmd";
03435                 e->usage = cmd_usage;
03436                 return NULL;
03437         case CLI_GENERATE:
03438                 return NULL;
03439    }
03440    return res2cli(rpt_do_cmd(a->fd,a->argc,a->argv));
03441 }

static char* handle_cli_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3288 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_debug(), and ast_cli_entry::usage.

03290 {
03291         switch (cmd) {
03292         case CLI_INIT:
03293                 e->command = "rpt debug level";
03294                 e->usage = debug_usage;
03295                 return NULL;
03296         case CLI_GENERATE:
03297                 return NULL;
03298    }
03299    return res2cli(rpt_do_debug(a->fd,a->argc,a->argv));
03300 }

static char* handle_cli_dump ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3302 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_dump(), and ast_cli_entry::usage.

03304 {
03305         switch (cmd) {
03306         case CLI_INIT:
03307                 e->command = "rpt dump level";
03308                 e->usage = dump_usage;
03309                 return NULL;
03310         case CLI_GENERATE:
03311                 return NULL;
03312    }
03313    return res2cli(rpt_do_dump(a->fd,a->argc,a->argv));
03314 }

static char* handle_cli_fun ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3401 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_fun(), and ast_cli_entry::usage.

03403 {
03404         switch (cmd) {
03405         case CLI_INIT:
03406                 e->command = "rpt fun";
03407                 e->usage = fun_usage;
03408                 return NULL;
03409         case CLI_GENERATE:
03410                 return NULL;
03411    }
03412    return res2cli(rpt_do_fun(a->fd,a->argc,a->argv));
03413 }

static char* handle_cli_fun1 ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3415 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_fun1(), and ast_cli_entry::usage.

03417 {
03418         switch (cmd) {
03419         case CLI_INIT:
03420                 e->command = "rpt fun1";
03421                 e->usage = fun_usage;
03422                 return NULL;
03423         case CLI_GENERATE:
03424                 return NULL;
03425    }
03426    return res2cli(rpt_do_fun1(a->fd,a->argc,a->argv));
03427 }

static char* handle_cli_local_nodes ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3345 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_local_nodes(), and ast_cli_entry::usage.

03347 {
03348         switch (cmd) {
03349         case CLI_INIT:
03350                 e->command = "rpt localnodes";
03351                 e->usage = usage_local_nodes;
03352                 return NULL;
03353         case CLI_GENERATE:
03354                 return NULL;
03355    }
03356    return res2cli(rpt_do_local_nodes(a->fd,a->argc,a->argv));
03357 }

static char* handle_cli_lstats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3359 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_lstats(), and ast_cli_entry::usage.

03361 {
03362         switch (cmd) {
03363         case CLI_INIT:
03364                 e->command = "rpt lstats";
03365                 e->usage = dump_lstats;
03366                 return NULL;
03367         case CLI_GENERATE:
03368                 return NULL;
03369    }
03370    return res2cli(rpt_do_lstats(a->fd,a->argc,a->argv));
03371 }

static char* handle_cli_nodes ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3331 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_nodes(), and ast_cli_entry::usage.

03333 {
03334         switch (cmd) {
03335         case CLI_INIT:
03336                 e->command = "rpt nodes";
03337                 e->usage = dump_nodes;
03338                 return NULL;
03339         case CLI_GENERATE:
03340                 return NULL;
03341    }
03342    return res2cli(rpt_do_nodes(a->fd,a->argc,a->argv));
03343 }

static char* handle_cli_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3373 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_reload(), and ast_cli_entry::usage.

03375 {
03376         switch (cmd) {
03377         case CLI_INIT:
03378                 e->command = "rpt reload";
03379                 e->usage = reload_usage;
03380                 return NULL;
03381         case CLI_GENERATE:
03382                 return NULL;
03383    }
03384    return res2cli(rpt_do_reload(a->fd,a->argc,a->argv));
03385 }

static char* handle_cli_restart ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3387 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_restart(), and ast_cli_entry::usage.

03389 {
03390         switch (cmd) {
03391         case CLI_INIT:
03392                 e->command = "rpt restart";
03393                 e->usage = restart_usage;
03394                 return NULL;
03395         case CLI_GENERATE:
03396                 return NULL;
03397    }
03398    return res2cli(rpt_do_restart(a->fd,a->argc,a->argv));
03399 }

static char* handle_cli_stats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 3317 of file app_rpt.c.

References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, res2cli(), rpt_do_stats(), and ast_cli_entry::usage.

03319 {
03320         switch (cmd) {
03321         case CLI_INIT:
03322                 e->command = "rpt stats";
03323                 e->usage = dump_stats;
03324                 return NULL;
03325         case CLI_GENERATE:
03326                 return NULL;
03327    }
03328    return res2cli(rpt_do_stats(a->fd,a->argc,a->argv));
03329 }

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

Definition at line 6683 of file app_rpt.c.

References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_TEXT, ast_log(), ast_matchmore_extension(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt::calldigittimer, 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(), dtmfstr, rpt::endchar, rpt::exten, ast_frame::frametype, func_xlat(), rpt::funcchar, rpt::inpadtest, rpt_topkey::keyed, rpt::keyed, rpt::lastdtmfcommand, rpt::lastkeyedtime, 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::newkey, rpt_link::next, rpt_topkey::node, ast_frame::offset, rpt::outxlat, rpt::p, rpt::patchcontext, rpt::patchquiet, rpt::pchannel, PROC, rpt::propagate_dtmf, rpt::propagate_phonedtmf, ast_frame::ptr, 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, rpt_topkey::timesince, rpt::topkey, TOPKEYMAXSTR, TOPKEYN, rpt::topkeystate, and rpt::totalexecdcommands.

Referenced by rpt().

06685 {
06686 char  tmp[512],tmp1[512],cmd[300] = "",dest[300],src[300],c;
06687 int   i,seq, res, ts;
06688 struct rpt_link *l;
06689 struct   ast_frame wf;
06690 
06691    wf.frametype = AST_FRAME_TEXT;
06692    wf.subclass = 0;
06693    wf.offset = 0;
06694    wf.mallocd = 0;
06695    wf.datalen = strlen(str) + 1;
06696    wf.samples = 0;
06697    /* put string in our buffer */
06698    strncpy(tmp,str,sizeof(tmp) - 1);
06699 
06700         if (!strcmp(tmp,discstr))
06701         {
06702                 mylink->disced = 1;
06703       mylink->retries = mylink->max_retries + 1;
06704                 ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV);
06705                 return;
06706         }
06707         if (!strcmp(tmp,newkeystr))
06708         {
06709       mylink->newkey = 1;
06710                 return;
06711         }
06712    if (tmp[0] == 'L')
06713    {
06714       rpt_mutex_lock(&myrpt->lock);
06715       strcpy(mylink->linklist,tmp + 2);
06716       time(&mylink->linklistreceived);
06717       rpt_mutex_unlock(&myrpt->lock);
06718       if (debug > 6) ast_log(LOG_NOTICE,"@@@@ node %s recieved node list %s from node %s\n",
06719          myrpt->name,tmp,mylink->name);
06720       return;
06721    }
06722    if (tmp[0] == 'K')
06723    {
06724       if (sscanf(tmp,"%s %s %s %d %d",cmd,dest,src,&seq,&ts) != 5)
06725       {
06726          ast_log(LOG_WARNING, "Unable to parse keying string %s\n",str);
06727          return;
06728       }
06729       if (dest[0] == '0')
06730       {
06731          strcpy(dest,myrpt->name);
06732       }     
06733       /* if not for me, redistribute to all links */
06734       if (strcmp(dest,myrpt->name))
06735       {
06736          l = myrpt->links.next;
06737          /* see if this is one in list */
06738          while(l != &myrpt->links)
06739          {
06740             if (l->name[0] == '0') 
06741             {
06742                l = l->next;
06743                continue;
06744             }
06745             /* dont send back from where it came */
06746             if ((l == mylink) || (!strcmp(l->name,mylink->name)))
06747             {
06748                l = l->next;
06749                continue;
06750             }
06751             /* if it is, send it and we're done */
06752             if (!strcmp(l->name,dest))
06753             {
06754                /* send, but not to src */
06755                if (strcmp(l->name,src)) {
06756                   wf.data.ptr = str;
06757                   if (l->chan) ast_write(l->chan,&wf);
06758                }
06759                return;
06760             }
06761             l = l->next;
06762          }
06763       }
06764       /* if not for me, or is broadcast, redistribute to all links */
06765       if ((strcmp(dest,myrpt->name)) || (dest[0] == '*'))
06766       {
06767          l = myrpt->links.next;
06768          /* otherwise, send it to all of em */
06769          while(l != &myrpt->links)
06770          {
06771             if (l->name[0] == '0') 
06772             {
06773                l = l->next;
06774                continue;
06775             }
06776             /* dont send back from where it came */
06777             if ((l == mylink) || (!strcmp(l->name,mylink->name)))
06778             {
06779                l = l->next;
06780                continue;
06781             }
06782             /* send, but not to src */
06783             if (strcmp(l->name,src)) {
06784                wf.data.ptr = str;
06785                if (l->chan) ast_write(l->chan,&wf); 
06786             }
06787             l = l->next;
06788          }
06789       }
06790       /* if not for me, end here */
06791       if (strcmp(dest,myrpt->name) && (dest[0] != '*')) return;
06792       if (cmd[1] == '?')
06793       {
06794          time_t now;
06795          int n = 0;
06796 
06797          time(&now);
06798          if (myrpt->lastkeyedtime)
06799          {
06800             n = (int)(now - myrpt->lastkeyedtime);
06801          }
06802          sprintf(tmp1,"K %s %s %d %d",src,myrpt->name,myrpt->keyed,n);
06803          wf.data.ptr = tmp1;
06804          wf.datalen = strlen(tmp1) + 1;
06805          if (mylink->chan) ast_write(mylink->chan,&wf); 
06806          return;
06807       }
06808       if (myrpt->topkeystate != 1) return;
06809       rpt_mutex_lock(&myrpt->lock);
06810       for(i = 0; i < TOPKEYN; i++)
06811       {
06812          if (!strcmp(myrpt->topkey[i].node,src)) break;
06813       }
06814       if (i >= TOPKEYN)
06815       {
06816          for(i = 0; i < TOPKEYN; i++)
06817          {
06818             if (!myrpt->topkey[i].node[0]) break;
06819          }
06820       }
06821       if (i < TOPKEYN)
06822       {
06823          strncpy(myrpt->topkey[i].node,src,TOPKEYMAXSTR - 1);
06824          myrpt->topkey[i].timesince = ts;
06825          myrpt->topkey[i].keyed = seq;
06826       }
06827       rpt_mutex_unlock(&myrpt->lock);
06828       return;
06829    }
06830    if (tmp[0] == 'I')
06831    {
06832       if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3)
06833       {
06834          ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
06835          return;
06836       }
06837       mdc1200_notify(myrpt,src,seq);
06838       strcpy(dest,"*");
06839    }
06840    else
06841    {
06842       if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
06843       {
06844          ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
06845          return;
06846       }
06847       if (strcmp(cmd,"D"))
06848       {
06849          ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
06850          return;
06851       }
06852    }
06853    if (dest[0] == '0')
06854    {
06855       strcpy(dest,myrpt->name);
06856    }     
06857 
06858    /* if not for me, redistribute to all links */
06859    if (strcmp(dest,myrpt->name))
06860    {
06861       l = myrpt->links.next;
06862       /* see if this is one in list */
06863       while(l != &myrpt->links)
06864       {
06865          if (l->name[0] == '0') 
06866          {
06867             l = l->next;
06868             continue;
06869          }
06870          /* dont send back from where it came */
06871          if ((l == mylink) || (!strcmp(l->name,mylink->name)))
06872          {
06873             l = l->next;
06874             continue;
06875          }
06876          /* if it is, send it and we're done */
06877          if (!strcmp(l->name,dest))
06878          {
06879             /* send, but not to src */
06880             if (strcmp(l->name,src)) {
06881                wf.data.ptr = str;
06882                if (l->chan) ast_write(l->chan,&wf);
06883             }
06884             return;
06885          }
06886          l = l->next;
06887       }
06888       l = myrpt->links.next;
06889       /* otherwise, send it to all of em */
06890       while(l != &myrpt->links)
06891       {
06892          if (l->name[0] == '0') 
06893          {
06894             l = l->next;
06895             continue;
06896          }
06897          /* dont send back from where it came */
06898          if ((l == mylink) || (!strcmp(l->name,mylink->name)))
06899          {
06900             l = l->next;
06901             continue;
06902          }
06903          /* send, but not to src */
06904          if (strcmp(l->name,src)) {
06905             wf.data.ptr = str;
06906             if (l->chan) ast_write(l->chan,&wf); 
06907          }
06908          l = l->next;
06909       }
06910       return;
06911    }
06912    if (myrpt->p.archivedir)
06913    {
06914       char dtmfstr[100];
06915 
06916       sprintf(dtmfstr,"DTMF,%s,%c",mylink->name,c);
06917       donodelog(myrpt,dtmfstr);
06918    }
06919    c = func_xlat(myrpt,c,&myrpt->p.outxlat);
06920    if (!c) return;
06921    rpt_mutex_lock(&myrpt->lock);
06922    if (c == myrpt->p.endchar) myrpt->stopgen = 1;
06923    if (myrpt->callmode == 1)
06924    {
06925       myrpt->exten[myrpt->cidx++] = c;
06926       myrpt->exten[myrpt->cidx] = 0;
06927       /* if this exists */
06928       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
06929       {
06930          /* if this really it, end now */
06931          if (!ast_matchmore_extension(myrpt->pchannel,myrpt->patchcontext,
06932             myrpt->exten,1,NULL)) 
06933          {
06934             myrpt->callmode = 2;
06935             if(!myrpt->patchquiet)
06936             {
06937                rpt_mutex_unlock(&myrpt->lock);
06938                rpt_telemetry(myrpt,PROC,NULL); 
06939                rpt_mutex_lock(&myrpt->lock);
06940             }
06941          }
06942          else /* othewise, reset timer */
06943          {
06944             myrpt->calldigittimer = 1;
06945          }
06946       }
06947       /* if can continue, do so */
06948       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
06949       {
06950          /* call has failed, inform user */
06951          myrpt->callmode = 4;
06952       }
06953    }
06954    if ((!myrpt->inpadtest) &&(c == myrpt->p.funcchar))
06955    {
06956       myrpt->rem_dtmfidx = 0;
06957       myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
06958       time(&myrpt->rem_dtmf_time);
06959       rpt_mutex_unlock(&myrpt->lock);
06960       return;
06961    } 
06962    else if (myrpt->rem_dtmfidx < 0)
06963    {
06964       if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
06965       {
06966          myrpt->mydtmf = c;
06967       }
06968       if (myrpt->p.propagate_dtmf) do_dtmf_local(myrpt,c);
06969       if (myrpt->p.propagate_phonedtmf) do_dtmf_phone(myrpt,mylink,c);
06970       rpt_mutex_unlock(&myrpt->lock);
06971       return;
06972    }
06973    else if (((myrpt->inpadtest) || (c != myrpt->p.endchar)) && (myrpt->rem_dtmfidx >= 0))
06974    {
06975       time(&myrpt->rem_dtmf_time);
06976       if (myrpt->rem_dtmfidx < MAXDTMF)
06977       {
06978          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
06979          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
06980          
06981          rpt_mutex_unlock(&myrpt->lock);
06982          strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
06983          res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink);
06984          rpt_mutex_lock(&myrpt->lock);
06985          
06986          switch(res){
06987 
06988             case DC_INDETERMINATE:
06989                break;
06990             
06991             case DC_REQ_FLUSH:
06992                myrpt->rem_dtmfidx = 0;
06993                myrpt->rem_dtmfbuf[0] = 0;
06994                break;
06995             
06996             
06997             case DC_COMPLETE:
06998             case DC_COMPLETEQUIET:
06999                myrpt->totalexecdcommands++;
07000                myrpt->dailyexecdcommands++;
07001                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
07002                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
07003                myrpt->rem_dtmfbuf[0] = 0;
07004                myrpt->rem_dtmfidx = -1;
07005                myrpt->rem_dtmf_time = 0;
07006                break;
07007             
07008             case DC_ERROR:
07009             default:
07010                myrpt->rem_dtmfbuf[0] = 0;
07011                myrpt->rem_dtmfidx = -1;
07012                myrpt->rem_dtmf_time = 0;
07013                break;
07014          }
07015       }
07016 
07017    }
07018    rpt_mutex_unlock(&myrpt->lock);
07019    return;
07020 }

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

Definition at line 7022 of file app_rpt.c.

References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), ast_matchmore_extension(), rpt::calldigittimer, 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::inpadtest, rpt::lastdtmfcommand, rpt_link::lastrealrx, 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_ALT, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, rpt::stopgen, and rpt::totalexecdcommands.

Referenced by rpt().

07024 {
07025 
07026 char  cmd[300];
07027 int   res;
07028 
07029    if (myrpt->p.archivedir)
07030    {
07031       char str[100];
07032 
07033       sprintf(str,"DTMF(P),%s,%c",mylink->name,c);
07034       donodelog(myrpt,str);
07035    }
07036    rpt_mutex_lock(&myrpt->lock);
07037 
07038    if (mylink->phonemode == 3) /*If in simplex dumb phone mode */
07039    {
07040       if(c == myrpt->p.endchar) /* If end char */
07041       {
07042          mylink->lastrealrx = 0; /* Keying state = off */
07043          rpt_mutex_unlock(&myrpt->lock);
07044          return;
07045       }
07046 
07047       if(c == myrpt->p.funcchar) /* If lead-in char */
07048       {
07049          mylink->lastrealrx = !mylink->lastrealrx; /* Toggle keying state */
07050          rpt_mutex_unlock(&myrpt->lock);
07051          return;
07052       }
07053    }
07054    else
07055    {
07056       if (c == myrpt->p.endchar)
07057       {
07058          if (mylink->lastrx)
07059          {
07060             mylink->lastrealrx = 0;
07061             rpt_mutex_unlock(&myrpt->lock);
07062             return;
07063          }
07064          myrpt->stopgen = 1;
07065          if (myrpt->cmdnode[0])
07066          {
07067             myrpt->cmdnode[0] = 0;
07068             myrpt->dtmfidx = -1;
07069             myrpt->dtmfbuf[0] = 0;
07070             rpt_mutex_unlock(&myrpt->lock);
07071             rpt_telemetry(myrpt,COMPLETE,NULL);
07072             return;
07073          }
07074       }
07075    }
07076    if (myrpt->cmdnode[0])
07077    {
07078       rpt_mutex_unlock(&myrpt->lock);
07079       send_link_dtmf(myrpt,c);
07080       return;
07081    }
07082    if (myrpt->callmode == 1)
07083    {
07084       myrpt->exten[myrpt->cidx++] = c;
07085       myrpt->exten[myrpt->cidx] = 0;
07086       /* if this exists */
07087       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
07088       {
07089          /* if this really it, end now */
07090          if (!ast_matchmore_extension(myrpt->pchannel,myrpt->patchcontext,
07091             myrpt->exten,1,NULL)) 
07092          {
07093             myrpt->callmode = 2;
07094             if(!myrpt->patchquiet)
07095             {
07096                rpt_mutex_unlock(&myrpt->lock);
07097                rpt_telemetry(myrpt,PROC,NULL); 
07098                rpt_mutex_lock(&myrpt->lock);
07099             }
07100          }
07101          else /* othewise, reset timer */
07102          {
07103             myrpt->calldigittimer = 1;
07104          }
07105       }
07106       /* if can continue, do so */
07107       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
07108       {
07109          /* call has failed, inform user */
07110          myrpt->callmode = 4;
07111       }
07112    }
07113    if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
07114    {
07115       myrpt->mydtmf = c;
07116    }
07117    if ((!myrpt->inpadtest) && (c == myrpt->p.funcchar))
07118    {
07119       myrpt->rem_dtmfidx = 0;
07120       myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
07121       time(&myrpt->rem_dtmf_time);
07122       rpt_mutex_unlock(&myrpt->lock);
07123       return;
07124    } 
07125    else if (((myrpt->inpadtest) || (c != myrpt->p.endchar)) && (myrpt->rem_dtmfidx >= 0))
07126    {
07127       time(&myrpt->rem_dtmf_time);
07128       if (myrpt->rem_dtmfidx < MAXDTMF)
07129       {
07130          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c;
07131          myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0;
07132          
07133          rpt_mutex_unlock(&myrpt->lock);
07134          strncpy(cmd, myrpt->rem_dtmfbuf, sizeof(cmd) - 1);
07135          switch(mylink->phonemode)
07136          {
07137              case 1:
07138             res = collect_function_digits(myrpt, cmd, 
07139                SOURCE_PHONE, mylink);
07140             break;
07141              case 2:
07142             res = collect_function_digits(myrpt, cmd, 
07143                SOURCE_DPHONE,mylink);
07144             break;
07145              case 4:
07146             res = collect_function_digits(myrpt, cmd, 
07147                SOURCE_ALT,mylink);
07148             break;
07149              default:
07150             res = collect_function_digits(myrpt, cmd, 
07151                SOURCE_LNK, mylink);
07152             break;
07153          }
07154 
07155          rpt_mutex_lock(&myrpt->lock);
07156          
07157          switch(res){
07158 
07159             case DC_INDETERMINATE:
07160                break;
07161             
07162             case DC_DOKEY:
07163                mylink->lastrealrx = 1;
07164                break;
07165             
07166             case DC_REQ_FLUSH:
07167                myrpt->rem_dtmfidx = 0;
07168                myrpt->rem_dtmfbuf[0] = 0;
07169                break;
07170             
07171             
07172             case DC_COMPLETE:
07173             case DC_COMPLETEQUIET:
07174                myrpt->totalexecdcommands++;
07175                myrpt->dailyexecdcommands++;
07176                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
07177                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
07178                myrpt->rem_dtmfbuf[0] = 0;
07179                myrpt->rem_dtmfidx = -1;
07180                myrpt->rem_dtmf_time = 0;
07181                break;
07182             
07183             case DC_ERROR:
07184             default:
07185                myrpt->rem_dtmfbuf[0] = 0;
07186                myrpt->rem_dtmfidx = -1;
07187                myrpt->rem_dtmf_time = 0;
07188                break;
07189          }
07190       }
07191 
07192    }
07193    rpt_mutex_unlock(&myrpt->lock);
07194    return;
07195 }

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

Definition at line 10235 of file app_rpt.c.

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

10236 {
10237 char  tmp[300],cmd[300],dest[300],src[300],c;
10238 int   seq,res;
10239 
10240    /* put string in our buffer */
10241    strncpy(tmp,str,sizeof(tmp) - 1);
10242    if (!strcmp(tmp,discstr)) return 0;
10243         if (!strcmp(tmp,newkeystr))
10244         {
10245       myrpt->newkey = 1;
10246                 return 0;
10247         }
10248 
10249 #ifndef  DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES
10250    if (tmp[0] == 'I')
10251    {
10252       if (sscanf(tmp,"%s %s %x",cmd,src,&seq) != 3)
10253       {
10254          ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
10255          return 0;
10256       }
10257       mdc1200_notify(myrpt,src,seq);
10258       return 0;
10259    }
10260 #endif
10261    if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5)
10262    {
10263       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
10264       return 0;
10265    }
10266    if (strcmp(cmd,"D"))
10267    {
10268       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
10269       return 0;
10270    }
10271    /* if not for me, ignore */
10272    if (strcmp(dest,myrpt->name)) return 0;
10273    if (myrpt->p.archivedir)
10274    {
10275       char dtmfstr[100];
10276 
10277       sprintf(dtmfstr,"DTMF,%c",c);
10278       donodelog(myrpt,dtmfstr);
10279    }
10280    c = func_xlat(myrpt,c,&myrpt->p.outxlat);
10281    if (!c) return(0);
10282    res = handle_remote_dtmf_digit(myrpt,c, NULL, 0);
10283    if (res != 1)
10284       return res;
10285    rpt_telemetry(myrpt,COMPLETE,NULL);
10286    return 0;
10287 }

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

Definition at line 10121 of file app_rpt.c.

References ast_log(), 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, LOG_NOTICE, MAXDTMF, rpt::p, rpt::propagate_dtmf, rpt_mutex_lock, rpt_mutex_unlock, SOURCE_ALT, SOURCE_DPHONE, SOURCE_PHONE, SOURCE_RMT, stop_scan(), and rpt::totalexecdcommands.

Referenced by handle_remote_data(), and handle_remote_phone_dtmf().

10122 {
10123 time_t   now;
10124 int   ret,res = 0,src;
10125 
10126    if(debug > 6)
10127       ast_log(LOG_NOTICE,"c=%c  phonemode=%i  dtmfidx=%i\n",c,phonemode,myrpt->dtmfidx);
10128 
10129    time(&myrpt->last_activity_time);
10130    /* Stop scan mode if in scan mode */
10131    if(myrpt->hfscanmode){
10132       stop_scan(myrpt);
10133       return 0;
10134    }
10135 
10136    time(&now);
10137    /* if timed-out */
10138    if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now)
10139    {
10140       myrpt->dtmfidx = -1;
10141       myrpt->dtmfbuf[0] = 0;
10142       myrpt->dtmf_time_rem = 0;
10143    }
10144    /* if decode not active */
10145    if (myrpt->dtmfidx == -1)
10146    {
10147       /* if not lead-in digit, dont worry */
10148       if (c != myrpt->p.funcchar)
10149       {
10150          if (!myrpt->p.propagate_dtmf)
10151          {
10152             rpt_mutex_lock(&myrpt->lock);
10153             do_dtmf_local(myrpt,c);
10154             rpt_mutex_unlock(&myrpt->lock);
10155          }
10156          return 0;
10157       }
10158       myrpt->dtmfidx = 0;
10159       myrpt->dtmfbuf[0] = 0;
10160       myrpt->dtmf_time_rem = now;
10161       return 0;
10162    }
10163    /* if too many in buffer, start over */
10164    if (myrpt->dtmfidx >= MAXDTMF)
10165    {
10166       myrpt->dtmfidx = 0;
10167       myrpt->dtmfbuf[0] = 0;
10168       myrpt->dtmf_time_rem = now;
10169    }
10170    if (c == myrpt->p.funcchar)
10171    {
10172       /* if star at beginning, or 2 together, erase buffer */
10173       if ((myrpt->dtmfidx < 1) || 
10174          (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->p.funcchar))
10175       {
10176          myrpt->dtmfidx = 0;
10177          myrpt->dtmfbuf[0] = 0;
10178          myrpt->dtmf_time_rem = now;
10179          return 0;
10180       }
10181    }
10182    myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
10183    myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
10184    myrpt->dtmf_time_rem = now;
10185    
10186    
10187    src = SOURCE_RMT;
10188    if (phonemode == 2) src = SOURCE_DPHONE;
10189    else if (phonemode) src = SOURCE_PHONE;
10190    else if (phonemode == 4) src = SOURCE_ALT;
10191    ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL);
10192    
10193    switch(ret){
10194    
10195       case DC_INDETERMINATE:
10196          res = 0;
10197          break;
10198             
10199       case DC_DOKEY:
10200          if (keyed) *keyed = 1;
10201          res = 0;
10202          break;
10203             
10204       case DC_REQ_FLUSH:
10205          myrpt->dtmfidx = 0;
10206          myrpt->dtmfbuf[0] = 0;
10207          res = 0;
10208          break;
10209             
10210             
10211       case DC_COMPLETE:
10212          res = 1;
10213       case DC_COMPLETEQUIET:
10214          myrpt->totalexecdcommands++;
10215          myrpt->dailyexecdcommands++;
10216          strncpy(myrpt->lastdtmfcommand, myrpt->dtmfbuf, MAXDTMF-1);
10217          myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
10218          myrpt->dtmfbuf[0] = 0;
10219          myrpt->dtmfidx = -1;
10220          myrpt->dtmf_time_rem = 0;
10221          break;
10222             
10223       case DC_ERROR:
10224       default:
10225          myrpt->dtmfbuf[0] = 0;
10226          myrpt->dtmfidx = -1;
10227          myrpt->dtmf_time_rem = 0;
10228          res = 0;
10229          break;
10230    }
10231 
10232    return res;
10233 }

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

Definition at line 10289 of file app_rpt.c.

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

10290 {
10291 int   res;
10292 
10293 
10294    if(phonemode == 3) /* simplex phonemode, funcchar key/unkey toggle */
10295    {
10296       if (keyed && *keyed && ((c == myrpt->p.funcchar) || (c == myrpt->p.endchar)))
10297       {
10298          *keyed = 0; /* UNKEY */
10299          return 0;
10300       }
10301       else if (keyed && !*keyed && (c = myrpt->p.funcchar))
10302       {
10303          *keyed = 1; /* KEY */
10304          return 0;
10305       }
10306    }
10307    else /* endchar unkey */
10308    {
10309 
10310       if (keyed && *keyed && (c == myrpt->p.endchar))
10311       {
10312          *keyed = 0;
10313          return DC_INDETERMINATE;
10314       }
10315    }
10316    if (myrpt->p.archivedir)
10317    {
10318       char str[100];
10319 
10320       sprintf(str,"DTMF(P),%c",c);
10321       donodelog(myrpt,str);
10322    }
10323    res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode);
10324    if (res != 1)
10325       return res;
10326    rpt_telemetry(myrpt,COMPLETE,NULL);
10327    return 0;
10328 }

static int ic706_pltocode ( char *  str  )  [static]

Definition at line 8755 of file app_rpt.c.

References ast_log(), LOG_NOTICE, and s.

Referenced by set_ic706().

08756 {
08757    int i;
08758    char *s;
08759    int rv=-1;
08760 
08761    s = strchr(str,'.');
08762    i = 0;
08763    if (s) i = atoi(s + 1);
08764    i += atoi(str) * 10;
08765    switch(i)
08766    {
08767        case 670:
08768          rv=0;
08769        case 693:
08770          rv=1;
08771        case 719:
08772          rv=2;
08773        case 744:
08774          rv=3;
08775        case 770:
08776          rv=4;
08777        case 797:
08778          rv=5;
08779        case 825:
08780          rv=6;
08781        case 854:
08782          rv=7;
08783        case 885:
08784          rv=8;
08785        case 915:
08786          rv=9;
08787        case 948:
08788          rv=10;
08789        case 974:
08790          rv=11;
08791        case 1000:
08792          rv=12;
08793        case 1035:
08794          rv=13;
08795        case 1072:
08796          rv=14;
08797        case 1109:
08798          rv=15;
08799        case 1148:
08800          rv=16;
08801        case 1188:
08802          rv=17;
08803        case 1230:
08804          rv=18;
08805        case 1273:
08806          rv=19;
08807        case 1318:
08808          rv=20;
08809        case 1365:
08810          rv=21;
08811        case 1413:
08812          rv=22;
08813        case 1462:
08814          rv=23;
08815        case 1514:
08816          rv=24;
08817        case 1567:
08818          rv=25;
08819        case 1598:
08820          rv=26;
08821        case 1622:
08822          rv=27;
08823        case 1655:
08824          rv=28;      
08825        case 1679:
08826          rv=29;
08827        case 1713:
08828          rv=30;
08829        case 1738:
08830          rv=31;
08831        case 1773:
08832          rv=32;
08833        case 1799:
08834          rv=33;
08835         case 1835:
08836          rv=34;
08837        case 1862:
08838          rv=35;
08839        case 1899:
08840          rv=36;
08841        case 1928:
08842          rv=37;
08843        case 1966:
08844          rv=38;
08845        case 1995:
08846          rv=39;
08847        case 2035:
08848          rv=40;
08849        case 2065:
08850          rv=41;
08851        case 2107:
08852          rv=42;
08853        case 2181:
08854          rv=43;
08855        case 2257:
08856          rv=44;
08857        case 2291:
08858          rv=45;
08859        case 2336:
08860          rv=46;
08861        case 2418:
08862          rv=47;
08863        case 2503:
08864          rv=48;
08865        case 2541:
08866          rv=49;
08867    }
08868    if(debug > 1)
08869       ast_log(LOG_NOTICE,"%i  rv=%i\n",i, rv);
08870 
08871    return rv;
08872 }

static int kenwood_pltocode ( char *  str  )  [static]

Definition at line 7539 of file app_rpt.c.

References s.

Referenced by set_tm271(), and setkenwood().

07540 {
07541 int i;
07542 char *s;
07543 
07544    s = strchr(str,'.');
07545    i = 0;
07546    if (s) i = atoi(s + 1);
07547    i += atoi(str) * 10;
07548    switch(i)
07549    {
07550        case 670:
07551       return 1;
07552        case 719:
07553       return 3;
07554        case 744:
07555       return 4;
07556        case 770:
07557       return 5;
07558        case 797:
07559       return 6;
07560        case 825:
07561       return 7;
07562        case 854:
07563       return 8;
07564        case 885:
07565       return 9;
07566        case 915:
07567       return 10;
07568        case 948:
07569       return 11;
07570        case 974:
07571       return 12;
07572        case 1000:
07573       return 13;
07574        case 1035:
07575       return 14;
07576        case 1072:
07577       return 15;
07578        case 1109:
07579       return 16;
07580        case 1148:
07581       return 17;
07582        case 1188:
07583       return 18;
07584        case 1230:
07585       return 19;
07586        case 1273:
07587       return 20;
07588        case 1318:
07589       return 21;
07590        case 1365:
07591       return 22;
07592        case 1413:
07593       return 23;
07594        case 1462:
07595       return 24;
07596        case 1514:
07597       return 25;
07598        case 1567:
07599       return 26;
07600        case 1622:
07601       return 27;
07602        case 1679:
07603       return 28;
07604        case 1738:
07605       return 29;
07606        case 1799:
07607       return 30;
07608        case 1862:
07609       return 31;
07610        case 1928:
07611       return 32;
07612        case 2035:
07613       return 33;
07614        case 2107:
07615       return 34;
07616        case 2181:
07617       return 35;
07618        case 2257:
07619       return 36;
07620        case 2336:
07621       return 37;
07622        case 2418:
07623       return 38;
07624        case 2503:
07625       return 39;
07626    }
07627    return -1;
07628 }

static int linkcount ( struct rpt myrpt  )  [static]

Definition at line 1379 of file app_rpt.c.

References ast_log(), rpt::links, LOG_NOTICE, LOG_WARNING, MAX_STAT_LINKS, and rpt_link::next.

Referenced by rpt_exec().

01380 {
01381    struct   rpt_link *l;
01382    char *reverse_patch_state;
01383    int numoflinks;
01384 
01385    reverse_patch_state = "DOWN";
01386    numoflinks = 0;
01387    l = myrpt->links.next;
01388    while(l && (l != &myrpt->links)){
01389       if(numoflinks >= MAX_STAT_LINKS){
01390          ast_log(LOG_WARNING,
01391          "maximum number of links exceeds %d in rpt_do_stats()!",MAX_STAT_LINKS);
01392          break;
01393       }
01394       //if (l->name[0] == '0'){ /* Skip '0' nodes */
01395       // reverse_patch_state = "UP";
01396       // l = l->next;
01397       // continue;
01398       //}
01399       numoflinks++;
01400     
01401       l = l->next;
01402    }
01403    ast_log(LOG_NOTICE, "numoflinks=%i\n",numoflinks);
01404    return numoflinks;
01405 }

static int load_module ( void   )  [static]

Definition at line 15142 of file app_rpt.c.

References ast_cli_register(), ast_cli_register_multiple(), ast_manager_register, ast_pthread_create, ast_register_application, cli_reload, manager_rpt_local_nodes(), manager_rpt_status(), rpt_cli, rpt_exec(), and rpt_master().

15144 {
15145    int res;
15146    ast_pthread_create(&rpt_master_thread,NULL,rpt_master,NULL);
15147 
15148 #ifdef   NEW_ASTERISK
15149    ast_cli_register_multiple(rpt_cli,sizeof(rpt_cli) / 
15150       sizeof(struct ast_cli_entry));
15151    res = 0;
15152 #else
15153    /* Register cli extensions */
15154    ast_cli_register(&cli_debug);
15155    ast_cli_register(&cli_dump);
15156    ast_cli_register(&cli_stats);
15157    ast_cli_register(&cli_lstats);
15158    ast_cli_register(&cli_nodes);
15159    ast_cli_register(&cli_local_nodes);
15160    ast_cli_register(&cli_reload);
15161    ast_cli_register(&cli_restart);
15162    ast_cli_register(&cli_fun);
15163    ast_cli_register(&cli_fun1);
15164    res = ast_cli_register(&cli_cmd);
15165 #endif
15166 #ifndef OLD_ASTERISK
15167    res |= ast_manager_register("RptLocalNodes", 0, manager_rpt_local_nodes, "List local node numbers");
15168    res |= ast_manager_register("RptStatus", 0, manager_rpt_status, "Return Rpt Status for CGI");
15169 
15170 #endif
15171    res |= ast_register_application(app, rpt_exec, synopsis, descrip);
15172    return res;
15173 }

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

Definition at line 2221 of file app_rpt.c.

References 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, config_flags, 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, ENDCHAR, EXTNODEFILE, EXTNODES, finddelim(), FUNCCHAR, FUNCTIONS, HANGTIME, IDTIME, lock, LOG_NOTICE, LOG_WARNING, MACRO, MAX_SYSSTATES, MAXXLAT, MEMORY, ast_variable::name, name, ast_variable::next, NODES, option_verbose, PARROTTIME, POLITEID, retrieve_astcfgint(), SIMPLEX_PATCH_DELAY, SIMPLEX_PHONE_DELAY, STATPOST_PROGRAM, TONEMACRO, TOTIME, ast_variable::value, VERBOSE_PREFIX_3, VOX_RECOVER_MS, and VOX_TIMEOUT_MS.

Referenced by rpt(), and rpt_master().

02222 {
02223 char *this,*val;
02224 int   i,j,longestnode;
02225 struct ast_variable *vp;
02226 struct ast_config *cfg;
02227 char *strs[100];
02228 char s1[256];
02229 static char *cs_keywords[] = {"rptena","rptdis","apena","apdis","lnkena","lnkdis","totena","totdis","skena","skdis",
02230             "ufena","ufdis","atena","atdis",NULL};
02231 
02232    if (option_verbose > 2)
02233       ast_verbose(VERBOSE_PREFIX_3 "%s config for repeater %s\n",
02234          (init) ? "Loading initial" : "Re-Loading",rpt_vars[n].name);
02235    ast_mutex_lock(&rpt_vars[n].lock);
02236    if (rpt_vars[n].cfg) ast_config_destroy(rpt_vars[n].cfg);
02237 #ifdef   NEW_ASTERISK
02238    cfg = ast_config_load("rpt.conf",config_flags);
02239 #else
02240    cfg = ast_config_load("rpt.conf");
02241 #endif
02242    if (!cfg) {
02243       ast_mutex_unlock(&rpt_vars[n].lock);
02244       ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf.  Radio Repeater disabled.\n");
02245       pthread_exit(NULL);
02246    }
02247    rpt_vars[n].cfg = cfg; 
02248    this = rpt_vars[n].name;
02249    memset(&rpt_vars[n].p,0,sizeof(rpt_vars[n].p));
02250    if (init)
02251    {
02252       char *cp;
02253       int savearea = (char *)&rpt_vars[n].p - (char *)&rpt_vars[n];
02254 
02255       cp = (char *) &rpt_vars[n].p;
02256       memset(cp + sizeof(rpt_vars[n].p),0,
02257          sizeof(rpt_vars[n]) - (sizeof(rpt_vars[n].p) + savearea));
02258       rpt_vars[n].tele.next = &rpt_vars[n].tele;
02259       rpt_vars[n].tele.prev = &rpt_vars[n].tele;
02260       rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
02261       rpt_vars[n].tailmessagen = 0;
02262    }
02263 #ifdef   __RPT_NOTCH
02264    /* zot out filters stuff */
02265    memset(&rpt_vars[n].filters,0,sizeof(rpt_vars[n].filters));
02266 #endif
02267    val = (char *) ast_variable_retrieve(cfg,this,"context");
02268    if (val) rpt_vars[n].p.ourcontext = val;
02269    else rpt_vars[n].p.ourcontext = this;
02270    val = (char *) ast_variable_retrieve(cfg,this,"callerid");
02271    if (val) rpt_vars[n].p.ourcallerid = val;
02272    val = (char *) ast_variable_retrieve(cfg,this,"accountcode");
02273    if (val) rpt_vars[n].p.acctcode = val;
02274    val = (char *) ast_variable_retrieve(cfg,this,"idrecording");
02275    if (val) rpt_vars[n].p.ident = val;
02276    val = (char *) ast_variable_retrieve(cfg,this,"hangtime");
02277    if (val) rpt_vars[n].p.hangtime = atoi(val);
02278       else rpt_vars[n].p.hangtime = HANGTIME;
02279    val = (char *) ast_variable_retrieve(cfg,this,"althangtime");
02280    if (val) rpt_vars[n].p.althangtime = atoi(val);
02281       else rpt_vars[n].p.althangtime = HANGTIME;
02282    val = (char *) ast_variable_retrieve(cfg,this,"totime");
02283    if (val) rpt_vars[n].p.totime = atoi(val);
02284       else rpt_vars[n].p.totime = TOTIME;
02285    val = (char *) ast_variable_retrieve(cfg,this,"voxtimeout");
02286    if (val) rpt_vars[n].p.voxtimeout_ms = atoi(val);
02287       else rpt_vars[n].p.voxtimeout_ms = VOX_TIMEOUT_MS;
02288    val = (char *) ast_variable_retrieve(cfg,this,"voxrecover");
02289    if (val) rpt_vars[n].p.voxrecover_ms = atoi(val);
02290       else rpt_vars[n].p.voxrecover_ms = VOX_RECOVER_MS;
02291    val = (char *) ast_variable_retrieve(cfg,this,"simplexpatchdelay");
02292    if (val) rpt_vars[n].p.simplexpatchdelay = atoi(val);
02293       else rpt_vars[n].p.simplexpatchdelay = SIMPLEX_PATCH_DELAY;
02294    val = (char *) ast_variable_retrieve(cfg,this,"simplexphonedelay");
02295    if (val) rpt_vars[n].p.simplexphonedelay = atoi(val);
02296       else rpt_vars[n].p.simplexphonedelay = SIMPLEX_PHONE_DELAY;
02297    val = (char *) ast_variable_retrieve(cfg,this,"statpost_program");
02298    if (val) rpt_vars[n].p.statpost_program = val;
02299       else rpt_vars[n].p.statpost_program = STATPOST_PROGRAM;
02300    rpt_vars[n].p.statpost_url = 
02301       (char *) ast_variable_retrieve(cfg,this,"statpost_url");
02302    rpt_vars[n].p.tailmessagetime = retrieve_astcfgint(&rpt_vars[n],this, "tailmessagetime", 0, 2400000, 0);    
02303    rpt_vars[n].p.tailsquashedtime = retrieve_astcfgint(&rpt_vars[n],this, "tailsquashedtime", 0, 2400000, 0);     
02304    rpt_vars[n].p.duplex = retrieve_astcfgint(&rpt_vars[n],this,"duplex",0,4,2);
02305    rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", -60000, 2400000, IDTIME);   /* Enforce a min max including zero */
02306    rpt_vars[n].p.politeid = retrieve_astcfgint(&rpt_vars[n],this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */
02307    val = (char *) ast_variable_retrieve(cfg,this,"tonezone");
02308    if (val) rpt_vars[n].p.tonezone = val;
02309    rpt_vars[n].p.tailmessages[0] = 0;
02310    rpt_vars[n].p.tailmessagemax = 0;
02311    val = (char *) ast_variable_retrieve(cfg,this,"tailmessagelist");
02312    if (val) rpt_vars[n].p.tailmessagemax = finddelim(val, rpt_vars[n].p.tailmessages, 500);
02313    val = (char *) ast_variable_retrieve(cfg,this,"memory");
02314    if (!val) val = MEMORY;
02315    rpt_vars[n].p.memory = val;
02316    val = (char *) ast_variable_retrieve(cfg,this,"macro");
02317    if (!val) val = MACRO;
02318    rpt_vars[n].p.macro = val;
02319    val = (char *) ast_variable_retrieve(cfg,this,"tonemacro");
02320    if (!val) val = TONEMACRO;
02321    rpt_vars[n].p.tonemacro = val;
02322    val = (char *) ast_variable_retrieve(cfg,this,"startup_macro");
02323    if (val) rpt_vars[n].p.startupmacro = val;
02324    val = (char *) ast_variable_retrieve(cfg,this,"iobase");
02325    /* do not use atoi() here, we need to be able to have
02326       the input specified in hex or decimal so we use
02327       sscanf with a %i */
02328    if ((!val) || (sscanf(val,"%i",&rpt_vars[n].p.iobase) != 1))
02329       rpt_vars[n].p.iobase = DEFAULT_IOBASE;
02330    val = (char *) ast_variable_retrieve(cfg,this,"ioport");
02331    rpt_vars[n].p.ioport = val;
02332    val = (char *) ast_variable_retrieve(cfg,this,"functions");
02333    if (!val)
02334       {
02335          val = FUNCTIONS;
02336          rpt_vars[n].p.simple = 1;
02337       } 
02338    rpt_vars[n].p.functions = val;
02339    val =  (char *) ast_variable_retrieve(cfg,this,"link_functions");
02340    if (val) rpt_vars[n].p.link_functions = val;
02341    else 
02342       rpt_vars[n].p.link_functions = rpt_vars[n].p.functions;
02343    val = (char *) ast_variable_retrieve(cfg,this,"phone_functions");
02344    if (val) rpt_vars[n].p.phone_functions = val;
02345    val = (char *) ast_variable_retrieve(cfg,this,"dphone_functions");
02346    if (val) rpt_vars[n].p.dphone_functions = val;
02347    val = (char *) ast_variable_retrieve(cfg,this,"alt_functions");
02348    if (val) rpt_vars[n].p.alt_functions = val;
02349    val = (char *) ast_variable_retrieve(cfg,this,"funcchar");
02350    if (!val) rpt_vars[n].p.funcchar = FUNCCHAR; else 
02351       rpt_vars[n].p.funcchar = *val;      
02352    val = (char *) ast_variable_retrieve(cfg,this,"endchar");
02353    if (!val) rpt_vars[n].p.endchar = ENDCHAR; else 
02354       rpt_vars[n].p.endchar = *val;    
02355    val = (char *) ast_variable_retrieve(cfg,this,"nobusyout");
02356    if (val) rpt_vars[n].p.nobusyout = ast_true(val);
02357    val = (char *) ast_variable_retrieve(cfg,this,"notelemtx");
02358    if (val) rpt_vars[n].p.notelemtx = ast_true(val);
02359    val = (char *) ast_variable_retrieve(cfg,this,"propagate_dtmf");
02360    if (val) rpt_vars[n].p.propagate_dtmf = ast_true(val);
02361    val = (char *) ast_variable_retrieve(cfg,this,"propagate_phonedtmf");
02362    if (val) rpt_vars[n].p.propagate_phonedtmf = ast_true(val);
02363    val = (char *) ast_variable_retrieve(cfg,this,"linktolink");
02364    if (val) rpt_vars[n].p.linktolink = ast_true(val);
02365    val = (char *) ast_variable_retrieve(cfg,this,"nodes");
02366    if (!val) val = NODES;
02367    rpt_vars[n].p.nodes = val;
02368    val = (char *) ast_variable_retrieve(cfg,this,"extnodes");
02369    if (!val) val = EXTNODES;
02370    rpt_vars[n].p.extnodes = val;
02371    val = (char *) ast_variable_retrieve(cfg,this,"extnodefile");
02372    if (!val) val = EXTNODEFILE;
02373    rpt_vars[n].p.extnodefile = val;
02374    val = (char *) ast_variable_retrieve(cfg,this,"archivedir");
02375    if (val) rpt_vars[n].p.archivedir = val;
02376    val = (char *) ast_variable_retrieve(cfg,this,"authlevel");
02377    if (val) rpt_vars[n].p.authlevel = atoi(val); 
02378    else rpt_vars[n].p.authlevel = 0;
02379    val = (char *) ast_variable_retrieve(cfg,this,"parrot");
02380    if (val) rpt_vars[n].p.parrotmode = ast_true(val) * 2;
02381    else rpt_vars[n].p.parrotmode = 0;
02382    val = (char *) ast_variable_retrieve(cfg,this,"parrottime");
02383    if (val) rpt_vars[n].p.parrottime = atoi(val); 
02384    else rpt_vars[n].p.parrottime = PARROTTIME;
02385    val = (char *) ast_variable_retrieve(cfg,this,"rptnode");
02386    rpt_vars[n].p.rptnode = val;
02387    val = (char *) ast_variable_retrieve(cfg,this,"mars");
02388    if (val) rpt_vars[n].p.remote_mars = atoi(val); 
02389    else rpt_vars[n].p.remote_mars = 0;
02390    val = (char *) ast_variable_retrieve(cfg,this,"monminblocks");
02391    if (val) rpt_vars[n].p.monminblocks = atol(val); 
02392    else rpt_vars[n].p.monminblocks = DEFAULT_MONITOR_MIN_DISK_BLOCKS;
02393    val = (char *) ast_variable_retrieve(cfg,this,"remote_inact_timeout");
02394    if (val) rpt_vars[n].p.remoteinacttimeout = atoi(val); 
02395    else rpt_vars[n].p.remoteinacttimeout = DEFAULT_REMOTE_INACT_TIMEOUT;
02396    val = (char *) ast_variable_retrieve(cfg,this,"civaddr");
02397    if (val) rpt_vars[n].p.civaddr = atoi(val); 
02398    else rpt_vars[n].p.civaddr = DEFAULT_CIV_ADDR;
02399    val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout");
02400    if (val) rpt_vars[n].p.remotetimeout = atoi(val); 
02401    else rpt_vars[n].p.remotetimeout = DEFAULT_REMOTE_TIMEOUT;
02402    val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning");
02403    if (val) rpt_vars[n].p.remotetimeoutwarning = atoi(val); 
02404    else rpt_vars[n].p.remotetimeoutwarning = DEFAULT_REMOTE_TIMEOUT_WARNING;
02405    val = (char *) ast_variable_retrieve(cfg,this,"remote_timeout_warning_freq");
02406    if (val) rpt_vars[n].p.remotetimeoutwarningfreq = atoi(val); 
02407    else rpt_vars[n].p.remotetimeoutwarningfreq = DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ;
02408 #ifdef   __RPT_NOTCH
02409    val = (char *) ast_variable_retrieve(cfg,this,"rxnotch");
02410    if (val) {
02411       i = finddelim(val,strs,MAXFILTERS * 2);
02412       i &= ~1; /* force an even number, rounded down */
02413       if (i >= 2) for(j = 0; j < i; j += 2)
02414       {
02415          rpt_mknotch(atof(strs[j]),atof(strs[j + 1]),
02416            &rpt_vars[n].filters[j >> 1].gain,
02417              &rpt_vars[n].filters[j >> 1].const0,
02418             &rpt_vars[n].filters[j >> 1].const1,
02419                 &rpt_vars[n].filters[j >> 1].const2);
02420          sprintf(rpt_vars[n].filters[j >> 1].desc,"%s Hz, BW = %s",
02421             strs[j],strs[j + 1]);
02422       }
02423 
02424    }
02425 #endif
02426    val = (char *) ast_variable_retrieve(cfg,this,"inxlat");
02427    if (val) {
02428       memset(&rpt_vars[n].p.inxlat,0,sizeof(struct rpt_xlat));
02429       i = finddelim(val,strs,3);
02430       if (i) strncpy(rpt_vars[n].p.inxlat.funccharseq,strs[0],MAXXLAT - 1);
02431       if (i > 1) strncpy(rpt_vars[n].p.inxlat.endcharseq,strs[1],MAXXLAT - 1);
02432       if (i > 2) strncpy(rpt_vars[n].p.inxlat.passchars,strs[2],MAXXLAT - 1);
02433    }
02434    val = (char *) ast_variable_retrieve(cfg,this,"outxlat");
02435    if (val) {
02436       memset(&rpt_vars[n].p.outxlat,0,sizeof(struct rpt_xlat));
02437       i = finddelim(val,strs,3);
02438       if (i) strncpy(rpt_vars[n].p.outxlat.funccharseq,strs[0],MAXXLAT - 1);
02439       if (i > 1) strncpy(rpt_vars[n].p.outxlat.endcharseq,strs[1],MAXXLAT - 1);
02440       if (i > 2) strncpy(rpt_vars[n].p.outxlat.passchars,strs[2],MAXXLAT - 1);
02441    }
02442    /* retreive the stanza name for the control states if there is one */
02443    val = (char *) ast_variable_retrieve(cfg,this,"controlstates");
02444    rpt_vars[n].p.csstanzaname = val;
02445       
02446    /* retreive the stanza name for the scheduler if there is one */
02447    val = (char *) ast_variable_retrieve(cfg,this,"scheduler");
02448    rpt_vars[n].p.skedstanzaname = val;
02449 
02450    /* retreive the stanza name for the txlimits */
02451    val = (char *) ast_variable_retrieve(cfg,this,"txlimits");
02452    rpt_vars[n].p.txlimitsstanzaname = val;
02453 
02454    longestnode = 0;
02455 
02456    vp = ast_variable_browse(cfg, rpt_vars[n].p.nodes);
02457       
02458    while(vp){
02459       j = strlen(vp->name);
02460       if (j > longestnode)
02461          longestnode = j;
02462       vp = vp->next;
02463    }
02464 
02465    rpt_vars[n].longestnode = longestnode;
02466       
02467    /*
02468    * For this repeater, Determine the length of the longest function 
02469    */
02470    rpt_vars[n].longestfunc = 0;
02471    vp = ast_variable_browse(cfg, rpt_vars[n].p.functions);
02472    while(vp){
02473       j = strlen(vp->name);
02474       if (j > rpt_vars[n].longestfunc)
02475          rpt_vars[n].longestfunc = j;
02476       vp = vp->next;
02477    }
02478    /*
02479    * For this repeater, Determine the length of the longest function 
02480    */
02481    rpt_vars[n].link_longestfunc = 0;
02482    vp = ast_variable_browse(cfg, rpt_vars[n].p.link_functions);
02483    while(vp){
02484       j = strlen(vp->name);
02485       if (j > rpt_vars[n].link_longestfunc)
02486          rpt_vars[n].link_longestfunc = j;
02487       vp = vp->next;
02488    }
02489    rpt_vars[n].phone_longestfunc = 0;
02490    if (rpt_vars[n].p.phone_functions)
02491    {
02492       vp = ast_variable_browse(cfg, rpt_vars[n].p.phone_functions);
02493       while(vp){
02494          j = strlen(vp->name);
02495          if (j > rpt_vars[n].phone_longestfunc)
02496             rpt_vars[n].phone_longestfunc = j;
02497          vp = vp->next;
02498       }
02499    }
02500    rpt_vars[n].dphone_longestfunc = 0;
02501    if (rpt_vars[n].p.dphone_functions)
02502    {
02503       vp = ast_variable_browse(cfg, rpt_vars[n].p.dphone_functions);
02504       while(vp){
02505          j = strlen(vp->name);
02506          if (j > rpt_vars[n].dphone_longestfunc)
02507             rpt_vars[n].dphone_longestfunc = j;
02508          vp = vp->next;
02509       }
02510    }
02511    rpt_vars[n].alt_longestfunc = 0;
02512    if (rpt_vars[n].p.alt_functions)
02513    {
02514       vp = ast_variable_browse(cfg, rpt_vars[n].p.alt_functions);
02515       while(vp){
02516          j = strlen(vp->name);
02517          if (j > rpt_vars[n].alt_longestfunc)
02518             rpt_vars[n].alt_longestfunc = j;
02519          vp = vp->next;
02520       }
02521    }
02522    rpt_vars[n].macro_longest = 1;
02523    vp = ast_variable_browse(cfg, rpt_vars[n].p.macro);
02524    while(vp){
02525       j = strlen(vp->name);
02526       if (j > rpt_vars[n].macro_longest)
02527          rpt_vars[n].macro_longest = j;
02528       vp = vp->next;
02529    }
02530    
02531    /* Browse for control states */
02532    if(rpt_vars[n].p.csstanzaname)
02533       vp = ast_variable_browse(cfg, rpt_vars[n].p.csstanzaname);
02534    else
02535       vp = NULL;
02536    for( i = 0 ; vp && (i < MAX_SYSSTATES) ; i++){ /* Iterate over the number of control state lines in the stanza */
02537       int k,nukw,statenum;
02538       statenum=atoi(vp->name);
02539       strncpy(s1, vp->value, 255);
02540       s1[255] = 0;
02541       nukw  = finddelim(s1,strs,32);
02542       
02543       for (k = 0 ; k < nukw ; k++){ /* for each user specified keyword */  
02544          for(j = 0 ; cs_keywords[j] != NULL ; j++){ /* try to match to one in our internal table */
02545             if(!strcmp(strs[k],cs_keywords[j])){
02546                switch(j){
02547                   case 0: /* rptena */
02548                      rpt_vars[n].p.s[statenum].txdisable = 0;
02549                      break;
02550                   case 1: /* rptdis */
02551                      rpt_vars[n].p.s[statenum].txdisable = 1;
02552                      break;
02553          
02554                   case 2: /* apena */
02555                      rpt_vars[n].p.s[statenum].autopatchdisable = 0;
02556                      break;
02557 
02558                   case 3: /* apdis */
02559                      rpt_vars[n].p.s[statenum].autopatchdisable = 1;
02560                      break;
02561 
02562                   case 4: /* lnkena */
02563                      rpt_vars[n].p.s[statenum].linkfundisable = 0;
02564                      break;
02565    
02566                   case 5: /* lnkdis */
02567                      rpt_vars[n].p.s[statenum].linkfundisable = 1;
02568                      break;
02569 
02570                   case 6: /* totena */
02571                      rpt_vars[n].p.s[statenum].totdisable = 0;
02572                      break;
02573                
02574                   case 7: /* totdis */
02575                      rpt_vars[n].p.s[statenum].totdisable = 1;
02576                      break;
02577 
02578                   case 8: /* skena */
02579                      rpt_vars[n].p.s[statenum].schedulerdisable = 0;
02580                      break;
02581 
02582                   case 9: /* skdis */
02583                      rpt_vars[n].p.s[statenum].schedulerdisable = 1;
02584                      break;
02585 
02586                   case 10: /* ufena */
02587                      rpt_vars[n].p.s[statenum].userfundisable = 0;
02588                      break;
02589 
02590                   case 11: /* ufdis */
02591                      rpt_vars[n].p.s[statenum].userfundisable = 1;
02592                      break;
02593 
02594                   case 12: /* atena */
02595                      rpt_vars[n].p.s[statenum].alternatetail = 1;
02596                      break;
02597 
02598                   case 13: /* atdis */
02599                      rpt_vars[n].p.s[statenum].alternatetail = 0;
02600                      break;
02601          
02602                   default:
02603                      ast_log(LOG_WARNING,
02604                         "Unhandled control state keyword %s", cs_keywords[i]);
02605                      break;
02606                }
02607             }
02608          }
02609       }
02610       vp = vp->next;
02611    }
02612    ast_mutex_unlock(&rpt_vars[n].lock);
02613 }

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

Definition at line 10405 of file app_rpt.c.

References rpt::archivedir, ast_canmatch_extension(), ast_exists_extension(), ast_log(), ast_matchmore_extension(), ast_pthread_create, rpt::calldigittimer, rpt::callmode, channel_revert(), 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::inpadtest, rpt::lastdtmfcommand, rpt::lock, LOG_WARNING, rpt::macropatch, 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_ALT, SOURCE_RPT, rpt::stopgen, TERM, and rpt::totalexecdcommands.

Referenced by rpt().

10406 {
10407 int   res;
10408 pthread_attr_t attr;
10409 char  cmd[MAXDTMF+1] = "",c;
10410 
10411 
10412    c = c_in & 0x7f;
10413    if (myrpt->p.archivedir)
10414    {
10415       char str[100];
10416 
10417       sprintf(str,"DTMF,MAIN,%c",c);
10418       donodelog(myrpt,str);
10419    }
10420    if (c == myrpt->p.endchar)
10421    {
10422    /* if in simple mode, kill autopatch */
10423       if (myrpt->p.simple && myrpt->callmode)
10424       {   
10425          if(debug)
10426             ast_log(LOG_WARNING, "simple mode autopatch kill\n");
10427          rpt_mutex_lock(&myrpt->lock);
10428          myrpt->callmode = 0;
10429          myrpt->macropatch=0;
10430          channel_revert(myrpt);
10431          rpt_mutex_unlock(&myrpt->lock);
10432          rpt_telemetry(myrpt,TERM,NULL);
10433          return;
10434       }
10435       rpt_mutex_lock(&myrpt->lock);
10436       myrpt->stopgen = 1;
10437       if (myrpt->cmdnode[0])
10438       {
10439          myrpt->cmdnode[0] = 0;
10440          myrpt->dtmfidx = -1;
10441          myrpt->dtmfbuf[0] = 0;
10442          rpt_mutex_unlock(&myrpt->lock);
10443          rpt_telemetry(myrpt,COMPLETE,NULL);
10444          return;
10445       } 
10446       else if(!myrpt->inpadtest)
10447                 {
10448                         rpt_mutex_unlock(&myrpt->lock);
10449                         if (myrpt->p.propagate_phonedtmf)
10450                                do_dtmf_phone(myrpt,NULL,c);
10451          return;
10452                 }
10453       else
10454          rpt_mutex_unlock(&myrpt->lock);
10455    }
10456    rpt_mutex_lock(&myrpt->lock);
10457    if (myrpt->cmdnode[0])
10458    {
10459       rpt_mutex_unlock(&myrpt->lock);
10460       send_link_dtmf(myrpt,c);
10461       return;
10462    }
10463    if (!myrpt->p.simple)
10464    {
10465       if ((!myrpt->inpadtest)&&(c == myrpt->p.funcchar))
10466       {
10467          myrpt->dtmfidx = 0;
10468          myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
10469          rpt_mutex_unlock(&myrpt->lock);
10470          time(&myrpt->dtmf_time);
10471          return;
10472       } 
10473       else if (((myrpt->inpadtest)||(c != myrpt->p.endchar)) && (myrpt->dtmfidx >= 0))
10474       {
10475          time(&myrpt->dtmf_time);
10476          
10477          if (myrpt->dtmfidx < MAXDTMF)
10478          {
10479             int src;
10480 
10481             myrpt->dtmfbuf[myrpt->dtmfidx++] = c;
10482             myrpt->dtmfbuf[myrpt->dtmfidx] = 0;
10483             
10484             strncpy(cmd, myrpt->dtmfbuf, sizeof(cmd) - 1);
10485             
10486             rpt_mutex_unlock(&myrpt->lock);
10487             src = SOURCE_RPT;
10488             if (c_in & 0x80) src = SOURCE_ALT;
10489             res = collect_function_digits(myrpt, cmd, src, NULL);
10490             rpt_mutex_lock(&myrpt->lock);
10491             switch(res){
10492                 case DC_INDETERMINATE:
10493                break;
10494                 case DC_REQ_FLUSH:
10495                myrpt->dtmfidx = 0;
10496                myrpt->dtmfbuf[0] = 0;
10497                break;
10498                 case DC_COMPLETE:
10499                 case DC_COMPLETEQUIET:
10500                myrpt->totalexecdcommands++;
10501                myrpt->dailyexecdcommands++;
10502                strncpy(myrpt->lastdtmfcommand, cmd, MAXDTMF-1);
10503                myrpt->lastdtmfcommand[MAXDTMF-1] = '\0';
10504                myrpt->dtmfbuf[0] = 0;
10505                myrpt->dtmfidx = -1;
10506                myrpt->dtmf_time = 0;
10507                break;
10508 
10509                 case DC_ERROR:
10510                 default:
10511                myrpt->dtmfbuf[0] = 0;
10512                myrpt->dtmfidx = -1;
10513                myrpt->dtmf_time = 0;
10514                break;
10515             }
10516             if(res != DC_INDETERMINATE) {
10517                rpt_mutex_unlock(&myrpt->lock);
10518                return;
10519             }
10520          } 
10521       }
10522    }
10523    else /* if simple */
10524    {
10525       if ((!myrpt->callmode) && (c == myrpt->p.funcchar))
10526       {
10527          myrpt->callmode = 1;
10528          myrpt->patchnoct = 0;
10529          myrpt->patchquiet = 0;
10530          myrpt->patchfarenddisconnect = 0;
10531          myrpt->patchdialtime = 0;
10532          strncpy(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT);
10533          myrpt->cidx = 0;
10534          myrpt->exten[myrpt->cidx] = 0;
10535          rpt_mutex_unlock(&myrpt->lock);
10536               pthread_attr_init(&attr);
10537               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
10538          ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt);
10539          return;
10540       }
10541    }
10542    if (myrpt->callmode == 1)
10543    {
10544       myrpt->exten[myrpt->cidx++] = c;
10545       myrpt->exten[myrpt->cidx] = 0;
10546       /* if this exists */
10547       if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
10548       {
10549          /* if this really it, end now */
10550          if (!ast_matchmore_extension(myrpt->pchannel,myrpt->patchcontext,
10551             myrpt->exten,1,NULL)) 
10552          {
10553             myrpt->callmode = 2;
10554             rpt_mutex_unlock(&myrpt->lock);
10555             if(!myrpt->patchquiet)
10556                rpt_telemetry(myrpt,PROC,NULL); 
10557             return;
10558          }
10559          else /* othewise, reset timer */
10560          {
10561             myrpt->calldigittimer = 1;
10562          }
10563       }
10564       /* if can continue, do so */
10565       if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL))
10566       {
10567          /* call has failed, inform user */
10568          myrpt->callmode = 4;
10569       }
10570       rpt_mutex_unlock(&myrpt->lock);
10571       return;
10572    }
10573    if ((myrpt->callmode == 2) || (myrpt->callmode == 3))
10574    {
10575       myrpt->mydtmf = c;
10576    }
10577    rpt_mutex_unlock(&myrpt->lock);
10578    if ((myrpt->dtmfidx < 0) && myrpt->p.propagate_phonedtmf)
10579       do_dtmf_phone(myrpt,NULL,c);
10580    return;
10581 }

static int manager_rpt_local_nodes ( struct mansession s,
const struct message m 
) [static]

Definition at line 14616 of file app_rpt.c.

References astman_append(), name, RESULT_SUCCESS, and s.

Referenced by load_module().

14617 {
14618     int i;
14619     astman_append(s, "<?xml version=\"1.0\"?>\r\n");
14620     astman_append(s, "<nodes>\r\n");
14621     for (i=0; i< nrpts; i++)
14622     {
14623         astman_append(s, "  <node>%s</node>\r\n", rpt_vars[i].name);        
14624     } /* for i */
14625     astman_append(s, "</nodes>\r\n");
14626     astman_append(s, "\r\n"); /* Properly terminate Manager output */
14627     return RESULT_SUCCESS;
14628 } /* manager_rpt_local_nodes() */

static int manager_rpt_status ( struct mansession s,
const struct message m 
) [static]

Definition at line 14993 of file app_rpt.c.

References ast_free, ast_malloc, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), name, rpt_manager_do_stats(), rpt_manager_success(), and s.

Referenced by load_module().

14994 {
14995    int i,res,len,idx;
14996    int uptime,hours,minutes;
14997    time_t now;
14998    const char *cmd = astman_get_header(m, "Command");
14999    char *str;
15000    enum {MGRCMD_RPTSTAT,MGRCMD_NODESTAT};
15001    struct mgrcmdtbl{
15002       const char *cmd;
15003       int index;
15004    };
15005    static struct mgrcmdtbl mct[] = {
15006       {"RptStat",MGRCMD_RPTSTAT},
15007       {"NodeStat",MGRCMD_NODESTAT},
15008       {NULL,0} /* NULL marks end of command table */
15009    };
15010 
15011    time(&now);
15012 
15013    len = 1024; /* Allocate a working buffer */
15014    if(!(str = ast_malloc(len)))
15015       return -1;
15016 
15017    /* Check for Command */
15018    if(ast_strlen_zero(cmd)){
15019       astman_send_error(s, m, "RptStatus missing command");
15020       ast_free(str);
15021       return 0;
15022    }
15023    /* Try to find the command in the table */
15024    for(i = 0 ; mct[i].cmd ; i++){
15025       if(!strcmp(mct[i].cmd, cmd))
15026          break;
15027    }
15028 
15029    if(!mct[i].cmd){ /* Found or not found ? */
15030       astman_send_error(s, m, "RptStatus unknown command");
15031       ast_free(str);
15032       return 0;
15033    }
15034    else
15035       idx = mct[i].index;
15036 
15037    switch(idx){ /* Use the index to go to the correct command */
15038 
15039       case MGRCMD_RPTSTAT:
15040          /* Return Nodes: and a comma separated list of nodes */
15041          if((res = snprintf(str, len, "Nodes: ")) > -1)
15042             len -= res;
15043          else{
15044             ast_free(str);
15045             return 0;
15046          }
15047          for(i = 0; i < nrpts; i++){
15048             if(i < nrpts - 1){
15049                if((res = snprintf(str+strlen(str), len, "%s,",rpt_vars[i].name)) < 0){
15050                   ast_free(str);
15051                   return 0;
15052                }
15053             }
15054             else{
15055                if((res = snprintf(str+strlen(str), len, "%s",rpt_vars[i].name)) < 0){
15056                   ast_free(str);
15057                   return 0;
15058                }
15059             }
15060             len -= res;
15061          }
15062 
15063          rpt_manager_success(s,m);
15064          
15065          if(!nrpts)
15066             astman_append(s, "<NONE>\r\n");
15067          else
15068             astman_append(s, "%s\r\n", str);
15069 
15070          uptime = (int)(now - starttime);
15071                         hours = uptime/3600;
15072                         uptime %= 3600;
15073                         minutes = uptime/60;
15074                         uptime %= 60;
15075 
15076                         astman_append(s, "RptUptime: %02d:%02d:%02d\r\n",
15077                                 hours, minutes, uptime);
15078 
15079          astman_append(s, "\r\n");
15080          break;      
15081 
15082       case  MGRCMD_NODESTAT:
15083          res = rpt_manager_do_stats(s,m,str);
15084          ast_free(str);
15085          return res;
15086 
15087       default:
15088          astman_send_error(s, m, "RptStatus invalid command");
15089          break;
15090    }
15091    ast_free(str);
15092    return 0;
15093 }

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

Definition at line 2056 of file app_rpt.c.

Referenced by function_autopatchup().

02057 {
02058 int   i,ls;
02059    for( i = 0 ; keywords[i] ; i++){
02060       ls = strlen(keywords[i]);
02061       if(!ls){
02062          *param = NULL;
02063          return 0;
02064       }
02065       if(!strncmp(string, keywords[i], ls)){
02066          if(param)
02067             *param = string + ls;
02068          return i + 1; 
02069       }
02070    }
02071    *param = NULL;
02072    return 0;
02073 }

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

Definition at line 1712 of file app_rpt.c.

References ast_verbose, and rpt::name.

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

01713 {
01714    if (!fromnode)
01715    {
01716       ast_verbose("Got MDC-1200 ID %04X from local system (%s)\n",
01717          unit,myrpt->name);
01718    }
01719    else
01720    {
01721       ast_verbose("Got MDC-1200 ID %04X from node %s (%s)\n",
01722          unit,fromnode,myrpt->name);
01723    }
01724 }

static int mem2vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 9085 of file app_rpt.c.

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

Referenced by set_ic706().

09086 {
09087    unsigned char cmdstr[10];
09088    
09089    cmdstr[0] = cmdstr[1] = 0xfe;
09090    cmdstr[2] = myrpt->p.civaddr;
09091    cmdstr[3] = 0xe0;
09092    cmdstr[4] = 0x0a;
09093    cmdstr[5] = 0xfd;
09094 
09095    return(civ_cmd(myrpt,cmdstr,6));
09096 }

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

Definition at line 9484 of file app_rpt.c.

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

Referenced by function_remote(), and service_scan().

09485 {
09486    if(!strcmp(myrpt->remoterig, remote_rig_ft897))
09487       return multimode_bump_freq_ft897(myrpt, interval);
09488    else if(!strcmp(myrpt->remoterig, remote_rig_ic706))
09489       return multimode_bump_freq_ic706(myrpt, interval);
09490    else
09491       return -1;
09492 }

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

Definition at line 8597 of file app_rpt.c.

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

Referenced by multimode_bump_freq().

08598 {
08599    int m,d;
08600    char mhz[MAXREMSTR], decimals[MAXREMSTR];
08601 
08602    if(debug)
08603       printf("Before bump: %s\n", myrpt->freq);
08604 
08605    if(split_freq(mhz, decimals, myrpt->freq))
08606       return -1;
08607    
08608    m = atoi(mhz);
08609    d = atoi(decimals);
08610 
08611    d += (interval / 10); /* 10Hz resolution */
08612    if(d < 0){
08613       m--;
08614       d += 100000;
08615    }
08616    else if(d >= 100000){
08617       m++;
08618       d -= 100000;
08619    }
08620 
08621    if(check_freq_ft897(m, d, NULL)){
08622       if(debug)
08623          printf("Bump freq invalid\n");
08624       return -1;
08625    }
08626 
08627    snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d);
08628 
08629    if(debug)
08630       printf("After bump: %s\n", myrpt->freq);
08631 
08632    return set_freq_ft897(myrpt, myrpt->freq);   
08633 }

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

Definition at line 9179 of file app_rpt.c.

References check_freq_ic706(), rpt::civaddr, rpt::freq, MAXREMSTR, rpt::p, rpt::remote_mars, serial_remote_io(), and split_freq().

Referenced by multimode_bump_freq().

09180 {
09181    int m,d;
09182    char mhz[MAXREMSTR], decimals[MAXREMSTR];
09183    unsigned char cmdstr[20];
09184 
09185    if(debug)
09186       printf("Before bump: %s\n", myrpt->freq);
09187 
09188    if(split_freq(mhz, decimals, myrpt->freq))
09189       return -1;
09190    
09191    m = atoi(mhz);
09192    d = atoi(decimals);
09193 
09194    d += (interval / 10); /* 10Hz resolution */
09195    if(d < 0){
09196       m--;
09197       d += 100000;
09198    }
09199    else if(d >= 100000){
09200       m++;
09201       d -= 100000;
09202    }
09203 
09204    if(check_freq_ic706(m, d, NULL,myrpt->p.remote_mars)){
09205       if(debug)
09206          printf("Bump freq invalid\n");
09207       return -1;
09208    }
09209 
09210    snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d);
09211 
09212    if(debug)
09213       printf("After bump: %s\n", myrpt->freq);
09214 
09215    /* The ic-706 likes packed BCD frequencies */
09216 
09217    cmdstr[0] = cmdstr[1] = 0xfe;
09218    cmdstr[2] = myrpt->p.civaddr;
09219    cmdstr[3] = 0xe0;
09220    cmdstr[4] = 0;
09221    cmdstr[5] = ((d % 10) << 4);
09222    cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10);
09223    cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000);
09224    cmdstr[8] = (((m % 100)/10) << 4) + (m % 10);
09225    cmdstr[9] = (m / 100);
09226    cmdstr[10] = 0xfd;
09227 
09228    return(serial_remote_io(myrpt,cmdstr,11,NULL,0,0));
09229 }

static int multimode_capable ( struct rpt myrpt  )  [static]

Definition at line 1077 of file app_rpt.c.

References rpt::remoterig.

Referenced by function_remote(), and rpt_tele_thread().

01078 {
01079    if(!strcmp(myrpt->remoterig, remote_rig_ft897))
01080       return 1;
01081    if(!strcmp(myrpt->remoterig, remote_rig_ic706))
01082       return 1;
01083    return 0;
01084 }  

static int myatoi ( char *  str  )  [static]

Definition at line 2098 of file app_rpt.c.

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

02099 {
02100 int   ret;
02101 
02102    if (str == NULL) return -1;
02103    /* leave this %i alone, non-base-10 input is useful here */
02104    if (sscanf(str,"%i",&ret) != 1) return -1;
02105    return ret;
02106 }

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

Definition at line 2108 of file app_rpt.c.

Referenced by rpt_do_nodes(), and rpt_tele_thread().

02109 {
02110 char  **x = (char **) a;
02111 char  **y = (char **) b;
02112 int   xoff,yoff;
02113 
02114    if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0;
02115    if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0;
02116    return(strcmp((*x) + xoff,(*y) + yoff));
02117 }

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

Definition at line 1984 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, config_flags, 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(), function_ilink(), and rpt_exec().

01985 {
01986 
01987 char *val;
01988 int longestnode,j;
01989 struct stat mystat;
01990 static time_t last = 0;
01991 static struct ast_config *ourcfg = NULL;
01992 struct ast_variable *vp;
01993 
01994    /* try to look it up locally first */
01995    val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf);
01996    if (val) return(val);
01997    ast_mutex_lock(&nodelookuplock);
01998    /* if file does not exist */
01999    if (stat(myrpt->p.extnodefile,&mystat) == -1)
02000    {
02001       if (ourcfg) ast_config_destroy(ourcfg);
02002       ourcfg = NULL;
02003       ast_mutex_unlock(&nodelookuplock);
02004       return(NULL);
02005    }
02006    /* if we need to reload */
02007    if (mystat.st_mtime > last)
02008    {
02009       if (ourcfg) ast_config_destroy(ourcfg);
02010 #ifdef   NEW_ASTERISK
02011       ourcfg = ast_config_load(myrpt->p.extnodefile,config_flags);
02012 #else
02013       ourcfg = ast_config_load(myrpt->p.extnodefile);
02014 #endif
02015       /* if file not there, just bail */
02016       if (!ourcfg)
02017       {
02018          ast_mutex_unlock(&nodelookuplock);
02019          return(NULL);
02020       }
02021       /* reset "last" time */
02022       last = mystat.st_mtime;
02023 
02024       /* determine longest node length again */    
02025       longestnode = 0;
02026       vp = ast_variable_browse(myrpt->cfg, myrpt->p.nodes);
02027       while(vp){
02028          j = strlen(vp->name);
02029          if (j > longestnode)
02030             longestnode = j;
02031          vp = vp->next;
02032       }
02033 
02034       vp = ast_variable_browse(ourcfg, myrpt->p.extnodes);
02035       while(vp){
02036          j = strlen(vp->name);
02037          if (j > longestnode)
02038             longestnode = j;
02039          vp = vp->next;
02040       }
02041 
02042       myrpt->longestnode = longestnode;
02043    }
02044    val = NULL;
02045    if (ourcfg)
02046       val = (char *) ast_variable_retrieve(ourcfg, myrpt->p.extnodes, digitbuf);
02047    ast_mutex_unlock(&nodelookuplock);
02048    return(val);
02049 }

static int openserial ( struct rpt myrpt,
char *  fname 
) [static]

Definition at line 1674 of file app_rpt.c.

References ast_log(), ECHO, errno, LOG_NOTICE, LOG_WARNING, rpt::remoterig, and setdtr().

Referenced by rpt().

01675 {
01676    struct termios mode;
01677    int fd;
01678 
01679    fd = open(fname,O_RDWR);
01680    if (fd == -1)
01681    {
01682       ast_log(LOG_WARNING,"Cannot open serial port %s\n",fname);
01683       return -1;
01684    }
01685    memset(&mode, 0, sizeof(mode));
01686    if (tcgetattr(fd, &mode)) {
01687       ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", fname, strerror(errno));
01688       return -1;
01689    }
01690 #ifndef  SOLARIS
01691    cfmakeraw(&mode);
01692 #else
01693         mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
01694                         |INLCR|IGNCR|ICRNL|IXON);
01695         mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
01696         mode.c_cflag &= ~(CSIZE|PARENB|CRTSCTS);
01697         mode.c_cflag |= CS8;
01698    mode.c_cc[VTIME] = 3;
01699    mode.c_cc[VMIN] = 1; 
01700 #endif
01701 
01702    cfsetispeed(&mode, B9600);
01703    cfsetospeed(&mode, B9600);
01704    if (tcsetattr(fd, TCSANOW, &mode)) 
01705       ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", fname, strerror(errno));
01706    if(!strcmp(myrpt->remoterig, remote_rig_kenwood)) setdtr(fd,0); 
01707    usleep(100000);
01708    if (debug)ast_log(LOG_NOTICE,"Opened serial port %s\n",fname);
01709    return(fd); 
01710 }

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

Definition at line 3267 of file app_rpt.c.

References chan, and play_tone_pair().

Referenced by send_morse().

03268 {
03269    return play_tone_pair(chan, 0, 0, duration, 0);
03270 }

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

Definition at line 3262 of file app_rpt.c.

References chan, and play_tone_pair().

Referenced by rpt_tele_thread(), and send_morse().

03263 {
03264    return play_tone_pair(chan, freq, 0, duration, amplitude);
03265 }

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

Definition at line 3248 of file app_rpt.c.

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

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

03249 {
03250    int res;
03251 
03252         if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude)))
03253                 return res;
03254                                                                                                                                             
03255         while(chan->generatordata) {
03256       if (ast_safe_sleep(chan,1)) return -1;
03257    }
03258 
03259         return 0;
03260 }

static int priority_jump ( struct rpt myrpt,
struct ast_channel chan 
) [static]

Definition at line 1365 of file app_rpt.c.

References ast_goto_if_exists(), chan, ast_channel::context, ast_channel::exten, and ast_channel::priority.

Referenced by rpt_exec().

01366 {
01367    int res=0;
01368 
01369    // if (ast_test_flag(&flags,OPT_JUMP) && ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101) == 0){
01370    if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101) == 0){
01371       res = 0;
01372    } else {
01373       res = -1;
01374    }
01375    return res;
01376 }

static void queue_id ( struct rpt myrpt  )  [static]

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

10587 {
10588    if(myrpt->p.idtime){ /* ID time must be non-zero */
10589       myrpt->mustid = myrpt->tailid = 0;
10590       myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */
10591       rpt_mutex_unlock(&myrpt->lock);
10592       rpt_telemetry(myrpt,ID,NULL);
10593       rpt_mutex_lock(&myrpt->lock);
10594    }
10595 }

static int rbi_mhztoband ( char *  str  )  [static]

Definition at line 7228 of file app_rpt.c.

Referenced by setrbi(), setrbi_check(), setrtx(), and setrtx_check().

07229 {
07230 int   i;
07231 
07232    i = atoi(str) / 10; /* get the 10's of mhz */
07233    switch(i)
07234    {
07235        case 2:
07236       return 10;
07237        case 5:
07238       return 11;
07239        case 14:
07240       return 2;
07241        case 22:
07242       return 3;
07243        case 44:
07244       return 4;
07245        case 124:
07246       return 0;
07247        case 125:
07248       return 1;
07249        case 126:
07250       return 8;
07251        case 127:
07252       return 5;
07253        case 128:
07254       return 6;
07255        case 129:
07256       return 7;
07257        default:
07258       break;
07259    }
07260    return -1;
07261 }

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

Definition at line 7387 of file app_rpt.c.

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

Referenced by setrbi().

07388 {
07389 struct dahdi_radio_param r;
07390 
07391    memset(&r,0,sizeof(struct dahdi_radio_param));
07392    r.radpar = DAHDI_RADPAR_REMMODE;
07393    r.data = DAHDI_RADPAR_REM_RBI1;
07394    /* if setparam ioctl fails, its probably not a pciradio card */
07395    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_SETPARAM,&r) == -1)
07396    {
07397       rbi_out_parallel(myrpt,data);
07398       return;
07399    }
07400    r.radpar = DAHDI_RADPAR_REMCOMMAND;
07401    memcpy(&r.data,data,5);
07402    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_SETPARAM,&r) == -1)
07403    {
07404       ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->dahdirxchannel->name);
07405       return;
07406    }
07407 }

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

Definition at line 7359 of file app_rpt.c.

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

Referenced by rbi_out().

07360     {
07361 #ifdef __i386__
07362     int i,j;
07363     unsigned char od,d;
07364     static volatile long long delayvar;
07365 
07366     for(i = 0 ; i < 5 ; i++){
07367         od = *data++; 
07368         for(j = 0 ; j < 8 ; j++){
07369             d = od & 1;
07370             outb(d,myrpt->p.iobase);
07371        /* >= 15 us */
07372        for(delayvar = 1; delayvar < 15000; delayvar++); 
07373             od >>= 1;
07374             outb(d | 2,myrpt->p.iobase);
07375        /* >= 30 us */
07376        for(delayvar = 1; delayvar < 30000; delayvar++); 
07377             outb(d,myrpt->p.iobase);
07378        /* >= 10 us */
07379        for(delayvar = 1; delayvar < 10000; delayvar++); 
07380             }
07381         }
07382    /* >= 50 us */
07383         for(delayvar = 1; delayvar < 50000; delayvar++); 
07384 #endif
07385     }

static int rbi_pltocode ( char *  str  )  [static]

Definition at line 7264 of file app_rpt.c.

References s.

Referenced by setrbi(), setrbi_check(), setrtx(), and setrtx_check().

07265 {
07266 int i;
07267 char *s;
07268 
07269    s = strchr(str,'.');
07270    i = 0;
07271    if (s) i = atoi(s + 1);
07272    i += atoi(str) * 10;
07273    switch(i)
07274    {
07275        case 670:
07276       return 0;
07277        case 719:
07278       return 1;
07279        case 744:
07280       return 2;
07281        case 770:
07282       return 3;
07283        case 797:
07284       return 4;
07285        case 825:
07286       return 5;
07287        case 854:
07288       return 6;
07289        case 885:
07290       return 7;
07291        case 915:
07292       return 8;
07293        case 948:
07294       return 9;
07295        case 974:
07296       return 10;
07297        case 1000:
07298       return 11;
07299        case 1035:
07300       return 12;
07301        case 1072:
07302       return 13;
07303        case 1109:
07304       return 14;
07305        case 1148:
07306       return 15;
07307        case 1188:
07308       return 16;
07309        case 1230:
07310       return 17;
07311        case 1273:
07312       return 18;
07313        case 1318:
07314       return 19;
07315        case 1365:
07316       return 20;
07317        case 1413:
07318       return 21;
07319        case 1462:
07320       return 22;
07321        case 1514:
07322       return 23;
07323        case 1567:
07324       return 24;
07325        case 1622:
07326       return 25;
07327        case 1679:
07328       return 26;
07329        case 1738:
07330       return 27;
07331        case 1799:
07332       return 28;
07333        case 1862:
07334       return 29;
07335        case 1928:
07336       return 30;
07337        case 2035:
07338       return 31;
07339        case 2107:
07340       return 32;
07341        case 2181:
07342       return 33;
07343        case 2257:
07344       return 34;
07345        case 2336:
07346       return 35;
07347        case 2418:
07348       return 36;
07349        case 2503:
07350       return 37;
07351    }
07352    return -1;
07353 }

static int reload ( void   )  [static]

Definition at line 15196 of file app_rpt.c.

References reload.

15198 {
15199 int   n;
15200 
15201    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
15202    return(0);
15203 }

static char* res2cli ( int  r  )  [static]

Definition at line 3274 of file app_rpt.c.

References CLI_FAILURE, CLI_SHOWUSAGE, CLI_SUCCESS, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

03276 {
03277    switch (r)
03278    {
03279        case RESULT_SUCCESS:
03280       return(CLI_SUCCESS);
03281        case RESULT_SHOWUSAGE:
03282       return(CLI_SHOWUSAGE);
03283        default:
03284       return(CLI_FAILURE);
03285    }
03286 }

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

Definition at line 1412 of file app_rpt.c.

References ast_log(), ast_variable_retrieve(), rpt::cfg, rpt::freq, LOG_NOTICE, 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_cop(), get_mem_set(), and rpt_master().

01413 {
01414    char tmp[30], *s, *s1, *val;
01415 
01416    if (debug)ast_log(LOG_NOTICE, "memory=%s block=%s\n",memory,myrpt->p.memory);
01417 
01418    val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.memory, memory);
01419    if (!val){
01420       return -1;
01421    }        
01422    strncpy(tmp,val,sizeof(tmp) - 1);
01423    tmp[sizeof(tmp)-1] = 0;
01424 
01425    s = strchr(tmp,',');
01426    if (!s)
01427       return 1; 
01428    *s++ = 0;
01429    s1 = strchr(s,',');
01430    if (!s1)
01431       return 1;
01432    *s1++ = 0;
01433    strncpy(myrpt->freq, tmp, sizeof(myrpt->freq) - 1);
01434    strncpy(myrpt->rxpl, s, sizeof(myrpt->rxpl) - 1);
01435    strncpy(myrpt->txpl, s, sizeof(myrpt->rxpl) - 1);
01436    myrpt->remmode = REM_MODE_FM;
01437    myrpt->offset = REM_SIMPLEX;
01438    myrpt->powerlevel = REM_MEDPWR;
01439    myrpt->txplon = myrpt->rxplon = 0;
01440    while(*s1){
01441       switch(*s1++){
01442          case 'A':
01443          case 'a':
01444             strcpy(myrpt->rxpl, "100.0");
01445             strcpy(myrpt->txpl, "100.0");
01446             myrpt->remmode = REM_MODE_AM; 
01447             break;
01448          case 'B':
01449          case 'b':
01450             strcpy(myrpt->rxpl, "100.0");
01451             strcpy(myrpt->txpl, "100.0");
01452             myrpt->remmode = REM_MODE_LSB;
01453             break;
01454          case 'F':
01455             myrpt->remmode = REM_MODE_FM;
01456             break;
01457          case 'L':
01458          case 'l':
01459             myrpt->powerlevel = REM_LOWPWR;
01460             break;               
01461          case 'H':
01462          case 'h':
01463             myrpt->powerlevel = REM_HIPWR;
01464             break;
01465                
01466          case 'M':
01467          case 'm':
01468             myrpt->powerlevel = REM_MEDPWR;
01469             break;
01470                   
01471          case '-':
01472             myrpt->offset = REM_MINUS;
01473             break;
01474                   
01475          case '+':
01476             myrpt->offset = REM_PLUS;
01477             break;
01478                   
01479          case 'S':
01480          case 's':
01481             myrpt->offset = REM_SIMPLEX;
01482             break;
01483                   
01484          case 'T':
01485          case 't':
01486             myrpt->txplon = 1;
01487             break;
01488                   
01489          case 'R':
01490          case 'r':
01491             myrpt->rxplon = 1;
01492             break;
01493 
01494          case 'U':
01495          case 'u':
01496             strcpy(myrpt->rxpl, "100.0");
01497             strcpy(myrpt->txpl, "100.0");
01498             myrpt->remmode = REM_MODE_USB;
01499             break;
01500          default:
01501             return 1;
01502       }
01503    }
01504    return 0;
01505 }

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

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

02195 {
02196         char *var;
02197         int ret;
02198    char include_zero = 0;
02199 
02200    if(min < 0){ /* If min is negative, this means include 0 as a valid entry */
02201       min = -min;
02202       include_zero = 1;
02203    }           
02204                                                                      
02205         var = (char *) ast_variable_retrieve(myrpt->cfg, category, name);
02206         if(var){
02207                 ret = myatoi(var);
02208       if(include_zero && !ret)
02209          return 0;
02210                 if(ret < min)
02211                         ret = min;
02212                 if(ret > max)
02213                         ret = max;
02214         }
02215         else
02216                 ret = defl;
02217         return ret;
02218 }

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

Definition at line 10725 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_free, ast_frfree, ast_hangup(), ast_indicate(), AST_LIST_EMPTY, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_log(), ast_malloc, 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_tvdiff_ms(), ast_tvnow(), 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, channel_revert(), CMD_STATE_EXECUTING, CMD_STATE_IDLE, CMD_STATE_READY, rpt::cmdAction, rpt::cmdnode, rpt_cmd_struct::command_source, rpt::conf, CONNECTED, rpt_link::connected, rpt_link::connecttime, CONNFAIL, rpt::dahdirxchannel, rpt::dahditxchannel, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, ast_frame::data, ast_channel::data, ast_frame::datalen, rpt_cmd_struct::digits, DISC_TIME, rpt_link::disced, rpt_link::disctime, rpt::disgorgetime, diskavail(), do_dtmf_local(), do_scheduler(), donodelog(), dovox(), 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, ast_frame::frame_list, func_xlat(), function_table_tag::function, function_table, rpt_cmd_struct::functionNumber, handle_link_data(), handle_link_phone_dtmf(), rpt::hangtime, rpt_link::hasconnected, ID, IDTALKOVER, rpt::idtime, rpt::idtimer, rpt::inpadtest, rpt::inxlat, rpt::iobase, rpt::iofd, rpt::ioport, rpt_link::isremote, ISRIG_RTX, rpt::keyed, KEYPOSTSHORTTIME, KEYPOSTTIME, rpt::keyposttimer, rpt_link::killme, rpt::lastdtmfcommand, rpt_link::lastf1, rpt::lastf1, rpt_link::lastf2, rpt::lastf2, rpt::lastkeyedtime, rpt_link::lastlinktv, rpt::lastnodewhichkeyedusup, rpt_link::lastrealrx, rpt_link::lastrx, rpt_link::lastrx1, rpt::lasttone, rpt_link::lasttx, rpt_link::lasttx1, rpt::lasttxkeyedtime, LINKLISTTIME, rpt_link::linklisttimer, LINKPOSTTIME, rpt::linkposttimer, rpt::links, rpt::linktolink, LINKUNKEY, load_rpt_vars(), local_dtmf_helper(), rpt::localtx, rpt::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, rpt::macrobuf, rpt::macropatch, 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::newkey, rpt_link::next, rpt_tele::next, rpt::notelemtx, openserial(), option_verbose, rpt_link::outbound, rpt::p, rpt_cmd_struct::param, PARROT, rpt::parrotchannel, rpt::parrotcnt, PARROTFILE, rpt::parrotmode, rpt::parrotstate, rpt::parrotstream, rpt::parrottime, rpt::parrottimer, rpt_link::pchan, rpt::pchannel, rpt_link::phonemode, rpt_link::phonevox, rpt::politeid, rpt_link::prev, ast_frame::ptr, queue_id(), rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, REMDISC, rpt::remoterig, rpt_link::rerxtimer, rpt::rerxtimer, rpt_link::retries, RETRY_TIMER_MS, rpt_link::retrytimer, rpt_link::retxtimer, rpt::retxtimer, RPT_LOCKOUT_SECS, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::rpt_thread, rpt::rxchanname, rpt::rxchannel, rpt_link::rxq, s, rpt::s, rpt::scram, send_newkey(), setrem(), rpt::simplexpatchdelay, rpt::simplexphonedelay, rpt::skedtimer, START_DELAY, rpt::startupmacro, rpt_cmd_struct::state, statpost(), STATS_TIME_LOCAL, status, rpt::sysstate_cur, rpt::tailevent, rpt::tailid, rpt::tailmessages, rpt::tailmessagetime, TAILMSG, rpt::tailtimer, rpt::tele, rpt_link::thisconnected, TIMEOUT, rpt::timeouts, rpt::tmsgtimer, rpt::tonemacro, rpt::tonotify, topcompar(), TOPKEY, rpt::topkey, TOPKEYN, rpt::topkeystate, rpt::topkeytime, TOPKEYWAIT, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, rpt::totime, rpt::totimer, rpt::tounkeyed, rpt::txchanname, rpt::txchannel, rpt::txconf, sysstate::txdisable, rpt::txkeyed, rpt::txpchannel, rpt::txq, rpt::txrealkeyed, UNKEY, VERBOSE_PREFIX_3, rpt::vox, rpt_link::vox, rpt::voxchannel, voxinit_link(), voxinit_rpt(), rpt::voxrecover_ms, rpt::voxtimeout_ms, rpt_link::voxtostate, rpt::voxtostate, rpt_link::voxtotimer, rpt::voxtotimer, rpt_link::wasvox, rpt::wasvox, ast_channel::whentohangup, and rpt::xlink.

10726 {
10727 struct   rpt *myrpt = (struct rpt *)this;
10728 char *tele,*idtalkover,c,myfirst,*p;
10729 int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,othertelemqueued;
10730 int tailmessagequeued,ctqueued,dtmfed,lastmyrx,localmsgqueued;
10731 struct ast_channel *who;
10732 struct dahdi_confinfo ci;  /* conference info */
10733 time_t   t;
10734 struct rpt_link *l,*m;
10735 struct rpt_tele *telem;
10736 char tmpstr[300],lstr[MAXLINKLIST];
10737 
10738 
10739    if (myrpt->p.archivedir) mkdir(myrpt->p.archivedir,0600);
10740    sprintf(tmpstr,"%s/%s",myrpt->p.archivedir,myrpt->name);
10741    mkdir(tmpstr,0600);
10742    rpt_mutex_lock(&myrpt->lock);
10743 
10744    telem = myrpt->tele.next;
10745    while(telem != &myrpt->tele)
10746    {
10747       ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV);
10748       telem = telem->next;
10749    }
10750    rpt_mutex_unlock(&myrpt->lock);
10751    /* find our index, and load the vars initially */
10752    for(i = 0; i < nrpts; i++)
10753    {
10754       if (&rpt_vars[i] == myrpt)
10755       {
10756          load_rpt_vars(i,0);
10757          break;
10758       }
10759    }
10760 
10761    rpt_mutex_lock(&myrpt->lock);
10762    while(myrpt->xlink)
10763    {
10764       myrpt->xlink = 3;
10765       rpt_mutex_unlock(&myrpt->lock);
10766       usleep(100000);
10767       rpt_mutex_lock(&myrpt->lock);
10768    }
10769 #ifdef HAVE_IOPERM
10770    if ((!strcmp(myrpt->remoterig, remote_rig_rbi)) &&
10771      (ioperm(myrpt->p.iobase,1,1) == -1))
10772    {
10773       rpt_mutex_unlock(&myrpt->lock);
10774       ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase);
10775       myrpt->rpt_thread = AST_PTHREADT_STOP;
10776       pthread_exit(NULL);
10777    }
10778 #endif
10779    strncpy(tmpstr,myrpt->rxchanname,sizeof(tmpstr) - 1);
10780    tele = strchr(tmpstr,'/');
10781    if (!tele)
10782    {
10783       fprintf(stderr,"rpt:Rxchannel Dial number (%s) must be in format tech/number\n",myrpt->rxchanname);
10784       rpt_mutex_unlock(&myrpt->lock);
10785       myrpt->rpt_thread = AST_PTHREADT_STOP;
10786       pthread_exit(NULL);
10787    }
10788    *tele++ = 0;
10789    myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL);
10790    myrpt->dahdirxchannel = NULL;
10791    if (!strcasecmp(tmpstr,"DAHDI"))
10792       myrpt->dahdirxchannel = myrpt->rxchannel;
10793    if (myrpt->rxchannel)
10794    {
10795       if (myrpt->rxchannel->_state == AST_STATE_BUSY)
10796       {
10797          fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
10798          rpt_mutex_unlock(&myrpt->lock);
10799          ast_hangup(myrpt->rxchannel);
10800          myrpt->rpt_thread = AST_PTHREADT_STOP;
10801          pthread_exit(NULL);
10802       }
10803       ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
10804       ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
10805 #ifdef   AST_CDR_FLAG_POST_DISABLED
10806       if (myrpt->rxchannel->cdr)
10807          ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
10808 #endif
10809 #ifndef  NEW_ASTERISK
10810       myrpt->rxchannel->whentohangup = 0;
10811 #endif
10812       myrpt->rxchannel->appl = "Apprpt";
10813       myrpt->rxchannel->data = "(Repeater Rx)";
10814       if (option_verbose > 2)
10815          ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
10816             tmpstr,tele,myrpt->rxchannel->name);
10817       ast_call(myrpt->rxchannel,tele,999);
10818       if (myrpt->rxchannel->_state != AST_STATE_UP)
10819       {
10820          rpt_mutex_unlock(&myrpt->lock);
10821          ast_hangup(myrpt->rxchannel);
10822          myrpt->rpt_thread = AST_PTHREADT_STOP;
10823          pthread_exit(NULL);
10824       }
10825    }
10826    else
10827    {
10828       fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
10829       rpt_mutex_unlock(&myrpt->lock);
10830       myrpt->rpt_thread = AST_PTHREADT_STOP;
10831       pthread_exit(NULL);
10832    }
10833    myrpt->dahditxchannel = NULL;
10834    if (myrpt->txchanname)
10835    {
10836       strncpy(tmpstr,myrpt->txchanname,sizeof(tmpstr) - 1);
10837       tele = strchr(tmpstr,'/');
10838       if (!tele)
10839       {
10840          fprintf(stderr,"rpt:Txchannel Dial number (%s) must be in format tech/number\n",myrpt->txchanname);
10841          rpt_mutex_unlock(&myrpt->lock);
10842          ast_hangup(myrpt->rxchannel);
10843          myrpt->rpt_thread = AST_PTHREADT_STOP;
10844          pthread_exit(NULL);
10845       }
10846       *tele++ = 0;
10847       myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL);
10848       if (!strcasecmp(tmpstr,"DAHDI"))
10849          myrpt->dahditxchannel = myrpt->txchannel;
10850       if (myrpt->txchannel)
10851       {
10852          if (myrpt->txchannel->_state == AST_STATE_BUSY)
10853          {
10854             fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
10855             rpt_mutex_unlock(&myrpt->lock);
10856             ast_hangup(myrpt->txchannel);
10857             ast_hangup(myrpt->rxchannel);
10858             myrpt->rpt_thread = AST_PTHREADT_STOP;
10859             pthread_exit(NULL);
10860          }        
10861          ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
10862          ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
10863 #ifdef   AST_CDR_FLAG_POST_DISABLED
10864          if (myrpt->txchannel->cdr)
10865             ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
10866 #endif
10867 #ifndef  NEW_ASTERISK
10868          myrpt->txchannel->whentohangup = 0;
10869 #endif
10870          myrpt->txchannel->appl = "Apprpt";
10871          myrpt->txchannel->data = "(Repeater Tx)";
10872          if (option_verbose > 2)
10873             ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
10874                tmpstr,tele,myrpt->txchannel->name);
10875          ast_call(myrpt->txchannel,tele,999);
10876          if (myrpt->rxchannel->_state != AST_STATE_UP)
10877          {
10878             rpt_mutex_unlock(&myrpt->lock);
10879             ast_hangup(myrpt->rxchannel);
10880             ast_hangup(myrpt->txchannel);
10881             myrpt->rpt_thread = AST_PTHREADT_STOP;
10882             pthread_exit(NULL);
10883          }
10884       }
10885       else
10886       {
10887          fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
10888          rpt_mutex_unlock(&myrpt->lock);
10889          ast_hangup(myrpt->rxchannel);
10890          myrpt->rpt_thread = AST_PTHREADT_STOP;
10891          pthread_exit(NULL);
10892       }
10893    }
10894    else
10895    {
10896       myrpt->txchannel = myrpt->rxchannel;
10897       if (!strncasecmp(myrpt->rxchanname,"DAHDI",3))
10898          myrpt->dahditxchannel = myrpt->txchannel;
10899    }
10900    ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
10901    ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
10902    /* allocate a pseudo-channel thru asterisk */
10903    myrpt->pchannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
10904    if (!myrpt->pchannel)
10905    {
10906       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
10907       rpt_mutex_unlock(&myrpt->lock);
10908       if (myrpt->txchannel != myrpt->rxchannel) 
10909          ast_hangup(myrpt->txchannel);
10910       ast_hangup(myrpt->rxchannel);
10911       myrpt->rpt_thread = AST_PTHREADT_STOP;
10912       pthread_exit(NULL);
10913    }
10914 #ifdef   AST_CDR_FLAG_POST_DISABLED
10915    if (myrpt->pchannel->cdr)
10916       ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
10917 #endif
10918    if (!myrpt->dahdirxchannel) myrpt->dahdirxchannel = myrpt->pchannel;
10919    if (!myrpt->dahditxchannel)
10920    {
10921       /* allocate a pseudo-channel thru asterisk */
10922       myrpt->dahditxchannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
10923       if (!myrpt->dahditxchannel)
10924       {
10925          fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
10926          rpt_mutex_unlock(&myrpt->lock);
10927          if (myrpt->txchannel != myrpt->rxchannel) 
10928             ast_hangup(myrpt->txchannel);
10929          ast_hangup(myrpt->rxchannel);
10930          myrpt->rpt_thread = AST_PTHREADT_STOP;
10931          pthread_exit(NULL);
10932       }
10933       ast_set_read_format(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
10934       ast_set_write_format(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
10935 #ifdef   AST_CDR_FLAG_POST_DISABLED
10936       if (myrpt->dahditxchannel->cdr)
10937          ast_set_flag(myrpt->dahditxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
10938 #endif
10939    }
10940    /* allocate a pseudo-channel thru asterisk */
10941    myrpt->monchannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
10942    if (!myrpt->monchannel)
10943    {
10944       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
10945       rpt_mutex_unlock(&myrpt->lock);
10946       if (myrpt->txchannel != myrpt->rxchannel) 
10947          ast_hangup(myrpt->txchannel);
10948       ast_hangup(myrpt->rxchannel);
10949       myrpt->rpt_thread = AST_PTHREADT_STOP;
10950       pthread_exit(NULL);
10951    }
10952    ast_set_read_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
10953    ast_set_write_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
10954 #ifdef   AST_CDR_FLAG_POST_DISABLED
10955    if (myrpt->monchannel->cdr)
10956       ast_set_flag(myrpt->monchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
10957 #endif
10958    /* make a conference for the tx */
10959    ci.chan = 0;
10960    ci.confno = -1; /* make a new conf */
10961    ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_LISTENER;
10962    /* first put the channel on the conference in proper mode */
10963    if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
10964    {
10965       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
10966       rpt_mutex_unlock(&myrpt->lock);
10967       ast_hangup(myrpt->pchannel);
10968       ast_hangup(myrpt->monchannel);
10969       if (myrpt->txchannel != myrpt->rxchannel) 
10970          ast_hangup(myrpt->txchannel);
10971       ast_hangup(myrpt->rxchannel);
10972       myrpt->rpt_thread = AST_PTHREADT_STOP;
10973       pthread_exit(NULL);
10974    }
10975    /* save tx conference number */
10976    myrpt->txconf = ci.confno;
10977    /* make a conference for the pseudo */
10978    ci.chan = 0;
10979    ci.confno = -1; /* make a new conf */
10980    ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? DAHDI_CONF_CONFANNMON :
10981       (DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER);
10982    /* first put the channel on the conference in announce mode */
10983    if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
10984    {
10985       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
10986       rpt_mutex_unlock(&myrpt->lock);
10987       ast_hangup(myrpt->pchannel);
10988       ast_hangup(myrpt->monchannel);
10989       if (myrpt->txchannel != myrpt->rxchannel) 
10990          ast_hangup(myrpt->txchannel);
10991       ast_hangup(myrpt->rxchannel);
10992       myrpt->rpt_thread = AST_PTHREADT_STOP;
10993       pthread_exit(NULL);
10994    }
10995    /* save pseudo channel conference number */
10996    myrpt->conf = ci.confno;
10997    /* make a conference for the pseudo */
10998    ci.chan = 0;
10999    if ((strstr(myrpt->txchannel->name,"pseudo") == NULL) &&
11000       (myrpt->dahditxchannel == myrpt->txchannel))
11001    {
11002       /* get tx channel's port number */
11003       if (ioctl(myrpt->txchannel->fds[0],DAHDI_CHANNO,&ci.confno) == -1)
11004       {
11005          ast_log(LOG_WARNING, "Unable to set tx channel's chan number\n");
11006          rpt_mutex_unlock(&myrpt->lock);
11007          ast_hangup(myrpt->pchannel);
11008          ast_hangup(myrpt->monchannel);
11009          if (myrpt->txchannel != myrpt->rxchannel) 
11010             ast_hangup(myrpt->txchannel);
11011          ast_hangup(myrpt->rxchannel);
11012          myrpt->rpt_thread = AST_PTHREADT_STOP;
11013          pthread_exit(NULL);
11014       }
11015       ci.confmode = DAHDI_CONF_MONITORTX;
11016    }
11017    else
11018    {
11019       ci.confno = myrpt->txconf;
11020       ci.confmode = DAHDI_CONF_CONFANNMON;
11021    }
11022    /* first put the channel on the conference in announce mode */
11023    if (ioctl(myrpt->monchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
11024    {
11025       ast_log(LOG_WARNING, "Unable to set conference mode for monitor\n");
11026       rpt_mutex_unlock(&myrpt->lock);
11027       ast_hangup(myrpt->pchannel);
11028       ast_hangup(myrpt->monchannel);
11029       if (myrpt->txchannel != myrpt->rxchannel) 
11030          ast_hangup(myrpt->txchannel);
11031       ast_hangup(myrpt->rxchannel);
11032       myrpt->rpt_thread = AST_PTHREADT_STOP;
11033       pthread_exit(NULL);
11034    }
11035    /* allocate a pseudo-channel thru asterisk */
11036    myrpt->parrotchannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
11037    if (!myrpt->parrotchannel)
11038    {
11039       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
11040       rpt_mutex_unlock(&myrpt->lock);
11041       if (myrpt->txchannel != myrpt->rxchannel) 
11042          ast_hangup(myrpt->txchannel);
11043       ast_hangup(myrpt->rxchannel);
11044       myrpt->rpt_thread = AST_PTHREADT_STOP;
11045       pthread_exit(NULL);
11046    }
11047    ast_set_read_format(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
11048    ast_set_write_format(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
11049 #ifdef   AST_CDR_FLAG_POST_DISABLED
11050    if (myrpt->parrotchannel->cdr)
11051       ast_set_flag(myrpt->parrotchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
11052 #endif
11053    /* allocate a pseudo-channel thru asterisk */
11054    myrpt->voxchannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
11055    if (!myrpt->voxchannel)
11056    {
11057       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
11058       rpt_mutex_unlock(&myrpt->lock);
11059       if (myrpt->txchannel != myrpt->rxchannel) 
11060          ast_hangup(myrpt->txchannel);
11061       ast_hangup(myrpt->rxchannel);
11062       myrpt->rpt_thread = AST_PTHREADT_STOP;
11063       pthread_exit(NULL);
11064    }
11065    ast_set_read_format(myrpt->voxchannel,AST_FORMAT_SLINEAR);
11066    ast_set_write_format(myrpt->voxchannel,AST_FORMAT_SLINEAR);
11067 #ifdef   AST_CDR_FLAG_POST_DISABLED
11068    if (myrpt->voxchannel->cdr)
11069       ast_set_flag(myrpt->voxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
11070 #endif
11071    /* allocate a pseudo-channel thru asterisk */
11072    myrpt->txpchannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
11073    if (!myrpt->txpchannel)
11074    {
11075       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
11076       rpt_mutex_unlock(&myrpt->lock);
11077       ast_hangup(myrpt->pchannel);
11078       ast_hangup(myrpt->monchannel);
11079       if (myrpt->txchannel != myrpt->rxchannel) 
11080          ast_hangup(myrpt->txchannel);
11081       ast_hangup(myrpt->rxchannel);
11082       myrpt->rpt_thread = AST_PTHREADT_STOP;
11083       pthread_exit(NULL);
11084    }
11085 #ifdef   AST_CDR_FLAG_POST_DISABLED
11086    if (myrpt->txpchannel->cdr)
11087       ast_set_flag(myrpt->txpchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
11088 #endif
11089    /* make a conference for the tx */
11090    ci.chan = 0;
11091    ci.confno = myrpt->txconf;
11092    ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER ;
11093    /* first put the channel on the conference in proper mode */
11094    if (ioctl(myrpt->txpchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
11095    {
11096       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
11097       rpt_mutex_unlock(&myrpt->lock);
11098       ast_hangup(myrpt->txpchannel);
11099       ast_hangup(myrpt->monchannel);
11100       if (myrpt->txchannel != myrpt->rxchannel) 
11101          ast_hangup(myrpt->txchannel);
11102       ast_hangup(myrpt->rxchannel);
11103       myrpt->rpt_thread = AST_PTHREADT_STOP;
11104       pthread_exit(NULL);
11105    }
11106    /* if serial io port, open it */
11107    myrpt->iofd = -1;
11108    if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt,myrpt->p.ioport)) == -1))
11109    {
11110       ast_log(LOG_ERROR, "Unable to open %s\n",myrpt->p.ioport);
11111       rpt_mutex_unlock(&myrpt->lock);
11112       ast_hangup(myrpt->pchannel);
11113       if (myrpt->txchannel != myrpt->rxchannel) 
11114          ast_hangup(myrpt->txchannel);
11115       ast_hangup(myrpt->rxchannel);
11116       pthread_exit(NULL);
11117    }
11118    /* Now, the idea here is to copy from the physical rx channel buffer
11119       into the pseudo tx buffer, and from the pseudo rx buffer into the 
11120       tx channel buffer */
11121    myrpt->links.next = &myrpt->links;
11122    myrpt->links.prev = &myrpt->links;
11123    myrpt->tailtimer = 0;
11124    myrpt->totimer = 0;
11125    myrpt->tmsgtimer = myrpt->p.tailmessagetime;
11126    myrpt->idtimer = myrpt->p.politeid;
11127    myrpt->mustid = myrpt->tailid = 0;
11128    myrpt->callmode = 0;
11129    myrpt->tounkeyed = 0;
11130    myrpt->tonotify = 0;
11131    myrpt->retxtimer = 0;
11132    myrpt->rerxtimer = 0;
11133    myrpt->skedtimer = 0;
11134    myrpt->tailevent = 0;
11135    lasttx = 0;
11136    myrpt->keyed = 0;
11137    myrpt->txkeyed = 0;
11138    time(&myrpt->lastkeyedtime);
11139    myrpt->lastkeyedtime -= RPT_LOCKOUT_SECS;
11140    time(&myrpt->lasttxkeyedtime);
11141    myrpt->lasttxkeyedtime -= RPT_LOCKOUT_SECS;
11142    idtalkover = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "idtalkover");
11143    myrpt->dtmfidx = -1;
11144    myrpt->dtmfbuf[0] = 0;
11145    myrpt->rem_dtmfidx = -1;
11146    myrpt->rem_dtmfbuf[0] = 0;
11147    myrpt->dtmf_time = 0;
11148    myrpt->rem_dtmf_time = 0;
11149    myrpt->inpadtest = 0;
11150    myrpt->disgorgetime = 0;
11151    myrpt->lastnodewhichkeyedusup[0] = '\0';
11152    myrpt->dailytxtime = 0;
11153    myrpt->totaltxtime = 0;
11154    myrpt->dailykeyups = 0;
11155    myrpt->totalkeyups = 0;
11156    myrpt->dailykerchunks = 0;
11157    myrpt->totalkerchunks = 0;
11158    myrpt->dailyexecdcommands = 0;
11159    myrpt->totalexecdcommands = 0;
11160    myrpt->timeouts = 0;
11161    myrpt->exten[0] = '\0';
11162    myrpt->lastdtmfcommand[0] = '\0';
11163    voxinit_rpt(myrpt,1);
11164    myrpt->wasvox = 0;
11165    if (myrpt->p.startupmacro)
11166    {
11167       snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro);
11168    }
11169    rpt_mutex_unlock(&myrpt->lock);
11170    val = 1;
11171    ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0);
11172    val = 1;
11173    ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
11174    if (myrpt->p.archivedir) donodelog(myrpt,"STARTUP");
11175    dtmfed = 0;
11176    if (myrpt->remoterig && !ISRIG_RTX(myrpt->remoterig)) setrem(myrpt);
11177    lastmyrx = 0;
11178    myfirst = 0;
11179    while (ms >= 0)
11180    {
11181       struct ast_frame *f,*f1,*f2;
11182       struct ast_channel *cs[300],*cs1[300];
11183       int totx=0,elap=0,n,x,toexit=0;
11184 
11185       /* DEBUG Dump */
11186       if((myrpt->disgorgetime) && (time(NULL) >= myrpt->disgorgetime)){
11187          struct rpt_link *dl;
11188          struct rpt_tele *dt;
11189 
11190          myrpt->disgorgetime = 0;
11191          ast_log(LOG_NOTICE,"********** Variable Dump Start (app_rpt) **********\n");
11192          ast_log(LOG_NOTICE,"totx = %d\n",totx);
11193          ast_log(LOG_NOTICE,"remrx = %d\n",remrx);
11194          ast_log(LOG_NOTICE,"lasttx = %d\n",lasttx);
11195          ast_log(LOG_NOTICE,"elap = %d\n",elap);
11196          ast_log(LOG_NOTICE,"toexit = %d\n",toexit);
11197 
11198          ast_log(LOG_NOTICE,"myrpt->keyed = %d\n",myrpt->keyed);
11199          ast_log(LOG_NOTICE,"myrpt->localtx = %d\n",myrpt->localtx);
11200          ast_log(LOG_NOTICE,"myrpt->callmode = %d\n",myrpt->callmode);
11201          ast_log(LOG_NOTICE,"myrpt->mustid = %d\n",myrpt->mustid);
11202          ast_log(LOG_NOTICE,"myrpt->tounkeyed = %d\n",myrpt->tounkeyed);
11203          ast_log(LOG_NOTICE,"myrpt->tonotify = %d\n",myrpt->tonotify);
11204          ast_log(LOG_NOTICE,"myrpt->retxtimer = %ld\n",myrpt->retxtimer);
11205          ast_log(LOG_NOTICE,"myrpt->totimer = %d\n",myrpt->totimer);
11206          ast_log(LOG_NOTICE,"myrpt->tailtimer = %d\n",myrpt->tailtimer);
11207          ast_log(LOG_NOTICE,"myrpt->tailevent = %d\n",myrpt->tailevent);
11208 
11209          dl = myrpt->links.next;
11210                   while(dl != &myrpt->links){
11211             ast_log(LOG_NOTICE,"*** Link Name: %s ***\n",dl->name);
11212             ast_log(LOG_NOTICE,"        link->lasttx %d\n",dl->lasttx);
11213             ast_log(LOG_NOTICE,"        link->lastrx %d\n",dl->lastrx);
11214             ast_log(LOG_NOTICE,"        link->connected %d\n",dl->connected);
11215             ast_log(LOG_NOTICE,"        link->hasconnected %d\n",dl->hasconnected);
11216             ast_log(LOG_NOTICE,"        link->outbound %d\n",dl->outbound);
11217             ast_log(LOG_NOTICE,"        link->disced %d\n",dl->disced);
11218             ast_log(LOG_NOTICE,"        link->killme %d\n",dl->killme);
11219             ast_log(LOG_NOTICE,"        link->disctime %ld\n",dl->disctime);
11220             ast_log(LOG_NOTICE,"        link->retrytimer %ld\n",dl->retrytimer);
11221             ast_log(LOG_NOTICE,"        link->retries = %d\n",dl->retries);
11222             ast_log(LOG_NOTICE,"        link->reconnects = %d\n",dl->reconnects);
11223             ast_log(LOG_NOTICE,"        link->newkey = %d\n",dl->newkey);
11224                            dl = dl->next;
11225                   }
11226                                                                                                                                
11227          dt = myrpt->tele.next;
11228          if(dt != &myrpt->tele)
11229             ast_log(LOG_NOTICE,"*** Telemetry Queue ***\n");
11230                   while(dt != &myrpt->tele){
11231             ast_log(LOG_NOTICE,"        Telemetry mode: %d\n",dt->mode);
11232                            dt = dt->next;
11233                   }
11234          ast_log(LOG_NOTICE,"******* Variable Dump End (app_rpt) *******\n");
11235 
11236       }  
11237 
11238 
11239       if (myrpt->reload)
11240       {
11241          struct rpt_tele *inner_telem;
11242 
11243          rpt_mutex_lock(&myrpt->lock);
11244          inner_telem = myrpt->tele.next;
11245          while(inner_telem != &myrpt->tele)
11246          {
11247             ast_softhangup(inner_telem->chan,AST_SOFTHANGUP_DEV);
11248             inner_telem = inner_telem->next;
11249          }
11250          myrpt->reload = 0;
11251          rpt_mutex_unlock(&myrpt->lock);
11252          usleep(10000);
11253          /* find our index, and load the vars */
11254          for(i = 0; i < nrpts; i++)
11255          {
11256             if (&rpt_vars[i] == myrpt)
11257             {
11258                load_rpt_vars(i,0);
11259                break;
11260             }
11261          }
11262       }
11263 
11264       rpt_mutex_lock(&myrpt->lock);
11265       if (ast_check_hangup(myrpt->rxchannel)) break;
11266       if (ast_check_hangup(myrpt->txchannel)) break;
11267       if (ast_check_hangup(myrpt->pchannel)) break;
11268       if (ast_check_hangup(myrpt->monchannel)) break;
11269       if (myrpt->parrotchannel && 
11270          ast_check_hangup(myrpt->parrotchannel)) break;
11271       if (myrpt->voxchannel && 
11272          ast_check_hangup(myrpt->voxchannel)) break;
11273       if (ast_check_hangup(myrpt->txpchannel)) break;
11274       if (myrpt->dahditxchannel && ast_check_hangup(myrpt->dahditxchannel)) break;
11275 
11276       /* Set local tx with keyed */
11277       myrpt->localtx = myrpt->keyed;
11278       /* If someone's connected, and they're transmitting from their end to us, set remrx true */
11279       l = myrpt->links.next;
11280       remrx = 0;
11281       while(l != &myrpt->links)
11282       {
11283          if (l->lastrx){
11284             remrx = 1;
11285             if(l->name[0] != '0') /* Ignore '0' nodes */
11286                strcpy(myrpt->lastnodewhichkeyedusup, l->name); /* Note the node which is doing the key up */
11287          }
11288          l = l->next;
11289       }
11290       /* Create a "must_id" flag for the cleanup ID */      
11291       if(myrpt->p.idtime) /* ID time must be non-zero */
11292          myrpt->mustid |= (myrpt->idtimer) && (myrpt->keyed || remrx) ;
11293       /* Build a fresh totx from myrpt->keyed and autopatch activated */
11294       /* If full duplex, add local tx to totx */
11295       if (myrpt->p.duplex > 1) 
11296       {
11297          totx = myrpt->callmode;
11298          totx = totx || myrpt->localtx;
11299       }
11300       else
11301       {
11302          int myrx = myrpt->localtx || remrx || (!myrpt->callmode);
11303 
11304          if (lastmyrx != myrx)
11305          {
11306             voxinit_rpt(myrpt,!myrx);
11307             lastmyrx = myrx;
11308          }
11309          totx = 0;
11310          if (myrpt->callmode && (myrpt->voxtotimer <= 0))
11311          {
11312             if (myrpt->voxtostate)
11313             {
11314                myrpt->voxtotimer = myrpt->p.voxtimeout_ms;
11315                myrpt->voxtostate = 0;
11316             }           
11317             else
11318             {
11319                myrpt->voxtotimer = myrpt->p.voxrecover_ms;
11320                myrpt->voxtostate = 1;
11321             }
11322          }
11323          if (!myrpt->voxtostate)
11324             totx = myrpt->callmode && myrpt->wasvox;
11325       }
11326       /* Traverse the telemetry list to see what's queued */
11327       identqueued = 0;
11328       localmsgqueued = 0;
11329       othertelemqueued = 0;
11330       tailmessagequeued = 0;
11331       ctqueued = 0;
11332       telem = myrpt->tele.next;
11333       while(telem != &myrpt->tele)
11334       {
11335          if((telem->mode == ID) || (telem->mode == IDTALKOVER)){
11336             identqueued = 1; /* Identification telemetry */
11337          }
11338          else if(telem->mode == TAILMSG)
11339          {
11340             tailmessagequeued = 1; /* Tail message telemetry */
11341          }
11342          else if(telem->mode == STATS_TIME_LOCAL) 
11343          {
11344             localmsgqueued = 1; /* Local message */
11345          }
11346          else
11347          {
11348             if ((telem->mode != UNKEY) && (telem->mode != LINKUNKEY))
11349                othertelemqueued = 1;  /* Other telemetry */
11350             else
11351                ctqueued = 1; /* Courtesy tone telemetry */
11352          }
11353          telem = telem->next;
11354       }
11355    
11356       /* Add in any "other" telemetry, unless specified otherwise */
11357       if (!myrpt->p.notelemtx) totx = totx || othertelemqueued;
11358       /* Update external (to links) transmitter PTT state with everything but */
11359       /* ID, CT, local messages, and tailmessage telemetry */
11360       myrpt->exttx = totx;
11361       totx = totx || myrpt->dtmf_local_timer;
11362       /* If half or 3/4 duplex, add localtx to external link tx */
11363       if (myrpt->p.duplex < 2) myrpt->exttx = myrpt->exttx || myrpt->localtx;
11364       /* Add in ID telemetry to local transmitter */
11365       totx = totx || remrx;
11366       /* If 3/4 or full duplex, add in ident, CT telemetry, and local messages */
11367       if (myrpt->p.duplex > 0)
11368          totx = totx || identqueued || ctqueued || localmsgqueued;
11369       /* If full duplex, add local dtmf stuff active */
11370       if (myrpt->p.duplex > 1) 
11371       {
11372          totx = totx || (myrpt->dtmfidx > -1) ||
11373             myrpt->cmdnode[0];
11374       }
11375       /* add in parrot stuff */
11376       totx = totx || (myrpt->parrotstate > 1);
11377       /* Reset time out timer variables if there is no activity */
11378       if (!totx) 
11379       {
11380          myrpt->totimer = myrpt->p.totime;
11381          myrpt->tounkeyed = 0;
11382          myrpt->tonotify = 0;
11383       }
11384       else{
11385          myrpt->tailtimer = myrpt->p.s[myrpt->p.sysstate_cur].alternatetail ?
11386             myrpt->p.althangtime : /* Initialize tail timer */
11387             myrpt->p.hangtime;
11388       }
11389       /* Disable the local transmitter if we are timed out */
11390       totx = totx && myrpt->totimer;
11391       /* if timed-out and not said already, say it */
11392       if ((!myrpt->totimer) && (!myrpt->tonotify))
11393       {
11394          myrpt->tonotify = 1;
11395          myrpt->timeouts++;
11396          rpt_mutex_unlock(&myrpt->lock);
11397          rpt_telemetry(myrpt,TIMEOUT,NULL);
11398          rpt_mutex_lock(&myrpt->lock);
11399       }
11400 
11401       /* If unkey and re-key, reset time out timer */
11402       if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!myrpt->keyed))
11403       {
11404          myrpt->tounkeyed = 1;
11405       }
11406       if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->keyed)
11407       {
11408          myrpt->totimer = myrpt->p.totime;
11409          myrpt->tounkeyed = 0;
11410          myrpt->tonotify = 0;
11411          rpt_mutex_unlock(&myrpt->lock);
11412          continue;
11413       }
11414       /* if timed-out and in circuit busy after call */
11415       if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4))
11416       {
11417           if(debug)
11418             ast_log(LOG_NOTICE, "timed-out and in circuit busy after call\n");
11419          myrpt->callmode = 0;
11420          myrpt->macropatch=0;
11421          channel_revert(myrpt);
11422       }
11423       /* get rid of tail if timed out */
11424       if (!myrpt->totimer) myrpt->tailtimer = 0;
11425       /* if not timed-out, add in tail */
11426       if (myrpt->totimer) totx = totx || myrpt->tailtimer;
11427       /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */
11428       /* If tail message, kill the message if someone keys up over it */ 
11429       if ((myrpt->keyed || remrx) && ((identqueued && idtalkover) || (tailmessagequeued))) {
11430          int hasid = 0,hastalkover = 0;
11431 
11432          telem = myrpt->tele.next;
11433          while(telem != &myrpt->tele){
11434             if(telem->mode == ID){
11435                if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
11436                hasid = 1;
11437             }
11438             if(telem->mode == TAILMSG){
11439                                         if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */
11440                                 }
11441             if (telem->mode == IDTALKOVER) hastalkover = 1;
11442             telem = telem->next;
11443          }
11444          rpt_mutex_unlock(&myrpt->lock);
11445          if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */
11446          rpt_mutex_lock(&myrpt->lock);
11447       }
11448       /* Try to be polite */
11449       /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/
11450       /* If within 30 seconds of the time to ID, try do it in the tail */
11451       /* else if at ID time limit, do it right over the top of them */
11452       /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */
11453       if(myrpt->mustid && (!myrpt->idtimer))
11454          queue_id(myrpt);
11455 
11456       if ((myrpt->p.idtime && totx && (!myrpt->exttx) &&
11457           (myrpt->idtimer <= myrpt->p.politeid) && myrpt->tailtimer)) /* ID time must be non-zero */ 
11458          {
11459             myrpt->tailid = 1;
11460          }
11461 
11462       /* If tail timer expires, then check for tail messages */
11463 
11464       if(myrpt->tailevent){
11465          myrpt->tailevent = 0;
11466          if(myrpt->tailid){
11467             totx = 1;
11468             queue_id(myrpt);
11469          }
11470          else if ((myrpt->p.tailmessages[0]) &&
11471             (myrpt->p.tailmessagetime) && (myrpt->tmsgtimer == 0)){
11472                totx = 1;
11473                myrpt->tmsgtimer = myrpt->p.tailmessagetime; 
11474                rpt_mutex_unlock(&myrpt->lock);
11475                rpt_telemetry(myrpt, TAILMSG, NULL);
11476                rpt_mutex_lock(&myrpt->lock);
11477          }  
11478       }
11479 
11480       /* Main TX control */
11481 
11482       /* let telemetry transmit anyway (regardless of timeout) */
11483       if (myrpt->p.duplex > 0) totx = totx || (myrpt->tele.next != &myrpt->tele);
11484       totx = totx && !myrpt->p.s[myrpt->p.sysstate_cur].txdisable;
11485       myrpt->txrealkeyed = totx;
11486       totx = totx || (!AST_LIST_EMPTY(&myrpt->txq));
11487       if (totx && (!lasttx))
11488       {
11489          char mydate[100],myfname[100];
11490          time_t myt;
11491 
11492          if (myrpt->monstream) ast_closestream(myrpt->monstream);
11493          if (myrpt->p.archivedir)
11494          {
11495             long blocksleft;
11496 
11497             time(&myt);
11498             strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S",
11499                localtime(&myt));
11500             sprintf(myfname,"%s/%s/%s",myrpt->p.archivedir,
11501                myrpt->name,mydate);
11502             myrpt->monstream = ast_writefile(myfname,"wav49",
11503                "app_rpt Air Archive",O_CREAT | O_APPEND,0,0600);
11504             if (myrpt->p.monminblocks)
11505             {
11506                blocksleft = diskavail(myrpt);
11507                if (blocksleft >= myrpt->p.monminblocks)
11508                   donodelog(myrpt,"TXKEY,MAIN");
11509             } else donodelog(myrpt,"TXKEY,MAIN");
11510          }
11511          lasttx = 1;
11512          myrpt->txkeyed = 1;
11513          time(&myrpt->lasttxkeyedtime);
11514          myrpt->dailykeyups++;
11515          myrpt->totalkeyups++;
11516          rpt_mutex_unlock(&myrpt->lock);
11517          ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
11518          rpt_mutex_lock(&myrpt->lock);
11519       }
11520       if ((!totx) && lasttx)
11521       {
11522          if (myrpt->monstream) ast_closestream(myrpt->monstream);
11523          myrpt->monstream = NULL;
11524 
11525          lasttx = 0;
11526          myrpt->txkeyed = 0;
11527          time(&myrpt->lasttxkeyedtime);
11528          rpt_mutex_unlock(&myrpt->lock);
11529          ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
11530          rpt_mutex_lock(&myrpt->lock);
11531          donodelog(myrpt,"TXUNKEY,MAIN");
11532       }
11533       time(&t);
11534       /* if DTMF timeout */
11535       if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((myrpt->dtmf_time + DTMF_TIMEOUT) < t))
11536       {
11537          myrpt->inpadtest = 0;
11538          myrpt->dtmfidx = -1;
11539          myrpt->dtmfbuf[0] = 0;
11540       }        
11541       /* if remote DTMF timeout */
11542       if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t))
11543       {
11544          myrpt->inpadtest = 0;
11545          myrpt->rem_dtmfidx = -1;
11546          myrpt->rem_dtmfbuf[0] = 0;
11547       }  
11548 
11549       if (myrpt->exttx && myrpt->parrotchannel && 
11550          myrpt->p.parrotmode && (!myrpt->parrotstate))
11551       {
11552          char myfname[300];
11553 
11554          ci.confno = myrpt->conf;
11555          ci.confmode = DAHDI_CONF_CONFANNMON;
11556          ci.chan = 0;
11557 
11558          /* first put the channel on the conference in announce mode */
11559          if (ioctl(myrpt->parrotchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
11560          {
11561             ast_log(LOG_WARNING, "Unable to set conference mode for parrot\n");
11562             break;
11563          }
11564 
11565          sprintf(myfname,PARROTFILE,myrpt->name,myrpt->parrotcnt);
11566          strcat(myfname,".wav");
11567          unlink(myfname);        
11568          sprintf(myfname,PARROTFILE,myrpt->name,myrpt->parrotcnt);
11569          myrpt->parrotstate = 1;
11570          myrpt->parrottimer = myrpt->p.parrottime;
11571          if (myrpt->parrotstream) 
11572             ast_closestream(myrpt->parrotstream);
11573          myrpt->parrotstream = NULL;
11574          myrpt->parrotstream = ast_writefile(myfname,"wav",
11575             "app_rpt Parrot",O_CREAT | O_TRUNC,0,0600);
11576       }
11577 
11578       /* Reconnect */
11579    
11580       l = myrpt->links.next;
11581       while(l != &myrpt->links)
11582       {
11583          if (l->killme)
11584          {
11585             /* remove from queue */
11586             remque((struct qelem *) l);
11587             if (!strcmp(myrpt->cmdnode,l->name))
11588                myrpt->cmdnode[0] = 0;
11589             rpt_mutex_unlock(&myrpt->lock);
11590             /* hang-up on call to device */
11591             if (l->chan) ast_hangup(l->chan);
11592             ast_hangup(l->pchan);
11593             ast_free(l);
11594             rpt_mutex_lock(&myrpt->lock);
11595             /* re-start link traversal */
11596             l = myrpt->links.next;
11597             continue;
11598          }
11599          l = l->next;
11600       }
11601       n = 0;
11602       cs[n++] = myrpt->rxchannel;
11603       cs[n++] = myrpt->pchannel;
11604       cs[n++] = myrpt->monchannel;
11605       if (myrpt->parrotchannel) cs[n++] = myrpt->parrotchannel;
11606       if (myrpt->voxchannel) cs[n++] = myrpt->voxchannel;
11607       cs[n++] = myrpt->txpchannel;
11608       if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel;
11609       if (myrpt->dahditxchannel != myrpt->txchannel)
11610          cs[n++] = myrpt->dahditxchannel;
11611       l = myrpt->links.next;
11612       while(l != &myrpt->links)
11613       {
11614          if ((!l->killme) && (!l->disctime) && l->chan)
11615          {
11616             cs[n++] = l->chan;
11617             cs[n++] = l->pchan;
11618          }
11619          l = l->next;
11620       }
11621       if ((myrpt->topkeystate == 1) && 
11622           ((t - myrpt->topkeytime) > TOPKEYWAIT))
11623       {
11624          myrpt->topkeystate = 2;
11625          qsort(myrpt->topkey,TOPKEYN,sizeof(struct rpt_topkey),
11626             topcompar);
11627       }
11628       rpt_mutex_unlock(&myrpt->lock);
11629 
11630       if (myrpt->topkeystate == 2)
11631       {
11632          rpt_telemetry(myrpt,TOPKEY,NULL);
11633          myrpt->topkeystate = 3;
11634       }
11635       ms = MSWAIT;
11636       for(x = 0; x < n; x++)
11637       {
11638          int s = -(-x - myrpt->scram - 1) % n;
11639          cs1[x] = cs[s];
11640       }
11641       myrpt->scram++;
11642       who = ast_waitfor_n(cs1,n,&ms);
11643       if (who == NULL) ms = 0;
11644       elap = MSWAIT - ms;
11645       rpt_mutex_lock(&myrpt->lock);
11646       l = myrpt->links.next;
11647       while(l != &myrpt->links)
11648       {
11649          int myrx;
11650 
11651          if (l->voxtotimer) l->voxtotimer -= elap;
11652          if (l->voxtotimer < 0) l->voxtotimer = 0;
11653 
11654          if (l->lasttx != l->lasttx1)
11655          {
11656             voxinit_link(l,!l->lasttx);
11657             l->lasttx1 = l->lasttx;
11658          }
11659          myrx = l->lastrealrx;
11660          if ((l->phonemode) && (l->phonevox))
11661          {
11662             myrx = myrx || (!AST_LIST_EMPTY(&l->rxq));
11663             if (l->voxtotimer <= 0)
11664             {
11665                if (l->voxtostate)
11666                {
11667                   l->voxtotimer = myrpt->p.voxtimeout_ms;
11668                   l->voxtostate = 0;
11669                }           
11670                else
11671                {
11672                   l->voxtotimer = myrpt->p.voxrecover_ms;
11673                   l->voxtostate = 1;
11674                }
11675             }
11676             if (!l->voxtostate)
11677                myrx = myrx || l->wasvox ;
11678          }
11679          l->lastrx = myrx;
11680          if (l->linklisttimer)
11681          {
11682             l->linklisttimer -= elap;
11683             if (l->linklisttimer < 0) l->linklisttimer = 0;
11684          }
11685          if ((!l->linklisttimer) && (l->name[0] != '0') && (!l->isremote))
11686          {
11687             struct   ast_frame lf;
11688 
11689             memset(&lf,0,sizeof(lf));
11690             lf.frametype = AST_FRAME_TEXT;
11691             lf.subclass = 0;
11692             lf.offset = 0;
11693             lf.mallocd = 0;
11694             lf.samples = 0;
11695             l->linklisttimer = LINKLISTTIME;
11696             strcpy(lstr,"L ");
11697             __mklinklist(myrpt,l,lstr + 2);
11698             if (l->chan)
11699             {
11700                lf.datalen = strlen(lstr) + 1;
11701                lf.data.ptr = lstr;
11702                ast_write(l->chan,&lf);
11703                if (debug > 6) ast_log(LOG_NOTICE,
11704                   "@@@@ node %s sent node string %s to node %s\n",
11705                      myrpt->name,lstr,l->name);
11706             }
11707          }
11708          if (l->newkey)
11709          {
11710             if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME)
11711             {
11712                l->retxtimer = 0;
11713                if (l->chan && l->phonemode == 0) 
11714                {
11715                   if (l->lasttx)
11716                      ast_indicate(l->chan,AST_CONTROL_RADIO_KEY);
11717                   else
11718                      ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY);
11719                }
11720             }
11721             if ((l->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 5))
11722             {
11723                if (debug == 7) printf("@@@@ rx un-key\n");
11724                l->lastrealrx = 0;
11725                l->rerxtimer = 0;
11726                if (l->lastrx1)
11727                {
11728                   if (myrpt->p.archivedir)
11729                   {
11730                      char str[100];
11731    
11732                      sprintf(str,"RXUNKEY(T),%s",l->name);
11733                      donodelog(myrpt,str);
11734                   }
11735                   if(myrpt->p.duplex) 
11736                      rpt_telemetry(myrpt,LINKUNKEY,l);
11737                   l->lastrx1 = 0;
11738                }
11739             }
11740          }
11741          if (l->disctime) /* Disconnect timer active on a channel ? */
11742          {
11743             l->disctime -= elap;
11744             if (l->disctime <= 0) /* Disconnect timer expired on inbound channel ? */
11745                l->disctime = 0; /* Yep */
11746          }
11747 
11748          if (l->retrytimer)
11749          {
11750             l->retrytimer -= elap;
11751             if (l->retrytimer < 0) l->retrytimer = 0;
11752          }
11753 
11754          /* Tally connect time */
11755          l->connecttime += elap;
11756 
11757          /* ignore non-timing channels */
11758          if (l->elaptime < 0)
11759          {
11760             l = l->next;
11761             continue;
11762          }
11763          l->elaptime += elap;
11764          /* if connection has taken too long */
11765          if ((l->elaptime > MAXCONNECTTIME) && 
11766             ((!l->chan) || (l->chan->_state != AST_STATE_UP)))
11767          {
11768             l->elaptime = 0;
11769             rpt_mutex_unlock(&myrpt->lock);
11770             if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV);
11771             rpt_mutex_lock(&myrpt->lock);
11772             break;
11773          }
11774          if ((!l->chan) && (!l->retrytimer) && l->outbound && 
11775             (l->retries++ < l->max_retries) && (l->hasconnected))
11776          {
11777             if (l->chan) ast_hangup(l->chan);
11778             l->chan = 0;
11779             rpt_mutex_unlock(&myrpt->lock);
11780             if ((l->name[0] != '0') && (!l->isremote))
11781             {
11782                if (attempt_reconnect(myrpt,l) == -1)
11783                {
11784                   l->retrytimer = RETRY_TIMER_MS;
11785                } 
11786             }
11787             else 
11788             {
11789                l->retrytimer = l->max_retries + 1;
11790             }
11791 
11792             rpt_mutex_lock(&myrpt->lock);
11793             break;
11794          }
11795          if ((!l->chan) && (!l->retrytimer) && l->outbound &&
11796             (l->retries >= l->max_retries))
11797          {
11798             /* remove from queue */
11799             remque((struct qelem *) l);
11800             if (!strcmp(myrpt->cmdnode,l->name))
11801                myrpt->cmdnode[0] = 0;
11802             rpt_mutex_unlock(&myrpt->lock);
11803             if (l->name[0] != '0')
11804             {
11805                if (!l->hasconnected)
11806                   rpt_telemetry(myrpt,CONNFAIL,l);
11807                else rpt_telemetry(myrpt,REMDISC,l);
11808             }
11809             if (myrpt->p.archivedir)
11810             {
11811                char str[100];
11812 
11813                if (!l->hasconnected)
11814                   sprintf(str,"LINKFAIL,%s",l->name);
11815                else
11816                   sprintf(str,"LINKDISC,%s",l->name);
11817                donodelog(myrpt,str);
11818             }
11819             /* hang-up on call to device */
11820             ast_hangup(l->pchan);
11821             ast_free(l);
11822                                 rpt_mutex_lock(&myrpt->lock);
11823             break;
11824          }
11825             if ((!l->chan) && (!l->disctime) && (!l->outbound))
11826             {
11827             if(debug)ast_log(LOG_NOTICE, "LINKDISC AA\n");
11828                 /* remove from queue */
11829                 remque((struct qelem *) l);
11830             if(myrpt->links.next==&myrpt->links)channel_revert(myrpt);
11831                 if (!strcmp(myrpt->cmdnode,l->name))myrpt->cmdnode[0] = 0;
11832                 rpt_mutex_unlock(&myrpt->lock);
11833             if (l->name[0] != '0') 
11834             {
11835                   rpt_telemetry(myrpt,REMDISC,l);
11836             }
11837             if (myrpt->p.archivedir)
11838             {
11839                char str[100];
11840                sprintf(str,"LINKDISC,%s",l->name);
11841                donodelog(myrpt,str);
11842             }
11843                 /* hang-up on call to device */
11844                 ast_hangup(l->pchan);
11845                 ast_free(l);
11846                 rpt_mutex_lock(&myrpt->lock);
11847                 break;
11848             }
11849          l = l->next;
11850       }
11851       if (myrpt->linkposttimer)
11852       {
11853          myrpt->linkposttimer -= elap;
11854          if (myrpt->linkposttimer < 0) myrpt->linkposttimer = 0;
11855       }
11856       if (myrpt->linkposttimer <= 0)
11857       {
11858          int nstr;
11859          char lst,*str;
11860          time_t now;
11861 
11862          myrpt->linkposttimer = LINKPOSTTIME;
11863          nstr = 0;
11864          for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
11865          {
11866             /* if is not a real link, ignore it */
11867             if (l->name[0] == '0') continue;
11868             nstr += strlen(l->name) + 1;
11869          }
11870          str = ast_malloc(nstr + 256);
11871          if (!str)
11872          {
11873             ast_log(LOG_NOTICE,"Cannot ast_malloc()\n");
11874             break;
11875          }
11876          nstr = 0;
11877          strcpy(str,"nodes=");
11878          for(l = myrpt->links.next; l != &myrpt->links; l = l->next)
11879          {
11880             /* if is not a real link, ignore it */
11881             if (l->name[0] == '0') continue;
11882             lst = 'T';
11883             if (!l->mode) lst = 'R';
11884             if (!l->thisconnected) lst = 'C';
11885             if (nstr) strcat(str,",");
11886             sprintf(str + strlen(str),"%c%s",lst,l->name);
11887             nstr = 1;
11888          }
11889                   p = strstr(tdesc, "version");
11890                   if(p){
11891             int vmajor,vminor;
11892             if(sscanf(p, "version %d.%d", &vmajor, &vminor) == 2)
11893                sprintf(str + strlen(str),"&apprptvers=%d.%d",vmajor,vminor);
11894          }
11895          time(&now);
11896          sprintf(str + strlen(str),"&apprptuptime=%d",(int)(now-starttime));
11897          sprintf(str + strlen(str),
11898          "&totalkerchunks=%d&totalkeyups=%d&totaltxtime=%d&timeouts=%d&totalexecdcommands=%d",
11899          myrpt->totalkerchunks,myrpt->totalkeyups,(int) myrpt->totaltxtime/1000,
11900          myrpt->timeouts,myrpt->totalexecdcommands);
11901          rpt_mutex_unlock(&myrpt->lock);
11902          statpost(myrpt,str);
11903          rpt_mutex_lock(&myrpt->lock);
11904          ast_free(str);
11905       }
11906       if (myrpt->keyposttimer)
11907       {
11908          myrpt->keyposttimer -= elap;
11909          if (myrpt->keyposttimer < 0) myrpt->keyposttimer = 0;
11910       }
11911       if (myrpt->keyposttimer <= 0)
11912       {
11913          char str[100];
11914          int diff = 0;
11915          time_t now;
11916 
11917          myrpt->keyposttimer = KEYPOSTTIME;
11918          time(&now);
11919          if (myrpt->lastkeyedtime)
11920          {
11921             diff = (int)(now - myrpt->lastkeyedtime);
11922          }
11923          sprintf(str,"keyed=%d&keytime=%d",myrpt->keyed,diff);
11924          rpt_mutex_unlock(&myrpt->lock);
11925          statpost(myrpt,str);
11926          rpt_mutex_lock(&myrpt->lock);
11927       }
11928       if(totx){
11929          myrpt->dailytxtime += elap;
11930          myrpt->totaltxtime += elap;
11931       }
11932       i = myrpt->tailtimer;
11933       if (myrpt->tailtimer) myrpt->tailtimer -= elap;
11934       if (myrpt->tailtimer < 0) myrpt->tailtimer = 0;
11935       if((i) && (myrpt->tailtimer == 0))
11936          myrpt->tailevent = 1;
11937       if ((!myrpt->p.s[myrpt->p.sysstate_cur].totdisable) && myrpt->totimer) myrpt->totimer -= elap;
11938       if (myrpt->totimer < 0) myrpt->totimer = 0;
11939       if (myrpt->idtimer) myrpt->idtimer -= elap;
11940       if (myrpt->idtimer < 0) myrpt->idtimer = 0;
11941       if (myrpt->tmsgtimer) myrpt->tmsgtimer -= elap;
11942       if (myrpt->tmsgtimer < 0) myrpt->tmsgtimer = 0;
11943       if (myrpt->voxtotimer) myrpt->voxtotimer -= elap;
11944       if (myrpt->voxtotimer < 0) myrpt->voxtotimer = 0;
11945       if (myrpt->exttx)
11946       {
11947          myrpt->parrottimer = myrpt->p.parrottime;
11948       }
11949       else
11950       {
11951          if (myrpt->parrottimer) myrpt->parrottimer -= elap;
11952          if (myrpt->parrottimer < 0) myrpt->parrottimer = 0;
11953       }
11954       /* do macro timers */
11955       if (myrpt->macrotimer) myrpt->macrotimer -= elap;
11956       if (myrpt->macrotimer < 0) myrpt->macrotimer = 0;
11957       /* do local dtmf timer */
11958       if (myrpt->dtmf_local_timer)
11959       {
11960          if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap;
11961          if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1;
11962       }
11963       do_dtmf_local(myrpt,0);
11964       /* Execute scheduler appx. every 2 tenths of a second */
11965       if (myrpt->skedtimer <= 0){
11966          myrpt->skedtimer = 200;
11967          do_scheduler(myrpt);
11968       }
11969       else
11970          myrpt->skedtimer -=elap;
11971       if (!ms) 
11972       {
11973          rpt_mutex_unlock(&myrpt->lock);
11974          continue;
11975       }
11976       if (myrpt->p.parrotmode && (myrpt->parrotstate == 1) &&
11977          (myrpt->parrottimer <= 0))
11978       {
11979 
11980          ci.confno = 0;
11981          ci.confmode = 0;
11982          ci.chan = 0;
11983 
11984          /* first put the channel on the conference in announce mode */
11985          if (ioctl(myrpt->parrotchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
11986          {
11987             ast_log(LOG_WARNING, "Unable to set conference mode for parrot\n");
11988             break;
11989          }
11990          if (myrpt->parrotstream) 
11991             ast_closestream(myrpt->parrotstream);
11992          myrpt->parrotstream = NULL;
11993          myrpt->parrotstate = 2;
11994          rpt_telemetry(myrpt,PARROT,(void *) ((intptr_t)myrpt->parrotcnt++)); 
11995       }        
11996       if (myrpt->cmdAction.state == CMD_STATE_READY)
11997       { /* there is a command waiting to be processed */
11998          int status;
11999          myrpt->cmdAction.state = CMD_STATE_EXECUTING;
12000          // lose the lock
12001          rpt_mutex_unlock(&myrpt->lock);
12002          // do the function
12003          status = (*function_table[myrpt->cmdAction.functionNumber].function)(myrpt,myrpt->cmdAction.param, myrpt->cmdAction.digits, myrpt->cmdAction.command_source, NULL);
12004          // get the lock again
12005          rpt_mutex_lock(&myrpt->lock);
12006          myrpt->cmdAction.state = CMD_STATE_IDLE;
12007       } /* if myrpt->cmdAction.state == CMD_STATE_READY */
12008       
12009       c = myrpt->macrobuf[0];
12010       time(&t);
12011       if (c && (!myrpt->macrotimer) && 
12012          starttime && (t > (starttime + START_DELAY)))
12013       {
12014          char cin = c & 0x7f;
12015          myrpt->macrotimer = MACROTIME;
12016          memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1);
12017          if ((cin == 'p') || (cin == 'P'))
12018             myrpt->macrotimer = MACROPTIME;
12019          rpt_mutex_unlock(&myrpt->lock);
12020          if (myrpt->p.archivedir)
12021          {
12022             char str[100];
12023 
12024             sprintf(str,"DTMF(M),MAIN,%c",cin);
12025             donodelog(myrpt,str);
12026          }
12027          local_dtmf_helper(myrpt,c);
12028       } else rpt_mutex_unlock(&myrpt->lock);
12029       if (who == myrpt->rxchannel) /* if it was a read from rx */
12030       {
12031          int ismuted;
12032 
12033          f = ast_read(myrpt->rxchannel);
12034          if (!f)
12035          {
12036             if (debug) printf("@@@@ rpt:Hung Up\n");
12037             break;
12038          }
12039          if (f->frametype == AST_FRAME_VOICE)
12040          {
12041 #ifdef   _MDC_DECODE_H_
12042             unsigned char ubuf[2560];
12043             short *sp;
12044             int n;
12045 #endif
12046 
12047             if ((!myrpt->localtx) && (!myrpt->p.linktolink)) {
12048                memset(f->data.ptr,0,f->datalen);
12049             }
12050 
12051 #ifdef   _MDC_DECODE_H_
12052             sp = (short *) f->data;
12053             /* convert block to unsigned char */
12054             for(n = 0; n < f->datalen / 2; n++)
12055             {
12056                ubuf[n] = (*sp++ >> 8) + 128;
12057             }
12058             n = mdc_decoder_process_samples(myrpt->mdc,ubuf,f->datalen / 2);
12059             if (n == 1)
12060             {
12061                   unsigned char op,arg;
12062                   unsigned short unitID;
12063 
12064                   mdc_decoder_get_packet(myrpt->mdc,&op,&arg,&unitID);
12065                   if (debug > 2)
12066                   {
12067                      ast_log(LOG_NOTICE,"Got (single-length) packet:\n");
12068                      ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n",
12069                         op & 255,arg & 255,unitID);
12070                   }
12071                   if ((op == 1) && (arg == 0))
12072                   {
12073                      myrpt->lastunit = unitID;
12074                      mdc1200_notify(myrpt,NULL,myrpt->lastunit);
12075                      mdc1200_send(myrpt,myrpt->lastunit);
12076                   }
12077             }
12078             if ((debug > 2) && (i == 2))
12079             {
12080                unsigned char op,arg,ex1,ex2,ex3,ex4;
12081                unsigned short unitID;
12082 
12083                mdc_decoder_get_double_packet(myrpt->mdc,&op,&arg,&unitID,
12084                   &ex1,&ex2,&ex3,&ex4);
12085                ast_log(LOG_NOTICE,"Got (double-length) packet:\n");
12086                ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n",
12087                   op & 255,arg & 255,unitID);
12088                ast_log(LOG_NOTICE,"ex1: %02x, ex2: %02x, ex3: %02x, ex4: %02x\n",
12089                   ex1 & 255, ex2 & 255, ex3 & 255, ex4 & 255);
12090             }
12091 #endif
12092 #ifdef   __RPT_NOTCH
12093             /* apply inbound filters, if any */
12094             rpt_filter(myrpt,f->data,f->datalen / 2);
12095 #endif
12096             if (ioctl(myrpt->dahdirxchannel->fds[0], DAHDI_GETCONFMUTE, &ismuted) == -1)
12097             {
12098                ismuted = 0;
12099             }
12100             if (dtmfed) ismuted = 1;
12101             dtmfed = 0;
12102             if (ismuted)
12103             {
12104                memset(f->data.ptr,0,f->datalen);
12105                if (myrpt->lastf1)
12106                   memset(myrpt->lastf1->data.ptr,0,myrpt->lastf1->datalen);
12107                if (myrpt->lastf2)
12108                   memset(myrpt->lastf2->data.ptr,0,myrpt->lastf2->datalen);
12109             } 
12110             if (f) f2 = ast_frdup(f);
12111             else f2 = NULL;
12112             f1 = myrpt->lastf2;
12113             myrpt->lastf2 = myrpt->lastf1;
12114             myrpt->lastf1 = f2;
12115             if (ismuted)
12116             {
12117                if (myrpt->lastf1)
12118                   memset(myrpt->lastf1->data.ptr,0,myrpt->lastf1->datalen);
12119                if (myrpt->lastf2)
12120                   memset(myrpt->lastf2->data.ptr,0,myrpt->lastf2->datalen);
12121             }
12122             if (f1)
12123             {
12124                ast_write(myrpt->pchannel,f1);
12125                ast_frfree(f1);
12126             }
12127          }
12128 #ifndef  OLD_ASTERISK
12129          else if (f->frametype == AST_FRAME_DTMF_BEGIN)
12130          {
12131             if (myrpt->lastf1)
12132                memset(myrpt->lastf1->data.ptr,0,myrpt->lastf1->datalen);
12133             if (myrpt->lastf2)
12134                memset(myrpt->lastf2->data.ptr,0,myrpt->lastf2->datalen);
12135             dtmfed = 1;
12136          }
12137 #endif
12138          else if (f->frametype == AST_FRAME_DTMF)
12139          {
12140             c = (char) f->subclass; /* get DTMF char */
12141             ast_frfree(f);
12142             if (myrpt->lastf1)
12143                memset(myrpt->lastf1->data.ptr,0,myrpt->lastf1->datalen);
12144             if (myrpt->lastf2)
12145                memset(myrpt->lastf2->data.ptr,0,myrpt->lastf2->datalen);
12146             dtmfed = 1;
12147             if (!myrpt->keyed) continue;
12148             c = func_xlat(myrpt,c,&myrpt->p.inxlat);
12149             if (c) local_dtmf_helper(myrpt,c);
12150             continue;
12151          }                 
12152          else if (f->frametype == AST_FRAME_CONTROL)
12153          {
12154             if (f->subclass == AST_CONTROL_HANGUP)
12155             {
12156                if (debug) printf("@@@@ rpt:Hung Up\n");
12157                ast_frfree(f);
12158                break;
12159             }
12160             /* if RX key */
12161             if (f->subclass == AST_CONTROL_RADIO_KEY)
12162             {
12163                if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink)) 
12164                {
12165                   if (debug == 7) printf("@@@@ rx key\n");
12166                   myrpt->keyed = 1;
12167                   time(&myrpt->lastkeyedtime);
12168                   myrpt->keyposttimer = KEYPOSTSHORTTIME;
12169                }
12170                if (myrpt->p.archivedir)
12171                {
12172                   donodelog(myrpt,"RXKEY,MAIN");
12173                }
12174                if (f->datalen && f->data.ptr)
12175                {
12176                   char busy = 0;
12177 
12178                   if (debug) ast_log(LOG_NOTICE,"Got PL %s on node %s\n",(char *)f->data.ptr,myrpt->name);
12179                   // ctcss code autopatch initiate
12180                   if (strstr((char *)f->data.ptr,"/M/")&& !myrpt->macropatch)
12181                   {
12182                       char value[16];
12183                      strcat(value,"*6");
12184                      myrpt->macropatch=1;
12185                      rpt_mutex_lock(&myrpt->lock);
12186                      if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(value)){
12187                         rpt_mutex_unlock(&myrpt->lock);
12188                         busy=1;
12189                      }
12190                      if(!busy){
12191                         myrpt->macrotimer = MACROTIME;
12192                         strncat(myrpt->macrobuf,value,MAXMACRO - 1);
12193                         if (!busy) strcpy(myrpt->lasttone,(char*)f->data.ptr);
12194                      }
12195                      rpt_mutex_unlock(&myrpt->lock);
12196                   }
12197                   else if (strcmp((char *)f->data.ptr,myrpt->lasttone))
12198                   {
12199                      char *value = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->p.tonemacro, (char *)f->data.ptr);
12200                      if (value)
12201                      {
12202                         if (debug) ast_log(LOG_NOTICE,"Tone %s doing %s on node %s\n",(char *) f->data.ptr,value,myrpt->name);
12203                         rpt_mutex_lock(&myrpt->lock);
12204                         if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(value)){
12205                            rpt_mutex_unlock(&myrpt->lock);
12206                            busy=1;
12207                         }
12208                         if(!busy){
12209                            myrpt->macrotimer = MACROTIME;
12210                            strncat(myrpt->macrobuf,value,MAXMACRO - 1);
12211                         }
12212                         rpt_mutex_unlock(&myrpt->lock);
12213                      }
12214                      if (!busy) strcpy(myrpt->lasttone,(char*)f->data.ptr);
12215                   }
12216                } else myrpt->lasttone[0] = 0;
12217             }
12218             /* if RX un-key */
12219             if (f->subclass == AST_CONTROL_RADIO_UNKEY)
12220             {
12221                if ((!lasttx) || (myrpt->p.duplex > 1) || (myrpt->p.linktolink))
12222                {
12223                   if (debug == 7) printf("@@@@ rx un-key\n");
12224                   if(myrpt->p.duplex && myrpt->keyed) {
12225                      rpt_telemetry(myrpt,UNKEY,NULL);
12226                   }
12227                }
12228                myrpt->keyed = 0;
12229                time(&myrpt->lastkeyedtime);
12230                myrpt->keyposttimer = KEYPOSTSHORTTIME;
12231                if (myrpt->p.archivedir)
12232                {
12233                   donodelog(myrpt,"RXUNKEY,MAIN");
12234                }
12235             }
12236          }
12237          ast_frfree(f);
12238          continue;
12239       }
12240       if (who == myrpt->pchannel) /* if it was a read from pseudo */
12241       {
12242          f = ast_read(myrpt->pchannel);
12243          if (!f)
12244          {
12245             if (debug) printf("@@@@ rpt:Hung Up\n");
12246             break;
12247          }
12248          if (f->frametype == AST_FRAME_VOICE)
12249          {
12250             ast_write(myrpt->txpchannel,f);
12251          }
12252          if (f->frametype == AST_FRAME_CONTROL)
12253          {
12254             if (f->subclass == AST_CONTROL_HANGUP)
12255             {
12256                if (debug) printf("@@@@ rpt:Hung Up\n");
12257                ast_frfree(f);
12258                break;
12259             }
12260          }
12261          ast_frfree(f);
12262          continue;
12263       }
12264       if (who == myrpt->txchannel) /* if it was a read from tx */
12265       {
12266          f = ast_read(myrpt->txchannel);
12267          if (!f)
12268          {
12269             if (debug) printf("@@@@ rpt:Hung Up\n");
12270             break;
12271          }
12272          if (f->frametype == AST_FRAME_CONTROL)
12273          {
12274             if (f->subclass == AST_CONTROL_HANGUP)
12275             {
12276                if (debug) printf("@@@@ rpt:Hung Up\n");
12277                ast_frfree(f);
12278                break;
12279             }
12280          }
12281          ast_frfree(f);
12282          continue;
12283       }
12284       if (who == myrpt->dahditxchannel) /* if it was a read from pseudo-tx */
12285       {
12286          f = ast_read(myrpt->dahditxchannel);
12287          if (!f)
12288          {
12289             if (debug) printf("@@@@ rpt:Hung Up\n");
12290             break;
12291          }
12292          if (f->frametype == AST_FRAME_VOICE)
12293          {
12294             struct ast_frame *vframe;
12295 
12296             if (myrpt->p.duplex < 2)
12297             {
12298                if (myrpt->txrealkeyed) 
12299                {
12300                   if ((!myfirst) && myrpt->callmode)
12301                   {
12302                       x = 0;
12303                       AST_LIST_TRAVERSE(&myrpt->txq, vframe,
12304                      frame_list) x++;
12305                       for(;x < myrpt->p.simplexpatchdelay; x++)
12306                       {
12307                         vframe = ast_frdup(f);
12308                         memset(vframe->data.ptr,0,vframe->datalen);
12309                         AST_LIST_INSERT_TAIL(&myrpt->txq,vframe,frame_list);
12310                       }
12311                       myfirst = 1;
12312                   }
12313                   vframe = ast_frdup(f);
12314                   AST_LIST_INSERT_TAIL(&myrpt->txq,
12315                      vframe,frame_list);
12316                } else myfirst = 0;
12317                x = 0;
12318                AST_LIST_TRAVERSE(&myrpt->txq, vframe,
12319                   frame_list) x++;
12320                if (!x)
12321                {
12322                   memset(f->data.ptr,0,f->datalen);
12323                }
12324                else
12325                {
12326                   ast_frfree(f);
12327                   f = AST_LIST_REMOVE_HEAD(&myrpt->txq,
12328                      frame_list);
12329                }
12330             }
12331             else
12332             {
12333                while((vframe = AST_LIST_REMOVE_HEAD(&myrpt->txq,
12334                   frame_list))) ast_frfree(vframe);
12335             }
12336             ast_write(myrpt->txchannel,f);
12337          }
12338          if (f->frametype == AST_FRAME_CONTROL)
12339          {
12340             if (f->subclass == AST_CONTROL_HANGUP)
12341             {
12342                if (debug) printf("@@@@ rpt:Hung Up\n");
12343                ast_frfree(f);
12344                break;
12345             }
12346          }
12347          ast_frfree(f);
12348          continue;
12349       }
12350       toexit = 0;
12351       rpt_mutex_lock(&myrpt->lock);
12352       l = myrpt->links.next;
12353       while(l != &myrpt->links)
12354       {
12355          int remnomute;
12356          struct timeval now;
12357 
12358          if (l->disctime)
12359          {
12360             l = l->next;
12361             continue;
12362          }
12363 
12364          remrx = 0;
12365          /* see if any other links are receiving */
12366          m = myrpt->links.next;
12367          while(m != &myrpt->links)
12368          {
12369             /* if not us, count it */
12370             if ((m != l) && (m->lastrx)) remrx = 1;
12371             m = m->next;
12372          }
12373          rpt_mutex_unlock(&myrpt->lock);
12374          now = ast_tvnow();
12375          if ((who == l->chan) || (!l->lastlinktv.tv_sec) ||
12376             (ast_tvdiff_ms(now,l->lastlinktv) >= 19))
12377          {
12378             l->lastlinktv = now;
12379             remnomute = myrpt->localtx && 
12380                 (!(myrpt->cmdnode[0] || 
12381                (myrpt->dtmfidx > -1)));
12382             totx = (((l->isremote) ? (remnomute) : 
12383                myrpt->exttx) || remrx) && l->mode;
12384             if (l->phonemode == 0 && l->chan && (l->lasttx != totx))
12385             {
12386                if (totx)
12387                {
12388                   ast_indicate(l->chan,AST_CONTROL_RADIO_KEY);
12389                }
12390                else
12391                {
12392                   ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY);
12393                }
12394                if (myrpt->p.archivedir)
12395                {
12396                   char str[100];
12397 
12398                   if (totx)
12399                      sprintf(str,"TXKEY,%s",l->name);
12400                   else
12401                      sprintf(str,"TXUNKEY,%s",l->name);
12402                   donodelog(myrpt,str);
12403                }
12404             }
12405             l->lasttx = totx;
12406          }
12407          rpt_mutex_lock(&myrpt->lock);
12408          if (who == l->chan) /* if it was a read from rx */
12409          {
12410             rpt_mutex_unlock(&myrpt->lock);
12411             f = ast_read(l->chan);
12412             if (!f)
12413             {
12414                rpt_mutex_lock(&myrpt->lock);
12415                __kickshort(myrpt);
12416                rpt_mutex_unlock(&myrpt->lock);
12417                if ((!l->disced) && (!l->outbound))
12418                {
12419                   if ((l->name[0] == '0') || l->isremote)
12420                      l->disctime = 1;
12421                   else
12422                      l->disctime = DISC_TIME;
12423                   rpt_mutex_lock(&myrpt->lock);
12424                   ast_hangup(l->chan);
12425                   l->chan = 0;
12426                   break;
12427                }
12428 
12429                if (l->retrytimer) 
12430                {
12431                   ast_hangup(l->chan);
12432                   l->chan = 0;
12433                   rpt_mutex_lock(&myrpt->lock);
12434                   break; 
12435                }
12436                if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected))
12437                {
12438                   rpt_mutex_lock(&myrpt->lock);
12439                   if (l->chan) ast_hangup(l->chan);
12440                   l->chan = 0;
12441                   l->hasconnected = 1;
12442                   l->retrytimer = RETRY_TIMER_MS;
12443                   l->elaptime = 0;
12444                   l->connecttime = 0;
12445                   l->thisconnected = 0;
12446                   break;
12447                }
12448                rpt_mutex_lock(&myrpt->lock);
12449                /* remove from queue */
12450                remque((struct qelem *) l);
12451                if (!strcmp(myrpt->cmdnode,l->name))
12452                   myrpt->cmdnode[0] = 0;
12453                __kickshort(myrpt);
12454                rpt_mutex_unlock(&myrpt->lock);
12455                if (!l->hasconnected)
12456                   rpt_telemetry(myrpt,CONNFAIL,l);
12457                else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l);
12458                if (myrpt->p.archivedir)
12459                {
12460                   char str[100];
12461 
12462                   if (!l->hasconnected)
12463                      sprintf(str,"LINKFAIL,%s",l->name);
12464                   else
12465                      sprintf(str,"LINKDISC,%s",l->name);
12466                   donodelog(myrpt,str);
12467                }
12468                if (l->lastf1) ast_frfree(l->lastf1);
12469                l->lastf1 = NULL;
12470                if (l->lastf2) ast_frfree(l->lastf2);
12471                l->lastf2 = NULL;
12472                /* hang-up on call to device */
12473                ast_hangup(l->chan);
12474                ast_hangup(l->pchan);
12475                ast_free(l);
12476                rpt_mutex_lock(&myrpt->lock);
12477                break;
12478             }
12479             if (f->frametype == AST_FRAME_VOICE)
12480             {
12481                int ismuted,n1;
12482 
12483                if ((l->phonemode) && (l->phonevox))
12484                {
12485                   n1 = dovox(&l->vox,
12486                      f->data.ptr,f->datalen / 2);
12487                   if (n1 != l->wasvox)
12488                   {
12489                      if (debug)ast_log(LOG_DEBUG,"Link Node %s, vox %d\n",l->name,n1);
12490                      l->wasvox = n1;
12491                      l->voxtostate = 0;
12492                      if (n1) l->voxtotimer = myrpt->p.voxtimeout_ms;
12493                      else l->voxtotimer = 0;
12494                   }
12495                   if (l->lastrealrx || n1)
12496                   {
12497                      if (!myfirst)
12498                      {
12499                          x = 0;
12500                          AST_LIST_TRAVERSE(&l->rxq, f1,
12501                         frame_list) x++;
12502                          for(;x < myrpt->p.simplexphonedelay; x++)
12503                         {
12504                            f1 = ast_frdup(f);
12505                            memset(f1->data.ptr,0,f1->datalen);
12506                            AST_LIST_INSERT_TAIL(&l->rxq,
12507                               f1,frame_list);
12508                          }
12509                          myfirst = 1;
12510                      }
12511                      f1 = ast_frdup(f);
12512                      AST_LIST_INSERT_TAIL(&l->rxq,f1,frame_list);
12513                   } else myfirst = 0; 
12514                   x = 0;
12515                   AST_LIST_TRAVERSE(&l->rxq, f1,frame_list) x++;
12516                   if (!x)
12517                   {
12518                      memset(f->data.ptr,0,f->datalen);
12519                   }
12520                   else
12521                   {
12522                      ast_frfree(f);
12523                      f = AST_LIST_REMOVE_HEAD(&l->rxq,frame_list);
12524                   }
12525                   if (ioctl(l->chan->fds[0], DAHDI_GETCONFMUTE, &ismuted) == -1)
12526                   {
12527                      ismuted = 0;
12528                   }
12529                   /* if not receiving, zero-out audio */
12530                   ismuted |= (!l->lastrx);
12531                   if (l->dtmfed && l->phonemode) ismuted = 1;
12532                   l->dtmfed = 0;
12533                   if (ismuted)
12534                   {
12535                      memset(f->data.ptr,0,f->datalen);
12536                      if (l->lastf1)
12537                         memset(l->lastf1->data.ptr,0,l->lastf1->datalen);
12538                      if (l->lastf2)
12539                         memset(l->lastf2->data.ptr,0,l->lastf2->datalen);
12540                   } 
12541                   if (f) f2 = ast_frdup(f);
12542                   else f2 = NULL;
12543                   f1 = l->lastf2;
12544                   l->lastf2 = l->lastf1;
12545                   l->lastf1 = f2;
12546                   if (ismuted)
12547                   {
12548                      if (l->lastf1)
12549                         memset(l->lastf1->data.ptr,0,l->lastf1->datalen);
12550                      if (l->lastf2)
12551                         memset(l->lastf2->data.ptr,0,l->lastf2->datalen);
12552                   }
12553                   if (f1)
12554                   {
12555                      ast_write(l->pchan,f1);
12556                      ast_frfree(f1);
12557                   }
12558                }
12559                else
12560                {
12561                   if (!l->lastrx)
12562                      memset(f->data.ptr,0,f->datalen);
12563                   ast_write(l->pchan,f);
12564                }
12565             }
12566 #ifndef  OLD_ASTERISK
12567             else if (f->frametype == AST_FRAME_DTMF_BEGIN)
12568             {
12569                if (l->lastf1)
12570                   memset(l->lastf1->data.ptr,0,l->lastf1->datalen);
12571                if (l->lastf2)
12572                   memset(l->lastf2->data.ptr,0,l->lastf2->datalen);
12573                l->dtmfed = 1;
12574             }
12575 #endif
12576             if (f->frametype == AST_FRAME_TEXT)
12577             {
12578                handle_link_data(myrpt,l,f->data.ptr);
12579             }
12580             if (f->frametype == AST_FRAME_DTMF)
12581             {
12582                if (l->lastf1)
12583                   memset(l->lastf1->data.ptr,0,l->lastf1->datalen);
12584                if (l->lastf2)
12585                   memset(l->lastf2->data.ptr,0,l->lastf2->datalen);
12586                l->dtmfed = 1;
12587                handle_link_phone_dtmf(myrpt,l,f->subclass);
12588             }
12589             if (f->frametype == AST_FRAME_CONTROL)
12590             {
12591                if (f->subclass == AST_CONTROL_ANSWER)
12592                {
12593                   char lconnected = l->connected;
12594 
12595                   __kickshort(myrpt);
12596                   l->connected = 1;
12597                   l->hasconnected = 1;
12598                   l->thisconnected = 1;
12599                   l->elaptime = -1;
12600                   if (!l->phonemode) send_newkey(l->chan);
12601                   if (!l->isremote) l->retries = 0;
12602                   if (!lconnected) 
12603                   {
12604                      rpt_telemetry(myrpt,CONNECTED,l);
12605                      if (myrpt->p.archivedir)
12606                      {
12607                         char str[100];
12608 
12609                         if (l->mode)
12610                            sprintf(str,"LINKTRX,%s",l->name);
12611                         else
12612                            sprintf(str,"LINKMONITOR,%s",l->name);
12613                         donodelog(myrpt,str);
12614                      }
12615                   }     
12616                   else
12617                      l->reconnects++;
12618                }
12619                /* if RX key */
12620                if (f->subclass == AST_CONTROL_RADIO_KEY)
12621                {
12622                   if (debug == 7 ) printf("@@@@ rx key\n");
12623                   l->lastrealrx = 1;
12624                   l->rerxtimer = 0;
12625                   if (!l->lastrx1)
12626                   {
12627                      if (myrpt->p.archivedir)
12628                      {
12629                         char str[100];
12630 
12631                         sprintf(str,"RXKEY,%s",l->name);
12632                         donodelog(myrpt,str);
12633                      }
12634                      l->lastrx1 = 1;
12635                   }
12636                }
12637                /* if RX un-key */
12638                if (f->subclass == AST_CONTROL_RADIO_UNKEY)
12639                {
12640                   if (debug == 7) printf("@@@@ rx un-key\n");
12641                   l->lastrealrx = 0;
12642                   l->rerxtimer = 0;
12643                   if (l->lastrx1)
12644                   {
12645                      if (myrpt->p.archivedir)
12646                      {
12647                         char str[100];
12648 
12649                         sprintf(str,"RXUNKEY,%s",l->name);
12650                         donodelog(myrpt,str);
12651                      }
12652                      l->lastrx1 = 0;
12653                      if(myrpt->p.duplex) 
12654                         rpt_telemetry(myrpt,LINKUNKEY,l);
12655                   }
12656                }
12657                if (f->subclass == AST_CONTROL_HANGUP)
12658                {
12659                   ast_frfree(f);
12660                   rpt_mutex_lock(&myrpt->lock);
12661                   __kickshort(myrpt);
12662                   rpt_mutex_unlock(&myrpt->lock);
12663                   if ((!l->outbound) && (!l->disced))
12664                   {
12665                      if ((l->name[0] == '0') || l->isremote)
12666                         l->disctime = 1;
12667                      else
12668                         l->disctime = DISC_TIME;
12669                      rpt_mutex_lock(&myrpt->lock);
12670                      ast_hangup(l->chan);
12671                      l->chan = 0;
12672                      break;
12673                   }
12674                   if (l->retrytimer) 
12675                   {
12676                      if (l->chan) ast_hangup(l->chan);
12677                      l->chan = 0;
12678                      rpt_mutex_lock(&myrpt->lock);
12679                      break;
12680                   }
12681                   if (l->outbound && (l->retries++ < l->max_retries) && (l->hasconnected))
12682                   {
12683                      rpt_mutex_lock(&myrpt->lock);
12684                      if (l->chan) ast_hangup(l->chan);
12685                      l->chan = 0;
12686                      l->hasconnected = 1;
12687                      l->elaptime = 0;
12688                      l->retrytimer = RETRY_TIMER_MS;
12689                      l->connecttime = 0;
12690                      l->thisconnected = 0;
12691                      break;
12692                   }
12693                   rpt_mutex_lock(&myrpt->lock);
12694                   /* remove from queue */
12695                   remque((struct qelem *) l);
12696                   if (!strcmp(myrpt->cmdnode,l->name))
12697                      myrpt->cmdnode[0] = 0;
12698                   __kickshort(myrpt);
12699                   rpt_mutex_unlock(&myrpt->lock);
12700                   if (!l->hasconnected)
12701                      rpt_telemetry(myrpt,CONNFAIL,l);
12702                   else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l);
12703                   if (myrpt->p.archivedir)
12704                   {
12705                      char str[100];
12706 
12707                      if (!l->hasconnected)
12708                         sprintf(str,"LINKFAIL,%s",l->name);
12709                      else
12710                         sprintf(str,"LINKDISC,%s",l->name);
12711                      donodelog(myrpt,str);
12712                   }
12713                   if (l->lastf1) ast_frfree(l->lastf1);
12714                   l->lastf1 = NULL;
12715                   if (l->lastf2) ast_frfree(l->lastf2);
12716                   l->lastf2 = NULL;
12717                   /* hang-up on call to device */
12718                   ast_hangup(l->chan);
12719                   ast_hangup(l->pchan);
12720                   ast_free(l);
12721                   rpt_mutex_lock(&myrpt->lock);
12722                   break;
12723                }
12724             }
12725             ast_frfree(f);
12726             rpt_mutex_lock(&myrpt->lock);
12727             break;
12728          }
12729          if (who == l->pchan) 
12730          {
12731             rpt_mutex_unlock(&myrpt->lock);
12732             f = ast_read(l->pchan);
12733             if (!f)
12734             {
12735                if (debug) printf("@@@@ rpt:Hung Up\n");
12736                toexit = 1;
12737                rpt_mutex_lock(&myrpt->lock);
12738                break;
12739             }
12740             if (f->frametype == AST_FRAME_VOICE)
12741             {
12742                if (l->chan) ast_write(l->chan,f);
12743             }
12744             if (f->frametype == AST_FRAME_CONTROL)
12745             {
12746                if (f->subclass == AST_CONTROL_HANGUP)
12747                {
12748                   if (debug) printf("@@@@ rpt:Hung Up\n");
12749                   ast_frfree(f);
12750                   toexit = 1;
12751                   rpt_mutex_lock(&myrpt->lock);
12752                   break;
12753                }
12754             }
12755             ast_frfree(f);
12756             rpt_mutex_lock(&myrpt->lock);
12757             break;
12758          }
12759          l = l->next;
12760       }
12761       rpt_mutex_unlock(&myrpt->lock);
12762       if (toexit) break;
12763       if (who == myrpt->monchannel) 
12764       {
12765          f = ast_read(myrpt->monchannel);
12766          if (!f)
12767          {
12768             if (debug) printf("@@@@ rpt:Hung Up\n");
12769             break;
12770          }
12771          if (f->frametype == AST_FRAME_VOICE)
12772          {
12773             if (myrpt->monstream) 
12774                ast_writestream(myrpt->monstream,f);
12775          }
12776          if (f->frametype == AST_FRAME_CONTROL)
12777          {
12778             if (f->subclass == AST_CONTROL_HANGUP)
12779             {
12780                if (debug) printf("@@@@ rpt:Hung Up\n");
12781                ast_frfree(f);
12782                break;
12783             }
12784          }
12785          ast_frfree(f);
12786          continue;
12787       }
12788       if (myrpt->parrotchannel && (who == myrpt->parrotchannel))
12789       {
12790          f = ast_read(myrpt->parrotchannel);
12791          if (!f)
12792          {
12793             if (debug) printf("@@@@ rpt:Hung Up\n");
12794             break;
12795          }
12796          if (!myrpt->p.parrotmode)
12797          {
12798             char myfname[300];
12799 
12800             if (myrpt->parrotstream)
12801             {
12802                ast_closestream(myrpt->parrotstream);
12803                myrpt->parrotstream = 0;
12804             }
12805             sprintf(myfname,PARROTFILE,myrpt->name,myrpt->parrotcnt);
12806             strcat(myfname,".wav");
12807             unlink(myfname);        
12808          } else if (f->frametype == AST_FRAME_VOICE)
12809          {
12810             if (myrpt->parrotstream) 
12811                ast_writestream(myrpt->parrotstream,f);
12812          }
12813          if (f->frametype == AST_FRAME_CONTROL)
12814          {
12815             if (f->subclass == AST_CONTROL_HANGUP)
12816             {
12817                if (debug) printf("@@@@ rpt:Hung Up\n");
12818                ast_frfree(f);
12819                break;
12820             }
12821          }
12822          ast_frfree(f);
12823          continue;
12824       }
12825       if (myrpt->voxchannel && (who == myrpt->voxchannel))
12826       {
12827          f = ast_read(myrpt->voxchannel);
12828          if (!f)
12829          {
12830             if (debug) printf("@@@@ rpt:Hung Up\n");
12831             break;
12832          }
12833          if (f->frametype == AST_FRAME_VOICE)
12834          {
12835             n = dovox(&myrpt->vox,f->data.ptr,f->datalen / 2);
12836             if (n != myrpt->wasvox)
12837             {
12838                if (debug) ast_log(LOG_DEBUG,"Node %s, vox %d\n",myrpt->name,n);
12839                myrpt->wasvox = n;
12840                myrpt->voxtostate = 0;
12841                if (n) myrpt->voxtotimer = myrpt->p.voxtimeout_ms;
12842                else myrpt->voxtotimer = 0;
12843             }
12844          }
12845          if (f->frametype == AST_FRAME_CONTROL)
12846          {
12847             if (f->subclass == AST_CONTROL_HANGUP)
12848             {
12849                if (debug) printf("@@@@ rpt:Hung Up\n");
12850                ast_frfree(f);
12851                break;
12852             }
12853          }
12854          ast_frfree(f);
12855          continue;
12856       }
12857       if (who == myrpt->txpchannel) /* if it was a read from remote tx */
12858       {
12859          f = ast_read(myrpt->txpchannel);
12860          if (!f)
12861          {
12862             if (debug) printf("@@@@ rpt:Hung Up\n");
12863             break;
12864          }
12865          if (f->frametype == AST_FRAME_CONTROL)
12866          {
12867             if (f->subclass == AST_CONTROL_HANGUP)
12868             {
12869                if (debug) printf("@@@@ rpt:Hung Up\n");
12870                ast_frfree(f);
12871                break;
12872             }
12873          }
12874          ast_frfree(f);
12875          continue;
12876       }
12877    }
12878    usleep(100000);
12879    ast_hangup(myrpt->pchannel);
12880    ast_hangup(myrpt->monchannel);
12881    if (myrpt->parrotchannel) ast_hangup(myrpt->parrotchannel);
12882    myrpt->parrotstate = 0;
12883    if (myrpt->voxchannel) ast_hangup(myrpt->voxchannel);
12884    ast_hangup(myrpt->txpchannel);
12885    if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel);
12886    if (myrpt->dahditxchannel != myrpt->txchannel) ast_hangup(myrpt->dahditxchannel);
12887    if (myrpt->lastf1) ast_frfree(myrpt->lastf1);
12888    myrpt->lastf1 = NULL;
12889    if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
12890    myrpt->lastf2 = NULL;
12891    ast_hangup(myrpt->rxchannel);
12892    rpt_mutex_lock(&myrpt->lock);
12893    l = myrpt->links.next;
12894    while(l != &myrpt->links)
12895    {
12896       struct rpt_link *ll = l;
12897       /* remove from queue */
12898       remque((struct qelem *) l);
12899       /* hang-up on call to device */
12900       if (l->chan) ast_hangup(l->chan);
12901       ast_hangup(l->pchan);
12902       l = l->next;
12903       ast_free(ll);
12904    }
12905    if (myrpt->xlink  == 1) myrpt->xlink = 2;
12906    rpt_mutex_unlock(&myrpt->lock);
12907    if (debug) printf("@@@@ rpt:Hung up channel\n");
12908    myrpt->rpt_thread = AST_PTHREADT_STOP;
12909    pthread_exit(NULL); 
12910    return NULL;
12911 }

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

Definition at line 5287 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_free, 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, ast_strdup, rpt::calldigittimer, rpt::callmode, ast_channel::cdr, channel_revert(), 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, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macropatch, MSWAIT, rpt::mydtmf, name, rpt::ourcallerid, rpt::p, PATCH_DIALPLAN_TIMEOUT, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchquiet, ast_channel::pbx, rpt::pchannel, ast_channel::priority, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), ast_frame::subclass, TERM, rpt::tonezone, and rpt::voxchannel.

Referenced by function_autopatchup(), and local_dtmf_helper().

05288 {
05289 struct dahdi_confinfo ci;  /* conference info */
05290 struct   rpt *myrpt = (struct rpt *)this;
05291 int   res;
05292 int stopped,congstarted,dialtimer,lastcidx,aborted;
05293 struct ast_channel *mychannel,*genchannel;
05294 
05295    myrpt->mydtmf = 0;
05296    /* allocate a pseudo-channel thru asterisk */
05297    mychannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
05298    if (!mychannel)
05299    {
05300       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
05301       pthread_exit(NULL);
05302    }
05303 #ifdef   AST_CDR_FLAG_POST_DISABLED
05304    if (mychannel->cdr)
05305       ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED);
05306 #endif
05307    ci.chan = 0;
05308    ci.confno = myrpt->conf; /* use the pseudo conference */
05309 #if   0
05310    ci.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER
05311       | DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 
05312 #endif
05313    ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER;
05314    /* first put the channel on the conference */
05315    if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1)
05316    {
05317       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
05318       ast_hangup(mychannel);
05319       myrpt->callmode = 0;
05320       pthread_exit(NULL);
05321    }
05322    /* allocate a pseudo-channel thru asterisk */
05323    genchannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
05324    if (!genchannel)
05325    {
05326       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
05327       ast_hangup(mychannel);
05328       pthread_exit(NULL);
05329    }
05330 #ifdef   AST_CDR_FLAG_POST_DISABLED
05331    if (genchannel->cdr)
05332       ast_set_flag(genchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
05333 #endif
05334    ci.chan = 0;
05335    ci.confno = myrpt->conf;
05336    ci.confmode = DAHDI_CONF_REALANDPSEUDO | DAHDI_CONF_TALKER | DAHDI_CONF_LISTENER
05337       | DAHDI_CONF_PSEUDO_TALKER | DAHDI_CONF_PSEUDO_LISTENER; 
05338    /* first put the channel on the conference */
05339    if (ioctl(genchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
05340    {
05341       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
05342       ast_hangup(mychannel);
05343       ast_hangup(genchannel);
05344       myrpt->callmode = 0;
05345       pthread_exit(NULL);
05346    }
05347    if (myrpt->p.tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->p.tonezone) == -1))
05348    {
05349       ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone);
05350       ast_hangup(mychannel);
05351       ast_hangup(genchannel);
05352       myrpt->callmode = 0;
05353       pthread_exit(NULL);
05354    }
05355    if (myrpt->p.tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->p.tonezone) == -1))
05356    {
05357       ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone);
05358       ast_hangup(mychannel);
05359       ast_hangup(genchannel);
05360       myrpt->callmode = 0;
05361       pthread_exit(NULL);
05362    }
05363    /* start dialtone if patchquiet is 0. Special patch modes don't send dial tone */
05364    if ((!myrpt->patchquiet) && (tone_zone_play_tone(genchannel->fds[0],DAHDI_TONE_DIALTONE) < 0))
05365    {
05366       ast_log(LOG_WARNING, "Cannot start dialtone\n");
05367       ast_hangup(mychannel);
05368       ast_hangup(genchannel);
05369       myrpt->callmode = 0;
05370       pthread_exit(NULL);
05371    }
05372    stopped = 0;
05373    congstarted = 0;
05374    dialtimer = 0;
05375    lastcidx = 0;
05376    myrpt->calldigittimer = 0;
05377    aborted = 0;
05378 
05379    while ((myrpt->callmode == 1) || (myrpt->callmode == 4))
05380    {
05381       if((myrpt->patchdialtime)&&(myrpt->callmode == 1)&&(myrpt->cidx != lastcidx)){
05382          dialtimer = 0;
05383          lastcidx = myrpt->cidx;
05384       }     
05385 
05386       if((myrpt->patchdialtime)&&(dialtimer >= myrpt->patchdialtime)){ 
05387           if(debug)
05388             ast_log(LOG_NOTICE, "dialtimer %i > patchdialtime %i\n", dialtimer,myrpt->patchdialtime);
05389          rpt_mutex_lock(&myrpt->lock);
05390          aborted = 1;
05391          myrpt->callmode = 0;
05392          rpt_mutex_unlock(&myrpt->lock);
05393          break;
05394       }
05395    
05396       if ((!myrpt->patchquiet) && (!stopped) && (myrpt->callmode == 1) && (myrpt->cidx > 0))
05397       {
05398          stopped = 1;
05399          /* stop dial tone */
05400          tone_zone_play_tone(genchannel->fds[0],-1);
05401       }
05402       if (myrpt->callmode == 1)
05403       {
05404          if(myrpt->calldigittimer > PATCH_DIALPLAN_TIMEOUT)
05405          {
05406             myrpt->callmode = 2;
05407             break;
05408          }
05409          /* bump timer if active */
05410          if (myrpt->calldigittimer) 
05411             myrpt->calldigittimer += MSWAIT;
05412       }
05413       if (myrpt->callmode == 4)
05414       {
05415          if(!congstarted){
05416             congstarted = 1;
05417             /* start congestion tone */
05418             tone_zone_play_tone(genchannel->fds[0],DAHDI_TONE_CONGESTION);
05419          }
05420       }
05421       res = ast_safe_sleep(mychannel, MSWAIT);
05422       if (res < 0)
05423       {
05424           if(debug)
05425             ast_log(LOG_NOTICE, "ast_safe_sleep=%i\n", res);
05426          ast_hangup(mychannel);
05427          ast_hangup(genchannel);
05428          rpt_mutex_lock(&myrpt->lock);
05429          myrpt->callmode = 0;
05430          rpt_mutex_unlock(&myrpt->lock);
05431          pthread_exit(NULL);
05432       }
05433       dialtimer += MSWAIT;
05434    }
05435    /* stop any tone generation */
05436    tone_zone_play_tone(genchannel->fds[0],-1);
05437    /* end if done */
05438    if (!myrpt->callmode)
05439    {
05440       if(debug)
05441          ast_log(LOG_NOTICE, "callmode==0\n");
05442       ast_hangup(mychannel);
05443       ast_hangup(genchannel);
05444       rpt_mutex_lock(&myrpt->lock);
05445       myrpt->callmode = 0;
05446       myrpt->macropatch=0;
05447       channel_revert(myrpt);
05448       rpt_mutex_unlock(&myrpt->lock);
05449       if((!myrpt->patchquiet) && aborted)
05450          rpt_telemetry(myrpt, TERM, NULL);
05451       pthread_exit(NULL);        
05452    }
05453 
05454    if (myrpt->p.ourcallerid && *myrpt->p.ourcallerid){
05455       char *name, *loc, *instr;
05456       instr = ast_strdup(myrpt->p.ourcallerid);
05457       if(instr){
05458          ast_callerid_parse(instr, &name, &loc);
05459          if(loc){
05460             if(mychannel->cid.cid_num)
05461                ast_free(mychannel->cid.cid_num);
05462             mychannel->cid.cid_num = ast_strdup(loc);
05463          }
05464          if(name){
05465             if(mychannel->cid.cid_name)
05466                ast_free(mychannel->cid.cid_name);
05467             mychannel->cid.cid_name = ast_strdup(name);
05468          }
05469          ast_free(instr);
05470       }
05471    }
05472 
05473    ast_copy_string(mychannel->exten, myrpt->exten, sizeof(mychannel->exten) - 1);
05474    ast_copy_string(mychannel->context, myrpt->patchcontext, sizeof(mychannel->context) - 1);
05475    
05476    if (myrpt->p.acctcode)
05477       ast_cdr_setaccount(mychannel,myrpt->p.acctcode);
05478    mychannel->priority = 1;
05479    ast_channel_undefer_dtmf(mychannel);
05480    if (ast_pbx_start(mychannel) < 0)
05481    {
05482       ast_log(LOG_WARNING, "Unable to start PBX!!\n");
05483       ast_hangup(mychannel);
05484       ast_hangup(genchannel);
05485       rpt_mutex_lock(&myrpt->lock);
05486       myrpt->callmode = 0;
05487       rpt_mutex_unlock(&myrpt->lock);
05488       pthread_exit(NULL);
05489    }
05490    usleep(10000);
05491    rpt_mutex_lock(&myrpt->lock);
05492    myrpt->callmode = 3;
05493    /* set appropriate conference for the pseudo */
05494    ci.chan = 0;
05495    ci.confno = myrpt->conf;
05496    ci.confmode = (myrpt->p.duplex == 2) ? DAHDI_CONF_CONFANNMON :
05497       (DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER);
05498    /* first put the channel on the conference in announce mode */
05499    if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
05500    {
05501       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
05502       ast_hangup(mychannel);
05503       ast_hangup(genchannel);
05504       myrpt->callmode = 0;
05505       pthread_exit(NULL);
05506    }
05507    /* get its channel number */
05508    if (ioctl(mychannel->fds[0],DAHDI_CHANNO,&res) == -1)
05509    {
05510       ast_log(LOG_WARNING, "Unable to get autopatch channel number\n");
05511       ast_hangup(mychannel);
05512       myrpt->callmode = 0;
05513       pthread_exit(NULL);
05514    }
05515    ci.chan = 0;
05516    ci.confno = res;
05517    ci.confmode = DAHDI_CONF_MONITOR;
05518    /* put vox channel monitoring on the channel  */
05519    if (ioctl(myrpt->voxchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
05520    {
05521       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
05522       ast_hangup(mychannel);
05523       myrpt->callmode = 0;
05524       pthread_exit(NULL);
05525    }
05526    while(myrpt->callmode)
05527    {
05528       if ((!mychannel->pbx) && (myrpt->callmode != 4))
05529       {
05530           /* If patch is setup for far end disconnect */
05531          if(myrpt->patchfarenddisconnect || (myrpt->p.duplex < 2)){ 
05532             if(debug)ast_log(LOG_NOTICE,"callmode=%i, patchfarenddisconnect=%i, duplex=%i\n",\
05533                   myrpt->callmode,myrpt->patchfarenddisconnect,myrpt->p.duplex);
05534             myrpt->callmode = 0;
05535             myrpt->macropatch=0;
05536             if(!myrpt->patchquiet){
05537                rpt_mutex_unlock(&myrpt->lock);
05538                rpt_telemetry(myrpt, TERM, NULL);
05539                rpt_mutex_lock(&myrpt->lock);
05540             }
05541          }
05542          else{ /* Send congestion until patch is downed by command */
05543             myrpt->callmode = 4;
05544             rpt_mutex_unlock(&myrpt->lock);
05545             /* start congestion tone */
05546             tone_zone_play_tone(genchannel->fds[0],DAHDI_TONE_CONGESTION);
05547             rpt_mutex_lock(&myrpt->lock);
05548          }
05549       }
05550       if (myrpt->mydtmf)
05551       {
05552          struct ast_frame wf = {AST_FRAME_DTMF, } ;
05553          wf.subclass = myrpt->mydtmf;
05554          rpt_mutex_unlock(&myrpt->lock);
05555          ast_queue_frame(mychannel,&wf);
05556 #ifdef   NEW_ASTERISK
05557          ast_senddigit(genchannel,myrpt->mydtmf,0);
05558 #else
05559          ast_senddigit(genchannel,myrpt->mydtmf);
05560 #endif
05561          rpt_mutex_lock(&myrpt->lock);
05562          myrpt->mydtmf = 0;
05563       }
05564       rpt_mutex_unlock(&myrpt->lock);
05565       usleep(MSWAIT * 1000);
05566       rpt_mutex_lock(&myrpt->lock);
05567    }
05568    if(debug)
05569       ast_log(LOG_NOTICE, "exit channel loop\n");
05570    rpt_mutex_unlock(&myrpt->lock);
05571    tone_zone_play_tone(genchannel->fds[0],-1);
05572    if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV);
05573    ast_hangup(genchannel);
05574    rpt_mutex_lock(&myrpt->lock);
05575    myrpt->callmode = 0;
05576    myrpt->macropatch=0;
05577    channel_revert(myrpt);
05578    rpt_mutex_unlock(&myrpt->lock);
05579    /* set appropriate conference for the pseudo */
05580    ci.chan = 0;
05581    ci.confno = myrpt->conf;
05582    ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? DAHDI_CONF_CONFANNMON :
05583       (DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER);
05584    /* first put the channel on the conference in announce mode */
05585    if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
05586    {
05587       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
05588    }
05589    pthread_exit(NULL);
05590 }

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

Definition at line 3182 of file app_rpt.c.

References ast_cli(), CMD_STATE_BUSY, CMD_STATE_IDLE, CMD_STATE_READY, rpt::cmdAction, rpt_cmd_struct::digits, function_table, rpt::lock, MAXDTMF, name, rpt_cmd_struct::param, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, SOURCE_RPT, and rpt_cmd_struct::state.

Referenced by handle_cli_cmd().

03183 {
03184    int i, l;
03185    int busy=0;
03186    int maxActions = sizeof(function_table)/sizeof(struct function_table_tag);
03187 
03188    int thisRpt = -1;
03189    int thisAction = -1;
03190    struct rpt *myrpt = NULL;
03191    if (argc != 6) return RESULT_SHOWUSAGE;
03192    
03193    for(i = 0; i < nrpts; i++)
03194    {
03195       if(!strcmp(argv[2], rpt_vars[i].name))
03196       {
03197          thisRpt = i;
03198          myrpt = &rpt_vars[i];
03199          break;
03200       } /* if !strcmp... */
03201    } /* for i */
03202 
03203    if (thisRpt < 0)
03204    {
03205       ast_cli(fd, "Unknown node number %s.\n", argv[2]);
03206       return RESULT_FAILURE;
03207    } /* if thisRpt < 0 */
03208    
03209    /* Look up the action */
03210    l = strlen(argv[3]);
03211    for(i = 0 ; i < maxActions; i++)
03212    {
03213       if(!strncasecmp(argv[3], function_table[i].action, l))
03214       {
03215          thisAction = i;
03216          break;
03217       } /* if !strncasecmp... */
03218    } /* for i */
03219    
03220    if (thisAction < 0)
03221    {
03222       ast_cli(fd, "Unknown action name %s.\n", argv[3]);
03223       return RESULT_FAILURE;
03224    } /* if thisAction < 0 */
03225 
03226    /* at this point, it looks like all the arguments make sense... */
03227 
03228    rpt_mutex_lock(&myrpt->lock);
03229 
03230    if (rpt_vars[thisRpt].cmdAction.state == CMD_STATE_IDLE)
03231    {
03232       rpt_vars[thisRpt].cmdAction.state = CMD_STATE_BUSY;
03233       rpt_vars[thisRpt].cmdAction.functionNumber = thisAction;
03234       strncpy(rpt_vars[thisRpt].cmdAction.param, argv[4], MAXDTMF);
03235       strncpy(rpt_vars[thisRpt].cmdAction.digits, argv[5], MAXDTMF);
03236       rpt_vars[thisRpt].cmdAction.command_source = SOURCE_RPT;
03237       rpt_vars[thisRpt].cmdAction.state = CMD_STATE_READY;
03238    } /* if (rpt_vars[thisRpt].cmdAction.state == CMD_STATE_IDLE */
03239    else
03240    {
03241       busy = 1;
03242    } /* if (rpt_vars[thisRpt].cmdAction.state == CMD_STATE_IDLE */
03243    rpt_mutex_unlock(&myrpt->lock);
03244 
03245    return (busy ? RESULT_FAILURE : RESULT_SUCCESS);
03246 } /* rpt_do_cmd() */

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

Definition at line 2619 of file app_rpt.c.

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

Referenced by handle_cli_debug().

02620 {
02621    int newlevel;
02622 
02623         if (argc != 4)
02624                 return RESULT_SHOWUSAGE;
02625         newlevel = myatoi(argv[3]);
02626         if((newlevel < 0) || (newlevel > 7))
02627                 return RESULT_SHOWUSAGE;
02628         if(newlevel)
02629                 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
02630         else
02631                 ast_cli(fd, "app_rpt Debugging disabled\n");
02632 
02633         debug = newlevel;                                                                                                                          
02634         return RESULT_SUCCESS;
02635 }

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

Definition at line 2641 of file app_rpt.c.

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

Referenced by handle_cli_dump().

02642 {
02643    int i;
02644 
02645         if (argc != 3)
02646                 return RESULT_SHOWUSAGE;
02647 
02648    for(i = 0; i < nrpts; i++)
02649    {
02650       if (!strcmp(argv[2],rpt_vars[i].name))
02651       {
02652          rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
02653               ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]);
02654               return RESULT_SUCCESS;
02655       }
02656    }
02657    return RESULT_FAILURE;
02658 }

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

Definition at line 3104 of file app_rpt.c.

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

Referenced by handle_cli_fun().

03105 {
03106    int   i,busy=0;
03107 
03108         if (argc != 4) return RESULT_SHOWUSAGE;
03109 
03110    for(i = 0; i < nrpts; i++){
03111       if(!strcmp(argv[2], rpt_vars[i].name)){
03112          struct rpt *myrpt = &rpt_vars[i];
03113          rpt_mutex_lock(&myrpt->lock);
03114          if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(argv[3])){
03115             rpt_mutex_unlock(&myrpt->lock);
03116             busy=1;
03117          }
03118          if(!busy){
03119             myrpt->macrotimer = MACROTIME;
03120             strncat(myrpt->macrobuf,argv[3],MAXMACRO - 1);
03121          }
03122          rpt_mutex_unlock(&myrpt->lock);
03123       }
03124    }
03125    if(busy){
03126       ast_cli(fd, "Function decoder busy");
03127    }
03128    return RESULT_FAILURE;
03129 }

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

Definition at line 3164 of file app_rpt.c.

References name, RESULT_FAILURE, RESULT_SHOWUSAGE, and rpt_push_alt_macro().

Referenced by handle_cli_fun1().

03165 {
03166    int   i;
03167 
03168     if (argc != 4) return RESULT_SHOWUSAGE;
03169 
03170    for(i = 0; i < nrpts; i++){
03171       if(!strcmp(argv[2], rpt_vars[i].name)){
03172          struct rpt *myrpt = &rpt_vars[i];
03173          rpt_push_alt_macro(myrpt,argv[3]);
03174       }
03175    }
03176    return RESULT_FAILURE;
03177 }

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

Definition at line 3054 of file app_rpt.c.

References ast_cli(), name, and RESULT_SUCCESS.

Referenced by handle_cli_local_nodes().

03055 {
03056 
03057     int i;
03058     ast_cli(fd, "\nNode\n----\n");
03059     for (i=0; i< nrpts; i++)
03060     {
03061         ast_cli(fd, "%s\n", rpt_vars[i].name);        
03062     } /* for i */
03063     ast_cli(fd,"\n");
03064     return RESULT_SUCCESS;
03065 } 

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

Definition at line 2914 of file app_rpt.c.

References ast_cli(), ast_free, ast_log(), ast_malloc, rpt_link::chan, rpt_link::chan_stat, rpt_lstat::connecttime, rpt_link::connecttime, rpt::links, rpt::lock, LOG_ERROR, 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, s, and rpt_link::thisconnected.

Referenced by handle_cli_lstats().

02915 {
02916    int i,j;
02917    char *connstate;
02918    struct rpt *myrpt;
02919    struct rpt_link *l;
02920    struct rpt_lstat *s,*t;
02921    struct rpt_lstat s_head;
02922    if(argc != 3)
02923       return RESULT_SHOWUSAGE;
02924 
02925    s = NULL;
02926    s_head.next = &s_head;
02927    s_head.prev = &s_head;
02928 
02929    for(i = 0; i < nrpts; i++)
02930    {
02931       if (!strcmp(argv[2],rpt_vars[i].name)){
02932          /* Make a copy of all stat variables while locked */
02933          myrpt = &rpt_vars[i];
02934          rpt_mutex_lock(&myrpt->lock); /* LOCK */
02935          /* Traverse the list of connected nodes */
02936          j = 0;
02937          l = myrpt->links.next;
02938          while(l && (l != &myrpt->links)){
02939             if (l->name[0] == '0'){ /* Skip '0' nodes */
02940                l = l->next;
02941                continue;
02942             }
02943             if((s = (struct rpt_lstat *) ast_malloc(sizeof(struct rpt_lstat))) == NULL){
02944                ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n");
02945                rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02946                return RESULT_FAILURE;
02947             }
02948             memset(s, 0, sizeof(struct rpt_lstat));
02949             strncpy(s->name, l->name, MAXREMSTR - 1);
02950             if (l->chan) pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1);
02951             else strcpy(s->peer,"(none)");
02952             s->mode = l->mode;
02953             s->outbound = l->outbound;
02954             s->reconnects = l->reconnects;
02955             s->connecttime = l->connecttime;
02956             s->thisconnected = l->thisconnected;
02957             memcpy(s->chan_stat,l->chan_stat,NRPTSTAT * sizeof(struct rpt_chan_stat));
02958             insque((struct qelem *) s, (struct qelem *) s_head.next);
02959             memset(l->chan_stat,0,NRPTSTAT * sizeof(struct rpt_chan_stat));
02960             l = l->next;
02961          }
02962          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02963          ast_cli(fd, "NODE      PEER                RECONNECTS  DIRECTION  CONNECT TIME        CONNECT STATE\n");
02964          ast_cli(fd, "----      ----                ----------  ---------  ------------        -------------\n");
02965 
02966          for(s = s_head.next; s != &s_head; s = s->next){
02967             int hours, minutes, seconds;
02968             long long connecttime = s->connecttime;
02969             char conntime[21];
02970             hours = (int) connecttime/3600000;
02971             connecttime %= 3600000;
02972             minutes = (int) connecttime/60000;
02973             connecttime %= 60000;
02974             seconds = (int)  connecttime/1000;
02975             connecttime %= 1000;
02976             snprintf(conntime, 20, "%02d:%02d:%02d.%d",
02977                hours, minutes, seconds, (int) connecttime);
02978             conntime[20] = 0;
02979             if(s->thisconnected)
02980                connstate  = "ESTABLISHED";
02981             else
02982                connstate = "CONNECTING";
02983             ast_cli(fd, "%-10s%-20s%-12d%-11s%-20s%-20s\n",
02984                s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime, connstate);
02985          }  
02986          /* destroy our local link queue */
02987          s = s_head.next;
02988          while(s != &s_head){
02989             t = s;
02990             s = s->next;
02991             remque((struct qelem *)t);
02992             ast_free(t);
02993          }        
02994          return RESULT_SUCCESS;
02995       }
02996    }
02997    return RESULT_FAILURE;
02998 }

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

Definition at line 3004 of file app_rpt.c.

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

Referenced by handle_cli_nodes().

03005 {
03006    int i,j;
03007    char ns;
03008    char lbuf[MAXLINKLIST],*strs[MAXLINKLIST];
03009    struct rpt *myrpt;
03010    if(argc != 3)
03011       return RESULT_SHOWUSAGE;
03012 
03013    for(i = 0; i < nrpts; i++)
03014    {
03015       if (!strcmp(argv[2],rpt_vars[i].name)){
03016          /* Make a copy of all stat variables while locked */
03017          myrpt = &rpt_vars[i];
03018          rpt_mutex_lock(&myrpt->lock); /* LOCK */
03019          __mklinklist(myrpt,NULL,lbuf);
03020          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
03021          /* parse em */
03022          ns = finddelim(lbuf,strs,MAXLINKLIST);
03023          /* sort em */
03024          if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar);
03025          ast_cli(fd,"\n");
03026          ast_cli(fd, "************************* CONNECTED NODES *************************\n\n");
03027          for(j = 0 ;; j++){
03028             if(!strs[j]){
03029                if(!j){
03030                   ast_cli(fd,"<NONE>");
03031                }
03032                break;
03033             }
03034             ast_cli(fd, "%s", strs[j]);
03035             if(j % 8 == 7){
03036                ast_cli(fd, "\n");
03037             }
03038             else{
03039                if(strs[j + 1])
03040                   ast_cli(fd, ", ");
03041             }
03042          }
03043          ast_cli(fd,"\n\n");
03044          return RESULT_SUCCESS;
03045       }
03046    }
03047    return RESULT_FAILURE;
03048 }

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

Definition at line 3072 of file app_rpt.c.

References reload, RESULT_FAILURE, and RESULT_SHOWUSAGE.

Referenced by handle_cli_reload().

03073 {
03074 int   n;
03075 
03076         if (argc > 2) return RESULT_SHOWUSAGE;
03077 
03078    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
03079 
03080    return RESULT_FAILURE;
03081 }

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

Definition at line 3087 of file app_rpt.c.

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

Referenced by handle_cli_restart().

03088 {
03089 int   i;
03090 
03091         if (argc > 2) return RESULT_SHOWUSAGE;
03092    for(i = 0; i < nrpts; i++)
03093    {
03094       if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV);
03095    }
03096    return RESULT_FAILURE;
03097 }

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

Definition at line 2664 of file app_rpt.c.

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

Referenced by handle_cli_stats().

02665 {
02666    int i,j,numoflinks;
02667    int dailytxtime, dailykerchunks;
02668    time_t now;
02669    int totalkerchunks, dailykeyups, totalkeyups, timeouts;
02670    int totalexecdcommands, dailyexecdcommands, hours, minutes, seconds;
02671    int uptime;
02672    long long totaltxtime;
02673    struct   rpt_link *l;
02674    char *listoflinks[MAX_STAT_LINKS];  
02675    char *lastdtmfcommand,*parrot_ena;
02676    char *tot_state, *ider_state, *patch_state;
02677    char *reverse_patch_state, *sys_ena, *tot_ena, *link_ena, *patch_ena;
02678    char *sch_ena, *input_signal, *called_number, *user_funs, *tail_type;
02679    struct rpt *myrpt;
02680 
02681    static char *not_applicable = "N/A";
02682 
02683    if(argc != 3)
02684       return RESULT_SHOWUSAGE;
02685 
02686    tot_state = ider_state = 
02687    patch_state = reverse_patch_state = 
02688    input_signal = not_applicable;
02689    called_number = lastdtmfcommand = NULL;
02690 
02691    time(&now);
02692    for(i = 0; i < nrpts; i++)
02693    {
02694       if (!strcmp(argv[2],rpt_vars[i].name)){
02695          /* Make a copy of all stat variables while locked */
02696          myrpt = &rpt_vars[i];
02697          rpt_mutex_lock(&myrpt->lock); /* LOCK */
02698          uptime = (int)(now - starttime);
02699          dailytxtime = myrpt->dailytxtime;
02700          totaltxtime = myrpt->totaltxtime;
02701          dailykeyups = myrpt->dailykeyups;
02702          totalkeyups = myrpt->totalkeyups;
02703          dailykerchunks = myrpt->dailykerchunks;
02704          totalkerchunks = myrpt->totalkerchunks;
02705          dailyexecdcommands = myrpt->dailyexecdcommands;
02706          totalexecdcommands = myrpt->totalexecdcommands;
02707          timeouts = myrpt->timeouts;
02708 
02709          /* Traverse the list of connected nodes */
02710          reverse_patch_state = "DOWN";
02711          numoflinks = 0;
02712          l = myrpt->links.next;
02713          while(l && (l != &myrpt->links)){
02714             if(numoflinks >= MAX_STAT_LINKS){
02715                ast_log(LOG_NOTICE,
02716                "maximum number of links exceeds %d in rpt_do_stats()!",MAX_STAT_LINKS);
02717                break;
02718             }
02719             if (l->name[0] == '0'){ /* Skip '0' nodes */
02720                reverse_patch_state = "UP";
02721                l = l->next;
02722                continue;
02723             }
02724             listoflinks[numoflinks] = ast_strdup(l->name);
02725             if(listoflinks[numoflinks] == NULL){
02726                break;
02727             }
02728             else{
02729                numoflinks++;
02730             }
02731             l = l->next;
02732          }
02733 
02734          if(myrpt->keyed)
02735             input_signal = "YES";
02736          else
02737             input_signal = "NO";
02738 
02739          if(myrpt->p.parrotmode)
02740             parrot_ena = "ENABLED";
02741          else
02742             parrot_ena = "DISABLED";
02743 
02744          if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable)
02745             sys_ena = "DISABLED";
02746          else
02747             sys_ena = "ENABLED";
02748 
02749          if(myrpt->p.s[myrpt->p.sysstate_cur].totdisable)
02750             tot_ena = "DISABLED";
02751          else
02752             tot_ena = "ENABLED";
02753 
02754          if(myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable)
02755             link_ena = "DISABLED";
02756          else
02757             link_ena = "ENABLED";
02758 
02759          if(myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
02760             patch_ena = "DISABLED";
02761          else
02762             patch_ena = "ENABLED";
02763 
02764          if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable)
02765             sch_ena = "DISABLED";
02766          else
02767             sch_ena = "ENABLED";
02768 
02769          if(myrpt->p.s[myrpt->p.sysstate_cur].userfundisable)
02770             user_funs = "DISABLED";
02771          else
02772             user_funs = "ENABLED";
02773 
02774          if(myrpt->p.s[myrpt->p.sysstate_cur].alternatetail)
02775             tail_type = "ALTERNATE";
02776          else
02777             tail_type = "STANDARD";
02778 
02779          if(!myrpt->totimer)
02780             tot_state = "TIMED OUT!";
02781          else if(myrpt->totimer != myrpt->p.totime)
02782             tot_state = "ARMED";
02783          else
02784             tot_state = "RESET";
02785 
02786          if(myrpt->tailid)
02787             ider_state = "QUEUED IN TAIL";
02788          else if(myrpt->mustid)
02789             ider_state = "QUEUED FOR CLEANUP";
02790          else
02791             ider_state = "CLEAN";
02792 
02793          switch(myrpt->callmode){
02794             case 1:
02795                patch_state = "DIALING";
02796                break;
02797             case 2:
02798                patch_state = "CONNECTING";
02799                break;
02800             case 3:
02801                patch_state = "UP";
02802                break;
02803 
02804             case 4:
02805                patch_state = "CALL FAILED";
02806                break;
02807 
02808             default:
02809                patch_state = "DOWN";
02810          }
02811 
02812          if(strlen(myrpt->exten)){
02813             called_number = ast_strdup(myrpt->exten);
02814          }
02815 
02816          if(strlen(myrpt->lastdtmfcommand)){
02817             lastdtmfcommand = ast_strdup(myrpt->lastdtmfcommand);
02818          }
02819          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
02820 
02821          ast_cli(fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name);
02822          ast_cli(fd, "Selected system state............................: %d\n", myrpt->p.sysstate_cur);
02823          ast_cli(fd, "Signal on input..................................: %s\n", input_signal);
02824          ast_cli(fd, "System...........................................: %s\n", sys_ena);
02825          ast_cli(fd, "Parrot Mode......................................: %s\n", parrot_ena);
02826          ast_cli(fd, "Scheduler........................................: %s\n", sch_ena);
02827          ast_cli(fd, "Tail Time........................................: %s\n", tail_type);
02828          ast_cli(fd, "Time out timer...................................: %s\n", tot_ena);
02829          ast_cli(fd, "Time out timer state.............................: %s\n", tot_state);
02830          ast_cli(fd, "Time outs since system initialization............: %d\n", timeouts);
02831          ast_cli(fd, "Identifier state.................................: %s\n", ider_state);
02832          ast_cli(fd, "Kerchunks today..................................: %d\n", dailykerchunks);
02833          ast_cli(fd, "Kerchunks since system initialization............: %d\n", totalkerchunks);
02834          ast_cli(fd, "Keyups today.....................................: %d\n", dailykeyups);
02835          ast_cli(fd, "Keyups since system initialization...............: %d\n", totalkeyups);
02836          ast_cli(fd, "DTMF commands today..............................: %d\n", dailyexecdcommands);
02837          ast_cli(fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands);
02838          ast_cli(fd, "Last DTMF command executed.......................: %s\n", 
02839          (lastdtmfcommand && strlen(lastdtmfcommand)) ? lastdtmfcommand : not_applicable);
02840          hours = dailytxtime/3600000;
02841          dailytxtime %= 3600000;
02842          minutes = dailytxtime/60000;
02843          dailytxtime %= 60000;
02844          seconds = dailytxtime/1000;
02845          dailytxtime %= 1000;
02846 
02847          ast_cli(fd, "TX time today....................................: %02d:%02d:%02d.%d\n",
02848             hours, minutes, seconds, dailytxtime);
02849 
02850          hours = (int) totaltxtime/3600000;
02851          totaltxtime %= 3600000;
02852          minutes = (int) totaltxtime/60000;
02853          totaltxtime %= 60000;
02854          seconds = (int)  totaltxtime/1000;
02855          totaltxtime %= 1000;
02856 
02857          ast_cli(fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n",
02858              hours, minutes, seconds, (int) totaltxtime);
02859 
02860                         hours = uptime/3600;
02861                         uptime %= 3600;
02862                         minutes = uptime/60;
02863                         uptime %= 60;
02864 
02865                         ast_cli(fd, "Uptime...........................................: %02d:%02d:%02d\n",
02866                                 hours, minutes, uptime);
02867 
02868          ast_cli(fd, "Nodes currently connected to us..................: ");
02869                         if(!numoflinks){
02870                          ast_cli(fd,"<NONE>");
02871                         }
02872          else{
02873             for(j = 0 ;j < numoflinks; j++){
02874                ast_cli(fd, "%s", listoflinks[j]);
02875                if(j % 4 == 3){
02876                   ast_cli(fd, "\n");
02877                   ast_cli(fd, "                                                 : ");
02878                }  
02879                else{
02880                   if((numoflinks - 1) - j  > 0)
02881                      ast_cli(fd, ", ");
02882                }
02883             }
02884          }
02885          ast_cli(fd,"\n");
02886 
02887          ast_cli(fd, "Autopatch........................................: %s\n", patch_ena);
02888          ast_cli(fd, "Autopatch state..................................: %s\n", patch_state);
02889          ast_cli(fd, "Autopatch called number..........................: %s\n",
02890          (called_number && strlen(called_number)) ? called_number : not_applicable);
02891          ast_cli(fd, "Reverse patch/IAXRPT connected...................: %s\n", reverse_patch_state);
02892          ast_cli(fd, "User linking commands............................: %s\n", link_ena);
02893          ast_cli(fd, "User functions...................................: %s\n\n", user_funs);
02894 
02895          for(j = 0; j < numoflinks; j++){ /* ast_free() all link names */
02896             ast_free(listoflinks[j]);
02897          }
02898          if(called_number){
02899             ast_free(called_number);
02900          }
02901          if(lastdtmfcommand){
02902             ast_free(lastdtmfcommand);
02903          }
02904               return RESULT_SUCCESS;
02905       }
02906    }
02907    return RESULT_FAILURE;
02908 }

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

Definition at line 13117 of file app_rpt.c.

References __kickshort(), ast_channel::_state, ahp, rpt::archivedir, ast_answer(), ast_callerid_parse(), AST_CDR_FLAG_POST_DISABLED, ast_channel_setoption(), AST_CONTROL_BUSY, ast_exists_extension(), AST_FORMAT_SLINEAR, ast_free, ast_gethostbyname(), ast_indicate(), ast_inet_ntoa(), ast_log(), ast_malloc, ast_masq_park_call(), AST_OPTION_TONE_VERIFY, ast_request(), ast_safe_sleep(), ast_set_callerid(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_shrink_phone_number(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_verbose, rpt::bargechan, rpt::callmode, ast_channel::cdr, chan, channel_revert(), channel_steer(), ast_channel::cid, ast_callerid::cid_num, rpt::conf, ast_channel::context, context, rpt_link::disced, donodelog(), rpt::duplex, ast_channel::exten, exten, f, hp, rpt::keyed, rpt_link::killme, rpt::lasttone, linkcount(), rpt::links, rpt::lock, LOG_NOTICE, LOG_WARNING, MAX_RETRIES, rpt_link::max_retries, MAXNODESTR, rpt_link::name, rpt::name, ast_channel::name, name, rpt_link::next, rpt::nobusyout, node_lookup(), rpt::nowchan, option_verbose, rpt::p, rpt::parrotmode, pbx_builtin_setvar(), pbx_builtin_setvar_helper(), pbx_substitute_variables_helper(), ast_channel::priority, priority_jump(), rpt_link::reconnects, rpt::remote, rpt::remoteon, rpt_link::retries, REV_PATCH, RPT_LOCKOUT_SECS, rpt_mutex_lock, rpt_mutex_unlock, rpt_push_alt_macro(), rpt_telemetry(), rpt::rptnode, s, rpt::s, send_newkey(), START_DELAY, strsep(), rpt::sysstate_cur, rpt::txkeyed, VERBOSE_PREFIX_3, voxinit_link(), rpt::waschan, and rpt::xlink.

Referenced by load_module().

13118 {
13119    int res=-1,i,rem_totx,rem_rx,remkeyed,n,phone_mode = 0;
13120    int iskenwood_pci4,authtold,authreq,setting,notremming,reming;
13121    int ismuted,dtmfed,phone_vox = 0;
13122 #ifdef   OLD_ASTERISK
13123    struct localuser *u;
13124 #endif
13125    char tmp[256], keyed = 0,keyed1 = 0;
13126    char *options,*stringp,*tele,c,*altp,*memp;
13127    char sx[320],*sy;
13128    struct   rpt *myrpt;
13129    struct ast_frame *f,*f1,*f2;
13130    struct ast_channel *who;
13131    struct ast_channel *cs[20];
13132    struct   rpt_link *l;
13133    struct dahdi_confinfo ci;  /* conference info */
13134    struct dahdi_params par;
13135    int ms,elap,nullfd;
13136    time_t t,last_timeout_warning;
13137    struct   dahdi_radio_param z;
13138    struct rpt_tele *telem;
13139    int   numlinks;
13140 
13141    nullfd = open("/dev/null",O_RDWR);
13142    if (ast_strlen_zero(data)) {
13143       ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n");
13144       return -1;
13145    }
13146 
13147    strncpy(tmp, (char *)data, sizeof(tmp)-1);
13148    time(&t);
13149    /* if time has externally shifted negative, screw it */
13150    if (t < starttime) t = starttime + START_DELAY;
13151    if ((!starttime) || (t < (starttime + START_DELAY)))
13152    {
13153       ast_log(LOG_NOTICE,"Node %s rejecting call: too soon!\n",tmp);
13154       ast_safe_sleep(chan,3000);
13155       return -1;
13156    }
13157 
13158    ast_log(LOG_NOTICE,"parsing argument=%s \n",tmp);
13159 
13160    altp=strstr(tmp, "|*");
13161    if(altp){
13162       altp[0]=0;
13163       altp++;
13164     }
13165 
13166    memp=strstr(tmp, "|M");
13167    if(memp){
13168       memp[0]=0;
13169       memp+=2;
13170     }
13171 
13172    stringp=tmp;
13173    strsep(&stringp, "|");
13174    options = stringp;
13175 
13176    ast_log(LOG_NOTICE,"options=%s \n",options);
13177    if(memp>0)ast_log(LOG_NOTICE,"memp=%s \n",memp);
13178    if(altp>0)ast_log(LOG_NOTICE,"altp=%s \n",altp);
13179 
13180    myrpt = NULL;
13181    /* see if we can find our specified one */
13182    for(i = 0; i < nrpts; i++)
13183    {
13184       /* if name matches, assign it and exit loop */
13185       if (!strcmp(tmp,rpt_vars[i].name))
13186       {
13187          myrpt = &rpt_vars[i];
13188          break;
13189       }
13190    }
13191 
13192    pbx_builtin_setvar_helper(chan, "RPT_STAT_ERR", "");
13193 
13194    if (myrpt == NULL)
13195    {
13196       pbx_builtin_setvar_helper(chan, "RPT_STAT_ERR", "NODE_NOT_FOUND");
13197       ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp);
13198       return (priority_jump(NULL,chan));
13199    }
13200 
13201    numlinks=linkcount(myrpt);
13202 
13203    if(options && *options == 'q')
13204    {
13205       char buf2[128];
13206 
13207       if(myrpt->keyed)
13208          pbx_builtin_setvar_helper(chan, "RPT_STAT_RXKEYED", "1");
13209       else
13210          pbx_builtin_setvar_helper(chan, "RPT_STAT_RXKEYED", "0");   
13211 
13212       if(myrpt->txkeyed)
13213          pbx_builtin_setvar_helper(chan, "RPT_STAT_TXKEYED", "1");
13214       else
13215          pbx_builtin_setvar_helper(chan, "RPT_STAT_TXKEYED", "0");   
13216 
13217       snprintf(buf2,sizeof(buf2),"%s=%i", "RPT_STAT_XLINK", myrpt->xlink);
13218       pbx_builtin_setvar(chan, buf2);
13219       snprintf(buf2,sizeof(buf2),"%s=%i", "RPT_STAT_LINKS", numlinks);
13220       pbx_builtin_setvar(chan, buf2);
13221       snprintf(buf2,sizeof(buf2),"%s=%d", "RPT_STAT_WASCHAN", myrpt->waschan);
13222       pbx_builtin_setvar(chan, buf2);
13223       snprintf(buf2,sizeof(buf2),"%s=%d", "RPT_STAT_NOWCHAN", myrpt->nowchan);
13224       pbx_builtin_setvar(chan, buf2);
13225       snprintf(buf2,sizeof(buf2),"%s=%d", "RPT_STAT_DUPLEX", myrpt->p.duplex);
13226       pbx_builtin_setvar(chan, buf2);
13227       snprintf(buf2,sizeof(buf2),"%s=%d", "RPT_STAT_PARROT", myrpt->p.parrotmode);
13228       pbx_builtin_setvar(chan, buf2);
13229       //snprintf(buf2,sizeof(buf2),"%s=%d", "RPT_STAT_PHONEVOX", myrpt->phonevox);
13230       //pbx_builtin_setvar(chan, buf2);
13231       //snprintf(buf2,sizeof(buf2),"%s=%d", "RPT_STAT_CONNECTED", myrpt->connected);
13232       //pbx_builtin_setvar(chan, buf2);
13233       snprintf(buf2,sizeof(buf2),"%s=%d", "RPT_STAT_CALLMODE", myrpt->callmode);
13234       pbx_builtin_setvar(chan, buf2);
13235       snprintf(buf2,sizeof(buf2),"%s=%s", "RPT_STAT_LASTTONE", myrpt->lasttone);
13236       pbx_builtin_setvar(chan, buf2);
13237 
13238       return priority_jump(myrpt,chan);
13239    }
13240 
13241    if(options && *options == 'o')
13242    {
13243       return(channel_revert(myrpt));
13244    }
13245 
13246    #if 0
13247    if((altp)&&(*options == 'Z'))
13248    {
13249       rpt_push_alt_macro(myrpt,altp);
13250       return 0;
13251    }
13252    #endif
13253 
13254 
13255    /* if not phone access, must be an IAX connection */
13256    if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R') || (*options == 'S')))
13257    {
13258       int val;
13259 
13260       pbx_builtin_setvar_helper(chan, "RPT_STAT_BUSY", "0");
13261        
13262       myrpt->bargechan=0;
13263       if(options && strstr(options, "f")>0)
13264       {
13265          myrpt->bargechan=1;     
13266       }
13267 
13268       if(memp>0)
13269       {
13270          char radiochan;
13271          radiochan=strtod(data,NULL);
13272          // if(myrpt->nowchan!=0 && radiochan!=myrpt->nowchan && !myrpt->bargechan)
13273 
13274          if(numlinks>0 && radiochan!=myrpt->nowchan && !myrpt->bargechan)
13275          {
13276             pbx_builtin_setvar_helper(chan, "RPT_STAT_BUSY", "1");
13277             ast_log(LOG_NOTICE, "Radio Channel Busy.\n");
13278             return (priority_jump(myrpt,chan));
13279          }
13280          else if(radiochan!=myrpt->nowchan || myrpt->bargechan)
13281          {
13282             channel_steer(myrpt,memp); 
13283          }
13284       }
13285       if(altp)rpt_push_alt_macro(myrpt,altp);
13286       phone_mode = 1;
13287       if (*options == 'D') phone_mode = 2;
13288       if (*options == 'S') phone_mode = 3;
13289       ast_set_callerid(chan,"0","app_rpt user","0");
13290       val = 1;
13291       ast_channel_setoption(chan,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0);
13292       if ((*(options + 1) == 'V') || (*(options + 1) == 'v')) phone_vox = 1;
13293    }
13294    else
13295    {
13296 #ifdef ALLOW_LOCAL_CHANNELS
13297            /* Check to insure the connection is IAX2 or Local*/
13298            if ( (strncmp(chan->name,"IAX2",4)) && (strncmp(chan->name,"Local",5)) ) {
13299                ast_log(LOG_WARNING, "We only accept links via IAX2 or Local!!\n");
13300                return -1;
13301            }
13302 #else
13303       if (strncmp(chan->name,"IAX2",4))
13304       {
13305          ast_log(LOG_WARNING, "We only accept links via IAX2!!\n");
13306          return -1;
13307       }
13308 #endif
13309            if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable){ /* Do not allow incoming radio connections if disabled */
13310                  ast_log(LOG_NOTICE, "Connect attempt to node %s  with tx disabled", myrpt->name);
13311                   return -1;
13312          }  
13313    }
13314    if (options && (*options == 'R'))
13315    {
13316       /* Parts of this section taken from app_parkandannounce */
13317       char *return_context;
13318       int length, m, lot, timeout = 0;
13319       char buffer[256],*template;
13320       char *working, *context, *exten, *priority;
13321       char *s,*orig_s;
13322 
13323       rpt_mutex_lock(&myrpt->lock);
13324       m = myrpt->callmode;
13325       rpt_mutex_unlock(&myrpt->lock);
13326 
13327       if ((!myrpt->p.nobusyout) && m)
13328       {
13329          if (chan->_state != AST_STATE_UP)
13330          {
13331             ast_indicate(chan,AST_CONTROL_BUSY);
13332          }
13333          while(ast_safe_sleep(chan,10000) != -1);
13334          return -1;
13335       }
13336 
13337       if (chan->_state != AST_STATE_UP)
13338       {
13339          ast_answer(chan);
13340          if (!phone_mode) send_newkey(chan);
13341       }
13342 
13343       length=strlen(options)+2;
13344       orig_s=ast_malloc(length);
13345       if(!orig_s) {
13346          ast_log(LOG_WARNING, "Out of memory\n");
13347          return -1;
13348       }
13349       s=orig_s;
13350       strncpy(s,options,length);
13351 
13352       template=strsep(&s,"|");
13353       if(!template) {
13354          ast_log(LOG_WARNING, "An announce template must be defined\n");
13355          ast_free(orig_s);
13356          return -1;
13357       } 
13358   
13359       if(s) {
13360          timeout = atoi(strsep(&s, "|"));
13361          timeout *= 1000;
13362       }
13363    
13364       return_context = s;
13365   
13366       if(return_context != NULL) {
13367          /* set the return context. Code borrowed from the Goto builtin */
13368     
13369          working = return_context;
13370          context = strsep(&working, "|");
13371          exten = strsep(&working, "|");
13372          if(!exten) {
13373             /* Only a priority in this one */
13374             priority = context;
13375             exten = NULL;
13376             context = NULL;
13377          } else {
13378             priority = strsep(&working, "|");
13379             if(!priority) {
13380                /* Only an extension and priority in this one */
13381                priority = exten;
13382                exten = context;
13383                context = NULL;
13384          }
13385       }
13386       if(atoi(priority) < 0) {
13387          ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority);
13388          ast_free(orig_s);
13389          return -1;
13390       }
13391       /* At this point we have a priority and maybe an extension and a context */
13392       chan->priority = atoi(priority);
13393 #ifdef OLD_ASTERISK
13394       if(exten && strcasecmp(exten, "BYEXTENSION"))
13395 #else
13396       if(exten)
13397 #endif
13398          strncpy(chan->exten, exten, sizeof(chan->exten)-1);
13399       if(context)
13400          strncpy(chan->context, context, sizeof(chan->context)-1);
13401       } else {  /* increment the priority by default*/
13402          chan->priority++;
13403       }
13404 
13405       if(option_verbose > 2) {
13406          ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num);
13407          if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
13408             ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n");
13409          }
13410       }
13411   
13412       /* we are using masq_park here to protect * from touching the channel once we park it.  If the channel comes out of timeout
13413       before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
13414 
13415       ast_masq_park_call(chan, NULL, timeout, &lot);
13416 
13417       if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context);
13418 
13419       snprintf(buffer, sizeof(buffer) - 1, "%d,%s", lot, template + 1);
13420 
13421       rpt_telemetry(myrpt,REV_PATCH,buffer);
13422 
13423       ast_free(orig_s);
13424 
13425       return 0;
13426 
13427    }
13428 
13429    if (!options)
13430    {
13431         struct ast_hostent ahp;
13432         struct hostent *hp;
13433         struct in_addr ia;
13434         char hisip[100],nodeip[100],*val, *s, *s1, *s2, *s3, *b,*b1;
13435 
13436       /* look at callerid to see what node this comes from */
13437       if (!chan->cid.cid_num) /* if doesn't have caller id */
13438       {
13439          ast_log(LOG_WARNING, "Does not have callerid on %s\n",tmp);
13440          return -1;
13441       }
13442       /* get his IP from IAX2 module */
13443       memset(hisip,0,sizeof(hisip));
13444 #ifdef ALLOW_LOCAL_CHANNELS
13445         /* set IP address if this is a local connection*/
13446         if (strncmp(chan->name,"Local",5)==0) {
13447             strcpy(hisip,"127.0.0.1");
13448         } else {
13449          pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
13450       }
13451 #else
13452       pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1);
13453 #endif
13454 
13455       if (!hisip[0])
13456       {
13457          ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n");
13458          return -1;
13459       }
13460       
13461       ast_callerid_parse(chan->cid.cid_num,&b,&b1);
13462       ast_shrink_phone_number(b1);
13463       if (!strcmp(myrpt->name,b1))
13464       {
13465          ast_log(LOG_WARNING, "Trying to link to self!!\n");
13466          return -1;
13467       }
13468 
13469       if (*b1 < '1')
13470       {
13471          ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1);
13472          return -1;
13473       }
13474 
13475 
13476       /* look for his reported node string */
13477       val = node_lookup(myrpt,b1);
13478       if (!val)
13479       {
13480          ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1);
13481          return -1;
13482       }
13483       strncpy(tmp,val,sizeof(tmp) - 1);
13484       s = tmp;
13485       s1 = strsep(&s,",");
13486       if (!strchr(s1,':') && strchr(s1,'/') && strncasecmp(s1, "local/", 6))
13487       {
13488          sy = strchr(s1,'/');    
13489          *sy = 0;
13490          sprintf(sx,"%s:4569/%s",s1,sy + 1);
13491          s1 = sx;
13492       }
13493       s2 = strsep(&s,",");
13494       if (!s2)
13495       {
13496          ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1);
13497          return -1;
13498       }
13499                 if (strcmp(s2,"NONE")) {
13500          hp = ast_gethostbyname(s2, &ahp);
13501          if (!hp)
13502          {
13503             ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2);
13504             return -1;
13505          }
13506          memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
13507 #ifdef   OLD_ASTERISK
13508          ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia);
13509 #else
13510          strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1);
13511 #endif
13512          s3 = strchr(hisip,':');
13513          if (s3) *s3 = 0;
13514          if (strcmp(hisip,nodeip))
13515          {
13516             s3 = strchr(s1,'@');
13517             if (s3) s1 = s3 + 1;
13518             s3 = strchr(s1,'/');
13519             if (s3) *s3 = 0;
13520             s3 = strchr(s1,':');
13521             if (s3) *s3 = 0;
13522             hp = ast_gethostbyname(s1, &ahp);
13523             if (!hp)
13524             {
13525                ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1);
13526                return -1;
13527             }
13528             memcpy(&ia,hp->h_addr,sizeof(in_addr_t));
13529 #ifdef   OLD_ASTERISK
13530             ast_inet_ntoa(nodeip,sizeof(nodeip) - 1,ia);
13531 #else
13532             strncpy(nodeip,ast_inet_ntoa(ia),sizeof(nodeip) - 1);
13533 #endif
13534             if (strcmp(hisip,nodeip))
13535             {
13536                ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip);
13537                return -1;
13538             }
13539          }
13540       }
13541    }
13542 
13543    /* if is not a remote */
13544    if (!myrpt->remote)
13545    {
13546       char *b,*b1;
13547       int reconnects = 0;
13548 
13549       rpt_mutex_lock(&myrpt->lock);
13550       i = myrpt->xlink;
13551       rpt_mutex_unlock(&myrpt->lock);
13552       if (i)
13553       {
13554          ast_log(LOG_WARNING, "Cannot connect to node %s, system busy\n",myrpt->name);
13555          return -1;
13556       }
13557       /* look at callerid to see what node this comes from */
13558       if (!chan->cid.cid_num) /* if doesn't have caller id */
13559       {
13560          ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp);
13561          return -1;
13562       }
13563 
13564       ast_callerid_parse(chan->cid.cid_num,&b,&b1);
13565       ast_shrink_phone_number(b1);
13566       if (!strcmp(myrpt->name,b1))
13567       {
13568          ast_log(LOG_WARNING, "Trying to link to self!!\n");
13569          return -1;
13570       }
13571       rpt_mutex_lock(&myrpt->lock);
13572       l = myrpt->links.next;
13573       /* try to find this one in queue */
13574       while(l != &myrpt->links)
13575       {
13576          if (l->name[0] == '0') 
13577          {
13578             l = l->next;
13579             continue;
13580          }
13581          /* if found matching string */
13582          if (!strcmp(l->name,b1)) break;
13583          l = l->next;
13584       }
13585       /* if found */
13586       if (l != &myrpt->links) 
13587       {
13588          l->killme = 1;
13589          l->retries = l->max_retries + 1;
13590          l->disced = 2;
13591          reconnects = l->reconnects;
13592          reconnects++;
13593                         rpt_mutex_unlock(&myrpt->lock);
13594          usleep(500000);   
13595       } else 
13596          rpt_mutex_unlock(&myrpt->lock);
13597       /* establish call in tranceive mode */
13598       l = ast_malloc(sizeof(struct rpt_link));
13599       if (!l)
13600       {
13601          ast_log(LOG_WARNING, "Unable to malloc\n");
13602          pthread_exit(NULL);
13603       }
13604       /* zero the silly thing */
13605       memset((char *)l,0,sizeof(struct rpt_link));
13606       l->mode = 1;
13607       strncpy(l->name,b1,MAXNODESTR - 1);
13608       l->isremote = 0;
13609       l->chan = chan;
13610       l->connected = 1;
13611       l->thisconnected = 1;
13612       l->hasconnected = 1;
13613       l->reconnects = reconnects;
13614       l->phonemode = phone_mode;
13615       l->phonevox = phone_vox;
13616       l->lastf1 = NULL;
13617       l->lastf2 = NULL;
13618       l->dtmfed = 0;
13619       voxinit_link(l,1);
13620       ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
13621       ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
13622       /* allocate a pseudo-channel thru asterisk */
13623       l->pchan = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
13624       if (!l->pchan)
13625       {
13626          fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
13627          pthread_exit(NULL);
13628       }
13629       ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
13630       ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
13631 #ifdef   AST_CDR_FLAG_POST_DISABLED
13632       if (l->pchan->cdr)
13633          ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
13634 #endif
13635       /* make a conference for the tx */
13636       ci.chan = 0;
13637       ci.confno = myrpt->conf;
13638       ci.confmode = DAHDI_CONF_CONF | DAHDI_CONF_LISTENER | DAHDI_CONF_TALKER;
13639       /* first put the channel on the conference in proper mode */
13640       if (ioctl(l->pchan->fds[0],DAHDI_SETCONF,&ci) == -1)
13641       {
13642          ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
13643          pthread_exit(NULL);
13644       }
13645       rpt_mutex_lock(&myrpt->lock);
13646       if ((phone_mode == 2) && (!phone_vox)) l->lastrealrx = 1;
13647       l->max_retries = MAX_RETRIES;
13648       /* insert at end of queue */
13649       insque((struct qelem *)l,(struct qelem *)myrpt->links.next);
13650       __kickshort(myrpt);
13651       rpt_mutex_unlock(&myrpt->lock);
13652       if (chan->_state != AST_STATE_UP) {
13653          ast_answer(chan);
13654          if (!phone_mode) send_newkey(chan);
13655       }
13656       if (myrpt->p.archivedir)
13657       {
13658          char str[100];
13659 
13660          if (l->phonemode)
13661             sprintf(str,"LINK(P),%s",l->name);
13662          else
13663             sprintf(str,"LINK,%s",l->name);
13664          donodelog(myrpt,str);
13665       }
13666       if (!phone_mode) send_newkey(chan);
13667       return 0;
13668    }
13669    /* well, then it is a remote */
13670    rpt_mutex_lock(&myrpt->lock);
13671    /* if remote, error if anyone else already linked */
13672    if (myrpt->remoteon)
13673    {
13674       rpt_mutex_unlock(&myrpt->lock);
13675       usleep(500000);
13676       if (myrpt->remoteon)
13677       {
13678          ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp);
13679 #ifdef   AST_CDR_FLAG_POST_DISABLED
13680          if (chan->cdr)
13681             ast_set_flag(chan->cdr,AST_CDR_FLAG_POST_DISABLED);
13682 #endif
13683          return -1;
13684       }     
13685       rpt_mutex_lock(&myrpt->lock);
13686    }
13687    if (myrpt->p.rptnode)
13688    {
13689       char killedit = 0;
13690       time_t now;
13691 
13692       time(&now);
13693       for(i = 0; i < nrpts; i++)
13694       {
13695          if (!strcasecmp(rpt_vars[i].name,myrpt->p.rptnode))
13696          {
13697             if ((rpt_vars[i].links.next != &rpt_vars[i].links) ||
13698                rpt_vars[i].keyed ||
13699                 ((rpt_vars[i].lastkeyedtime + RPT_LOCKOUT_SECS) > now) ||
13700                  rpt_vars[i].txkeyed ||
13701                   ((rpt_vars[i].lasttxkeyedtime + RPT_LOCKOUT_SECS) > now))
13702             {
13703                rpt_mutex_unlock(&myrpt->lock);
13704                ast_log(LOG_WARNING, "Trying to use busy link (repeater node %s) on %s\n",rpt_vars[i].name,tmp);
13705 #ifdef   AST_CDR_FLAG_POST_DISABLED
13706                if (chan->cdr)
13707                   ast_set_flag(chan->cdr,AST_CDR_FLAG_POST_DISABLED);
13708 #endif
13709                return -1;
13710             }
13711             while(rpt_vars[i].xlink != 3)
13712             {
13713                if (!killedit)
13714                {
13715                   ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV);
13716                   rpt_vars[i].xlink = 1;
13717                   killedit = 1;
13718                }
13719                rpt_mutex_unlock(&myrpt->lock);
13720                if (ast_safe_sleep(chan,500) == -1)
13721                {
13722 #ifdef   AST_CDR_FLAG_POST_DISABLED
13723                   if (chan->cdr)
13724                      ast_set_flag(chan->cdr,AST_CDR_FLAG_POST_DISABLED);
13725 #endif
13726                   return -1;
13727                }
13728                rpt_mutex_lock(&myrpt->lock);
13729             }
13730             break;
13731          }
13732       }
13733    }
13734 
13735 #ifdef HAVE_IOPERM
13736    if ( (!strcmp(myrpt->remoterig, remote_rig_rbi)||!strcmp(myrpt->remoterig, remote_rig_ppp16)) &&
13737      (ioperm(myrpt->p.iobase,1,1) == -1))
13738    {
13739       rpt_mutex_unlock(&myrpt->lock);
13740       ast_log(LOG_WARNING, "Can't get io permission on IO port %x hex\n",myrpt->p.iobase);
13741       return -1;
13742    }
13743 #endif
13744    myrpt->remoteon = 1;
13745 #ifdef   OLD_ASTERISK
13746    LOCAL_USER_ADD(u);
13747 #endif
13748    rpt_mutex_unlock(&myrpt->lock);
13749    /* find our index, and load the vars initially */
13750    for(i = 0; i < nrpts; i++)
13751    {
13752       if (&rpt_vars[i] == myrpt)
13753       {
13754          load_rpt_vars(i,0);
13755          break;
13756       }
13757    }
13758    rpt_mutex_lock(&myrpt->lock);
13759    tele = strchr(myrpt->rxchanname,'/');
13760    if (!tele)
13761    {
13762       fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
13763       rpt_mutex_unlock(&myrpt->lock);
13764       pthread_exit(NULL);
13765    }
13766    *tele++ = 0;
13767    myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL);
13768    myrpt->dahdirxchannel = NULL;
13769    if (!strcasecmp(myrpt->rxchanname,"DAHDI"))
13770       myrpt->dahdirxchannel = myrpt->rxchannel;
13771    if (myrpt->rxchannel)
13772    {
13773       ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
13774       ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
13775 #ifdef   AST_CDR_FLAG_POST_DISABLED
13776       if (myrpt->rxchannel->cdr)
13777          ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
13778 #endif
13779 #ifndef  NEW_ASTERISK
13780       myrpt->rxchannel->whentohangup = 0;
13781 #endif
13782       myrpt->rxchannel->appl = "Apprpt";
13783       myrpt->rxchannel->data = "(Link Rx)";
13784       if (option_verbose > 2)
13785          ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n",
13786             myrpt->rxchanname,tele,myrpt->rxchannel->name);
13787       rpt_mutex_unlock(&myrpt->lock);
13788       ast_call(myrpt->rxchannel,tele,999);
13789       rpt_mutex_lock(&myrpt->lock);
13790    }
13791    else
13792    {
13793       fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n");
13794       rpt_mutex_unlock(&myrpt->lock);
13795       pthread_exit(NULL);
13796    }
13797    *--tele = '/';
13798    myrpt->dahditxchannel = NULL;
13799    if (myrpt->txchanname)
13800    {
13801       tele = strchr(myrpt->txchanname,'/');
13802       if (!tele)
13803       {
13804          fprintf(stderr,"rpt:Dial number must be in format tech/number\n");
13805          rpt_mutex_unlock(&myrpt->lock);
13806          ast_hangup(myrpt->rxchannel);
13807          pthread_exit(NULL);
13808       }
13809       *tele++ = 0;
13810       myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL);
13811       if (!strncasecmp(myrpt->txchanname,"DAHDI",3))
13812          myrpt->dahditxchannel = myrpt->txchannel;
13813       if (myrpt->txchannel)
13814       {
13815          ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
13816          ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
13817 #ifdef   AST_CDR_FLAG_POST_DISABLED
13818          if (myrpt->txchannel->cdr)
13819             ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
13820 #endif
13821 #ifndef  NEW_ASTERISK
13822          myrpt->txchannel->whentohangup = 0;
13823 #endif
13824          myrpt->txchannel->appl = "Apprpt";
13825          myrpt->txchannel->data = "(Link Tx)";
13826          if (option_verbose > 2)
13827             ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n",
13828                myrpt->txchanname,tele,myrpt->txchannel->name);
13829          rpt_mutex_unlock(&myrpt->lock);
13830          ast_call(myrpt->txchannel,tele,999);
13831          rpt_mutex_lock(&myrpt->lock);
13832       }
13833       else
13834       {
13835          fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n");
13836          rpt_mutex_unlock(&myrpt->lock);
13837          ast_hangup(myrpt->rxchannel);
13838          pthread_exit(NULL);
13839       }
13840       *--tele = '/';
13841    }
13842    else
13843    {
13844       myrpt->txchannel = myrpt->rxchannel;
13845       if (!strncasecmp(myrpt->rxchanname,"DAHDI",3))
13846          myrpt->dahditxchannel = myrpt->rxchannel;
13847    }
13848    /* allocate a pseudo-channel thru asterisk */
13849    myrpt->pchannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
13850    if (!myrpt->pchannel)
13851    {
13852       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
13853       rpt_mutex_unlock(&myrpt->lock);
13854       if (myrpt->txchannel != myrpt->rxchannel) 
13855          ast_hangup(myrpt->txchannel);
13856       ast_hangup(myrpt->rxchannel);
13857       pthread_exit(NULL);
13858    }
13859    ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
13860    ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
13861 #ifdef   AST_CDR_FLAG_POST_DISABLED
13862    if (myrpt->pchannel->cdr)
13863       ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
13864 #endif
13865    if (!myrpt->dahdirxchannel) myrpt->dahdirxchannel = myrpt->pchannel;
13866    if (!myrpt->dahditxchannel) myrpt->dahditxchannel = myrpt->pchannel;
13867    /* make a conference for the pseudo */
13868    ci.chan = 0;
13869    ci.confno = -1; /* make a new conf */
13870    ci.confmode = DAHDI_CONF_CONFANNMON ;
13871    /* first put the channel on the conference in announce/monitor mode */
13872    if (ioctl(myrpt->pchannel->fds[0],DAHDI_SETCONF,&ci) == -1)
13873    {
13874       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
13875       rpt_mutex_unlock(&myrpt->lock);
13876       ast_hangup(myrpt->pchannel);
13877       if (myrpt->txchannel != myrpt->rxchannel) 
13878          ast_hangup(myrpt->txchannel);
13879       ast_hangup(myrpt->rxchannel);
13880       pthread_exit(NULL);
13881    }
13882    /* save pseudo channel conference number */
13883    myrpt->conf = myrpt->txconf = ci.confno;
13884    /* if serial io port, open it */
13885    myrpt->iofd = -1;
13886    if (myrpt->p.ioport && ((myrpt->iofd = openserial(myrpt,myrpt->p.ioport)) == -1))
13887    {
13888       rpt_mutex_unlock(&myrpt->lock);
13889       ast_hangup(myrpt->pchannel);
13890       if (myrpt->txchannel != myrpt->rxchannel) 
13891          ast_hangup(myrpt->txchannel);
13892       ast_hangup(myrpt->rxchannel);
13893       pthread_exit(NULL);
13894    }
13895    iskenwood_pci4 = 0;
13896    memset(&z,0,sizeof(z));
13897    if ((myrpt->iofd < 1) && (myrpt->txchannel == myrpt->dahditxchannel))
13898    {
13899       z.radpar = DAHDI_RADPAR_REMMODE;
13900       z.data = DAHDI_RADPAR_REM_NONE;
13901       res = ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z);
13902       /* if PCIRADIO and kenwood selected */
13903       if ((!res) && (!strcmp(myrpt->remoterig,remote_rig_kenwood)))
13904       {
13905          z.radpar = DAHDI_RADPAR_UIOMODE;
13906          z.data = 1;
13907          if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
13908          {
13909             ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
13910             return -1;
13911          }
13912          z.radpar = DAHDI_RADPAR_UIODATA;
13913          z.data = 3;
13914          if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
13915          {
13916             ast_log(LOG_ERROR,"Cannot set UIODATA\n");
13917             return -1;
13918          }
13919          i = DAHDI_OFFHOOK;
13920          if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_HOOK,&i) == -1)
13921          {
13922             ast_log(LOG_ERROR,"Cannot set hook\n");
13923             return -1;
13924          }
13925          iskenwood_pci4 = 1;
13926       }
13927    }
13928    if (myrpt->txchannel == myrpt->dahditxchannel)
13929    {
13930       i = DAHDI_ONHOOK;
13931       ioctl(myrpt->dahditxchannel->fds[0],DAHDI_HOOK,&i);
13932       /* if PCIRADIO and Yaesu ft897/ICOM IC-706 selected */
13933       if ((myrpt->iofd < 1) && (!res) &&
13934          ((!strcmp(myrpt->remoterig,remote_rig_ft897)) ||
13935             (!strcmp(myrpt->remoterig,remote_rig_ic706)) ||
13936                (!strcmp(myrpt->remoterig,remote_rig_tm271))))
13937       {
13938          z.radpar = DAHDI_RADPAR_UIOMODE;
13939          z.data = 1;
13940          if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
13941          {
13942             ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
13943             return -1;
13944          }
13945          z.radpar = DAHDI_RADPAR_UIODATA;
13946          z.data = 3;
13947          if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
13948          {
13949             ast_log(LOG_ERROR,"Cannot set UIODATA\n");
13950             return -1;
13951          }
13952       }
13953    }
13954    myrpt->remoterx = 0;
13955    myrpt->remotetx = 0;
13956    myrpt->retxtimer = 0;
13957    myrpt->rerxtimer = 0;
13958    myrpt->remoteon = 1;
13959    myrpt->dtmfidx = -1;
13960    myrpt->dtmfbuf[0] = 0;
13961    myrpt->dtmf_time_rem = 0;
13962    myrpt->hfscanmode = 0;
13963    myrpt->hfscanstatus = 0;
13964    if (myrpt->p.startupmacro)
13965    {
13966       snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro);
13967    }
13968    time(&myrpt->start_time);
13969    myrpt->last_activity_time = myrpt->start_time;
13970    last_timeout_warning = 0;
13971    myrpt->reload = 0;
13972    myrpt->tele.next = &myrpt->tele;
13973    myrpt->tele.prev = &myrpt->tele;
13974    myrpt->newkey = 0;
13975    rpt_mutex_unlock(&myrpt->lock);
13976    ast_set_write_format(chan, AST_FORMAT_SLINEAR);
13977    ast_set_read_format(chan, AST_FORMAT_SLINEAR);
13978    rem_rx = 0;
13979    remkeyed = 0;
13980    /* if we are on 2w loop and are a remote, turn EC on */
13981    if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel))
13982    {
13983       i = 128;
13984       ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_ECHOCANCEL,&i);
13985    }
13986    if (chan->_state != AST_STATE_UP) {
13987       ast_answer(chan);
13988       if (!phone_mode) send_newkey(chan);
13989    }
13990 
13991    if (myrpt->rxchannel == myrpt->dahdirxchannel)
13992    {
13993       if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_GET_PARAMS,&par) != -1)
13994       {
13995          if (par.rxisoffhook)
13996          {
13997             ast_indicate(chan,AST_CONTROL_RADIO_KEY);
13998             myrpt->remoterx = 1;
13999             remkeyed = 1;
14000          }
14001       }
14002    }
14003    if (myrpt->p.archivedir)
14004    {
14005       char mycmd[100],mydate[100],*b,*b1;
14006       time_t myt;
14007       long blocksleft;
14008 
14009 
14010       mkdir(myrpt->p.archivedir,0600);
14011       sprintf(mycmd,"%s/%s",myrpt->p.archivedir,myrpt->name);
14012       mkdir(mycmd,0600);
14013       time(&myt);
14014       strftime(mydate,sizeof(mydate) - 1,"%Y%m%d%H%M%S",
14015          localtime(&myt));
14016       sprintf(mycmd,"mixmonitor start %s %s/%s/%s.wav49 a",chan->name,
14017          myrpt->p.archivedir,myrpt->name,mydate);
14018       if (myrpt->p.monminblocks)
14019       {
14020          blocksleft = diskavail(myrpt);
14021          if (myrpt->p.remotetimeout)
14022          {
14023             blocksleft -= (myrpt->p.remotetimeout *
14024                MONITOR_DISK_BLOCKS_PER_MINUTE) / 60;
14025          }
14026          if (blocksleft >= myrpt->p.monminblocks)
14027             ast_cli_command(nullfd,mycmd);
14028       } else ast_cli_command(nullfd,mycmd);
14029       /* look at callerid to see what node this comes from */
14030       if (!chan->cid.cid_num) /* if doesn't have caller id */
14031       {
14032          b1 = "0";
14033       } else {
14034          ast_callerid_parse(chan->cid.cid_num,&b,&b1);
14035          ast_shrink_phone_number(b1);
14036       }
14037       sprintf(mycmd,"CONNECT,%s",b1);
14038       donodelog(myrpt,mycmd);
14039    }
14040    myrpt->loginuser[0] = 0;
14041    myrpt->loginlevel[0] = 0;
14042    myrpt->authtelltimer = 0;
14043    myrpt->authtimer = 0;
14044    authtold = 0;
14045    authreq = 0;
14046    if (myrpt->p.authlevel > 1) authreq = 1;
14047    setrem(myrpt); 
14048    n = 0;
14049    dtmfed = 0;
14050    cs[n++] = chan;
14051    cs[n++] = myrpt->rxchannel;
14052    cs[n++] = myrpt->pchannel;
14053    if (myrpt->rxchannel != myrpt->txchannel)
14054       cs[n++] = myrpt->txchannel;
14055    if (!phone_mode) send_newkey(chan);
14056    /* start un-locked */
14057    for(;;) 
14058    {
14059       if (ast_check_hangup(chan)) break;
14060       if (ast_check_hangup(myrpt->rxchannel)) break;
14061       notremming = 0;
14062       setting = 0;
14063       reming = 0;
14064       telem = myrpt->tele.next;
14065       while(telem != &myrpt->tele)
14066       {
14067          if (telem->mode == SETREMOTE) setting = 1;
14068          if ((telem->mode == SETREMOTE) ||
14069              (telem->mode == SCAN) ||
14070             (telem->mode == TUNE))  reming = 1;
14071          else notremming = 1;
14072          telem = telem->next;
14073       }
14074       if (myrpt->reload)
14075       {
14076          myrpt->reload = 0;
14077          /* find our index, and load the vars */
14078          for(i = 0; i < nrpts; i++)
14079          {
14080             if (&rpt_vars[i] == myrpt)
14081             {
14082                load_rpt_vars(i,0);
14083                break;
14084             }
14085          }
14086       }
14087       time(&t);
14088       if (myrpt->p.remotetimeout)
14089       { 
14090          time_t r;
14091 
14092          r = (t - myrpt->start_time);
14093          if (r >= myrpt->p.remotetimeout)
14094          {
14095             saynode(myrpt,chan,myrpt->name);
14096             sayfile(chan,"rpt/timeout");
14097             ast_safe_sleep(chan,1000);
14098             break;
14099          }
14100          if ((myrpt->p.remotetimeoutwarning) && 
14101              (r >= (myrpt->p.remotetimeout -
14102             myrpt->p.remotetimeoutwarning)) &&
14103                 (r <= (myrpt->p.remotetimeout - 
14104                   myrpt->p.remotetimeoutwarningfreq)))
14105          {
14106             if (myrpt->p.remotetimeoutwarningfreq)
14107             {
14108                 if ((t - last_timeout_warning) >=
14109                myrpt->p.remotetimeoutwarningfreq)
14110                 {
14111                time(&last_timeout_warning);
14112                rpt_telemetry(myrpt,TIMEOUT_WARNING,0);
14113                 }
14114             }
14115             else
14116             {
14117                 if (!last_timeout_warning)
14118                 {
14119                time(&last_timeout_warning);
14120                rpt_telemetry(myrpt,TIMEOUT_WARNING,0);
14121                 }
14122             }
14123          }
14124       }
14125       if (myrpt->p.remoteinacttimeout && myrpt->last_activity_time)
14126       { 
14127          time_t r;
14128 
14129          r = (t - myrpt->last_activity_time);
14130          if (r >= myrpt->p.remoteinacttimeout)
14131          {
14132             saynode(myrpt,chan,myrpt->name);
14133             ast_safe_sleep(chan,1000);
14134             break;
14135          }
14136          if ((myrpt->p.remotetimeoutwarning) && 
14137              (r >= (myrpt->p.remoteinacttimeout -
14138             myrpt->p.remotetimeoutwarning)) &&
14139                 (r <= (myrpt->p.remoteinacttimeout - 
14140                   myrpt->p.remotetimeoutwarningfreq)))
14141          {
14142             if (myrpt->p.remotetimeoutwarningfreq)
14143             {
14144                 if ((t - last_timeout_warning) >=
14145                myrpt->p.remotetimeoutwarningfreq)
14146                 {
14147                time(&last_timeout_warning);
14148                rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0);
14149                 }
14150             }
14151             else
14152             {
14153                 if (!last_timeout_warning)
14154                 {
14155                time(&last_timeout_warning);
14156                rpt_telemetry(myrpt,ACT_TIMEOUT_WARNING,0);
14157                 }
14158             }
14159          }
14160       }
14161       ms = MSWAIT;
14162       who = ast_waitfor_n(cs,n,&ms);
14163       if (who == NULL) ms = 0;
14164       elap = MSWAIT - ms;
14165       if (myrpt->macrotimer) myrpt->macrotimer -= elap;
14166       if (myrpt->macrotimer < 0) myrpt->macrotimer = 0;
14167       if (!ms) continue;
14168       /* do local dtmf timer */
14169       if (myrpt->dtmf_local_timer)
14170       {
14171          if (myrpt->dtmf_local_timer > 1) myrpt->dtmf_local_timer -= elap;
14172          if (myrpt->dtmf_local_timer < 1) myrpt->dtmf_local_timer = 1;
14173       }
14174       rpt_mutex_lock(&myrpt->lock);
14175       do_dtmf_local(myrpt,0);
14176       rpt_mutex_unlock(&myrpt->lock);
14177       //
14178       rem_totx =  myrpt->dtmf_local_timer && (!phone_mode);
14179       rem_totx |= keyed && (!myrpt->tunerequest);
14180       rem_rx = (remkeyed && (!setting)) || (myrpt->tele.next != &myrpt->tele);
14181       if(!strcmp(myrpt->remoterig, remote_rig_ic706))
14182          rem_totx |= myrpt->tunerequest;
14183       //
14184        if((debug > 6) && rem_totx) {
14185          ast_log(LOG_NOTICE,"Set rem_totx=%i.  dtmf_local_timer=%i phone_mode=%i keyed=%i tunerequest=%i\n",rem_totx,myrpt->dtmf_local_timer,phone_mode,keyed,myrpt->tunerequest);
14186       }
14187       if (keyed && (!keyed1))
14188       {
14189          keyed1 = 1;
14190       }
14191 
14192       if (!keyed && (keyed1))
14193       {
14194          time_t myt;
14195 
14196          keyed1 = 0;
14197          time(&myt);
14198          /* if login necessary, and not too soon */
14199          if ((myrpt->p.authlevel) && 
14200              (!myrpt->loginlevel[0]) &&
14201             (myt > (t + 3)))
14202          {
14203             authreq = 1;
14204             authtold = 0;
14205             myrpt->authtelltimer = AUTHTELLTIME - AUTHTXTIME;
14206          }
14207       }
14208 
14209       if (rem_rx && (!myrpt->remoterx))
14210       {
14211          myrpt->remoterx = 1;
14212          ast_indicate(chan,AST_CONTROL_RADIO_KEY);
14213       }
14214       if ((!rem_rx) && (myrpt->remoterx))
14215       {
14216          myrpt->remoterx = 0;
14217          ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
14218       }
14219       /* if auth requested, and not authed yet */
14220       if (authreq && (!myrpt->loginlevel[0]))
14221       {
14222          if ((!authtold) && ((myrpt->authtelltimer += elap)
14223              >= AUTHTELLTIME))
14224          {
14225             authtold = 1;
14226             rpt_telemetry(myrpt,LOGINREQ,NULL);
14227          }
14228          if ((myrpt->authtimer += elap) >= AUTHLOGOUTTIME)
14229          {
14230             break; /* if not logged in, hang up after a time */
14231          }
14232       }
14233       if (myrpt->newkey)
14234       {
14235          if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME)
14236          {
14237             myrpt->retxtimer = 0;
14238             if ((myrpt->remoterx) && (!myrpt->remotetx))
14239                ast_indicate(chan,AST_CONTROL_RADIO_KEY);
14240             else
14241                ast_indicate(chan,AST_CONTROL_RADIO_UNKEY);
14242          }
14243 
14244          if ((myrpt->rerxtimer += elap) >= (REDUNDANT_TX_TIME * 2))
14245          {
14246             keyed = 0;
14247             myrpt->rerxtimer = 0;
14248          }
14249       }
14250       if (rem_totx && (!myrpt->remotetx))
14251       {
14252          /* if not authed, and needed, do not transmit */
14253          if ((!myrpt->p.authlevel) || myrpt->loginlevel[0])
14254          {
14255             if(debug > 6)
14256                ast_log(LOG_NOTICE,"Handle rem_totx=%i.  dtmf_local_timer=%i  tunerequest=%i\n",rem_totx,myrpt->dtmf_local_timer,myrpt->tunerequest);
14257 
14258             myrpt->remotetx = 1;
14259             /* asdf maw ??? is this really what you want? Doesn't it always get executed? */
14260             if((myrpt->remtxfreqok = check_tx_freq(myrpt)))
14261             {
14262                time(&myrpt->last_activity_time);
14263                if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->dahditxchannel))
14264                {
14265                   z.radpar = DAHDI_RADPAR_UIODATA;
14266                   z.data = 1;
14267                   if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
14268                   {
14269                      ast_log(LOG_ERROR,"Cannot set UIODATA\n");
14270                      return -1;
14271                   }
14272                }
14273                else
14274                {
14275                   ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
14276                }
14277                if (myrpt->p.archivedir) donodelog(myrpt,"TXKEY");
14278             }
14279          }
14280       }
14281       if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */
14282       {
14283          myrpt->remotetx = 0;
14284          if(!myrpt->remtxfreqok){
14285             rpt_telemetry(myrpt,UNAUTHTX,NULL);
14286          }
14287          if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->dahditxchannel))
14288          {
14289             z.radpar = DAHDI_RADPAR_UIODATA;
14290             z.data = 3;
14291             if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
14292             {
14293                ast_log(LOG_ERROR,"Cannot set UIODATA\n");
14294                return -1;
14295             }
14296          }
14297          else
14298          {
14299             ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
14300          }
14301          if (myrpt->p.archivedir) donodelog(myrpt,"TXUNKEY");
14302       }
14303       if (myrpt->hfscanmode){
14304          myrpt->scantimer -= elap;
14305          if(myrpt->scantimer <= 0){
14306             if (!reming)
14307             {
14308                myrpt->scantimer = REM_SCANTIME;
14309                rpt_telemetry(myrpt,SCAN,0);
14310             } else myrpt->scantimer = 1;
14311          }
14312       }
14313       rpt_mutex_lock(&myrpt->lock);
14314       c = myrpt->macrobuf[0];
14315       if (c && (!myrpt->macrotimer))
14316       {
14317          myrpt->macrotimer = MACROTIME;
14318          memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1);
14319          if ((c == 'p') || (c == 'P'))
14320             myrpt->macrotimer = MACROPTIME;
14321          rpt_mutex_unlock(&myrpt->lock);
14322          if (myrpt->p.archivedir)
14323          {
14324             char str[100];
14325                sprintf(str,"DTMF(M),%c",c);
14326             donodelog(myrpt,str);
14327          }
14328          if (handle_remote_dtmf_digit(myrpt,c,&keyed,0) == -1) break;
14329          continue;
14330       } else rpt_mutex_unlock(&myrpt->lock);
14331       if (who == chan) /* if it was a read from incomming */
14332       {
14333          f = ast_read(chan);
14334          if (!f)
14335          {
14336             if (debug) printf("@@@@ link:Hung Up\n");
14337             break;
14338          }
14339          if (f->frametype == AST_FRAME_VOICE)
14340          {
14341             if (ioctl(chan->fds[0], DAHDI_GETCONFMUTE, &ismuted) == -1)
14342             {
14343                ismuted = 0;
14344             }
14345             /* if not transmitting, zero-out audio */
14346             ismuted |= (!myrpt->remotetx);
14347             if (dtmfed && phone_mode) ismuted = 1;
14348             dtmfed = 0;
14349             if (ismuted)
14350             {
14351                memset(f->data.ptr,0,f->datalen);
14352                if (myrpt->lastf1)
14353                   memset(myrpt->lastf1->data.ptr,0,myrpt->lastf1->datalen);
14354                if (myrpt->lastf2)
14355                   memset(myrpt->lastf2->data.ptr,0,myrpt->lastf2->datalen);
14356             } 
14357             if (f) f2 = ast_frdup(f);
14358             else f2 = NULL;
14359             f1 = myrpt->lastf2;
14360             myrpt->lastf2 = myrpt->lastf1;
14361             myrpt->lastf1 = f2;
14362             if (ismuted)
14363             {
14364                if (myrpt->lastf1)
14365                   memset(myrpt->lastf1->data.ptr,0,myrpt->lastf1->datalen);
14366                if (myrpt->lastf2)
14367                   memset(myrpt->lastf2->data.ptr,0,myrpt->lastf2->datalen);
14368             }
14369             if (f1)
14370             {
14371                if (phone_mode)
14372                   ast_write(myrpt->txchannel,f1);
14373                else
14374                   ast_write(myrpt->txchannel,f);
14375                ast_frfree(f1);
14376             }
14377          }
14378 #ifndef  OLD_ASTERISK
14379          else if (f->frametype == AST_FRAME_DTMF_BEGIN)
14380          {
14381             if (myrpt->lastf1)
14382                memset(myrpt->lastf1->data.ptr,0,myrpt->lastf1->datalen);
14383             if (myrpt->lastf2)
14384                memset(myrpt->lastf2->data.ptr,0,myrpt->lastf2->datalen);
14385             dtmfed = 1;
14386          }
14387 #endif
14388          if (f->frametype == AST_FRAME_DTMF)
14389          {
14390             if (myrpt->lastf1)
14391                memset(myrpt->lastf1->data.ptr,0,myrpt->lastf1->datalen);
14392             if (myrpt->lastf2)
14393                memset(myrpt->lastf2->data.ptr,0,myrpt->lastf2->datalen);
14394             dtmfed = 1;
14395             if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1)
14396             {
14397                if (debug) printf("@@@@ rpt:Hung Up\n");
14398                ast_frfree(f);
14399                break;
14400             }
14401          }
14402          if (f->frametype == AST_FRAME_TEXT)
14403          {
14404             if (handle_remote_data(myrpt,f->data.ptr) == -1)
14405             {
14406                if (debug) printf("@@@@ rpt:Hung Up\n");
14407                ast_frfree(f);
14408                break;
14409             }
14410          }
14411          if (f->frametype == AST_FRAME_CONTROL)
14412          {
14413             if (f->subclass == AST_CONTROL_HANGUP)
14414             {
14415                if (debug) printf("@@@@ rpt:Hung Up\n");
14416                ast_frfree(f);
14417                break;
14418             }
14419             /* if RX key */
14420             if (f->subclass == AST_CONTROL_RADIO_KEY)
14421             {
14422                if (debug == 7) printf("@@@@ rx key\n");
14423                keyed = 1;
14424                myrpt->rerxtimer = 0;
14425             }
14426             /* if RX un-key */
14427             if (f->subclass == AST_CONTROL_RADIO_UNKEY)
14428             {
14429                myrpt->rerxtimer = 0;
14430                if (debug == 7) printf("@@@@ rx un-key\n");
14431                keyed = 0;
14432             }
14433          }
14434          ast_frfree(f);
14435          continue;
14436       }
14437       if (who == myrpt->rxchannel) /* if it was a read from radio */
14438       {
14439          f = ast_read(myrpt->rxchannel);
14440          if (!f)
14441          {
14442             if (debug) printf("@@@@ link:Hung Up\n");
14443             break;
14444          }
14445          if (f->frametype == AST_FRAME_VOICE)
14446          {
14447             int myreming = 0;
14448 
14449             if(!strcmp(myrpt->remoterig, remote_rig_kenwood))
14450                myreming = reming;
14451 
14452             if (myreming || (!remkeyed) ||
14453             ((myrpt->remote) && (myrpt->remotetx)) ||
14454               ((myrpt->remmode != REM_MODE_FM) &&
14455                 notremming))
14456                memset(f->data.ptr,0,f->datalen); 
14457              ast_write(myrpt->pchannel,f);
14458          }
14459          else if (f->frametype == AST_FRAME_CONTROL)
14460          {
14461             if (f->subclass == AST_CONTROL_HANGUP)
14462             {
14463                if (debug) printf("@@@@ rpt:Hung Up\n");
14464                ast_frfree(f);
14465                break;
14466             }
14467             /* if RX key */
14468             if (f->subclass == AST_CONTROL_RADIO_KEY)
14469             {
14470                if (debug == 7) printf("@@@@ remote rx key\n");
14471                if (!myrpt->remotetx)
14472                {
14473                   remkeyed = 1;
14474                }
14475             }
14476             /* if RX un-key */
14477             if (f->subclass == AST_CONTROL_RADIO_UNKEY)
14478             {
14479                if (debug == 7) printf("@@@@ remote rx un-key\n");
14480                if (!myrpt->remotetx) 
14481                {
14482                   remkeyed = 0;
14483                }
14484             }
14485          }
14486          ast_frfree(f);
14487          continue;
14488       }
14489       if (who == myrpt->pchannel) /* if is remote mix output */
14490       {
14491          f = ast_read(myrpt->pchannel);
14492          if (!f)
14493          {
14494             if (debug) printf("@@@@ link:Hung Up\n");
14495             break;
14496          }
14497          if (f->frametype == AST_FRAME_VOICE)
14498          {
14499             ast_write(chan,f);
14500          }
14501          if (f->frametype == AST_FRAME_CONTROL)
14502          {
14503             if (f->subclass == AST_CONTROL_HANGUP)
14504             {
14505                if (debug) printf("@@@@ rpt:Hung Up\n");
14506                ast_frfree(f);
14507                break;
14508             }
14509          }
14510          ast_frfree(f);
14511          continue;
14512       }
14513       if ((myrpt->rxchannel != myrpt->txchannel) && 
14514          (who == myrpt->txchannel)) /* do this cuz you have to */
14515       {
14516          f = ast_read(myrpt->txchannel);
14517          if (!f)
14518          {
14519             if (debug) printf("@@@@ link:Hung Up\n");
14520             break;
14521          }
14522          if (f->frametype == AST_FRAME_CONTROL)
14523          {
14524             if (f->subclass == AST_CONTROL_HANGUP)
14525             {
14526                if (debug) printf("@@@@ rpt:Hung Up\n");
14527                ast_frfree(f);
14528                break;
14529             }
14530          }
14531          ast_frfree(f);
14532          continue;
14533       }
14534    }
14535    if (myrpt->p.archivedir)
14536    {
14537       char mycmd[100],*b,*b1;
14538 
14539       /* look at callerid to see what node this comes from */
14540       if (!chan->cid.cid_num) /* if doesn't have caller id */
14541       {
14542          b1 = "0";
14543       } else {
14544          ast_callerid_parse(chan->cid.cid_num,&b,&b1);
14545          ast_shrink_phone_number(b1);
14546       }
14547       sprintf(mycmd,"DISCONNECT,%s",b1);
14548       donodelog(myrpt,mycmd);
14549    }
14550    /* wait for telem to be done */
14551    while(myrpt->tele.next != &myrpt->tele) usleep(100000);
14552    sprintf(tmp,"mixmonitor stop %s",chan->name);
14553    ast_cli_command(nullfd,tmp);
14554    close(nullfd);
14555    rpt_mutex_lock(&myrpt->lock);
14556    myrpt->hfscanmode = 0;
14557    myrpt->hfscanstatus = 0;
14558    myrpt->remoteon = 0;
14559    rpt_mutex_unlock(&myrpt->lock);
14560    if (myrpt->lastf1) ast_frfree(myrpt->lastf1);
14561    myrpt->lastf1 = NULL;
14562    if (myrpt->lastf2) ast_frfree(myrpt->lastf2);
14563    myrpt->lastf2 = NULL;
14564    if ((iskenwood_pci4) && (myrpt->txchannel == myrpt->dahditxchannel))
14565    {
14566       z.radpar = DAHDI_RADPAR_UIOMODE;
14567       z.data = 3;
14568       if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
14569       {
14570          ast_log(LOG_ERROR,"Cannot set UIOMODE\n");
14571          return -1;
14572       }
14573       z.radpar = DAHDI_RADPAR_UIODATA;
14574       z.data = 3;
14575       if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_RADIO_SETPARAM,&z) == -1)
14576       {
14577          ast_log(LOG_ERROR,"Cannot set UIODATA\n");
14578          return -1;
14579       }
14580       i = DAHDI_OFFHOOK;
14581       if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_HOOK,&i) == -1)
14582       {
14583          ast_log(LOG_ERROR,"Cannot set hook\n");
14584          return -1;
14585       }
14586    }
14587    if (myrpt->iofd) close(myrpt->iofd);
14588    myrpt->iofd = -1;
14589    ast_hangup(myrpt->pchannel);
14590    if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel);
14591    ast_hangup(myrpt->rxchannel);
14592    closerem(myrpt);
14593    if (myrpt->p.rptnode)
14594    {
14595       rpt_mutex_lock(&myrpt->lock);
14596       for(i = 0; i < nrpts; i++)
14597       {
14598          if (!strcasecmp(rpt_vars[i].name,myrpt->p.rptnode))
14599          {
14600             rpt_vars[i].xlink = 0;
14601             break;
14602          }
14603       }
14604       rpt_mutex_unlock(&myrpt->lock);
14605    }
14606 #ifdef   OLD_ASTERISK
14607    LOCAL_USER_REMOVE(u);
14608 #endif
14609    return res;
14610 }

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

Definition at line 2171 of file app_rpt.c.

References ast_localtime().

Referenced by do_scheduler(), and rpt_tele_thread().

02172 {
02173    struct timeval when;
02174 
02175    when.tv_sec = *t;
02176    when.tv_usec = 0;
02177    ast_localtime(&when, lt, NULL);
02178 }

static int rpt_manager_do_stats ( struct mansession s,
const struct message m,
char *  str 
) [static]

Definition at line 14648 of file app_rpt.c.

References ast_free, ast_log(), ast_strdup, ast_strlen_zero(), astman_append(), astman_get_header(), rpt::callmode, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, rpt::exten, rpt::freq, rpt::keyed, rpt::lastdtmfcommand, rpt::links, rpt::lock, LOG_NOTICE, rpt::loginlevel, rpt::loginuser, MAX_STAT_LINKS, rpt::mustid, rpt_link::name, name, rpt_link::next, rpt::offset, rpt::p, rpt::parrotmode, rpt::powerlevel, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_USB, REM_SIMPLEX, rpt::remmode, rpt::remote, rpt::remoteon, rpt_manager_success(), rpt_mutex_lock, rpt_mutex_unlock, rpt::rxpl, rpt::rxplon, rpt::s, s, rpt::sysstate_cur, rpt::tailid, rpt::timeouts, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, rpt::totime, rpt::totimer, rpt::txkeyed, rpt::txpl, and rpt::txplon.

Referenced by manager_rpt_status().

14649 {
14650    int i,j,numoflinks;
14651    int dailytxtime, dailykerchunks;
14652    time_t now;
14653    int totalkerchunks, dailykeyups, totalkeyups, timeouts;
14654    int totalexecdcommands, dailyexecdcommands, hours, minutes, seconds;
14655    long long totaltxtime;
14656    struct   rpt_link *l;
14657    char *listoflinks[MAX_STAT_LINKS];  
14658    char *lastdtmfcommand,*parrot_ena;
14659    char *tot_state, *ider_state, *patch_state;
14660    char *reverse_patch_state, *sys_ena, *tot_ena, *link_ena, *patch_ena;
14661    char *sch_ena, *input_signal, *called_number, *user_funs, *tail_type;
14662    char *transmitterkeyed;
14663    const char *node = astman_get_header(m, "Node");
14664    struct rpt *myrpt;
14665 
14666    static char *not_applicable = "N/A";
14667 
14668    tot_state = ider_state = 
14669    patch_state = reverse_patch_state = 
14670    input_signal = not_applicable;
14671    called_number = lastdtmfcommand = transmitterkeyed = NULL;
14672 
14673    time(&now);
14674    for(i = 0; i < nrpts; i++)
14675    {
14676       if ((node)&&(!strcmp(node,rpt_vars[i].name))){
14677          rpt_manager_success(s,m);
14678 
14679          myrpt = &rpt_vars[i];
14680 
14681          if(myrpt->remote){ /* Remote base ? */
14682             char *loginuser, *loginlevel, *freq, *rxpl, *txpl, *modestr;
14683             char offset = 0, powerlevel = 0, rxplon = 0, txplon = 0, remoteon, remmode = 0, reportfmstuff;
14684             char offsetc,powerlevelc;
14685 
14686             loginuser = loginlevel = freq = rxpl = txpl = NULL;
14687             /* Make a copy of all stat variables while locked */
14688             rpt_mutex_lock(&myrpt->lock); /* LOCK */
14689             if((remoteon = myrpt->remoteon)){
14690                if(!ast_strlen_zero(myrpt->loginuser))
14691                   loginuser = ast_strdup(myrpt->loginuser);
14692                if(!ast_strlen_zero(myrpt->loginlevel))
14693                   loginlevel = ast_strdup(myrpt->loginlevel);
14694                if(!ast_strlen_zero(myrpt->freq))
14695                   freq = ast_strdup(myrpt->freq);
14696                if(!ast_strlen_zero(myrpt->rxpl))
14697                   rxpl = ast_strdup(myrpt->rxpl);
14698                if(!ast_strlen_zero(myrpt->txpl))
14699                   txpl = ast_strdup(myrpt->txpl);
14700                remmode = myrpt->remmode;
14701                offset = myrpt->offset;
14702                powerlevel = myrpt->powerlevel;
14703                rxplon = myrpt->rxplon;
14704                txplon = myrpt->txplon;       
14705             }
14706             rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
14707             astman_append(s, "IsRemoteBase: YES\r\n");
14708             astman_append(s, "RemoteOn: %s\r\n",(remoteon) ? "YES": "NO");
14709             if(remoteon){
14710                if(loginuser){
14711                   astman_append(s, "LogInUser: %s\r\n", loginuser);
14712                   ast_free(loginuser);
14713                }
14714                if(loginlevel){
14715                   astman_append(s, "LogInLevel: %s\r\n", loginlevel);
14716                   ast_free(loginlevel);
14717                }
14718                if(freq){
14719                   astman_append(s, "Freq: %s\r\n", freq);
14720                   ast_free(freq);
14721                }
14722                reportfmstuff = 0;
14723                switch(remmode){
14724                   case REM_MODE_FM:
14725                      modestr = "FM";   
14726                      reportfmstuff = 1;
14727                      break;
14728                   case REM_MODE_AM:
14729                      modestr = "AM";
14730                      break;
14731                   case REM_MODE_USB:
14732                      modestr = "USB";
14733                      break;
14734                   default:
14735                      modestr = "LSB";
14736                      break;
14737                }
14738                astman_append(s, "RemMode: %s\r\n", modestr);
14739                if(reportfmstuff){
14740                   switch(offset){
14741                      case REM_SIMPLEX:
14742                         offsetc = 'S';
14743                         break;
14744                      case REM_MINUS:
14745                         offsetc = '-';
14746                         break;
14747                      default:
14748                         offsetc = '+';
14749                         break;
14750                   }
14751                   astman_append(s, "RemOffset: %c\r\n", offsetc);
14752                   if(rxplon && rxpl){
14753                      astman_append(s, "RxPl: %s\r\n",rxpl);
14754                      ast_free(rxpl);
14755                   }
14756                   if(txplon && txpl){
14757                      astman_append(s, "TxPl: %s\r\n",txpl);
14758                      ast_free(txpl);
14759                   }
14760                }
14761                switch(powerlevel){
14762                   case REM_LOWPWR:
14763                      powerlevelc = 'L';
14764                      break;
14765                   case REM_MEDPWR:
14766                      powerlevelc = 'M';
14767                      break;
14768                   default:
14769                      powerlevelc = 'H';
14770                      break;
14771                }
14772                astman_append(s,"PowerLevel: %c\r\n", powerlevelc);
14773             }
14774             astman_append(s, "\r\n");
14775             return 0; /* End of remote base status reporting */
14776          }  
14777 
14778          /* ELSE Process as a repeater node */
14779          /* Make a copy of all stat variables while locked */
14780          rpt_mutex_lock(&myrpt->lock); /* LOCK */
14781          dailytxtime = myrpt->dailytxtime;
14782          totaltxtime = myrpt->totaltxtime;
14783          dailykeyups = myrpt->dailykeyups;
14784          totalkeyups = myrpt->totalkeyups;
14785          dailykerchunks = myrpt->dailykerchunks;
14786          totalkerchunks = myrpt->totalkerchunks;
14787          dailyexecdcommands = myrpt->dailyexecdcommands;
14788          totalexecdcommands = myrpt->totalexecdcommands;
14789          timeouts = myrpt->timeouts;
14790 
14791 
14792          /* Traverse the list of connected nodes */
14793          reverse_patch_state = "DOWN";
14794          numoflinks = 0;
14795          l = myrpt->links.next;
14796          while(l && (l != &myrpt->links)){
14797             if(numoflinks >= MAX_STAT_LINKS){
14798                ast_log(LOG_NOTICE,
14799                "maximum number of links exceeds %d in rpt_do_stats()!",MAX_STAT_LINKS);
14800                break;
14801             }
14802             if (l->name[0] == '0'){ /* Skip '0' nodes */
14803                reverse_patch_state = "UP";
14804                l = l->next;
14805                continue;
14806             }
14807             listoflinks[numoflinks] = ast_strdup(l->name);
14808             if(listoflinks[numoflinks] == NULL){
14809                break;
14810             }
14811             else{
14812                numoflinks++;
14813             }
14814             l = l->next;
14815          }
14816 
14817          if(myrpt->keyed)
14818             input_signal = "YES";
14819          else
14820             input_signal = "NO";
14821          
14822          if(myrpt->txkeyed)
14823             transmitterkeyed = "YES";
14824          else
14825             transmitterkeyed = "NO";
14826 
14827          if(myrpt->p.parrotmode)
14828             parrot_ena = "ENABLED";
14829          else
14830             parrot_ena = "DISABLED";
14831 
14832          if(myrpt->p.s[myrpt->p.sysstate_cur].txdisable)
14833             sys_ena = "DISABLED";
14834          else
14835             sys_ena = "ENABLED";
14836 
14837          if(myrpt->p.s[myrpt->p.sysstate_cur].totdisable)
14838             tot_ena = "DISABLED";
14839          else
14840             tot_ena = "ENABLED";
14841 
14842          if(myrpt->p.s[myrpt->p.sysstate_cur].linkfundisable)
14843             link_ena = "DISABLED";
14844          else
14845             link_ena = "ENABLED";
14846 
14847          if(myrpt->p.s[myrpt->p.sysstate_cur].autopatchdisable)
14848             patch_ena = "DISABLED";
14849          else
14850             patch_ena = "ENABLED";
14851 
14852          if(myrpt->p.s[myrpt->p.sysstate_cur].schedulerdisable)
14853             sch_ena = "DISABLED";
14854          else
14855             sch_ena = "ENABLED";
14856 
14857          if(myrpt->p.s[myrpt->p.sysstate_cur].userfundisable)
14858             user_funs = "DISABLED";
14859          else
14860             user_funs = "ENABLED";
14861 
14862          if(myrpt->p.s[myrpt->p.sysstate_cur].alternatetail)
14863             tail_type = "ALTERNATE";
14864          else
14865             tail_type = "STANDARD";
14866 
14867          if(!myrpt->totimer)
14868             tot_state = "TIMED OUT!";
14869          else if(myrpt->totimer != myrpt->p.totime)
14870             tot_state = "ARMED";
14871          else
14872             tot_state = "RESET";
14873 
14874          if(myrpt->tailid)
14875             ider_state = "QUEUED IN TAIL";
14876          else if(myrpt->mustid)
14877             ider_state = "QUEUED FOR CLEANUP";
14878          else
14879             ider_state = "CLEAN";
14880 
14881          switch(myrpt->callmode){
14882             case 1:
14883                patch_state = "DIALING";
14884                break;
14885             case 2:
14886                patch_state = "CONNECTING";
14887                break;
14888             case 3:
14889                patch_state = "UP";
14890                break;
14891 
14892             case 4:
14893                patch_state = "CALL FAILED";
14894                break;
14895 
14896             default:
14897                patch_state = "DOWN";
14898          }
14899 
14900          if(strlen(myrpt->exten)){
14901             called_number = ast_strdup(myrpt->exten);
14902          }
14903 
14904          if(strlen(myrpt->lastdtmfcommand)){
14905             lastdtmfcommand = ast_strdup(myrpt->lastdtmfcommand);
14906          }
14907          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
14908 
14909          astman_append(s, "IsRemoteBase: NO\r\n");
14910          astman_append(s, "NodeState: %d\r\n", myrpt->p.sysstate_cur);
14911          astman_append(s, "SignalOnInput: %s\r\n", input_signal);
14912          astman_append(s, "TransmitterKeyed: %s\r\n", transmitterkeyed);
14913          astman_append(s, "Transmitter: %s\r\n", sys_ena);
14914          astman_append(s, "Parrot: %s\r\n", parrot_ena);
14915          astman_append(s, "Scheduler: %s\r\n", sch_ena);
14916          astman_append(s, "TailLength: %s\r\n", tail_type);
14917          astman_append(s, "TimeOutTimer: %s\r\n", tot_ena);
14918          astman_append(s, "TimeOutTimerState: %s\r\n", tot_state);
14919          astman_append(s, "TimeOutsSinceSystemInitialization: %d\r\n", timeouts);
14920          astman_append(s, "IdentifierState: %s\r\n", ider_state);
14921          astman_append(s, "KerchunksToday: %d\r\n", dailykerchunks);
14922          astman_append(s, "KerchunksSinceSystemInitialization: %d\r\n", totalkerchunks);
14923          astman_append(s, "KeyupsToday: %d\r\n", dailykeyups);
14924          astman_append(s, "KeyupsSinceSystemInitialization: %d\r\n", totalkeyups);
14925          astman_append(s, "DtmfCommandsToday: %d\r\n", dailyexecdcommands);
14926          astman_append(s, "DtmfCommandsSinceSystemInitialization: %d\r\n", totalexecdcommands);
14927          astman_append(s, "LastDtmfCommandExecuted: %s\r\n", 
14928          (lastdtmfcommand && strlen(lastdtmfcommand)) ? lastdtmfcommand : not_applicable);
14929          hours = dailytxtime/3600000;
14930          dailytxtime %= 3600000;
14931          minutes = dailytxtime/60000;
14932          dailytxtime %= 60000;
14933          seconds = dailytxtime/1000;
14934          dailytxtime %= 1000;
14935 
14936          astman_append(s, "TxTimeToday: %02d:%02d:%02d.%d\r\n",
14937             hours, minutes, seconds, dailytxtime);
14938 
14939          hours = (int) totaltxtime/3600000;
14940          totaltxtime %= 3600000;
14941          minutes = (int) totaltxtime/60000;
14942          totaltxtime %= 60000;
14943          seconds = (int)  totaltxtime/1000;
14944          totaltxtime %= 1000;
14945 
14946          astman_append(s, "TxTimeSinceSystemInitialization: %02d:%02d:%02d.%d\r\n",
14947              hours, minutes, seconds, (int) totaltxtime);
14948 
14949          sprintf(str, "NodesCurrentlyConnectedToUs: ");
14950                         if(!numoflinks){
14951                          strcat(str,"<NONE>");
14952                         }
14953          else{
14954             for(j = 0 ;j < numoflinks; j++){
14955                sprintf(str+strlen(str), "%s", listoflinks[j]);
14956                if(j < numoflinks - 1)
14957                   strcat(str,",");
14958             }
14959          }
14960          astman_append(s,"%s\r\n", str);
14961 
14962          astman_append(s, "Autopatch: %s\r\n", patch_ena);
14963          astman_append(s, "AutopatchState: %s\r\n", patch_state);
14964          astman_append(s, "AutopatchCalledNumber: %s\r\n",
14965          (called_number && strlen(called_number)) ? called_number : not_applicable);
14966          astman_append(s, "ReversePatchIaxrptConnected: %s\r\n", reverse_patch_state);
14967          astman_append(s, "UserLinkingCommands: %s\r\n", link_ena);
14968          astman_append(s, "UserFunctions: %s\r\n", user_funs);
14969 
14970          for(j = 0; j < numoflinks; j++){ /* ast_free() all link names */
14971             ast_free(listoflinks[j]);
14972          }
14973          if(called_number){
14974             ast_free(called_number);
14975          }
14976          if(lastdtmfcommand){
14977             ast_free(lastdtmfcommand);
14978          }
14979          astman_append(s, "\r\n"); /* We're Done! */
14980               return 0;
14981       }
14982    }
14983    astman_send_error(s, m, "RptStatus unknown or missing node");
14984    return -1;
14985 }

static void rpt_manager_success ( struct mansession s,
const struct message m 
) [static]

Definition at line 14636 of file app_rpt.c.

References ast_strlen_zero(), astman_append(), astman_get_header(), and s.

Referenced by manager_rpt_status(), and rpt_manager_do_stats().

14637 {
14638    const char *id = astman_get_header(m, "ActionID");
14639    if (!ast_strlen_zero(id))
14640       astman_append(s, "ActionID: %s\r\n", id);
14641    astman_append(s, "Response: Success\r\n");
14642 }

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

Definition at line 12914 of file app_rpt.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load, ast_free, 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_strdup, ast_test_flag, ast_variable_retrieve(), config_flags, load_rpt_vars(), lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, name, nodeloglock, REM_LOWPWR, REM_MODE_FM, REM_SIMPLEX, and retreive_memory().

Referenced by load_module().

12915 {
12916 int   i,n;
12917 pthread_attr_t attr;
12918 struct ast_config *cfg;
12919 char *this,*val;
12920 
12921    /* init nodelog queue */
12922    nodelog.next = nodelog.prev = &nodelog;
12923    /* go thru all the specified repeaters */
12924    this = NULL;
12925    n = 0;
12926 #ifndef OLD_ASTERISK
12927    /* wait until asterisk starts */
12928         while(!ast_test_flag(&ast_options,AST_OPT_FLAG_FULLY_BOOTED))
12929                 usleep(250000);
12930 #endif
12931 #ifdef   NEW_ASTERISK
12932    rpt_vars[n].cfg = ast_config_load("rpt.conf",config_flags);
12933 #else
12934    rpt_vars[n].cfg = ast_config_load("rpt.conf");
12935 #endif
12936    cfg = rpt_vars[n].cfg;
12937    if (!cfg) {
12938       ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf.  Radio Repeater disabled.\n");
12939       pthread_exit(NULL);
12940    }
12941    while((this = ast_category_browse(cfg,this)) != NULL)
12942    {
12943       for(i = 0 ; i < strlen(this) ; i++){
12944          if((this[i] < '0') || (this[i] > '9'))
12945             break;
12946       }
12947       if(i != strlen(this)) continue; /* Not a node defn */
12948       memset(&rpt_vars[n],0,sizeof(rpt_vars[n]));
12949       rpt_vars[n].name = ast_strdup(this);
12950       val = (char *) ast_variable_retrieve(cfg,this,"rxchannel");
12951       if (val) rpt_vars[n].rxchanname = ast_strdup(val);
12952       val = (char *) ast_variable_retrieve(cfg,this,"txchannel");
12953       if (val) rpt_vars[n].txchanname = ast_strdup(val);
12954       rpt_vars[n].remote = 0;
12955       rpt_vars[n].remoterig = "";
12956       val = (char *) ast_variable_retrieve(cfg,this,"remote");
12957       if (val) 
12958       {
12959          rpt_vars[n].remoterig = ast_strdup(val);
12960          rpt_vars[n].remote = 1;
12961       }
12962       val = (char *) ast_variable_retrieve(cfg,this,"radiotype");
12963       if (val) rpt_vars[n].remoterig = ast_strdup(val);
12964       ast_mutex_init(&rpt_vars[n].lock);
12965       ast_mutex_init(&rpt_vars[n].remlock);
12966       ast_mutex_init(&rpt_vars[n].statpost_lock);
12967       rpt_vars[n].tele.next = &rpt_vars[n].tele;
12968       rpt_vars[n].tele.prev = &rpt_vars[n].tele;
12969       rpt_vars[n].rpt_thread = AST_PTHREADT_NULL;
12970       rpt_vars[n].tailmessagen = 0;
12971 #ifdef   _MDC_DECODE_H_
12972       rpt_vars[n].mdc = mdc_decoder_new(8000);
12973 #endif
12974       n++;
12975    }
12976    nrpts = n;
12977    ast_config_destroy(cfg);
12978 
12979    /* start em all */
12980    for(i = 0; i < n; i++)
12981    {
12982       load_rpt_vars(i,1);
12983 
12984       /* if is a remote, dont start one for it */
12985       if (rpt_vars[i].remote)
12986       {
12987          if(retreive_memory(&rpt_vars[i],"init")){ /* Try to retreive initial memory channel */
12988             if (!strcmp(rpt_vars[i].remoterig,remote_rig_rtx450))
12989                strncpy(rpt_vars[i].freq, "446.500", sizeof(rpt_vars[i].freq) - 1);
12990             else
12991                strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1);
12992             strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1);
12993 
12994             strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1);
12995             rpt_vars[i].remmode = REM_MODE_FM;
12996             rpt_vars[i].offset = REM_SIMPLEX;
12997             rpt_vars[i].powerlevel = REM_LOWPWR;
12998          }
12999          continue;
13000       }
13001       else /* is a normal repeater */
13002       {
13003           rpt_vars[i].p.memory = rpt_vars[i].name;
13004          if(retreive_memory(&rpt_vars[i],"radiofreq")){ /* Try to retreive initial memory channel */
13005             if (!strcmp(rpt_vars[i].remoterig,remote_rig_rtx450))
13006                strncpy(rpt_vars[i].freq, "446.500", sizeof(rpt_vars[i].freq) - 1);
13007             else if (!strcmp(rpt_vars[i].remoterig,remote_rig_rtx150))
13008                strncpy(rpt_vars[i].freq, "146.580", sizeof(rpt_vars[i].freq) - 1);
13009             strncpy(rpt_vars[i].rxpl, "100.0", sizeof(rpt_vars[i].rxpl) - 1);
13010 
13011             strncpy(rpt_vars[i].txpl, "100.0", sizeof(rpt_vars[i].txpl) - 1);
13012             rpt_vars[i].remmode = REM_MODE_FM;
13013             rpt_vars[i].offset = REM_SIMPLEX;
13014             rpt_vars[i].powerlevel = REM_LOWPWR;
13015          }
13016          ast_log(LOG_NOTICE,"Normal Repeater Init  %s  %s  %s\n",rpt_vars[i].name, rpt_vars[i].remoterig, rpt_vars[i].freq);
13017       }
13018       if (!rpt_vars[i].p.ident)
13019       {
13020          ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name);
13021          ast_config_destroy(cfg);
13022          pthread_exit(NULL);
13023       }
13024            pthread_attr_init(&attr);
13025            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
13026       ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
13027    }
13028    usleep(500000);
13029    time(&starttime);
13030    for(;;)
13031    {
13032       /* Now monitor each thread, and restart it if necessary */
13033       for(i = 0; i < n; i++)
13034       { 
13035          int rv;
13036          if (rpt_vars[i].remote) continue;
13037          if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP) 
13038             rv = -1;
13039          else
13040             rv = pthread_kill(rpt_vars[i].rpt_thread,0);
13041          if (rv)
13042          {
13043             if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15)
13044             {
13045                if(rpt_vars[i].threadrestarts >= 5)
13046                {
13047                   ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n");
13048                   exit(1); /* Stuck in a restart loop, kill Asterisk and start over */
13049                }
13050                else
13051                {
13052                   ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name);
13053                   rpt_vars[i].threadrestarts++;
13054                }
13055             }
13056             else
13057                rpt_vars[i].threadrestarts = 0;
13058 
13059             rpt_vars[i].lastthreadrestarttime = time(NULL);
13060                  pthread_attr_init(&attr);
13061                  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
13062             ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]);
13063             /* if (!rpt_vars[i].xlink) */
13064                ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name);
13065          }
13066 
13067       }
13068       for(;;)
13069       {
13070          struct nodelog *nodep;
13071          char *space,datestr[100],fname[300];
13072          int fd;
13073 
13074          ast_mutex_lock(&nodeloglock);
13075          nodep = nodelog.next;
13076          if(nodep == &nodelog) /* if nothing in queue */
13077          {
13078             ast_mutex_unlock(&nodeloglock);
13079             break;
13080          }
13081          remque((struct qelem *)nodep);
13082          ast_mutex_unlock(&nodeloglock);
13083          space = strchr(nodep->str,' ');
13084          if (!space) 
13085          {
13086             ast_free(nodep);
13087             continue;
13088          }
13089          *space = 0;
13090          strftime(datestr,sizeof(datestr) - 1,"%Y%m%d",
13091             localtime(&nodep->timestamp));
13092          sprintf(fname,"%s/%s/%s.txt",nodep->archivedir,
13093             nodep->str,datestr);
13094          fd = open(fname,O_WRONLY | O_CREAT | O_APPEND,0600);
13095          if (fd == -1)
13096          {
13097             ast_log(LOG_ERROR,"Cannot open node log file %s for write",space + 1);
13098             ast_free(nodep);
13099             continue;
13100          }
13101          if (write(fd,space + 1,strlen(space + 1)) !=
13102             strlen(space + 1))
13103          {
13104             ast_log(LOG_ERROR,"Cannot write node log file %s for write",space + 1);
13105             ast_free(nodep);
13106             continue;
13107          }
13108          close(fd);
13109          ast_free(nodep);
13110       }
13111       sleep(2);
13112    }
13113    ast_config_destroy(cfg);
13114    pthread_exit(NULL);
13115 }

static int rpt_push_alt_macro ( struct rpt myrpt,
char *  sptr 
) [static]

Definition at line 3138 of file app_rpt.c.

References ast_log(), rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, rpt_mutex_lock, and rpt_mutex_unlock.

Referenced by rpt_do_fun1(), and rpt_exec().

03139 {
03140    int   busy=0;
03141 
03142    rpt_mutex_lock(&myrpt->lock);
03143    if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(sptr)){
03144       rpt_mutex_unlock(&myrpt->lock);
03145       busy=1;
03146    }
03147    if(!busy){
03148       int x;
03149       if (debug)ast_log(LOG_NOTICE, "rpt_push_alt_macro %s\n",sptr);
03150       myrpt->macrotimer = MACROTIME;
03151       for(x = 0; *(sptr + x); x++)
03152           myrpt->macrobuf[x] = *(sptr + x) | 0x80;
03153       *(sptr + x) = 0;
03154    }
03155    rpt_mutex_unlock(&myrpt->lock);
03156 
03157    if(busy)ast_log(LOG_WARNING, "Function decoder busy on app_rpt command macro.\n");
03158 
03159    return busy;
03160 }

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

Definition at line 3934 of file app_rpt.c.

References __mklinklist(), ACT_TIMEOUT_WARNING, ARB_ALPHA, AST_CDR_FLAG_POST_DISABLED, ast_fileexists(), AST_FORMAT_SLINEAR, ast_free, ast_hangup(), ast_log(), ast_malloc, 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_strdup, 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_PARROT, DLY_TELEM, DLY_UNKEY, ast_channel::fds, finddelim(), 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, 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, rpt_tele::parrot, PARROT, PARROTFILE, play_tone(), PLAYBACK, 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(), saynode(), saynum(), SCAN, SCANSTAT, service_scan(), set_ft897(), set_ic706(), set_mode_ft897(), set_mode_ic706(), set_tm271(), setdtr(), setkenwood(), setrbi(), SETREMOTE, simple_command_ft897(), split_freq(), STATS_TIME, STATS_TIME_LOCAL, STATS_VERSION, STATUS, strsep(), rpt_tele::submode, TAILMSG, telem_any(), telem_lookup(), TERM, TEST_TONE, rpt_link::thisconnected, TIMEOUT, TIMEOUT_WARNING, TOPKEY, TOPKEYN, TUNE, UNAUTHTX, UNKEY, and wait_interval().

Referenced by rpt_telemetry().

03935 {
03936 struct dahdi_confinfo ci;  /* conference info */
03937 int   res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x;
03938 struct   rpt_tele *mytele = (struct rpt_tele *)this;
03939 struct  rpt_tele *tlist;
03940 struct   rpt *myrpt;
03941 struct   rpt_link *l,*l1,linkbase;
03942 struct   ast_channel *mychannel;
03943 int id_malloc, vmajor, vminor, m;
03944 char *p,*ct,*ct_copy,*ident, *nodename,*cp;
03945 time_t t;
03946 #ifdef   NEW_ASTERISK
03947 struct ast_tm localtm;
03948 #else
03949 struct tm localtm;
03950 #endif
03951 char lbuf[MAXLINKLIST],*strs[MAXLINKLIST];
03952 int   i,ns,rbimode;
03953 char mhz[MAXREMSTR];
03954 char decimals[MAXREMSTR];
03955 char  mystr[200];
03956 struct dahdi_params par;
03957 
03958 
03959    /* get a pointer to myrpt */
03960    myrpt = mytele->rpt;
03961 
03962    /* Snag copies of a few key myrpt variables */
03963    rpt_mutex_lock(&myrpt->lock);
03964    nodename = ast_strdup(myrpt->name);
03965    if(!nodename)
03966    {
03967        fprintf(stderr,"rpt:Sorry unable strdup nodename\n");
03968        rpt_mutex_lock(&myrpt->lock);
03969        remque((struct qelem *)mytele);
03970        ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
03971        rpt_mutex_unlock(&myrpt->lock);
03972        ast_free(mytele);
03973        pthread_exit(NULL);
03974    }
03975 
03976    if (myrpt->p.ident){
03977       ident = ast_strdup(myrpt->p.ident);
03978          if(!ident)
03979       {
03980                  fprintf(stderr,"rpt:Sorry unable strdup ident\n");
03981          rpt_mutex_lock(&myrpt->lock);
03982                   remque((struct qelem *)mytele);
03983                   ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",
03984          __LINE__, mytele->mode); /*@@@@@@@@@@@*/
03985                   rpt_mutex_unlock(&myrpt->lock);
03986          ast_free(nodename);
03987                   ast_free(mytele);
03988                   pthread_exit(NULL);
03989          }
03990       else{
03991          id_malloc = 1;
03992       }
03993    }
03994    else
03995    {
03996       ident = "";
03997       id_malloc = 0;
03998    }
03999    rpt_mutex_unlock(&myrpt->lock);
04000       
04001 
04002 
04003    /* allocate a pseudo-channel thru asterisk */
04004    mychannel = ast_request("DAHDI",AST_FORMAT_SLINEAR,"pseudo",NULL);
04005    if (!mychannel)
04006    {
04007       fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
04008       rpt_mutex_lock(&myrpt->lock);
04009       remque((struct qelem *)mytele);
04010       ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
04011       rpt_mutex_unlock(&myrpt->lock);
04012       ast_free(nodename);
04013       if(id_malloc)
04014          ast_free(ident);
04015       ast_free(mytele);    
04016       pthread_exit(NULL);
04017    }
04018 #ifdef   AST_CDR_FLAG_POST_DISABLED
04019    if (mychannel->cdr) 
04020       ast_set_flag(mychannel->cdr,AST_CDR_FLAG_POST_DISABLED);
04021 #endif
04022    rpt_mutex_lock(&myrpt->lock);
04023    mytele->chan = mychannel;
04024    rpt_mutex_unlock(&myrpt->lock);
04025 
04026    while((mytele->mode != SETREMOTE) && (mytele->mode != UNKEY) &&
04027       (mytele->mode != LINKUNKEY))
04028    {  
04029                 rpt_mutex_lock(&myrpt->lock);
04030       if (!myrpt->active_telem)
04031       {
04032          myrpt->active_telem = mytele;
04033                    rpt_mutex_unlock(&myrpt->lock);
04034          break;
04035       }
04036                 rpt_mutex_unlock(&myrpt->lock);
04037       usleep(100000);
04038    }
04039 
04040    /* make a conference for the tx */
04041    ci.chan = 0;
04042    /* If the telemetry is only intended for a local audience, */
04043    /* only connect the ID audio to the local tx conference so */
04044    /* linked systems can't hear it */
04045    ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) || 
04046       (mytele->mode == TAILMSG) || (mytele->mode == LINKUNKEY) || (mytele->mode == TIMEOUT) || 
04047       (mytele->mode == PARROT) || (mytele->mode == STATS_TIME_LOCAL)) ? 
04048          myrpt->txconf : myrpt->conf);
04049    ci.confmode = DAHDI_CONF_CONFANN;
04050    /* first put the channel on the conference in announce mode */
04051    if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1)
04052    {
04053       ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04054       rpt_mutex_lock(&myrpt->lock);
04055       myrpt->active_telem = NULL;
04056       remque((struct qelem *)mytele);
04057       rpt_mutex_unlock(&myrpt->lock);
04058       ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
04059       ast_free(nodename);
04060       if(id_malloc)
04061          ast_free(ident);
04062       ast_free(mytele);    
04063       ast_hangup(mychannel);
04064       pthread_exit(NULL);
04065    }
04066    ast_stopstream(mychannel);
04067    switch(mytele->mode)
04068    {
04069        case ID:
04070        case ID1:
04071       /* wait a bit */
04072       wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel);
04073       res = telem_any(myrpt,mychannel, ident); 
04074       imdone=1;   
04075       break;
04076       
04077        case TAILMSG:
04078       res = ast_streamfile(mychannel, myrpt->p.tailmessages[myrpt->tailmessagen], mychannel->language); 
04079       break;
04080       
04081        case IDTALKOVER:
04082          p = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "idtalkover");
04083          if(p)
04084          res = telem_any(myrpt,mychannel, p); 
04085       imdone=1;   
04086          break;
04087             
04088        case PROC:
04089       /* wait a little bit longer */
04090       wait_interval(myrpt, DLY_TELEM, mychannel);
04091       res = telem_lookup(myrpt, mychannel, myrpt->name, "patchup");
04092       if(res < 0){ /* Then default message */
04093          res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language);
04094       }
04095       break;
04096        case TERM:
04097       /* wait a little bit longer */
04098       wait_interval(myrpt, DLY_CALLTERM, mychannel);
04099       res = telem_lookup(myrpt, mychannel, myrpt->name, "patchdown");
04100       if(res < 0){ /* Then default message */
04101          res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language);
04102       }
04103       break;
04104        case COMPLETE:
04105       /* wait a little bit */
04106       wait_interval(myrpt, DLY_TELEM, mychannel);
04107       res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
04108       break;
04109        case MACRO_NOTFOUND:
04110       /* wait a little bit */
04111       wait_interval(myrpt, DLY_TELEM, mychannel);
04112       res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language);
04113       break;
04114        case MACRO_BUSY:
04115       /* wait a little bit */
04116       wait_interval(myrpt, DLY_TELEM, mychannel);
04117       res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language);
04118       break;
04119        case UNKEY:
04120       if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */
04121          imdone = 1;
04122          break;
04123       }
04124          
04125       /*
04126       * Reset the Unkey to CT timer
04127       */
04128 
04129       x = get_wait_interval(myrpt, DLY_UNKEY);
04130       rpt_mutex_lock(&myrpt->lock);
04131       myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */
04132       rpt_mutex_unlock(&myrpt->lock);
04133 
04134       /*
04135       * If there's one already queued, don't do another
04136       */
04137 
04138       tlist = myrpt->tele.next;
04139       unkeys_queued = 0;
04140                 if (tlist != &myrpt->tele)
04141                 {
04142                         rpt_mutex_lock(&myrpt->lock);
04143                         while(tlist != &myrpt->tele){
04144                                 if (tlist->mode == UNKEY) unkeys_queued++;
04145                                 tlist = tlist->next;
04146                         }
04147                         rpt_mutex_unlock(&myrpt->lock);
04148       }
04149       if( unkeys_queued > 1){
04150          imdone = 1;
04151          break;
04152       }
04153 
04154       /* Wait for the telemetry timer to expire */
04155       /* Periodically check the timer since it can be re-initialized above */
04156       while(myrpt->unkeytocttimer)
04157       {
04158          int ctint;
04159          if(myrpt->unkeytocttimer > 100)
04160             ctint = 100;
04161          else
04162             ctint = myrpt->unkeytocttimer;
04163          ast_safe_sleep(mychannel, ctint);
04164          rpt_mutex_lock(&myrpt->lock);
04165          if(myrpt->unkeytocttimer < ctint)
04166             myrpt->unkeytocttimer = 0;
04167          else
04168             myrpt->unkeytocttimer -= ctint;
04169          rpt_mutex_unlock(&myrpt->lock);
04170       }
04171    
04172       /*
04173       * Now, the carrier on the rptr rx should be gone. 
04174       * If it re-appeared, then forget about sending the CT
04175       */
04176       if(myrpt->keyed){
04177          imdone = 1;
04178          break;
04179       }
04180       
04181       rpt_mutex_lock(&myrpt->lock); /* Update the kerchunk counters */
04182       myrpt->dailykerchunks++;
04183       myrpt->totalkerchunks++;
04184       rpt_mutex_unlock(&myrpt->lock);
04185    
04186       haslink = 0;
04187       hastx = 0;
04188       hasremote = 0;    
04189       l = myrpt->links.next;
04190       if (l != &myrpt->links)
04191       {
04192          rpt_mutex_lock(&myrpt->lock);
04193          while(l != &myrpt->links)
04194          {
04195             if (l->name[0] == '0')
04196             {
04197                l = l->next;
04198                continue;
04199             }
04200             haslink = 1;
04201             if (l->mode) {
04202                hastx++;
04203                if (l->isremote) hasremote++;
04204             }
04205             l = l->next;
04206          }
04207          rpt_mutex_unlock(&myrpt->lock);
04208       }
04209       if (haslink)
04210       {
04211 
04212          res = telem_lookup(myrpt,mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx");
04213          if(res)
04214             ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name);
04215          
04216       
04217          /* if in remote cmd mode, indicate it */
04218          if (myrpt->cmdnode[0])
04219          {
04220             ast_safe_sleep(mychannel,200);
04221             res = telem_lookup(myrpt,mychannel, myrpt->name, "cmdmode");
04222             if(res)
04223                ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name);
04224             ast_stopstream(mychannel);
04225          }
04226       }
04227       else if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */
04228          ct_copy = ast_strdup(ct);
04229          if(ct_copy)
04230          {
04231             res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
04232             ast_free(ct_copy);
04233          }
04234          else
04235             res = -1;
04236          if(res)
04237             ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);     
04238       }  
04239       if (hasremote && (!myrpt->cmdnode[0]))
04240       {
04241          /* set for all to hear */
04242          ci.chan = 0;
04243          ci.confno = myrpt->conf;
04244          ci.confmode = DAHDI_CONF_CONFANN;
04245          /* first put the channel on the conference in announce mode */
04246          if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1)
04247          {
04248             ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04249             rpt_mutex_lock(&myrpt->lock);
04250             myrpt->active_telem = NULL;
04251             remque((struct qelem *)mytele);
04252             rpt_mutex_unlock(&myrpt->lock);
04253             ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
04254             ast_free(nodename);
04255             if(id_malloc)
04256                ast_free(ident);
04257             ast_free(mytele);    
04258             ast_hangup(mychannel);
04259             pthread_exit(NULL);
04260          }
04261          if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */
04262             ast_safe_sleep(mychannel,200);
04263             ct_copy = ast_strdup(ct);
04264             if(ct_copy)
04265             {
04266                res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
04267                ast_free(ct_copy);
04268             }
04269             else
04270                res = -1;
04271       
04272             if(res)
04273                ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);     
04274          }  
04275       }
04276 #if   defined(_MDC_DECODE_H_) && defined(MDC_SAY_WHEN_DOING_CT)
04277       if (myrpt->lastunit)
04278       {
04279          char mystr[10];
04280 
04281          ast_safe_sleep(mychannel,200);
04282          /* set for all to hear */
04283          ci.chan = 0;
04284          ci.confno = myrpt->txconf;
04285          ci.confmode = DAHDI_CONF_CONFANN;
04286          /* first put the channel on the conference in announce mode */
04287          if (ioctl(mychannel->fds[0],DAHDI_SETCONF,&ci) == -1)
04288          {
04289             ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n");
04290             rpt_mutex_lock(&myrpt->lock);
04291             myrpt->active_telem = NULL;
04292             remque((struct qelem *)mytele);
04293             rpt_mutex_unlock(&myrpt->lock);
04294             ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
04295             ast_free(nodename);
04296             if(id_malloc)
04297                ast_free(ident);
04298             ast_free(mytele);    
04299             ast_hangup(mychannel);
04300             pthread_exit(NULL);
04301          }
04302          sprintf(mystr,"%04x",myrpt->lastunit);
04303          myrpt->lastunit = 0;
04304          ast_say_character_str(mychannel,mystr,NULL,mychannel->language);
04305          break;
04306       }
04307 #endif
04308       imdone = 1;
04309       break;
04310        case LINKUNKEY:
04311       if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */
04312          imdone = 1;
04313          break;
04314       }
04315          
04316       /*
04317       * Reset the Unkey to CT timer
04318       */
04319 
04320       x = get_wait_interval(myrpt, DLY_LINKUNKEY);
04321       mytele->mylink.linkunkeytocttimer = x; /* Must be protected as it is changed below */
04322 
04323       /*
04324       * If there's one already queued, don't do another
04325       */
04326 
04327       tlist = myrpt->tele.next;
04328       unkeys_queued = 0;
04329                 if (tlist != &myrpt->tele)
04330                 {
04331                         rpt_mutex_lock(&myrpt->lock);
04332                         while(tlist != &myrpt->tele){
04333                                 if (tlist->mode == LINKUNKEY) unkeys_queued++;
04334                                 tlist = tlist->next;
04335                         }
04336                         rpt_mutex_unlock(&myrpt->lock);
04337       }
04338       if( unkeys_queued > 1){
04339          imdone = 1;
04340          break;
04341       }
04342 
04343       /* Wait for the telemetry timer to expire */
04344       /* Periodically check the timer since it can be re-initialized above */
04345       while(mytele->mylink.linkunkeytocttimer)
04346       {
04347          int ctint;
04348          if(mytele->mylink.linkunkeytocttimer > 100)
04349             ctint = 100;
04350          else
04351             ctint = mytele->mylink.linkunkeytocttimer;
04352          ast_safe_sleep(mychannel, ctint);
04353          rpt_mutex_lock(&myrpt->lock);
04354          if(mytele->mylink.linkunkeytocttimer < ctint)
04355             mytele->mylink.linkunkeytocttimer = 0;
04356          else
04357             mytele->mylink.linkunkeytocttimer -= ctint;
04358          rpt_mutex_unlock(&myrpt->lock);
04359       }
04360    
04361       if((ct = (char *) ast_variable_retrieve(myrpt->cfg, nodename, "linkunkeyct"))){ /* Unlinked Courtesy Tone */
04362          ct_copy = ast_strdup(ct);
04363          if(ct_copy){
04364             res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy);
04365             ast_free(ct_copy);
04366          }
04367          else
04368             res = -1;
04369          if(res)
04370             ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name);     
04371       }  
04372       imdone = 1;
04373       break;
04374        case REMDISC:
04375       /* wait a little bit */
04376       wait_interval(myrpt, DLY_TELEM, mychannel);
04377       l = myrpt->links.next;
04378       haslink = 0;
04379       /* dont report if a link for this one still on system */
04380       if (l != &myrpt->links)
04381       {
04382          rpt_mutex_lock(&myrpt->lock);
04383          while(l != &myrpt->links)
04384          {
04385             if (l->name[0] == '0')
04386             {
04387                l = l->next;
04388                continue;
04389             }
04390             if (!strcmp(l->name,mytele->mylink.name))
04391             {
04392                haslink = 1;
04393                break;
04394             }
04395             l = l->next;
04396          }
04397          rpt_mutex_unlock(&myrpt->lock);
04398       }
04399       if (haslink)
04400       {
04401          imdone = 1;
04402          break;
04403       }
04404       res = saynode(myrpt,mychannel,mytele->mylink.name);
04405       if (!res) 
04406           res = ast_streamfile(mychannel, ((mytele->mylink.hasconnected) ? 
04407          "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language);
04408       break;
04409        case REMALREADY:
04410       /* wait a little bit */
04411       wait_interval(myrpt, DLY_TELEM, mychannel);
04412       res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language);
04413       break;
04414        case REMNOTFOUND:
04415       /* wait a little bit */
04416       wait_interval(myrpt, DLY_TELEM, mychannel);
04417       res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language);
04418       break;
04419        case REMGO:
04420       /* wait a little bit */
04421       wait_interval(myrpt, DLY_TELEM, mychannel);
04422       res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language);
04423       break;
04424        case CONNECTED:
04425       /* wait a little bit */
04426       wait_interval(myrpt, DLY_TELEM,  mychannel);
04427       res = saynode(myrpt,mychannel,mytele->mylink.name);
04428       if (!res)
04429           res = ast_streamfile(mychannel, "rpt/connected", mychannel->language);
04430       if (!res) 
04431          res = ast_waitstream(mychannel, "");
04432       else
04433           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04434       ast_stopstream(mychannel);
04435       res = ast_streamfile(mychannel, "digits/2", mychannel->language);
04436       if (!res) 
04437          res = ast_waitstream(mychannel, "");
04438       else
04439           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04440       ast_stopstream(mychannel);
04441       res = saynode(myrpt,mychannel,myrpt->name);
04442       imdone = 1;
04443       break;
04444        case CONNFAIL:
04445       res = saynode(myrpt,mychannel,mytele->mylink.name);
04446       if (!res) 
04447           res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language);
04448       break;
04449        case MEMNOTFOUND:
04450       /* wait a little bit */
04451       wait_interval(myrpt, DLY_TELEM, mychannel);
04452       res = ast_streamfile(mychannel, "rpt/memory_notfound", mychannel->language);
04453       break;
04454        case PLAYBACK:
04455       /* wait a little bit */
04456       wait_interval(myrpt, DLY_TELEM, mychannel);
04457       res = ast_streamfile(mychannel, mytele->param, mychannel->language);
04458       break;
04459        case TOPKEY:
04460       /* wait a little bit */
04461       wait_interval(myrpt, DLY_TELEM, mychannel);
04462       for(i = 0; i < TOPKEYN; i++)
04463       {
04464          if (!myrpt->topkey[i].node[0]) continue;
04465          if ((!myrpt->topkeylong) && (myrpt->topkey[i].keyed)) continue;
04466          res = saynode(myrpt, mychannel,  myrpt->topkey[i].node);
04467          if (!res) res = sayfile(mychannel,(myrpt->topkey[i].keyed) ?
04468             "rpt/keyedfor" : "rpt/unkeyedfor");
04469          if (!res) res = saynum(mychannel,
04470             myrpt->topkey[i].timesince);
04471          if (!res) res = sayfile(mychannel,"rpt/seconds");
04472          if (!myrpt->topkeylong) break;
04473       }
04474       imdone = 1;
04475       break;
04476        case SETREMOTE:
04477       ast_mutex_lock(&myrpt->remlock);
04478       res = 0;
04479       if(!strcmp(myrpt->remoterig, remote_rig_ft897))
04480       {
04481          res = set_ft897(myrpt);
04482       }
04483       else if(!strcmp(myrpt->remoterig, remote_rig_tm271))
04484       {
04485          res = set_tm271(myrpt);
04486       }
04487       else if(!strcmp(myrpt->remoterig, remote_rig_ic706))
04488       {
04489          res = set_ic706(myrpt);
04490       }
04491 #ifdef HAVE_IOPERM
04492       else if(!strcmp(myrpt->remoterig, remote_rig_rbi)||!strcmp(myrpt->remoterig, remote_rig_ppp16))
04493       {
04494          if (ioperm(myrpt->p.iobase,1,1) == -1)
04495          {
04496             rpt_mutex_unlock(&myrpt->lock);
04497             ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase);
04498             res = -1;
04499          }
04500          else res = setrbi(myrpt);
04501       }
04502 #endif
04503       else if(!strcmp(myrpt->remoterig, remote_rig_kenwood))
04504       {
04505          if (myrpt->iofd >= 0) setdtr(myrpt->iofd,1);
04506          res = setkenwood(myrpt);
04507          if (myrpt->iofd >= 0) setdtr(myrpt->iofd,0);
04508          if (ast_safe_sleep(mychannel,200) == -1)
04509          {
04510             ast_mutex_unlock(&myrpt->remlock);
04511             res = -1;
04512             break;
04513          }
04514          if (myrpt->iofd < 0)
04515          {
04516             i = DAHDI_FLUSH_EVENT;
04517             if (ioctl(myrpt->dahditxchannel->fds[0],DAHDI_FLUSH,&i) == -1)
04518             {
04519                ast_mutex_unlock(&myrpt->remlock);
04520                ast_log(LOG_ERROR,"Cant flush events");
04521                res = -1;
04522                break;
04523             }
04524             if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_GET_PARAMS,&par) == -1)
04525             {
04526                ast_mutex_unlock(&myrpt->remlock);
04527                ast_log(LOG_ERROR,"Cant get params");
04528                res = -1;
04529                break;
04530             }
04531             myrpt->remoterx = 
04532                (par.rxisoffhook || (myrpt->tele.next != &myrpt->tele));
04533          }
04534       }
04535 
04536       ast_mutex_unlock(&myrpt->remlock);
04537       if (!res)
04538       {
04539          imdone = 1;
04540          break;
04541       }
04542       /* fall thru to invalid freq */
04543        case INVFREQ:
04544       /* wait a little bit */
04545       wait_interval(myrpt, DLY_TELEM, mychannel);
04546       res = ast_streamfile(mychannel, "rpt/invalid-freq", mychannel->language);
04547       break;
04548        case REMMODE:
04549       cp = 0;
04550       wait_interval(myrpt, DLY_TELEM, mychannel);
04551       switch(myrpt->remmode)
04552       {
04553           case REM_MODE_FM:
04554          saycharstr(mychannel,"FM");
04555          break;
04556           case REM_MODE_USB:
04557          saycharstr(mychannel,"USB");
04558          break;
04559           case REM_MODE_LSB:
04560          saycharstr(mychannel,"LSB");
04561          break;
04562           case REM_MODE_AM:
04563          saycharstr(mychannel,"AM");
04564          break;
04565       }
04566       wait_interval(myrpt, DLY_COMP, mychannel);
04567       if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
04568       break;
04569        case LOGINREQ:
04570       wait_interval(myrpt, DLY_TELEM, mychannel);
04571       sayfile(mychannel,"rpt/login");
04572       saycharstr(mychannel,myrpt->name);
04573       break;
04574        case REMLOGIN:
04575       wait_interval(myrpt, DLY_TELEM, mychannel);
04576       saycharstr(mychannel,myrpt->loginuser);
04577       saynode(myrpt,mychannel,myrpt->name);
04578       wait_interval(myrpt, DLY_COMP, mychannel);
04579       if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
04580       break;
04581        case REMXXX:
04582       wait_interval(myrpt, DLY_TELEM, mychannel);
04583       res = 0;
04584       switch(mytele->submode)
04585       {
04586           case 100: /* RX PL Off */
04587          sayfile(mychannel, "rpt/rxpl");
04588          sayfile(mychannel, "rpt/off");
04589          break;
04590           case 101: /* RX PL On */
04591          sayfile(mychannel, "rpt/rxpl");
04592          sayfile(mychannel, "rpt/on");
04593          break;
04594           case 102: /* TX PL Off */
04595          sayfile(mychannel, "rpt/txpl");
04596          sayfile(mychannel, "rpt/off");
04597          break;
04598           case 103: /* TX PL On */
04599          sayfile(mychannel, "rpt/txpl");
04600          sayfile(mychannel, "rpt/on");
04601          break;
04602           case 104: /* Low Power */
04603          sayfile(mychannel, "rpt/lopwr");
04604          break;
04605           case 105: /* Medium Power */
04606          sayfile(mychannel, "rpt/medpwr");
04607          break;
04608           case 106: /* Hi Power */
04609          sayfile(mychannel, "rpt/hipwr");
04610          break;
04611           case 113: /* Scan down slow */
04612          sayfile(mychannel,"rpt/down");
04613          sayfile(mychannel, "rpt/slow");
04614          break;
04615           case 114: /* Scan down quick */
04616          sayfile(mychannel,"rpt/down");
04617          sayfile(mychannel, "rpt/quick");
04618          break;
04619           case 115: /* Scan down fast */
04620          sayfile(mychannel,"rpt/down");
04621          sayfile(mychannel, "rpt/fast");
04622          break;
04623           case 116: /* Scan up slow */
04624          sayfile(mychannel,"rpt/up");
04625          sayfile(mychannel, "rpt/slow");
04626          break;
04627           case 117: /* Scan up quick */
04628          sayfile(mychannel,"rpt/up");
04629          sayfile(mychannel, "rpt/quick");
04630          break;
04631           case 118: /* Scan up fast */
04632          sayfile(mychannel,"rpt/up");
04633          sayfile(mychannel, "rpt/fast");
04634          break;
04635           default:
04636          res = -1;
04637       }
04638       wait_interval(myrpt, DLY_COMP, mychannel);
04639       if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
04640       break;
04641        case SCAN:
04642       ast_mutex_lock(&myrpt->remlock);
04643       if (myrpt->hfscanstop)
04644       {
04645          myrpt->hfscanstatus = 0;
04646          myrpt->hfscanmode = 0;
04647          myrpt->hfscanstop = 0;
04648          mytele->mode = SCANSTAT;
04649          ast_mutex_unlock(&myrpt->remlock);
04650          if (ast_safe_sleep(mychannel,1000) == -1) break;
04651          sayfile(mychannel, "rpt/stop"); 
04652          imdone = 1;
04653          break;
04654       }
04655       if (myrpt->hfscanstatus > -2) service_scan(myrpt);
04656       i = myrpt->hfscanstatus;
04657       myrpt->hfscanstatus = 0;
04658       if (i) mytele->mode = SCANSTAT;
04659       ast_mutex_unlock(&myrpt->remlock);
04660       if (i < 0) sayfile(mychannel, "rpt/stop"); 
04661       else if (i > 0) saynum(mychannel,i);
04662       imdone = 1;
04663       break;
04664        case TUNE:
04665       ast_mutex_lock(&myrpt->remlock);
04666       if (!strcmp(myrpt->remoterig,remote_rig_ic706))
04667       {
04668          set_mode_ic706(myrpt, REM_MODE_AM);
04669          if(play_tone(mychannel, 800, 6000, 8192) == -1) break;
04670          ast_safe_sleep(mychannel,500);
04671          set_mode_ic706(myrpt, myrpt->remmode);
04672          myrpt->tunerequest = 0;
04673          ast_mutex_unlock(&myrpt->remlock);
04674          imdone = 1;
04675          break;
04676       }
04677       set_mode_ft897(myrpt, REM_MODE_AM);
04678       simple_command_ft897(myrpt, 8);
04679       if(play_tone(mychannel, 800, 6000, 8192) == -1) break;
04680       simple_command_ft897(myrpt, 0x88);
04681       ast_safe_sleep(mychannel,500);
04682       set_mode_ft897(myrpt, myrpt->remmode);
04683       myrpt->tunerequest = 0;
04684       ast_mutex_unlock(&myrpt->remlock);
04685       imdone = 1;
04686       break;
04687        case REMSHORTSTATUS:
04688        case REMLONGSTATUS: 
04689       wait_interval(myrpt, DLY_TELEM, mychannel);
04690       res = saynode(myrpt,mychannel,myrpt->name);
04691       if(!res)
04692          res = sayfile(mychannel,"rpt/frequency");
04693       if(!res)
04694          res = split_freq(mhz, decimals, myrpt->freq);
04695       if (!multimode_capable(myrpt)) decimals[3] = 0;
04696       if(!res){
04697          m = atoi(mhz);
04698          if(m < 100)
04699             res = saynum(mychannel, m);
04700          else
04701             res = saycharstr(mychannel, mhz);
04702       }
04703       if(!res)
04704          res = sayfile(mychannel, "letters/dot");
04705       if(!res)
04706          res = saycharstr(mychannel, decimals);
04707    
04708       if(res)  break;
04709       if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */
04710          switch(myrpt->offset){
04711    
04712             case REM_MINUS:
04713                res = sayfile(mychannel,"rpt/minus");
04714                break;
04715             
04716             case REM_SIMPLEX:
04717                res = sayfile(mychannel,"rpt/simplex");
04718                break;
04719                
04720             case REM_PLUS:
04721                res = sayfile(mychannel,"rpt/plus");
04722                break;
04723                
04724             default:
04725                break;
04726          }
04727       }
04728       else{ /* Must be USB, LSB, or AM */
04729          switch(myrpt->remmode){
04730 
04731             case REM_MODE_USB:
04732                res = saycharstr(mychannel, "USB");
04733                break;
04734 
04735             case REM_MODE_LSB:
04736                res = saycharstr(mychannel, "LSB");
04737                break;
04738 
04739             case REM_MODE_AM:
04740                res = saycharstr(mychannel, "AM");
04741                break;
04742 
04743 
04744             default:
04745                break;
04746          }
04747       }
04748 
04749       if (res == -1) break;
04750 
04751       if(mytele->mode == REMSHORTSTATUS){ /* Short status? */
04752          wait_interval(myrpt, DLY_COMP, mychannel);
04753          if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
04754          break;
04755       }
04756 
04757       if (strcmp(myrpt->remoterig,remote_rig_ic706))
04758       {
04759          switch(myrpt->powerlevel){
04760 
04761             case REM_LOWPWR:
04762                res = sayfile(mychannel,"rpt/lopwr") ;
04763                break;
04764             case REM_MEDPWR:
04765                res = sayfile(mychannel,"rpt/medpwr");
04766                break;
04767             case REM_HIPWR:
04768                res = sayfile(mychannel,"rpt/hipwr"); 
04769                break;
04770             }
04771       }
04772 
04773       rbimode = ((!strncmp(myrpt->remoterig,remote_rig_rbi,3))
04774         || (!strncmp(myrpt->remoterig,remote_rig_ic706,3)));
04775       if (res || (sayfile(mychannel,"rpt/rxpl") == -1)) break;
04776       if (rbimode && (sayfile(mychannel,"rpt/txpl") == -1)) break;
04777       if ((sayfile(mychannel,"rpt/frequency") == -1) ||
04778          (saycharstr(mychannel,myrpt->rxpl) == -1)) break;
04779       if ((!rbimode) && ((sayfile(mychannel,"rpt/txpl") == -1) ||
04780          (sayfile(mychannel,"rpt/frequency") == -1) ||
04781          (saycharstr(mychannel,myrpt->txpl) == -1))) break;
04782       if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */
04783          if ((sayfile(mychannel,"rpt/rxpl") == -1) ||
04784             (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1) ||
04785             (sayfile(mychannel,"rpt/txpl") == -1) ||
04786             (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1))
04787             {
04788                break;
04789             }
04790       }
04791       wait_interval(myrpt, DLY_COMP, mychannel);
04792       if (!res) res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete");
04793       break;
04794        case STATUS:
04795       /* wait a little bit */
04796       wait_interval(myrpt, DLY_TELEM, mychannel);
04797       hastx = 0;
04798       linkbase.next = &linkbase;
04799       linkbase.prev = &linkbase;
04800       rpt_mutex_lock(&myrpt->lock);
04801       /* make our own list of links */
04802       l = myrpt->links.next;
04803       while(l != &myrpt->links)
04804       {
04805          if (l->name[0] == '0')
04806          {
04807             l = l->next;
04808             continue;
04809          }
04810          l1 = ast_malloc(sizeof(struct rpt_link));
04811          if (!l1)
04812          {
04813             ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name);
04814             remque((struct qelem *)mytele);
04815             myrpt->active_telem = NULL;
04816             rpt_mutex_unlock(&myrpt->lock);
04817             ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/
04818             ast_free(nodename);
04819             if(id_malloc)
04820                ast_free(ident);
04821             ast_free(mytele);    
04822             ast_hangup(mychannel);
04823             pthread_exit(NULL);
04824          }
04825          memcpy(l1,l,sizeof(struct rpt_link));
04826          l1->next = l1->prev = NULL;
04827          insque((struct qelem *)l1,(struct qelem *)linkbase.next);
04828          l = l->next;
04829       }
04830       rpt_mutex_unlock(&myrpt->lock);
04831       res = saynode(myrpt,mychannel,myrpt->name);
04832       if (myrpt->callmode)
04833       {
04834          hastx = 1;
04835          res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language);
04836          if (!res) 
04837             res = ast_waitstream(mychannel, "");
04838          else
04839              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04840          ast_stopstream(mychannel);
04841       }
04842       l = linkbase.next;
04843       while(l != &linkbase)
04844       {
04845          char *s;
04846 
04847          hastx = 1;
04848          res = saynode(myrpt,mychannel,l->name);
04849          s = "rpt/tranceive";
04850          if (!l->mode) s = "rpt/monitor";
04851          if (!l->thisconnected) s = "rpt/connecting";
04852          res = ast_streamfile(mychannel, s, mychannel->language);
04853          if (!res) 
04854             res = ast_waitstream(mychannel, "");
04855          else
04856             ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04857          ast_stopstream(mychannel);
04858          l = l->next;
04859       }        
04860       if (!hastx)
04861       {
04862          res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language);
04863          if (!res) 
04864             res = ast_waitstream(mychannel, "");
04865          else
04866              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04867          ast_stopstream(mychannel);
04868       }
04869       /* destroy our local link queue */
04870       l = linkbase.next;
04871       while(l != &linkbase)
04872       {
04873          l1 = l;
04874          l = l->next;
04875          remque((struct qelem *)l1);
04876          ast_free(l1);
04877       }        
04878       imdone = 1;
04879       break;
04880        case FULLSTATUS:
04881       rpt_mutex_lock(&myrpt->lock);
04882       /* get all the nodes */
04883       __mklinklist(myrpt,NULL,lbuf);
04884       rpt_mutex_unlock(&myrpt->lock);
04885       /* parse em */
04886       ns = finddelim(lbuf,strs,MAXLINKLIST);
04887       /* sort em */
04888       if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar);
04889       /* wait a little bit */
04890       wait_interval(myrpt, DLY_TELEM, mychannel);
04891       hastx = 0;
04892       res = saynode(myrpt,mychannel,myrpt->name);
04893       if (myrpt->callmode)
04894       {
04895          hastx = 1;
04896          res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language);
04897          if (!res) 
04898             res = ast_waitstream(mychannel, "");
04899          else
04900              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04901          ast_stopstream(mychannel);
04902       }
04903       /* go thru all the nodes in list */
04904       for(i = 0; i < ns; i++)
04905       {
04906          char *s,mode = 'T';
04907 
04908          /* if a mode spec at first, handle it */
04909          if ((*strs[i] < '0') || (*strs[i] > '9'))
04910          {
04911             mode = *strs[i];
04912             strs[i]++;
04913          }
04914 
04915          hastx = 1;
04916          res = saynode(myrpt,mychannel,strs[i]);
04917          s = "rpt/tranceive";
04918          if (mode == 'R') s = "rpt/monitor";
04919          if (mode == 'C') s = "rpt/connecting";
04920          res = ast_streamfile(mychannel, s, mychannel->language);
04921          if (!res) 
04922             res = ast_waitstream(mychannel, "");
04923          else
04924             ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04925          ast_stopstream(mychannel);
04926       }        
04927       if (!hastx)
04928       {
04929          res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language);
04930          if (!res) 
04931             res = ast_waitstream(mychannel, "");
04932          else
04933              ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04934          ast_stopstream(mychannel);
04935       }
04936       imdone = 1;
04937       break;
04938 
04939        case LASTNODEKEY: /* Identify last node which keyed us up */
04940       rpt_mutex_lock(&myrpt->lock);
04941       if(myrpt->lastnodewhichkeyedusup){
04942          p = ast_strdup(myrpt->lastnodewhichkeyedusup); /* Make a local copy of the node name */
04943          if(!p){
04944             ast_log(LOG_WARNING, "ast_strdup failed in telemetery LASTNODEKEY");
04945             imdone = 1;
04946             break;
04947          }
04948       }
04949       else
04950          p = NULL;
04951       rpt_mutex_unlock(&myrpt->lock);
04952       if(!p){
04953          imdone = 1; /* no node previously keyed us up, or the node which did has been disconnected */
04954          break;
04955       }
04956       wait_interval(myrpt, DLY_TELEM, mychannel);
04957       res = saynode(myrpt,mychannel,p);
04958       ast_free(p);
04959       imdone = 1;
04960       break;      
04961 
04962        case UNAUTHTX: /* Say unauthorized transmit frequency */
04963       wait_interval(myrpt, DLY_TELEM, mychannel);
04964       res = ast_streamfile(mychannel, "rpt/unauthtx", mychannel->language);
04965       if (!res) 
04966          res = ast_waitstream(mychannel, "");
04967       else
04968           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04969       ast_stopstream(mychannel);
04970       imdone = 1;
04971       break;
04972 
04973        case PARROT: /* Repeat stuff */
04974 
04975       sprintf(mystr,PARROTFILE,myrpt->name,(unsigned int)mytele->parrot);
04976       if (ast_fileexists(mystr,NULL,mychannel->language) <= 0)
04977       {
04978          imdone = 1;
04979          myrpt->parrotstate = 0;
04980          break;
04981       }
04982       wait_interval(myrpt, DLY_PARROT, mychannel);
04983       sprintf(mystr,PARROTFILE,myrpt->name,(unsigned int)mytele->parrot);
04984       res = ast_streamfile(mychannel, mystr, mychannel->language);
04985       if (!res) 
04986          res = ast_waitstream(mychannel, "");
04987       else
04988           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
04989       ast_stopstream(mychannel);
04990       sprintf(mystr,PARROTFILE,myrpt->name,(unsigned int)mytele->parrot);
04991       strcat(mystr,".wav");
04992       unlink(mystr);       
04993       imdone = 1;
04994       myrpt->parrotstate = 0;
04995       break;
04996 
04997        case TIMEOUT:
04998       res = saynode(myrpt,mychannel,myrpt->name);
04999       if (!res)
05000          res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language);
05001       break;
05002       
05003        case TIMEOUT_WARNING:
05004       time(&t);
05005       res = saynode(myrpt,mychannel,myrpt->name);
05006       if (!res)
05007          res = ast_streamfile(mychannel, "rpt/timeout-warning", mychannel->language);
05008       if (!res) 
05009          res = ast_waitstream(mychannel, "");
05010       else
05011           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
05012       ast_stopstream(mychannel);
05013       if(!res) /* Say number of seconds */
05014          ast_say_number(mychannel, myrpt->p.remotetimeout - 
05015              (t - myrpt->last_activity_time), 
05016             "", mychannel->language, (char *) NULL);
05017       if (!res) 
05018          res = ast_waitstream(mychannel, "");
05019       ast_stopstream(mychannel); 
05020       res = ast_streamfile(mychannel, "queue-seconds", mychannel->language);
05021       break;
05022 
05023        case ACT_TIMEOUT_WARNING:
05024       time(&t);
05025       res = saynode(myrpt,mychannel,myrpt->name);
05026       if (!res)
05027           res = ast_streamfile(mychannel, "rpt/act-timeout-warning", mychannel->language);
05028       if (!res) 
05029          res = ast_waitstream(mychannel, "");
05030       else
05031           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
05032       ast_stopstream(mychannel);
05033       if(!res) /* Say number of seconds */
05034          ast_say_number(mychannel, myrpt->p.remoteinacttimeout - 
05035              (t - myrpt->last_activity_time), 
05036             "", mychannel->language, (char *) NULL);
05037       if (!res) 
05038          res = ast_waitstream(mychannel, "");
05039       ast_stopstream(mychannel); 
05040       res = ast_streamfile(mychannel, "queue-seconds", mychannel->language);
05041       break;
05042       
05043        case STATS_TIME:
05044             case STATS_TIME_LOCAL:
05045          wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
05046       t = time(NULL);
05047       rpt_localtime(&t, &localtm);
05048       /* Say the phase of the day is before the time */
05049       if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12))
05050          p = "rpt/goodmorning";
05051       else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18))
05052          p = "rpt/goodafternoon";
05053       else
05054          p = "rpt/goodevening";
05055       if (sayfile(mychannel,p) == -1)
05056       {
05057          imdone = 1;
05058          break;
05059       }
05060       /* Say the time is ... */     
05061       if (sayfile(mychannel,"rpt/thetimeis") == -1)
05062       {
05063          imdone = 1;
05064          break;
05065       }
05066       /* Say the time */            
05067          res = ast_say_time(mychannel, t, "", mychannel->language);
05068       if (!res) 
05069          res = ast_waitstream(mychannel, "");
05070       ast_stopstream(mychannel);    
05071       imdone = 1;
05072          break;
05073        case STATS_VERSION:
05074       p = strstr(tdesc, "version"); 
05075       if(!p)
05076          break;   
05077       if(sscanf(p, "version %d.%d", &vmajor, &vminor) != 2)
05078          break;
05079          wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
05080       /* Say "version" */
05081       if (sayfile(mychannel,"rpt/version") == -1)
05082       {
05083          imdone = 1;
05084          break;
05085       }
05086       if(!res) /* Say "X" */
05087          ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL);
05088       if (!res) 
05089          res = ast_waitstream(mychannel, "");
05090       ast_stopstream(mychannel); 
05091       if (saycharstr(mychannel,".") == -1)
05092       {
05093          imdone = 1;
05094          break;
05095       }
05096       if(!res) /* Say "Y" */
05097          ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL);
05098       if (!res){
05099          res = ast_waitstream(mychannel, "");
05100          ast_stopstream(mychannel);
05101       }  
05102       else
05103           ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
05104       imdone = 1;
05105          break;
05106        case ARB_ALPHA:
05107          wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
05108          if(mytele->param)
05109             saycharstr(mychannel, mytele->param);
05110          imdone = 1;
05111       break;
05112        case REV_PATCH:
05113          wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */
05114          if(mytele->param) {
05115 
05116          /* Parts of this section taken from app_parkandannounce */
05117          char *tpl_working, *tpl_current;
05118          char *tmp[100], *myparm;
05119          int looptemp=0,idx=0, dres = 0;
05120    
05121 
05122          tpl_working = ast_strdup(mytele->param);
05123          myparm = strsep(&tpl_working,",");
05124          tpl_current=strsep(&tpl_working, ":");
05125 
05126          while(tpl_current && looptemp < sizeof(tmp)) {
05127             tmp[looptemp]=tpl_current;
05128             looptemp++;
05129             tpl_current=strsep(&tpl_working,":");
05130          }
05131 
05132          for(idx=0; idx<looptemp; idx++) {
05133             if(!strcmp(tmp[idx], "PARKED")) {
05134                ast_say_digits(mychannel, atoi(myparm), "", mychannel->language);
05135             } else if(!strcmp(tmp[idx], "NODE")) {
05136                ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language);
05137             } else {
05138                dres = ast_streamfile(mychannel, tmp[idx], mychannel->language);
05139                if(!dres) {
05140                   dres = ast_waitstream(mychannel, "");
05141                } else {
05142                   ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[idx], mychannel->name);
05143                   dres = 0;
05144                }
05145             }
05146          }
05147          ast_free(tpl_working);
05148       }
05149          imdone = 1;
05150       break;
05151        case TEST_TONE:
05152       imdone = 1;
05153       if (myrpt->stopgen) break;
05154       myrpt->stopgen = -1;
05155            if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0))) 
05156       {
05157          myrpt->stopgen = 0;
05158          break;
05159       }
05160            while(mychannel->generatordata && (myrpt->stopgen <= 0)) {
05161          if (ast_safe_sleep(mychannel,1)) break;
05162             imdone = 1;
05163          }
05164       myrpt->stopgen = 0;
05165       break;
05166        default:
05167          break;
05168    }
05169    if (!imdone)
05170    {
05171       if (!res) 
05172          res = ast_waitstream(mychannel, "");
05173       else {
05174          ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
05175          res = 0;
05176       }
05177    }
05178    ast_stopstream(mychannel);
05179    rpt_mutex_lock(&myrpt->lock);
05180    if (mytele->mode == TAILMSG)
05181    {
05182       if (!res)
05183       {
05184          myrpt->tailmessagen++;
05185          if(myrpt->tailmessagen >= myrpt->p.tailmessagemax) myrpt->tailmessagen = 0;
05186       }
05187       else
05188       {
05189          myrpt->tmsgtimer = myrpt->p.tailsquashedtime;
05190       }
05191    }
05192    remque((struct qelem *)mytele);
05193    myrpt->active_telem = NULL;
05194    rpt_mutex_unlock(&myrpt->lock);
05195    ast_free(nodename);
05196    if(id_malloc)
05197       ast_free(ident);
05198    ast_free(mytele);    
05199    ast_hangup(mychannel);
05200 #ifdef  APP_RPT_LOCK_DEBUG
05201    {
05202       struct lockthread *t;
05203 
05204       sleep(5);
05205       ast_mutex_lock(&locklock);
05206       t = get_lockthread(pthread_self());
05207       if (t) memset(t,0,sizeof(struct lockthread));
05208       ast_mutex_unlock(&locklock);
05209    }        
05210 #endif
05211    pthread_exit(NULL);
05212 }

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

Definition at line 5214 of file app_rpt.c.

References ARB_ALPHA, ast_log(), ast_malloc, ast_pthread_create, ast_variable_retrieve(), rpt::cfg, CONNECTED, CONNFAIL, LINKUNKEY, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::name, rpt_tele::next, PARROT, PLAYBACK, REMDISC, REMXXX, REV_PATCH, rpt_mutex_lock, rpt_mutex_unlock, rpt_tele_thread(), rpt::tele, telem_lookup(), TELEPARAMSIZE, and UNKEY.

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

05215 {
05216 struct rpt_tele *tele;
05217 struct rpt_link *mylink = NULL;
05218 int res;
05219 pthread_attr_t attr;
05220 char *v1, *v2;
05221 
05222    if(debug > 6)
05223       ast_log(LOG_NOTICE,"mode=%i  data=%s\n",mode, (char *)data);
05224 
05225    switch(mode)
05226    {
05227        case UNKEY:
05228       /* if any of the following are defined, go ahead and do it,
05229          otherwise, dont bother */
05230       v1 = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, 
05231          "unlinkedct");
05232       v2 = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, 
05233          "remotect");
05234       if (telem_lookup(myrpt,NULL, myrpt->name, "remotemon") &&
05235         telem_lookup(myrpt,NULL, myrpt->name, "remotetx") &&
05236         telem_lookup(myrpt,NULL, myrpt->name, "cmdmode") &&
05237         (!(v1 && telem_lookup(myrpt,NULL, myrpt->name, v1))) && 
05238         (!(v2 && telem_lookup(myrpt,NULL, myrpt->name, v2)))) return;
05239       break;
05240        case LINKUNKEY:
05241       if (!ast_variable_retrieve(myrpt->cfg, myrpt->name, "linkunkeyct"))
05242          return;
05243       break;
05244        default:
05245       break;
05246    }
05247    tele = ast_malloc(sizeof(struct rpt_tele));
05248    if (!tele)
05249    {
05250       ast_log(LOG_WARNING, "Unable to allocate memory\n");
05251       pthread_exit(NULL);
05252       return;
05253    }
05254    /* zero it out */
05255    memset((char *)tele,0,sizeof(struct rpt_tele));
05256    tele->rpt = myrpt;
05257    tele->mode = mode;
05258    if (mode == PARROT) tele->parrot = (uintptr_t) data;
05259    else mylink = (struct rpt_link *) data;
05260    rpt_mutex_lock(&myrpt->lock);
05261    if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED) ||
05262        (mode == LINKUNKEY)){
05263       memset(&tele->mylink,0,sizeof(struct rpt_link));
05264       if (mylink){
05265          memcpy(&tele->mylink,mylink,sizeof(struct rpt_link));
05266       }
05267    }
05268    else if ((mode == ARB_ALPHA) || (mode == REV_PATCH) || (mode == PLAYBACK)) {
05269       strncpy(tele->param, (char *) data, TELEPARAMSIZE - 1);
05270       tele->param[TELEPARAMSIZE - 1] = 0;
05271    }
05272    if (mode == REMXXX) tele->submode = (intptr_t) data;
05273    insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next);
05274    rpt_mutex_unlock(&myrpt->lock);
05275         pthread_attr_init(&attr);
05276         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
05277    res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele);
05278    if(res < 0){
05279       rpt_mutex_lock(&myrpt->lock);
05280       remque((struct qlem *) tele); /* We don't like stuck transmitters, remove it from the queue */
05281       rpt_mutex_unlock(&myrpt->lock);  
05282       ast_log(LOG_WARNING, "Could not create telemetry thread: %s",strerror(res));
05283    }
05284    return;
05285 }

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

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

03692 {
03693 int   res;
03694 
03695    res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
03696    if (!res) 
03697       res = ast_waitstream(mychannel, "");
03698    else
03699        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03700    ast_stopstream(mychannel);
03701    return res;
03702 }

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

Definition at line 3678 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(), saynode(), and telem_any().

03679 {
03680 int   res;
03681 
03682    res = ast_streamfile(mychannel, fname, mychannel->language);
03683    if (!res) 
03684       res = ast_waitstream(mychannel, "");
03685    else
03686        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03687    ast_stopstream(mychannel);
03688    return res;
03689 }

static int saynode ( struct rpt myrpt,
struct ast_channel mychannel,
char *  name 
) [static]

Definition at line 3719 of file app_rpt.c.

References ast_fileexists(), ast_say_character_str(), ast_variable_retrieve(), rpt::cfg, ast_channel::language, rpt::name, NODENAMES, and sayfile().

Referenced by rpt_tele_thread().

03720 {
03721 int   res;
03722 char  *val,fname[300];
03723 
03724    val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "nodenames");
03725    if (!val) val = NODENAMES;
03726    snprintf(fname,sizeof(fname) - 1,"%s/%s",val,name);
03727    if (ast_fileexists(fname,NULL,mychannel->language) > 0)
03728       return(sayfile(mychannel,fname));
03729    res = sayfile(mychannel,"rpt/node");
03730    if (!res) 
03731       res = ast_say_character_str(mychannel,name,NULL,mychannel->language);
03732    return res;
03733 }

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

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

03705 {
03706    int res;
03707    res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL);
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    return res;
03714 }

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

Definition at line 9098 of file app_rpt.c.

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

Referenced by set_ic706().

09099 {
09100    unsigned char cmdstr[10];
09101    
09102    cmdstr[0] = cmdstr[1] = 0xfe;
09103    cmdstr[2] = myrpt->p.civaddr;
09104    cmdstr[3] = 0xe0;
09105    cmdstr[4] = 8;
09106    cmdstr[5] = 0;
09107    cmdstr[6] = ((slot / 10) << 4) + (slot % 10);
09108    cmdstr[7] = 0xfd;
09109 
09110    return(civ_cmd(myrpt,cmdstr,8));
09111 }

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

Definition at line 5592 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::ptr, ast_frame::samples, and ast_frame::subclass.

Referenced by handle_link_phone_dtmf(), and local_dtmf_helper().

05593 {
05594 char  str[300];
05595 struct   ast_frame wf;
05596 struct   rpt_link *l;
05597 
05598    snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c);
05599    wf.frametype = AST_FRAME_TEXT;
05600    wf.subclass = 0;
05601    wf.offset = 0;
05602    wf.mallocd = 0;
05603    wf.datalen = strlen(str) + 1;
05604    wf.samples = 0;
05605    l = myrpt->links.next;
05606    /* first, see if our dude is there */
05607    while(l != &myrpt->links)
05608    {
05609       if (l->name[0] == '0') 
05610       {
05611          l = l->next;
05612          continue;
05613       }
05614       /* if we found it, write it and were done */
05615       if (!strcmp(l->name,myrpt->cmdnode))
05616       {
05617          wf.data.ptr = str;
05618          if (l->chan) ast_write(l->chan,&wf);
05619          return;
05620       }
05621       l = l->next;
05622    }
05623    l = myrpt->links.next;
05624    /* if not, give it to everyone */
05625    while(l != &myrpt->links)
05626    {
05627       wf.data.ptr = str;
05628       if (l->chan) ast_write(l->chan,&wf);
05629       l = l->next;
05630    }
05631    return;
05632 }

static void send_link_keyquery ( struct rpt myrpt  )  [static]

Definition at line 5634 of file app_rpt.c.

References AST_FRAME_TEXT, ast_write(), rpt_link::chan, ast_frame::data, ast_frame::datalen, ast_frame::frametype, rpt::links, rpt::lock, ast_frame::mallocd, rpt::name, rpt_link::next, ast_frame::offset, ast_frame::ptr, rpt_mutex_lock, rpt_mutex_unlock, ast_frame::samples, ast_frame::subclass, rpt::topkey, rpt::topkeystate, and rpt::topkeytime.

Referenced by function_cop().

05635 {
05636 char  str[300];
05637 struct   ast_frame wf;
05638 struct   rpt_link *l;
05639 
05640    rpt_mutex_lock(&myrpt->lock);
05641    memset(myrpt->topkey,0,sizeof(myrpt->topkey));
05642    myrpt->topkeystate = 1;
05643    time(&myrpt->topkeytime);
05644    rpt_mutex_unlock(&myrpt->lock);
05645    snprintf(str, sizeof(str), "K? * %s 0 0", myrpt->name);
05646    wf.frametype = AST_FRAME_TEXT;
05647    wf.subclass = 0;
05648    wf.offset = 0;
05649    wf.mallocd = 0;
05650    wf.datalen = strlen(str) + 1;
05651    wf.samples = 0;
05652    l = myrpt->links.next;
05653    /* give it to everyone */
05654    while(l != &myrpt->links)
05655    {
05656       wf.data.ptr = str;
05657       if (l->chan) ast_write(l->chan,&wf);
05658       l = l->next;
05659    }
05660    return;
05661 }

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

Definition at line 3459 of file app_rpt.c.

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

Referenced by telem_any().

03460 {
03461 
03462 static struct morse_bits mbits[] = {
03463       {0, 0}, /* SPACE */
03464       {0, 0}, 
03465       {6, 18},/* " */
03466       {0, 0},
03467       {7, 72},/* $ */
03468       {0, 0},
03469       {0, 0},
03470       {6, 30},/* ' */
03471       {5, 13},/* ( */
03472       {6, 29},/* ) */
03473       {0, 0},
03474       {5, 10},/* + */
03475       {6, 51},/* , */
03476       {6, 33},/* - */
03477       {6, 42},/* . */
03478       {5, 9}, /* / */
03479       {5, 31},/* 0 */
03480       {5, 30},/* 1 */
03481       {5, 28},/* 2 */
03482       {5, 24},/* 3 */
03483       {5, 16},/* 4 */
03484       {5, 0}, /* 5 */
03485       {5, 1}, /* 6 */
03486       {5, 3}, /* 7 */
03487       {5, 7}, /* 8 */
03488       {5, 15},/* 9 */
03489       {6, 7}, /* : */
03490       {6, 21},/* ; */
03491       {0, 0},
03492       {5, 33},/* = */
03493       {0, 0},
03494       {6, 12},/* ? */
03495       {0, 0},
03496          {2, 2}, /* A */
03497       {4, 1}, /* B */
03498       {4, 5}, /* C */
03499       {3, 1}, /* D */
03500       {1, 0}, /* E */
03501       {4, 4}, /* F */
03502       {3, 3}, /* G */
03503       {4, 0}, /* H */
03504       {2, 0}, /* I */
03505       {4, 14},/* J */
03506       {3, 5}, /* K */
03507       {4, 2}, /* L */
03508       {2, 3}, /* M */
03509       {2, 1}, /* N */
03510       {3, 7}, /* O */
03511       {4, 6}, /* P */
03512       {4, 11},/* Q */
03513       {3, 2}, /* R */
03514       {3, 0}, /* S */
03515       {1, 1}, /* T */
03516       {3, 4}, /* U */
03517       {4, 8}, /* V */
03518       {3, 6}, /* W */
03519       {4, 9}, /* X */
03520       {4, 13},/* Y */
03521       {4, 3}  /* Z */
03522    };
03523 
03524 
03525    int dottime;
03526    int dashtime;
03527    int intralettertime;
03528    int interlettertime;
03529    int interwordtime;
03530    int len, ddcomb;
03531    int res;
03532    int c;
03533    int i;
03534    int flags;
03535          
03536    res = 0;
03537    
03538    /* Approximate the dot time from the speed arg. */
03539    
03540    dottime = 900/speed;
03541    
03542    /* Establish timing releationships */
03543    
03544    dashtime = 3 * dottime;
03545    intralettertime = dottime;
03546    interlettertime = dottime * 4 ;
03547    interwordtime = dottime * 7;
03548    
03549    for(;(*string) && (!res); string++){
03550    
03551       c = *string;
03552       
03553       /* Convert lower case to upper case */
03554       
03555       if((c >= 'a') && (c <= 'z'))
03556          c -= 0x20;
03557       
03558       /* Can't deal with any char code greater than Z, skip it */
03559       
03560       if(c  > 'Z')
03561          continue;
03562       
03563       /* If space char, wait the inter word time */
03564                
03565       if(c == ' '){
03566          if(!res)
03567             res = play_silence(chan, interwordtime);
03568          continue;
03569       }
03570       
03571       /* Subtract out control char offset to match our table */
03572       
03573       c -= 0x20;
03574       
03575       /* Get the character data */
03576       
03577       len = mbits[c].len;
03578       ddcomb = mbits[c].ddcomb;
03579       
03580       /* Send the character */
03581       
03582       for(; len ; len--){
03583          if(!res)
03584             res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude);
03585          if(!res)
03586             res = play_silence(chan, intralettertime);
03587          ddcomb >>= 1;
03588       }
03589       
03590       /* Wait the interletter time */
03591       
03592       if(!res)
03593          res = play_silence(chan, interlettertime - intralettertime);
03594    }
03595    
03596    /* Wait for all the frames to be sent */
03597    
03598    if (!res) 
03599       res = ast_waitstream(chan, "");
03600    ast_stopstream(chan);
03601    
03602    /*
03603    * Wait for the DAHDI driver to physically write the tone blocks to the hardware
03604    */
03605 
03606    for(i = 0; i < 20 ; i++){
03607       flags =  DAHDI_IOMUX_WRITEEMPTY | DAHDI_IOMUX_NOWAIT; 
03608       res = ioctl(chan->fds[0], DAHDI_IOMUX, &flags);
03609       if(flags & DAHDI_IOMUX_WRITEEMPTY)
03610          break;
03611       if( ast_safe_sleep(chan, 50)){
03612          res = -1;
03613          break;
03614       }
03615    }
03616 
03617    
03618    return res;
03619 }

static void send_newkey ( struct ast_channel chan  )  [static]

Definition at line 5665 of file app_rpt.c.

References ast_sendtext(), and chan.

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

05666 {
05667 
05668    /* ast_safe_sleep(chan,10); */
05669    ast_sendtext(chan,newkeystr);
05670    return;
05671 }

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

Definition at line 3621 of file app_rpt.c.

References ast_free, ast_safe_sleep(), ast_stopstream(), ast_strdup, ast_waitstream(), chan, ast_channel::fds, play_tone_pair(), and strsep().

Referenced by telem_any().

03622 {
03623    char *p,*stringp;
03624    char *tonesubset;
03625    int f1,f2;
03626    int duration;
03627    int amplitude;
03628    int res;
03629    int i;
03630    int flags;
03631    
03632    res = 0;
03633 
03634    if(!tonestring)
03635       return res;
03636    
03637    p = stringp = ast_strdup(tonestring);
03638 
03639    for(;tonestring;){
03640       tonesubset = strsep(&stringp,")");
03641       if(!tonesubset)
03642          break;
03643       if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &amplitude) != 4)
03644          break;
03645       res = play_tone_pair(chan, f1, f2, duration, amplitude);
03646       if(res)
03647          break;
03648    }
03649    if(p)
03650       ast_free(p);
03651    if(!res)
03652       res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */
03653    
03654    if (!res) 
03655       res = ast_waitstream(chan, "");
03656 
03657    ast_stopstream(chan);
03658 
03659    /*
03660    * Wait for the DAHDI driver to physically write the tone blocks to the hardware
03661    */
03662 
03663    for(i = 0; i < 20 ; i++){
03664       flags =  DAHDI_IOMUX_WRITEEMPTY | DAHDI_IOMUX_NOWAIT; 
03665       res = ioctl(chan->fds[0], DAHDI_IOMUX, &flags);
03666       if(flags & DAHDI_IOMUX_WRITEEMPTY)
03667          break;
03668       if( ast_safe_sleep(chan, 50)){
03669          res = -1;
03670          break;
03671       }
03672    }
03673       
03674    return res;
03675       
03676 }

static int send_usb_txt ( struct rpt myrpt,
char *  txt 
) [static]

Definition at line 1869 of file app_rpt.c.

References AST_FRAME_TEXT, ast_log(), ast_write(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_NOTICE, ast_frame::mallocd, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::subclass, and rpt::txchannel.

Referenced by channel_steer(), and setrtx().

01870 {
01871    struct ast_frame wf;
01872  
01873    if (debug)ast_log(LOG_NOTICE, "send_usb_txt %s\n",txt);
01874    wf.frametype = AST_FRAME_TEXT;
01875    wf.subclass = 0;
01876    wf.offset = 0;
01877    wf.mallocd = 0;
01878    wf.datalen = strlen(txt) + 1;
01879    wf.data.ptr = txt;
01880    wf.samples = 0;
01881    ast_write(myrpt->txchannel,&wf); 
01882    return 0;
01883 }

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

Definition at line 7522 of file app_rpt.c.

References ast_log(), LOG_NOTICE, and serial_remote_io().

Referenced by sendrxkenwood().

07523 {
07524 int   i;
07525 
07526 ast_log(LOG_NOTICE,"Sent to kenwood: %s\n",txstr);
07527    if (debug) printf("Send to kenwood: %s\n",txstr);
07528    i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr), 
07529       (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3);
07530    if (i < 0) return -1;
07531    if ((i > 0) && (rxstr[i - 1] == '\r'))
07532       rxstr[i-- - 1] = 0;
07533    if (debug) printf("Got from kenwood: %s\n",rxstr);
07534 ast_log(LOG_NOTICE,"Got from kenwood: %s\n",rxstr);
07535    return(i);
07536 }

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

Definition at line 7630 of file app_rpt.c.

References KENWOOD_RETRIES, and sendkenwood().

Referenced by set_tm271(), and setkenwood().

07632 {
07633 int   i,j;
07634 
07635    for(i = 0;i < KENWOOD_RETRIES;i++)
07636    {
07637       j = sendkenwood(myrpt,txstr,rxstr);
07638       if (j < 0) return(j);
07639       if (j == 0) continue;
07640       if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0);
07641    }
07642    return(-1);
07643 }     

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

Definition at line 7409 of file app_rpt.c.

References ast_log(), rpt::dahdirxchannel, ast_channel::fds, rpt::iofd, rpt::ioport, LOG_NOTICE, rpt::p, and rpt::rxchannel.

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

07411 {
07412    int i,j,idx,oldmode,olddata;
07413    struct dahdi_radio_param prm;
07414    char c;
07415 
07416     if(debug) {
07417        ast_log(LOG_NOTICE, "ioport=%s  iofd=0x%x\n",myrpt->p.ioport,myrpt->iofd);
07418       printf("String output was:\n");
07419       for(i = 0; i < txbytes; i++)
07420          printf("%02X ", (unsigned char ) txbuf[i]);
07421       printf("\n");
07422    }
07423 
07424    if (myrpt->iofd >= 0)  /* if to do out a serial port */
07425    {
07426       if (write(myrpt->iofd,txbuf,txbytes) != txbytes)
07427       {
07428          return -1;
07429       }
07430       if ((!rxmaxbytes) || (rxbuf == NULL)) 
07431       {
07432          return(0);
07433       }
07434       memset(rxbuf,0,rxmaxbytes);
07435       for(i = 0; i < rxmaxbytes; i++)
07436       {
07437          j = read(myrpt->iofd,&c,1);
07438          if (j < 1) 
07439          {
07440             return(i);
07441          }
07442          rxbuf[i] = c;
07443          if (asciiflag & 1)
07444          {
07445             rxbuf[i + 1] = 0;
07446             if (c == '\r') break;
07447          }
07448       }              
07449       if(debug) {
07450          printf("String returned was:\n");
07451          for(j = 0; j < i; j++)
07452             printf("%02X ", (unsigned char ) rxbuf[j]);
07453          printf("\n");
07454       }
07455       return(i);
07456    }
07457 
07458    /* if not a DAHDI channel, cant use pciradio stuff */
07459    if (myrpt->rxchannel != myrpt->dahdirxchannel) return -1;   
07460 
07461    prm.radpar = DAHDI_RADPAR_UIOMODE;
07462    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_GETPARAM,&prm) == -1) return -1;
07463    oldmode = prm.data;
07464    prm.radpar = DAHDI_RADPAR_UIODATA;
07465    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_GETPARAM,&prm) == -1) return -1;
07466    olddata = prm.data;
07467         prm.radpar = DAHDI_RADPAR_REMMODE;
07468         if (asciiflag & 1)  prm.data = DAHDI_RADPAR_REM_SERIAL_ASCII;
07469         else prm.data = DAHDI_RADPAR_REM_SERIAL;
07470    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
07471    if (asciiflag & 2)
07472    {
07473       i = DAHDI_ONHOOK;
07474       if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_HOOK,&i) == -1) return -1;
07475       usleep(100000);
07476    }
07477         prm.radpar = DAHDI_RADPAR_REMCOMMAND;
07478         prm.data = rxmaxbytes;
07479         memcpy(prm.buf,txbuf,txbytes);
07480         prm.index = txbytes;
07481    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
07482         if (rxbuf)
07483         {
07484                 *rxbuf = 0;
07485                 memcpy(rxbuf,prm.buf,prm.index);
07486         }
07487    idx = prm.index;
07488         prm.radpar = DAHDI_RADPAR_REMMODE;
07489         prm.data = DAHDI_RADPAR_REM_NONE;
07490    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
07491    if (asciiflag & 2)
07492    {
07493       i = DAHDI_OFFHOOK;
07494       if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_HOOK,&i) == -1) return -1;
07495    }
07496    prm.radpar = DAHDI_RADPAR_UIOMODE;
07497    prm.data = oldmode;
07498    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
07499    prm.radpar = DAHDI_RADPAR_UIODATA;
07500    prm.data = olddata;
07501    if (ioctl(myrpt->dahdirxchannel->fds[0],DAHDI_RADIO_SETPARAM,&prm) == -1) return -1;
07502         return(idx);
07503 }

static int service_scan ( struct rpt myrpt  )  [static]

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

09511 {
09512    int res, interval;
09513    char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0;
09514 
09515    switch(myrpt->hfscanmode){
09516 
09517       case HF_SCAN_DOWN_SLOW:
09518          interval = -10; /* 100Hz /sec */
09519          break;
09520 
09521       case HF_SCAN_DOWN_QUICK:
09522          interval = -50; /* 500Hz /sec */
09523          break;
09524 
09525       case HF_SCAN_DOWN_FAST:
09526          interval = -200; /* 2KHz /sec */
09527          break;
09528 
09529       case HF_SCAN_UP_SLOW:
09530          interval = 10; /* 100Hz /sec */
09531          break;
09532 
09533       case HF_SCAN_UP_QUICK:
09534          interval = 50; /* 500 Hz/sec */
09535          break;
09536 
09537       case HF_SCAN_UP_FAST:
09538          interval = 200; /* 2KHz /sec */
09539          break;
09540 
09541       default:
09542          myrpt->hfscanmode = 0; /* Huh? */
09543          return -1;
09544    }
09545 
09546    res = split_freq(mhz, decimals, myrpt->freq);
09547       
09548    if(!res){
09549       k100 =decimals[0];
09550       k10 = decimals[1];
09551       res = multimode_bump_freq(myrpt, interval);
09552    }
09553 
09554    if(!res)
09555       res = split_freq(mhz, decimals, myrpt->freq);
09556 
09557 
09558    if(res){
09559       myrpt->hfscanmode = 0;
09560       myrpt->hfscanstatus = -2;
09561       return -1;
09562    }
09563 
09564    /* Announce 10KHz boundaries */
09565    if(k10 != decimals[1]){
09566       int myhund = (interval < 0) ? k100 : decimals[0];
09567       int myten = (interval < 0) ? k10 : decimals[1];
09568       myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10;
09569    } else myrpt->hfscanstatus = 0;
09570    return res;
09571 
09572 }

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

Definition at line 8494 of file app_rpt.c.

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

Referenced by set_ft897().

08495 {
08496    unsigned char cmdstr[5];
08497    char hertz[MAXREMSTR],decimal[MAXREMSTR];
08498    int h,d; 
08499 
08500    memset(cmdstr, 0, 5);
08501 
08502    if(split_ctcss_freq(hertz, decimal, txtone))
08503       return -1; 
08504 
08505    h = atoi(hertz);
08506    d = atoi(decimal);
08507    
08508    cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10;
08509    cmdstr[1] = ((h % 10) << 4) + (d % 10);
08510    
08511    if(rxtone){
08512    
08513       if(split_ctcss_freq(hertz, decimal, rxtone))
08514          return -1; 
08515 
08516       h = atoi(hertz);
08517       d = atoi(decimal);
08518    
08519       cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10;
08520       cmdstr[3] = ((h % 10) << 4) + (d % 10);
08521    }
08522    cmdstr[4] = 0x0B; 
08523 
08524    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08525 }  

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

Definition at line 8471 of file app_rpt.c.

References serial_remote_io().

Referenced by set_ft897().

08472 {
08473    unsigned char cmdstr[5];
08474    
08475    memset(cmdstr, 0, 5);
08476    
08477    if(rxplon && txplon)
08478       cmdstr[0] = 0x2A; /* Encode and Decode */
08479    else if (!rxplon && txplon)
08480       cmdstr[0] = 0x4A; /* Encode only */
08481    else if (rxplon && !txplon)
08482       cmdstr[0] = 0x3A; /* Encode only */
08483    else
08484       cmdstr[0] = 0x8A; /* OFF */
08485 
08486    cmdstr[4] = 0x0A; 
08487 
08488    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08489 }

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

Definition at line 8990 of file app_rpt.c.

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

Referenced by set_ic706().

08991 {
08992    unsigned char cmdstr[10];
08993    int rv;
08994 
08995    if(debug > 6)
08996       ast_log(LOG_NOTICE,"txplon=%i  rxplon=%i \n",txplon,rxplon);
08997 
08998    cmdstr[0] = cmdstr[1] = 0xfe;
08999    cmdstr[2] = myrpt->p.civaddr;
09000    cmdstr[3] = 0xe0;
09001    cmdstr[4] = 0x16;
09002    cmdstr[5] = 0x42;
09003    cmdstr[6] = (txplon != 0);
09004    cmdstr[7] = 0xfd;
09005 
09006    rv = civ_cmd(myrpt,cmdstr,8);
09007    if (rv) return(-1);
09008 
09009    cmdstr[0] = cmdstr[1] = 0xfe;
09010    cmdstr[2] = myrpt->p.civaddr;
09011    cmdstr[3] = 0xe0;
09012    cmdstr[4] = 0x16;
09013    cmdstr[5] = 0x43;
09014    cmdstr[6] = (rxplon != 0);
09015    cmdstr[7] = 0xfd;
09016 
09017    return(civ_cmd(myrpt,cmdstr,8));
09018 }

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

Definition at line 8363 of file app_rpt.c.

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

Referenced by multimode_bump_freq_ft897(), and set_ft897().

08364 {
08365    unsigned char cmdstr[5];
08366    int fd,m,d;
08367    char mhz[MAXREMSTR];
08368    char decimals[MAXREMSTR];
08369 
08370    fd = 0;
08371    if(debug) 
08372       printf("New frequency: %s\n",newfreq);
08373 
08374    if(split_freq(mhz, decimals, newfreq))
08375       return -1; 
08376 
08377    m = atoi(mhz);
08378    d = atoi(decimals);
08379 
08380    /* The FT-897 likes packed BCD frequencies */
08381 
08382    cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10);        /* 100MHz 10Mhz */
08383    cmdstr[1] = ((m % 10) << 4) + (d / 10000);         /* 1MHz 100KHz */
08384    cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100);  /* 10KHz 1KHz */
08385    cmdstr[3] = (((d % 100)/10) << 4) + (d % 10);         /* 100Hz 10Hz */
08386    cmdstr[4] = 0x01;                /* command */
08387 
08388    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08389 
08390 }

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

Definition at line 8894 of file app_rpt.c.

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

Referenced by set_ic706().

08895 {
08896    unsigned char cmdstr[20];
08897    char mhz[MAXREMSTR], decimals[MAXREMSTR];
08898    int fd,m,d;
08899 
08900    fd = 0;
08901    if(debug) 
08902       ast_log(LOG_NOTICE,"newfreq:%s\n",newfreq);        
08903 
08904    if(split_freq(mhz, decimals, newfreq))
08905       return -1; 
08906 
08907    m = atoi(mhz);
08908    d = atoi(decimals);
08909 
08910    /* The ic-706 likes packed BCD frequencies */
08911 
08912    cmdstr[0] = cmdstr[1] = 0xfe;
08913    cmdstr[2] = myrpt->p.civaddr;
08914    cmdstr[3] = 0xe0;
08915    cmdstr[4] = 5;
08916    cmdstr[5] = ((d % 10) << 4);
08917    cmdstr[6] = (((d % 1000)/ 100) << 4) + ((d % 100)/10);
08918    cmdstr[7] = ((d / 10000) << 4) + ((d % 10000)/1000);
08919    cmdstr[8] = (((m % 100)/10) << 4) + (m % 10);
08920    cmdstr[9] = (m / 100);
08921    cmdstr[10] = 0xfd;
08922 
08923    return(civ_cmd(myrpt,cmdstr,11));
08924 }

static int set_ft897 ( struct rpt myrpt  )  [static]

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

08530 {
08531    int res;
08532    
08533    if(debug)
08534       printf("@@@@ lock on\n");
08535 
08536    res = simple_command_ft897(myrpt, 0x00);  /* LOCK on */  
08537 
08538    if(debug)
08539       printf("@@@@ ptt off\n");
08540 
08541    if(!res)
08542       res = simple_command_ft897(myrpt, 0x88);     /* PTT off */
08543 
08544    if(debug)
08545       printf("Modulation mode\n");
08546 
08547    if(!res)
08548       res = set_mode_ft897(myrpt, myrpt->remmode);    /* Modulation mode */
08549 
08550    if(debug)
08551       printf("Split off\n");
08552 
08553    if(!res)
08554       simple_command_ft897(myrpt, 0x82);        /* Split off */
08555 
08556    if(debug)
08557       printf("Frequency\n");
08558 
08559    if(!res)
08560       res = set_freq_ft897(myrpt, myrpt->freq);    /* Frequency */
08561    if((myrpt->remmode == REM_MODE_FM)){
08562       if(debug)
08563          printf("Offset\n");
08564       if(!res)
08565          res = set_offset_ft897(myrpt, myrpt->offset);   /* Offset if FM */
08566       if((!res)&&(myrpt->rxplon || myrpt->txplon)){
08567          if(debug)
08568             printf("CTCSS tone freqs.\n");
08569          res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */
08570       }
08571       if(!res){
08572          if(debug)
08573             printf("CTCSS mode\n");
08574          res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */
08575       }
08576    }
08577    if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){
08578       if(debug)
08579          printf("Clarifier off\n");
08580       simple_command_ft897(myrpt, 0x85);        /* Clarifier off if LSB or USB */
08581    }
08582    return res;
08583 }

static int set_ic706 ( struct rpt myrpt  )  [static]

Definition at line 9113 of file app_rpt.c.

References ast_log(), IC706_PL_MEMORY_OFFSET, ic706_pltocode(), rpt::iobase, LOG_NOTICE, mem2vfo_ic706(), rpt::p, 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().

09114 {
09115    int res = 0,i;
09116    
09117    if(debug)ast_log(LOG_NOTICE, "Set to VFO A iobase=%i\n",myrpt->p.iobase);
09118 
09119    if (!res)
09120       res = simple_command_ic706(myrpt,7,0);
09121 
09122    if((myrpt->remmode == REM_MODE_FM))
09123    {
09124       i = ic706_pltocode(myrpt->rxpl);
09125       if (i == -1) return -1;
09126       if(debug)
09127          printf("Select memory number\n");
09128       if (!res)
09129          res = select_mem_ic706(myrpt,i + IC706_PL_MEMORY_OFFSET);
09130       if(debug)
09131          printf("Transfer memory to VFO\n");
09132       if (!res)
09133          res = mem2vfo_ic706(myrpt);
09134    }
09135       
09136    if(debug)
09137       printf("Set to VFO\n");
09138 
09139    if (!res)
09140       res = vfo_ic706(myrpt);
09141 
09142    if(debug)
09143       printf("Modulation mode\n");
09144 
09145    if (!res)
09146       res = set_mode_ic706(myrpt, myrpt->remmode);    /* Modulation mode */
09147 
09148    if(debug)
09149       printf("Split off\n");
09150 
09151    if(!res)
09152       simple_command_ic706(myrpt, 0x82,0);         /* Split off */
09153 
09154    if(debug)
09155       printf("Frequency\n");
09156 
09157    if(!res)
09158       res = set_freq_ic706(myrpt, myrpt->freq);    /* Frequency */
09159    if((myrpt->remmode == REM_MODE_FM)){
09160       if(debug)
09161          printf("Offset\n");
09162       if(!res)
09163          res = set_offset_ic706(myrpt, myrpt->offset);   /* Offset if FM */
09164       if(!res){
09165          if(debug)
09166             printf("CTCSS mode\n");
09167          res = set_ctcss_mode_ic706(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */
09168       }
09169    }
09170    return res;
09171 }

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

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

08439 {
08440    unsigned char cmdstr[5];
08441    
08442    memset(cmdstr, 0, 5);
08443    
08444    switch(newmode){
08445       case  REM_MODE_FM:
08446          cmdstr[0] = 0x08;
08447          break;
08448 
08449       case  REM_MODE_USB:
08450          cmdstr[0] = 0x01;
08451          break;
08452 
08453       case  REM_MODE_LSB:
08454          cmdstr[0] = 0x00;
08455          break;
08456 
08457       case  REM_MODE_AM:
08458          cmdstr[0] = 0x04;
08459          break;
08460       
08461       default:
08462          return -1;
08463    }
08464    cmdstr[4] = 0x07; 
08465 
08466    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08467 }

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

Definition at line 8958 of file app_rpt.c.

References ast_log(), LOG_NOTICE, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, and simple_command_ic706().

Referenced by rpt_tele_thread(), and set_ic706().

08959 {
08960    unsigned char c;
08961    
08962    if(debug > 6)
08963       ast_log(LOG_NOTICE,"newmode=%i\n",newmode);
08964 
08965    switch(newmode){
08966       case  REM_MODE_FM:
08967          c = 5;
08968          break;
08969 
08970       case  REM_MODE_USB:
08971          c = 1;
08972          break;
08973 
08974       case  REM_MODE_LSB:
08975          c = 0;
08976          break;
08977 
08978       case  REM_MODE_AM:
08979          c = 2;
08980          break;
08981       
08982       default:
08983          return -1;
08984    }
08985    return simple_command_ic706(myrpt,6,c);
08986 }

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

Definition at line 8408 of file app_rpt.c.

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

Referenced by set_ft897().

08409 {
08410    unsigned char cmdstr[5];
08411    
08412    memset(cmdstr, 0, 5);
08413 
08414    switch(offset){
08415       case  REM_SIMPLEX:
08416          cmdstr[0] = 0x89;
08417          break;
08418 
08419       case  REM_MINUS:
08420          cmdstr[0] = 0x09;
08421          break;
08422       
08423       case  REM_PLUS:
08424          cmdstr[0] = 0x49;
08425          break;   
08426 
08427       default:
08428          return -1;
08429    }
08430 
08431    cmdstr[4] = 0x09; 
08432 
08433    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08434 }

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

Definition at line 8928 of file app_rpt.c.

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

Referenced by set_ic706().

08929 {
08930    unsigned char c;
08931 
08932    if(debug > 6)
08933       ast_log(LOG_NOTICE,"offset=%i\n",offset);
08934 
08935    switch(offset){
08936       case  REM_SIMPLEX:
08937          c = 0x10;
08938          break;
08939 
08940       case  REM_MINUS:
08941          c = 0x11;
08942          break;
08943       
08944       case  REM_PLUS:
08945          c = 0x12;
08946          break;   
08947 
08948       default:
08949          return -1;
08950    }
08951 
08952    return simple_command_ic706(myrpt,0x0f,c);
08953 
08954 }

static int set_tm271 ( struct rpt myrpt  )  [static]

Definition at line 7687 of file app_rpt.c.

References rpt::freq, kenwood_pltocode(), MAXREMSTR, rpt::offset, rpt::powerlevel, rpt::rxpl, sendrxkenwood(), split_freq(), rpt::txpl, and rpt::txplon.

Referenced by rpt_tele_thread().

07688 {
07689 char rxstr[RAD_SERIAL_BUFLEN],txstr[RAD_SERIAL_BUFLEN],freq[20];
07690 char mhz[MAXREMSTR],decimals[MAXREMSTR];
07691    
07692 int offsets[] = {0,2,1};
07693 int powers[] = {2,1,0};
07694 
07695    split_freq(mhz, decimals, myrpt->freq);
07696    strcpy(freq,"000000");
07697    strncpy(freq,decimals,strlen(decimals));
07698 
07699    sprintf(txstr,"VF %04d%s,4,%d,0,%d,0,0,%d,%d,000,00600000,0,0\r",
07700       atoi(mhz),freq,offsets[(int)myrpt->offset],
07701       (myrpt->txplon != 0),kenwood_pltocode(myrpt->txpl),
07702       kenwood_pltocode(myrpt->rxpl));
07703 
07704    if (sendrxkenwood(myrpt,txstr,rxstr,"VF") < 0) return -1;
07705    if (sendrxkenwood(myrpt,"VM 0\r",rxstr,"VM") < 0) return -1;
07706    sprintf(txstr,"PC %d\r",powers[(int)myrpt->powerlevel]);
07707    if (sendrxkenwood(myrpt,txstr,rxstr,"PC") < 0) return -1;
07708    return 0;
07709 }

static int setdtr ( int  fd,
int  enable 
) [static]

Definition at line 1648 of file app_rpt.c.

References ast_log(), errno, and LOG_WARNING.

Referenced by openserial(), and rpt_tele_thread().

01649 {
01650 struct termios mode;
01651 
01652    if (fd < 0) return -1;
01653    if (tcgetattr(fd, &mode)) {
01654       ast_log(LOG_WARNING, "Unable to get serial parameters for dtr: %s\n", strerror(errno));
01655       return -1;
01656    }
01657    if (enable)
01658    {
01659       cfsetspeed(&mode, B9600);
01660    }
01661    else
01662    {
01663       cfsetspeed(&mode, B0);
01664       usleep(100000);
01665    }
01666    if (tcsetattr(fd, TCSADRAIN, &mode)) {
01667       ast_log(LOG_WARNING, "Unable to set serial parameters for dtr: %s\n", strerror(errno));
01668       return -1;
01669    }
01670    if (enable) usleep(100000);
01671    return 0;
01672 }

static int setkenwood ( struct rpt myrpt  )  [static]

Definition at line 7645 of file app_rpt.c.

References rpt::freq, IS_XPMR, kenwood_pltocode(), MAXREMSTR, rpt::offset, rpt::powerlevel, rpt::rxpl, rpt::rxplon, sendrxkenwood(), split_freq(), rpt::txpl, and rpt::txplon.

Referenced by rpt_tele_thread().

07646 {
07647 char rxstr[RAD_SERIAL_BUFLEN],txstr[RAD_SERIAL_BUFLEN],freq[20];
07648 char mhz[MAXREMSTR],offset[20],band,decimals[MAXREMSTR],band1,band2;
07649 int myrxpl;
07650    
07651 int offsets[] = {0,2,1};
07652 int powers[] = {2,1,0};
07653 
07654    if (sendrxkenwood(myrpt,"VMC 0,0\r",rxstr,"VMC") < 0) return -1;
07655    split_freq(mhz, decimals, myrpt->freq);
07656    if (atoi(mhz) > 400)
07657    {
07658       band = '6';
07659       band1 = '1';
07660       band2 = '5';
07661       strcpy(offset,"005000000");
07662    }
07663    else
07664    {
07665       band = '2';
07666       band1 = '0';
07667       band2 = '2';
07668       strcpy(offset,"000600000");
07669    }
07670    strcpy(freq,"000000");
07671    strncpy(freq,decimals,strlen(decimals));
07672    myrxpl = myrpt->rxplon;
07673    if (IS_XPMR(myrpt)) myrxpl = 0;
07674    sprintf(txstr,"VW %c,%05d%s,0,%d,0,%d,%d,,%02d,,%02d,%s\r",
07675       band,atoi(mhz),freq,offsets[(int)myrpt->offset],
07676       (myrpt->txplon != 0),myrxpl,
07677       kenwood_pltocode(myrpt->txpl),kenwood_pltocode(myrpt->rxpl),
07678       offset);
07679    if (sendrxkenwood(myrpt,txstr,rxstr,"VW") < 0) return -1;
07680    sprintf(txstr,"RBN %c\r",band2);
07681    if (sendrxkenwood(myrpt,txstr,rxstr,"RBN") < 0) return -1;
07682    sprintf(txstr,"PC %c,%d\r",band1,powers[(int)myrpt->powerlevel]);
07683    if (sendrxkenwood(myrpt,txstr,rxstr,"PC") < 0) return -1;
07684    return 0;
07685 }

static int setrbi ( struct rpt myrpt  )  [static]

Definition at line 7711 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::remoterig, rpt::rxpl, rpt::rxplon, s, setrbi_check(), and rpt::txplon.

Referenced by rpt_tele_thread().

07712 {
07713 char tmp[MAXREMSTR] = "",*s;
07714 unsigned char rbicmd[5];
07715 int   band,txoffset = 0,txpower = 0,rxpl;
07716 
07717    /* must be a remote system */
07718    if (!myrpt->remoterig) return(0);
07719    if (!myrpt->remoterig[0]) return(0);
07720    /* must have rbi hardware */
07721    if (strncmp(myrpt->remoterig,remote_rig_rbi,3)) return(0);
07722    if (setrbi_check(myrpt) == -1) return(-1);
07723    strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
07724    s = strchr(tmp,'.');
07725    /* if no decimal, is invalid */
07726    
07727    if (s == NULL){
07728       if(debug)
07729          printf("@@@@ Frequency needs a decimal\n");
07730       return -1;
07731    }
07732    
07733    *s++ = 0;
07734    if (strlen(tmp) < 2){
07735       if(debug)
07736          printf("@@@@ Bad MHz digits: %s\n", tmp);
07737       return -1;
07738    }
07739     
07740    if (strlen(s) < 3){
07741       if(debug)
07742          printf("@@@@ Bad KHz digits: %s\n", s);
07743       return -1;
07744    }
07745 
07746    if ((s[2] != '0') && (s[2] != '5')){
07747       if(debug)
07748          printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
07749       return -1;
07750    }
07751     
07752    band = rbi_mhztoband(tmp);
07753    if (band == -1){
07754       if(debug)
07755          printf("@@@@ Bad Band: %s\n", tmp);
07756       return -1;
07757    }
07758    
07759    rxpl = rbi_pltocode(myrpt->rxpl);
07760    
07761    if (rxpl == -1){
07762       if(debug)
07763          printf("@@@@ Bad TX PL: %s\n", myrpt->rxpl);
07764       return -1;
07765    }
07766 
07767    
07768    switch(myrpt->offset)
07769    {
07770        case REM_MINUS:
07771       txoffset = 0;
07772       break;
07773        case REM_PLUS:
07774       txoffset = 0x10;
07775       break;
07776        case REM_SIMPLEX:
07777       txoffset = 0x20;
07778       break;
07779    }
07780    switch(myrpt->powerlevel)
07781    {
07782        case REM_LOWPWR:
07783       txpower = 0;
07784       break;
07785        case REM_MEDPWR:
07786       txpower = 0x20;
07787       break;
07788        case REM_HIPWR:
07789       txpower = 0x10;
07790       break;
07791    }
07792    rbicmd[0] = 0;
07793    rbicmd[1] = band | txpower | 0xc0;
07794    rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80;
07795    if (s[2] == '5') rbicmd[2] |= 0x40;
07796    rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0');
07797    rbicmd[4] = rxpl;
07798    if (myrpt->txplon) rbicmd[4] |= 0x40;
07799    if (myrpt->rxplon) rbicmd[4] |= 0x80;
07800    rbi_out(myrpt,rbicmd);
07801    return 0;
07802 }

static int setrbi_check ( struct rpt myrpt  )  [static]

Definition at line 7962 of file app_rpt.c.

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

Referenced by setrbi(), and setrem().

07963 {
07964 char tmp[MAXREMSTR] = "",*s;
07965 int   band,txpl;
07966 
07967    /* must be a remote system */
07968    if (!myrpt->remote) return(0);
07969    /* must have rbi hardware */
07970    if (strncmp(myrpt->remoterig,remote_rig_rbi,3)) return(0);
07971    strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
07972    s = strchr(tmp,'.');
07973    /* if no decimal, is invalid */
07974    
07975    if (s == NULL){
07976       if(debug)
07977          printf("@@@@ Frequency needs a decimal\n");
07978       return -1;
07979    }
07980    
07981    *s++ = 0;
07982    if (strlen(tmp) < 2){
07983       if(debug)
07984          printf("@@@@ Bad MHz digits: %s\n", tmp);
07985       return -1;
07986    }
07987     
07988    if (strlen(s) < 3){
07989       if(debug)
07990          printf("@@@@ Bad KHz digits: %s\n", s);
07991       return -1;
07992    }
07993 
07994    if ((s[2] != '0') && (s[2] != '5')){
07995       if(debug)
07996          printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
07997       return -1;
07998    }
07999     
08000    band = rbi_mhztoband(tmp);
08001    if (band == -1){
08002       if(debug)
08003          printf("@@@@ Bad Band: %s\n", tmp);
08004       return -1;
08005    }
08006    
08007    txpl = rbi_pltocode(myrpt->txpl);
08008    
08009    if (txpl == -1){
08010       if(debug)
08011          printf("@@@@ Bad TX PL: %s\n", myrpt->txpl);
08012       return -1;
08013    }
08014    return 0;
08015 }

static int setrem ( struct rpt myrpt  )  [static]

Definition at line 9236 of file app_rpt.c.

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

Referenced by function_cop(), function_remote(), get_mem_set(), and rpt().

09237 {
09238 char  str[300];
09239 char  *offsets[] = {"SIMPLEX","MINUS","PLUS"};
09240 char  *powerlevels[] = {"LOW","MEDIUM","HIGH"};
09241 char  *modes[] = {"FM","USB","LSB","AM"};
09242 int   res = -1;
09243 
09244 #if   0
09245 printf("FREQ,%s,%s,%s,%s,%s,%s,%d,%d\n",myrpt->freq,
09246    modes[(int)myrpt->remmode],
09247    myrpt->txpl,myrpt->rxpl,offsets[(int)myrpt->offset],
09248    powerlevels[(int)myrpt->powerlevel],myrpt->txplon,
09249    myrpt->rxplon);
09250 #endif
09251    if (myrpt->p.archivedir)
09252    {
09253       sprintf(str,"FREQ,%s,%s,%s,%s,%s,%s,%d,%d",myrpt->freq,
09254          modes[(int)myrpt->remmode],
09255          myrpt->txpl,myrpt->rxpl,offsets[(int)myrpt->offset],
09256          powerlevels[(int)myrpt->powerlevel],myrpt->txplon,
09257          myrpt->rxplon);
09258       donodelog(myrpt,str);
09259    }
09260    if(!strcmp(myrpt->remoterig, remote_rig_ft897))
09261    {
09262       rpt_telemetry(myrpt,SETREMOTE,NULL);
09263       res = 0;
09264    }
09265    if(!strcmp(myrpt->remoterig, remote_rig_ic706))
09266    {
09267       rpt_telemetry(myrpt,SETREMOTE,NULL);
09268       res = 0;
09269    }
09270    if(!strcmp(myrpt->remoterig, remote_rig_tm271))
09271    {
09272       rpt_telemetry(myrpt,SETREMOTE,NULL);
09273       res = 0;
09274    }
09275    else if(!strcmp(myrpt->remoterig, remote_rig_rbi))
09276    {
09277       res = setrbi_check(myrpt);
09278       if (!res)
09279       {
09280          rpt_telemetry(myrpt,SETREMOTE,NULL);
09281          res = 0;
09282       }
09283    }
09284    else if(ISRIG_RTX(myrpt->remoterig))
09285    {
09286       setrtx(myrpt);
09287       res = 0;
09288    }
09289    else if(!strcmp(myrpt->remoterig, remote_rig_kenwood)) {
09290       rpt_telemetry(myrpt,SETREMOTE,NULL);
09291       res = 0;
09292    }
09293    else
09294       res = 0;
09295 
09296    if (res < 0) ast_log(LOG_ERROR,"Unable to send remote command on node %s\n",myrpt->name);
09297 
09298    return res;
09299 }

static int setrtx ( struct rpt myrpt  )  [static]

Definition at line 7804 of file app_rpt.c.

References COMPLETE, rpt::freq, IS_XPMR, ISRIG_RTX, MAXREMSTR, rpt::name, rpt::offset, rpt::powerlevel, rbi_mhztoband(), rbi_pltocode(), REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_PLUS, REM_SIMPLEX, rpt::remoterig, rpt_telemetry(), rpt::rxpl, rpt::rxplon, s, send_usb_txt(), setrtx_check(), rpt::txpl, and rpt::txplon.

Referenced by setrem().

07805 {
07806 char tmp[MAXREMSTR] = "",*s,rigstr[200],pwr,res = 0;
07807 int   band,txoffset = 0,txpower = 0,rxpl,txpl;
07808 float ofac;
07809 double txfreq;
07810 
07811    /* must be a remote system */
07812    if (!myrpt->remoterig) return(0);
07813    if (!myrpt->remoterig[0]) return(0);
07814    /* must have rtx hardware */
07815    if (!ISRIG_RTX(myrpt->remoterig)) return(0);
07816    /* must be a usbradio interface type */
07817    if (!IS_XPMR(myrpt)) return(0);
07818    strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
07819    s = strchr(tmp,'.');
07820    /* if no decimal, is invalid */
07821    
07822    if(debug)printf("setrtx() %s %s\n",myrpt->name,myrpt->remoterig);
07823 
07824    if (s == NULL){
07825       if(debug)
07826          printf("@@@@ Frequency needs a decimal\n");
07827       return -1;
07828    }
07829    *s++ = 0;
07830    if (strlen(tmp) < 2){
07831       if(debug)
07832          printf("@@@@ Bad MHz digits: %s\n", tmp);
07833       return -1;
07834    }
07835     
07836    if (strlen(s) < 3){
07837       if(debug)
07838          printf("@@@@ Bad KHz digits: %s\n", s);
07839       return -1;
07840    }
07841 
07842    if ((s[2] != '0') && (s[2] != '5')){
07843       if(debug)
07844          printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
07845       return -1;
07846    }
07847     
07848    band = rbi_mhztoband(tmp);
07849    if (band == -1){
07850       if(debug)
07851          printf("@@@@ Bad Band: %s\n", tmp);
07852       return -1;
07853    }
07854    
07855    rxpl = rbi_pltocode(myrpt->rxpl);
07856    
07857    if (rxpl == -1){
07858       if(debug)
07859          printf("@@@@ Bad RX PL: %s\n", myrpt->rxpl);
07860       return -1;
07861    }
07862 
07863    txpl = rbi_pltocode(myrpt->txpl);
07864    
07865    if (txpl == -1){
07866       if(debug)
07867          printf("@@@@ Bad TX PL: %s\n", myrpt->txpl);
07868       return -1;
07869    }
07870    
07871    switch(myrpt->offset)
07872    {
07873        case REM_MINUS:
07874       txoffset = 0;
07875       break;
07876        case REM_PLUS:
07877       txoffset = 0x10;
07878       break;
07879        case REM_SIMPLEX:
07880       txoffset = 0x20;
07881       break;
07882    }
07883    switch(myrpt->powerlevel)
07884    {
07885        case REM_LOWPWR:
07886       txpower = 0;
07887       break;
07888        case REM_MEDPWR:
07889       txpower = 0x20;
07890       break;
07891        case REM_HIPWR:
07892       txpower = 0x10;
07893       break;
07894    }
07895 
07896    res = setrtx_check(myrpt);
07897    if (res < 0) return res;
07898    ofac = 0.0;
07899    if (myrpt->offset == REM_MINUS) ofac = -1.0;
07900    if (myrpt->offset == REM_PLUS) ofac = 1.0;
07901 
07902    if (!strcmp(myrpt->remoterig,remote_rig_rtx450))
07903       txfreq = atof(myrpt->freq) +  (ofac * 5.0);
07904    else
07905       txfreq = atof(myrpt->freq) +  (ofac * 0.6);
07906 
07907    pwr = 'L';
07908    if (myrpt->powerlevel == REM_HIPWR) pwr = 'H';
07909    if (!res)
07910    {
07911       sprintf(rigstr,"SETFREQ %s %f %s %s %c",myrpt->freq,txfreq,
07912          (myrpt->rxplon) ? myrpt->rxpl : "0.0",
07913          (myrpt->txplon) ? myrpt->txpl : "0.0",pwr);
07914       send_usb_txt(myrpt,rigstr);
07915       rpt_telemetry(myrpt,COMPLETE,NULL);
07916       res = 0;
07917    }
07918    return 0;
07919 }

static int setrtx_check ( struct rpt myrpt  )  [static]

Definition at line 8017 of file app_rpt.c.

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

Referenced by setrtx().

08018 {
08019 char tmp[MAXREMSTR] = "",*s;
08020 int   band,txpl,rxpl;
08021 
08022    /* must be a remote system */
08023    if (!myrpt->remote) return(0);
08024    /* must have rbi hardware */
08025    if (strncmp(myrpt->remoterig,remote_rig_rbi,3)) return(0);
08026    strncpy(tmp, myrpt->freq, sizeof(tmp) - 1);
08027    s = strchr(tmp,'.');
08028    /* if no decimal, is invalid */
08029    
08030    if (s == NULL){
08031       if(debug)
08032          printf("@@@@ Frequency needs a decimal\n");
08033       return -1;
08034    }
08035    
08036    *s++ = 0;
08037    if (strlen(tmp) < 2){
08038       if(debug)
08039          printf("@@@@ Bad MHz digits: %s\n", tmp);
08040       return -1;
08041    }
08042     
08043    if (strlen(s) < 3){
08044       if(debug)
08045          printf("@@@@ Bad KHz digits: %s\n", s);
08046       return -1;
08047    }
08048 
08049    if ((s[2] != '0') && (s[2] != '5')){
08050       if(debug)
08051          printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]);
08052       return -1;
08053    }
08054     
08055    band = rbi_mhztoband(tmp);
08056    if (band == -1){
08057       if(debug)
08058          printf("@@@@ Bad Band: %s\n", tmp);
08059       return -1;
08060    }
08061    
08062    txpl = rbi_pltocode(myrpt->txpl);
08063    
08064    if (txpl == -1){
08065       if(debug)
08066          printf("@@@@ Bad TX PL: %s\n", myrpt->txpl);
08067       return -1;
08068    }
08069 
08070    rxpl = rbi_pltocode(myrpt->rxpl);
08071    
08072    if (rxpl == -1){
08073       if(debug)
08074          printf("@@@@ Bad RX PL: %s\n", myrpt->rxpl);
08075       return -1;
08076    }
08077    return 0;
08078 }

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

Definition at line 8394 of file app_rpt.c.

References serial_remote_io().

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

08395 {
08396    unsigned char cmdstr[5];
08397    
08398    memset(cmdstr, 0, 5);
08399 
08400    cmdstr[4] = command; 
08401 
08402    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08403 
08404 }

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

Definition at line 8876 of file app_rpt.c.

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

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

08877 {
08878    unsigned char cmdstr[10];
08879    
08880    cmdstr[0] = cmdstr[1] = 0xfe;
08881    cmdstr[2] = myrpt->p.civaddr;
08882    cmdstr[3] = 0xe0;
08883    cmdstr[4] = command;
08884    cmdstr[5] = subcommand;
08885    cmdstr[6] = 0xfd;
08886 
08887    return(civ_cmd(myrpt,cmdstr,7));
08888 }

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

Definition at line 2080 of file app_rpt.c.

Referenced by function_autopatchup().

02081 {
02082 int i;   
02083    while(*string){
02084       for(i = 0; charlist[i] ; i++){
02085          if(*string == charlist[i]){
02086             string++;
02087             break;
02088          }
02089       }
02090       if(!charlist[i])
02091          return string;
02092    }
02093    return string;
02094 }  

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

Definition at line 8247 of file app_rpt.c.

References MAXREMSTR.

Referenced by set_ctcss_freq_ft897().

08248 {
08249    char freq_copy[MAXREMSTR];
08250    char *decp;
08251 
08252    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
08253    if(decp){
08254       *decp++ = 0;
08255       strncpy(hertz, freq_copy, MAXREMSTR);
08256       strncpy(decimal, decp, strlen(decp));
08257       decimal[strlen(decp)] = '\0';
08258       return 0;
08259    }
08260    else
08261       return -1;
08262 }

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

Definition at line 8224 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(), set_tm271(), and setkenwood().

08225 {
08226    char freq_copy[MAXREMSTR];
08227    char *decp;
08228 
08229    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
08230    if(decp){
08231       *decp++ = 0;
08232       strncpy(mhz, freq_copy, MAXREMSTR);
08233       strcpy(decimals, "00000");
08234       strncpy(decimals, decp, strlen(decp));
08235       decimals[5] = 0;
08236       return 0;
08237    }
08238    else
08239       return -1;
08240 
08241 }

static void statpost ( struct rpt myrpt,
char *  pairs 
) [static]

Definition at line 1949 of file app_rpt.c.

References ast_free, ast_log(), ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), ast_safe_fork(), ast_strdup, finddelim(), LOG_ERROR, rpt::name, rpt::p, seq, rpt::statpost_lock, rpt::statpost_program, rpt::statpost_seqno, and rpt::statpost_url.

Referenced by rpt().

01950 {
01951 char *str,*astr;
01952 char *astrs[100];
01953 int   n,pid;
01954 time_t   now;
01955 unsigned int seq;
01956 
01957    if (!myrpt->p.statpost_url) return;
01958    str = ast_malloc(strlen(pairs) + strlen(myrpt->p.statpost_url) + 200);
01959    astr = ast_strdup(myrpt->p.statpost_program);
01960    if ((!str) || (!astr)) return;
01961    n = finddelim(astr,astrs,100);
01962    if (n < 1) return;
01963    ast_mutex_lock(&myrpt->statpost_lock);
01964    seq = ++myrpt->statpost_seqno;
01965    ast_mutex_unlock(&myrpt->statpost_lock);
01966    astrs[n++] = str;
01967    astrs[n] = NULL;
01968    time(&now);
01969    sprintf(str,"%s?node=%s&time=%u&seqno=%u",myrpt->p.statpost_url,
01970       myrpt->name,(unsigned int) now,seq);
01971    if (pairs) sprintf(str + strlen(str),"&%s",pairs);
01972    if (!(pid = ast_safe_fork(0)))
01973    {
01974       execv(astrs[0],astrs);
01975       ast_log(LOG_ERROR, "exec of %s failed.\n", astrs[0]);
01976       perror("asterisk");
01977       exit(0);
01978    }
01979    ast_free(astr);
01980    ast_free(str);
01981    return;
01982 }

static void stop_scan ( struct rpt myrpt  )  [static]

Definition at line 9499 of file app_rpt.c.

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

Referenced by handle_remote_dtmf_digit().

09500 {
09501    myrpt->hfscanstop = 1;
09502    rpt_telemetry(myrpt,SCAN,0);
09503 }

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

Definition at line 3735 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and telem_lookup().

03736 {
03737    int res;
03738    char c;
03739    
03740    static int morsespeed;
03741    static int morsefreq;
03742    static int morseampl;
03743    static int morseidfreq = 0;
03744    static int morseidampl;
03745    static char mcat[] = MORSE;
03746    
03747    res = 0;
03748    
03749    if(!morseidfreq){ /* Get the morse parameters if not already loaded */
03750       morsespeed = retrieve_astcfgint(myrpt, mcat, "speed", 5, 20, 20);
03751          morsefreq = retrieve_astcfgint(myrpt, mcat, "frequency", 300, 3000, 800);
03752          morseampl = retrieve_astcfgint(myrpt, mcat, "amplitude", 200, 8192, 4096);
03753       morseidampl = retrieve_astcfgint(myrpt, mcat, "idamplitude", 200, 8192, 2048);
03754       morseidfreq = retrieve_astcfgint(myrpt, mcat, "idfrequency", 300, 3000, 330); 
03755    }
03756    
03757    /* Is it a file, or a tone sequence? */
03758          
03759    if(entry[0] == '|'){
03760       c = entry[1];
03761       if((c >= 'a')&&(c <= 'z'))
03762          c -= 0x20;
03763    
03764       switch(c){
03765          case 'I': /* Morse ID */
03766             res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl);
03767             break;
03768          
03769          case 'M': /* Morse Message */
03770             res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl);
03771             break;
03772          
03773          case 'T': /* Tone sequence */
03774             res = send_tone_telemetry(chan, entry + 2);
03775             break;
03776          default:
03777             res = -1;
03778       }
03779    }
03780    else
03781       res = sayfile(chan, entry); /* File */
03782    return res;
03783 }

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

Definition at line 3791 of file app_rpt.c.

References ast_free, ast_log(), ast_strdup, ast_variable_retrieve(), rpt::cfg, chan, LOG_WARNING, tele_defs, telem_any(), and TELEMETRY.

Referenced by rpt_tele_thread(), and rpt_telemetry().

03792 {
03793    
03794    int res;
03795    int i;
03796    char *entry;
03797    char *telemetry;
03798    char *telemetry_save;
03799 
03800    res = 0;
03801    telemetry_save = NULL;
03802    entry = NULL;
03803    
03804    /* Retrieve the section name for telemetry from the node section */
03805    telemetry = (char *) ast_variable_retrieve(myrpt->cfg, node, TELEMETRY);
03806    if(telemetry ){
03807       telemetry_save = ast_strdup(telemetry);
03808       if(!telemetry_save){
03809          ast_log(LOG_WARNING,"ast_strdup() failed in telem_lookup()\n");
03810          return res;
03811       }
03812       entry = (char *) ast_variable_retrieve(myrpt->cfg, telemetry_save, name);
03813    }
03814    
03815    /* Try to look up the telemetry name */   
03816 
03817    if(!entry){
03818       /* Telemetry name wasn't found in the config file, use the default */
03819       for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
03820          if(!strcasecmp(tele_defs[i].name, name))
03821             entry = tele_defs[i].value;
03822       }
03823    }
03824    if(entry){  
03825       if(strlen(entry))
03826          if (chan) telem_any(myrpt,chan, entry);
03827    }
03828    else{
03829       res = -1;
03830    }
03831    if(telemetry_save)
03832       ast_free(telemetry_save);
03833    return res;
03834 }

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

Definition at line 2119 of file app_rpt.c.

References rpt_topkey::timesince.

Referenced by rpt().

02120 {
02121 struct rpt_topkey *x = (struct rpt_topkey *) a;
02122 struct rpt_topkey *y = (struct rpt_topkey *) b;
02123 
02124    return(x->timesince - y->timesince);
02125 }

static int unload_module ( void   )  [static]

Definition at line 15100 of file app_rpt.c.

References ast_cli_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_destroy(), ast_unregister_application(), cli_reload, lock, name, and rpt_cli.

15102 {
15103    int i, res;
15104 
15105 #ifdef   OLD_ASTERISK
15106    STANDARD_HANGUP_LOCALUSERS;
15107 #endif
15108    for(i = 0; i < nrpts; i++) {
15109       if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue;
15110                 ast_mutex_destroy(&rpt_vars[i].lock);
15111                 ast_mutex_destroy(&rpt_vars[i].remlock);
15112    }
15113    res = ast_unregister_application(app);
15114 
15115 #ifdef   NEW_ASTERISK
15116    ast_cli_unregister_multiple(rpt_cli,sizeof(rpt_cli) / 
15117       sizeof(struct ast_cli_entry));
15118 #else
15119    /* Unregister cli extensions */
15120    ast_cli_unregister(&cli_debug);
15121    ast_cli_unregister(&cli_dump);
15122    ast_cli_unregister(&cli_stats);
15123    ast_cli_unregister(&cli_lstats);
15124    ast_cli_unregister(&cli_nodes);
15125    ast_cli_unregister(&cli_local_nodes);
15126    ast_cli_unregister(&cli_reload);
15127    ast_cli_unregister(&cli_restart);
15128    ast_cli_unregister(&cli_fun);
15129    ast_cli_unregister(&cli_fun1);
15130    res |= ast_cli_unregister(&cli_cmd);
15131 #endif
15132 #ifndef OLD_ASTERISK
15133    res |= ast_manager_unregister("RptLocalNodes");
15134    res |= ast_manager_unregister("RptStatus");
15135 #endif
15136    return res;
15137 }

static int vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 9072 of file app_rpt.c.

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

Referenced by set_ic706().

09073 {
09074    unsigned char cmdstr[10];
09075    
09076    cmdstr[0] = cmdstr[1] = 0xfe;
09077    cmdstr[2] = myrpt->p.civaddr;
09078    cmdstr[3] = 0xe0;
09079    cmdstr[4] = 7;
09080    cmdstr[5] = 0xfd;
09081 
09082    return(civ_cmd(myrpt,cmdstr,6));
09083 }

static void voxinit_link ( struct rpt_link mylink,
char  enable 
) [static]

Definition at line 1102 of file app_rpt.c.

References vox::enacount, vox::lastvox, vox::noise_energy, vox::offdebcnt, vox::ondebcnt, vox::speech_energy, rpt_link::vox, VOX_OFF_DEBOUNCE_COUNT, VOX_ON_DEBOUNCE_COUNT, vox::voxena, rpt_link::voxtostate, rpt_link::voxtotimer, and rpt_link::wasvox.

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

01103 {
01104 
01105    mylink->vox.speech_energy = 0.0;
01106    mylink->vox.noise_energy = 0.0;
01107    mylink->vox.enacount = 0;
01108    mylink->vox.voxena = 0;
01109    if (!enable) mylink->vox.voxena = -1;
01110    mylink->vox.lastvox = 0;
01111    mylink->vox.ondebcnt = VOX_ON_DEBOUNCE_COUNT;
01112    mylink->vox.offdebcnt = VOX_OFF_DEBOUNCE_COUNT;
01113    mylink->wasvox = 0;
01114    mylink->voxtotimer = 0;
01115    mylink->voxtostate = 0;
01116 }

static void voxinit_rpt ( struct rpt myrpt,
char  enable 
) [static]

Definition at line 1086 of file app_rpt.c.

References vox::enacount, vox::lastvox, vox::noise_energy, vox::offdebcnt, vox::ondebcnt, vox::speech_energy, rpt::vox, VOX_OFF_DEBOUNCE_COUNT, VOX_ON_DEBOUNCE_COUNT, vox::voxena, rpt::voxtostate, rpt::voxtotimer, and rpt::wasvox.

Referenced by rpt().

01087 {
01088 
01089    myrpt->vox.speech_energy = 0.0;
01090    myrpt->vox.noise_energy = 0.0;
01091    myrpt->vox.enacount = 0;
01092    myrpt->vox.voxena = 0;
01093    if (!enable) myrpt->vox.voxena = -1;
01094    myrpt->vox.lastvox = 0;
01095    myrpt->vox.ondebcnt = VOX_ON_DEBOUNCE_COUNT;
01096    myrpt->vox.offdebcnt = VOX_OFF_DEBOUNCE_COUNT;
01097    myrpt->wasvox = 0;
01098    myrpt->voxtotimer = 0;
01099    myrpt->voxtostate = 0;
01100 }

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

Definition at line 3919 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

03920 {
03921    int interval;
03922    interval = get_wait_interval(myrpt, type);
03923    if(debug)
03924       ast_log(LOG_NOTICE,"Delay interval = %d\n", interval);
03925    if(interval)
03926       ast_safe_sleep(chan,interval);
03927    if(debug)
03928       ast_log(LOG_NOTICE,"Delay complete\n");
03929    return;
03930 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 15212 of file app_rpt.c.

char* app = "Rpt" [static]

Definition at line 379 of file app_rpt.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 15212 of file app_rpt.c.

char cmd_usage[] [static]

Initial value:

"Usage: rpt cmd <nodename> <cmd-name> <cmd-index> <cmd-args.\n"
"       Send a command to a node.\n        i.e. rpt cmd 2000 ilink 3 2001\n"

Definition at line 1222 of file app_rpt.c.

struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }

Definition at line 368 of file app_rpt.c.

Referenced by __ast_http_load(), __ast_http_post_load(), __ast_rtp_reload(), __ast_udptl_reload(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), adsi_load(), advanced_options(), aji_load_config(), ast_readconfig(), conf_exec(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_provision_reload(), ind_load_module(), init_logger_chain(), jingle_load_config(), load_config(), load_config_meetme(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_rpt_vars(), make_email_file(), misdn_cfg_init(), node_lookup(), odbc_load_module(), osp_load(), parse_config(), pbx_load_config(), pbx_load_users(), play_message(), prep_email_sub_vars(), private_enum_init(), read_agent_config(), realtime_directory(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), set_config(), setup_dahdi(), sla_load_config(), smdi_load(), tds_load_module(), vm_change_password(), and vm_forwardoptions().

int debug = 0 [static]

Definition at line 439 of file app_rpt.c.

Referenced by aji_load_config(), check_peer_ok(), handle_incoming(), handle_pri_show_debug(), and handle_verbose().

char debug_usage[] [static]

Initial value:

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

Definition at line 1186 of file app_rpt.c.

char* descrip [static]

Definition at line 383 of file app_rpt.c.

char* discstr = "!!DISCONNECT!!"

Definition at line 459 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 1198 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 1202 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 1194 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 1190 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 1218 of file app_rpt.c.

struct function_table_tag function_table[] [static]

Definition at line 1323 of file app_rpt.c.

Referenced by collect_function_digits(), rpt(), and rpt_do_cmd().

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

Definition at line 446 of file app_rpt.c.

char* newkeystr = "!NEWKEY!"

Definition at line 460 of file app_rpt.c.

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

Definition at line 886 of file app_rpt.c.

Referenced by donodelog(), and rpt_master().

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

Definition at line 888 of file app_rpt.c.

Referenced by node_lookup().

int nrpts = 0 [static]

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

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

Definition at line 442 of file app_rpt.c.

char* remote_rig_ft897 = "ft897" [static]

Definition at line 461 of file app_rpt.c.

char* remote_rig_ic706 = "ic706" [static]

Definition at line 465 of file app_rpt.c.

char* remote_rig_kenwood = "kenwood" [static]

Definition at line 463 of file app_rpt.c.

char* remote_rig_ppp16 = "ppp16" [static]

Definition at line 468 of file app_rpt.c.

char* remote_rig_rbi = "rbi" [static]

Definition at line 462 of file app_rpt.c.

char* remote_rig_rtx150 = "rtx150" [static]

Definition at line 466 of file app_rpt.c.

char* remote_rig_rtx450 = "rtx450" [static]

Definition at line 467 of file app_rpt.c.

char* remote_rig_tm271 = "tm271" [static]

Definition at line 464 of file app_rpt.c.

char restart_usage[] [static]

Initial value:

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

Definition at line 1214 of file app_rpt.c.

struct ast_cli_entry rpt_cli[] [static]

Definition at line 3443 of file app_rpt.c.

Referenced by load_module(), and unload_module().

pthread_t rpt_master_thread [static]

Definition at line 524 of file app_rpt.c.

struct rpt rpt_vars[MAXRPTS] [static]

time_t starttime = 0 [static]

Definition at line 522 of file app_rpt.c.

Referenced by tzparse(), and wait_for_answer().

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

Definition at line 381 of file app_rpt.c.

char* tdesc = "Radio Repeater / Remote Base version 0.115 5/12/2008" [static]

Definition at line 377 of file app_rpt.c.

struct telem_defaults tele_defs[] [static]

Definition at line 1279 of file app_rpt.c.

Referenced by telem_lookup().

char usage_local_nodes[] [static]

Initial value:

"Usage: rpt localnodes\n"
"       Dumps a list of the locally configured node numbers to the console.\n"

Definition at line 1206 of file app_rpt.c.


Generated on Fri Jul 24 00:41:14 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7