Mon Mar 19 11:30:33 2012

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)
void ast_playtones_stop (struct ast_channel *chan)
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 (const 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, const char *const *argv)
static int rpt_do_debug (int fd, int argc, const char *const *argv)
static int rpt_do_dump (int fd, int argc, const char *const *argv)
static int rpt_do_fun (int fd, int argc, const char *const *argv)
static int rpt_do_fun1 (int fd, int argc, const char *const *argv)
static int rpt_do_local_nodes (int fd, int argc, const char *const *argv)
static int rpt_do_lstats (int fd, int argc, const char *const *argv)
static int rpt_do_nodes (int fd, int argc, const char *const *argv)
static int rpt_do_reload (int fd, int argc, const char *const *argv)
static int rpt_do_restart (int fd, int argc, const char *const *argv)
static int rpt_do_stats (int fd, int argc, const char *const *argv)
static int rpt_exec (struct ast_channel *chan, const char *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 = "88eaa8f5c1bd988bedd71113385e0886" , .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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static ast_mutex_t nodelookuplock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static int nrpts = 0
static char reload_usage []
static const 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 265 of file app_rpt.c.

#define ALLOW_LOCAL_CHANNELS

Definition at line 287 of file app_rpt.c.

#define AUTHLOGOUTTIME   25000

Definition at line 197 of file app_rpt.c.

#define AUTHTELLTIME   7000

Definition at line 195 of file app_rpt.c.

#define AUTHTXTIME   1000

Definition at line 196 of file app_rpt.c.

#define CMD_DEPTH   1

Definition at line 643 of file app_rpt.c.

#define CMD_STATE_BUSY   1

Definition at line 645 of file app_rpt.c.

Referenced by rpt_do_cmd().

#define CMD_STATE_EXECUTING   3

Definition at line 647 of file app_rpt.c.

Referenced by rpt().

#define CMD_STATE_IDLE   0

Definition at line 644 of file app_rpt.c.

Referenced by rpt(), and rpt_do_cmd().

#define CMD_STATE_READY   2

Definition at line 646 of file app_rpt.c.

Referenced by rpt(), and rpt_do_cmd().

#define DEFAULT_CIV_ADDR   0x58

Definition at line 253 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_IOBASE   0x378

Definition at line 251 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_MONITOR_MIN_DISK_BLOCKS   10000

Definition at line 229 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_INACT_TIMEOUT   (15 * 60)

Definition at line 230 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT   (60 * 60)

Definition at line 231 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING   (3 * 60)

Definition at line 232 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DEFAULT_REMOTE_TIMEOUT_WARNING_FREQ   30

Definition at line 233 of file app_rpt.c.

Referenced by load_rpt_vars().

#define DELIMCHR   ','

Definition at line 224 of file app_rpt.c.

Referenced by finddelim().

#define DISC_TIME   10000

Definition at line 203 of file app_rpt.c.

Referenced by rpt().

#define DTMF_LOCAL_STARTTIME   500

Definition at line 272 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_LOCAL_TIME   250

Definition at line 271 of file app_rpt.c.

Referenced by do_dtmf_local().

#define DTMF_TIMEOUT   3

Definition at line 189 of file app_rpt.c.

Referenced by handle_remote_dtmf_digit(), and rpt().

#define ENDCHAR   '#'

Definition at line 244 of file app_rpt.c.

Referenced by load_rpt_vars().

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

Definition at line 245 of file app_rpt.c.

Referenced by load_rpt_vars().

#define EXTNODES   "extnodes"

Definition at line 236 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCCHAR   '*'

Definition at line 243 of file app_rpt.c.

Referenced by load_rpt_vars().

#define FUNCTDELAY   1500

Definition at line 486 of file app_rpt.c.

#define FUNCTIONS   "functions"

Definition at line 239 of file app_rpt.c.

Referenced by load_rpt_vars().

#define HANGTIME   5000

Definition at line 480 of file app_rpt.c.

Referenced by load_rpt_vars().

#define IC706_PL_MEMORY_OFFSET   50

Definition at line 274 of file app_rpt.c.

Referenced by set_ic706().

#define IDTIME   300000

Definition at line 482 of file app_rpt.c.

Referenced by load_rpt_vars().

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

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

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

#define KENWOOD_RETRIES   5

Definition at line 190 of file app_rpt.c.

Referenced by sendrxkenwood().

#define KEYPOSTSHORTTIME   200

Definition at line 186 of file app_rpt.c.

Referenced by rpt().

#define KEYPOSTTIME   30000

Definition at line 185 of file app_rpt.c.

Referenced by rpt().

#define LINKLISTSHORTTIME   200

Definition at line 182 of file app_rpt.c.

Referenced by __kickshort().

#define LINKLISTTIME   10000

Definition at line 181 of file app_rpt.c.

Referenced by rpt().

#define LINKPOSTSHORTTIME   200

Definition at line 184 of file app_rpt.c.

Referenced by __kickshort().

#define LINKPOSTTIME   30000

Definition at line 183 of file app_rpt.c.

Referenced by rpt().

#define MACRO   "macro"

Definition at line 238 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MACROPTIME   500

Definition at line 188 of file app_rpt.c.

Referenced by rpt().

#define MACROTIME   100

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

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

#define MAX_RETRIES_PERM   1000000000

Definition at line 205 of file app_rpt.c.

Referenced by connect_link().

#define MAX_STAT_LINKS   32

Definition at line 484 of file app_rpt.c.

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

#define MAX_SYSSTATES   10

Definition at line 491 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXCONNECTTIME   5000

Definition at line 255 of file app_rpt.c.

Referenced by rpt().

#define MAXDTMF   32

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

#define MAXLINKLIST   512

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

#define MAXNODESTR   300

Definition at line 257 of file app_rpt.c.

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

#define MAXPATCHCONTEXT   100

Definition at line 263 of file app_rpt.c.

Referenced by function_autopatchup(), and local_dtmf_helper().

#define MAXPEERSTR   31

Definition at line 221 of file app_rpt.c.

Referenced by rpt_do_lstats().

#define MAXREMSTR   15

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

#define MAXXLAT   20

Definition at line 488 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MAXXLATTIME   3

Definition at line 489 of file app_rpt.c.

Referenced by func_xlat().

#define MEMORY   "memory"

Definition at line 237 of file app_rpt.c.

Referenced by load_rpt_vars().

#define MONITOR_DISK_BLOCKS_PER_MINUTE   38

Definition at line 227 of file app_rpt.c.

#define MORSE   "morse"

Definition at line 241 of file app_rpt.c.

Referenced by telem_any().

#define MSWAIT   200

Definition at line 479 of file app_rpt.c.

Referenced by rpt(), and rpt_call().

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

Definition at line 503 of file app_rpt.c.

Referenced by dovox().

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

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

Referenced by saynode().

#define NODES   "nodes"

Definition at line 235 of file app_rpt.c.

Referenced by load_rpt_vars().

#define NRPTSTAT   7

Definition at line 449 of file app_rpt.c.

Referenced by rpt_do_lstats().

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

Definition at line 247 of file app_rpt.c.

Referenced by rpt(), and rpt_tele_thread().

#define PARROTTIME   1000

Definition at line 249 of file app_rpt.c.

Referenced by load_rpt_vars().

#define PATCH_DIALPLAN_TIMEOUT   1500

Definition at line 211 of file app_rpt.c.

Referenced by rpt_call().

#define POLITEID   30000

Definition at line 485 of file app_rpt.c.

Referenced by load_rpt_vars().

#define QUOTECHR   34

Definition at line 225 of file app_rpt.c.

Referenced by finddelim().

#define REDUNDANT_TX_TIME   2000

Definition at line 207 of file app_rpt.c.

Referenced by rpt().

#define REM_SCANTIME   100

Definition at line 269 of file app_rpt.c.

Referenced by function_remote().

#define RETRY_TIMER_MS   5000

Definition at line 209 of file app_rpt.c.

Referenced by rpt().

#define RPT_LOCKOUT_SECS   10

Definition at line 219 of file app_rpt.c.

Referenced by rpt(), and rpt_exec().

#define rpt_mutex_lock (  )     ast_mutex_lock(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 rpt_mutex_unlock (  )     ast_mutex_unlock(x)

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

Referenced by load_rpt_vars().

#define SIMPLEX_PHONE_DELAY   25

Definition at line 283 of file app_rpt.c.

Referenced by load_rpt_vars().

#define START_DELAY   2

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

Referenced by load_rpt_vars().

#define TELEMETRY   "telemetry"

Definition at line 240 of file app_rpt.c.

Referenced by telem_lookup().

#define TELEPARAMSIZE   256

Definition at line 267 of file app_rpt.c.

Referenced by rpt_telemetry().

#define TONEMACRO   "tonemacro"

Definition at line 242 of file app_rpt.c.

Referenced by load_rpt_vars().

#define TOPKEYMAXSTR   30

Definition at line 193 of file app_rpt.c.

Referenced by handle_link_data().

#define TOPKEYN   32

Definition at line 191 of file app_rpt.c.

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

#define TOPKEYWAIT   3

Definition at line 192 of file app_rpt.c.

Referenced by rpt().

#define TOTIME   180000

Definition at line 481 of file app_rpt.c.

Referenced by load_rpt_vars().

#define VOX_MAX_THRESHOLD   10000.0

Definition at line 278 of file app_rpt.c.

Referenced by dovox().

#define VOX_MIN_THRESHOLD   3000.0

Definition at line 279 of file app_rpt.c.

Referenced by dovox().

#define VOX_OFF_DEBOUNCE_COUNT   20

Definition at line 277 of file app_rpt.c.

Referenced by voxinit_link(), and voxinit_rpt().

#define VOX_ON_DEBOUNCE_COUNT   3

Definition at line 276 of file app_rpt.c.

Referenced by voxinit_link(), and voxinit_rpt().

#define VOX_RECOVER_MS   500

Definition at line 281 of file app_rpt.c.

Referenced by load_rpt_vars().

#define VOX_TIMEOUT_MS   5000

Definition at line 280 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 289 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 291 of file app_rpt.c.

anonymous enum

Enumerator:
REM_SIMPLEX 
REM_MINUS 
REM_PLUS 

Definition at line 301 of file app_rpt.c.

anonymous enum

Enumerator:
REM_LOWPWR 
REM_MEDPWR 
REM_HIPWR 

Definition at line 303 of file app_rpt.c.

anonymous enum

Enumerator:
DC_INDETERMINATE 
DC_REQ_FLUSH 
DC_ERROR 
DC_COMPLETE 
DC_COMPLETEQUIET 
DC_DOKEY 

Definition at line 305 of file app_rpt.c.

anonymous enum

Enumerator:
SOURCE_RPT 
SOURCE_LNK 
SOURCE_RMT 
SOURCE_PHONE 
SOURCE_DPHONE 
SOURCE_ALT 

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

anonymous enum

Enumerator:
REM_MODE_FM 
REM_MODE_USB 
REM_MODE_LSB 
REM_MODE_AM 

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

anonymous enum

Enumerator:
TOP_TOP 
TOP_WON 
WON_BEFREAD 
BEFREAD_AFTERREAD 

Definition at line 445 of file app_rpt.c.


Function Documentation

static void __kickshort ( struct rpt myrpt  )  [static]

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

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

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

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

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

static void __reg_module ( void   )  [static]

Definition at line 15231 of file app_rpt.c.

static void __unreg_module ( void   )  [static]

Definition at line 15231 of file app_rpt.c.

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

Definition at line 315 of file indications.c.

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

00316 {
00317    char *s, *data = ast_strdupa(playlst);
00318    struct playtones_def d = { vol, -1, 0, 1, NULL };
00319    char *stringp;
00320    char *separator;
00321    static const float sample_rate = 8000.0;
00322    static const float max_sample_val = 32768.0;
00323 
00324    if (vol < 1) {
00325       d.vol = 7219; /* Default to -8db */
00326    }
00327 
00328    d.interruptible = interruptible;
00329 
00330    stringp = data;
00331 
00332    /* check if the data is separated with '|' or with ',' by default */
00333    if (strchr(stringp,'|')) {
00334       separator = "|";
00335    } else {
00336       separator = ",";
00337    }
00338 
00339    while ((s = strsep(&stringp, separator)) && !ast_strlen_zero(s)) {
00340       struct ast_tone_zone_part tone_data = {
00341          .time = 0,
00342       };
00343 
00344       s = ast_strip(s);
00345 
00346       if (s[0]=='!') {
00347          s++;
00348       } else if (d.reppos == -1) {
00349          d.reppos = d.nitems;
00350       }
00351 
00352       if (ast_tone_zone_part_parse(s, &tone_data)) {
00353          ast_log(LOG_ERROR, "Failed to parse tone part '%s'\n", s);
00354          continue;
00355       }
00356 
00357       if (tone_data.midinote) {
00358          /* midi notes must be between 0 and 127 */
00359 
00360          if (tone_data.freq1 >= 0 && tone_data.freq1 <= 127) {
00361             tone_data.freq1 = midi_tohz[tone_data.freq1];
00362          } else {
00363             tone_data.freq1 = 0;
00364          }
00365 
00366          if (tone_data.freq2 >= 0 && tone_data.freq2 <= 127) {
00367             tone_data.freq2 = midi_tohz[tone_data.freq2];
00368          } else {
00369             tone_data.freq2 = 0;
00370          }
00371       }
00372 
00373       if (!(d.items = ast_realloc(d.items, (d.nitems + 1) * sizeof(*d.items)))) {
00374          return -1;
00375       }
00376 
00377       d.items[d.nitems].fac1 = 2.0 * cos(2.0 * M_PI * (tone_data.freq1 / sample_rate)) * max_sample_val;
00378       d.items[d.nitems].init_v2_1 = sin(-4.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol;
00379       d.items[d.nitems].init_v3_1 = sin(-2.0 * M_PI * (tone_data.freq1 / sample_rate)) * d.vol;
00380 
00381       d.items[d.nitems].fac2 = 2.0 * cos(2.0 * M_PI * (tone_data.freq2 / sample_rate)) * max_sample_val;
00382       d.items[d.nitems].init_v2_2 = sin(-4.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol;
00383       d.items[d.nitems].init_v3_2 = sin(-2.0 * M_PI * (tone_data.freq2 / sample_rate)) * d.vol;
00384 
00385       d.items[d.nitems].duration = tone_data.time;
00386       d.items[d.nitems].modulate = tone_data.modulate;
00387 
00388       d.nitems++;
00389    }
00390 
00391    if (!d.nitems) {
00392       ast_log(LOG_ERROR, "No valid tone parts\n");
00393       return -1;
00394    }
00395 
00396    if (ast_activate_generator(chan, &playtones, &d)) {
00397       ast_free(d.items);
00398       return -1;
00399    }
00400 
00401    return 0;
00402 }

void ast_playtones_stop ( struct ast_channel chan  ) 

Stop the tones from playing

Definition at line 404 of file indications.c.

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

00405 {
00406    ast_deactivate_generator(chan);
00407 }

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

Definition at line 10344 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, send_newkey(), strsep(), and VERBOSE_PREFIX_3.

Referenced by rpt().

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

static void birdbath ( struct rpt myrpt  )  [static]

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

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

static int channel_revert ( struct rpt myrpt  )  [static]

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

09627 {
09628    int res=0;
09629    if(debug)ast_log(LOG_NOTICE,"remoterig=%s, nowchan=%02d, waschan=%02d\n",myrpt->remoterig,myrpt->nowchan,myrpt->waschan);
09630    if (!myrpt->remoterig) return(0);
09631    if(myrpt->nowchan!=myrpt->waschan)
09632    {
09633       char data[8];
09634         if(debug)ast_log(LOG_NOTICE,"reverting.\n");
09635       sprintf(data,"%02d",myrpt->waschan);
09636       myrpt->nowchan=myrpt->waschan;
09637       channel_steer(myrpt,data);
09638       res=1;
09639    }
09640    return(res);
09641 }

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

Definition at line 9597 of file app_rpt.c.

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

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

09598 {
09599    int res=0;
09600 
09601    if(debug)ast_log(LOG_NOTICE,"remoterig=%s, data=%s\n",myrpt->remoterig,data);
09602    if (!myrpt->remoterig) return(0);
09603    if(data<=0)
09604    {
09605       res=-1;
09606    }
09607    else
09608    {
09609       myrpt->nowchan=strtod(data,NULL);
09610       if(!strcmp(myrpt->remoterig, remote_rig_ppp16))
09611       {
09612          char string[16];
09613          sprintf(string,"SETCHAN %d ",myrpt->nowchan);
09614          send_usb_txt(myrpt,string);   
09615       }
09616       else
09617       {
09618          if(get_mem_set(myrpt, data))res=-1;
09619       }
09620    }
09621    if(debug)ast_log(LOG_NOTICE,"nowchan=%i  res=%i\n",myrpt->nowchan, res);
09622    return res;
09623 }

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

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

09322 {
09323    if(!strcmp(myrpt->remoterig, remote_rig_ft897))
09324       return check_freq_ft897(m, d, defmode);
09325    else if(!strcmp(myrpt->remoterig, remote_rig_ic706))
09326       return check_freq_ic706(m, d, defmode,myrpt->p.remote_mars);
09327    else if(!strcmp(myrpt->remoterig, remote_rig_rbi))
09328       return check_freq_rbi(m, d, defmode);
09329    else if(!strcmp(myrpt->remoterig, remote_rig_kenwood))
09330       return check_freq_kenwood(m, d, defmode);
09331    else if(!strcmp(myrpt->remoterig, remote_rig_tm271))
09332       return check_freq_tm271(m, d, defmode);
09333    else if(ISRIG_RTX(myrpt->remoterig))
09334       return check_freq_rtx(m, d, defmode, myrpt);
09335    else
09336       return -1;
09337 }

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

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

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

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

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

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

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

Definition at line 8088 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

08089 {
08090    int dflmd = REM_MODE_FM;
08091 
08092    if (m == 144){ /* 2 meters */
08093       if(d < 10100)
08094          return -1;
08095    }
08096    else if((m >= 145) && (m < 148)){
08097       ;
08098    }
08099    else if((m >= 430) && (m < 450)){ /* 70 centimeters */
08100       ;
08101    }
08102    else
08103       return -1;
08104    
08105    if(defmode)
08106       *defmode = dflmd; 
08107 
08108 
08109    return 0;
08110 }

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

Definition at line 8137 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

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

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

Definition at line 8177 of file app_rpt.c.

References REM_MODE_FM, and rpt::remoterig.

Referenced by check_freq().

08178 {
08179    int dflmd = REM_MODE_FM;
08180 
08181    if (!strcmp(myrpt->remoterig,remote_rig_rtx150))
08182    {
08183 
08184       if(m == 144){ /* 2 meters */
08185          if(d < 10100)
08186             return -1;
08187       }
08188       else if((m >= 145) && (m < 148)){
08189          ;
08190       }
08191       else
08192          return -1;
08193    }
08194    else 
08195    {
08196       if((m >= 430) && (m < 450)){ /* 70 centimeters */
08197          ;
08198       }
08199       else
08200          return -1;
08201    }
08202    if(defmode)
08203       *defmode = dflmd; 
08204 
08205 
08206    return 0;
08207 }

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

Definition at line 8113 of file app_rpt.c.

References REM_MODE_FM.

Referenced by check_freq().

08114 {
08115    int dflmd = REM_MODE_FM;
08116 
08117    if (m == 144){ /* 2 meters */
08118       if(d < 10100)
08119          return -1;
08120    }
08121    else if((m >= 145) && (m < 148)){
08122       ;
08123    }
08124       return -1;
08125    
08126    if(defmode)
08127       *defmode = dflmd; 
08128 
08129 
08130    return 0;
08131 }

static char check_tx_freq ( struct rpt myrpt  )  [static]

Definition at line 9344 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, split_freq(), rpt::txlimitsstanzaname, and ast_variable::value.

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

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

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

07514 {
07515 unsigned char rxbuf[100];
07516 int   i,rv ;
07517 
07518    rv = serial_remote_io(myrpt,cmd,cmdlen,rxbuf,cmdlen + 6,0);
07519    if (rv == -1) return(-1);
07520    if (rv != (cmdlen + 6)) return(1);
07521    for(i = 0; i < 6; i++)
07522       if (rxbuf[i] != cmd[i]) return(1);
07523    if (rxbuf[cmdlen] != 0xfe) return(1);
07524    if (rxbuf[cmdlen + 1] != 0xfe) return(1);
07525    if (rxbuf[cmdlen + 4] != 0xfb) return(1);
07526    if (rxbuf[cmdlen + 5] != 0xfd) return(1);
07527    return(0);
07528 }

static int closerem ( struct rpt myrpt  )  [static]

Definition at line 9309 of file app_rpt.c.

References closerem_ft897(), and rpt::remoterig.

09310 {
09311    if(!strcmp(myrpt->remoterig, remote_rig_ft897))
09312       return closerem_ft897(myrpt);
09313    else
09314       return 0;
09315 }

static int closerem_ft897 ( struct rpt myrpt  )  [static]

Definition at line 8593 of file app_rpt.c.

References simple_command_ft897().

Referenced by closerem().

08594 {
08595    simple_command_ft897(myrpt, 0x88); /* PTT off */
08596    return 0;
08597 }  

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

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

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

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

Definition at line 5687 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, send_newkey(), strsep(), and voxinit_link().

Referenced by function_ilink().

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

static int decimals2int ( char *  fraction  )  [static]

Definition at line 8213 of file app_rpt.c.

Referenced by check_tx_freq().

08214 {
08215    int i;
08216    char len = strlen(fraction);
08217    int multiplier = 100000;
08218    int res = 0;
08219 
08220    if(!len)
08221       return 0;
08222    for( i = 0 ; i < len ; i++, multiplier /= 10)
08223       res += (fraction[i] - '0') * multiplier;
08224    return res;
08225 }

static long diskavail ( struct rpt myrpt  )  [static]

Definition at line 1335 of file app_rpt.c.

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

Referenced by rpt().

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

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

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

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

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

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

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

static void do_scheduler ( struct rpt myrpt  )  [static]

Definition at line 10614 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, ast_variable::value, and value.

Referenced by rpt().

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

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

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

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

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

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

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

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

Definition at line 1809 of file app_rpt.c.

Referenced by check_tx_freq().

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

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

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

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

static void flush_telem ( struct rpt myrpt  )  [static]

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

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

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

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

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

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

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

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

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

Definition at line 6152 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(), rpt::sysstate_cur, and value.

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

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

Definition at line 6378 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, string, rpt::sysstate_cur, TEST_TONE, rpt::topkeylong, sysstate::totdisable, sysstate::txdisable, and sysstate::userfundisable.

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

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

Definition at line 5881 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, ast_frame_subclass::integer, 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, ast_frame::samples, rpt::savednodes, SOURCE_ALT, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, SOURCE_RPT, STATUS, strsep(), ast_frame::subclass, and rpt::sysstate_cur.

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

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

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

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

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

Definition at line 6358 of file app_rpt.c.

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

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

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

Definition at line 9646 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, rpt::scantimer, setrem(), SOURCE_LNK, SOURCE_RPT, split_freq(), strsep(), TUNE, rpt::tunerequest, rpt::txchannel, rpt::txpl, and rpt::txplon.

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

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

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

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

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

Definition at line 9584 of file app_rpt.c.

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

Referenced by channel_steer(), and function_remote().

09585 {
09586    int res=0;
09587    if(debug)ast_log(LOG_NOTICE," digitbuf=%s\n", digitbuf);
09588    res = retreive_memory(myrpt, digitbuf);
09589    if(!res)res=setrem(myrpt); 
09590    if(debug)ast_log(LOG_NOTICE," freq=%s  res=%i\n", myrpt->freq, res);
09591    return res;
09592 }

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

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

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

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

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

03446 {
03447         switch (cmd) {
03448         case CLI_INIT:
03449                 e->command = "rpt cmd";
03450                 e->usage = cmd_usage;
03451                 return NULL;
03452         case CLI_GENERATE:
03453                 return NULL;
03454    }
03455    return res2cli(rpt_do_cmd(a->fd,a->argc,a->argv));
03456 }

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

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

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

static char* handle_cli_dump ( 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_dump(), and ast_cli_entry::usage.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 6685 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, ast_frame_subclass::integer, 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().

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

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

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

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

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

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

10244 {
10245 /* XXX ATTENTION: if you change the size of these arrays you MUST
10246  * change the limits in corresponding sscanf() calls below. */
10247 char  tmp[300],cmd[300],dest[300],src[300],c;
10248 int   seq,res;
10249 
10250    /* put string in our buffer */
10251    strncpy(tmp,str,sizeof(tmp) - 1);
10252    if (!strcmp(tmp,discstr)) return 0;
10253         if (!strcmp(tmp,newkeystr))
10254         {
10255       myrpt->newkey = 1;
10256                 return 0;
10257         }
10258 
10259 #ifndef  DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES
10260    if (tmp[0] == 'I')
10261    {
10262       /* XXX WARNING: be very careful with the limits on the folowing
10263        * sscanf() call, make sure they match the values defined above */
10264       if (sscanf(tmp,"%299s %299s %30x",cmd,src,&seq) != 3)
10265       {
10266          ast_log(LOG_WARNING, "Unable to parse ident string %s\n",str);
10267          return 0;
10268       }
10269       mdc1200_notify(myrpt,src,seq);
10270       return 0;
10271    }
10272 #endif
10273    /* XXX WARNING: be very careful with the limits on the folowing
10274     * sscanf() call, make sure they match the values defined above */
10275    if (sscanf(tmp,"%299s %299s %299s %30d %1c",cmd,dest,src,&seq,&c) != 5)
10276    {
10277       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
10278       return 0;
10279    }
10280    if (strcmp(cmd,"D"))
10281    {
10282       ast_log(LOG_WARNING, "Unable to parse link string %s\n",str);
10283       return 0;
10284    }
10285    /* if not for me, ignore */
10286    if (strcmp(dest,myrpt->name)) return 0;
10287    if (myrpt->p.archivedir)
10288    {
10289       char dtmfstr[100];
10290 
10291       sprintf(dtmfstr,"DTMF,%c",c);
10292       donodelog(myrpt,dtmfstr);
10293    }
10294    c = func_xlat(myrpt,c,&myrpt->p.outxlat);
10295    if (!c) return(0);
10296    res = handle_remote_dtmf_digit(myrpt,c, NULL, 0);
10297    if (res != 1)
10298       return res;
10299    rpt_telemetry(myrpt,COMPLETE,NULL);
10300    return 0;
10301 }

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

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

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

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

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

10304 {
10305 int   res;
10306 
10307 
10308    if(phonemode == 3) /* simplex phonemode, funcchar key/unkey toggle */
10309    {
10310       if (keyed && *keyed && ((c == myrpt->p.funcchar) || (c == myrpt->p.endchar)))
10311       {
10312          *keyed = 0; /* UNKEY */
10313          return 0;
10314       }
10315       else if (keyed && !*keyed && (c = myrpt->p.funcchar))
10316       {
10317          *keyed = 1; /* KEY */
10318          return 0;
10319       }
10320    }
10321    else /* endchar unkey */
10322    {
10323 
10324       if (keyed && *keyed && (c == myrpt->p.endchar))
10325       {
10326          *keyed = 0;
10327          return DC_INDETERMINATE;
10328       }
10329    }
10330    if (myrpt->p.archivedir)
10331    {
10332       char str[100];
10333 
10334       sprintf(str,"DTMF(P),%c",c);
10335       donodelog(myrpt,str);
10336    }
10337    res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode);
10338    if (res != 1)
10339       return res;
10340    rpt_telemetry(myrpt,COMPLETE,NULL);
10341    return 0;
10342 }

static int ic706_pltocode ( char *  str  )  [static]

Definition at line 8763 of file app_rpt.c.

References ast_log(), and LOG_NOTICE.

Referenced by set_ic706().

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

static int kenwood_pltocode ( char *  str  )  [static]

Definition at line 7547 of file app_rpt.c.

Referenced by set_tm271(), and setkenwood().

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

static int linkcount ( struct rpt myrpt  )  [static]

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

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

static int load_module ( void   )  [static]

Definition at line 15162 of file app_rpt.c.

References ARRAY_LEN, 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().

15164 {
15165    int res;
15166    ast_pthread_create(&rpt_master_thread,NULL,rpt_master,NULL);
15167 
15168 #ifdef   NEW_ASTERISK
15169    ast_cli_register_multiple(rpt_cli, ARRAY_LEN(rpt_cli));
15170    res = 0;
15171 #else
15172    /* Register cli extensions */
15173    ast_cli_register(&cli_debug);
15174    ast_cli_register(&cli_dump);
15175    ast_cli_register(&cli_stats);
15176    ast_cli_register(&cli_lstats);
15177    ast_cli_register(&cli_nodes);
15178    ast_cli_register(&cli_local_nodes);
15179    ast_cli_register(&cli_reload);
15180    ast_cli_register(&cli_restart);
15181    ast_cli_register(&cli_fun);
15182    ast_cli_register(&cli_fun1);
15183    res = ast_cli_register(&cli_cmd);
15184 #endif
15185 #ifndef OLD_ASTERISK
15186    res |= ast_manager_register("RptLocalNodes", 0, manager_rpt_local_nodes, "List local node numbers");
15187    res |= ast_manager_register("RptStatus", 0, manager_rpt_status, "Return Rpt Status for CGI");
15188 
15189 #endif
15190    res |= ast_register_application(app, rpt_exec, synopsis, descrip);
15191    return res;
15192 }

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

Definition at line 2234 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, CONFIG_STATUS_FILEINVALID, 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().

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

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

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

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

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

Definition at line 14637 of file app_rpt.c.

References astman_append(), name, and RESULT_SUCCESS.

Referenced by load_module().

14638 {
14639     int i;
14640     astman_append(s, "<?xml version=\"1.0\"?>\r\n");
14641     astman_append(s, "<nodes>\r\n");
14642     for (i=0; i< nrpts; i++)
14643     {
14644         astman_append(s, "  <node>%s</node>\r\n", rpt_vars[i].name);        
14645     } /* for i */
14646     astman_append(s, "</nodes>\r\n");
14647     astman_append(s, "\r\n"); /* Properly terminate Manager output */
14648     return RESULT_SUCCESS;
14649 } /* manager_rpt_local_nodes() */

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

Definition at line 15014 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(), and rpt_manager_success().

Referenced by load_module().

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

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

Definition at line 2065 of file app_rpt.c.

Referenced by function_autopatchup().

02066 {
02067 int   i,ls;
02068    for( i = 0 ; keywords[i] ; i++){
02069       ls = strlen(keywords[i]);
02070       if(!ls){
02071          *param = NULL;
02072          return 0;
02073       }
02074       if(!strncmp(string, keywords[i], ls)){
02075          if(param)
02076             *param = string + ls;
02077          return i + 1; 
02078       }
02079    }
02080    *param = NULL;
02081    return 0;
02082 }

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

Definition at line 1713 of file app_rpt.c.

References ast_verbose, and rpt::name.

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

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

static int mem2vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 9093 of file app_rpt.c.

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

Referenced by set_ic706().

09094 {
09095    unsigned char cmdstr[10];
09096    
09097    cmdstr[0] = cmdstr[1] = 0xfe;
09098    cmdstr[2] = myrpt->p.civaddr;
09099    cmdstr[3] = 0xe0;
09100    cmdstr[4] = 0x0a;
09101    cmdstr[5] = 0xfd;
09102 
09103    return(civ_cmd(myrpt,cmdstr,6));
09104 }

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

Definition at line 9492 of file app_rpt.c.

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

Referenced by function_remote(), and service_scan().

09493 {
09494    if(!strcmp(myrpt->remoterig, remote_rig_ft897))
09495       return multimode_bump_freq_ft897(myrpt, interval);
09496    else if(!strcmp(myrpt->remoterig, remote_rig_ic706))
09497       return multimode_bump_freq_ic706(myrpt, interval);
09498    else
09499       return -1;
09500 }

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

Definition at line 8605 of file app_rpt.c.

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

Referenced by multimode_bump_freq().

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

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

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

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

static int multimode_capable ( struct rpt myrpt  )  [static]

Definition at line 1078 of file app_rpt.c.

References rpt::remoterig.

Referenced by function_remote(), and rpt_tele_thread().

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

static int myatoi ( const char *  str  )  [static]

Definition at line 2105 of file app_rpt.c.

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

02106 {
02107    int   ret;
02108 
02109    if (!str) {
02110       return -1;
02111    }
02112 
02113    /* leave this %i alone, non-base-10 input is useful here */
02114    if (sscanf(str, "%30i", &ret) != 1) {
02115       return -1;
02116    }
02117 
02118    return ret;
02119 }

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

Definition at line 2121 of file app_rpt.c.

Referenced by rpt_do_nodes(), and rpt_tele_thread().

02122 {
02123 char  **x = (char **) a;
02124 char  **y = (char **) b;
02125 int   xoff,yoff;
02126 
02127    if ((**x < '0') || (**x > '9')) xoff = 1; else xoff = 0;
02128    if ((**y < '0') || (**y > '9')) yoff = 1; else yoff = 0;
02129    return(strcmp((*x) + xoff,(*y) + yoff));
02130 }

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

Definition at line 1993 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, CONFIG_STATUS_FILEINVALID, rpt::extnodefile, rpt::extnodes, last, rpt::longestnode, ast_variable::name, ast_variable::next, nodelookuplock, rpt::nodes, and rpt::p.

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

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

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

Definition at line 1675 of file app_rpt.c.

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

Referenced by rpt().

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

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

Definition at line 3282 of file app_rpt.c.

References play_tone_pair().

Referenced by send_morse().

03283 {
03284    return play_tone_pair(chan, 0, 0, duration, 0);
03285 }

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

Definition at line 3277 of file app_rpt.c.

References play_tone_pair().

Referenced by rpt_tele_thread(), and send_morse().

03278 {
03279    return play_tone_pair(chan, freq, 0, duration, amplitude);
03280 }

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

Definition at line 3263 of file app_rpt.c.

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

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

03264 {
03265    int res;
03266 
03267         if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude)))
03268                 return res;
03269                                                                                                                                             
03270         while(chan->generatordata) {
03271       if (ast_safe_sleep(chan,1)) return -1;
03272    }
03273 
03274         return 0;
03275 }

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

Definition at line 1366 of file app_rpt.c.

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

Referenced by rpt_exec().

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

static void queue_id ( struct rpt myrpt  )  [static]

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

10601 {
10602    if(myrpt->p.idtime){ /* ID time must be non-zero */
10603       myrpt->mustid = myrpt->tailid = 0;
10604       myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */
10605       rpt_mutex_unlock(&myrpt->lock);
10606       rpt_telemetry(myrpt,ID,NULL);
10607       rpt_mutex_lock(&myrpt->lock);
10608    }
10609 }

static int rbi_mhztoband ( char *  str  )  [static]

Definition at line 7236 of file app_rpt.c.

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

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

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

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

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

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

Definition at line 7367 of file app_rpt.c.

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

Referenced by rbi_out().

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

static int rbi_pltocode ( char *  str  )  [static]

Definition at line 7272 of file app_rpt.c.

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

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

static int reload ( void   )  [static]

Definition at line 15215 of file app_rpt.c.

References reload.

15217 {
15218 int   n;
15219 
15220    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
15221    return(0);
15222 }

static char* res2cli ( int  r  )  [static]

Definition at line 3289 of file app_rpt.c.

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

Referenced by handle_cli_cmd(), handle_cli_debug(), handle_cli_dump(), handle_cli_fun(), handle_cli_fun1(), handle_cli_local_nodes(), handle_cli_lstats(), handle_cli_nodes(), handle_cli_reload(), handle_cli_restart(), handle_cli_stats(), handle_console_key(), handle_console_unkey(), handle_radio_active(), handle_radio_debug(), handle_radio_debug_off(), handle_radio_tune(), and handle_set_xdebug().

03291 {
03292    switch (r)
03293    {
03294        case RESULT_SUCCESS:
03295       return(CLI_SUCCESS);
03296        case RESULT_SHOWUSAGE:
03297       return(CLI_SHOWUSAGE);
03298        default:
03299       return(CLI_FAILURE);
03300    }
03301 }

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

Definition at line 1413 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, rpt::txpl, and rpt::txplon.

Referenced by function_cop(), get_mem_set(), and rpt_master().

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

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

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

02208 {
02209         char *var;
02210         int ret;
02211    char include_zero = 0;
02212 
02213    if(min < 0){ /* If min is negative, this means include 0 as a valid entry */
02214       min = -min;
02215       include_zero = 1;
02216    }           
02217                                                                      
02218         var = (char *) ast_variable_retrieve(myrpt->cfg, category, name);
02219         if(var){
02220                 ret = myatoi(var);
02221       if(include_zero && !ret)
02222          return 0;
02223                 if(ret < min)
02224                         ret = min;
02225                 if(ret > max)
02226                         ret = max;
02227         }
02228         else
02229                 ret = defl;
02230         return ret;
02231 }

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

Definition at line 10739 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, 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, 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, value, 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.

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

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

Definition at line 5289 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, ast_channel::caller, rpt::callmode, ast_channel::cdr, channel_revert(), rpt::cidx, rpt::conf, ast_channel::context, rpt::duplex, rpt::exten, ast_channel::exten, ast_channel::fds, ast_party_caller::id, ast_frame_subclass::integer, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macropatch, MSWAIT, rpt::mydtmf, ast_party_id::name, name, ast_party_id::number, 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_party_name::str, ast_party_number::str, ast_frame::subclass, TERM, rpt::tonezone, ast_party_name::valid, ast_party_number::valid, and rpt::voxchannel.

Referenced by function_autopatchup(), and local_dtmf_helper().

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

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

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

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

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

Definition at line 2631 of file app_rpt.c.

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

Referenced by handle_cli_debug().

02632 {
02633    int newlevel;
02634 
02635    if (argc != 4) {
02636       return RESULT_SHOWUSAGE;
02637    }
02638 
02639    newlevel = myatoi(argv[3]);
02640 
02641    if (newlevel < 0 || newlevel > 7) {
02642       return RESULT_SHOWUSAGE;
02643    }
02644 
02645    if (newlevel) {
02646       ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel);
02647    } else {
02648       ast_cli(fd, "app_rpt Debugging disabled\n");
02649    }
02650 
02651    debug = newlevel;
02652 
02653    return RESULT_SUCCESS;
02654 }

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

Definition at line 2660 of file app_rpt.c.

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

Referenced by handle_cli_dump().

02661 {
02662    int i;
02663 
02664         if (argc != 3)
02665                 return RESULT_SHOWUSAGE;
02666 
02667    for(i = 0; i < nrpts; i++)
02668    {
02669       if (!strcmp(argv[2],rpt_vars[i].name))
02670       {
02671          rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */
02672               ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]);
02673               return RESULT_SUCCESS;
02674       }
02675    }
02676    return RESULT_FAILURE;
02677 }

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

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

03120 {
03121    int   i,busy=0;
03122 
03123         if (argc != 4) return RESULT_SHOWUSAGE;
03124 
03125    for(i = 0; i < nrpts; i++){
03126       if(!strcmp(argv[2], rpt_vars[i].name)){
03127          struct rpt *myrpt = &rpt_vars[i];
03128          rpt_mutex_lock(&myrpt->lock);
03129          if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(argv[3])){
03130             rpt_mutex_unlock(&myrpt->lock);
03131             busy=1;
03132          }
03133          if(!busy){
03134             myrpt->macrotimer = MACROTIME;
03135             strncat(myrpt->macrobuf,argv[3],MAXMACRO - 1);
03136          }
03137          rpt_mutex_unlock(&myrpt->lock);
03138       }
03139    }
03140    if(busy){
03141       ast_cli(fd, "Function decoder busy");
03142    }
03143    return RESULT_FAILURE;
03144 }

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

Definition at line 3179 of file app_rpt.c.

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

Referenced by handle_cli_fun1().

03180 {
03181    int   i;
03182 
03183     if (argc != 4) return RESULT_SHOWUSAGE;
03184 
03185    for(i = 0; i < nrpts; i++){
03186       if(!strcmp(argv[2], rpt_vars[i].name)){
03187          struct rpt *myrpt = &rpt_vars[i];
03188          rpt_push_alt_macro(myrpt, (char *) argv[3]);
03189       }
03190    }
03191    return RESULT_FAILURE;
03192 }

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

Definition at line 3069 of file app_rpt.c.

References ast_cli(), name, and RESULT_SUCCESS.

Referenced by handle_cli_local_nodes().

03070 {
03071 
03072     int i;
03073     ast_cli(fd, "\nNode\n----\n");
03074     for (i=0; i< nrpts; i++)
03075     {
03076         ast_cli(fd, "%s\n", rpt_vars[i].name);        
03077     } /* for i */
03078     ast_cli(fd,"\n");
03079     return RESULT_SUCCESS;
03080 } 

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

Definition at line 2929 of file app_rpt.c.

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

Referenced by handle_cli_lstats().

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

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

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

03020 {
03021    int i,j;
03022    char ns;
03023    char lbuf[MAXLINKLIST],*strs[MAXLINKLIST];
03024    struct rpt *myrpt;
03025    if(argc != 3)
03026       return RESULT_SHOWUSAGE;
03027 
03028    for(i = 0; i < nrpts; i++)
03029    {
03030       if (!strcmp(argv[2],rpt_vars[i].name)){
03031          /* Make a copy of all stat variables while locked */
03032          myrpt = &rpt_vars[i];
03033          rpt_mutex_lock(&myrpt->lock); /* LOCK */
03034          __mklinklist(myrpt,NULL,lbuf);
03035          rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */
03036          /* parse em */
03037          ns = finddelim(lbuf,strs,MAXLINKLIST);
03038          /* sort em */
03039          if (ns) qsort((void *)strs,ns,sizeof(char *),mycompar);
03040          ast_cli(fd,"\n");
03041          ast_cli(fd, "************************* CONNECTED NODES *************************\n\n");
03042          for(j = 0 ;; j++){
03043             if(!strs[j]){
03044                if(!j){
03045                   ast_cli(fd,"<NONE>");
03046                }
03047                break;
03048             }
03049             ast_cli(fd, "%s", strs[j]);
03050             if(j % 8 == 7){
03051                ast_cli(fd, "\n");
03052             }
03053             else{
03054                if(strs[j + 1])
03055                   ast_cli(fd, ", ");
03056             }
03057          }
03058          ast_cli(fd,"\n\n");
03059          return RESULT_SUCCESS;
03060       }
03061    }
03062    return RESULT_FAILURE;
03063 }

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

Definition at line 3087 of file app_rpt.c.

References reload, RESULT_FAILURE, and RESULT_SHOWUSAGE.

Referenced by handle_cli_reload().

03088 {
03089 int   n;
03090 
03091         if (argc > 2) return RESULT_SHOWUSAGE;
03092 
03093    for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1;
03094 
03095    return RESULT_FAILURE;
03096 }

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

Definition at line 3102 of file app_rpt.c.

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

Referenced by handle_cli_restart().

03103 {
03104 int   i;
03105 
03106         if (argc > 2) return RESULT_SHOWUSAGE;
03107    for(i = 0; i < nrpts; i++)
03108    {
03109       if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV);
03110    }
03111    return RESULT_FAILURE;
03112 }

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

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

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

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

Definition at line 13131 of file app_rpt.c.

References __kickshort(), ast_channel::_state, ahp, rpt::archivedir, ast_answer(), 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_strdupa, ast_strlen_zero(), ast_verbose, rpt::bargechan, buf2, ast_channel::caller, rpt::callmode, ast_channel::cdr, rpt_tele::chan, channel_revert(), channel_steer(), rpt::conf, ast_channel::connected, ast_channel::context, context, rpt_link::disced, donodelog(), rpt::duplex, ast_channel::exten, exten, f, hp, ast_party_caller::id, 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, ast_party_id::number, 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, rpt::s, S_COR, send_newkey(), START_DELAY, ast_party_number::str, strsep(), rpt::sysstate_cur, rpt::txkeyed, ast_party_number::valid, VERBOSE_PREFIX_3, voxinit_link(), rpt::waschan, and rpt::xlink.

Referenced by load_module().

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

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

Definition at line 2184 of file app_rpt.c.

References ast_localtime().

Referenced by do_scheduler(), and rpt_tele_thread().

02185 {
02186    struct timeval when;
02187 
02188    when.tv_sec = *t;
02189    when.tv_usec = 0;
02190    ast_localtime(&when, lt, NULL);
02191 }

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

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

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

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

Definition at line 14657 of file app_rpt.c.

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

Referenced by manager_rpt_status(), and rpt_manager_do_stats().

14658 {
14659    const char *id = astman_get_header(m, "ActionID");
14660    if (!ast_strlen_zero(id))
14661       astman_append(s, "ActionID: %s\r\n", id);
14662    astman_append(s, "Response: Success\r\n");
14663 }

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

Definition at line 12928 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, CONFIG_STATUS_FILEINVALID, 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().

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

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

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

03154 {
03155    int   busy=0;
03156 
03157    rpt_mutex_lock(&myrpt->lock);
03158    if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(sptr)){
03159       rpt_mutex_unlock(&myrpt->lock);
03160       busy=1;
03161    }
03162    if(!busy){
03163       int x;
03164       if (debug)ast_log(LOG_NOTICE, "rpt_push_alt_macro %s\n",sptr);
03165       myrpt->macrotimer = MACROTIME;
03166       for(x = 0; *(sptr + x); x++)
03167           myrpt->macrobuf[x] = *(sptr + x) | 0x80;
03168       *(sptr + x) = 0;
03169    }
03170    rpt_mutex_unlock(&myrpt->lock);
03171 
03172    if(busy)ast_log(LOG_WARNING, "Function decoder busy on app_rpt command macro.\n");
03173 
03174    return busy;
03175 }

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

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

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

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

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

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

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

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

03706 {
03707 int   res;
03708 
03709    res = ast_say_character_str(mychannel,str,NULL,mychannel->language);
03710    if (!res) 
03711       res = ast_waitstream(mychannel, "");
03712    else
03713        ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03714    ast_stopstream(mychannel);
03715    return res;
03716 }

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

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

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

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

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

03734 {
03735 int   res;
03736 char  *val,fname[300];
03737 
03738    val = (char *) ast_variable_retrieve(myrpt->cfg, myrpt->name, "nodenames");
03739    if (!val) val = NODENAMES;
03740    snprintf(fname,sizeof(fname) - 1,"%s/%s",val,name);
03741    if (ast_fileexists(fname,NULL,mychannel->language) > 0)
03742       return(sayfile(mychannel,fname));
03743    res = sayfile(mychannel,"rpt/node");
03744    if (!res) 
03745       res = ast_say_character_str(mychannel,name,NULL,mychannel->language);
03746    return res;
03747 }

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

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

03719 {
03720    int res;
03721    res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL);
03722    if(!res)
03723       res = ast_waitstream(mychannel, "");
03724    else
03725       ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name);
03726    ast_stopstream(mychannel);
03727    return res;
03728 }

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

Definition at line 9106 of file app_rpt.c.

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

Referenced by set_ic706().

09107 {
09108    unsigned char cmdstr[10];
09109    
09110    cmdstr[0] = cmdstr[1] = 0xfe;
09111    cmdstr[2] = myrpt->p.civaddr;
09112    cmdstr[3] = 0xe0;
09113    cmdstr[4] = 8;
09114    cmdstr[5] = 0;
09115    cmdstr[6] = ((slot / 10) << 4) + (slot % 10);
09116    cmdstr[7] = 0xfd;
09117 
09118    return(civ_cmd(myrpt,cmdstr,8));
09119 }

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

Definition at line 5594 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, ast_frame_subclass::integer, 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().

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

static void send_link_keyquery ( struct rpt myrpt  )  [static]

Definition at line 5636 of file app_rpt.c.

References AST_FRAME_TEXT, ast_write(), rpt_link::chan, ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame_subclass::integer, 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().

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

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

Definition at line 3474 of file app_rpt.c.

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

Referenced by telem_any().

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

static void send_newkey ( struct ast_channel chan  )  [static]

Definition at line 5667 of file app_rpt.c.

References ast_sendtext(), and rpt_link::chan.

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

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

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

Definition at line 3636 of file app_rpt.c.

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

Referenced by telem_any().

03637 {
03638    char *p,*stringp;
03639    char *tonesubset;
03640    int f1,f2;
03641    int duration;
03642    int amplitude;
03643    int res;
03644    int i;
03645    int flags;
03646    
03647    res = 0;
03648 
03649    if(!tonestring)
03650       return res;
03651    
03652    p = stringp = ast_strdup(tonestring);
03653 
03654    for(;tonestring;){
03655       tonesubset = strsep(&stringp,")");
03656       if(!tonesubset)
03657          break;
03658       if(sscanf(tonesubset,"(%30d,%30d,%30d,%30d", &f1, &f2, &duration, &amplitude) != 4)
03659          break;
03660       res = play_tone_pair(chan, f1, f2, duration, amplitude);
03661       if(res)
03662          break;
03663    }
03664    ast_free(p);
03665    if(!res)
03666       res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */
03667    
03668    if (!res) 
03669       res = ast_waitstream(chan, "");
03670 
03671    ast_stopstream(chan);
03672 
03673    /*
03674    * Wait for the DAHDI driver to physically write the tone blocks to the hardware
03675    */
03676 
03677    for(i = 0; i < 20 ; i++){
03678       flags =  DAHDI_IOMUX_WRITEEMPTY | DAHDI_IOMUX_NOWAIT; 
03679       res = ioctl(chan->fds[0], DAHDI_IOMUX, &flags);
03680       if(flags & DAHDI_IOMUX_WRITEEMPTY)
03681          break;
03682       if( ast_safe_sleep(chan, 50)){
03683          res = -1;
03684          break;
03685       }
03686    }
03687       
03688    return res;
03689       
03690 }

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

Definition at line 1870 of file app_rpt.c.

References AST_FRAME_TEXT, ast_log(), ast_write(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, ast_frame_subclass::integer, 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().

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

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

Definition at line 7530 of file app_rpt.c.

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

Referenced by sendrxkenwood().

07531 {
07532 int   i;
07533 
07534 ast_log(LOG_NOTICE,"Sent to kenwood: %s\n",txstr);
07535    if (debug) printf("Send to kenwood: %s\n",txstr);
07536    i = serial_remote_io(myrpt, (unsigned char *)txstr, strlen(txstr), 
07537       (unsigned char *)rxstr,RAD_SERIAL_BUFLEN - 1,3);
07538    if (i < 0) return -1;
07539    if ((i > 0) && (rxstr[i - 1] == '\r'))
07540       rxstr[i-- - 1] = 0;
07541    if (debug) printf("Got from kenwood: %s\n",rxstr);
07542 ast_log(LOG_NOTICE,"Got from kenwood: %s\n",rxstr);
07543    return(i);
07544 }

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

Definition at line 7638 of file app_rpt.c.

References KENWOOD_RETRIES, and sendkenwood().

Referenced by set_tm271(), and setkenwood().

07640 {
07641 int   i,j;
07642 
07643    for(i = 0;i < KENWOOD_RETRIES;i++)
07644    {
07645       j = sendkenwood(myrpt,txstr,rxstr);
07646       if (j < 0) return(j);
07647       if (j == 0) continue;
07648       if (!strncmp(rxstr,cmpstr,strlen(cmpstr))) return(0);
07649    }
07650    return(-1);
07651 }     

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

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

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

static int service_scan ( struct rpt myrpt  )  [static]

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

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

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

Definition at line 8502 of file app_rpt.c.

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

Referenced by set_ft897().

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

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

Definition at line 8479 of file app_rpt.c.

References serial_remote_io().

Referenced by set_ft897().

08480 {
08481    unsigned char cmdstr[5];
08482    
08483    memset(cmdstr, 0, 5);
08484    
08485    if(rxplon && txplon)
08486       cmdstr[0] = 0x2A; /* Encode and Decode */
08487    else if (!rxplon && txplon)
08488       cmdstr[0] = 0x4A; /* Encode only */
08489    else if (rxplon && !txplon)
08490       cmdstr[0] = 0x3A; /* Encode only */
08491    else
08492       cmdstr[0] = 0x8A; /* OFF */
08493 
08494    cmdstr[4] = 0x0A; 
08495 
08496    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08497 }

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

Definition at line 8998 of file app_rpt.c.

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

Referenced by set_ic706().

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

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

Definition at line 8371 of file app_rpt.c.

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

Referenced by multimode_bump_freq_ft897(), and set_ft897().

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

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

Definition at line 8902 of file app_rpt.c.

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

Referenced by set_ic706().

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

static int set_ft897 ( struct rpt myrpt  )  [static]

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

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

static int set_ic706 ( struct rpt myrpt  )  [static]

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

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

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

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

08447 {
08448    unsigned char cmdstr[5];
08449    
08450    memset(cmdstr, 0, 5);
08451    
08452    switch(newmode){
08453       case  REM_MODE_FM:
08454          cmdstr[0] = 0x08;
08455          break;
08456 
08457       case  REM_MODE_USB:
08458          cmdstr[0] = 0x01;
08459          break;
08460 
08461       case  REM_MODE_LSB:
08462          cmdstr[0] = 0x00;
08463          break;
08464 
08465       case  REM_MODE_AM:
08466          cmdstr[0] = 0x04;
08467          break;
08468       
08469       default:
08470          return -1;
08471    }
08472    cmdstr[4] = 0x07; 
08473 
08474    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08475 }

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

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

08967 {
08968    unsigned char c;
08969    
08970    if(debug > 6)
08971       ast_log(LOG_NOTICE,"newmode=%i\n",newmode);
08972 
08973    switch(newmode){
08974       case  REM_MODE_FM:
08975          c = 5;
08976          break;
08977 
08978       case  REM_MODE_USB:
08979          c = 1;
08980          break;
08981 
08982       case  REM_MODE_LSB:
08983          c = 0;
08984          break;
08985 
08986       case  REM_MODE_AM:
08987          c = 2;
08988          break;
08989       
08990       default:
08991          return -1;
08992    }
08993    return simple_command_ic706(myrpt,6,c);
08994 }

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

Definition at line 8416 of file app_rpt.c.

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

Referenced by set_ft897().

08417 {
08418    unsigned char cmdstr[5];
08419    
08420    memset(cmdstr, 0, 5);
08421 
08422    switch(offset){
08423       case  REM_SIMPLEX:
08424          cmdstr[0] = 0x89;
08425          break;
08426 
08427       case  REM_MINUS:
08428          cmdstr[0] = 0x09;
08429          break;
08430       
08431       case  REM_PLUS:
08432          cmdstr[0] = 0x49;
08433          break;   
08434 
08435       default:
08436          return -1;
08437    }
08438 
08439    cmdstr[4] = 0x09; 
08440 
08441    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08442 }

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

Definition at line 8936 of file app_rpt.c.

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

Referenced by set_ic706().

08937 {
08938    unsigned char c;
08939 
08940    if(debug > 6)
08941       ast_log(LOG_NOTICE,"offset=%i\n",offset);
08942 
08943    switch(offset){
08944       case  REM_SIMPLEX:
08945          c = 0x10;
08946          break;
08947 
08948       case  REM_MINUS:
08949          c = 0x11;
08950          break;
08951       
08952       case  REM_PLUS:
08953          c = 0x12;
08954          break;   
08955 
08956       default:
08957          return -1;
08958    }
08959 
08960    return simple_command_ic706(myrpt,0x0f,c);
08961 
08962 }

static int set_tm271 ( struct rpt myrpt  )  [static]

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

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

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

Definition at line 1649 of file app_rpt.c.

References ast_log(), errno, and LOG_WARNING.

Referenced by openserial(), and rpt_tele_thread().

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

static int setkenwood ( struct rpt myrpt  )  [static]

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

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

static int setrbi ( struct rpt myrpt  )  [static]

Definition at line 7719 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, setrbi_check(), and rpt::txplon.

Referenced by rpt_tele_thread().

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

static int setrbi_check ( struct rpt myrpt  )  [static]

Definition at line 7970 of file app_rpt.c.

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

Referenced by setrbi(), and setrem().

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

static int setrem ( struct rpt myrpt  )  [static]

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

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

static int setrtx ( struct rpt myrpt  )  [static]

Definition at line 7812 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, send_usb_txt(), setrtx_check(), rpt::txpl, and rpt::txplon.

Referenced by setrem().

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

static int setrtx_check ( struct rpt myrpt  )  [static]

Definition at line 8025 of file app_rpt.c.

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

Referenced by setrtx().

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

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

Definition at line 8402 of file app_rpt.c.

References serial_remote_io().

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

08403 {
08404    unsigned char cmdstr[5];
08405    
08406    memset(cmdstr, 0, 5);
08407 
08408    cmdstr[4] = command; 
08409 
08410    return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0);
08411 
08412 }

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

Definition at line 8884 of file app_rpt.c.

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

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

08885 {
08886    unsigned char cmdstr[10];
08887    
08888    cmdstr[0] = cmdstr[1] = 0xfe;
08889    cmdstr[2] = myrpt->p.civaddr;
08890    cmdstr[3] = 0xe0;
08891    cmdstr[4] = command;
08892    cmdstr[5] = subcommand;
08893    cmdstr[6] = 0xfd;
08894 
08895    return(civ_cmd(myrpt,cmdstr,7));
08896 }

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

Definition at line 2089 of file app_rpt.c.

Referenced by function_autopatchup().

02090 {
02091 int i;   
02092    while(*string){
02093       for(i = 0; charlist[i] ; i++){
02094          if(*string == charlist[i]){
02095             string++;
02096             break;
02097          }
02098       }
02099       if(!charlist[i])
02100          return string;
02101    }
02102    return string;
02103 }

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

Definition at line 8255 of file app_rpt.c.

References MAXREMSTR.

Referenced by set_ctcss_freq_ft897().

08256 {
08257    char freq_copy[MAXREMSTR];
08258    char *decp;
08259 
08260    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
08261    if(decp){
08262       *decp++ = 0;
08263       strncpy(hertz, freq_copy, MAXREMSTR);
08264       strncpy(decimal, decp, strlen(decp));
08265       decimal[strlen(decp)] = '\0';
08266       return 0;
08267    }
08268    else
08269       return -1;
08270 }

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

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

08233 {
08234    char freq_copy[MAXREMSTR];
08235    char *decp;
08236 
08237    decp = strchr(strncpy(freq_copy, freq, MAXREMSTR),'.');
08238    if(decp){
08239       *decp++ = 0;
08240       strncpy(mhz, freq_copy, MAXREMSTR);
08241       strcpy(decimals, "00000");
08242       strncpy(decimals, decp, strlen(decp));
08243       decimals[5] = 0;
08244       return 0;
08245    }
08246    else
08247       return -1;
08248 
08249 }

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

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

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

static void stop_scan ( struct rpt myrpt  )  [static]

Definition at line 9507 of file app_rpt.c.

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

Referenced by handle_remote_dtmf_digit().

09508 {
09509    myrpt->hfscanstop = 1;
09510    rpt_telemetry(myrpt,SCAN,0);
09511 }

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

Definition at line 3749 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and telem_lookup().

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

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

Definition at line 3805 of file app_rpt.c.

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

Referenced by rpt_tele_thread(), and rpt_telemetry().

03806 {
03807    
03808    int res;
03809    int i;
03810    char *entry;
03811    char *telemetry;
03812    char *telemetry_save;
03813 
03814    res = 0;
03815    telemetry_save = NULL;
03816    entry = NULL;
03817    
03818    /* Retrieve the section name for telemetry from the node section */
03819    telemetry = (char *) ast_variable_retrieve(myrpt->cfg, node, TELEMETRY);
03820    if(telemetry ){
03821       telemetry_save = ast_strdup(telemetry);
03822       if(!telemetry_save){
03823          ast_log(LOG_WARNING,"ast_strdup() failed in telem_lookup()\n");
03824          return res;
03825       }
03826       entry = (char *) ast_variable_retrieve(myrpt->cfg, telemetry_save, name);
03827    }
03828    
03829    /* Try to look up the telemetry name */   
03830 
03831    if(!entry){
03832       /* Telemetry name wasn't found in the config file, use the default */
03833       for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){
03834          if(!strcasecmp(tele_defs[i].name, name))
03835             entry = tele_defs[i].value;
03836       }
03837    }
03838    if(entry){  
03839       if(strlen(entry))
03840          if (chan) telem_any(myrpt,chan, entry);
03841    }
03842    else{
03843       res = -1;
03844    }
03845    ast_free(telemetry_save);
03846    return res;
03847 }

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

Definition at line 2132 of file app_rpt.c.

References rpt_topkey::timesince.

Referenced by rpt().

02133 {
02134 struct rpt_topkey *x = (struct rpt_topkey *) a;
02135 struct rpt_topkey *y = (struct rpt_topkey *) b;
02136 
02137    return(x->timesince - y->timesince);
02138 }

static int unload_module ( void   )  [static]

Definition at line 15121 of file app_rpt.c.

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

15123 {
15124    int i, res;
15125 
15126 #ifdef   OLD_ASTERISK
15127    STANDARD_HANGUP_LOCALUSERS;
15128 #endif
15129    for(i = 0; i < nrpts; i++) {
15130       if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue;
15131                 ast_mutex_destroy(&rpt_vars[i].lock);
15132                 ast_mutex_destroy(&rpt_vars[i].remlock);
15133    }
15134    res = ast_unregister_application(app);
15135 
15136 #ifdef   NEW_ASTERISK
15137    ast_cli_unregister_multiple(rpt_cli, ARRAY_LEN(rpt_cli));
15138 #else
15139    /* Unregister cli extensions */
15140    ast_cli_unregister(&cli_debug);
15141    ast_cli_unregister(&cli_dump);
15142    ast_cli_unregister(&cli_stats);
15143    ast_cli_unregister(&cli_lstats);
15144    ast_cli_unregister(&cli_nodes);
15145    ast_cli_unregister(&cli_local_nodes);
15146    ast_cli_unregister(&cli_reload);
15147    ast_cli_unregister(&cli_restart);
15148    ast_cli_unregister(&cli_fun);
15149    ast_cli_unregister(&cli_fun1);
15150    res |= ast_cli_unregister(&cli_cmd);
15151 #endif
15152 #ifndef OLD_ASTERISK
15153    res |= ast_manager_unregister("RptLocalNodes");
15154    res |= ast_manager_unregister("RptStatus");
15155 #endif
15156    return res;
15157 }

static int vfo_ic706 ( struct rpt myrpt  )  [static]

Definition at line 9080 of file app_rpt.c.

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

Referenced by set_ic706().

09081 {
09082    unsigned char cmdstr[10];
09083    
09084    cmdstr[0] = cmdstr[1] = 0xfe;
09085    cmdstr[2] = myrpt->p.civaddr;
09086    cmdstr[3] = 0xe0;
09087    cmdstr[4] = 7;
09088    cmdstr[5] = 0xfd;
09089 
09090    return(civ_cmd(myrpt,cmdstr,6));
09091 }

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

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

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

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

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

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

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

Definition at line 3931 of file app_rpt.c.

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

Referenced by rpt_tele_thread().

03932 {
03933    int interval;
03934    interval = get_wait_interval(myrpt, type);
03935    if(debug)
03936       ast_log(LOG_NOTICE,"Delay interval = %d\n", interval);
03937    if(interval)
03938       ast_safe_sleep(chan,interval);
03939    if(debug)
03940       ast_log(LOG_NOTICE,"Delay complete\n");
03941    return;
03942 }


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

Definition at line 15231 of file app_rpt.c.

char* app = "Rpt" [static]

Definition at line 380 of file app_rpt.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

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

struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS }

Definition at line 369 of file app_rpt.c.

Referenced by __ast_http_load(), __ast_http_post_load(), __ast_udptl_reload(), __init_manager(), _dsp_init(), action_getconfig(), action_getconfigjson(), action_listcategories(), action_updateconfig(), adsi_load(), advanced_options(), aji_load_config(), ast_cli_perms_init(), ast_plc_reload(), ast_readconfig(), conf_exec(), config_load(), config_module(), directory_exec(), do_reload(), festival_exec(), find_conf(), gtalk_load_config(), handle_cli_dialplan_save(), iax_provision_reload(), init_logger_chain(), initialize_cc_max_requests(), jingle_load_config(), load_config(), load_config_meetme(), load_indications(), load_module(), load_modules(), load_moh_classes(), load_odbc_config(), load_pktccops_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(), read_password_from_file(), realtime_directory(), reload(), reload_config(), reload_followme(), reload_queue_rules(), reload_queues(), rpt_master(), rtp_reload(), set_config(), setup_dahdi_int(), sla_load_config(), smdi_load(), tds_load_module(), vm_change_password(), and vm_forwardoptions().

int debug = 0 [static]

Definition at line 440 of file app_rpt.c.

Referenced by add_sdp(), aji_load_config(), check_peer_ok(), handle_incoming(), handle_pri_show_debug(), process_sdp(), process_sdp_a_audio(), process_sdp_a_text(), process_sdp_a_video(), set_destination(), and sip_sendtext().

char debug_usage[] [static]

Initial value:

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

Definition at line 1187 of file app_rpt.c.

char* descrip [static]

Definition at line 384 of file app_rpt.c.

Referenced by aji_handle_presence().

char* discstr = "!!DISCONNECT!!"

Definition at line 460 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 1199 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 1203 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 1195 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 1191 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 1219 of file app_rpt.c.

struct function_table_tag function_table[] [static]

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

char* newkeystr = "!NEWKEY!"

Definition at line 461 of file app_rpt.c.

ast_mutex_t nodeloglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 887 of file app_rpt.c.

Referenced by donodelog(), and rpt_master().

ast_mutex_t nodelookuplock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static]

Definition at line 889 of file app_rpt.c.

Referenced by node_lookup().

int nrpts = 0 [static]

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

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

Definition at line 443 of file app_rpt.c.

char* remote_rig_ft897 = "ft897" [static]

Definition at line 462 of file app_rpt.c.

char* remote_rig_ic706 = "ic706" [static]

Definition at line 466 of file app_rpt.c.

char* remote_rig_kenwood = "kenwood" [static]

Definition at line 464 of file app_rpt.c.

char* remote_rig_ppp16 = "ppp16" [static]

Definition at line 469 of file app_rpt.c.

char* remote_rig_rbi = "rbi" [static]

Definition at line 463 of file app_rpt.c.

char* remote_rig_rtx150 = "rtx150" [static]

Definition at line 467 of file app_rpt.c.

char* remote_rig_rtx450 = "rtx450" [static]

Definition at line 468 of file app_rpt.c.

char* remote_rig_tm271 = "tm271" [static]

Definition at line 465 of file app_rpt.c.

char restart_usage[] [static]

Initial value:

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

Definition at line 1215 of file app_rpt.c.

struct ast_cli_entry rpt_cli[] [static]

Definition at line 3458 of file app_rpt.c.

Referenced by load_module(), and unload_module().

pthread_t rpt_master_thread [static]

Definition at line 525 of file app_rpt.c.

struct rpt rpt_vars[MAXRPTS] [static]

time_t starttime = 0 [static]

Definition at line 523 of file app_rpt.c.

Referenced by tzparse(), and wait_for_answer().

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

Definition at line 382 of file app_rpt.c.

Referenced by acf_retrieve_docs(), handle_cli_agi_show(), handle_show_function(), init_acf_query(), and print_app_docs().

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

Definition at line 378 of file app_rpt.c.

struct telem_defaults tele_defs[] [static]

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


Generated on Mon Mar 19 11:30:34 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7