#include "asterisk.h"
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/io.h>
#include <math.h>
#include <zaptel/zaptel.h>
#include <zaptel/tonezone.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/features.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/localtime.h"
Include dependency graph for app_rpt.c:
Go to the source code of this file.
Data Structures | |
struct | function_table_tag |
struct | morse_bits |
struct | rpt |
struct | rpt_link |
struct | rpt_lstat |
struct | rpt_tele |
struct | telem_defaults |
Defines | |
#define | ACTIONSIZE 32 |
#define | DEFAULT_IOBASE 0x378 |
#define | DELIMCHR ',' |
#define | DISC_TIME 10000 |
#define | DTMF_TIMEOUT 3 |
#define | ENDCHAR '#' |
#define | FUNCCHAR '*' |
#define | FUNCTDELAY 1500 |
#define | FUNCTIONS "functions" |
#define | HANGTIME 5000 |
#define | IDTIME 300000 |
#define | MACRO "macro" |
#define | MACROPTIME 500 |
#define | MACROTIME 100 |
#define | MAX_RETRIES 5 |
#define | MAX_STAT_LINKS 32 |
#define | MAXCONNECTTIME 5000 |
#define | MAXDTMF 32 |
#define | MAXMACRO 2048 |
#define | MAXNODESTR 300 |
#define | MAXPATCHCONTEXT 100 |
#define | MAXPEERSTR 31 |
#define | MAXREMSTR 15 |
#define | MAXRPTS 20 |
#define | MEMORY "memory" |
#define | MORSE "morse" |
#define | MSWAIT 200 |
#define | NODES "nodes" |
#define | POLITEID 30000 |
#define | QUOTECHR 34 |
#define | REDUNDANT_TX_TIME 2000 |
#define | REM_SCANTIME 100 |
#define | RETRY_TIMER_MS 5000 |
#define | rpt_mutex_lock(x) ast_mutex_lock(x) |
#define | rpt_mutex_unlock(x) ast_mutex_unlock(x) |
#define | TELEMETRY "telemetry" |
#define | TELEPARAMSIZE 256 |
#define | TOTIME 180000 |
Enumerations | |
enum | { REM_OFF, REM_MONITOR, REM_TX } |
enum | { ID, PROC, TERM, COMPLETE, UNKEY, REMDISC, REMALREADY, REMNOTFOUND, REMGO, CONNECTED, CONNFAIL, STATUS, TIMEOUT, ID1, STATS_TIME, STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH, TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY } |
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_DOKEY } |
enum | { SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE } |
enum | { DLY_TELEM, DLY_ID, DLY_UNKEY, DLY_CALLTERM } |
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 } |
Functions | |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Radio Repeater / Remote Base",.load=load_module,.unload=unload_module,.reload=reload,) | |
static int | attempt_reconnect (struct rpt *myrpt, struct rpt_link *l) |
static int | check_freq (struct rpt *myrpt, int m, int d, int *defmode) |
static int | check_freq_ft897 (int m, int d, int *defmode) |
static int | check_freq_rbi (int m, int d, int *defmode) |
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 void | do_scheduler (struct rpt *myrpt) |
static int | finddelim (char *str, char *strp[], int limit) |
static int | function_autopatchdn (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_autopatchup (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_cop (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_ilink (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_macro (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_remote (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | function_status (struct rpt *myrpt, char *param, char *digitbuf, int command_source, struct rpt_link *mylink) |
static int | get_wait_interval (struct rpt *myrpt, int type) |
static void | handle_link_data (struct rpt *myrpt, struct rpt_link *mylink, char *str) |
static void | handle_link_phone_dtmf (struct rpt *myrpt, struct rpt_link *mylink, char c) |
static int | handle_remote_data (struct rpt *myrpt, char *str) |
static int | handle_remote_dtmf_digit (struct rpt *myrpt, char c, char *keyed, int phonemode) |
static int | handle_remote_phone_dtmf (struct rpt *myrpt, char c, char *keyed, int phonemode) |
static int | load_module (void) |
static void | load_rpt_vars (int n, int init) |
static void | local_dtmf_helper (struct rpt *myrpt, char c) |
static int | matchkeyword (char *string, char **param, char *keywords[]) |
static int | multimode_bump_freq (struct rpt *myrpt, int interval) |
static int | multimode_bump_freq_ft897 (struct rpt *myrpt, int interval) |
static int | multimode_capable (struct rpt *myrpt) |
static int | myatoi (const char *str) |
static int | play_silence (struct ast_channel *chan, int duration) |
static int | play_tone (struct ast_channel *chan, int freq, int duration, int amplitude) |
static int | play_tone_pair (struct ast_channel *chan, int f1, int f2, int duration, int amplitude) |
static void | queue_id (struct rpt *myrpt) |
static int | rbi_mhztoband (char *str) |
static void | rbi_out (struct rpt *myrpt, unsigned char *data) |
static void | rbi_out_parallel (struct rpt *myrpt, unsigned char *data) |
static int | rbi_pltocode (char *str) |
static int | reload (void) |
static int | retrieve_astcfgint (struct rpt *myrpt, char *category, char *name, int min, int max, int defl) |
static int | rmt_saycharstr (struct rpt *myrpt, struct ast_channel *chan, int delay, char *charstr) |
static int | rmt_sayfile (struct rpt *myrpt, struct ast_channel *chan, int delay, char *filename) |
static int | rmt_telem_finish (struct rpt *myrpt, struct ast_channel *chan) |
static int | rmt_telem_start (struct rpt *myrpt, struct ast_channel *chan, int delay) |
static void * | rpt (void *this) |
static void * | rpt_call (void *this) |
static int | rpt_do_debug (int fd, int argc, char *argv[]) |
static int | rpt_do_dump (int fd, int argc, char *argv[]) |
static int | rpt_do_lstats (int fd, int argc, char *argv[]) |
static int | rpt_do_reload (int fd, int argc, char *argv[]) |
static int | rpt_do_restart (int fd, int argc, char *argv[]) |
static int | rpt_do_stats (int fd, int argc, char *argv[]) |
static int | rpt_exec (struct ast_channel *chan, void *data) |
static void * | rpt_master (void *config) |
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, const char *fname) |
static int | saynum (struct ast_channel *mychannel, int num) |
static void | send_link_dtmf (struct rpt *myrpt, char c) |
static int | send_morse (struct ast_channel *chan, const char *string, int speed, int freq, int amplitude) |
static int | send_tone_telemetry (struct ast_channel *chan, const char *tonestring) |
static int | serial_remote_io (struct rpt *myrpt, unsigned char *txbuf, int txbytes, 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_freq_ft897 (struct rpt *myrpt, char *newfreq) |
static int | set_ft897 (struct rpt *myrpt) |
static int | set_mode_ft897 (struct rpt *myrpt, char newmode) |
static int | set_offset_ft897 (struct rpt *myrpt, char offset) |
static int | setrbi (struct rpt *myrpt) |
static int | setrem (struct rpt *myrpt) |
static int | simple_command_ft897 (struct rpt *myrpt, char command) |
static char * | skipchars (char *string, char *charlist) |
static int | split_ctcss_freq (char *hertz, char *decimal, char *freq) |
static int | split_freq (char *mhz, char *decimals, char *freq) |
static void | stop_scan (struct rpt *myrpt, int flag) |
static int | telem_any (struct rpt *myrpt, struct ast_channel *chan, const char *entry) |
static int | telem_lookup (struct rpt *myrpt, struct ast_channel *chan, char *node, char *name) |
static int | unload_module (void) |
static void | wait_interval (struct rpt *myrpt, int type, struct ast_channel *chan) |
Variables | |
static char * | app = "Rpt" |
static struct ast_cli_entry | cli_rpt [] |
static int | debug = 0 |
static char | debug_usage [] |
static char * | descrip |
char * | discstr = "!!DISCONNECT!!" |
static char | dump_lstats [] |
static char | dump_stats [] |
static char | dump_usage [] |
static struct function_table_tag | function_table [] |
static int | nrpts = 0 |
static char | reload_usage [] |
static char * | remote_rig_ft897 = "ft897" |
static char * | remote_rig_rbi = "rbi" |
static char | restart_usage [] |
static pthread_t | rpt_master_thread |
static struct rpt | rpt_vars [MAXRPTS] |
static char * | synopsis = "Radio Repeater/Remote Base Control System" |
static struct telem_defaults | tele_defs [] |
static unsigned int | vmajor = 0 |
static unsigned int | vminor = 47 |
Repeater / Remote Functions: "Simple" Mode: * - autopatch access, # - autopatch hangup Normal mode: See the function list in rpt.conf (autopatchup, autopatchdn) autopatchup can optionally take comma delimited setting=value pairs:
context=string : Override default context with "string" dialtime=ms : Specify the max number of milliseconds between phone number digits (1000 milliseconds = 1 second) farenddisconnect=1 : Automatically disconnect when called party hangs up noct=1 : Don't send repeater courtesy tone during autopatch calls quiet=1 : Don't send dial tone, or connect messages. Do not send patch down message when called party hangs up
Example: 123=autopatchup,dialtime=20000,noct=1,farenddisconnect=1
To send an asterisk (*) while dialing or talking on phone, use the autopatch acess code.
status cmds:
1 - Force ID 2 - Give Time of Day 3 - Give software Version
cop (control operator) cmds:
1 - System warm boot 2 - System enable 3 - System disable 4 - Test Tone On 5 - Dump System Variables on Console (debug) 6 - PTT (phone mode only)
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
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)
'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 DEFAULT_IOBASE 0x378 |
#define DELIMCHR ',' |
#define DTMF_TIMEOUT 3 |
#define ENDCHAR '#' |
#define FUNCCHAR '*' |
#define FUNCTIONS "functions" |
#define HANGTIME 5000 |
#define IDTIME 300000 |
#define MACRO "macro" |
#define MACROTIME 100 |
#define MAX_RETRIES 5 |
Definition at line 144 of file app_rpt.c.
Referenced by function_ilink(), handle_link_data(), rpt(), and rpt_exec().
#define MAX_STAT_LINKS 32 |
#define MAXDTMF 32 |
Definition at line 133 of file app_rpt.c.
Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and local_dtmf_helper().
#define MAXMACRO 2048 |
#define MAXNODESTR 300 |
#define MAXPATCHCONTEXT 100 |
Definition at line 171 of file app_rpt.c.
Referenced by function_autopatchup(), and local_dtmf_helper().
#define MAXPEERSTR 31 |
#define MAXREMSTR 15 |
Definition at line 151 of file app_rpt.c.
Referenced by function_remote(), multimode_bump_freq_ft897(), rpt_do_lstats(), service_scan(), set_ctcss_freq_ft897(), set_freq_ft897(), setrbi(), split_ctcss_freq(), and split_freq().
#define MEMORY "memory" |
#define MORSE "morse" |
#define MSWAIT 200 |
#define NODES "nodes" |
#define POLITEID 30000 |
#define QUOTECHR 34 |
#define REM_SCANTIME 100 |
#define rpt_mutex_lock | ( | x | ) | ast_mutex_lock(x) |
Definition at line 687 of file app_rpt.c.
Referenced by attempt_reconnect(), function_autopatchdn(), function_autopatchup(), function_ilink(), function_macro(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_do_lstats(), rpt_do_stats(), rpt_exec(), rpt_tele_thread(), and rpt_telemetry().
#define rpt_mutex_unlock | ( | x | ) | ast_mutex_unlock(x) |
Definition at line 688 of file app_rpt.c.
Referenced by attempt_reconnect(), function_autopatchdn(), function_autopatchup(), function_ilink(), function_macro(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), rpt_do_lstats(), rpt_do_stats(), rpt_exec(), rpt_tele_thread(), and rpt_telemetry().
#define TELEMETRY "telemetry" |
#define TELEPARAMSIZE 256 |
#define TOTIME 180000 |
anonymous enum |
anonymous enum |
Definition at line 182 of file app_rpt.c.
00182 {ID,PROC,TERM,COMPLETE,UNKEY,REMDISC,REMALREADY,REMNOTFOUND,REMGO, 00183 CONNECTED,CONNFAIL,STATUS,TIMEOUT,ID1, STATS_TIME, 00184 STATS_VERSION, IDTALKOVER, ARB_ALPHA, TEST_TONE, REV_PATCH, 00185 TAILMSG, MACRO_NOTFOUND, MACRO_BUSY, LASTNODEKEY};
anonymous enum |
anonymous enum |
anonymous enum |
Definition at line 191 of file app_rpt.c.
00191 {DC_INDETERMINATE, DC_REQ_FLUSH, DC_ERROR, DC_COMPLETE, DC_DOKEY};
anonymous enum |
Definition at line 193 of file app_rpt.c.
00193 {SOURCE_RPT, SOURCE_LNK, SOURCE_RMT, SOURCE_PHONE, SOURCE_DPHONE};
anonymous enum |
anonymous enum |
anonymous 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 |
Definition at line 199 of file app_rpt.c.
00199 {HF_SCAN_OFF,HF_SCAN_DOWN_SLOW,HF_SCAN_DOWN_QUICK, 00200 HF_SCAN_DOWN_FAST,HF_SCAN_UP_SLOW,HF_SCAN_UP_QUICK,HF_SCAN_UP_FAST};
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_DEFAULT | , | |||
"Radio Repeater / Remote Base" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
Definition at line 5772 of file app_rpt.c.
References ast_call(), AST_FORMAT_SLINEAR, ast_log(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_variable_retrieve(), ast_verbose(), rpt::cfg, free, rpt::links, rpt::lock, LOG_NOTICE, rpt::name, rpt_link::name, rpt_link::next, rpt::nodes, option_verbose, rpt::p, rpt_mutex_lock, rpt_mutex_unlock, s, strdup, strsep(), and VERBOSE_PREFIX_3.
Referenced by rpt().
05773 { 05774 const char *val; 05775 char *s, *s1, *s2, *tele; 05776 char tmp[300], deststr[300] = ""; 05777 05778 val = ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, l->name); 05779 if (!val) 05780 { 05781 fprintf(stderr,"attempt_reconnect: cannot find node %s\n",l->name); 05782 return -1; 05783 } 05784 05785 rpt_mutex_lock(&myrpt->lock); 05786 /* remove from queue */ 05787 remque((struct qelem *) l); 05788 rpt_mutex_unlock(&myrpt->lock); 05789 ast_copy_string(tmp,val,sizeof(tmp)); 05790 s = tmp; 05791 s1 = strsep(&s,","); 05792 s2 = strsep(&s,","); 05793 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 05794 tele = strchr(deststr, '/'); 05795 if (!tele) { 05796 fprintf(stderr,"attempt_reconnect:Dial number (%s) must be in format tech/number\n",deststr); 05797 return -1; 05798 } 05799 *tele++ = 0; 05800 l->elaptime = 0; 05801 l->connecttime = 0; 05802 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 05803 if (l->chan){ 05804 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 05805 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 05806 l->chan->whentohangup = 0; 05807 l->chan->appl = "Apprpt"; 05808 l->chan->data = "(Remote Rx)"; 05809 if (option_verbose > 2) 05810 ast_verbose(VERBOSE_PREFIX_3 "rpt (attempt_reconnect) initiating call to %s/%s on %s\n", 05811 deststr, tele, l->chan->name); 05812 if(l->chan->cid.cid_num) 05813 free(l->chan->cid.cid_num); 05814 l->chan->cid.cid_num = strdup(myrpt->name); 05815 ast_call(l->chan,tele,999); 05816 05817 } 05818 else 05819 { 05820 if (option_verbose > 2) 05821 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 05822 deststr,tele,l->chan->name); 05823 return -1; 05824 } 05825 rpt_mutex_lock(&myrpt->lock); 05826 /* put back in queue */ 05827 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 05828 rpt_mutex_unlock(&myrpt->lock); 05829 ast_log(LOG_NOTICE,"Reconnect Attempt to %s in process\n",l->name); 05830 return 0; 05831 }
static int check_freq | ( | struct rpt * | myrpt, | |
int | m, | |||
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 4737 of file app_rpt.c.
References check_freq_ft897(), check_freq_rbi(), and rpt::remote.
Referenced by function_remote().
04738 { 04739 if(!strcmp(myrpt->remote, remote_rig_ft897)) 04740 return check_freq_ft897(m, d, defmode); 04741 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 04742 return check_freq_rbi(m, d, defmode); 04743 else 04744 return -1; 04745 }
static int check_freq_ft897 | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 4340 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().
04341 { 04342 int dflmd = REM_MODE_FM; 04343 04344 if(m == 1){ /* 160 meters */ 04345 dflmd = REM_MODE_LSB; 04346 if(d < 80001) 04347 return -1; 04348 } 04349 else if(m == 3){ /* 80 meters */ 04350 dflmd = REM_MODE_LSB; 04351 if(d < 75001) 04352 return -1; 04353 } 04354 else if(m == 7){ /* 40 meters */ 04355 dflmd = REM_MODE_LSB; 04356 if((d < 15001) || (d > 29999)) 04357 return -1; 04358 } 04359 else if(m == 14){ /* 20 meters */ 04360 dflmd = REM_MODE_USB; 04361 if((d < 15001) || (d > 34999)) 04362 return -1; 04363 } 04364 else if(m == 18){ /* 17 meters */ 04365 dflmd = REM_MODE_USB; 04366 if((d < 11001) || (d > 16797)) 04367 return -1; 04368 } 04369 else if(m == 21){ /* 15 meters */ 04370 dflmd = REM_MODE_USB; 04371 if((d < 20001) || (d > 44999)) 04372 return -1; 04373 } 04374 else if(m == 24){ /* 12 meters */ 04375 dflmd = REM_MODE_USB; 04376 if((d < 93001) || (d > 98999)) 04377 return -1; 04378 } 04379 else if(m == 28){ /* 10 meters */ 04380 dflmd = REM_MODE_USB; 04381 if(d < 30001) 04382 return -1; 04383 } 04384 else if(m == 29){ 04385 if(d >= 51000) 04386 dflmd = REM_MODE_FM; 04387 else 04388 dflmd = REM_MODE_USB; 04389 if(d > 69999) 04390 return -1; 04391 } 04392 else if(m == 50){ /* 6 meters */ 04393 if(d < 10100) 04394 return -1; 04395 if(d >= 30000) 04396 dflmd = REM_MODE_FM; 04397 else 04398 dflmd = REM_MODE_USB; 04399 04400 } 04401 else if((m >= 51) && ( m < 54)){ 04402 dflmd = REM_MODE_FM; 04403 } 04404 else if(m == 144){ /* 2 meters */ 04405 if(d < 10100) 04406 return -1; 04407 if(d >= 30000) 04408 dflmd = REM_MODE_FM; 04409 else 04410 dflmd = REM_MODE_USB; 04411 } 04412 else if((m >= 145) && (m < 148)){ 04413 dflmd = REM_MODE_FM; 04414 } 04415 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 04416 if(m < 438) 04417 dflmd = REM_MODE_USB; 04418 else 04419 dflmd = REM_MODE_FM; 04420 ; 04421 } 04422 else 04423 return -1; 04424 04425 if(defmode) 04426 *defmode = dflmd; 04427 04428 return 0; 04429 }
static int check_freq_rbi | ( | int | m, | |
int | d, | |||
int * | defmode | |||
) | [static] |
Definition at line 4253 of file app_rpt.c.
References REM_MODE_FM.
Referenced by check_freq().
04254 { 04255 int dflmd = REM_MODE_FM; 04256 04257 if(m == 50){ /* 6 meters */ 04258 if(d < 10100) 04259 return -1; 04260 } 04261 else if((m >= 51) && ( m < 54)){ 04262 ; 04263 } 04264 else if(m == 144){ /* 2 meters */ 04265 if(d < 10100) 04266 return -1; 04267 } 04268 else if((m >= 145) && (m < 148)){ 04269 ; 04270 } 04271 else if((m >= 222) && (m < 225)){ /* 1.25 meters */ 04272 ; 04273 } 04274 else if((m >= 430) && (m < 450)){ /* 70 centimeters */ 04275 ; 04276 } 04277 else if((m >= 1240) && (m < 1300)){ /* 23 centimeters */ 04278 ; 04279 } 04280 else 04281 return -1; 04282 04283 if(defmode) 04284 *defmode = dflmd; 04285 04286 04287 return 0; 04288 }
static int closerem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 4724 of file app_rpt.c.
References closerem_ft897(), and rpt::remote.
04725 { 04726 return 0; /* XXX BROKEN!! */ 04727 if(!strcmp(myrpt->remote, remote_rig_ft897)) 04728 return closerem_ft897(myrpt); 04729 else 04730 return 0; 04731 }
static int closerem_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 4657 of file app_rpt.c.
References simple_command_ft897().
Referenced by closerem().
04658 { 04659 simple_command_ft897(myrpt, 0x88); /* PTT off */ 04660 return 0; 04661 }
static int collect_function_digits | ( | struct rpt * | myrpt, | |
char * | digits, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 3533 of file app_rpt.c.
References ast_variable_browse(), rpt::cfg, DC_ERROR, DC_INDETERMINATE, rpt::dphone_functions, rpt::dphone_longestfunc, function_table, rpt::functions, rpt::link_functions, rpt::link_longestfunc, rpt::longestfunc, ast_variable::name, ast_variable::next, rpt::p, rpt::phone_functions, rpt::phone_longestfunc, SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, strsep(), and ast_variable::value.
Referenced by handle_link_data(), handle_link_phone_dtmf(), handle_remote_dtmf_digit(), and local_dtmf_helper().
03535 { 03536 int i; 03537 char *stringp,*action,*param,*functiondigits; 03538 char function_table_name[30] = ""; 03539 char workstring[200]; 03540 03541 struct ast_variable *vp; 03542 03543 if(debug) 03544 printf("@@@@ Digits collected: %s, source: %d\n", digits, command_source); 03545 03546 if (command_source == SOURCE_DPHONE) { 03547 if (!myrpt->p.dphone_functions) return DC_INDETERMINATE; 03548 ast_copy_string(function_table_name, myrpt->p.dphone_functions, sizeof(function_table_name)); 03549 } 03550 else if (command_source == SOURCE_PHONE) { 03551 if (!myrpt->p.phone_functions) return DC_INDETERMINATE; 03552 ast_copy_string(function_table_name, myrpt->p.phone_functions, sizeof(function_table_name)); 03553 } 03554 else if (command_source == SOURCE_LNK) 03555 ast_copy_string(function_table_name, myrpt->p.link_functions, sizeof(function_table_name)); 03556 else 03557 ast_copy_string(function_table_name, myrpt->p.functions, sizeof(function_table_name)); 03558 vp = ast_variable_browse(myrpt->cfg, function_table_name); 03559 while(vp) { 03560 if(!strncasecmp(vp->name, digits, strlen(vp->name))) 03561 break; 03562 vp = vp->next; 03563 } 03564 if(!vp) { 03565 int n; 03566 03567 n = myrpt->longestfunc; 03568 if (command_source == SOURCE_LNK) n = myrpt->link_longestfunc; 03569 else 03570 if (command_source == SOURCE_PHONE) n = myrpt->phone_longestfunc; 03571 else 03572 if (command_source == SOURCE_DPHONE) n = myrpt->dphone_longestfunc; 03573 03574 if(strlen(digits) >= n) 03575 return DC_ERROR; 03576 else 03577 return DC_INDETERMINATE; 03578 } 03579 /* Found a match, retrieve value part and parse */ 03580 ast_copy_string(workstring, vp->value, sizeof(workstring)); 03581 stringp = workstring; 03582 action = strsep(&stringp, ","); 03583 param = stringp; 03584 if(debug) 03585 printf("@@@@ action: %s, param = %s\n",action, (param) ? param : "(null)"); 03586 /* Look up the action */ 03587 for(i = 0 ; i < (sizeof(function_table)/sizeof(struct function_table_tag)); i++){ 03588 if(!strncasecmp(action, function_table[i].action, strlen(action))) 03589 break; 03590 } 03591 if(debug) 03592 printf("@@@@ table index i = %d\n",i); 03593 if(i == (sizeof(function_table)/sizeof(struct function_table_tag))){ 03594 /* Error, action not in table */ 03595 return DC_ERROR; 03596 } 03597 if(function_table[i].function == NULL){ 03598 /* Error, function undefined */ 03599 if(debug) 03600 printf("@@@@ NULL for action: %s\n",action); 03601 return DC_ERROR; 03602 } 03603 functiondigits = digits + strlen(vp->name); 03604 return (*function_table[i].function)(myrpt, param, functiondigits, command_source, mylink); 03605 }
static void do_scheduler | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 5988 of file app_rpt.c.
References ast_localtime(), ast_log(), rpt::curtv, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, and LOG_NOTICE.
Referenced by rpt().
05989 { 05990 int res; 05991 struct tm tmnow; 05992 05993 memcpy(&myrpt->lasttv, &myrpt->curtv, sizeof(struct timeval)); 05994 05995 if( (res = gettimeofday(&myrpt->curtv, NULL)) < 0) 05996 ast_log(LOG_NOTICE, "Scheduler gettime of day returned: %s\n", strerror(res)); 05997 05998 /* Try to get close to a 1 second resolution */ 05999 06000 if(myrpt->lasttv.tv_sec == myrpt->curtv.tv_sec) 06001 return; 06002 06003 ast_localtime(&myrpt->curtv.tv_sec, &tmnow, NULL); 06004 06005 /* If midnight, then reset all daily statistics */ 06006 06007 if((tmnow.tm_hour == 0)&&(tmnow.tm_min == 0)&&(tmnow.tm_sec == 0)){ 06008 myrpt->dailykeyups = 0; 06009 myrpt->dailytxtime = 0; 06010 myrpt->dailykerchunks = 0; 06011 myrpt->dailyexecdcommands = 0; 06012 } 06013 }
static int finddelim | ( | char * | str, | |
char * | strp[], | |||
int | limit | |||
) | [static] |
Definition at line 816 of file app_rpt.c.
References DELIMCHR, and QUOTECHR.
Referenced by function_autopatchup(), and load_rpt_vars().
00817 { 00818 int i,l,inquo; 00819 00820 inquo = 0; 00821 i = 0; 00822 strp[i++] = str; 00823 if (!*str) 00824 { 00825 strp[0] = 0; 00826 return(0); 00827 } 00828 for(l = 0; *str && (l < limit) ; str++) 00829 { 00830 if (*str == QUOTECHR) 00831 { 00832 if (inquo) 00833 { 00834 *str = 0; 00835 inquo = 0; 00836 } 00837 else 00838 { 00839 strp[i - 1] = str + 1; 00840 inquo = 1; 00841 } 00842 } 00843 if ((*str == DELIMCHR) && (!inquo)) 00844 { 00845 *str = 0; 00846 l++; 00847 strp[i++] = str + 1; 00848 } 00849 } 00850 strp[i] = 0; 00851 return(i); 00852 00853 }
static int function_autopatchdn | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 3391 of file app_rpt.c.
References rpt::callmode, DC_COMPLETE, DC_ERROR, rpt::enable, rpt::lock, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), and TERM.
03392 { 03393 if (!myrpt->enable) 03394 return DC_ERROR; 03395 03396 if(debug) 03397 printf("@@@@ Autopatch down\n"); 03398 03399 rpt_mutex_lock(&myrpt->lock); 03400 03401 if (!myrpt->callmode){ 03402 rpt_mutex_unlock(&myrpt->lock); 03403 return DC_COMPLETE; 03404 } 03405 03406 myrpt->callmode = 0; 03407 rpt_mutex_unlock(&myrpt->lock); 03408 rpt_telemetry(myrpt, TERM, NULL); 03409 return DC_COMPLETE; 03410 }
static int function_autopatchup | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 3293 of file app_rpt.c.
References ast_log(), ast_pthread_create, ast_strdupa, rpt::callmode, rpt::cidx, DC_COMPLETE, DC_ERROR, rpt::enable, rpt::exten, finddelim(), rpt::funcchar, 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, and skipchars().
03294 { 03295 pthread_attr_t attr; 03296 int i, index, paramlength; 03297 char *lparam; 03298 char *value = NULL; 03299 char *paramlist[20]; 03300 03301 static char *keywords[] = { 03302 "context", 03303 "dialtime", 03304 "farenddisconnect", 03305 "noct", 03306 "quiet", 03307 NULL 03308 }; 03309 03310 if (!myrpt->enable) 03311 return DC_ERROR; 03312 03313 if(debug) 03314 printf("@@@@ Autopatch up\n"); 03315 03316 if(!myrpt->callmode){ 03317 /* Set defaults */ 03318 myrpt->patchnoct = 0; 03319 myrpt->patchdialtime = 0; 03320 myrpt->patchfarenddisconnect = 0; 03321 myrpt->patchquiet = 0; 03322 ast_copy_string(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT); 03323 03324 if(param){ 03325 /* Process parameter list */ 03326 lparam = ast_strdupa(param); 03327 if(!lparam){ 03328 ast_log(LOG_ERROR,"App_rpt out of memory on line %d\n",__LINE__); 03329 return DC_ERROR; 03330 } 03331 paramlength = finddelim(lparam, paramlist, 20); 03332 for(i = 0; i < paramlength; i++){ 03333 index = matchkeyword(paramlist[i], &value, keywords); 03334 if(value) 03335 value = skipchars(value, "= "); 03336 switch(index){ 03337 03338 case 1: /* context */ 03339 ast_copy_string(myrpt->patchcontext, value, MAXPATCHCONTEXT) ; 03340 break; 03341 03342 case 2: /* dialtime */ 03343 myrpt->patchdialtime = atoi(value); 03344 break; 03345 03346 case 3: /* farenddisconnect */ 03347 myrpt->patchfarenddisconnect = atoi(value); 03348 break; 03349 03350 case 4: /* noct */ 03351 myrpt->patchnoct = atoi(value); 03352 break; 03353 03354 case 5: /* quiet */ 03355 myrpt->patchquiet = atoi(value); 03356 break; 03357 03358 default: 03359 break; 03360 } 03361 } 03362 } 03363 } 03364 03365 rpt_mutex_lock(&myrpt->lock); 03366 03367 /* if on call, force * into current audio stream */ 03368 03369 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)){ 03370 myrpt->mydtmf = myrpt->p.funcchar; 03371 } 03372 if (myrpt->callmode){ 03373 rpt_mutex_unlock(&myrpt->lock); 03374 return DC_COMPLETE; 03375 } 03376 myrpt->callmode = 1; 03377 myrpt->cidx = 0; 03378 myrpt->exten[myrpt->cidx] = 0; 03379 rpt_mutex_unlock(&myrpt->lock); 03380 pthread_attr_init(&attr); 03381 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 03382 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *) myrpt); 03383 pthread_attr_destroy(&attr); 03384 return DC_COMPLETE; 03385 }
static int function_cop | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 3494 of file app_rpt.c.
References ARB_ALPHA, DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, rpt::disgorgetime, rpt::enable, myatoi(), rpt_telemetry(), SOURCE_PHONE, and TEST_TONE.
03495 { 03496 if(!param) 03497 return DC_ERROR; 03498 03499 switch(myatoi(param)){ 03500 case 1: /* System reset */ 03501 system("killall -9 asterisk"); /* FIXME to drastic? */ 03502 return DC_COMPLETE; 03503 03504 case 2: 03505 myrpt->enable = 1; 03506 rpt_telemetry(myrpt, ARB_ALPHA, (void *) "RPTENA"); 03507 return DC_COMPLETE; 03508 03509 case 3: 03510 myrpt->enable = 0; 03511 return DC_COMPLETE; 03512 03513 case 4: /* test tone on */ 03514 rpt_telemetry(myrpt, TEST_TONE, NULL); 03515 return DC_COMPLETE; 03516 03517 case 5: /* Disgorge variables to log for debug purposes */ 03518 myrpt->disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 03519 return DC_COMPLETE; 03520 03521 case 6: /* Simulate COR being activated (phone only) */ 03522 if (command_source != SOURCE_PHONE) return DC_INDETERMINATE; 03523 return DC_DOKEY; 03524 03525 } 03526 return DC_INDETERMINATE; 03527 }
static int function_ilink | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 2922 of file app_rpt.c.
References ast_call(), AST_FORMAT_SLINEAR, AST_FRAME_TEXT, ast_hangup(), ast_log(), ast_request(), ast_safe_sleep(), ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_true(), ast_variable_retrieve(), ast_verbose(), ast_write(), rpt::cfg, rpt_link::chan, rpt::cmdnode, COMPLETE, rpt::conf, CONNFAIL, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt_link::disced, rpt::enable, ast_frame::frametype, free, rpt::lastlinknode, LASTNODEKEY, rpt::links, rpt::lock, LOG_WARNING, rpt::longestnode, malloc, ast_frame::mallocd, MAX_RETRIES, MAXNODESTR, rpt_link::mode, myatoi(), rpt::name, rpt_link::name, rpt_link::next, rpt::nodes, ast_frame::offset, option_verbose, rpt::p, rpt_link::reconnects, REMALREADY, REMGO, rpt_link::retries, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), s, ast_frame::samples, SOURCE_DPHONE, SOURCE_PHONE, SOURCE_RPT, STATUS, strdup, strsep(), ast_frame::subclass, and VERBOSE_PREFIX_3.
02923 { 02924 02925 const char *val; 02926 char *s, *s1, *s2, *tele; 02927 char tmp[300], deststr[300] = "",modechange = 0; 02928 char digitbuf[MAXNODESTR]; 02929 struct rpt_link *l; 02930 int reconnects = 0; 02931 ZT_CONFINFO ci; /* conference info */ 02932 02933 if(!param) 02934 return DC_ERROR; 02935 02936 02937 if (!myrpt->enable) 02938 return DC_ERROR; 02939 02940 ast_copy_string(digitbuf,digits,MAXNODESTR); 02941 02942 if(debug) 02943 printf("@@@@ ilink param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 02944 02945 switch(myatoi(param)){ 02946 case 1: /* Link off */ 02947 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 02948 strcpy(digitbuf,myrpt->lastlinknode); 02949 val = ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf); 02950 if (!val){ 02951 if(strlen(digitbuf) >= myrpt->longestnode) 02952 return DC_ERROR; 02953 break; 02954 } 02955 ast_copy_string(tmp,val,sizeof(tmp)); 02956 s = tmp; 02957 s1 = strsep(&s,","); 02958 s2 = strsep(&s,","); 02959 rpt_mutex_lock(&myrpt->lock); 02960 l = myrpt->links.next; 02961 /* try to find this one in queue */ 02962 while(l != &myrpt->links){ 02963 if (l->name[0] == '0') 02964 { 02965 l = l->next; 02966 continue; 02967 } 02968 /* if found matching string */ 02969 if (!strcmp(l->name, digitbuf)) 02970 break; 02971 l = l->next; 02972 } 02973 if (l != &myrpt->links){ /* if found */ 02974 struct ast_frame wf; 02975 ast_copy_string(myrpt->lastlinknode,digitbuf,MAXNODESTR); 02976 l->retries = MAX_RETRIES + 1; 02977 l->disced = 1; 02978 rpt_mutex_unlock(&myrpt->lock); 02979 wf.frametype = AST_FRAME_TEXT; 02980 wf.subclass = 0; 02981 wf.offset = 0; 02982 wf.mallocd = 1; 02983 wf.datalen = strlen(discstr) + 1; 02984 wf.samples = 0; 02985 wf.data = strdup(discstr); 02986 if (l->chan) 02987 { 02988 ast_write(l->chan,&wf); 02989 if (ast_safe_sleep(l->chan,250) == -1) return DC_ERROR; 02990 ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 02991 } 02992 rpt_telemetry(myrpt, COMPLETE, NULL); 02993 return DC_COMPLETE; 02994 } 02995 rpt_mutex_unlock(&myrpt->lock); 02996 return DC_COMPLETE; 02997 case 2: /* Link Monitor */ 02998 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 02999 strcpy(digitbuf,myrpt->lastlinknode); 03000 val = ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf); 03001 if (!val){ 03002 if(strlen(digitbuf) >= myrpt->longestnode) 03003 return DC_ERROR; 03004 break; 03005 } 03006 ast_copy_string(tmp, val, sizeof(tmp)); 03007 s = tmp; 03008 s1 = strsep(&s,","); 03009 s2 = strsep(&s,","); 03010 rpt_mutex_lock(&myrpt->lock); 03011 l = myrpt->links.next; 03012 /* try to find this one in queue */ 03013 while(l != &myrpt->links){ 03014 if (l->name[0] == '0') 03015 { 03016 l = l->next; 03017 continue; 03018 } 03019 /* if found matching string */ 03020 if (!strcmp(l->name, digitbuf)) 03021 break; 03022 l = l->next; 03023 } 03024 /* if found */ 03025 if (l != &myrpt->links) 03026 { 03027 /* if already in this mode, just ignore */ 03028 if ((!l->mode) || (!l->chan)) { 03029 rpt_mutex_unlock(&myrpt->lock); 03030 rpt_telemetry(myrpt,REMALREADY,NULL); 03031 return DC_COMPLETE; 03032 03033 } 03034 reconnects = l->reconnects; 03035 rpt_mutex_unlock(&myrpt->lock); 03036 if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 03037 l->retries = MAX_RETRIES + 1; 03038 l->disced = 2; 03039 modechange = 1; 03040 } else 03041 rpt_mutex_unlock(&myrpt->lock); 03042 ast_copy_string(myrpt->lastlinknode,digitbuf,MAXNODESTR); 03043 /* establish call in monitor mode */ 03044 l = malloc(sizeof(struct rpt_link)); 03045 if (!l){ 03046 ast_log(LOG_WARNING, "Unable to malloc\n"); 03047 return DC_ERROR; 03048 } 03049 /* zero the silly thing */ 03050 memset((char *)l,0,sizeof(struct rpt_link)); 03051 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 03052 tele = strchr(deststr,'/'); 03053 if (!tele){ 03054 fprintf(stderr,"link2:Dial number (%s) must be in format tech/number\n",deststr); 03055 return DC_ERROR; 03056 } 03057 *tele++ = 0; 03058 l->isremote = (s && ast_true(s)); 03059 ast_copy_string(l->name, digitbuf, MAXNODESTR); 03060 l->chan = ast_request(deststr,AST_FORMAT_SLINEAR,tele,NULL); 03061 if (modechange) l->connected = 1; 03062 if (l->chan){ 03063 ast_set_read_format(l->chan,AST_FORMAT_SLINEAR); 03064 ast_set_write_format(l->chan,AST_FORMAT_SLINEAR); 03065 l->chan->whentohangup = 0; 03066 l->chan->appl = "Apprpt"; 03067 l->chan->data = "(Remote Rx)"; 03068 if (option_verbose > 2) 03069 ast_verbose(VERBOSE_PREFIX_3 "rpt (remote) initiating call to %s/%s on %s\n", 03070 deststr,tele,l->chan->name); 03071 if(l->chan->cid.cid_num) 03072 free(l->chan->cid.cid_num); 03073 l->chan->cid.cid_num = strdup(myrpt->name); 03074 ast_call(l->chan,tele,0); 03075 } 03076 else 03077 { 03078 rpt_telemetry(myrpt,CONNFAIL,l); 03079 free(l); 03080 if (option_verbose > 2) 03081 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 03082 deststr,tele,l->chan->name); 03083 return DC_ERROR; 03084 } 03085 /* allocate a pseudo-channel thru asterisk */ 03086 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 03087 if (!l->pchan){ 03088 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 03089 ast_hangup(l->chan); 03090 free(l); 03091 return DC_ERROR; 03092 } 03093 ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR); 03094 ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR); 03095 /* make a conference for the pseudo-one */ 03096 ci.chan = 0; 03097 ci.confno = myrpt->conf; 03098 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 03099 /* first put the channel on the conference in proper mode */ 03100 if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1) 03101 { 03102 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 03103 ast_hangup(l->chan); 03104 ast_hangup(l->pchan); 03105 free(l); 03106 return DC_ERROR; 03107 } 03108 rpt_mutex_lock(&myrpt->lock); 03109 l->reconnects = reconnects; 03110 /* insert at end of queue */ 03111 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 03112 rpt_mutex_unlock(&myrpt->lock); 03113 rpt_telemetry(myrpt,COMPLETE,NULL); 03114 return DC_COMPLETE; 03115 case 3: /* Link transceive */ 03116 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 03117 strcpy(digitbuf,myrpt->lastlinknode); 03118 val = ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf); 03119 if (!val){ 03120 if(strlen(digitbuf) >= myrpt->longestnode) 03121 return DC_ERROR; 03122 break; 03123 } 03124 ast_copy_string(tmp,val,sizeof(tmp)); 03125 s = tmp; 03126 s1 = strsep(&s,","); 03127 s2 = strsep(&s,","); 03128 rpt_mutex_lock(&myrpt->lock); 03129 l = myrpt->links.next; 03130 /* try to find this one in queue */ 03131 while(l != &myrpt->links){ 03132 if (l->name[0] == '0') 03133 { 03134 l = l->next; 03135 continue; 03136 } 03137 /* if found matching string */ 03138 if (!strcmp(l->name, digitbuf)) 03139 break; 03140 l = l->next; 03141 } 03142 /* if found */ 03143 if (l != &myrpt->links){ 03144 /* if already in this mode, just ignore */ 03145 if ((l->mode) || (!l->chan)) { 03146 rpt_mutex_unlock(&myrpt->lock); 03147 rpt_telemetry(myrpt, REMALREADY, NULL); 03148 return DC_COMPLETE; 03149 } 03150 reconnects = l->reconnects; 03151 rpt_mutex_unlock(&myrpt->lock); 03152 if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV); 03153 l->retries = MAX_RETRIES + 1; 03154 l->disced = 2; 03155 modechange = 1; 03156 } else 03157 rpt_mutex_unlock(&myrpt->lock); 03158 ast_copy_string(myrpt->lastlinknode,digitbuf,MAXNODESTR); 03159 /* establish call in tranceive mode */ 03160 l = malloc(sizeof(struct rpt_link)); 03161 if (!l){ 03162 ast_log(LOG_WARNING, "Unable to malloc\n"); 03163 return(DC_ERROR); 03164 } 03165 /* zero the silly thing */ 03166 memset((char *)l,0,sizeof(struct rpt_link)); 03167 l->mode = 1; 03168 l->outbound = 1; 03169 ast_copy_string(l->name, digitbuf, MAXNODESTR); 03170 l->isremote = (s && ast_true(s)); 03171 if (modechange) l->connected = 1; 03172 snprintf(deststr, sizeof(deststr), "IAX2/%s", s1); 03173 tele = strchr(deststr, '/'); 03174 if (!tele){ 03175 fprintf(stderr,"link3:Dial number (%s) must be in format tech/number\n",deststr); 03176 free(l); 03177 return DC_ERROR; 03178 } 03179 *tele++ = 0; 03180 l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, tele,NULL); 03181 if (l->chan){ 03182 ast_set_read_format(l->chan, AST_FORMAT_SLINEAR); 03183 ast_set_write_format(l->chan, AST_FORMAT_SLINEAR); 03184 l->chan->whentohangup = 0; 03185 l->chan->appl = "Apprpt"; 03186 l->chan->data = "(Remote Rx)"; 03187 if (option_verbose > 2) 03188 ast_verbose(VERBOSE_PREFIX_3 "rpt (remote) initiating call to %s/%s on %s\n", 03189 deststr, tele, l->chan->name); 03190 if(l->chan->cid.cid_num) 03191 free(l->chan->cid.cid_num); 03192 l->chan->cid.cid_num = strdup(myrpt->name); 03193 ast_call(l->chan,tele,999); 03194 } 03195 else{ 03196 rpt_telemetry(myrpt,CONNFAIL,l); 03197 free(l); 03198 if (option_verbose > 2) 03199 ast_verbose(VERBOSE_PREFIX_3 "Unable to place call to %s/%s on %s\n", 03200 deststr,tele,l->chan->name); 03201 return DC_ERROR; 03202 } 03203 /* allocate a pseudo-channel thru asterisk */ 03204 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 03205 if (!l->pchan){ 03206 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 03207 ast_hangup(l->chan); 03208 free(l); 03209 return DC_ERROR; 03210 } 03211 ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR); 03212 ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR); 03213 /* make a conference for the tx */ 03214 ci.chan = 0; 03215 ci.confno = myrpt->conf; 03216 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 03217 /* first put the channel on the conference in proper mode */ 03218 if (ioctl(l->pchan->fds[0], ZT_SETCONF, &ci) == -1) 03219 { 03220 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 03221 ast_hangup(l->chan); 03222 ast_hangup(l->pchan); 03223 free(l); 03224 return DC_ERROR; 03225 } 03226 rpt_mutex_lock(&myrpt->lock); 03227 l->reconnects = reconnects; 03228 /* insert at end of queue */ 03229 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 03230 rpt_mutex_unlock(&myrpt->lock); 03231 rpt_telemetry(myrpt,COMPLETE,NULL); 03232 return DC_COMPLETE; 03233 case 4: /* Enter Command Mode */ 03234 03235 /* if doesnt allow link cmd, or no links active, return */ 03236 if (((command_source != SOURCE_RPT) && (command_source != SOURCE_PHONE) && (command_source != SOURCE_DPHONE)) || (myrpt->links.next == &myrpt->links)) 03237 return DC_COMPLETE; 03238 03239 /* if already in cmd mode, or selected self, fughetabahtit */ 03240 if ((myrpt->cmdnode[0]) || (!strcmp(myrpt->name, digitbuf))){ 03241 03242 rpt_telemetry(myrpt, REMALREADY, NULL); 03243 return DC_COMPLETE; 03244 } 03245 if ((digitbuf[0] == '0') && (myrpt->lastlinknode[0])) 03246 strcpy(digitbuf,myrpt->lastlinknode); 03247 /* node must at least exist in list */ 03248 val = ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, digitbuf); 03249 if (!val){ 03250 if(strlen(digitbuf) >= myrpt->longestnode) 03251 return DC_ERROR; 03252 break; 03253 03254 } 03255 rpt_mutex_lock(&myrpt->lock); 03256 strcpy(myrpt->lastlinknode,digitbuf); 03257 ast_copy_string(myrpt->cmdnode, digitbuf, sizeof(myrpt->cmdnode)); 03258 rpt_mutex_unlock(&myrpt->lock); 03259 rpt_telemetry(myrpt, REMGO, NULL); 03260 return DC_COMPLETE; 03261 03262 case 5: /* Status */ 03263 rpt_telemetry(myrpt, STATUS, NULL); 03264 return DC_COMPLETE; 03265 03266 03267 case 6: /* All Links Off */ 03268 l = myrpt->links.next; 03269 03270 while(l != &myrpt->links){ /* This code is broke and needs to be changed to work with the reconnect kludge */ 03271 if (l->chan) ast_softhangup(l->chan, AST_SOFTHANGUP_DEV); /* Hang 'em up */ 03272 l = l->next; 03273 } 03274 rpt_telemetry(myrpt, COMPLETE, NULL); 03275 break; 03276 03277 case 7: /* Identify last node which keyed us up */ 03278 rpt_telemetry(myrpt, LASTNODEKEY, NULL); 03279 break; 03280 03281 default: 03282 return DC_ERROR; 03283 03284 } 03285 03286 return DC_INDETERMINATE; 03287 }
static int function_macro | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 3447 of file app_rpt.c.
References ast_variable_retrieve(), rpt::cfg, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt::enable, rpt::lock, rpt::macro, MACRO_BUSY, MACRO_NOTFOUND, rpt::macrobuf, MACROTIME, rpt::macrotimer, MAXMACRO, rpt::p, rpt::remchannel, rpt::remote, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), and rpt::startupmacro.
03448 { 03449 03450 const char *val; 03451 int i; 03452 struct ast_channel *mychannel; 03453 03454 if ((!myrpt->remote) && (!myrpt->enable)) 03455 return DC_ERROR; 03456 03457 if(debug) 03458 printf("@@@@ macro-oni param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 03459 03460 mychannel = myrpt->remchannel; 03461 03462 if(strlen(digitbuf) < 1) /* needs 1 digit */ 03463 return DC_INDETERMINATE; 03464 03465 for(i = 0 ; i < digitbuf[i] ; i++) { 03466 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 03467 return DC_ERROR; 03468 } 03469 03470 if (*digitbuf == '0') val = myrpt->p.startupmacro; 03471 else val = ast_variable_retrieve(myrpt->cfg, myrpt->p.macro, digitbuf); 03472 /* param was 1 for local buf */ 03473 if (!val){ 03474 rpt_telemetry(myrpt, MACRO_NOTFOUND, NULL); 03475 return DC_COMPLETE; 03476 } 03477 rpt_mutex_lock(&myrpt->lock); 03478 if ((MAXMACRO - strlen(myrpt->macrobuf)) < strlen(val)) 03479 { 03480 rpt_mutex_unlock(&myrpt->lock); 03481 rpt_telemetry(myrpt, MACRO_BUSY, NULL); 03482 return DC_ERROR; 03483 } 03484 myrpt->macrotimer = MACROTIME; 03485 strncat(myrpt->macrobuf,val,MAXMACRO - 1); 03486 rpt_mutex_unlock(&myrpt->lock); 03487 return DC_COMPLETE; 03488 }
static int function_remote | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 4919 of file app_rpt.c.
References AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_safe_sleep(), ast_variable_retrieve(), rpt::cfg, check_freq(), DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, 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, MAXREMSTR, rpt::memory, multimode_bump_freq(), multimode_capable(), myatoi(), rpt::name, rpt::offset, offset, rpt::p, rpt::powerlevel, REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, REM_PLUS, REM_SCANTIME, REM_SIMPLEX, rpt::remchannel, rpt::remmode, rpt::remoterx, rpt::remotetx, rmt_saycharstr(), rmt_sayfile(), rmt_telem_finish(), rmt_telem_start(), rpt::rxpl, rpt::rxplon, s, saycharstr(), sayfile(), saynum(), rpt::scantimer, setrem(), SOURCE_LNK, SOURCE_RPT, split_freq(), strsep(), rpt::tunerequest, rpt::txchannel, rpt::txpl, and rpt::txplon.
04920 { 04921 char *s,*s1,*s2; 04922 const char *val; 04923 int i,j,ht,k,l,ls2,m,d,res,offset,offsave, modesave, defmode; 04924 char multimode = 0; 04925 char oc; 04926 char tmp[20], freq[20] = "", savestr[20] = ""; 04927 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 04928 struct ast_channel *mychannel; 04929 04930 if((!param) || (command_source == SOURCE_RPT) || (command_source == SOURCE_LNK)) 04931 return DC_ERROR; 04932 04933 multimode = multimode_capable(myrpt); 04934 04935 mychannel = myrpt->remchannel; 04936 04937 04938 switch(myatoi(param)){ 04939 04940 case 1: /* retrieve memory */ 04941 if(strlen(digitbuf) < 2) /* needs 2 digits */ 04942 break; 04943 04944 for(i = 0 ; i < 2 ; i++){ 04945 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 04946 return DC_ERROR; 04947 } 04948 04949 val = ast_variable_retrieve(myrpt->cfg, myrpt->p.memory, digitbuf); 04950 if (!val){ 04951 if (ast_safe_sleep(mychannel,1000) == -1) 04952 return DC_ERROR; 04953 sayfile(mychannel,"rpt/memory_notfound"); 04954 return DC_COMPLETE; 04955 } 04956 ast_copy_string(tmp, val, sizeof(tmp)); 04957 s = strchr(tmp,','); 04958 if (!s) 04959 return DC_ERROR; 04960 *s++ = 0; 04961 s1 = strchr(s,','); 04962 if (!s1) 04963 return DC_ERROR; 04964 *s1++ = 0; 04965 ast_copy_string(myrpt->freq, tmp, sizeof(myrpt->freq)); 04966 ast_copy_string(myrpt->rxpl, s, sizeof(myrpt->rxpl)); 04967 ast_copy_string(myrpt->txpl, s, sizeof(myrpt->rxpl)); 04968 myrpt->remmode = REM_MODE_FM; 04969 myrpt->offset = REM_SIMPLEX; 04970 myrpt->powerlevel = REM_MEDPWR; 04971 myrpt->txplon = myrpt->rxplon = 0; 04972 while(*s1) 04973 { 04974 switch(*s1++){ 04975 case 'A': 04976 case 'a': 04977 strcpy(myrpt->rxpl, "100.0"); 04978 strcpy(myrpt->txpl, "100.0"); 04979 myrpt->remmode = REM_MODE_AM; 04980 break; 04981 04982 case 'B': 04983 case 'b': 04984 strcpy(myrpt->rxpl, "100.0"); 04985 strcpy(myrpt->txpl, "100.0"); 04986 myrpt->remmode = REM_MODE_LSB; 04987 break; 04988 04989 case 'F': 04990 myrpt->remmode = REM_MODE_FM; 04991 break; 04992 04993 case 'L': 04994 case 'l': 04995 myrpt->powerlevel = REM_LOWPWR; 04996 break; 04997 case 'H': 04998 case 'h': 04999 myrpt->powerlevel = REM_HIPWR; 05000 break; 05001 05002 case 'M': 05003 case 'm': 05004 myrpt->powerlevel = REM_MEDPWR; 05005 break; 05006 05007 case '-': 05008 myrpt->offset = REM_MINUS; 05009 break; 05010 05011 case '+': 05012 myrpt->offset = REM_PLUS; 05013 break; 05014 05015 case 'S': 05016 case 's': 05017 myrpt->offset = REM_SIMPLEX; 05018 break; 05019 05020 case 'T': 05021 case 't': 05022 myrpt->txplon = 1; 05023 break; 05024 05025 case 'R': 05026 case 'r': 05027 myrpt->rxplon = 1; 05028 break; 05029 05030 case 'U': 05031 case 'u': 05032 strcpy(myrpt->rxpl, "100.0"); 05033 strcpy(myrpt->txpl, "100.0"); 05034 myrpt->remmode = REM_MODE_USB; 05035 break; 05036 } 05037 } 05038 05039 05040 if (setrem(myrpt) == -1) 05041 return DC_ERROR; 05042 05043 05044 return DC_COMPLETE; 05045 05046 case 2: /* set freq and offset */ 05047 05048 05049 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for M+*K+*O or M+*H+* depending on mode */ 05050 if(digitbuf[i] == '*'){ 05051 j++; 05052 continue; 05053 } 05054 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 05055 goto invalid_freq; 05056 else{ 05057 if(j == 0) 05058 l++; /* # of digits before first * */ 05059 if(j == 1) 05060 k++; /* # of digits after first * */ 05061 } 05062 } 05063 05064 i = strlen(digitbuf) - 1; 05065 if(multimode){ 05066 if((j > 2) || (l > 3) || (k > 6)) 05067 goto invalid_freq; /* &^@#! */ 05068 } 05069 else{ 05070 if((j > 2) || (l > 4) || (k > 3)) 05071 goto invalid_freq; /* &^@#! */ 05072 } 05073 05074 /* Wait for M+*K+* */ 05075 05076 if(j < 2) 05077 break; /* Not yet */ 05078 05079 /* We have a frequency */ 05080 05081 ast_copy_string(tmp, digitbuf ,sizeof(tmp)); 05082 05083 s = tmp; 05084 s1 = strsep(&s, "*"); /* Pick off MHz */ 05085 s2 = strsep(&s,"*"); /* Pick off KHz and Hz */ 05086 ls2 = strlen(s2); 05087 05088 switch(ls2){ /* Allow partial entry of khz and hz digits for laziness support */ 05089 case 1: 05090 ht = 0; 05091 k = 100 * atoi(s2); 05092 break; 05093 05094 case 2: 05095 ht = 0; 05096 k = 10 * atoi(s2); 05097 break; 05098 05099 case 3: 05100 if(!multimode){ 05101 if((s2[2] != '0')&&(s2[2] != '5')) 05102 goto invalid_freq; 05103 } 05104 ht = 0; 05105 k = atoi(s2); 05106 break; 05107 case 4: 05108 k = atoi(s2)/10; 05109 ht = 10 * (atoi(s2+(ls2-1))); 05110 break; 05111 05112 case 5: 05113 k = atoi(s2)/100; 05114 ht = (atoi(s2+(ls2-2))); 05115 break; 05116 05117 default: 05118 goto invalid_freq; 05119 } 05120 05121 /* Check frequency for validity and establish a default mode */ 05122 05123 snprintf(freq, sizeof(freq), "%s.%03d%02d",s1, k, ht); 05124 05125 if(debug) 05126 printf("New frequency: %s\n", freq); 05127 05128 split_freq(mhz, decimals, freq); 05129 m = atoi(mhz); 05130 d = atoi(decimals); 05131 05132 if(check_freq(myrpt, m, d, &defmode)) /* Check to see if frequency entered is legit */ 05133 goto invalid_freq; 05134 05135 05136 if((defmode == REM_MODE_FM) && (digitbuf[i] == '*')) /* If FM, user must enter and additional offset digit */ 05137 break; /* Not yet */ 05138 05139 05140 offset = REM_SIMPLEX; /* Assume simplex */ 05141 05142 if(defmode == REM_MODE_FM){ 05143 oc = *s; /* Pick off offset */ 05144 05145 if (oc){ 05146 switch(oc){ 05147 case '1': 05148 offset = REM_MINUS; 05149 break; 05150 05151 case '2': 05152 offset = REM_SIMPLEX; 05153 break; 05154 05155 case '3': 05156 offset = REM_PLUS; 05157 break; 05158 05159 default: 05160 goto invalid_freq; 05161 } 05162 } 05163 } 05164 offsave = myrpt->offset; 05165 modesave = myrpt->remmode; 05166 ast_copy_string(savestr, myrpt->freq, sizeof(savestr)); 05167 ast_copy_string(myrpt->freq, freq, sizeof(myrpt->freq)); 05168 myrpt->offset = offset; 05169 myrpt->remmode = defmode; 05170 05171 if (setrem(myrpt) == -1){ 05172 myrpt->offset = offsave; 05173 myrpt->remmode = modesave; 05174 ast_copy_string(myrpt->freq, savestr, sizeof(myrpt->freq)); 05175 goto invalid_freq; 05176 } 05177 05178 return DC_COMPLETE; 05179 05180 05181 invalid_freq: 05182 05183 rmt_sayfile(myrpt, mychannel, 1000, "rpt/invalid-freq"); 05184 05185 return DC_ERROR; 05186 05187 case 3: /* set rx PL tone */ 05188 05189 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 05190 if(digitbuf[i] == '*'){ 05191 j++; 05192 continue; 05193 } 05194 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 05195 return DC_ERROR; 05196 else{ 05197 if(j) 05198 l++; 05199 else 05200 k++; 05201 } 05202 } 05203 if((j > 1) || (k > 3) || (l > 1)) 05204 return DC_ERROR; /* &$@^! */ 05205 i = strlen(digitbuf) - 1; 05206 if((j != 1) || (k < 2)|| (l != 1)) 05207 break; /* Not yet */ 05208 if(debug) 05209 printf("PL digits entered %s\n", digitbuf); 05210 05211 ast_copy_string(tmp, digitbuf, sizeof(tmp)); 05212 /* see if we have at least 1 */ 05213 s = strchr(tmp,'*'); 05214 if(s) 05215 *s = '.'; 05216 ast_copy_string(savestr, myrpt->rxpl, sizeof(savestr)); 05217 ast_copy_string(myrpt->rxpl, tmp, sizeof(myrpt->rxpl)); 05218 05219 if (setrem(myrpt) == -1){ 05220 ast_copy_string(myrpt->rxpl, savestr, sizeof(myrpt->rxpl)); 05221 return DC_ERROR; 05222 } 05223 05224 05225 return DC_COMPLETE; 05226 05227 case 4: /* set tx PL tone */ 05228 05229 for(i = 0, j = 0, k = 0, l = 0 ; digitbuf[i] ; i++){ /* look for N+*N */ 05230 if(digitbuf[i] == '*'){ 05231 j++; 05232 continue; 05233 } 05234 if((digitbuf[i] < '0') || (digitbuf[i] > '9')) 05235 return DC_ERROR; 05236 else{ 05237 if(j) 05238 l++; 05239 else 05240 k++; 05241 } 05242 } 05243 if((j > 1) || (k > 3) || (l > 1)) 05244 return DC_ERROR; /* &$@^! */ 05245 i = strlen(digitbuf) - 1; 05246 if((j != 1) || (k < 2)|| (l != 1)) 05247 break; /* Not yet */ 05248 if(debug) 05249 printf("PL digits entered %s\n", digitbuf); 05250 05251 ast_copy_string(tmp, digitbuf, sizeof(tmp)); 05252 /* see if we have at least 1 */ 05253 s = strchr(tmp,'*'); 05254 if(s) 05255 *s = '.'; 05256 ast_copy_string(savestr, myrpt->txpl, sizeof(savestr)); 05257 ast_copy_string(myrpt->txpl, tmp, sizeof(myrpt->txpl)); 05258 05259 if (setrem(myrpt) == -1){ 05260 ast_copy_string(myrpt->txpl, savestr, sizeof(myrpt->txpl) - 1); 05261 return DC_ERROR; 05262 } 05263 05264 05265 return DC_COMPLETE; 05266 05267 05268 case 6: /* MODE (FM,USB,LSB,AM) */ 05269 if(strlen(digitbuf) < 1) 05270 break; 05271 05272 if(!multimode) 05273 return DC_ERROR; /* Multimode radios only */ 05274 05275 switch(*digitbuf){ 05276 case '1': 05277 split_freq(mhz, decimals, myrpt->freq); 05278 m=atoi(mhz); 05279 if(m < 29) /* No FM allowed below 29MHz! */ 05280 return DC_ERROR; 05281 myrpt->remmode = REM_MODE_FM; 05282 res = rmt_saycharstr(myrpt, mychannel, 1000,"FM"); 05283 break; 05284 05285 case '2': 05286 myrpt->remmode = REM_MODE_USB; 05287 res = rmt_saycharstr(myrpt, mychannel, 1000,"USB"); 05288 break; 05289 05290 case '3': 05291 myrpt->remmode = REM_MODE_LSB; 05292 res = rmt_saycharstr(myrpt, mychannel, 1000,"LSB"); 05293 break; 05294 05295 case '4': 05296 myrpt->remmode = REM_MODE_AM; 05297 res = rmt_saycharstr(myrpt, mychannel, 1000,"AM"); 05298 break; 05299 05300 default: 05301 return DC_ERROR; 05302 } 05303 if(res) 05304 return DC_ERROR; 05305 05306 if(setrem(myrpt)) 05307 return DC_ERROR; 05308 return DC_COMPLETE; 05309 05310 case 100: /* other stuff */ 05311 case 101: 05312 case 102: 05313 case 103: 05314 case 104: 05315 case 105: 05316 case 106: 05317 res = rmt_telem_start(myrpt, mychannel, 1000); 05318 switch(myatoi(param)){ /* Quick commands requiring a setrem call */ 05319 case 100: /* RX PL Off */ 05320 myrpt->rxplon = 0; 05321 if(!res) 05322 res = sayfile(mychannel, "rpt/rxpl"); 05323 if(!res) 05324 sayfile(mychannel, "rpt/off"); 05325 break; 05326 05327 case 101: /* RX PL On */ 05328 myrpt->rxplon = 1; 05329 if(!res) 05330 res = sayfile(mychannel, "rpt/rxpl"); 05331 if(!res) 05332 sayfile(mychannel, "rpt/on"); 05333 break; 05334 05335 05336 case 102: /* TX PL Off */ 05337 myrpt->txplon = 0; 05338 if(!res) 05339 res = sayfile(mychannel, "rpt/txpl"); 05340 if(!res) 05341 sayfile(mychannel, "rpt/off"); 05342 break; 05343 05344 case 103: /* TX PL On */ 05345 myrpt->txplon = 1; 05346 if(!res) 05347 res = sayfile(mychannel, "rpt/txpl"); 05348 if(!res) 05349 sayfile(mychannel, "rpt/on"); 05350 break; 05351 05352 case 104: /* Low Power */ 05353 myrpt->powerlevel = REM_LOWPWR; 05354 if(!res) 05355 res = sayfile(mychannel, "rpt/lopwr"); 05356 break; 05357 05358 case 105: /* Medium Power */ 05359 myrpt->powerlevel = REM_MEDPWR; 05360 if(!res) 05361 res = sayfile(mychannel, "rpt/medpwr"); 05362 break; 05363 05364 case 106: /* Hi Power */ 05365 myrpt->powerlevel = REM_HIPWR; 05366 if(!res) 05367 res = sayfile(mychannel, "rpt/hipwr"); 05368 break; 05369 05370 default: 05371 if(!res) 05372 rmt_telem_finish(myrpt, mychannel); 05373 return DC_ERROR; 05374 } 05375 if(!res) 05376 res = rmt_telem_finish(myrpt, mychannel); 05377 if(res) 05378 return DC_ERROR; 05379 05380 if (setrem(myrpt) == -1) 05381 return DC_ERROR; 05382 return DC_COMPLETE; 05383 05384 case 107: /* Bump down 20Hz */ 05385 multimode_bump_freq(myrpt, -20); 05386 return DC_COMPLETE; 05387 05388 case 108: /* Bump down 100Hz */ 05389 multimode_bump_freq(myrpt, -100); 05390 return DC_COMPLETE; 05391 05392 case 109: /* Bump down 500Hz */ 05393 multimode_bump_freq(myrpt, -500); 05394 return DC_COMPLETE; 05395 05396 case 110: /* Bump up 20Hz */ 05397 multimode_bump_freq(myrpt, 20); 05398 return DC_COMPLETE; 05399 05400 case 111: /* Bump up 100Hz */ 05401 multimode_bump_freq(myrpt, 100); 05402 return DC_COMPLETE; 05403 05404 case 112: /* Bump up 500Hz */ 05405 multimode_bump_freq(myrpt, 500); 05406 return DC_COMPLETE; 05407 05408 05409 case 113: 05410 case 114: 05411 case 115: 05412 case 116: 05413 case 117: 05414 case 118: 05415 myrpt->remotetx = 0; 05416 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 05417 if (!myrpt->remoterx) 05418 ast_indicate(mychannel,AST_CONTROL_RADIO_KEY); 05419 if (ast_safe_sleep(mychannel,1000) == -1) 05420 return DC_ERROR; 05421 05422 switch(myatoi(param)){ 05423 05424 case 113: /* Scan down slow */ 05425 res = sayfile(mychannel,"rpt/down"); 05426 if(!res) 05427 res = sayfile(mychannel, "rpt/slow"); 05428 if(!res){ 05429 myrpt->scantimer = REM_SCANTIME; 05430 myrpt->hfscanmode = HF_SCAN_DOWN_SLOW; 05431 } 05432 break; 05433 05434 case 114: /* Scan down quick */ 05435 res = sayfile(mychannel,"rpt/down"); 05436 if(!res) 05437 res = sayfile(mychannel, "rpt/quick"); 05438 if(!res){ 05439 myrpt->scantimer = REM_SCANTIME; 05440 myrpt->hfscanmode = HF_SCAN_DOWN_QUICK; 05441 } 05442 break; 05443 05444 case 115: /* Scan down fast */ 05445 res = sayfile(mychannel,"rpt/down"); 05446 if(!res) 05447 res = sayfile(mychannel, "rpt/fast"); 05448 if(!res){ 05449 myrpt->scantimer = REM_SCANTIME; 05450 myrpt->hfscanmode = HF_SCAN_DOWN_FAST; 05451 } 05452 break; 05453 05454 case 116: /* Scan up slow */ 05455 res = sayfile(mychannel,"rpt/up"); 05456 if(!res) 05457 res = sayfile(mychannel, "rpt/slow"); 05458 if(!res){ 05459 myrpt->scantimer = REM_SCANTIME; 05460 myrpt->hfscanmode = HF_SCAN_UP_SLOW; 05461 } 05462 break; 05463 05464 case 117: /* Scan up quick */ 05465 res = sayfile(mychannel,"rpt/up"); 05466 if(!res) 05467 res = sayfile(mychannel, "rpt/quick"); 05468 if(!res){ 05469 myrpt->scantimer = REM_SCANTIME; 05470 myrpt->hfscanmode = HF_SCAN_UP_QUICK; 05471 } 05472 break; 05473 05474 case 118: /* Scan up fast */ 05475 res = sayfile(mychannel,"rpt/up"); 05476 if(!res) 05477 res = sayfile(mychannel, "rpt/fast"); 05478 if(!res){ 05479 myrpt->scantimer = REM_SCANTIME; 05480 myrpt->hfscanmode = HF_SCAN_UP_FAST; 05481 } 05482 break; 05483 } 05484 rmt_telem_finish(myrpt,mychannel); 05485 return DC_COMPLETE; 05486 05487 05488 case 119: /* Tune Request */ 05489 myrpt->tunerequest = 1; 05490 return DC_COMPLETE; 05491 05492 case 5: /* Long Status */ 05493 case 140: /* Short Status */ 05494 res = rmt_telem_start(myrpt, mychannel, 1000); 05495 05496 res = sayfile(mychannel,"rpt/node"); 05497 if(!res) 05498 res = saycharstr(mychannel, myrpt->name); 05499 if(!res) 05500 res = sayfile(mychannel,"rpt/frequency"); 05501 if(!res) 05502 res = split_freq(mhz, decimals, myrpt->freq); 05503 if(!res){ 05504 m = atoi(mhz); 05505 if(m < 100) 05506 res = saynum(mychannel, m); 05507 else 05508 res = saycharstr(mychannel, mhz); 05509 } 05510 if(!res) 05511 res = sayfile(mychannel, "letters/dot"); 05512 if(!res) 05513 res = saycharstr(mychannel, decimals); 05514 05515 if(res){ 05516 rmt_telem_finish(myrpt,mychannel); 05517 return DC_ERROR; 05518 } 05519 if(myrpt->remmode == REM_MODE_FM){ /* Mode FM? */ 05520 switch(myrpt->offset){ 05521 05522 case REM_MINUS: 05523 res = sayfile(mychannel,"rpt/minus"); 05524 break; 05525 05526 case REM_SIMPLEX: 05527 res = sayfile(mychannel,"rpt/simplex"); 05528 break; 05529 05530 case REM_PLUS: 05531 res = sayfile(mychannel,"rpt/plus"); 05532 break; 05533 05534 default: 05535 return DC_ERROR; 05536 05537 } 05538 } 05539 else{ /* Must be USB, LSB, or AM */ 05540 switch(myrpt->remmode){ 05541 05542 case REM_MODE_USB: 05543 res = saycharstr(mychannel, "USB"); 05544 break; 05545 05546 case REM_MODE_LSB: 05547 res = saycharstr(mychannel, "LSB"); 05548 break; 05549 05550 case REM_MODE_AM: 05551 res = saycharstr(mychannel, "AM"); 05552 break; 05553 05554 05555 default: 05556 return DC_ERROR; 05557 } 05558 } 05559 05560 if (res == -1){ 05561 rmt_telem_finish(myrpt,mychannel); 05562 return DC_ERROR; 05563 } 05564 05565 if(myatoi(param) == 140){ /* Short status? */ 05566 if(!res) 05567 res = rmt_telem_finish(myrpt, mychannel); 05568 if(res) 05569 return DC_ERROR; 05570 return DC_COMPLETE; 05571 } 05572 05573 switch(myrpt->powerlevel){ 05574 05575 case REM_LOWPWR: 05576 res = sayfile(mychannel,"rpt/lopwr") ; 05577 break; 05578 05579 case REM_MEDPWR: 05580 res = sayfile(mychannel,"rpt/medpwr"); 05581 break; 05582 case REM_HIPWR: 05583 res = sayfile(mychannel,"rpt/hipwr"); 05584 break; 05585 } 05586 if (res || (sayfile(mychannel,"rpt/rxpl") == -1) || 05587 (sayfile(mychannel,"rpt/frequency") == -1) || 05588 (saycharstr(mychannel,myrpt->rxpl) == -1) || 05589 (sayfile(mychannel,"rpt/txpl") == -1) || 05590 (sayfile(mychannel,"rpt/frequency") == -1) || 05591 (saycharstr(mychannel,myrpt->txpl) == -1) || 05592 (sayfile(mychannel,"rpt/txpl") == -1) || 05593 (sayfile(mychannel,((myrpt->txplon) ? "rpt/on" : "rpt/off")) == -1) || 05594 (sayfile(mychannel,"rpt/rxpl") == -1) || 05595 (sayfile(mychannel,((myrpt->rxplon) ? "rpt/on" : "rpt/off")) == -1)) 05596 { 05597 rmt_telem_finish(myrpt,mychannel); 05598 return DC_ERROR; 05599 } 05600 if(!res) 05601 res = rmt_telem_finish(myrpt,mychannel); 05602 if(res) 05603 return DC_ERROR; 05604 05605 return DC_COMPLETE; 05606 default: 05607 return DC_ERROR; 05608 } 05609 05610 return DC_INDETERMINATE; 05611 }
static int function_status | ( | struct rpt * | myrpt, | |
char * | param, | |||
char * | digitbuf, | |||
int | command_source, | |||
struct rpt_link * | mylink | |||
) | [static] |
Definition at line 3416 of file app_rpt.c.
References DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, rpt::enable, ID1, myatoi(), rpt_telemetry(), STATS_TIME, and STATS_VERSION.
03417 { 03418 03419 if (!param) 03420 return DC_ERROR; 03421 03422 if (!myrpt->enable) 03423 return DC_ERROR; 03424 03425 if(debug) 03426 printf("@@@@ status param = %s, digitbuf = %s\n", (param)? param : "(null)", digitbuf); 03427 03428 switch(myatoi(param)){ 03429 case 1: /* System ID */ 03430 rpt_telemetry(myrpt, ID1, NULL); 03431 return DC_COMPLETE; 03432 case 2: /* System Time */ 03433 rpt_telemetry(myrpt, STATS_TIME, NULL); 03434 return DC_COMPLETE; 03435 case 3: /* app_rpt.c version */ 03436 rpt_telemetry(myrpt, STATS_VERSION, NULL); 03437 default: 03438 return DC_ERROR; 03439 } 03440 return DC_INDETERMINATE; 03441 }
static int get_wait_interval | ( | struct rpt * | myrpt, | |
int | type | |||
) | [static] |
Definition at line 1882 of file app_rpt.c.
References ast_log(), ast_strdupa, ast_variable_retrieve(), rpt::cfg, DLY_CALLTERM, DLY_ID, DLY_TELEM, DLY_UNKEY, LOG_WARNING, rpt::name, and retrieve_astcfgint().
Referenced by rpt_tele_thread(), and wait_interval().
01883 { 01884 int interval; 01885 const char *wait_times; 01886 char *wait_times_save = NULL; 01887 01888 wait_times = ast_variable_retrieve(myrpt->cfg, myrpt->name, "wait_times"); 01889 01890 if (wait_times) { 01891 wait_times_save = ast_strdupa(wait_times); 01892 if (!wait_times_save) { 01893 ast_log(LOG_WARNING, "Out of memory in wait_interval()\n"); 01894 wait_times = NULL; 01895 } 01896 } 01897 01898 switch (type) { 01899 case DLY_TELEM: 01900 if (wait_times) 01901 interval = retrieve_astcfgint(myrpt, wait_times_save, "telemwait", 500, 5000, 1000); 01902 else 01903 interval = 1000; 01904 break; 01905 01906 case DLY_ID: 01907 if (wait_times) 01908 interval = retrieve_astcfgint(myrpt, wait_times_save, "idwait", 250, 5000, 500); 01909 else 01910 interval = 500; 01911 break; 01912 01913 case DLY_UNKEY: 01914 if (wait_times) 01915 interval = retrieve_astcfgint(myrpt, wait_times_save, "unkeywait", 500, 5000, 1000); 01916 else 01917 interval = 1000; 01918 break; 01919 01920 case DLY_CALLTERM: 01921 if (wait_times) 01922 interval = retrieve_astcfgint(myrpt, wait_times_save, "calltermwait", 500, 5000, 1500); 01923 else 01924 interval = 1500; 01925 break; 01926 01927 default: 01928 return 0; 01929 } 01930 return interval; 01931 }
Definition at line 3608 of file app_rpt.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_TEXT, ast_log(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_write(), rpt::callmode, rpt_link::chan, rpt::cidx, collect_function_digits(), rpt::dailyexecdcommands, ast_frame::data, ast_frame::datalen, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt_link::disced, rpt::endchar, rpt::exten, ast_frame::frametype, rpt::funcchar, rpt::lastdtmfcommand, rpt::links, rpt::lock, LOG_WARNING, ast_frame::mallocd, MAX_RETRIES, MAXDTMF, rpt::mydtmf, rpt_link::name, rpt::name, rpt_link::next, ast_frame::offset, rpt::p, rpt::patchcontext, rpt::patchquiet, rpt::pchannel, PROC, 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, strdup, ast_frame::subclass, and rpt::totalexecdcommands.
Referenced by rpt().
03610 { 03611 char tmp[300],cmd[300] = "",dest[300],src[300],c; 03612 int seq, res; 03613 struct rpt_link *l; 03614 struct ast_frame wf; 03615 03616 wf.frametype = AST_FRAME_TEXT; 03617 wf.subclass = 0; 03618 wf.offset = 0; 03619 wf.mallocd = 1; 03620 wf.datalen = strlen(str) + 1; 03621 wf.samples = 0; 03622 /* put string in our buffer */ 03623 ast_copy_string(tmp, str, sizeof(tmp)); 03624 03625 if (!strcmp(tmp,discstr)) 03626 { 03627 mylink->disced = 1; 03628 mylink->retries = MAX_RETRIES + 1; 03629 ast_softhangup(mylink->chan,AST_SOFTHANGUP_DEV); 03630 return; 03631 } 03632 if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5) 03633 { 03634 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 03635 return; 03636 } 03637 if (strcmp(cmd,"D")) 03638 { 03639 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 03640 return; 03641 } 03642 03643 if (dest[0] == '0') 03644 { 03645 strcpy(dest,myrpt->name); 03646 } 03647 03648 /* if not for me, redistribute to all links */ 03649 if (strcmp(dest,myrpt->name)) 03650 { 03651 l = myrpt->links.next; 03652 /* see if this is one in list */ 03653 while(l != &myrpt->links) 03654 { 03655 if (l->name[0] == '0') 03656 { 03657 l = l->next; 03658 continue; 03659 } 03660 /* dont send back from where it came */ 03661 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 03662 { 03663 l = l->next; 03664 continue; 03665 } 03666 /* if it is, send it and we're done */ 03667 if (!strcmp(l->name,dest)) 03668 { 03669 /* send, but not to src */ 03670 if (strcmp(l->name,src)) { 03671 wf.data = strdup(str); 03672 if (l->chan) ast_write(l->chan,&wf); 03673 } 03674 return; 03675 } 03676 l = l->next; 03677 } 03678 l = myrpt->links.next; 03679 /* otherwise, send it to all of em */ 03680 while(l != &myrpt->links) 03681 { 03682 if (l->name[0] == '0') 03683 { 03684 l = l->next; 03685 continue; 03686 } 03687 /* dont send back from where it came */ 03688 if ((l == mylink) || (!strcmp(l->name,mylink->name))) 03689 { 03690 l = l->next; 03691 continue; 03692 } 03693 /* send, but not to src */ 03694 if (strcmp(l->name,src)) { 03695 wf.data = strdup(str); 03696 if (l->chan) ast_write(l->chan,&wf); 03697 } 03698 l = l->next; 03699 } 03700 return; 03701 } 03702 rpt_mutex_lock(&myrpt->lock); 03703 if (c == myrpt->p.endchar) myrpt->stopgen = 1; 03704 if (myrpt->callmode == 1) 03705 { 03706 myrpt->exten[myrpt->cidx++] = c; 03707 myrpt->exten[myrpt->cidx] = 0; 03708 /* if this exists */ 03709 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 03710 { 03711 myrpt->callmode = 2; 03712 if(!myrpt->patchquiet){ 03713 rpt_mutex_unlock(&myrpt->lock); 03714 rpt_telemetry(myrpt,PROC,NULL); 03715 rpt_mutex_lock(&myrpt->lock); 03716 } 03717 } 03718 /* if can continue, do so */ 03719 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 03720 { 03721 /* call has failed, inform user */ 03722 myrpt->callmode = 4; 03723 } 03724 } 03725 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 03726 { 03727 myrpt->mydtmf = c; 03728 } 03729 if (c == myrpt->p.funcchar) 03730 { 03731 myrpt->rem_dtmfidx = 0; 03732 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 03733 time(&myrpt->rem_dtmf_time); 03734 rpt_mutex_unlock(&myrpt->lock); 03735 return; 03736 } 03737 else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0)) 03738 { 03739 time(&myrpt->rem_dtmf_time); 03740 if (myrpt->rem_dtmfidx < MAXDTMF) 03741 { 03742 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 03743 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 03744 03745 rpt_mutex_unlock(&myrpt->lock); 03746 ast_copy_string(cmd, myrpt->rem_dtmfbuf, sizeof(cmd)); 03747 res = collect_function_digits(myrpt, cmd, SOURCE_LNK, mylink); 03748 rpt_mutex_lock(&myrpt->lock); 03749 03750 switch(res){ 03751 03752 case DC_INDETERMINATE: 03753 break; 03754 03755 case DC_REQ_FLUSH: 03756 myrpt->rem_dtmfidx = 0; 03757 myrpt->rem_dtmfbuf[0] = 0; 03758 break; 03759 03760 03761 case DC_COMPLETE: 03762 myrpt->totalexecdcommands++; 03763 myrpt->dailyexecdcommands++; 03764 ast_copy_string(myrpt->lastdtmfcommand, cmd, MAXDTMF); 03765 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 03766 myrpt->rem_dtmfbuf[0] = 0; 03767 myrpt->rem_dtmfidx = -1; 03768 myrpt->rem_dtmf_time = 0; 03769 break; 03770 03771 case DC_ERROR: 03772 default: 03773 myrpt->rem_dtmfbuf[0] = 0; 03774 myrpt->rem_dtmfidx = -1; 03775 myrpt->rem_dtmf_time = 0; 03776 break; 03777 } 03778 } 03779 03780 } 03781 rpt_mutex_unlock(&myrpt->lock); 03782 return; 03783 }
static void handle_link_phone_dtmf | ( | struct rpt * | myrpt, | |
struct rpt_link * | mylink, | |||
char | c | |||
) | [static] |
Definition at line 3785 of file app_rpt.c.
References ast_canmatch_extension(), ast_exists_extension(), rpt::callmode, rpt::cidx, rpt::cmdnode, collect_function_digits(), COMPLETE, rpt::dailyexecdcommands, DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt::dtmfbuf, rpt::dtmfidx, rpt::endchar, rpt::exten, rpt::funcchar, rpt::lastdtmfcommand, rpt_link::lastrx, rpt::lock, MAXDTMF, rpt::mydtmf, rpt::p, rpt::patchcontext, rpt::patchquiet, rpt::pchannel, rpt_link::phonemode, PROC, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), send_link_dtmf(), SOURCE_DPHONE, SOURCE_LNK, SOURCE_PHONE, rpt::stopgen, and rpt::totalexecdcommands.
Referenced by rpt().
03787 { 03788 03789 char cmd[300]; 03790 int res; 03791 03792 rpt_mutex_lock(&myrpt->lock); 03793 if (c == myrpt->p.endchar) 03794 { 03795 if (mylink->lastrx) 03796 { 03797 mylink->lastrx = 0; 03798 rpt_mutex_unlock(&myrpt->lock); 03799 return; 03800 } 03801 myrpt->stopgen = 1; 03802 if (myrpt->cmdnode[0]) 03803 { 03804 myrpt->cmdnode[0] = 0; 03805 myrpt->dtmfidx = -1; 03806 myrpt->dtmfbuf[0] = 0; 03807 rpt_mutex_unlock(&myrpt->lock); 03808 rpt_telemetry(myrpt,COMPLETE,NULL); 03809 return; 03810 } 03811 } 03812 if (myrpt->cmdnode[0]) 03813 { 03814 rpt_mutex_unlock(&myrpt->lock); 03815 send_link_dtmf(myrpt,c); 03816 return; 03817 } 03818 if (myrpt->callmode == 1) 03819 { 03820 myrpt->exten[myrpt->cidx++] = c; 03821 myrpt->exten[myrpt->cidx] = 0; 03822 /* if this exists */ 03823 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 03824 { 03825 myrpt->callmode = 2; 03826 if(!myrpt->patchquiet){ 03827 rpt_mutex_unlock(&myrpt->lock); 03828 rpt_telemetry(myrpt,PROC,NULL); 03829 rpt_mutex_lock(&myrpt->lock); 03830 } 03831 } 03832 /* if can continue, do so */ 03833 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 03834 { 03835 /* call has failed, inform user */ 03836 myrpt->callmode = 4; 03837 } 03838 } 03839 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 03840 { 03841 myrpt->mydtmf = c; 03842 } 03843 if (c == myrpt->p.funcchar) 03844 { 03845 myrpt->rem_dtmfidx = 0; 03846 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 03847 time(&myrpt->rem_dtmf_time); 03848 rpt_mutex_unlock(&myrpt->lock); 03849 return; 03850 } 03851 else if ((c != myrpt->p.endchar) && (myrpt->rem_dtmfidx >= 0)) 03852 { 03853 time(&myrpt->rem_dtmf_time); 03854 if (myrpt->rem_dtmfidx < MAXDTMF) 03855 { 03856 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx++] = c; 03857 myrpt->rem_dtmfbuf[myrpt->rem_dtmfidx] = 0; 03858 03859 rpt_mutex_unlock(&myrpt->lock); 03860 ast_copy_string(cmd, myrpt->rem_dtmfbuf, sizeof(cmd)); 03861 switch(mylink->phonemode) 03862 { 03863 case 1: 03864 res = collect_function_digits(myrpt, cmd, 03865 SOURCE_PHONE, mylink); 03866 break; 03867 case 2: 03868 res = collect_function_digits(myrpt, cmd, 03869 SOURCE_DPHONE,mylink); 03870 break; 03871 default: 03872 res = collect_function_digits(myrpt, cmd, 03873 SOURCE_LNK, mylink); 03874 break; 03875 } 03876 03877 rpt_mutex_lock(&myrpt->lock); 03878 03879 switch(res){ 03880 03881 case DC_INDETERMINATE: 03882 break; 03883 03884 case DC_DOKEY: 03885 mylink->lastrx = 1; 03886 break; 03887 03888 case DC_REQ_FLUSH: 03889 myrpt->rem_dtmfidx = 0; 03890 myrpt->rem_dtmfbuf[0] = 0; 03891 break; 03892 03893 03894 case DC_COMPLETE: 03895 myrpt->totalexecdcommands++; 03896 myrpt->dailyexecdcommands++; 03897 ast_copy_string(myrpt->lastdtmfcommand, cmd, MAXDTMF); 03898 myrpt->lastdtmfcommand[MAXDTMF-1] = '\0'; 03899 myrpt->rem_dtmfbuf[0] = 0; 03900 myrpt->rem_dtmfidx = -1; 03901 myrpt->rem_dtmf_time = 0; 03902 break; 03903 03904 case DC_ERROR: 03905 default: 03906 myrpt->rem_dtmfbuf[0] = 0; 03907 myrpt->rem_dtmfidx = -1; 03908 myrpt->rem_dtmf_time = 0; 03909 break; 03910 } 03911 } 03912 03913 } 03914 rpt_mutex_unlock(&myrpt->lock); 03915 return; 03916 }
static int handle_remote_data | ( | struct rpt * | myrpt, | |
char * | str | |||
) | [static] |
Definition at line 5711 of file app_rpt.c.
References AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_log(), ast_safe_sleep(), handle_remote_dtmf_digit(), LOG_WARNING, rpt::name, rpt::remchannel, rpt::remoterx, rpt::remotetx, rmt_telem_finish(), seq, telem_lookup(), and rpt::txchannel.
05712 { 05713 char tmp[300],cmd[300],dest[300],src[300],c; 05714 int seq,res; 05715 05716 /* put string in our buffer */ 05717 ast_copy_string(tmp,str,sizeof(tmp)); 05718 if (!strcmp(tmp,discstr)) return 0; 05719 if (sscanf(tmp,"%s %s %s %d %c",cmd,dest,src,&seq,&c) != 5) 05720 { 05721 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 05722 return 0; 05723 } 05724 if (strcmp(cmd,"D")) 05725 { 05726 ast_log(LOG_WARNING, "Unable to parse link string %s\n",str); 05727 return 0; 05728 } 05729 /* if not for me, ignore */ 05730 if (strcmp(dest,myrpt->name)) return 0; 05731 res = handle_remote_dtmf_digit(myrpt,c, NULL, 0); 05732 if (res != 1) 05733 return res; 05734 myrpt->remotetx = 0; 05735 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 05736 if (!myrpt->remoterx) 05737 { 05738 ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_KEY); 05739 } 05740 if (ast_safe_sleep(myrpt->remchannel,1000) == -1) return -1; 05741 res = telem_lookup(myrpt,myrpt->remchannel, myrpt->name, "functcomplete"); 05742 rmt_telem_finish(myrpt,myrpt->remchannel); 05743 return res; 05744 }
static int handle_remote_dtmf_digit | ( | struct rpt * | myrpt, | |
char | c, | |||
char * | keyed, | |||
int | phonemode | |||
) | [static] |
Definition at line 5613 of file app_rpt.c.
References collect_function_digits(), rpt::dailyexecdcommands, DC_COMPLETE, DC_DOKEY, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt::dtmf_time_rem, DTMF_TIMEOUT, rpt::dtmfbuf, rpt::dtmfidx, rpt::funcchar, rpt::hfscanmode, rpt::lastdtmfcommand, MAXDTMF, rpt::p, SOURCE_DPHONE, SOURCE_PHONE, SOURCE_RMT, stop_scan(), and rpt::totalexecdcommands.
Referenced by handle_remote_data(), and handle_remote_phone_dtmf().
05614 { 05615 time_t now; 05616 int ret,res = 0,src; 05617 05618 /* Stop scan mode if in scan mode */ 05619 if(myrpt->hfscanmode){ 05620 stop_scan(myrpt,0); 05621 return 0; 05622 } 05623 05624 time(&now); 05625 /* if timed-out */ 05626 if ((myrpt->dtmf_time_rem + DTMF_TIMEOUT) < now) 05627 { 05628 myrpt->dtmfidx = -1; 05629 myrpt->dtmfbuf[0] = 0; 05630 myrpt->dtmf_time_rem = 0; 05631 } 05632 /* if decode not active */ 05633 if (myrpt->dtmfidx == -1) 05634 { 05635 /* if not lead-in digit, dont worry */ 05636 if (c != myrpt->p.funcchar) return 0; 05637 myrpt->dtmfidx = 0; 05638 myrpt->dtmfbuf[0] = 0; 05639 myrpt->dtmf_time_rem = now; 05640 return 0; 05641 } 05642 /* if too many in buffer, start over */ 05643 if (myrpt->dtmfidx >= MAXDTMF) 05644 { 05645 myrpt->dtmfidx = 0; 05646 myrpt->dtmfbuf[0] = 0; 05647 myrpt->dtmf_time_rem = now; 05648 } 05649 if (c == myrpt->p.funcchar) 05650 { 05651 /* if star at beginning, or 2 together, erase buffer */ 05652 if ((myrpt->dtmfidx < 1) || 05653 (myrpt->dtmfbuf[myrpt->dtmfidx - 1] == myrpt->p.funcchar)) 05654 { 05655 myrpt->dtmfidx = 0; 05656 myrpt->dtmfbuf[0] = 0; 05657 myrpt->dtmf_time_rem = now; 05658 return 0; 05659 } 05660 } 05661 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 05662 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 05663 myrpt->dtmf_time_rem = now; 05664 05665 05666 src = SOURCE_RMT; 05667 if (phonemode > 1) src = SOURCE_DPHONE; 05668 else if (phonemode) src = SOURCE_PHONE; 05669 ret = collect_function_digits(myrpt, myrpt->dtmfbuf, src, NULL); 05670 05671 switch(ret){ 05672 05673 case DC_INDETERMINATE: 05674 res = 0; 05675 break; 05676 05677 case DC_DOKEY: 05678 if (keyed) *keyed = 1; 05679 res = 0; 05680 break; 05681 05682 case DC_REQ_FLUSH: 05683 myrpt->dtmfidx = 0; 05684 myrpt->dtmfbuf[0] = 0; 05685 res = 0; 05686 break; 05687 05688 05689 case DC_COMPLETE: 05690 myrpt->totalexecdcommands++; 05691 myrpt->dailyexecdcommands++; 05692 ast_copy_string(myrpt->lastdtmfcommand, myrpt->dtmfbuf, MAXDTMF); 05693 myrpt->dtmfbuf[0] = 0; 05694 myrpt->dtmfidx = -1; 05695 myrpt->dtmf_time_rem = 0; 05696 res = 1; 05697 break; 05698 05699 case DC_ERROR: 05700 default: 05701 myrpt->dtmfbuf[0] = 0; 05702 myrpt->dtmfidx = -1; 05703 myrpt->dtmf_time_rem = 0; 05704 res = 0; 05705 break; 05706 } 05707 05708 return res; 05709 }
static int handle_remote_phone_dtmf | ( | struct rpt * | myrpt, | |
char | c, | |||
char * | keyed, | |||
int | phonemode | |||
) | [static] |
Definition at line 5746 of file app_rpt.c.
References AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_safe_sleep(), DC_INDETERMINATE, rpt::endchar, handle_remote_dtmf_digit(), rpt::name, rpt::p, rpt::remchannel, rpt::remoterx, rpt::remotetx, rmt_telem_finish(), telem_lookup(), and rpt::txchannel.
05747 { 05748 int res; 05749 05750 05751 if (keyed && *keyed && (c == myrpt->p.endchar)) 05752 { 05753 *keyed = 0; 05754 return DC_INDETERMINATE; 05755 } 05756 05757 res = handle_remote_dtmf_digit(myrpt,c,keyed, phonemode); 05758 if (res != 1) 05759 return res; 05760 myrpt->remotetx = 0; 05761 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 05762 if (!myrpt->remoterx) 05763 { 05764 ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_KEY); 05765 } 05766 if (ast_safe_sleep(myrpt->remchannel,1000) == -1) return -1; 05767 res = telem_lookup(myrpt,myrpt->remchannel, myrpt->name, "functcomplete"); 05768 rmt_telem_finish(myrpt,myrpt->remchannel); 05769 return res; 05770 }
static int load_module | ( | void | ) | [static] |
Definition at line 8031 of file app_rpt.c.
References ast_cli_register_multiple(), ast_config_load(), ast_log(), AST_MODULE_LOAD_DECLINE, ast_pthread_create, ast_register_application(), cli_rpt, LOG_WARNING, rpt_exec(), and rpt_master().
08032 { 08033 struct ast_config *cfg = ast_config_load("rpt.conf"); 08034 if (!cfg) { 08035 ast_log(LOG_WARNING, "No such configuration file rpt.conf\n"); 08036 return AST_MODULE_LOAD_DECLINE; 08037 } 08038 ast_pthread_create(&rpt_master_thread,NULL,rpt_master,cfg); 08039 08040 /* Register cli extensions */ 08041 ast_cli_register_multiple(cli_rpt, sizeof(cli_rpt) / sizeof(struct ast_cli_entry)); 08042 08043 return ast_register_application(app, rpt_exec, synopsis, descrip); 08044 }
static void load_rpt_vars | ( | int | n, | |
int | init | |||
) | [static] |
Definition at line 960 of file app_rpt.c.
References rpt::acctcode, ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_strdupa, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), rpt::cfg, DEFAULT_IOBASE, desc, rpt::dphone_functions, rpt::dphone_longestfunc, rpt::duplex, ENDCHAR, rpt::endchar, finddelim(), FUNCCHAR, rpt::funcchar, rpt::functions, FUNCTIONS, HANGTIME, rpt::hangtime, rpt::ident, IDTIME, rpt::idtime, rpt::iobase, rpt::link_functions, rpt::link_longestfunc, lock, LOG_NOTICE, rpt::longestfunc, rpt::longestnode, rpt::macro, MACRO, rpt::macro_longest, rpt::memory, MEMORY, ast_variable::name, rpt::name, name, ast_variable::next, rpt_tele::next, rpt::nobusyout, rpt::nodes, NODES, option_verbose, rpt::ourcallerid, rpt::ourcontext, rpt::p, rpt::phone_functions, rpt::phone_longestfunc, POLITEID, rpt::politeid, rpt_tele::prev, retrieve_astcfgint(), rpt::rpt_thread, rpt_vars, rpt::simple, rpt::startupmacro, rpt::tailmessagemax, rpt::tailmessagen, rpt::tailmessages, rpt::tailmessagetime, rpt::tailsquashedtime, rpt::tele, rpt::tonezone, TOTIME, rpt::totime, and VERBOSE_PREFIX_3.
Referenced by rpt(), rpt_exec(), and rpt_master().
00961 { 00962 char *this; 00963 const char *val; 00964 int j,longestnode; 00965 struct ast_variable *vp; 00966 struct ast_config *cfg; 00967 #ifdef __RPT_NOTCH 00968 int i; 00969 char *strs[100]; 00970 #endif 00971 00972 if (option_verbose > 2) 00973 ast_verbose(VERBOSE_PREFIX_3 "%s config for repeater %s\n", 00974 (init) ? "Loading initial" : "Re-Loading",rpt_vars[n].name); 00975 ast_mutex_lock(&rpt_vars[n].lock); 00976 if (rpt_vars[n].cfg) ast_config_destroy(rpt_vars[n].cfg); 00977 cfg = ast_config_load("rpt.conf"); 00978 if (!cfg) { 00979 ast_mutex_unlock(&rpt_vars[n].lock); 00980 ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); 00981 pthread_exit(NULL); 00982 } 00983 rpt_vars[n].cfg = cfg; 00984 this = rpt_vars[n].name; 00985 memset(&rpt_vars[n].p,0,sizeof(rpt_vars[n].p)); 00986 if (init) 00987 { 00988 char *cp; 00989 int savearea = (char *)&rpt_vars[n].p - (char *)&rpt_vars[n]; 00990 00991 cp = (char *) &rpt_vars[n].p; 00992 memset(cp + sizeof(rpt_vars[n].p),0, 00993 sizeof(rpt_vars[n]) - (sizeof(rpt_vars[n].p) + savearea)); 00994 rpt_vars[n].tele.next = &rpt_vars[n].tele; 00995 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 00996 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 00997 rpt_vars[n].tailmessagen = 0; 00998 } 00999 #ifdef __RPT_NOTCH 01000 /* zot out filters stuff */ 01001 memset(&rpt_vars[n].filters,0,sizeof(rpt_vars[n].filters)); 01002 #endif 01003 val = ast_variable_retrieve(cfg,this,"context"); 01004 if (val) rpt_vars[n].p.ourcontext = val; 01005 else rpt_vars[n].p.ourcontext = this; 01006 val = ast_variable_retrieve(cfg,this,"callerid"); 01007 if (val) rpt_vars[n].p.ourcallerid = val; 01008 val = ast_variable_retrieve(cfg,this,"accountcode"); 01009 if (val) rpt_vars[n].p.acctcode = val; 01010 val = ast_variable_retrieve(cfg,this,"idrecording"); 01011 if (val) rpt_vars[n].p.ident = val; 01012 val = ast_variable_retrieve(cfg,this,"hangtime"); 01013 if (val) rpt_vars[n].p.hangtime = atoi(val); 01014 else rpt_vars[n].p.hangtime = HANGTIME; 01015 val = ast_variable_retrieve(cfg,this,"totime"); 01016 if (val) rpt_vars[n].p.totime = atoi(val); 01017 else rpt_vars[n].p.totime = TOTIME; 01018 rpt_vars[n].p.tailmessagetime = retrieve_astcfgint(&rpt_vars[n],this, "tailmessagetime", 0, 2400000, 0); 01019 rpt_vars[n].p.tailsquashedtime = retrieve_astcfgint(&rpt_vars[n],this, "tailsquashedtime", 0, 2400000, 0); 01020 rpt_vars[n].p.duplex = retrieve_astcfgint(&rpt_vars[n],this,"duplex",0,4,2); 01021 rpt_vars[n].p.idtime = retrieve_astcfgint(&rpt_vars[n],this, "idtime", 60000, 2400000, IDTIME); /* Enforce a min max */ 01022 rpt_vars[n].p.politeid = retrieve_astcfgint(&rpt_vars[n],this, "politeid", 30000, 300000, POLITEID); /* Enforce a min max */ 01023 val = ast_variable_retrieve(cfg,this,"tonezone"); 01024 if (val) rpt_vars[n].p.tonezone = ast_strdupa(val); 01025 rpt_vars[n].p.tailmessages[0] = 0; 01026 rpt_vars[n].p.tailmessagemax = 0; 01027 val = ast_variable_retrieve(cfg,this,"tailmessagelist"); 01028 if (val) rpt_vars[n].p.tailmessagemax = finddelim(ast_strdupa(val), rpt_vars[n].p.tailmessages, 500); 01029 val = ast_variable_retrieve(cfg,this,"memory"); 01030 if (!val) val = MEMORY; 01031 rpt_vars[n].p.memory = val; 01032 val = ast_variable_retrieve(cfg,this,"macro"); 01033 if (!val) val = MACRO; 01034 rpt_vars[n].p.macro = val; 01035 val = ast_variable_retrieve(cfg,this,"startup_macro"); 01036 if (val) rpt_vars[n].p.startupmacro = val; 01037 val = ast_variable_retrieve(cfg,this,"iobase"); 01038 /* do not use atoi() here, we need to be able to have 01039 the input specified in hex or decimal so we use 01040 sscanf with a %i */ 01041 if ((!val) || (sscanf(val,"%i",&rpt_vars[n].p.iobase) != 1)) 01042 rpt_vars[n].p.iobase = DEFAULT_IOBASE; 01043 val = ast_variable_retrieve(cfg,this,"functions"); 01044 if (!val) 01045 { 01046 val = FUNCTIONS; 01047 rpt_vars[n].p.simple = 1; 01048 } 01049 rpt_vars[n].p.functions = val; 01050 val = ast_variable_retrieve(cfg,this,"link_functions"); 01051 if (val) rpt_vars[n].p.link_functions = val; 01052 else 01053 rpt_vars[n].p.link_functions = rpt_vars[n].p.functions; 01054 val = ast_variable_retrieve(cfg,this,"phone_functions"); 01055 if (val) rpt_vars[n].p.phone_functions = val; 01056 val = ast_variable_retrieve(cfg,this,"dphone_functions"); 01057 if (val) rpt_vars[n].p.dphone_functions = val; 01058 val = ast_variable_retrieve(cfg,this,"funcchar"); 01059 if (!val) rpt_vars[n].p.funcchar = FUNCCHAR; else 01060 rpt_vars[n].p.funcchar = *val; 01061 val = ast_variable_retrieve(cfg,this,"endchar"); 01062 if (!val) rpt_vars[n].p.endchar = ENDCHAR; else 01063 rpt_vars[n].p.endchar = *val; 01064 val = ast_variable_retrieve(cfg,this,"nobusyout"); 01065 if (val) rpt_vars[n].p.nobusyout = ast_true(val); 01066 val = ast_variable_retrieve(cfg,this,"nodes"); 01067 if (!val) val = NODES; 01068 rpt_vars[n].p.nodes = val; 01069 #ifdef __RPT_NOTCH 01070 val = ast_variable_retrieve(cfg,this,"rxnotch"); 01071 if (val) { 01072 i = finddelim(ast_strdupa(val),strs,MAXFILTERS * 2); 01073 i &= ~1; /* force an even number, rounded down */ 01074 if (i >= 2) for(j = 0; j < i; j += 2) 01075 { 01076 rpt_mknotch(atof(strs[j]),atof(strs[j + 1]), 01077 &rpt_vars[n].filters[j >> 1].gain, 01078 &rpt_vars[n].filters[j >> 1].const0, 01079 &rpt_vars[n].filters[j >> 1].const1, 01080 &rpt_vars[n].filters[j >> 1].const2); 01081 sprintf(rpt_vars[n].filters[j >> 1].desc,"%s Hz, BW = %s", 01082 strs[j],strs[j + 1]); 01083 } 01084 01085 } 01086 #endif 01087 longestnode = 0; 01088 01089 vp = ast_variable_browse(cfg, rpt_vars[n].p.nodes); 01090 01091 while(vp){ 01092 j = strlen(vp->name); 01093 if (j > longestnode) 01094 longestnode = j; 01095 vp = vp->next; 01096 } 01097 01098 rpt_vars[n].longestnode = longestnode; 01099 01100 /* 01101 * For this repeater, Determine the length of the longest function 01102 */ 01103 rpt_vars[n].longestfunc = 0; 01104 vp = ast_variable_browse(cfg, rpt_vars[n].p.functions); 01105 while(vp){ 01106 j = strlen(vp->name); 01107 if (j > rpt_vars[n].longestfunc) 01108 rpt_vars[n].longestfunc = j; 01109 vp = vp->next; 01110 } 01111 /* 01112 * For this repeater, Determine the length of the longest function 01113 */ 01114 rpt_vars[n].link_longestfunc = 0; 01115 vp = ast_variable_browse(cfg, rpt_vars[n].p.link_functions); 01116 while(vp){ 01117 j = strlen(vp->name); 01118 if (j > rpt_vars[n].link_longestfunc) 01119 rpt_vars[n].link_longestfunc = j; 01120 vp = vp->next; 01121 } 01122 rpt_vars[n].phone_longestfunc = 0; 01123 if (rpt_vars[n].p.phone_functions) 01124 { 01125 vp = ast_variable_browse(cfg, rpt_vars[n].p.phone_functions); 01126 while(vp){ 01127 j = strlen(vp->name); 01128 if (j > rpt_vars[n].phone_longestfunc) 01129 rpt_vars[n].phone_longestfunc = j; 01130 vp = vp->next; 01131 } 01132 } 01133 rpt_vars[n].dphone_longestfunc = 0; 01134 if (rpt_vars[n].p.dphone_functions) 01135 { 01136 vp = ast_variable_browse(cfg, rpt_vars[n].p.dphone_functions); 01137 while(vp){ 01138 j = strlen(vp->name); 01139 if (j > rpt_vars[n].dphone_longestfunc) 01140 rpt_vars[n].dphone_longestfunc = j; 01141 vp = vp->next; 01142 } 01143 } 01144 rpt_vars[n].macro_longest = 1; 01145 vp = ast_variable_browse(cfg, rpt_vars[n].p.macro); 01146 while(vp){ 01147 j = strlen(vp->name); 01148 if (j > rpt_vars[n].macro_longest) 01149 rpt_vars[n].macro_longest = j; 01150 vp = vp->next; 01151 } 01152 ast_mutex_unlock(&rpt_vars[n].lock); 01153 }
static void local_dtmf_helper | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 5834 of file app_rpt.c.
References ast_canmatch_extension(), ast_exists_extension(), ast_pthread_create, rpt::callmode, rpt::cidx, rpt::cmdnode, collect_function_digits(), COMPLETE, rpt::dailyexecdcommands, DC_COMPLETE, DC_ERROR, DC_INDETERMINATE, DC_REQ_FLUSH, rpt::dtmf_time, rpt::dtmfbuf, rpt::dtmfidx, rpt::endchar, rpt::exten, rpt::funcchar, rpt::lastdtmfcommand, rpt::lock, MAXDTMF, MAXPATCHCONTEXT, rpt::mydtmf, rpt::ourcontext, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchnoct, rpt::patchquiet, rpt::pchannel, PROC, rpt_call(), rpt::rpt_call_thread, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), send_link_dtmf(), rpt::simple, SOURCE_RPT, rpt::stopgen, TERM, and rpt::totalexecdcommands.
Referenced by rpt().
05835 { 05836 int res; 05837 pthread_attr_t attr; 05838 char cmd[MAXDTMF+1] = ""; 05839 05840 if (c == myrpt->p.endchar) 05841 { 05842 /* if in simple mode, kill autopatch */ 05843 if (myrpt->p.simple && myrpt->callmode) 05844 { 05845 rpt_mutex_lock(&myrpt->lock); 05846 myrpt->callmode = 0; 05847 rpt_mutex_unlock(&myrpt->lock); 05848 rpt_telemetry(myrpt,TERM,NULL); 05849 return; 05850 } 05851 rpt_mutex_lock(&myrpt->lock); 05852 myrpt->stopgen = 1; 05853 if (myrpt->cmdnode[0]) 05854 { 05855 myrpt->cmdnode[0] = 0; 05856 myrpt->dtmfidx = -1; 05857 myrpt->dtmfbuf[0] = 0; 05858 rpt_mutex_unlock(&myrpt->lock); 05859 rpt_telemetry(myrpt,COMPLETE,NULL); 05860 } else rpt_mutex_unlock(&myrpt->lock); 05861 return; 05862 } 05863 rpt_mutex_lock(&myrpt->lock); 05864 if (myrpt->cmdnode[0]) 05865 { 05866 rpt_mutex_unlock(&myrpt->lock); 05867 send_link_dtmf(myrpt,c); 05868 return; 05869 } 05870 if (!myrpt->p.simple) 05871 { 05872 if (c == myrpt->p.funcchar) 05873 { 05874 myrpt->dtmfidx = 0; 05875 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 05876 rpt_mutex_unlock(&myrpt->lock); 05877 time(&myrpt->dtmf_time); 05878 return; 05879 } 05880 else if ((c != myrpt->p.endchar) && (myrpt->dtmfidx >= 0)) 05881 { 05882 time(&myrpt->dtmf_time); 05883 05884 if (myrpt->dtmfidx < MAXDTMF) 05885 { 05886 myrpt->dtmfbuf[myrpt->dtmfidx++] = c; 05887 myrpt->dtmfbuf[myrpt->dtmfidx] = 0; 05888 05889 ast_copy_string(cmd, myrpt->dtmfbuf, sizeof(cmd)); 05890 05891 rpt_mutex_unlock(&myrpt->lock); 05892 res = collect_function_digits(myrpt, cmd, SOURCE_RPT, NULL); 05893 rpt_mutex_lock(&myrpt->lock); 05894 switch(res){ 05895 case DC_INDETERMINATE: 05896 break; 05897 case DC_REQ_FLUSH: 05898 myrpt->dtmfidx = 0; 05899 myrpt->dtmfbuf[0] = 0; 05900 break; 05901 case DC_COMPLETE: 05902 myrpt->totalexecdcommands++; 05903 myrpt->dailyexecdcommands++; 05904 ast_copy_string(myrpt->lastdtmfcommand, cmd, MAXDTMF); 05905 myrpt->dtmfbuf[0] = 0; 05906 myrpt->dtmfidx = -1; 05907 myrpt->dtmf_time = 0; 05908 break; 05909 05910 case DC_ERROR: 05911 default: 05912 myrpt->dtmfbuf[0] = 0; 05913 myrpt->dtmfidx = -1; 05914 myrpt->dtmf_time = 0; 05915 break; 05916 } 05917 if(res != DC_INDETERMINATE) { 05918 rpt_mutex_unlock(&myrpt->lock); 05919 return; 05920 } 05921 } 05922 } 05923 } 05924 else /* if simple */ 05925 { 05926 if ((!myrpt->callmode) && (c == myrpt->p.funcchar)) 05927 { 05928 myrpt->callmode = 1; 05929 myrpt->patchnoct = 0; 05930 myrpt->patchquiet = 0; 05931 myrpt->patchfarenddisconnect = 0; 05932 myrpt->patchdialtime = 0; 05933 ast_copy_string(myrpt->patchcontext, myrpt->p.ourcontext, MAXPATCHCONTEXT); 05934 myrpt->cidx = 0; 05935 myrpt->exten[myrpt->cidx] = 0; 05936 rpt_mutex_unlock(&myrpt->lock); 05937 pthread_attr_init(&attr); 05938 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 05939 ast_pthread_create(&myrpt->rpt_call_thread,&attr,rpt_call,(void *)myrpt); 05940 pthread_attr_destroy(&attr); 05941 return; 05942 } 05943 } 05944 if (myrpt->callmode == 1) 05945 { 05946 myrpt->exten[myrpt->cidx++] = c; 05947 myrpt->exten[myrpt->cidx] = 0; 05948 /* if this exists */ 05949 if (ast_exists_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05950 { 05951 myrpt->callmode = 2; 05952 rpt_mutex_unlock(&myrpt->lock); 05953 if(!myrpt->patchquiet) 05954 rpt_telemetry(myrpt,PROC,NULL); 05955 return; 05956 } 05957 /* if can continue, do so */ 05958 if (!ast_canmatch_extension(myrpt->pchannel,myrpt->patchcontext,myrpt->exten,1,NULL)) 05959 { 05960 /* call has failed, inform user */ 05961 myrpt->callmode = 4; 05962 } 05963 rpt_mutex_unlock(&myrpt->lock); 05964 return; 05965 } 05966 if ((myrpt->callmode == 2) || (myrpt->callmode == 3)) 05967 { 05968 myrpt->mydtmf = c; 05969 } 05970 rpt_mutex_unlock(&myrpt->lock); 05971 return; 05972 }
static int matchkeyword | ( | char * | string, | |
char ** | param, | |||
char * | keywords[] | |||
) | [static] |
Definition at line 860 of file app_rpt.c.
Referenced by function_autopatchup().
00861 { 00862 int i,ls; 00863 for( i = 0 ; keywords[i] ; i++){ 00864 ls = strlen(keywords[i]); 00865 if(!ls){ 00866 *param = NULL; 00867 return 0; 00868 } 00869 if(!strncmp(string, keywords[i], ls)){ 00870 if(param) 00871 *param = string + ls; 00872 return i + 1; 00873 } 00874 } 00875 param = NULL; 00876 return 0; 00877 }
static int multimode_bump_freq | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 4762 of file app_rpt.c.
References multimode_bump_freq_ft897(), and rpt::remote.
Referenced by function_remote(), and service_scan().
04763 { 04764 if(!strcmp(myrpt->remote, remote_rig_ft897)) 04765 return multimode_bump_freq_ft897(myrpt, interval); 04766 else 04767 return -1; 04768 }
static int multimode_bump_freq_ft897 | ( | struct rpt * | myrpt, | |
int | interval | |||
) | [static] |
Definition at line 4669 of file app_rpt.c.
References check_freq_ft897(), rpt::freq, MAXREMSTR, set_freq_ft897(), and split_freq().
Referenced by multimode_bump_freq().
04670 { 04671 int m,d; 04672 char mhz[MAXREMSTR], decimals[MAXREMSTR]; 04673 04674 if(debug) 04675 printf("Before bump: %s\n", myrpt->freq); 04676 04677 if(split_freq(mhz, decimals, myrpt->freq)) 04678 return -1; 04679 04680 m = atoi(mhz); 04681 d = atoi(decimals); 04682 04683 d += (interval / 10); /* 10Hz resolution */ 04684 if(d < 0){ 04685 m--; 04686 d += 100000; 04687 } 04688 else if(d >= 100000){ 04689 m++; 04690 d -= 100000; 04691 } 04692 04693 if(check_freq_ft897(m, d, NULL)){ 04694 if(debug) 04695 printf("Bump freq invalid\n"); 04696 return -1; 04697 } 04698 04699 snprintf(myrpt->freq, MAXREMSTR, "%d.%05d", m, d); 04700 04701 if(debug) 04702 printf("After bump: %s\n", myrpt->freq); 04703 04704 return set_freq_ft897(myrpt, myrpt->freq); 04705 }
static int multimode_capable | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 4751 of file app_rpt.c.
References rpt::remote.
Referenced by function_remote().
04752 { 04753 if(!strcmp(myrpt->remote, remote_rig_ft897)) 04754 return 1; 04755 return 0; 04756 }
static int myatoi | ( | const char * | str | ) | [static] |
Definition at line 902 of file app_rpt.c.
Referenced by function_cop(), function_ilink(), function_remote(), function_status(), retrieve_astcfgint(), and rpt_do_debug().
00903 { 00904 int ret; 00905 00906 if (str == NULL) return -1; 00907 /* leave this %i alone, non-base-10 input is useful here */ 00908 if (sscanf(str,"%i",&ret) != 1) return -1; 00909 return ret; 00910 }
static int play_silence | ( | struct ast_channel * | chan, | |
int | duration | |||
) | [static] |
Definition at line 1520 of file app_rpt.c.
References play_tone_pair().
Referenced by send_morse().
01521 { 01522 return play_tone_pair(chan, 0, 0, duration, 0); 01523 }
static int play_tone | ( | struct ast_channel * | chan, | |
int | freq, | |||
int | duration, | |||
int | amplitude | |||
) | [static] |
Definition at line 1515 of file app_rpt.c.
References play_tone_pair().
Referenced by send_morse().
01516 { 01517 return play_tone_pair(chan, freq, 0, duration, amplitude); 01518 }
static int play_tone_pair | ( | struct ast_channel * | chan, | |
int | f1, | |||
int | f2, | |||
int | duration, | |||
int | amplitude | |||
) | [static] |
Definition at line 1501 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().
01502 { 01503 int res; 01504 01505 if ((res = ast_tonepair_start(chan, f1, f2, duration, amplitude))) 01506 return res; 01507 01508 while(chan->generatordata) { 01509 if (ast_safe_sleep(chan,1)) return -1; 01510 } 01511 01512 return 0; 01513 }
static void queue_id | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 5977 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().
05978 { 05979 myrpt->mustid = myrpt->tailid = 0; 05980 myrpt->idtimer = myrpt->p.idtime; /* Reset our ID timer */ 05981 rpt_mutex_unlock(&myrpt->lock); 05982 rpt_telemetry(myrpt,ID,NULL); 05983 rpt_mutex_lock(&myrpt->lock); 05984 }
static int rbi_mhztoband | ( | char * | str | ) | [static] |
Definition at line 3949 of file app_rpt.c.
Referenced by setrbi().
03950 { 03951 int i; 03952 03953 i = atoi(str) / 10; /* get the 10's of mhz */ 03954 switch(i) 03955 { 03956 case 2: 03957 return 10; 03958 case 5: 03959 return 11; 03960 case 14: 03961 return 2; 03962 case 22: 03963 return 3; 03964 case 44: 03965 return 4; 03966 case 124: 03967 return 0; 03968 case 125: 03969 return 1; 03970 case 126: 03971 return 8; 03972 case 127: 03973 return 5; 03974 case 128: 03975 return 6; 03976 case 129: 03977 return 7; 03978 default: 03979 break; 03980 } 03981 return -1; 03982 }
static void rbi_out | ( | struct rpt * | myrpt, | |
unsigned char * | data | |||
) | [static] |
Definition at line 4106 of file app_rpt.c.
References ast_log(), ast_channel::fds, LOG_WARNING, rbi_out_parallel(), and rpt::rxchannel.
Referenced by setrbi().
04107 { 04108 struct zt_radio_param r; 04109 04110 memset(&r,0,sizeof(struct zt_radio_param)); 04111 r.radpar = ZT_RADPAR_REMMODE; 04112 r.data = ZT_RADPAR_REM_RBI1; 04113 /* if setparam ioctl fails, its probably not a pciradio card */ 04114 if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1) 04115 { 04116 rbi_out_parallel(myrpt,data); 04117 return; 04118 } 04119 r.radpar = ZT_RADPAR_REMCOMMAND; 04120 memcpy(&r.data,data,5); 04121 if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&r) == -1) 04122 { 04123 ast_log(LOG_WARNING,"Cannot send RBI command for channel %s\n",myrpt->rxchannel->name); 04124 return; 04125 } 04126 }
static void rbi_out_parallel | ( | struct rpt * | myrpt, | |
unsigned char * | data | |||
) | [static] |
Definition at line 4080 of file app_rpt.c.
References rpt::iobase, and rpt::p.
Referenced by rbi_out().
04081 { 04082 int i,j; 04083 unsigned char od,d; 04084 static volatile long long delayvar; 04085 04086 for(i = 0 ; i < 5 ; i++){ 04087 od = *data++; 04088 for(j = 0 ; j < 8 ; j++){ 04089 d = od & 1; 04090 outb(d,myrpt->p.iobase); 04091 /* >= 15 us */ 04092 for(delayvar = 1; delayvar < 15000; delayvar++); 04093 od >>= 1; 04094 outb(d | 2,myrpt->p.iobase); 04095 /* >= 30 us */ 04096 for(delayvar = 1; delayvar < 30000; delayvar++); 04097 outb(d,myrpt->p.iobase); 04098 /* >= 10 us */ 04099 for(delayvar = 1; delayvar < 10000; delayvar++); 04100 } 04101 } 04102 /* >= 50 us */ 04103 for(delayvar = 1; delayvar < 50000; delayvar++); 04104 }
static int rbi_pltocode | ( | char * | str | ) | [static] |
Definition at line 3985 of file app_rpt.c.
References s.
Referenced by setrbi().
03986 { 03987 int i; 03988 char *s; 03989 03990 s = strchr(str,'.'); 03991 i = 0; 03992 if (s) i = atoi(s + 1); 03993 i += atoi(str) * 10; 03994 switch(i) 03995 { 03996 case 670: 03997 return 0; 03998 case 719: 03999 return 1; 04000 case 744: 04001 return 2; 04002 case 770: 04003 return 3; 04004 case 797: 04005 return 4; 04006 case 825: 04007 return 5; 04008 case 854: 04009 return 6; 04010 case 885: 04011 return 7; 04012 case 915: 04013 return 8; 04014 case 948: 04015 return 9; 04016 case 974: 04017 return 10; 04018 case 1000: 04019 return 11; 04020 case 1035: 04021 return 12; 04022 case 1072: 04023 return 13; 04024 case 1109: 04025 return 14; 04026 case 1148: 04027 return 15; 04028 case 1188: 04029 return 16; 04030 case 1230: 04031 return 17; 04032 case 1273: 04033 return 18; 04034 case 1318: 04035 return 19; 04036 case 1365: 04037 return 20; 04038 case 1413: 04039 return 21; 04040 case 1462: 04041 return 22; 04042 case 1514: 04043 return 23; 04044 case 1567: 04045 return 24; 04046 case 1622: 04047 return 25; 04048 case 1679: 04049 return 26; 04050 case 1738: 04051 return 27; 04052 case 1799: 04053 return 28; 04054 case 1862: 04055 return 29; 04056 case 1928: 04057 return 30; 04058 case 2035: 04059 return 31; 04060 case 2107: 04061 return 32; 04062 case 2181: 04063 return 33; 04064 case 2257: 04065 return 34; 04066 case 2336: 04067 return 35; 04068 case 2418: 04069 return 36; 04070 case 2503: 04071 return 37; 04072 } 04073 return -1; 04074 }
static int reload | ( | void | ) | [static] |
static int retrieve_astcfgint | ( | struct rpt * | myrpt, | |
char * | category, | |||
char * | name, | |||
int | min, | |||
int | max, | |||
int | defl | |||
) | [static] |
Definition at line 941 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().
00942 { 00943 const char *var; 00944 int ret; 00945 00946 var = ast_variable_retrieve(myrpt->cfg, category, name); 00947 if(var){ 00948 ret = myatoi(var); 00949 if(ret < min) 00950 ret = min; 00951 if(ret > max) 00952 ret = max; 00953 } 00954 else 00955 ret = defl; 00956 return ret; 00957 }
static int rmt_saycharstr | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
int | delay, | |||
char * | charstr | |||
) | [static] |
Definition at line 4899 of file app_rpt.c.
References rmt_telem_finish(), rmt_telem_start(), and saycharstr().
Referenced by function_remote().
04900 { 04901 int res; 04902 04903 res = rmt_telem_start(myrpt, chan, delay); 04904 04905 if(!res) 04906 res = saycharstr(chan, charstr); 04907 04908 if(!res) 04909 res = rmt_telem_finish(myrpt, chan); 04910 return res; 04911 }
static int rmt_sayfile | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
int | delay, | |||
char * | filename | |||
) | [static] |
Definition at line 4885 of file app_rpt.c.
References rmt_telem_finish(), rmt_telem_start(), and sayfile().
Referenced by function_remote().
04886 { 04887 int res; 04888 04889 res = rmt_telem_start(myrpt, chan, delay); 04890 04891 if(!res) 04892 res = sayfile(chan, filename); 04893 04894 if(!res) 04895 res = rmt_telem_finish(myrpt, chan); 04896 return res; 04897 }
static int rmt_telem_finish | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan | |||
) | [static] |
Definition at line 4862 of file app_rpt.c.
References AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_channel::fds, rpt::remchannel, rpt::remoterx, and rpt::txchannel.
Referenced by function_remote(), handle_remote_data(), handle_remote_phone_dtmf(), rmt_saycharstr(), and rmt_sayfile().
04863 { 04864 04865 struct zt_params par; 04866 04867 if (ioctl(myrpt->txchannel->fds[0],ZT_GET_PARAMS,&par) == -1) 04868 { 04869 return -1; 04870 04871 } 04872 if (!par.rxisoffhook) 04873 { 04874 ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_UNKEY); 04875 myrpt->remoterx = 0; 04876 } 04877 else 04878 { 04879 myrpt->remoterx = 1; 04880 } 04881 return 0; 04882 }
static int rmt_telem_start | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
int | delay | |||
) | [static] |
Definition at line 4850 of file app_rpt.c.
References AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, ast_indicate(), ast_safe_sleep(), rpt::remoterx, rpt::remotetx, and rpt::txchannel.
Referenced by function_remote(), rmt_saycharstr(), and rmt_sayfile().
04851 { 04852 myrpt->remotetx = 0; 04853 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 04854 if (!myrpt->remoterx) 04855 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 04856 if (ast_safe_sleep(chan, delay) == -1) 04857 return -1; 04858 return 0; 04859 }
static void* rpt | ( | void * | this | ) | [static] |
Definition at line 6017 of file app_rpt.c.
References ast_channel::_state, ast_channel::appl, ast_call(), ast_channel_setoption(), ast_check_hangup(), 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_TEXT, AST_FRAME_VOICE, ast_frfree(), ast_hangup(), ast_indicate(), ast_log(), AST_OPTION_RELAXDTMF, AST_OPTION_TONE_VERIFY, AST_PTHREADT_STOP, ast_read(), ast_request(), ast_set_read_format(), ast_set_write_format(), ast_softhangup(), AST_SOFTHANGUP_DEV, AST_STATE_BUSY, AST_STATE_UP, ast_variable_retrieve(), ast_verbose(), ast_waitfor_n(), ast_write(), attempt_reconnect(), rpt::callmode, rpt::cfg, rpt_link::chan, rpt_tele::chan, rpt::cmdnode, rpt::conf, CONNECTED, rpt_link::connected, rpt_link::connecttime, CONNFAIL, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, ast_channel::data, DISC_TIME, rpt_link::disced, rpt_link::disctime, rpt::disgorgetime, do_scheduler(), rpt::dtmf_time, DTMF_TIMEOUT, rpt::dtmfbuf, rpt::dtmfidx, rpt::duplex, rpt_link::elaptime, rpt::enable, rpt::exten, rpt::exttx, f, ast_channel::fds, free, handle_link_data(), handle_link_phone_dtmf(), rpt::hangtime, rpt_link::hasconnected, ID, IDTALKOVER, rpt::idtimer, rpt_link::isremote, rpt::keyed, rpt_link::killme, rpt::lastdtmfcommand, rpt::lastnodewhichkeyedusup, rpt_link::lastrx, rpt_link::lasttx, rpt::links, load_rpt_vars(), local_dtmf_helper(), rpt::localtx, rpt::lock, LOG_NOTICE, LOG_WARNING, rpt::macrobuf, MACROPTIME, MACROTIME, rpt::macrotimer, MAX_RETRIES, MAXCONNECTTIME, MAXMACRO, rpt_link::mode, rpt_tele::mode, MSWAIT, rpt::mustid, rpt_link::name, rpt::name, rpt_link::next, rpt_tele::next, option_verbose, rpt_link::outbound, rpt::p, rpt_link::pchan, rpt::pchannel, rpt::politeid, rpt_link::prev, queue_id(), rpt_link::reconnects, REDUNDANT_TX_TIME, rpt::reload, rpt::rem_dtmf_time, rpt::rem_dtmfbuf, rpt::rem_dtmfidx, REMDISC, rpt_link::retries, RETRY_TIMER_MS, rpt_link::retrytimer, rpt_link::retxtimer, rpt::retxtimer, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt::rpt_thread, rpt_vars, rpt::rxchanname, rpt::rxchannel, rpt::skedtimer, rpt::startupmacro, t, rpt::tailevent, rpt::tailid, rpt::tailmessages, rpt::tailmessagetime, TAILMSG, rpt::tailtimer, rpt::tele, TIMEOUT, rpt::timeouts, rpt::tmsgtimer, rpt::tonotify, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, rpt::totime, rpt::totimer, rpt::tounkeyed, rpt::txchanname, rpt::txchannel, rpt::txconf, rpt::txpchannel, UNKEY, VERBOSE_PREFIX_3, and ast_channel::whentohangup.
06018 { 06019 struct rpt *myrpt = (struct rpt *)this; 06020 char *tele, c; 06021 const char *idtalkover; 06022 int ms = MSWAIT,i,lasttx=0,val,remrx=0,identqueued,othertelemqueued,tailmessagequeued,ctqueued; 06023 struct ast_channel *who; 06024 ZT_CONFINFO ci; /* conference info */ 06025 time_t t; 06026 struct rpt_link *l,*m; 06027 struct rpt_tele *telem; 06028 char tmpstr[300]; 06029 06030 rpt_mutex_lock(&myrpt->lock); 06031 06032 telem = myrpt->tele.next; 06033 while(telem != &myrpt->tele) 06034 { 06035 ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV); 06036 telem = telem->next; 06037 } 06038 rpt_mutex_unlock(&myrpt->lock); 06039 /* find our index, and load the vars initially */ 06040 for(i = 0; i < nrpts; i++) 06041 { 06042 if (&rpt_vars[i] == myrpt) 06043 { 06044 load_rpt_vars(i,0); 06045 break; 06046 } 06047 } 06048 rpt_mutex_lock(&myrpt->lock); 06049 ast_copy_string(tmpstr,myrpt->rxchanname,sizeof(tmpstr)); 06050 tele = strchr(tmpstr,'/'); 06051 if (!tele) 06052 { 06053 fprintf(stderr,"rpt:Rxchannel Dial number (%s) must be in format tech/number\n",myrpt->rxchanname); 06054 rpt_mutex_unlock(&myrpt->lock); 06055 myrpt->rpt_thread = AST_PTHREADT_STOP; 06056 pthread_exit(NULL); 06057 } 06058 *tele++ = 0; 06059 myrpt->rxchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 06060 if (myrpt->rxchannel) 06061 { 06062 if (myrpt->rxchannel->_state == AST_STATE_BUSY) 06063 { 06064 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 06065 rpt_mutex_unlock(&myrpt->lock); 06066 ast_hangup(myrpt->rxchannel); 06067 myrpt->rpt_thread = AST_PTHREADT_STOP; 06068 pthread_exit(NULL); 06069 } 06070 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 06071 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 06072 myrpt->rxchannel->whentohangup = 0; 06073 myrpt->rxchannel->appl = "Apprpt"; 06074 myrpt->rxchannel->data = "(Repeater Rx)"; 06075 if (option_verbose > 2) 06076 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 06077 tmpstr,tele,myrpt->rxchannel->name); 06078 ast_call(myrpt->rxchannel,tele,999); 06079 if (myrpt->rxchannel->_state != AST_STATE_UP) 06080 { 06081 rpt_mutex_unlock(&myrpt->lock); 06082 ast_hangup(myrpt->rxchannel); 06083 myrpt->rpt_thread = AST_PTHREADT_STOP; 06084 pthread_exit(NULL); 06085 } 06086 } 06087 else 06088 { 06089 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 06090 rpt_mutex_unlock(&myrpt->lock); 06091 myrpt->rpt_thread = AST_PTHREADT_STOP; 06092 pthread_exit(NULL); 06093 } 06094 if (myrpt->txchanname) 06095 { 06096 ast_copy_string(tmpstr,myrpt->txchanname,sizeof(tmpstr)); 06097 tele = strchr(tmpstr,'/'); 06098 if (!tele) 06099 { 06100 fprintf(stderr,"rpt:Txchannel Dial number (%s) must be in format tech/number\n",myrpt->txchanname); 06101 rpt_mutex_unlock(&myrpt->lock); 06102 ast_hangup(myrpt->rxchannel); 06103 myrpt->rpt_thread = AST_PTHREADT_STOP; 06104 pthread_exit(NULL); 06105 } 06106 *tele++ = 0; 06107 myrpt->txchannel = ast_request(tmpstr,AST_FORMAT_SLINEAR,tele,NULL); 06108 if (myrpt->txchannel) 06109 { 06110 if (myrpt->txchannel->_state == AST_STATE_BUSY) 06111 { 06112 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 06113 rpt_mutex_unlock(&myrpt->lock); 06114 ast_hangup(myrpt->txchannel); 06115 ast_hangup(myrpt->rxchannel); 06116 myrpt->rpt_thread = AST_PTHREADT_STOP; 06117 pthread_exit(NULL); 06118 } 06119 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 06120 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 06121 myrpt->txchannel->whentohangup = 0; 06122 myrpt->txchannel->appl = "Apprpt"; 06123 myrpt->txchannel->data = "(Repeater Tx)"; 06124 if (option_verbose > 2) 06125 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 06126 tmpstr,tele,myrpt->txchannel->name); 06127 ast_call(myrpt->txchannel,tele,999); 06128 if (myrpt->rxchannel->_state != AST_STATE_UP) 06129 { 06130 rpt_mutex_unlock(&myrpt->lock); 06131 ast_hangup(myrpt->rxchannel); 06132 ast_hangup(myrpt->txchannel); 06133 myrpt->rpt_thread = AST_PTHREADT_STOP; 06134 pthread_exit(NULL); 06135 } 06136 } 06137 else 06138 { 06139 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 06140 rpt_mutex_unlock(&myrpt->lock); 06141 ast_hangup(myrpt->rxchannel); 06142 myrpt->rpt_thread = AST_PTHREADT_STOP; 06143 pthread_exit(NULL); 06144 } 06145 } 06146 else 06147 { 06148 myrpt->txchannel = myrpt->rxchannel; 06149 } 06150 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 06151 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 06152 /* allocate a pseudo-channel thru asterisk */ 06153 myrpt->pchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 06154 if (!myrpt->pchannel) 06155 { 06156 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 06157 rpt_mutex_unlock(&myrpt->lock); 06158 if (myrpt->txchannel != myrpt->rxchannel) 06159 ast_hangup(myrpt->txchannel); 06160 ast_hangup(myrpt->rxchannel); 06161 myrpt->rpt_thread = AST_PTHREADT_STOP; 06162 pthread_exit(NULL); 06163 } 06164 /* make a conference for the tx */ 06165 ci.chan = 0; 06166 ci.confno = -1; /* make a new conf */ 06167 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER; 06168 /* first put the channel on the conference in proper mode */ 06169 if (ioctl(myrpt->txchannel->fds[0],ZT_SETCONF,&ci) == -1) 06170 { 06171 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 06172 rpt_mutex_unlock(&myrpt->lock); 06173 ast_hangup(myrpt->pchannel); 06174 if (myrpt->txchannel != myrpt->rxchannel) 06175 ast_hangup(myrpt->txchannel); 06176 ast_hangup(myrpt->rxchannel); 06177 myrpt->rpt_thread = AST_PTHREADT_STOP; 06178 pthread_exit(NULL); 06179 } 06180 /* save tx conference number */ 06181 myrpt->txconf = ci.confno; 06182 /* make a conference for the pseudo */ 06183 ci.chan = 0; 06184 ci.confno = -1; /* make a new conf */ 06185 ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON : 06186 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 06187 /* first put the channel on the conference in announce mode */ 06188 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 06189 { 06190 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 06191 rpt_mutex_unlock(&myrpt->lock); 06192 ast_hangup(myrpt->pchannel); 06193 if (myrpt->txchannel != myrpt->rxchannel) 06194 ast_hangup(myrpt->txchannel); 06195 ast_hangup(myrpt->rxchannel); 06196 myrpt->rpt_thread = AST_PTHREADT_STOP; 06197 pthread_exit(NULL); 06198 } 06199 /* save pseudo channel conference number */ 06200 myrpt->conf = ci.confno; 06201 /* allocate a pseudo-channel thru asterisk */ 06202 myrpt->txpchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 06203 if (!myrpt->txpchannel) 06204 { 06205 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 06206 rpt_mutex_unlock(&myrpt->lock); 06207 ast_hangup(myrpt->pchannel); 06208 if (myrpt->txchannel != myrpt->rxchannel) 06209 ast_hangup(myrpt->txchannel); 06210 ast_hangup(myrpt->rxchannel); 06211 myrpt->rpt_thread = AST_PTHREADT_STOP; 06212 pthread_exit(NULL); 06213 } 06214 /* make a conference for the tx */ 06215 ci.chan = 0; 06216 ci.confno = myrpt->txconf; 06217 ci.confmode = ZT_CONF_CONF | ZT_CONF_TALKER ; 06218 /* first put the channel on the conference in proper mode */ 06219 if (ioctl(myrpt->txpchannel->fds[0],ZT_SETCONF,&ci) == -1) 06220 { 06221 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 06222 rpt_mutex_unlock(&myrpt->lock); 06223 ast_hangup(myrpt->txpchannel); 06224 ast_hangup(myrpt->pchannel); 06225 if (myrpt->txchannel != myrpt->rxchannel) 06226 ast_hangup(myrpt->txchannel); 06227 ast_hangup(myrpt->rxchannel); 06228 myrpt->rpt_thread = AST_PTHREADT_STOP; 06229 pthread_exit(NULL); 06230 } 06231 /* Now, the idea here is to copy from the physical rx channel buffer 06232 into the pseudo tx buffer, and from the pseudo rx buffer into the 06233 tx channel buffer */ 06234 myrpt->links.next = &myrpt->links; 06235 myrpt->links.prev = &myrpt->links; 06236 myrpt->tailtimer = 0; 06237 myrpt->totimer = 0; 06238 myrpt->tmsgtimer = myrpt->p.tailmessagetime; 06239 myrpt->idtimer = myrpt->p.politeid; 06240 myrpt->mustid = myrpt->tailid = 0; 06241 myrpt->callmode = 0; 06242 myrpt->tounkeyed = 0; 06243 myrpt->tonotify = 0; 06244 myrpt->retxtimer = 0; 06245 myrpt->skedtimer = 0; 06246 myrpt->tailevent = 0; 06247 lasttx = 0; 06248 myrpt->keyed = 0; 06249 idtalkover = ast_variable_retrieve(myrpt->cfg, myrpt->name, "idtalkover"); 06250 myrpt->dtmfidx = -1; 06251 myrpt->dtmfbuf[0] = 0; 06252 myrpt->rem_dtmfidx = -1; 06253 myrpt->rem_dtmfbuf[0] = 0; 06254 myrpt->dtmf_time = 0; 06255 myrpt->rem_dtmf_time = 0; 06256 myrpt->enable = 1; 06257 myrpt->disgorgetime = 0; 06258 myrpt->lastnodewhichkeyedusup[0] = '\0'; 06259 myrpt->dailytxtime = 0; 06260 myrpt->totaltxtime = 0; 06261 myrpt->dailykeyups = 0; 06262 myrpt->totalkeyups = 0; 06263 myrpt->dailykerchunks = 0; 06264 myrpt->totalkerchunks = 0; 06265 myrpt->dailyexecdcommands = 0; 06266 myrpt->totalexecdcommands = 0; 06267 myrpt->timeouts = 0; 06268 myrpt->exten[0] = '\0'; 06269 myrpt->lastdtmfcommand[0] = '\0'; 06270 if (myrpt->p.startupmacro) 06271 { 06272 snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro); 06273 } 06274 rpt_mutex_unlock(&myrpt->lock); 06275 val = 0; 06276 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_TONE_VERIFY,&val,sizeof(char),0); 06277 val = 1; 06278 ast_channel_setoption(myrpt->rxchannel,AST_OPTION_RELAXDTMF,&val,sizeof(char),0); 06279 while (ms >= 0) 06280 { 06281 struct ast_frame *f; 06282 struct ast_channel *cs[300]; 06283 int totx=0,elap=0,n,toexit=0; 06284 06285 /* DEBUG Dump */ 06286 if((myrpt->disgorgetime) && (time(NULL) >= myrpt->disgorgetime)){ 06287 struct rpt_link *zl; 06288 struct rpt_tele *zt; 06289 06290 myrpt->disgorgetime = 0; 06291 ast_log(LOG_NOTICE,"********** Variable Dump Start (app_rpt) **********\n"); 06292 ast_log(LOG_NOTICE,"totx = %d\n",totx); 06293 ast_log(LOG_NOTICE,"remrx = %d\n",remrx); 06294 ast_log(LOG_NOTICE,"lasttx = %d\n",lasttx); 06295 ast_log(LOG_NOTICE,"elap = %d\n",elap); 06296 ast_log(LOG_NOTICE,"toexit = %d\n",toexit); 06297 06298 ast_log(LOG_NOTICE,"myrpt->keyed = %d\n",myrpt->keyed); 06299 ast_log(LOG_NOTICE,"myrpt->localtx = %d\n",myrpt->localtx); 06300 ast_log(LOG_NOTICE,"myrpt->callmode = %d\n",myrpt->callmode); 06301 ast_log(LOG_NOTICE,"myrpt->enable = %d\n",myrpt->enable); 06302 ast_log(LOG_NOTICE,"myrpt->mustid = %d\n",myrpt->mustid); 06303 ast_log(LOG_NOTICE,"myrpt->tounkeyed = %d\n",myrpt->tounkeyed); 06304 ast_log(LOG_NOTICE,"myrpt->tonotify = %d\n",myrpt->tonotify); 06305 ast_log(LOG_NOTICE,"myrpt->retxtimer = %ld\n",myrpt->retxtimer); 06306 ast_log(LOG_NOTICE,"myrpt->totimer = %d\n",myrpt->totimer); 06307 ast_log(LOG_NOTICE,"myrpt->tailtimer = %d\n",myrpt->tailtimer); 06308 ast_log(LOG_NOTICE,"myrpt->tailevent = %d\n",myrpt->tailevent); 06309 06310 zl = myrpt->links.next; 06311 while(zl != &myrpt->links){ 06312 ast_log(LOG_NOTICE,"*** Link Name: %s ***\n",zl->name); 06313 ast_log(LOG_NOTICE," link->lasttx %d\n",zl->lasttx); 06314 ast_log(LOG_NOTICE," link->lastrx %d\n",zl->lastrx); 06315 ast_log(LOG_NOTICE," link->connected %d\n",zl->connected); 06316 ast_log(LOG_NOTICE," link->hasconnected %d\n",zl->hasconnected); 06317 ast_log(LOG_NOTICE," link->outbound %d\n",zl->outbound); 06318 ast_log(LOG_NOTICE," link->disced %d\n",zl->disced); 06319 ast_log(LOG_NOTICE," link->killme %d\n",zl->killme); 06320 ast_log(LOG_NOTICE," link->disctime %ld\n",zl->disctime); 06321 ast_log(LOG_NOTICE," link->retrytimer %ld\n",zl->retrytimer); 06322 ast_log(LOG_NOTICE," link->retries = %d\n",zl->retries); 06323 ast_log(LOG_NOTICE," link->reconnects = %d\n",zl->reconnects); 06324 zl = zl->next; 06325 } 06326 06327 zt = myrpt->tele.next; 06328 if(zt != &myrpt->tele) 06329 ast_log(LOG_NOTICE,"*** Telemetry Queue ***\n"); 06330 while(zt != &myrpt->tele){ 06331 ast_log(LOG_NOTICE," Telemetry mode: %d\n",zt->mode); 06332 zt = zt->next; 06333 } 06334 ast_log(LOG_NOTICE,"******* Variable Dump End (app_rpt) *******\n"); 06335 06336 } 06337 06338 06339 if (myrpt->reload) 06340 { 06341 struct rpt_tele *telem; 06342 06343 rpt_mutex_lock(&myrpt->lock); 06344 telem = myrpt->tele.next; 06345 while(telem != &myrpt->tele) 06346 { 06347 ast_softhangup(telem->chan,AST_SOFTHANGUP_DEV); 06348 telem = telem->next; 06349 } 06350 myrpt->reload = 0; 06351 rpt_mutex_unlock(&myrpt->lock); 06352 usleep(10000); 06353 /* find our index, and load the vars */ 06354 for(i = 0; i < nrpts; i++) 06355 { 06356 if (&rpt_vars[i] == myrpt) 06357 { 06358 load_rpt_vars(i,0); 06359 break; 06360 } 06361 } 06362 } 06363 06364 rpt_mutex_lock(&myrpt->lock); 06365 if (ast_check_hangup(myrpt->rxchannel)) break; 06366 if (ast_check_hangup(myrpt->txchannel)) break; 06367 if (ast_check_hangup(myrpt->pchannel)) break; 06368 if (ast_check_hangup(myrpt->txpchannel)) break; 06369 06370 /* Update local tx with keyed if not parsing a command */ 06371 myrpt->localtx = myrpt->keyed && (myrpt->dtmfidx == -1) && (!myrpt->cmdnode[0]); 06372 /* If someone's connected, and they're transmitting from their end to us, set remrx true */ 06373 l = myrpt->links.next; 06374 remrx = 0; 06375 while(l != &myrpt->links) 06376 { 06377 if (l->lastrx){ 06378 remrx = 1; 06379 if(l->name[0] != '0') /* Ignore '0' nodes */ 06380 strcpy(myrpt->lastnodewhichkeyedusup, l->name); /* Note the node which is doing the key up */ 06381 } 06382 l = l->next; 06383 } 06384 /* Create a "must_id" flag for the cleanup ID */ 06385 myrpt->mustid |= (myrpt->idtimer) && (myrpt->keyed || remrx) ; 06386 /* Build a fresh totx from myrpt->keyed and autopatch activated */ 06387 totx = myrpt->callmode; 06388 /* If full duplex, add local tx to totx */ 06389 if (myrpt->p.duplex > 1) totx = totx || myrpt->localtx; 06390 /* Traverse the telemetry list to see what's queued */ 06391 identqueued = 0; 06392 othertelemqueued = 0; 06393 tailmessagequeued = 0; 06394 ctqueued = 0; 06395 telem = myrpt->tele.next; 06396 while(telem != &myrpt->tele) 06397 { 06398 if((telem->mode == ID) || (telem->mode == IDTALKOVER)){ 06399 identqueued = 1; /* Identification telemetry */ 06400 } 06401 else if(telem->mode == TAILMSG) 06402 { 06403 tailmessagequeued = 1; /* Tail message telemetry */ 06404 } 06405 else 06406 { 06407 if (telem->mode != UNKEY) 06408 othertelemqueued = 1; /* Other telemetry */ 06409 else 06410 ctqueued = 1; /* Courtesy tone telemetry */ 06411 } 06412 telem = telem->next; 06413 } 06414 06415 /* Add in any "other" telemetry, if 3/4 or full duplex */ 06416 if (myrpt->p.duplex > 0) totx = totx || othertelemqueued; 06417 /* Update external (to links) transmitter PTT state with everything but ID, CT, and tailmessage telemetry */ 06418 myrpt->exttx = totx; 06419 /* If half or 3/4 duplex, add localtx to external link tx */ 06420 if (myrpt->p.duplex < 2) myrpt->exttx = myrpt->exttx || myrpt->localtx; 06421 /* Add in ID telemetry to local transmitter */ 06422 totx = totx || remrx; 06423 /* If 3/4 or full duplex, add in ident and CT telemetry */ 06424 if (myrpt->p.duplex > 0) 06425 totx = totx || identqueued || ctqueued; 06426 /* Reset time out timer variables if there is no activity */ 06427 if (!totx) 06428 { 06429 myrpt->totimer = myrpt->p.totime; 06430 myrpt->tounkeyed = 0; 06431 myrpt->tonotify = 0; 06432 } 06433 else 06434 myrpt->tailtimer = myrpt->p.hangtime; /* Initialize tail timer */ 06435 /* Disable the local transmitter if we are timed out */ 06436 totx = totx && myrpt->totimer; 06437 /* if timed-out and not said already, say it */ 06438 if ((!myrpt->totimer) && (!myrpt->tonotify)) 06439 { 06440 myrpt->tonotify = 1; 06441 myrpt->timeouts++; 06442 rpt_mutex_unlock(&myrpt->lock); 06443 rpt_telemetry(myrpt,TIMEOUT,NULL); 06444 rpt_mutex_lock(&myrpt->lock); 06445 } 06446 06447 /* If unkey and re-key, reset time out timer */ 06448 if ((!totx) && (!myrpt->totimer) && (!myrpt->tounkeyed) && (!myrpt->keyed)) 06449 { 06450 myrpt->tounkeyed = 1; 06451 } 06452 if ((!totx) && (!myrpt->totimer) && myrpt->tounkeyed && myrpt->keyed) 06453 { 06454 myrpt->totimer = myrpt->p.totime; 06455 myrpt->tounkeyed = 0; 06456 myrpt->tonotify = 0; 06457 rpt_mutex_unlock(&myrpt->lock); 06458 continue; 06459 } 06460 /* if timed-out and in circuit busy after call */ 06461 if ((!totx) && (!myrpt->totimer) && (myrpt->callmode == 4)) 06462 { 06463 myrpt->callmode = 0; 06464 } 06465 /* get rid of tail if timed out */ 06466 if (!myrpt->totimer) myrpt->tailtimer = 0; 06467 /* if not timed-out, add in tail */ 06468 if (myrpt->totimer) totx = totx || myrpt->tailtimer; 06469 /* If user or links key up or are keyed up over standard ID, switch to talkover ID, if one is defined */ 06470 /* If tail message, kill the message if someone keys up over it */ 06471 if ((myrpt->keyed || remrx) && ((identqueued && idtalkover) || (tailmessagequeued))) { 06472 int hasid = 0,hastalkover = 0; 06473 06474 telem = myrpt->tele.next; 06475 while(telem != &myrpt->tele){ 06476 if(telem->mode == ID){ 06477 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 06478 hasid = 1; 06479 } 06480 if(telem->mode == TAILMSG){ 06481 if (telem->chan) ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ 06482 } 06483 if (telem->mode == IDTALKOVER) hastalkover = 1; 06484 telem = telem->next; 06485 } 06486 rpt_mutex_unlock(&myrpt->lock); 06487 if (hasid && (!hastalkover)) rpt_telemetry(myrpt, IDTALKOVER, NULL); /* Start Talkover ID */ 06488 rpt_mutex_lock(&myrpt->lock); 06489 } 06490 /* Try to be polite */ 06491 /* If the repeater has been inactive for longer than the ID time, do an initial ID in the tail*/ 06492 /* If within 30 seconds of the time to ID, try do it in the tail */ 06493 /* else if at ID time limit, do it right over the top of them */ 06494 /* Lastly, if the repeater has been keyed, and the ID timer is expired, do a clean up ID */ 06495 if(myrpt->mustid && (!myrpt->idtimer)) 06496 queue_id(myrpt); 06497 06498 if ((totx && (!myrpt->exttx) && 06499 (myrpt->idtimer <= myrpt->p.politeid) && myrpt->tailtimer)) 06500 { 06501 myrpt->tailid = 1; 06502 } 06503 06504 /* If tail timer expires, then check for tail messages */ 06505 06506 if(myrpt->tailevent){ 06507 myrpt->tailevent = 0; 06508 if(myrpt->tailid){ 06509 totx = 1; 06510 queue_id(myrpt); 06511 } 06512 else if ((myrpt->p.tailmessages[0]) && 06513 (myrpt->p.tailmessagetime) && (myrpt->tmsgtimer == 0)){ 06514 totx = 1; 06515 myrpt->tmsgtimer = myrpt->p.tailmessagetime; 06516 rpt_mutex_unlock(&myrpt->lock); 06517 rpt_telemetry(myrpt, TAILMSG, NULL); 06518 rpt_mutex_lock(&myrpt->lock); 06519 } 06520 } 06521 06522 /* Main TX control */ 06523 06524 /* let telemetry transmit anyway (regardless of timeout) */ 06525 if (myrpt->p.duplex > 0) totx = totx || (myrpt->tele.next != &myrpt->tele); 06526 if (totx && (!lasttx)) 06527 { 06528 lasttx = 1; 06529 myrpt->dailykeyups++; 06530 myrpt->totalkeyups++; 06531 rpt_mutex_unlock(&myrpt->lock); 06532 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 06533 rpt_mutex_lock(&myrpt->lock); 06534 } 06535 totx = totx && myrpt->enable; 06536 if ((!totx) && lasttx) 06537 { 06538 lasttx = 0; 06539 rpt_mutex_unlock(&myrpt->lock); 06540 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 06541 rpt_mutex_lock(&myrpt->lock); 06542 } 06543 time(&t); 06544 /* if DTMF timeout */ 06545 if ((!myrpt->cmdnode[0]) && (myrpt->dtmfidx >= 0) && ((myrpt->dtmf_time + DTMF_TIMEOUT) < t)) 06546 { 06547 myrpt->dtmfidx = -1; 06548 myrpt->dtmfbuf[0] = 0; 06549 } 06550 /* if remote DTMF timeout */ 06551 if ((myrpt->rem_dtmfidx >= 0) && ((myrpt->rem_dtmf_time + DTMF_TIMEOUT) < t)) 06552 { 06553 myrpt->rem_dtmfidx = -1; 06554 myrpt->rem_dtmfbuf[0] = 0; 06555 } 06556 06557 /* Reconnect */ 06558 06559 l = myrpt->links.next; 06560 while(l != &myrpt->links) 06561 { 06562 if (l->killme) 06563 { 06564 /* remove from queue */ 06565 remque((struct qelem *) l); 06566 if (!strcmp(myrpt->cmdnode,l->name)) 06567 myrpt->cmdnode[0] = 0; 06568 rpt_mutex_unlock(&myrpt->lock); 06569 /* hang-up on call to device */ 06570 if (l->chan) ast_hangup(l->chan); 06571 ast_hangup(l->pchan); 06572 free(l); 06573 rpt_mutex_lock(&myrpt->lock); 06574 /* re-start link traversal */ 06575 l = myrpt->links.next; 06576 continue; 06577 } 06578 l = l->next; 06579 } 06580 n = 0; 06581 cs[n++] = myrpt->rxchannel; 06582 cs[n++] = myrpt->pchannel; 06583 cs[n++] = myrpt->txpchannel; 06584 if (myrpt->txchannel != myrpt->rxchannel) cs[n++] = myrpt->txchannel; 06585 l = myrpt->links.next; 06586 while(l != &myrpt->links) 06587 { 06588 if ((!l->killme) && (!l->disctime) && l->chan) 06589 { 06590 cs[n++] = l->chan; 06591 cs[n++] = l->pchan; 06592 } 06593 l = l->next; 06594 } 06595 rpt_mutex_unlock(&myrpt->lock); 06596 ms = MSWAIT; 06597 who = ast_waitfor_n(cs,n,&ms); 06598 if (who == NULL) ms = 0; 06599 elap = MSWAIT - ms; 06600 rpt_mutex_lock(&myrpt->lock); 06601 l = myrpt->links.next; 06602 while(l != &myrpt->links) 06603 { 06604 if (!l->lasttx) 06605 { 06606 if ((l->retxtimer += elap) >= REDUNDANT_TX_TIME) 06607 { 06608 l->retxtimer = 0; 06609 if (l->chan) ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 06610 } 06611 } else l->retxtimer = 0; 06612 if (l->disctime) /* Disconnect timer active on a channel ? */ 06613 { 06614 l->disctime -= elap; 06615 if (l->disctime <= 0) /* Disconnect timer expired on inbound channel ? */ 06616 l->disctime = 0; /* Yep */ 06617 } 06618 06619 if (l->retrytimer) 06620 { 06621 l->retrytimer -= elap; 06622 if (l->retrytimer < 0) l->retrytimer = 0; 06623 } 06624 06625 /* Tally connect time */ 06626 l->connecttime += elap; 06627 06628 /* ignore non-timing channels */ 06629 if (l->elaptime < 0) 06630 { 06631 l = l->next; 06632 continue; 06633 } 06634 l->elaptime += elap; 06635 /* if connection has taken too long */ 06636 if ((l->elaptime > MAXCONNECTTIME) && 06637 ((!l->chan) || (l->chan->_state != AST_STATE_UP))) 06638 { 06639 l->elaptime = 0; 06640 rpt_mutex_unlock(&myrpt->lock); 06641 if (l->chan) ast_softhangup(l->chan,AST_SOFTHANGUP_DEV); 06642 rpt_mutex_lock(&myrpt->lock); 06643 break; 06644 } 06645 if ((!l->chan) && (!l->retrytimer) && l->outbound && 06646 (l->retries++ < MAX_RETRIES) && (l->hasconnected)) 06647 { 06648 if (l->chan) ast_hangup(l->chan); 06649 rpt_mutex_unlock(&myrpt->lock); 06650 if ((l->name[0] != '0') && (!l->isremote)) 06651 { 06652 l->retrytimer = MAX_RETRIES + 1; 06653 } 06654 else 06655 { 06656 if (attempt_reconnect(myrpt,l) == -1) 06657 { 06658 l->retrytimer = RETRY_TIMER_MS; 06659 } 06660 } 06661 rpt_mutex_lock(&myrpt->lock); 06662 break; 06663 } 06664 if ((!l->chan) && (!l->retrytimer) && l->outbound && 06665 (l->retries >= MAX_RETRIES)) 06666 { 06667 /* remove from queue */ 06668 remque((struct qelem *) l); 06669 if (!strcmp(myrpt->cmdnode,l->name)) 06670 myrpt->cmdnode[0] = 0; 06671 rpt_mutex_unlock(&myrpt->lock); 06672 if (l->name[0] != '0') 06673 { 06674 if (!l->hasconnected) 06675 rpt_telemetry(myrpt,CONNFAIL,l); 06676 else rpt_telemetry(myrpt,REMDISC,l); 06677 } 06678 /* hang-up on call to device */ 06679 ast_hangup(l->pchan); 06680 free(l); 06681 rpt_mutex_lock(&myrpt->lock); 06682 break; 06683 } 06684 if ((!l->chan) && (!l->disctime) && (!l->outbound)) 06685 { 06686 /* remove from queue */ 06687 remque((struct qelem *) l); 06688 if (!strcmp(myrpt->cmdnode,l->name)) 06689 myrpt->cmdnode[0] = 0; 06690 rpt_mutex_unlock(&myrpt->lock); 06691 if (l->name[0] != '0') 06692 { 06693 rpt_telemetry(myrpt,REMDISC,l); 06694 } 06695 /* hang-up on call to device */ 06696 ast_hangup(l->pchan); 06697 free(l); 06698 rpt_mutex_lock(&myrpt->lock); 06699 break; 06700 } 06701 l = l->next; 06702 } 06703 if(totx){ 06704 myrpt->dailytxtime += elap; 06705 myrpt->totaltxtime += elap; 06706 } 06707 i = myrpt->tailtimer; 06708 if (myrpt->tailtimer) myrpt->tailtimer -= elap; 06709 if (myrpt->tailtimer < 0) myrpt->tailtimer = 0; 06710 if((i) && (myrpt->tailtimer == 0)) 06711 myrpt->tailevent = 1; 06712 if (myrpt->totimer) myrpt->totimer -= elap; 06713 if (myrpt->totimer < 0) myrpt->totimer = 0; 06714 if (myrpt->idtimer) myrpt->idtimer -= elap; 06715 if (myrpt->idtimer < 0) myrpt->idtimer = 0; 06716 if (myrpt->tmsgtimer) myrpt->tmsgtimer -= elap; 06717 if (myrpt->tmsgtimer < 0) myrpt->tmsgtimer = 0; 06718 /* do macro timers */ 06719 if (myrpt->macrotimer) myrpt->macrotimer -= elap; 06720 if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; 06721 /* Execute scheduler appx. every 2 tenths of a second */ 06722 if (myrpt->skedtimer <= 0){ 06723 myrpt->skedtimer = 200; 06724 do_scheduler(myrpt); 06725 } 06726 else 06727 myrpt->skedtimer -=elap; 06728 if (!ms) 06729 { 06730 rpt_mutex_unlock(&myrpt->lock); 06731 continue; 06732 } 06733 c = myrpt->macrobuf[0]; 06734 if (c && (!myrpt->macrotimer)) 06735 { 06736 myrpt->macrotimer = MACROTIME; 06737 memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1); 06738 if ((c == 'p') || (c == 'P')) 06739 myrpt->macrotimer = MACROPTIME; 06740 rpt_mutex_unlock(&myrpt->lock); 06741 local_dtmf_helper(myrpt,c); 06742 } else rpt_mutex_unlock(&myrpt->lock); 06743 if (who == myrpt->rxchannel) /* if it was a read from rx */ 06744 { 06745 f = ast_read(myrpt->rxchannel); 06746 if (!f) 06747 { 06748 if (debug) printf("@@@@ rpt:Hung Up\n"); 06749 break; 06750 } 06751 if (f->frametype == AST_FRAME_VOICE) 06752 { 06753 #ifdef _MDC_DECODE_H_ 06754 unsigned char ubuf[2560]; 06755 short *sp; 06756 int n; 06757 #endif 06758 06759 if (!myrpt->localtx) { 06760 memset(f->data,0,f->datalen); 06761 } 06762 06763 #ifdef _MDC_DECODE_H_ 06764 sp = (short *) f->data; 06765 /* convert block to unsigned char */ 06766 for(n = 0; n < f->datalen / 2; n++) 06767 { 06768 ubuf[n] = (*sp++ >> 8) + 128; 06769 } 06770 n = mdc_decoder_process_samples(myrpt->mdc,ubuf,f->datalen / 2); 06771 if (n == 1) 06772 { 06773 unsigned char op,arg; 06774 unsigned short unitID; 06775 06776 mdc_decoder_get_packet(myrpt->mdc,&op,&arg,&unitID); 06777 if (debug > 2) 06778 { 06779 ast_log(LOG_NOTICE,"Got (single-length) packet:\n"); 06780 ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n", 06781 op & 255,arg & 255,unitID); 06782 } 06783 if ((op == 1) && (arg == 0)) 06784 { 06785 myrpt->lastunit = unitID; 06786 } 06787 } 06788 if ((debug > 2) && (i == 2)) 06789 { 06790 unsigned char op,arg,ex1,ex2,ex3,ex4; 06791 unsigned short unitID; 06792 06793 mdc_decoder_get_double_packet(myrpt->mdc,&op,&arg,&unitID, 06794 &ex1,&ex2,&ex3,&ex4); 06795 ast_log(LOG_NOTICE,"Got (double-length) packet:\n"); 06796 ast_log(LOG_NOTICE,"op: %02x, arg: %02x, UnitID: %04x\n", 06797 op & 255,arg & 255,unitID); 06798 ast_log(LOG_NOTICE,"ex1: %02x, ex2: %02x, ex3: %02x, ex4: %02x\n", 06799 ex1 & 255, ex2 & 255, ex3 & 255, ex4 & 255); 06800 } 06801 #endif 06802 #ifdef __RPT_NOTCH 06803 /* apply inbound filters, if any */ 06804 rpt_filter(myrpt,f->data,f->datalen / 2); 06805 #endif 06806 ast_write(myrpt->pchannel,f); 06807 } 06808 else if (f->frametype == AST_FRAME_DTMF) 06809 { 06810 c = (char) f->subclass; /* get DTMF char */ 06811 ast_frfree(f); 06812 if (!myrpt->keyed) continue; 06813 local_dtmf_helper(myrpt,c); 06814 continue; 06815 } 06816 else if (f->frametype == AST_FRAME_CONTROL) 06817 { 06818 if (f->subclass == AST_CONTROL_HANGUP) 06819 { 06820 if (debug) printf("@@@@ rpt:Hung Up\n"); 06821 ast_frfree(f); 06822 break; 06823 } 06824 /* if RX key */ 06825 if (f->subclass == AST_CONTROL_RADIO_KEY) 06826 { 06827 if ((!lasttx) || (myrpt->p.duplex > 1)) 06828 { 06829 if (debug == 7) printf("@@@@ rx key\n"); 06830 myrpt->keyed = 1; 06831 } 06832 } 06833 /* if RX un-key */ 06834 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 06835 { 06836 if ((!lasttx) || (myrpt->p.duplex > 1)) 06837 { 06838 if (debug == 7) printf("@@@@ rx un-key\n"); 06839 if(myrpt->keyed) { 06840 rpt_telemetry(myrpt,UNKEY,NULL); 06841 } 06842 myrpt->keyed = 0; 06843 } 06844 } 06845 } 06846 ast_frfree(f); 06847 continue; 06848 } 06849 if (who == myrpt->pchannel) /* if it was a read from pseudo */ 06850 { 06851 f = ast_read(myrpt->pchannel); 06852 if (!f) 06853 { 06854 if (debug) printf("@@@@ rpt:Hung Up\n"); 06855 break; 06856 } 06857 if (f->frametype == AST_FRAME_VOICE) 06858 { 06859 ast_write(myrpt->txpchannel,f); 06860 } 06861 if (f->frametype == AST_FRAME_CONTROL) 06862 { 06863 if (f->subclass == AST_CONTROL_HANGUP) 06864 { 06865 if (debug) printf("@@@@ rpt:Hung Up\n"); 06866 ast_frfree(f); 06867 break; 06868 } 06869 } 06870 ast_frfree(f); 06871 continue; 06872 } 06873 if (who == myrpt->txchannel) /* if it was a read from tx */ 06874 { 06875 f = ast_read(myrpt->txchannel); 06876 if (!f) 06877 { 06878 if (debug) printf("@@@@ rpt:Hung Up\n"); 06879 break; 06880 } 06881 if (f->frametype == AST_FRAME_CONTROL) 06882 { 06883 if (f->subclass == AST_CONTROL_HANGUP) 06884 { 06885 if (debug) printf("@@@@ rpt:Hung Up\n"); 06886 ast_frfree(f); 06887 break; 06888 } 06889 } 06890 ast_frfree(f); 06891 continue; 06892 } 06893 toexit = 0; 06894 rpt_mutex_lock(&myrpt->lock); 06895 l = myrpt->links.next; 06896 while(l != &myrpt->links) 06897 { 06898 if (l->disctime) 06899 { 06900 l = l->next; 06901 continue; 06902 } 06903 if (who == l->chan) /* if it was a read from rx */ 06904 { 06905 remrx = 0; 06906 /* see if any other links are receiving */ 06907 m = myrpt->links.next; 06908 while(m != &myrpt->links) 06909 { 06910 /* if not us, count it */ 06911 if ((m != l) && (m->lastrx)) remrx = 1; 06912 m = m->next; 06913 } 06914 rpt_mutex_unlock(&myrpt->lock); 06915 totx = (((l->isremote) ? myrpt->localtx : 06916 myrpt->exttx) || remrx) && l->mode; 06917 if (l->chan && (l->lasttx != totx)) 06918 { 06919 if (totx) 06920 { 06921 ast_indicate(l->chan,AST_CONTROL_RADIO_KEY); 06922 } 06923 else 06924 { 06925 ast_indicate(l->chan,AST_CONTROL_RADIO_UNKEY); 06926 } 06927 } 06928 l->lasttx = totx; 06929 f = ast_read(l->chan); 06930 if (!f) 06931 { 06932 if ((!l->disced) && (!l->outbound)) 06933 { 06934 if ((l->name[0] == '0') || l->isremote) 06935 l->disctime = 1; 06936 else 06937 l->disctime = DISC_TIME; 06938 rpt_mutex_lock(&myrpt->lock); 06939 ast_hangup(l->chan); 06940 l->chan = 0; 06941 break; 06942 } 06943 06944 if (l->retrytimer) 06945 { 06946 rpt_mutex_lock(&myrpt->lock); 06947 break; 06948 } 06949 if (l->outbound && (l->retries++ < MAX_RETRIES) && (l->hasconnected)) 06950 { 06951 rpt_mutex_lock(&myrpt->lock); 06952 ast_hangup(l->chan); 06953 l->chan = 0; 06954 rpt_mutex_unlock(&myrpt->lock); 06955 if (attempt_reconnect(myrpt,l) == -1) 06956 { 06957 l->retrytimer = RETRY_TIMER_MS; 06958 } 06959 rpt_mutex_lock(&myrpt->lock); 06960 break; 06961 } 06962 rpt_mutex_lock(&myrpt->lock); 06963 /* remove from queue */ 06964 remque((struct qelem *) l); 06965 if (!strcmp(myrpt->cmdnode,l->name)) 06966 myrpt->cmdnode[0] = 0; 06967 rpt_mutex_unlock(&myrpt->lock); 06968 if (!l->hasconnected) 06969 rpt_telemetry(myrpt,CONNFAIL,l); 06970 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 06971 /* hang-up on call to device */ 06972 ast_hangup(l->chan); 06973 ast_hangup(l->pchan); 06974 free(l); 06975 rpt_mutex_lock(&myrpt->lock); 06976 break; 06977 } 06978 if (f->frametype == AST_FRAME_VOICE) 06979 { 06980 if (!l->lastrx) 06981 { 06982 memset(f->data,0,f->datalen); 06983 } 06984 ast_write(l->pchan,f); 06985 } 06986 if (f->frametype == AST_FRAME_TEXT) 06987 { 06988 handle_link_data(myrpt,l,f->data); 06989 } 06990 if (f->frametype == AST_FRAME_DTMF) 06991 { 06992 handle_link_phone_dtmf(myrpt,l,f->subclass); 06993 } 06994 if (f->frametype == AST_FRAME_CONTROL) 06995 { 06996 if (f->subclass == AST_CONTROL_ANSWER) 06997 { 06998 char lconnected = l->connected; 06999 l->connected = 1; 07000 l->hasconnected = 1; 07001 l->elaptime = -1; 07002 l->retries = 0; 07003 if (!lconnected) 07004 rpt_telemetry(myrpt,CONNECTED,l); 07005 else 07006 l->reconnects++; 07007 } 07008 /* if RX key */ 07009 if (f->subclass == AST_CONTROL_RADIO_KEY) 07010 { 07011 if (debug == 7 ) printf("@@@@ rx key\n"); 07012 l->lastrx = 1; 07013 } 07014 /* if RX un-key */ 07015 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 07016 { 07017 if (debug == 7) printf("@@@@ rx un-key\n"); 07018 l->lastrx = 0; 07019 } 07020 if (f->subclass == AST_CONTROL_HANGUP) 07021 { 07022 ast_frfree(f); 07023 if ((!l->outbound) && (!l->disced)) 07024 { 07025 if ((l->name[0] == '0') || l->isremote) 07026 l->disctime = 1; 07027 else 07028 l->disctime = DISC_TIME; 07029 rpt_mutex_lock(&myrpt->lock); 07030 ast_hangup(l->chan); 07031 l->chan = 0; 07032 break; 07033 } 07034 if (l->retrytimer) 07035 { 07036 rpt_mutex_lock(&myrpt->lock); 07037 break; 07038 } 07039 if (l->outbound && (l->retries++ < MAX_RETRIES) && (l->hasconnected)) 07040 { 07041 rpt_mutex_lock(&myrpt->lock); 07042 ast_hangup(l->chan); 07043 l->chan = 0; 07044 rpt_mutex_unlock(&myrpt->lock); 07045 if (attempt_reconnect(myrpt,l) == -1) 07046 { 07047 l->retrytimer = RETRY_TIMER_MS; 07048 } 07049 rpt_mutex_lock(&myrpt->lock); 07050 break; 07051 } 07052 rpt_mutex_lock(&myrpt->lock); 07053 /* remove from queue */ 07054 remque((struct qelem *) l); 07055 if (!strcmp(myrpt->cmdnode,l->name)) 07056 myrpt->cmdnode[0] = 0; 07057 rpt_mutex_unlock(&myrpt->lock); 07058 if (!l->hasconnected) 07059 rpt_telemetry(myrpt,CONNFAIL,l); 07060 else if (l->disced != 2) rpt_telemetry(myrpt,REMDISC,l); 07061 /* hang-up on call to device */ 07062 ast_hangup(l->chan); 07063 ast_hangup(l->pchan); 07064 free(l); 07065 rpt_mutex_lock(&myrpt->lock); 07066 break; 07067 } 07068 } 07069 ast_frfree(f); 07070 rpt_mutex_lock(&myrpt->lock); 07071 break; 07072 } 07073 if (who == l->pchan) 07074 { 07075 rpt_mutex_unlock(&myrpt->lock); 07076 f = ast_read(l->pchan); 07077 if (!f) 07078 { 07079 if (debug) printf("@@@@ rpt:Hung Up\n"); 07080 toexit = 1; 07081 rpt_mutex_lock(&myrpt->lock); 07082 break; 07083 } 07084 if (f->frametype == AST_FRAME_VOICE) 07085 { 07086 if (l->chan) ast_write(l->chan,f); 07087 } 07088 if (f->frametype == AST_FRAME_CONTROL) 07089 { 07090 if (f->subclass == AST_CONTROL_HANGUP) 07091 { 07092 if (debug) printf("@@@@ rpt:Hung Up\n"); 07093 ast_frfree(f); 07094 toexit = 1; 07095 rpt_mutex_lock(&myrpt->lock); 07096 break; 07097 } 07098 } 07099 ast_frfree(f); 07100 rpt_mutex_lock(&myrpt->lock); 07101 break; 07102 } 07103 l = l->next; 07104 } 07105 rpt_mutex_unlock(&myrpt->lock); 07106 if (toexit) break; 07107 if (who == myrpt->txpchannel) /* if it was a read from remote tx */ 07108 { 07109 f = ast_read(myrpt->txpchannel); 07110 if (!f) 07111 { 07112 if (debug) printf("@@@@ rpt:Hung Up\n"); 07113 break; 07114 } 07115 if (f->frametype == AST_FRAME_CONTROL) 07116 { 07117 if (f->subclass == AST_CONTROL_HANGUP) 07118 { 07119 if (debug) printf("@@@@ rpt:Hung Up\n"); 07120 ast_frfree(f); 07121 break; 07122 } 07123 } 07124 ast_frfree(f); 07125 continue; 07126 } 07127 } 07128 usleep(100000); 07129 ast_hangup(myrpt->pchannel); 07130 ast_hangup(myrpt->txpchannel); 07131 if (myrpt->txchannel != myrpt->rxchannel) ast_hangup(myrpt->txchannel); 07132 ast_hangup(myrpt->rxchannel); 07133 rpt_mutex_lock(&myrpt->lock); 07134 l = myrpt->links.next; 07135 while(l != &myrpt->links) 07136 { 07137 struct rpt_link *ll = l; 07138 /* remove from queue */ 07139 remque((struct qelem *) l); 07140 /* hang-up on call to device */ 07141 if (l->chan) ast_hangup(l->chan); 07142 ast_hangup(l->pchan); 07143 l = l->next; 07144 free(ll); 07145 } 07146 rpt_mutex_unlock(&myrpt->lock); 07147 if (debug) printf("@@@@ rpt:Hung up channel\n"); 07148 myrpt->rpt_thread = AST_PTHREADT_STOP; 07149 pthread_exit(NULL); 07150 return NULL; 07151 }
static void* rpt_call | ( | void * | this | ) | [static] |
Definition at line 2625 of file app_rpt.c.
References accountcode, rpt::acctcode, ast_callerid_parse(), ast_channel_undefer_dtmf(), AST_FORMAT_SLINEAR, AST_FRAME_DTMF, ast_hangup(), ast_log(), ast_pbx_start(), ast_request(), ast_safe_sleep(), ast_softhangup(), AST_SOFTHANGUP_DEV, ast_string_field_set, ast_write(), rpt::callmode, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, rpt::cidx, rpt::conf, ast_channel::context, ast_frame::data, ast_frame::datalen, rpt::duplex, rpt::exten, ast_channel::exten, ast_channel::fds, ast_frame::frametype, free, rpt::lock, LOG_WARNING, ast_frame::mallocd, MSWAIT, rpt::mydtmf, name, ast_frame::offset, rpt::ourcallerid, rpt::p, rpt::patchcontext, rpt::patchdialtime, rpt::patchfarenddisconnect, rpt::patchquiet, ast_channel::pbx, rpt::pchannel, ast_channel::priority, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), ast_frame::samples, strdup, ast_frame::subclass, TERM, and rpt::tonezone.
Referenced by function_autopatchup(), and local_dtmf_helper().
02626 { 02627 ZT_CONFINFO ci; /* conference info */ 02628 struct rpt *myrpt = (struct rpt *)this; 02629 int res; 02630 struct ast_frame wf; 02631 int stopped,congstarted,dialtimer,lastcidx,aborted; 02632 struct ast_channel *mychannel,*genchannel; 02633 02634 02635 myrpt->mydtmf = 0; 02636 /* allocate a pseudo-channel thru asterisk */ 02637 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 02638 if (!mychannel) 02639 { 02640 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 02641 pthread_exit(NULL); 02642 } 02643 ci.chan = 0; 02644 ci.confno = myrpt->conf; /* use the pseudo conference */ 02645 ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER 02646 | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 02647 /* first put the channel on the conference */ 02648 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 02649 { 02650 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02651 ast_hangup(mychannel); 02652 myrpt->callmode = 0; 02653 pthread_exit(NULL); 02654 } 02655 /* allocate a pseudo-channel thru asterisk */ 02656 genchannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 02657 if (!genchannel) 02658 { 02659 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 02660 ast_hangup(mychannel); 02661 pthread_exit(NULL); 02662 } 02663 ci.chan = 0; 02664 ci.confno = myrpt->conf; 02665 ci.confmode = ZT_CONF_REALANDPSEUDO | ZT_CONF_TALKER | ZT_CONF_LISTENER 02666 | ZT_CONF_PSEUDO_TALKER | ZT_CONF_PSEUDO_LISTENER; 02667 /* first put the channel on the conference */ 02668 if (ioctl(genchannel->fds[0],ZT_SETCONF,&ci) == -1) 02669 { 02670 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02671 ast_hangup(mychannel); 02672 ast_hangup(genchannel); 02673 myrpt->callmode = 0; 02674 pthread_exit(NULL); 02675 } 02676 if (myrpt->p.tonezone && (tone_zone_set_zone(mychannel->fds[0],myrpt->p.tonezone) == -1)) 02677 { 02678 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone); 02679 ast_hangup(mychannel); 02680 ast_hangup(genchannel); 02681 myrpt->callmode = 0; 02682 pthread_exit(NULL); 02683 } 02684 if (myrpt->p.tonezone && (tone_zone_set_zone(genchannel->fds[0],myrpt->p.tonezone) == -1)) 02685 { 02686 ast_log(LOG_WARNING, "Unable to set tone zone %s\n",myrpt->p.tonezone); 02687 ast_hangup(mychannel); 02688 ast_hangup(genchannel); 02689 myrpt->callmode = 0; 02690 pthread_exit(NULL); 02691 } 02692 /* start dialtone if patchquiet is 0. Special patch modes don't send dial tone */ 02693 if ((!myrpt->patchquiet) && (tone_zone_play_tone(mychannel->fds[0],ZT_TONE_DIALTONE) < 0)) 02694 { 02695 ast_log(LOG_WARNING, "Cannot start dialtone\n"); 02696 ast_hangup(mychannel); 02697 ast_hangup(genchannel); 02698 myrpt->callmode = 0; 02699 pthread_exit(NULL); 02700 } 02701 stopped = 0; 02702 congstarted = 0; 02703 dialtimer = 0; 02704 lastcidx = 0; 02705 aborted = 0; 02706 02707 02708 while ((myrpt->callmode == 1) || (myrpt->callmode == 4)) 02709 { 02710 02711 if((myrpt->patchdialtime)&&(myrpt->callmode == 1)&&(myrpt->cidx != lastcidx)){ 02712 dialtimer = 0; 02713 lastcidx = myrpt->cidx; 02714 } 02715 02716 if((myrpt->patchdialtime)&&(dialtimer >= myrpt->patchdialtime)){ 02717 rpt_mutex_lock(&myrpt->lock); 02718 aborted = 1; 02719 myrpt->callmode = 0; 02720 rpt_mutex_unlock(&myrpt->lock); 02721 break; 02722 } 02723 02724 if ((!myrpt->patchquiet) && (!stopped) && (myrpt->callmode == 1) && (myrpt->cidx > 0)) 02725 { 02726 stopped = 1; 02727 /* stop dial tone */ 02728 tone_zone_play_tone(mychannel->fds[0],-1); 02729 } 02730 if (myrpt->callmode == 4) 02731 { 02732 if(!congstarted){ 02733 congstarted = 1; 02734 /* start congestion tone */ 02735 tone_zone_play_tone(mychannel->fds[0],ZT_TONE_CONGESTION); 02736 } 02737 } 02738 res = ast_safe_sleep(mychannel, MSWAIT); 02739 if (res < 0) 02740 { 02741 ast_hangup(mychannel); 02742 ast_hangup(genchannel); 02743 rpt_mutex_lock(&myrpt->lock); 02744 myrpt->callmode = 0; 02745 rpt_mutex_unlock(&myrpt->lock); 02746 pthread_exit(NULL); 02747 } 02748 dialtimer += MSWAIT; 02749 } 02750 /* stop any tone generation */ 02751 tone_zone_play_tone(mychannel->fds[0],-1); 02752 /* end if done */ 02753 if (!myrpt->callmode) 02754 { 02755 ast_hangup(mychannel); 02756 ast_hangup(genchannel); 02757 rpt_mutex_lock(&myrpt->lock); 02758 myrpt->callmode = 0; 02759 rpt_mutex_unlock(&myrpt->lock); 02760 if((!myrpt->patchquiet) && aborted) 02761 rpt_telemetry(myrpt, TERM, NULL); 02762 pthread_exit(NULL); 02763 } 02764 02765 if (myrpt->p.ourcallerid && *myrpt->p.ourcallerid){ 02766 char *name, *loc, *instr; 02767 instr = strdup(myrpt->p.ourcallerid); 02768 if(instr){ 02769 ast_callerid_parse(instr, &name, &loc); 02770 if(loc){ 02771 if(mychannel->cid.cid_num) 02772 free(mychannel->cid.cid_num); 02773 mychannel->cid.cid_num = strdup(loc); 02774 } 02775 if(name){ 02776 if(mychannel->cid.cid_name) 02777 free(mychannel->cid.cid_name); 02778 mychannel->cid.cid_name = strdup(name); 02779 } 02780 free(instr); 02781 } 02782 } 02783 02784 ast_copy_string(mychannel->exten, myrpt->exten, sizeof(mychannel->exten)); 02785 ast_copy_string(mychannel->context, myrpt->patchcontext, sizeof(mychannel->context)); 02786 02787 if (myrpt->p.acctcode) 02788 ast_string_field_set(mychannel, accountcode, myrpt->p.acctcode); 02789 mychannel->priority = 1; 02790 ast_channel_undefer_dtmf(mychannel); 02791 if (ast_pbx_start(mychannel) < 0) 02792 { 02793 ast_log(LOG_WARNING, "Unable to start PBX!!\n"); 02794 ast_hangup(mychannel); 02795 ast_hangup(genchannel); 02796 rpt_mutex_lock(&myrpt->lock); 02797 myrpt->callmode = 0; 02798 rpt_mutex_unlock(&myrpt->lock); 02799 pthread_exit(NULL); 02800 } 02801 usleep(10000); 02802 rpt_mutex_lock(&myrpt->lock); 02803 myrpt->callmode = 3; 02804 /* set appropriate conference for the pseudo */ 02805 ci.chan = 0; 02806 ci.confno = myrpt->conf; 02807 ci.confmode = (myrpt->p.duplex == 2) ? ZT_CONF_CONFANNMON : 02808 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 02809 /* first put the channel on the conference in announce mode */ 02810 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 02811 { 02812 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02813 ast_hangup(mychannel); 02814 ast_hangup(genchannel); 02815 myrpt->callmode = 0; 02816 pthread_exit(NULL); 02817 } 02818 while(myrpt->callmode) 02819 { 02820 if ((!mychannel->pbx) && (myrpt->callmode != 4)) 02821 { 02822 if(myrpt->patchfarenddisconnect){ /* If patch is setup for far end disconnect */ 02823 myrpt->callmode = 0; 02824 if(!myrpt->patchquiet){ 02825 rpt_mutex_unlock(&myrpt->lock); 02826 rpt_telemetry(myrpt, TERM, NULL); 02827 rpt_mutex_lock(&myrpt->lock); 02828 } 02829 } 02830 else{ /* Send congestion until patch is downed by command */ 02831 myrpt->callmode = 4; 02832 rpt_mutex_unlock(&myrpt->lock); 02833 /* start congestion tone */ 02834 tone_zone_play_tone(genchannel->fds[0],ZT_TONE_CONGESTION); 02835 rpt_mutex_lock(&myrpt->lock); 02836 } 02837 } 02838 if (myrpt->mydtmf) 02839 { 02840 wf.frametype = AST_FRAME_DTMF; 02841 wf.subclass = myrpt->mydtmf; 02842 wf.offset = 0; 02843 wf.mallocd = 0; 02844 wf.data = NULL; 02845 wf.datalen = 0; 02846 wf.samples = 0; 02847 rpt_mutex_unlock(&myrpt->lock); 02848 ast_write(genchannel,&wf); 02849 rpt_mutex_lock(&myrpt->lock); 02850 myrpt->mydtmf = 0; 02851 } 02852 rpt_mutex_unlock(&myrpt->lock); 02853 usleep(MSWAIT * 1000); 02854 rpt_mutex_lock(&myrpt->lock); 02855 } 02856 rpt_mutex_unlock(&myrpt->lock); 02857 tone_zone_play_tone(genchannel->fds[0],-1); 02858 if (mychannel->pbx) ast_softhangup(mychannel,AST_SOFTHANGUP_DEV); 02859 ast_hangup(genchannel); 02860 rpt_mutex_lock(&myrpt->lock); 02861 myrpt->callmode = 0; 02862 rpt_mutex_unlock(&myrpt->lock); 02863 /* set appropriate conference for the pseudo */ 02864 ci.chan = 0; 02865 ci.confno = myrpt->conf; 02866 ci.confmode = ((myrpt->p.duplex == 2) || (myrpt->p.duplex == 4)) ? ZT_CONF_CONFANNMON : 02867 (ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER); 02868 /* first put the channel on the conference in announce mode */ 02869 if (ioctl(myrpt->pchannel->fds[0],ZT_SETCONF,&ci) == -1) 02870 { 02871 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02872 } 02873 pthread_exit(NULL); 02874 }
static int rpt_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1159 of file app_rpt.c.
References ast_cli(), myatoi(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01160 { 01161 int newlevel; 01162 01163 if (argc != 4) 01164 return RESULT_SHOWUSAGE; 01165 newlevel = myatoi(argv[3]); 01166 if((newlevel < 0) || (newlevel > 7)) 01167 return RESULT_SHOWUSAGE; 01168 if(newlevel) 01169 ast_cli(fd, "app_rpt Debugging enabled, previous level: %d, new level: %d\n", debug, newlevel); 01170 else 01171 ast_cli(fd, "app_rpt Debugging disabled\n"); 01172 01173 debug = newlevel; 01174 return RESULT_SUCCESS; 01175 }
static int rpt_do_dump | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1181 of file app_rpt.c.
References ast_cli(), name, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, and rpt_vars.
01182 { 01183 int i; 01184 01185 if (argc != 3) 01186 return RESULT_SHOWUSAGE; 01187 01188 for(i = 0; i < nrpts; i++) 01189 { 01190 if (!strcmp(argv[2],rpt_vars[i].name)) 01191 { 01192 rpt_vars[i].disgorgetime = time(NULL) + 10; /* Do it 10 seconds later */ 01193 ast_cli(fd, "app_rpt struct dump requested for node %s\n",argv[2]); 01194 return RESULT_SUCCESS; 01195 } 01196 } 01197 return RESULT_FAILURE; 01198 }
static int rpt_do_lstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1393 of file app_rpt.c.
References ast_cli(), ast_log(), rpt_link::chan, rpt_lstat::connecttime, rpt_link::connecttime, free, rpt::links, rpt::lock, LOG_ERROR, malloc, MAXPEERSTR, MAXREMSTR, rpt_link::mode, rpt_link::name, name, rpt_link::next, rpt_lstat::next, rpt_link::outbound, pbx_substitute_variables_helper(), rpt_lstat::prev, rpt_link::reconnects, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, s, and t.
01394 { 01395 int i,j; 01396 struct rpt *myrpt; 01397 struct rpt_link *l; 01398 struct rpt_lstat *s,*t; 01399 struct rpt_lstat s_head; 01400 if(argc != 3) 01401 return RESULT_SHOWUSAGE; 01402 01403 s = NULL; 01404 s_head.next = &s_head; 01405 s_head.prev = &s_head; 01406 01407 for(i = 0; i < nrpts; i++) 01408 { 01409 if (!strcmp(argv[2],rpt_vars[i].name)){ 01410 /* Make a copy of all stat variables while locked */ 01411 myrpt = &rpt_vars[i]; 01412 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 01413 /* Traverse the list of connected nodes */ 01414 j = 0; 01415 l = myrpt->links.next; 01416 while(l != &myrpt->links){ 01417 if (l->name[0] == '0'){ /* Skip '0' nodes */ 01418 l = l->next; 01419 continue; 01420 } 01421 if((s = (struct rpt_lstat *) malloc(sizeof(struct rpt_lstat))) == NULL){ 01422 ast_log(LOG_ERROR, "Malloc failed in rpt_do_lstats\n"); 01423 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 01424 return RESULT_FAILURE; 01425 } 01426 memset(s, 0, sizeof(struct rpt_lstat)); 01427 ast_copy_string(s->name, l->name, MAXREMSTR); 01428 pbx_substitute_variables_helper(l->chan, "${IAXPEER(CURRENTCHANNEL)}", s->peer, MAXPEERSTR - 1); 01429 s->mode = l->mode; 01430 s->outbound = l->outbound; 01431 s->reconnects = l->reconnects; 01432 s->connecttime = l->connecttime; 01433 insque((struct qelem *) s, (struct qelem *) s_head.next); 01434 l = l->next; 01435 } 01436 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 01437 ast_cli(fd, "NODE PEER RECONNECTS DIRECTION CONNECT TIME\n"); 01438 ast_cli(fd, "---- ---- ---------- --------- ------------\n"); 01439 01440 for(s = s_head.next; s != &s_head; s = s->next){ 01441 int hours, minutes, seconds; 01442 long long connecttime = s->connecttime; 01443 char conntime[31]; 01444 hours = (int) connecttime/3600000; 01445 connecttime %= 3600000; 01446 minutes = (int) connecttime/60000; 01447 connecttime %= 60000; 01448 seconds = (int) connecttime/1000; 01449 connecttime %= 1000; 01450 snprintf(conntime, 30, "%02d:%02d:%02d.%d", 01451 hours, minutes, seconds, (int) connecttime); 01452 conntime[30] = 0; 01453 ast_cli(fd, "%-10s%-20s%-12d%-11s%-30s\n", 01454 s->name, s->peer, s->reconnects, (s->outbound)? "OUT":"IN", conntime); 01455 } 01456 /* destroy our local link queue */ 01457 s = s_head.next; 01458 while(s != &s_head){ 01459 t = s; 01460 s = s->next; 01461 remque((struct qelem *)t); 01462 free(t); 01463 } 01464 return RESULT_SUCCESS; 01465 } 01466 } 01467 return RESULT_FAILURE; 01468 }
static int rpt_do_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1474 of file app_rpt.c.
References reload(), RESULT_FAILURE, RESULT_SHOWUSAGE, and rpt_vars.
01475 { 01476 int n; 01477 01478 if (argc > 2) return RESULT_SHOWUSAGE; 01479 01480 for(n = 0; n < nrpts; n++) rpt_vars[n].reload = 1; 01481 01482 return RESULT_FAILURE; 01483 }
static int rpt_do_restart | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1489 of file app_rpt.c.
References ast_softhangup(), AST_SOFTHANGUP_DEV, RESULT_FAILURE, RESULT_SHOWUSAGE, and rpt_vars.
01490 { 01491 int i; 01492 01493 if (argc > 2) return RESULT_SHOWUSAGE; 01494 for(i = 0; i < nrpts; i++) 01495 { 01496 if (rpt_vars[i].rxchannel) ast_softhangup(rpt_vars[i].rxchannel,AST_SOFTHANGUP_DEV); 01497 } 01498 return RESULT_FAILURE; 01499 }
static int rpt_do_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1204 of file app_rpt.c.
References ast_cli(), ast_strdupa, rpt::callmode, rpt::dailyexecdcommands, rpt::dailykerchunks, rpt::dailykeyups, rpt::dailytxtime, rpt::enable, rpt::exten, rpt::keyed, rpt::lastdtmfcommand, rpt::lastnodewhichkeyedusup, rpt::links, rpt::lock, MAX_STAT_LINKS, rpt::mustid, rpt::name, rpt_link::name, name, rpt_link::next, rpt::p, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, rpt_mutex_lock, rpt_mutex_unlock, rpt_vars, rpt::tailid, rpt::timeouts, rpt::totalexecdcommands, rpt::totalkerchunks, rpt::totalkeyups, rpt::totaltxtime, rpt::totime, and rpt::totimer.
01205 { 01206 int i,j; 01207 int dailytxtime, dailykerchunks; 01208 int totalkerchunks, dailykeyups, totalkeyups, timeouts; 01209 int totalexecdcommands, dailyexecdcommands, hours, minutes, seconds; 01210 long long totaltxtime; 01211 struct rpt_link *l; 01212 char *listoflinks[MAX_STAT_LINKS]; 01213 char *lastnodewhichkeyedusup, *lastdtmfcommand; 01214 char *tot_state, *ider_state, *patch_state; 01215 char *reverse_patch_state, *enable_state, *input_signal, *called_number; 01216 struct rpt *myrpt; 01217 01218 static char *not_applicable = "N/A"; 01219 01220 if(argc != 3) 01221 return RESULT_SHOWUSAGE; 01222 01223 for(i = 0 ; i <= MAX_STAT_LINKS; i++) 01224 listoflinks[i] = NULL; 01225 01226 tot_state = ider_state = 01227 patch_state = reverse_patch_state = 01228 input_signal = called_number = 01229 lastdtmfcommand = not_applicable; 01230 01231 for(i = 0; i < nrpts; i++) 01232 { 01233 if (!strcmp(argv[2],rpt_vars[i].name)){ 01234 /* Make a copy of all stat variables while locked */ 01235 myrpt = &rpt_vars[i]; 01236 rpt_mutex_lock(&myrpt->lock); /* LOCK */ 01237 01238 dailytxtime = myrpt->dailytxtime; 01239 totaltxtime = myrpt->totaltxtime; 01240 dailykeyups = myrpt->dailykeyups; 01241 totalkeyups = myrpt->totalkeyups; 01242 dailykerchunks = myrpt->dailykerchunks; 01243 totalkerchunks = myrpt->totalkerchunks; 01244 dailyexecdcommands = myrpt->dailyexecdcommands; 01245 totalexecdcommands = myrpt->totalexecdcommands; 01246 timeouts = myrpt->timeouts; 01247 01248 /* Traverse the list of connected nodes */ 01249 reverse_patch_state = "DOWN"; 01250 j = 0; 01251 l = myrpt->links.next; 01252 while(l != &myrpt->links){ 01253 if (l->name[0] == '0'){ /* Skip '0' nodes */ 01254 reverse_patch_state = "UP"; 01255 l = l->next; 01256 continue; 01257 } 01258 listoflinks[j] = ast_strdupa(l->name); 01259 if(listoflinks[j]) 01260 j++; 01261 l = l->next; 01262 } 01263 01264 lastnodewhichkeyedusup = ast_strdupa(myrpt->lastnodewhichkeyedusup); 01265 if((!lastnodewhichkeyedusup) || (!strlen(lastnodewhichkeyedusup))) 01266 lastnodewhichkeyedusup = not_applicable; 01267 01268 if(myrpt->keyed) 01269 input_signal = "YES"; 01270 else 01271 input_signal = "NO"; 01272 01273 if(myrpt->enable) 01274 enable_state = "YES"; 01275 else 01276 enable_state = "NO"; 01277 01278 if(!myrpt->totimer) 01279 tot_state = "TIMED OUT!"; 01280 else if(myrpt->totimer != myrpt->p.totime) 01281 tot_state = "ARMED"; 01282 else 01283 tot_state = "RESET"; 01284 01285 if(myrpt->tailid) 01286 ider_state = "QUEUED IN TAIL"; 01287 else if(myrpt->mustid) 01288 ider_state = "QUEUED FOR CLEANUP"; 01289 else 01290 ider_state = "CLEAN"; 01291 01292 switch(myrpt->callmode){ 01293 case 1: 01294 patch_state = "DIALING"; 01295 break; 01296 case 2: 01297 patch_state = "CONNECTING"; 01298 break; 01299 case 3: 01300 patch_state = "UP"; 01301 break; 01302 01303 case 4: 01304 patch_state = "CALL FAILED"; 01305 break; 01306 01307 default: 01308 patch_state = "DOWN"; 01309 } 01310 01311 if(strlen(myrpt->exten)){ 01312 called_number = ast_strdupa(myrpt->exten); 01313 if(!called_number) 01314 called_number = not_applicable; 01315 } 01316 01317 if(strlen(myrpt->lastdtmfcommand)){ 01318 lastdtmfcommand = ast_strdupa(myrpt->lastdtmfcommand); 01319 if(!lastdtmfcommand) 01320 lastdtmfcommand = not_applicable; 01321 } 01322 01323 rpt_mutex_unlock(&myrpt->lock); /* UNLOCK */ 01324 01325 ast_cli(fd, "************************ NODE %s STATISTICS *************************\n\n", myrpt->name); 01326 ast_cli(fd, "Signal on input..................................: %s\n", input_signal); 01327 ast_cli(fd, "Transmitter enabled..............................: %s\n", enable_state); 01328 ast_cli(fd, "Time out timer state.............................: %s\n", tot_state); 01329 ast_cli(fd, "Time outs since system initialization............: %d\n", timeouts); 01330 ast_cli(fd, "Identifier state.................................: %s\n", ider_state); 01331 ast_cli(fd, "Kerchunks today..................................: %d\n", dailykerchunks); 01332 ast_cli(fd, "Kerchunks since system initialization............: %d\n", totalkerchunks); 01333 ast_cli(fd, "Keyups today.....................................: %d\n", dailykeyups); 01334 ast_cli(fd, "Keyups since system initialization...............: %d\n", totalkeyups); 01335 ast_cli(fd, "DTMF commands today..............................: %d\n", dailyexecdcommands); 01336 ast_cli(fd, "DTMF commands since system initialization........: %d\n", totalexecdcommands); 01337 ast_cli(fd, "Last DTMF command executed.......................: %s\n", lastdtmfcommand); 01338 01339 hours = dailytxtime/3600000; 01340 dailytxtime %= 3600000; 01341 minutes = dailytxtime/60000; 01342 dailytxtime %= 60000; 01343 seconds = dailytxtime/1000; 01344 dailytxtime %= 1000; 01345 01346 ast_cli(fd, "TX time today ...................................: %02d:%02d:%02d.%d\n", 01347 hours, minutes, seconds, dailytxtime); 01348 01349 hours = (int) totaltxtime/3600000; 01350 totaltxtime %= 3600000; 01351 minutes = (int) totaltxtime/60000; 01352 totaltxtime %= 60000; 01353 seconds = (int) totaltxtime/1000; 01354 totaltxtime %= 1000; 01355 01356 ast_cli(fd, "TX time since system initialization..............: %02d:%02d:%02d.%d\n", 01357 hours, minutes, seconds, (int) totaltxtime); 01358 ast_cli(fd, "Nodes currently connected to us..................: "); 01359 for(j = 0 ;; j++){ 01360 if(!listoflinks[j]){ 01361 if(!j){ 01362 ast_cli(fd,"<NONE>"); 01363 } 01364 break; 01365 } 01366 ast_cli(fd, "%s", listoflinks[j]); 01367 if(j % 4 == 3){ 01368 ast_cli(fd, "\n"); 01369 ast_cli(fd, " : "); 01370 } 01371 else{ 01372 if(listoflinks[j + 1]) 01373 ast_cli(fd, ", "); 01374 } 01375 } 01376 ast_cli(fd,"\n"); 01377 01378 ast_cli(fd, "Last node which transmitted to us................: %s\n", lastnodewhichkeyedusup); 01379 ast_cli(fd, "Autopatch state..................................: %s\n", patch_state); 01380 ast_cli(fd, "Autopatch called number..........................: %s\n", called_number); 01381 ast_cli(fd, "Reverse patch/IAXRPT connected...................: %s\n\n", reverse_patch_state); 01382 01383 return RESULT_SUCCESS; 01384 } 01385 } 01386 return RESULT_FAILURE; 01387 }
static int rpt_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 7271 of file app_rpt.c.
References ast_channel::_state, ahp, ast_channel::appl, ast_answer(), ast_call(), ast_callerid_parse(), ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_RADIO_KEY, ast_exists_extension(), AST_FORMAT_SLINEAR, ast_gethostbyname(), ast_hangup(), ast_indicate(), ast_inet_ntoa(), ast_log(), ast_masq_park_call(), ast_module_user_add, AST_PBX_KEEPALIVE, ast_request(), ast_safe_sleep(), ast_set_callerid(), ast_set_read_format(), ast_set_write_format(), ast_shrink_phone_number(), AST_STATE_UP, ast_strlen_zero(), ast_variable_retrieve(), ast_verbose(), rpt::callmode, rpt::cfg, rpt_link::chan, ast_channel::cid, ast_callerid::cid_num, rpt::conf, ast_channel::context, context, ast_channel::data, rpt_link::disced, rpt::dtmf_time_rem, rpt::dtmfbuf, rpt::dtmfidx, ast_channel::exten, exten, f, ast_channel::fds, free, rpt::hfscanmode, rpt::hfscanstatus, hp, rpt::iobase, rpt_link::killme, rpt::links, load_rpt_vars(), rpt::lock, LOG_WARNING, rpt::macrobuf, malloc, MAX_RETRIES, MAXMACRO, MAXNODESTR, rpt_link::name, rpt::name, name, rpt_link::next, rpt::nobusyout, rpt::nodes, option_verbose, rpt::p, pbx_substitute_variables_helper(), ast_channel::priority, rpt_link::reconnects, rpt::reload, rpt::remchannel, rpt::remote, rpt::remoteon, rpt::remoterx, rpt::remotetx, rpt_link::retries, rpt::retxtimer, REV_PATCH, rpt_mutex_lock, rpt_mutex_unlock, rpt_telemetry(), rpt_vars, rpt::rxchanname, rpt::rxchannel, s, setrem(), rpt::startupmacro, strsep(), timeout, rpt::txchanname, rpt::txchannel, VERBOSE_PREFIX_3, and ast_channel::whentohangup.
Referenced by load_module().
07272 { 07273 int res=-1,i,rem_totx,n,phone_mode = 0; 07274 struct ast_module_user *u; 07275 char tmp[256], keyed = 0; 07276 char *options,*stringp,*tele,c; 07277 struct rpt *myrpt; 07278 struct ast_frame *f; 07279 struct ast_channel *who; 07280 struct ast_channel *cs[20]; 07281 struct rpt_link *l; 07282 ZT_CONFINFO ci; /* conference info */ 07283 ZT_PARAMS par; 07284 int ms,elap; 07285 07286 if (ast_strlen_zero(data)) { 07287 ast_log(LOG_WARNING, "Rpt requires an argument (system node)\n"); 07288 return -1; 07289 } 07290 ast_copy_string(tmp, (char *)data, sizeof(tmp)); 07291 stringp=tmp; 07292 strsep(&stringp, "|"); 07293 options = stringp; 07294 myrpt = NULL; 07295 /* see if we can find our specified one */ 07296 for(i = 0; i < nrpts; i++) 07297 { 07298 /* if name matches, assign it and exit loop */ 07299 if (!strcmp(tmp,rpt_vars[i].name)) 07300 { 07301 myrpt = &rpt_vars[i]; 07302 break; 07303 } 07304 } 07305 if (myrpt == NULL) 07306 { 07307 ast_log(LOG_WARNING, "Cannot find specified system node %s\n",tmp); 07308 return -1; 07309 } 07310 07311 /* if not phone access, must be an IAX connection */ 07312 if (options && ((*options == 'P') || (*options == 'D') || (*options == 'R'))) 07313 { 07314 phone_mode = 1; 07315 if (*options == 'D') phone_mode = 2; 07316 ast_set_callerid(chan,"0","app_rpt user","0"); 07317 } 07318 else 07319 { 07320 if (strncmp(chan->name,"IAX2",4)) 07321 { 07322 ast_log(LOG_WARNING, "We only accept links via IAX2!!\n"); 07323 return -1; 07324 } 07325 } 07326 if (options && (*options == 'R')) 07327 { 07328 07329 /* Parts of this section taken from app_parkandannounce */ 07330 char *return_context; 07331 int l, m, lot, timeout = 0; 07332 char tmp[256],*template; 07333 char *working, *context, *exten, *priority; 07334 char *s,*orig_s; 07335 07336 07337 rpt_mutex_lock(&myrpt->lock); 07338 m = myrpt->callmode; 07339 rpt_mutex_unlock(&myrpt->lock); 07340 07341 if ((!myrpt->p.nobusyout) && m) 07342 { 07343 if (chan->_state != AST_STATE_UP) 07344 { 07345 ast_indicate(chan,AST_CONTROL_BUSY); 07346 } 07347 while(ast_safe_sleep(chan,10000) != -1); 07348 return -1; 07349 } 07350 07351 if (chan->_state != AST_STATE_UP) 07352 { 07353 ast_answer(chan); 07354 } 07355 07356 l=strlen(options)+2; 07357 orig_s=malloc(l); 07358 if(!orig_s) { 07359 ast_log(LOG_WARNING, "Out of memory\n"); 07360 return -1; 07361 } 07362 s=orig_s; 07363 ast_copy_string(s,options,l); 07364 07365 template=strsep(&s,"|"); 07366 if(!template) { 07367 ast_log(LOG_WARNING, "An announce template must be defined\n"); 07368 free(orig_s); 07369 return -1; 07370 } 07371 07372 if(s) { 07373 timeout = atoi(strsep(&s, "|")); 07374 timeout *= 1000; 07375 } 07376 07377 return_context = s; 07378 07379 if(return_context != NULL) { 07380 /* set the return context. Code borrowed from the Goto builtin */ 07381 07382 working = return_context; 07383 context = strsep(&working, "|"); 07384 exten = strsep(&working, "|"); 07385 if(!exten) { 07386 /* Only a priority in this one */ 07387 priority = context; 07388 exten = NULL; 07389 context = NULL; 07390 } else { 07391 priority = strsep(&working, "|"); 07392 if(!priority) { 07393 /* Only an extension and priority in this one */ 07394 priority = exten; 07395 exten = context; 07396 context = NULL; 07397 } 07398 } 07399 if(atoi(priority) < 0) { 07400 ast_log(LOG_WARNING, "Priority '%s' must be a number > 0\n", priority); 07401 free(orig_s); 07402 return -1; 07403 } 07404 /* At this point we have a priority and maybe an extension and a context */ 07405 chan->priority = atoi(priority); 07406 #ifdef OLD_ASTERISK 07407 if(exten && strcasecmp(exten, "BYEXTENSION")) 07408 #else 07409 if(exten) 07410 #endif 07411 ast_copy_string(chan->exten, exten, sizeof(chan->exten)); 07412 if(context) 07413 ast_copy_string(chan->context, context, sizeof(chan->context)); 07414 } else { /* increment the priority by default*/ 07415 chan->priority++; 07416 } 07417 07418 if(option_verbose > 2) { 07419 ast_verbose( VERBOSE_PREFIX_3 "Return Context: (%s,%s,%d) ID: %s\n", chan->context,chan->exten, chan->priority, chan->cid.cid_num); 07420 if(!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) { 07421 ast_verbose( VERBOSE_PREFIX_3 "Warning: Return Context Invalid, call will return to default|s\n"); 07422 } 07423 } 07424 07425 /* we are using masq_park here to protect * from touching the channel once we park it. If the channel comes out of timeout 07426 before we are done announcing and the channel is messed with, Kablooeee. So we use Masq to prevent this. */ 07427 07428 ast_masq_park_call(chan, NULL, timeout, &lot); 07429 07430 if (option_verbose > 2) ast_verbose( VERBOSE_PREFIX_3 "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, return_context); 07431 07432 snprintf(tmp,sizeof(tmp) - 1,"%d,%s",lot,template + 1); 07433 07434 rpt_telemetry(myrpt,REV_PATCH,tmp); 07435 07436 free(orig_s); 07437 07438 return 0; 07439 07440 } 07441 07442 if (!options) 07443 { 07444 struct ast_hostent ahp; 07445 struct hostent *hp; 07446 struct in_addr ia; 07447 char hisip[100],nodeip[100]; 07448 const char *val; 07449 char *s, *s1, *s2, *b,*b1; 07450 07451 /* look at callerid to see what node this comes from */ 07452 if (!chan->cid.cid_num) /* if doesn't have caller id */ 07453 { 07454 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 07455 return -1; 07456 } 07457 07458 /* get his IP from IAX2 module */ 07459 memset(hisip,0,sizeof(hisip)); 07460 pbx_substitute_variables_helper(chan,"${IAXPEER(CURRENTCHANNEL)}",hisip,sizeof(hisip) - 1); 07461 if (!hisip[0]) 07462 { 07463 ast_log(LOG_WARNING, "Link IP address cannot be determined!!\n"); 07464 return -1; 07465 } 07466 07467 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 07468 ast_shrink_phone_number(b1); 07469 if (!strcmp(myrpt->name,b1)) 07470 { 07471 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 07472 return -1; 07473 } 07474 07475 if (*b1 < '1') 07476 { 07477 ast_log(LOG_WARNING, "Node %s Invalid for connection here!!\n",b1); 07478 return -1; 07479 } 07480 07481 07482 /* look for his reported node string */ 07483 val = ast_variable_retrieve(myrpt->cfg, myrpt->p.nodes, b1); 07484 if (!val) 07485 { 07486 ast_log(LOG_WARNING, "Reported node %s cannot be found!!\n",b1); 07487 return -1; 07488 } 07489 ast_copy_string(tmp,val,sizeof(tmp)); 07490 s = tmp; 07491 s1 = strsep(&s,","); 07492 s2 = strsep(&s,","); 07493 if (!s2) 07494 { 07495 ast_log(LOG_WARNING, "Reported node %s not in correct format!!\n",b1); 07496 return -1; 07497 } 07498 if (strcmp(s2,"NONE")) { 07499 hp = ast_gethostbyname(s2, &ahp); 07500 if (!hp) 07501 { 07502 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s2); 07503 return -1; 07504 } 07505 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 07506 ast_copy_string(nodeip, ast_inet_ntoa(ia), sizeof(nodeip)); 07507 if (strcmp(hisip,nodeip)) 07508 { 07509 char *s3 = strchr(s1,'@'); 07510 if (s3) s1 = s3 + 1; 07511 s3 = strchr(s1,'/'); 07512 if (s3) *s3 = 0; 07513 hp = ast_gethostbyname(s1, &ahp); 07514 if (!hp) 07515 { 07516 ast_log(LOG_WARNING, "Reported node %s, name %s cannot be found!!\n",b1,s1); 07517 return -1; 07518 } 07519 memcpy(&ia,hp->h_addr,sizeof(in_addr_t)); 07520 ast_copy_string(nodeip, ast_inet_ntoa(ia), sizeof(nodeip)); 07521 if (strcmp(hisip,nodeip)) 07522 { 07523 ast_log(LOG_WARNING, "Node %s IP %s does not match link IP %s!!\n",b1,nodeip,hisip); 07524 return -1; 07525 } 07526 } 07527 } 07528 } 07529 07530 /* if is not a remote */ 07531 if (!myrpt->remote) 07532 { 07533 07534 char *b,*b1; 07535 int reconnects = 0; 07536 07537 /* look at callerid to see what node this comes from */ 07538 if (!chan->cid.cid_num) /* if doesn't have caller id */ 07539 { 07540 ast_log(LOG_WARNING, "Doesnt have callerid on %s\n",tmp); 07541 return -1; 07542 } 07543 07544 ast_callerid_parse(chan->cid.cid_num,&b,&b1); 07545 ast_shrink_phone_number(b1); 07546 if (!strcmp(myrpt->name,b1)) 07547 { 07548 ast_log(LOG_WARNING, "Trying to link to self!!\n"); 07549 return -1; 07550 } 07551 rpt_mutex_lock(&myrpt->lock); 07552 l = myrpt->links.next; 07553 /* try to find this one in queue */ 07554 while(l != &myrpt->links) 07555 { 07556 if (l->name[0] == '0') 07557 { 07558 l = l->next; 07559 continue; 07560 } 07561 /* if found matching string */ 07562 if (!strcmp(l->name,b1)) break; 07563 l = l->next; 07564 } 07565 /* if found */ 07566 if (l != &myrpt->links) 07567 { 07568 l->killme = 1; 07569 l->retries = MAX_RETRIES + 1; 07570 l->disced = 2; 07571 reconnects = l->reconnects; 07572 reconnects++; 07573 rpt_mutex_unlock(&myrpt->lock); 07574 usleep(500000); 07575 } else 07576 rpt_mutex_unlock(&myrpt->lock); 07577 /* establish call in tranceive mode */ 07578 l = malloc(sizeof(struct rpt_link)); 07579 if (!l) 07580 { 07581 ast_log(LOG_WARNING, "Unable to malloc\n"); 07582 pthread_exit(NULL); 07583 } 07584 /* zero the silly thing */ 07585 memset((char *)l,0,sizeof(struct rpt_link)); 07586 l->mode = 1; 07587 ast_copy_string(l->name,b1,MAXNODESTR); 07588 l->isremote = 0; 07589 l->chan = chan; 07590 l->connected = 1; 07591 l->hasconnected = 1; 07592 l->reconnects = reconnects; 07593 l->phonemode = phone_mode; 07594 ast_set_read_format(l->chan,AST_FORMAT_SLINEAR); 07595 ast_set_write_format(l->chan,AST_FORMAT_SLINEAR); 07596 /* allocate a pseudo-channel thru asterisk */ 07597 l->pchan = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 07598 if (!l->pchan) 07599 { 07600 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 07601 pthread_exit(NULL); 07602 } 07603 ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR); 07604 ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR); 07605 /* make a conference for the tx */ 07606 ci.chan = 0; 07607 ci.confno = myrpt->conf; 07608 ci.confmode = ZT_CONF_CONF | ZT_CONF_LISTENER | ZT_CONF_TALKER; 07609 /* first put the channel on the conference in proper mode */ 07610 if (ioctl(l->pchan->fds[0],ZT_SETCONF,&ci) == -1) 07611 { 07612 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 07613 pthread_exit(NULL); 07614 } 07615 rpt_mutex_lock(&myrpt->lock); 07616 if (phone_mode > 1) l->lastrx = 1; 07617 /* insert at end of queue */ 07618 insque((struct qelem *)l,(struct qelem *)myrpt->links.next); 07619 rpt_mutex_unlock(&myrpt->lock); 07620 if (chan->_state != AST_STATE_UP) { 07621 ast_answer(chan); 07622 } 07623 return AST_PBX_KEEPALIVE; 07624 } 07625 rpt_mutex_lock(&myrpt->lock); 07626 /* if remote, error if anyone else already linked */ 07627 if (myrpt->remoteon) 07628 { 07629 rpt_mutex_unlock(&myrpt->lock); 07630 usleep(500000); 07631 if (myrpt->remoteon) 07632 { 07633 ast_log(LOG_WARNING, "Trying to use busy link on %s\n",tmp); 07634 return -1; 07635 } 07636 rpt_mutex_lock(&myrpt->lock); 07637 } 07638 myrpt->remoteon = 1; 07639 if (ioperm(myrpt->p.iobase,1,1) == -1) 07640 { 07641 rpt_mutex_unlock(&myrpt->lock); 07642 ast_log(LOG_WARNING, "Cant get io permission on IO port %x hex\n",myrpt->p.iobase); 07643 return -1; 07644 } 07645 u = ast_module_user_add(chan); 07646 rpt_mutex_unlock(&myrpt->lock); 07647 /* find our index, and load the vars initially */ 07648 for(i = 0; i < nrpts; i++) 07649 { 07650 if (&rpt_vars[i] == myrpt) 07651 { 07652 load_rpt_vars(i,0); 07653 break; 07654 } 07655 } 07656 rpt_mutex_lock(&myrpt->lock); 07657 tele = strchr(myrpt->rxchanname,'/'); 07658 if (!tele) 07659 { 07660 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 07661 rpt_mutex_unlock(&myrpt->lock); 07662 pthread_exit(NULL); 07663 } 07664 *tele++ = 0; 07665 myrpt->rxchannel = ast_request(myrpt->rxchanname,AST_FORMAT_SLINEAR,tele,NULL); 07666 if (myrpt->rxchannel) 07667 { 07668 ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 07669 ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR); 07670 myrpt->rxchannel->whentohangup = 0; 07671 myrpt->rxchannel->appl = "Apprpt"; 07672 myrpt->rxchannel->data = "(Link Rx)"; 07673 if (option_verbose > 2) 07674 ast_verbose(VERBOSE_PREFIX_3 "rpt (Rx) initiating call to %s/%s on %s\n", 07675 myrpt->rxchanname,tele,myrpt->rxchannel->name); 07676 rpt_mutex_unlock(&myrpt->lock); 07677 ast_call(myrpt->rxchannel,tele,999); 07678 rpt_mutex_lock(&myrpt->lock); 07679 } 07680 else 07681 { 07682 fprintf(stderr,"rpt:Sorry unable to obtain Rx channel\n"); 07683 rpt_mutex_unlock(&myrpt->lock); 07684 pthread_exit(NULL); 07685 } 07686 *--tele = '/'; 07687 if (myrpt->txchanname) 07688 { 07689 tele = strchr(myrpt->txchanname,'/'); 07690 if (!tele) 07691 { 07692 fprintf(stderr,"rpt:Dial number must be in format tech/number\n"); 07693 rpt_mutex_unlock(&myrpt->lock); 07694 ast_hangup(myrpt->rxchannel); 07695 pthread_exit(NULL); 07696 } 07697 *tele++ = 0; 07698 myrpt->txchannel = ast_request(myrpt->txchanname,AST_FORMAT_SLINEAR,tele,NULL); 07699 if (myrpt->txchannel) 07700 { 07701 ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 07702 ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR); 07703 myrpt->txchannel->whentohangup = 0; 07704 myrpt->txchannel->appl = "Apprpt"; 07705 myrpt->txchannel->data = "(Link Tx)"; 07706 if (option_verbose > 2) 07707 ast_verbose(VERBOSE_PREFIX_3 "rpt (Tx) initiating call to %s/%s on %s\n", 07708 myrpt->txchanname,tele,myrpt->txchannel->name); 07709 rpt_mutex_unlock(&myrpt->lock); 07710 ast_call(myrpt->txchannel,tele,999); 07711 rpt_mutex_lock(&myrpt->lock); 07712 } 07713 else 07714 { 07715 fprintf(stderr,"rpt:Sorry unable to obtain Tx channel\n"); 07716 rpt_mutex_unlock(&myrpt->lock); 07717 ast_hangup(myrpt->rxchannel); 07718 pthread_exit(NULL); 07719 } 07720 *--tele = '/'; 07721 } 07722 else 07723 { 07724 myrpt->txchannel = myrpt->rxchannel; 07725 } 07726 myrpt->remoterx = 0; 07727 myrpt->remotetx = 0; 07728 myrpt->retxtimer = 0; 07729 myrpt->remoteon = 1; 07730 myrpt->dtmfidx = -1; 07731 myrpt->dtmfbuf[0] = 0; 07732 myrpt->dtmf_time_rem = 0; 07733 myrpt->hfscanmode = 0; 07734 myrpt->hfscanstatus = 0; 07735 if (myrpt->p.startupmacro) 07736 { 07737 myrpt->remchannel = chan; /* Save copy of channel */ 07738 snprintf(myrpt->macrobuf,MAXMACRO - 1,"PPPP%s",myrpt->p.startupmacro); 07739 } 07740 myrpt->reload = 0; 07741 rpt_mutex_unlock(&myrpt->lock); 07742 setrem(myrpt); 07743 ast_set_write_format(chan, AST_FORMAT_SLINEAR); 07744 ast_set_read_format(chan, AST_FORMAT_SLINEAR); 07745 /* if we are on 2w loop and are a remote, turn EC on */ 07746 if (myrpt->remote && (myrpt->rxchannel == myrpt->txchannel)) 07747 { 07748 i = 128; 07749 ioctl(myrpt->rxchannel->fds[0],ZT_ECHOCANCEL,&i); 07750 } 07751 if (chan->_state != AST_STATE_UP) { 07752 ast_answer(chan); 07753 } 07754 07755 if (ioctl(myrpt->txchannel->fds[0],ZT_GET_PARAMS,&par) != -1) 07756 { 07757 if (par.rxisoffhook) 07758 { 07759 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 07760 myrpt->remoterx = 1; 07761 } 07762 } 07763 n = 0; 07764 cs[n++] = chan; 07765 cs[n++] = myrpt->rxchannel; 07766 if (myrpt->rxchannel != myrpt->txchannel) 07767 cs[n++] = myrpt->txchannel; 07768 for(;;) 07769 { 07770 if (ast_check_hangup(chan)) break; 07771 if (ast_check_hangup(myrpt->rxchannel)) break; 07772 if (myrpt->reload) 07773 { 07774 myrpt->reload = 0; 07775 rpt_mutex_unlock(&myrpt->lock); 07776 /* find our index, and load the vars */ 07777 for(i = 0; i < nrpts; i++) 07778 { 07779 if (&rpt_vars[i] == myrpt) 07780 { 07781 load_rpt_vars(i,0); 07782 break; 07783 } 07784 } 07785 rpt_mutex_lock(&myrpt->lock); 07786 } 07787 ms = MSWAIT; 07788 who = ast_waitfor_n(cs,n,&ms); 07789 if (who == NULL) ms = 0; 07790 elap = MSWAIT - ms; 07791 if (myrpt->macrotimer) myrpt->macrotimer -= elap; 07792 if (myrpt->macrotimer < 0) myrpt->macrotimer = 0; 07793 rpt_mutex_unlock(&myrpt->lock); 07794 if (!ms) continue; 07795 rem_totx = keyed; 07796 07797 07798 if ((!myrpt->remoterx) && (!myrpt->remotetx)) 07799 { 07800 if ((myrpt->retxtimer += elap) >= REDUNDANT_TX_TIME) 07801 { 07802 myrpt->retxtimer = 0; 07803 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 07804 } 07805 } else myrpt->retxtimer = 0; 07806 if (rem_totx && (!myrpt->remotetx)) /* Remote base radio TX key */ 07807 { 07808 myrpt->remotetx = 1; 07809 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY); 07810 } 07811 if ((!rem_totx) && myrpt->remotetx) /* Remote base radio TX unkey */ 07812 { 07813 myrpt->remotetx = 0; 07814 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 07815 } 07816 07817 if(myrpt->tunerequest && (!strcmp(myrpt->remote, remote_rig_ft897))){ /* ft-897 specific for now... */ 07818 myrpt->tunerequest = 0; 07819 set_mode_ft897(myrpt, REM_MODE_AM); 07820 simple_command_ft897(myrpt, 8); 07821 myrpt->remotetx = 0; 07822 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 07823 if (!myrpt->remoterx) 07824 ast_indicate(chan, AST_CONTROL_RADIO_KEY); 07825 if(play_tone(chan, 800, 6000, 8192) == -1) 07826 break; 07827 07828 rmt_telem_finish(myrpt,chan); 07829 set_mode_ft897(myrpt, 0x88); 07830 setrem(myrpt); 07831 } 07832 07833 if (myrpt->hfscanmode){ 07834 myrpt->scantimer -= elap; 07835 if(myrpt->scantimer <= 0){ 07836 myrpt->scantimer = REM_SCANTIME; 07837 service_scan(myrpt); 07838 } 07839 } 07840 if (who == chan) /* if it was a read from incomming */ 07841 { 07842 f = ast_read(chan); 07843 if (!f) 07844 { 07845 if (debug) printf("@@@@ link:Hung Up\n"); 07846 break; 07847 } 07848 if (f->frametype == AST_FRAME_VOICE) 07849 { 07850 /* if not transmitting, zero-out audio */ 07851 if (!myrpt->remotetx) 07852 memset(f->data,0,f->datalen); 07853 ast_write(myrpt->txchannel,f); 07854 } 07855 if (f->frametype == AST_FRAME_DTMF) 07856 { 07857 myrpt->remchannel = chan; /* Save copy of channel */ 07858 if (handle_remote_phone_dtmf(myrpt,f->subclass,&keyed,phone_mode) == -1) 07859 { 07860 if (debug) printf("@@@@ rpt:Hung Up\n"); 07861 ast_frfree(f); 07862 break; 07863 } 07864 } 07865 if (f->frametype == AST_FRAME_TEXT) 07866 { 07867 myrpt->remchannel = chan; /* Save copy of channel */ 07868 if (handle_remote_data(myrpt,f->data) == -1) 07869 { 07870 if (debug) printf("@@@@ rpt:Hung Up\n"); 07871 ast_frfree(f); 07872 break; 07873 } 07874 } 07875 if (f->frametype == AST_FRAME_CONTROL) 07876 { 07877 if (f->subclass == AST_CONTROL_HANGUP) 07878 { 07879 if (debug) printf("@@@@ rpt:Hung Up\n"); 07880 ast_frfree(f); 07881 break; 07882 } 07883 /* if RX key */ 07884 if (f->subclass == AST_CONTROL_RADIO_KEY) 07885 { 07886 if (debug == 7) printf("@@@@ rx key\n"); 07887 keyed = 1; 07888 } 07889 /* if RX un-key */ 07890 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 07891 { 07892 if (debug == 7) printf("@@@@ rx un-key\n"); 07893 keyed = 0; 07894 } 07895 } 07896 if (myrpt->hfscanstatus){ 07897 myrpt->remchannel = chan; /* Save copy of channel */ 07898 myrpt->remotetx = 0; 07899 ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY); 07900 if (!myrpt->remoterx) 07901 { 07902 ast_indicate(myrpt->remchannel,AST_CONTROL_RADIO_KEY); 07903 } 07904 if(myrpt->hfscanstatus < 0) { 07905 if (myrpt->hfscanstatus == -1) { 07906 if (ast_safe_sleep(myrpt->remchannel,1000) == -1) break; 07907 } 07908 sayfile(myrpt->remchannel, "rpt/stop"); 07909 } 07910 else 07911 { 07912 saynum(myrpt->remchannel, myrpt->hfscanstatus ); 07913 } 07914 rmt_telem_finish(myrpt,myrpt->remchannel); 07915 myrpt->hfscanstatus = 0; 07916 } 07917 ast_frfree(f); 07918 rpt_mutex_lock(&myrpt->lock); 07919 c = myrpt->macrobuf[0]; 07920 if (c && (!myrpt->macrotimer)) 07921 { 07922 myrpt->macrotimer = MACROTIME; 07923 memmove(myrpt->macrobuf,myrpt->macrobuf + 1,MAXMACRO - 1); 07924 if ((c == 'p') || (c == 'P')) 07925 myrpt->macrotimer = MACROPTIME; 07926 rpt_mutex_unlock(&myrpt->lock); 07927 if (handle_remote_dtmf_digit(myrpt,c,&keyed,0) == -1) break; 07928 continue; 07929 } 07930 rpt_mutex_unlock(&myrpt->lock); 07931 continue; 07932 } 07933 if (who == myrpt->rxchannel) /* if it was a read from radio */ 07934 { 07935 f = ast_read(myrpt->rxchannel); 07936 if (!f) 07937 { 07938 if (debug) printf("@@@@ link:Hung Up\n"); 07939 break; 07940 } 07941 if (f->frametype == AST_FRAME_VOICE) 07942 { 07943 if ((myrpt->remote) && (myrpt->remotetx)) 07944 memset(f->data,0,f->datalen); 07945 ast_write(chan,f); 07946 } 07947 else if (f->frametype == AST_FRAME_CONTROL) 07948 { 07949 if (f->subclass == AST_CONTROL_HANGUP) 07950 { 07951 if (debug) printf("@@@@ rpt:Hung Up\n"); 07952 ast_frfree(f); 07953 break; 07954 } 07955 /* if RX key */ 07956 if (f->subclass == AST_CONTROL_RADIO_KEY) 07957 { 07958 if (debug == 7) printf("@@@@ remote rx key\n"); 07959 if (!myrpt->remotetx) 07960 { 07961 ast_indicate(chan,AST_CONTROL_RADIO_KEY); 07962 myrpt->remoterx = 1; 07963 } 07964 } 07965 /* if RX un-key */ 07966 if (f->subclass == AST_CONTROL_RADIO_UNKEY) 07967 { 07968 if (debug == 7) printf("@@@@ remote rx un-key\n"); 07969 if (!myrpt->remotetx) 07970 { 07971 ast_indicate(chan,AST_CONTROL_RADIO_UNKEY); 07972 myrpt->remoterx = 0; 07973 } 07974 } 07975 } 07976 ast_frfree(f); 07977 continue; 07978 } 07979 if ((myrpt->rxchannel != myrpt->txchannel) && 07980 (who == myrpt->txchannel)) /* do this cuz you have to */ 07981 { 07982 f = ast_read(myrpt->txchannel); 07983 if (!f) 07984 { 07985 if (debug) printf("@@@@ link:Hung Up\n"); 07986 break; 07987 } 07988 if (f->frametype == AST_FRAME_CONTROL) 07989 { 07990 if (f->subclass == AST_CONTROL_HANGUP) 07991 { 07992 if (debug) printf("@@@@ rpt:Hung Up\n"); 07993 ast_frfree(f); 07994 break; 07995 } 07996 } 07997 ast_frfree(f); 07998 continue; 07999 } 08000 08001 } 08002 rpt_mutex_lock(&myrpt->lock); 08003 if (myrpt->rxchannel != myrpt->txchannel) ast_hangup(myrpt->txchannel); 08004 ast_hangup(myrpt->rxchannel); 08005 myrpt->hfscanmode = 0; 08006 myrpt->hfscanstatus = 0; 08007 myrpt->remoteon = 0; 08008 rpt_mutex_unlock(&myrpt->lock); 08009 closerem(myrpt); 08010 ast_module_user_remove(u); 08011 return res; 08012 }
static void* rpt_master | ( | void * | config | ) | [static] |
Definition at line 7154 of file app_rpt.c.
References ast_category_browse(), ast_config_destroy(), ast_log(), ast_mutex_init(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_variable_retrieve(), rpt::cfg, rpt::ident, rpt::lastthreadrestarttime, load_rpt_vars(), lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, name, rpt::name, rpt_tele::next, rpt::offset, rpt::powerlevel, rpt_tele::prev, REM_MEDPWR, REM_MODE_FM, REM_SIMPLEX, rpt::remmode, rpt::remote, rpt::rpt_thread, rpt_vars, rpt::rxchanname, strdup, rpt::tailmessagen, rpt::tele, rpt::threadrestarts, and rpt::txchanname.
Referenced by load_module().
07155 { 07156 int i,n; 07157 pthread_attr_t attr; 07158 struct ast_config *cfg; 07159 char *this; 07160 const char *val; 07161 07162 /* go thru all the specified repeaters */ 07163 this = NULL; 07164 n = 0; 07165 rpt_vars[n].cfg = config; 07166 cfg = rpt_vars[n].cfg; 07167 if (!cfg) { 07168 ast_log(LOG_NOTICE, "Unable to open radio repeater configuration rpt.conf. Radio Repeater disabled.\n"); 07169 pthread_exit(NULL); 07170 } 07171 while((this = ast_category_browse(cfg,this)) != NULL) 07172 { 07173 for(i = 0 ; i < strlen(this) ; i++){ 07174 if((this[i] < '0') || (this[i] > '9')) 07175 break; 07176 } 07177 if(i != strlen(this)) continue; /* Not a node defn */ 07178 memset(&rpt_vars[n],0,sizeof(rpt_vars[n])); 07179 rpt_vars[n].name = strdup(this); 07180 val = ast_variable_retrieve(cfg,this,"rxchannel"); 07181 if (val) rpt_vars[n].rxchanname = strdup(val); 07182 val = ast_variable_retrieve(cfg,this,"txchannel"); 07183 if (val) rpt_vars[n].txchanname = strdup(val); 07184 val = ast_variable_retrieve(cfg,this,"remote"); 07185 if (val) rpt_vars[n].remote = strdup(val); 07186 ast_mutex_init(&rpt_vars[n].lock); 07187 rpt_vars[n].tele.next = &rpt_vars[n].tele; 07188 rpt_vars[n].tele.prev = &rpt_vars[n].tele; 07189 rpt_vars[n].rpt_thread = AST_PTHREADT_NULL; 07190 rpt_vars[n].tailmessagen = 0; 07191 #ifdef _MDC_DECODE_H_ 07192 rpt_vars[n].mdc = mdc_decoder_new(8000); 07193 #endif 07194 n++; 07195 } 07196 nrpts = n; 07197 ast_config_destroy(cfg); 07198 07199 /* start em all */ 07200 for(i = 0; i < n; i++) 07201 { 07202 load_rpt_vars(i,1); 07203 07204 /* if is a remote, dont start one for it */ 07205 if (rpt_vars[i].remote) 07206 { 07207 strcpy(rpt_vars[i].freq, "146.580"); 07208 strcpy(rpt_vars[i].rxpl, "100.0"); 07209 strcpy(rpt_vars[i].txpl, "100.0"); 07210 rpt_vars[i].remmode = REM_MODE_FM; 07211 rpt_vars[i].offset = REM_SIMPLEX; 07212 rpt_vars[i].powerlevel = REM_MEDPWR; 07213 continue; 07214 } 07215 if (!rpt_vars[i].p.ident) 07216 { 07217 ast_log(LOG_WARNING,"Did not specify ident for node %s\n",rpt_vars[i].name); 07218 ast_config_destroy(cfg); 07219 pthread_exit(NULL); 07220 } 07221 pthread_attr_init(&attr); 07222 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07223 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 07224 pthread_attr_destroy(&attr); 07225 } 07226 usleep(500000); 07227 for(;;) 07228 { 07229 /* Now monitor each thread, and restart it if necessary */ 07230 for(i = 0; i < n; i++) 07231 { 07232 int rv; 07233 if (rpt_vars[i].remote) continue; 07234 if (rpt_vars[i].rpt_thread == AST_PTHREADT_STOP) 07235 rv = -1; 07236 else 07237 rv = pthread_kill(rpt_vars[i].rpt_thread,0); 07238 if (rv) 07239 { 07240 if(time(NULL) - rpt_vars[i].lastthreadrestarttime <= 15) 07241 { 07242 if(rpt_vars[i].threadrestarts >= 5) 07243 { 07244 ast_log(LOG_ERROR,"Continual RPT thread restarts, killing Asterisk\n"); 07245 exit(1); /* Stuck in a restart loop, kill Asterisk and start over */ 07246 } 07247 else 07248 { 07249 ast_log(LOG_NOTICE,"RPT thread restarted on %s\n",rpt_vars[i].name); 07250 rpt_vars[i].threadrestarts++; 07251 } 07252 } 07253 else 07254 rpt_vars[i].threadrestarts = 0; 07255 07256 rpt_vars[i].lastthreadrestarttime = time(NULL); 07257 pthread_attr_init(&attr); 07258 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07259 ast_pthread_create(&rpt_vars[i].rpt_thread,&attr,rpt,(void *) &rpt_vars[i]); 07260 pthread_attr_destroy(&attr); 07261 ast_log(LOG_WARNING, "rpt_thread restarted on node %s\n", rpt_vars[i].name); 07262 } 07263 07264 } 07265 usleep(2000000); 07266 } 07267 ast_config_destroy(cfg); 07268 pthread_exit(NULL); 07269 }
static void* rpt_tele_thread | ( | void * | this | ) | [static] |
Definition at line 1953 of file app_rpt.c.
References ARB_ALPHA, AST_FORMAT_SLINEAR, ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_request(), ast_safe_sleep(), ast_say_character_str(), ast_say_digits(), ast_say_number(), ast_say_time, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_tonepair_start(), ast_variable_retrieve(), ast_waitstream(), rpt_tele::chan, COMPLETE, CONNECTED, rpt_link::connected, CONNFAIL, DLY_CALLTERM, DLY_ID, DLY_TELEM, DLY_UNKEY, ast_channel::fds, free, get_wait_interval(), ID, ID1, IDTALKOVER, rpt_link::isremote, LASTNODEKEY, LOG_NOTICE, LOG_WARNING, MACRO_BUSY, MACRO_NOTFOUND, malloc, rpt_link::mode, rpt_tele::mode, rpt_tele::mylink, rpt_link::name, rpt_link::next, rpt_tele::next, rpt_tele::param, rpt_link::prev, PROC, REMALREADY, REMDISC, REMGO, REMNOTFOUND, REV_PATCH, rpt_tele::rpt, rpt_mutex_lock, rpt_mutex_unlock, saycharstr(), sayfile(), STATS_TIME, STATS_VERSION, STATUS, strsep(), t, TAILMSG, telem_any(), telem_lookup(), TERM, TEST_TONE, TIMEOUT, UNKEY, and wait_interval().
Referenced by rpt_telemetry().
01954 { 01955 ZT_CONFINFO ci; /* conference info */ 01956 int res = 0,haslink,hastx,hasremote,imdone = 0, unkeys_queued, x; 01957 struct rpt_tele *mytele = (struct rpt_tele *)this; 01958 struct rpt_tele *tlist; 01959 struct rpt *myrpt; 01960 struct rpt_link *l,*m,linkbase; 01961 struct ast_channel *mychannel; 01962 const char *p, *ct; 01963 char *ct_copy, *ident, *nodename; 01964 time_t t; 01965 struct tm localtm; 01966 01967 /* get a pointer to myrpt */ 01968 myrpt = mytele->rpt; 01969 01970 /* Snag copies of a few key myrpt variables */ 01971 rpt_mutex_lock(&myrpt->lock); 01972 nodename = ast_strdupa(myrpt->name); 01973 ident = ast_strdupa(myrpt->p.ident); 01974 rpt_mutex_unlock(&myrpt->lock); 01975 01976 /* allocate a pseudo-channel thru asterisk */ 01977 mychannel = ast_request("zap",AST_FORMAT_SLINEAR,"pseudo",NULL); 01978 if (!mychannel) 01979 { 01980 fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n"); 01981 rpt_mutex_lock(&myrpt->lock); 01982 remque((struct qelem *)mytele); 01983 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 01984 rpt_mutex_unlock(&myrpt->lock); 01985 free(mytele); 01986 pthread_exit(NULL); 01987 } 01988 rpt_mutex_lock(&myrpt->lock); 01989 mytele->chan = mychannel; /* Save a copy of the channel so we can access it externally if need be */ 01990 rpt_mutex_unlock(&myrpt->lock); 01991 01992 /* make a conference for the tx */ 01993 ci.chan = 0; 01994 /* If there's an ID queued, or tail message queued, */ 01995 /* only connect the ID audio to the local tx conference so */ 01996 /* linked systems can't hear it */ 01997 ci.confno = (((mytele->mode == ID) || (mytele->mode == IDTALKOVER) || (mytele->mode == UNKEY) || 01998 (mytele->mode == TAILMSG)) ? 01999 myrpt->txconf : myrpt->conf); 02000 ci.confmode = ZT_CONF_CONFANN; 02001 /* first put the channel on the conference in announce mode */ 02002 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 02003 { 02004 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02005 rpt_mutex_lock(&myrpt->lock); 02006 remque((struct qelem *)mytele); 02007 rpt_mutex_unlock(&myrpt->lock); 02008 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02009 free(mytele); 02010 ast_hangup(mychannel); 02011 pthread_exit(NULL); 02012 } 02013 ast_stopstream(mychannel); 02014 switch(mytele->mode) 02015 { 02016 02017 case ID: 02018 case ID1: 02019 /* wait a bit */ 02020 wait_interval(myrpt, (mytele->mode == ID) ? DLY_ID : DLY_TELEM,mychannel); 02021 res = telem_any(myrpt,mychannel, ident); 02022 imdone=1; 02023 break; 02024 02025 case TAILMSG: 02026 res = ast_streamfile(mychannel, myrpt->p.tailmessages[myrpt->tailmessagen], mychannel->language); 02027 break; 02028 02029 case IDTALKOVER: 02030 p = ast_variable_retrieve(myrpt->cfg, nodename, "idtalkover"); 02031 if(p) 02032 res = telem_any(myrpt,mychannel, p); 02033 imdone=1; 02034 break; 02035 02036 case PROC: 02037 /* wait a little bit longer */ 02038 wait_interval(myrpt, DLY_TELEM, mychannel); 02039 res = telem_lookup(myrpt, mychannel, myrpt->name, "patchup"); 02040 if(res < 0){ /* Then default message */ 02041 res = ast_streamfile(mychannel, "rpt/callproceeding", mychannel->language); 02042 } 02043 break; 02044 case TERM: 02045 /* wait a little bit longer */ 02046 wait_interval(myrpt, DLY_CALLTERM, mychannel); 02047 res = telem_lookup(myrpt, mychannel, myrpt->name, "patchdown"); 02048 if(res < 0){ /* Then default message */ 02049 res = ast_streamfile(mychannel, "rpt/callterminated", mychannel->language); 02050 } 02051 break; 02052 case COMPLETE: 02053 /* wait a little bit */ 02054 wait_interval(myrpt, DLY_TELEM, mychannel); 02055 res = telem_lookup(myrpt,mychannel, myrpt->name, "functcomplete"); 02056 break; 02057 case MACRO_NOTFOUND: 02058 /* wait a little bit */ 02059 wait_interval(myrpt, DLY_TELEM, mychannel); 02060 res = ast_streamfile(mychannel, "rpt/macro_notfound", mychannel->language); 02061 break; 02062 case MACRO_BUSY: 02063 /* wait a little bit */ 02064 wait_interval(myrpt, DLY_TELEM, mychannel); 02065 res = ast_streamfile(mychannel, "rpt/macro_busy", mychannel->language); 02066 break; 02067 case UNKEY: 02068 if(myrpt->patchnoct && myrpt->callmode){ /* If no CT during patch configured, then don't send one */ 02069 imdone = 1; 02070 break; 02071 } 02072 02073 /* 02074 * Reset the Unkey to CT timer 02075 */ 02076 02077 x = get_wait_interval(myrpt, DLY_UNKEY); 02078 rpt_mutex_lock(&myrpt->lock); 02079 myrpt->unkeytocttimer = x; /* Must be protected as it is changed below */ 02080 rpt_mutex_unlock(&myrpt->lock); 02081 02082 /* 02083 * If there's one already queued, don't do another 02084 */ 02085 02086 tlist = myrpt->tele.next; 02087 unkeys_queued = 0; 02088 if (tlist != &myrpt->tele) 02089 { 02090 rpt_mutex_lock(&myrpt->lock); 02091 while(tlist != &myrpt->tele){ 02092 if (tlist->mode == UNKEY) unkeys_queued++; 02093 tlist = tlist->next; 02094 } 02095 rpt_mutex_unlock(&myrpt->lock); 02096 } 02097 if( unkeys_queued > 1){ 02098 imdone = 1; 02099 break; 02100 } 02101 02102 /* Wait for the telemetry timer to expire */ 02103 /* Periodically check the timer since it can be re-initialized above */ 02104 while(myrpt->unkeytocttimer) 02105 { 02106 int ctint; 02107 if(myrpt->unkeytocttimer > 100) 02108 ctint = 100; 02109 else 02110 ctint = myrpt->unkeytocttimer; 02111 ast_safe_sleep(mychannel, ctint); 02112 rpt_mutex_lock(&myrpt->lock); 02113 if(myrpt->unkeytocttimer < ctint) 02114 myrpt->unkeytocttimer = 0; 02115 else 02116 myrpt->unkeytocttimer -= ctint; 02117 rpt_mutex_unlock(&myrpt->lock); 02118 } 02119 02120 /* 02121 * Now, the carrier on the rptr rx should be gone. 02122 * If it re-appeared, then forget about sending the CT 02123 */ 02124 if(myrpt->keyed){ 02125 imdone = 1; 02126 break; 02127 } 02128 02129 rpt_mutex_lock(&myrpt->lock); /* Update the kerchunk counters */ 02130 myrpt->dailykerchunks++; 02131 myrpt->totalkerchunks++; 02132 rpt_mutex_unlock(&myrpt->lock); 02133 02134 haslink = 0; 02135 hastx = 0; 02136 hasremote = 0; 02137 l = myrpt->links.next; 02138 if (l != &myrpt->links) 02139 { 02140 rpt_mutex_lock(&myrpt->lock); 02141 while(l != &myrpt->links) 02142 { 02143 if (l->name[0] == '0') 02144 { 02145 l = l->next; 02146 continue; 02147 } 02148 haslink = 1; 02149 if (l->mode) { 02150 hastx++; 02151 if (l->isremote) hasremote++; 02152 } 02153 l = l->next; 02154 } 02155 rpt_mutex_unlock(&myrpt->lock); 02156 } 02157 if (haslink) 02158 { 02159 02160 res = telem_lookup(myrpt,mychannel, myrpt->name, (!hastx) ? "remotemon" : "remotetx"); 02161 if(res) 02162 ast_log(LOG_WARNING, "telem_lookup:remotexx failed on %s\n", mychannel->name); 02163 02164 02165 /* if in remote cmd mode, indicate it */ 02166 if (myrpt->cmdnode[0]) 02167 { 02168 ast_safe_sleep(mychannel,200); 02169 res = telem_lookup(myrpt,mychannel, myrpt->name, "cmdmode"); 02170 if(res) 02171 ast_log(LOG_WARNING, "telem_lookup:cmdmode failed on %s\n", mychannel->name); 02172 ast_stopstream(mychannel); 02173 } 02174 } 02175 else if((ct = ast_variable_retrieve(myrpt->cfg, nodename, "unlinkedct"))){ /* Unlinked Courtesy Tone */ 02176 ct_copy = ast_strdupa(ct); 02177 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 02178 if(res) 02179 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 02180 } 02181 if (hasremote && (!myrpt->cmdnode[0])) 02182 { 02183 /* set for all to hear */ 02184 ci.chan = 0; 02185 ci.confno = myrpt->conf; 02186 ci.confmode = ZT_CONF_CONFANN; 02187 /* first put the channel on the conference in announce mode */ 02188 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 02189 { 02190 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02191 rpt_mutex_lock(&myrpt->lock); 02192 remque((struct qelem *)mytele); 02193 rpt_mutex_unlock(&myrpt->lock); 02194 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02195 free(mytele); 02196 ast_hangup(mychannel); 02197 pthread_exit(NULL); 02198 } 02199 if((ct = ast_variable_retrieve(myrpt->cfg, nodename, "remotect"))){ /* Unlinked Courtesy Tone */ 02200 ast_safe_sleep(mychannel,200); 02201 ct_copy = ast_strdupa(ct); 02202 res = telem_lookup(myrpt,mychannel, myrpt->name, ct_copy); 02203 if(res) 02204 ast_log(LOG_WARNING, "telem_lookup:ctx failed on %s\n", mychannel->name); 02205 } 02206 } 02207 #ifdef _MDC_DECODE_H_ 02208 if (myrpt->lastunit) 02209 { 02210 char mystr[10]; 02211 02212 ast_safe_sleep(mychannel,200); 02213 /* set for all to hear */ 02214 ci.chan = 0; 02215 ci.confno = myrpt->txconf; 02216 ci.confmode = ZT_CONF_CONFANN; 02217 /* first put the channel on the conference in announce mode */ 02218 if (ioctl(mychannel->fds[0],ZT_SETCONF,&ci) == -1) 02219 { 02220 ast_log(LOG_WARNING, "Unable to set conference mode to Announce\n"); 02221 rpt_mutex_lock(&myrpt->lock); 02222 remque((struct qelem *)mytele); 02223 rpt_mutex_unlock(&myrpt->lock); 02224 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02225 free(mytele); 02226 ast_hangup(mychannel); 02227 pthread_exit(NULL); 02228 } 02229 sprintf(mystr,"%04x",myrpt->lastunit); 02230 myrpt->lastunit = 0; 02231 ast_say_character_str(mychannel,mystr,NULL,mychannel->language); 02232 break; 02233 } 02234 #endif 02235 imdone = 1; 02236 break; 02237 case REMDISC: 02238 /* wait a little bit */ 02239 wait_interval(myrpt, DLY_TELEM, mychannel); 02240 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 02241 if (!res) 02242 res = ast_waitstream(mychannel, ""); 02243 else 02244 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02245 ast_stopstream(mychannel); 02246 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 02247 res = ast_streamfile(mychannel, ((mytele->mylink.connected) ? 02248 "rpt/remote_disc" : "rpt/remote_busy"), mychannel->language); 02249 break; 02250 case REMALREADY: 02251 /* wait a little bit */ 02252 wait_interval(myrpt, DLY_TELEM, mychannel); 02253 res = ast_streamfile(mychannel, "rpt/remote_already", mychannel->language); 02254 break; 02255 case REMNOTFOUND: 02256 /* wait a little bit */ 02257 wait_interval(myrpt, DLY_TELEM, mychannel); 02258 res = ast_streamfile(mychannel, "rpt/remote_notfound", mychannel->language); 02259 break; 02260 case REMGO: 02261 /* wait a little bit */ 02262 wait_interval(myrpt, DLY_TELEM, mychannel); 02263 res = ast_streamfile(mychannel, "rpt/remote_go", mychannel->language); 02264 break; 02265 case CONNECTED: 02266 /* wait a little bit */ 02267 wait_interval(myrpt, DLY_TELEM, mychannel); 02268 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 02269 if (!res) 02270 res = ast_waitstream(mychannel, ""); 02271 else 02272 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02273 ast_stopstream(mychannel); 02274 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 02275 res = ast_streamfile(mychannel, "rpt/connected", mychannel->language); 02276 break; 02277 case CONNFAIL: 02278 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 02279 if (!res) 02280 res = ast_waitstream(mychannel, ""); 02281 else 02282 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02283 ast_stopstream(mychannel); 02284 ast_say_character_str(mychannel,mytele->mylink.name,NULL,mychannel->language); 02285 res = ast_streamfile(mychannel, "rpt/connection_failed", mychannel->language); 02286 break; 02287 case STATUS: 02288 /* wait a little bit */ 02289 wait_interval(myrpt, DLY_TELEM, mychannel); 02290 hastx = 0; 02291 linkbase.next = &linkbase; 02292 linkbase.prev = &linkbase; 02293 rpt_mutex_lock(&myrpt->lock); 02294 /* make our own list of links */ 02295 l = myrpt->links.next; 02296 while(l != &myrpt->links) 02297 { 02298 if (l->name[0] == '0') 02299 { 02300 l = l->next; 02301 continue; 02302 } 02303 m = malloc(sizeof(struct rpt_link)); 02304 if (!m) 02305 { 02306 ast_log(LOG_WARNING, "Cannot alloc memory on %s\n", mychannel->name); 02307 remque((struct qelem *)mytele); 02308 rpt_mutex_unlock(&myrpt->lock); 02309 ast_log(LOG_NOTICE,"Telemetry thread aborted at line %d, mode: %d\n",__LINE__, mytele->mode); /*@@@@@@@@@@@*/ 02310 free(mytele); 02311 ast_hangup(mychannel); 02312 pthread_exit(NULL); 02313 } 02314 memcpy(m,l,sizeof(struct rpt_link)); 02315 m->next = m->prev = NULL; 02316 insque((struct qelem *)m,(struct qelem *)linkbase.next); 02317 l = l->next; 02318 } 02319 rpt_mutex_unlock(&myrpt->lock); 02320 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 02321 if (!res) 02322 res = ast_waitstream(mychannel, ""); 02323 else 02324 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02325 ast_stopstream(mychannel); 02326 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 02327 if (!res) 02328 res = ast_waitstream(mychannel, ""); 02329 else 02330 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02331 ast_stopstream(mychannel); 02332 if (myrpt->callmode) 02333 { 02334 hastx = 1; 02335 res = ast_streamfile(mychannel, "rpt/autopatch_on", mychannel->language); 02336 if (!res) 02337 res = ast_waitstream(mychannel, ""); 02338 else 02339 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02340 ast_stopstream(mychannel); 02341 } 02342 l = linkbase.next; 02343 while(l != &linkbase) 02344 { 02345 hastx = 1; 02346 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 02347 if (!res) 02348 res = ast_waitstream(mychannel, ""); 02349 else 02350 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02351 ast_stopstream(mychannel); 02352 ast_say_character_str(mychannel,l->name,NULL,mychannel->language); 02353 if (!res) 02354 res = ast_waitstream(mychannel, ""); 02355 else 02356 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02357 ast_stopstream(mychannel); 02358 res = ast_streamfile(mychannel, ((l->mode) ? 02359 "rpt/tranceive" : "rpt/monitor"), mychannel->language); 02360 if (!res) 02361 res = ast_waitstream(mychannel, ""); 02362 else 02363 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02364 ast_stopstream(mychannel); 02365 l = l->next; 02366 } 02367 if (!hastx) 02368 { 02369 res = ast_streamfile(mychannel, "rpt/repeat_only", mychannel->language); 02370 if (!res) 02371 res = ast_waitstream(mychannel, ""); 02372 else 02373 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02374 ast_stopstream(mychannel); 02375 } 02376 /* destroy our local link queue */ 02377 l = linkbase.next; 02378 while(l != &linkbase) 02379 { 02380 m = l; 02381 l = l->next; 02382 remque((struct qelem *)m); 02383 free(m); 02384 } 02385 imdone = 1; 02386 break; 02387 02388 case LASTNODEKEY: /* Identify last node which keyed us up */ 02389 rpt_mutex_lock(&myrpt->lock); 02390 if(myrpt->lastnodewhichkeyedusup) 02391 p = ast_strdupa(myrpt->lastnodewhichkeyedusup); /* Make a local copy of the node name */ 02392 else 02393 p = NULL; 02394 rpt_mutex_unlock(&myrpt->lock); 02395 if(!p){ 02396 imdone = 1; /* no node previously keyed us up, or the node which did has been disconnected */ 02397 break; 02398 } 02399 wait_interval(myrpt, DLY_TELEM, mychannel); 02400 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 02401 if (!res) 02402 res = ast_waitstream(mychannel, ""); 02403 else 02404 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02405 ast_stopstream(mychannel); 02406 ast_say_character_str(mychannel, p, NULL, mychannel->language); 02407 if (!res) 02408 res = ast_waitstream(mychannel, ""); 02409 else 02410 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02411 ast_stopstream(mychannel); 02412 imdone = 1; 02413 break; 02414 02415 case TIMEOUT: 02416 res = ast_streamfile(mychannel, "rpt/node", mychannel->language); 02417 if (!res) 02418 res = ast_waitstream(mychannel, ""); 02419 else 02420 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02421 ast_stopstream(mychannel); 02422 ast_say_character_str(mychannel,myrpt->name,NULL,mychannel->language); 02423 res = ast_streamfile(mychannel, "rpt/timeout", mychannel->language); 02424 break; 02425 02426 case STATS_TIME: 02427 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 02428 t = time(NULL); 02429 localtime_r(&t, &localtm); 02430 /* Say the phase of the day is before the time */ 02431 if((localtm.tm_hour >= 0) && (localtm.tm_hour < 12)) 02432 p = "rpt/goodmorning"; 02433 else if((localtm.tm_hour >= 12) && (localtm.tm_hour < 18)) 02434 p = "rpt/goodafternoon"; 02435 else 02436 p = "rpt/goodevening"; 02437 if (sayfile(mychannel,p) == -1) 02438 { 02439 imdone = 1; 02440 break; 02441 } 02442 /* Say the time is ... */ 02443 if (sayfile(mychannel,"rpt/thetimeis") == -1) 02444 { 02445 imdone = 1; 02446 break; 02447 } 02448 /* Say the time */ 02449 res = ast_say_time(mychannel, t, "", mychannel->language); 02450 if (!res) 02451 res = ast_waitstream(mychannel, ""); 02452 ast_stopstream(mychannel); 02453 imdone = 1; 02454 break; 02455 case STATS_VERSION: 02456 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 02457 /* Say "version" */ 02458 if (sayfile(mychannel,"rpt/version") == -1) 02459 { 02460 imdone = 1; 02461 break; 02462 } 02463 if(!res) /* Say "X" */ 02464 ast_say_number(mychannel, vmajor, "", mychannel->language, (char *) NULL); 02465 if (!res) 02466 res = ast_waitstream(mychannel, ""); 02467 ast_stopstream(mychannel); 02468 if (saycharstr(mychannel,".") == -1) 02469 { 02470 imdone = 1; 02471 break; 02472 } 02473 if(!res) /* Say "Y" */ 02474 ast_say_number(mychannel, vminor, "", mychannel->language, (char *) NULL); 02475 if (!res){ 02476 res = ast_waitstream(mychannel, ""); 02477 ast_stopstream(mychannel); 02478 } 02479 else 02480 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02481 imdone = 1; 02482 break; 02483 case ARB_ALPHA: 02484 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 02485 if(mytele->param) 02486 saycharstr(mychannel, mytele->param); 02487 imdone = 1; 02488 break; 02489 case REV_PATCH: 02490 wait_interval(myrpt, DLY_TELEM, mychannel); /* Wait a little bit */ 02491 if(mytele->param) { 02492 02493 /* Parts of this section taken from app_parkandannounce */ 02494 char *tpl_working, *tpl_current; 02495 char *tmp[100], *myparm; 02496 int looptemp=0,i=0, dres = 0; 02497 02498 02499 tpl_working = strdupa(mytele->param); 02500 myparm = strsep(&tpl_working,","); 02501 tpl_current=strsep(&tpl_working, ":"); 02502 02503 while(tpl_current && looptemp < sizeof(tmp)) { 02504 tmp[looptemp]=tpl_current; 02505 looptemp++; 02506 tpl_current=strsep(&tpl_working,":"); 02507 } 02508 02509 for(i=0; i<looptemp; i++) { 02510 if(!strcmp(tmp[i], "PARKED")) { 02511 ast_say_digits(mychannel, atoi(myparm), "", mychannel->language); 02512 } else if(!strcmp(tmp[i], "NODE")) { 02513 ast_say_digits(mychannel, atoi(myrpt->name), "", mychannel->language); 02514 } else { 02515 dres = ast_streamfile(mychannel, tmp[i], mychannel->language); 02516 if(!dres) { 02517 dres = ast_waitstream(mychannel, ""); 02518 } else { 02519 ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], mychannel->name); 02520 dres = 0; 02521 } 02522 } 02523 } 02524 } 02525 imdone = 1; 02526 break; 02527 case TEST_TONE: 02528 imdone = 1; 02529 myrpt->stopgen = 0; 02530 if ((res = ast_tonepair_start(mychannel, 1004.0, 0, 99999999, 7200.0))) 02531 break; 02532 while(mychannel->generatordata && (!myrpt->stopgen)) { 02533 if (ast_safe_sleep(mychannel,1)) break; 02534 imdone = 1; 02535 } 02536 break; 02537 default: 02538 break; 02539 } 02540 myrpt->stopgen = 0; 02541 if (!imdone) 02542 { 02543 if (!res) 02544 res = ast_waitstream(mychannel, ""); 02545 else { 02546 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 02547 res = 0; 02548 } 02549 } 02550 ast_stopstream(mychannel); 02551 rpt_mutex_lock(&myrpt->lock); 02552 if (mytele->mode == TAILMSG) 02553 { 02554 if (!res) 02555 { 02556 myrpt->tailmessagen++; 02557 if(myrpt->tailmessagen >= myrpt->p.tailmessagemax) myrpt->tailmessagen = 0; 02558 } 02559 else 02560 { 02561 myrpt->tmsgtimer = myrpt->p.tailsquashedtime; 02562 } 02563 } 02564 remque((struct qelem *)mytele); 02565 rpt_mutex_unlock(&myrpt->lock); 02566 free(mytele); 02567 ast_hangup(mychannel); 02568 #ifdef APP_RPT_LOCK_DEBUG 02569 { 02570 struct lockthread *t; 02571 02572 sleep(5); 02573 ast_mutex_lock(&locklock); 02574 t = get_lockthread(pthread_self()); 02575 if (t) memset(t,0,sizeof(struct lockthread)); 02576 ast_mutex_unlock(&locklock); 02577 } 02578 #endif 02579 pthread_exit(NULL); 02580 }
static void rpt_telemetry | ( | struct rpt * | myrpt, | |
int | mode, | |||
void * | data | |||
) | [static] |
Definition at line 2582 of file app_rpt.c.
References ARB_ALPHA, ast_log(), ast_pthread_create, CONNECTED, CONNFAIL, rpt::lock, LOG_WARNING, malloc, rpt_tele::next, REMDISC, REV_PATCH, rpt_mutex_lock, rpt_mutex_unlock, rpt_tele_thread(), rpt::tele, and TELEPARAMSIZE.
Referenced by function_autopatchdn(), function_cop(), function_ilink(), function_macro(), function_status(), handle_link_data(), handle_link_phone_dtmf(), local_dtmf_helper(), queue_id(), rpt(), rpt_call(), and rpt_exec().
02583 { 02584 struct rpt_tele *tele; 02585 struct rpt_link *mylink = (struct rpt_link *) data; 02586 int res; 02587 pthread_attr_t attr; 02588 02589 tele = malloc(sizeof(struct rpt_tele)); 02590 if (!tele) 02591 { 02592 ast_log(LOG_WARNING, "Unable to allocate memory\n"); 02593 pthread_exit(NULL); 02594 return; 02595 } 02596 /* zero it out */ 02597 memset((char *)tele,0,sizeof(struct rpt_tele)); 02598 tele->rpt = myrpt; 02599 tele->mode = mode; 02600 rpt_mutex_lock(&myrpt->lock); 02601 if((mode == CONNFAIL) || (mode == REMDISC) || (mode == CONNECTED)){ 02602 memset(&tele->mylink,0,sizeof(struct rpt_link)); 02603 if (mylink){ 02604 memcpy(&tele->mylink,mylink,sizeof(struct rpt_link)); 02605 } 02606 } 02607 else if ((mode == ARB_ALPHA) || (mode == REV_PATCH)) { 02608 ast_copy_string(tele->param, (char *) data, TELEPARAMSIZE); 02609 } 02610 insque((struct qelem *)tele, (struct qelem *)myrpt->tele.next); 02611 rpt_mutex_unlock(&myrpt->lock); 02612 pthread_attr_init(&attr); 02613 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02614 res = ast_pthread_create(&tele->threadid,&attr,rpt_tele_thread,(void *) tele); 02615 pthread_attr_destroy(&attr); 02616 if(res < 0){ 02617 rpt_mutex_lock(&myrpt->lock); 02618 remque((struct qlem *) tele); /* We don't like stuck transmitters, remove it from the queue */ 02619 rpt_mutex_unlock(&myrpt->lock); 02620 ast_log(LOG_WARNING, "Could not create telemetry thread: %s\n",strerror(res)); 02621 } 02622 return; 02623 }
static int saycharstr | ( | struct ast_channel * | mychannel, | |
char * | str | |||
) | [static] |
Definition at line 1753 of file app_rpt.c.
References ast_log(), ast_say_character_str(), ast_stopstream(), ast_waitstream(), and LOG_WARNING.
Referenced by function_remote(), rmt_saycharstr(), and rpt_tele_thread().
01754 { 01755 int res; 01756 01757 res = ast_say_character_str(mychannel,str,NULL,mychannel->language); 01758 if (!res) 01759 res = ast_waitstream(mychannel, ""); 01760 else 01761 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01762 ast_stopstream(mychannel); 01763 return res; 01764 }
static int sayfile | ( | struct ast_channel * | mychannel, | |
const char * | fname | |||
) | [static] |
Definition at line 1740 of file app_rpt.c.
References ast_log(), ast_stopstream(), ast_streamfile(), ast_waitstream(), and LOG_WARNING.
Referenced by function_remote(), rmt_sayfile(), rpt_tele_thread(), and telem_any().
01741 { 01742 int res; 01743 01744 res = ast_streamfile(mychannel, fname, mychannel->language); 01745 if (!res) 01746 res = ast_waitstream(mychannel, ""); 01747 else 01748 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01749 ast_stopstream(mychannel); 01750 return res; 01751 }
static int saynum | ( | struct ast_channel * | mychannel, | |
int | num | |||
) | [static] |
Definition at line 1766 of file app_rpt.c.
References ast_log(), ast_say_number(), ast_stopstream(), ast_waitstream(), and LOG_WARNING.
Referenced by function_remote().
01767 { 01768 int res; 01769 res = ast_say_number(mychannel, num, NULL, mychannel->language, NULL); 01770 if(!res) 01771 res = ast_waitstream(mychannel, ""); 01772 else 01773 ast_log(LOG_WARNING, "ast_streamfile failed on %s\n", mychannel->name); 01774 ast_stopstream(mychannel); 01775 return res; 01776 }
static void send_link_dtmf | ( | struct rpt * | myrpt, | |
char | c | |||
) | [static] |
Definition at line 2876 of file app_rpt.c.
References AST_FRAME_TEXT, ast_write(), rpt_link::chan, rpt::cmdnode, ast_frame::data, ast_frame::datalen, rpt::dtmfidx, ast_frame::frametype, rpt::links, ast_frame::mallocd, rpt_link::name, rpt::name, rpt_link::next, ast_frame::offset, ast_frame::samples, strdup, and ast_frame::subclass.
Referenced by handle_link_phone_dtmf(), and local_dtmf_helper().
02877 { 02878 char str[300]; 02879 struct ast_frame wf; 02880 struct rpt_link *l; 02881 02882 snprintf(str, sizeof(str), "D %s %s %d %c", myrpt->cmdnode, myrpt->name, ++(myrpt->dtmfidx), c); 02883 wf.frametype = AST_FRAME_TEXT; 02884 wf.subclass = 0; 02885 wf.offset = 0; 02886 wf.mallocd = 1; 02887 wf.datalen = strlen(str) + 1; 02888 wf.samples = 0; 02889 l = myrpt->links.next; 02890 /* first, see if our dude is there */ 02891 while(l != &myrpt->links) 02892 { 02893 if (l->name[0] == '0') 02894 { 02895 l = l->next; 02896 continue; 02897 } 02898 /* if we found it, write it and were done */ 02899 if (!strcmp(l->name,myrpt->cmdnode)) 02900 { 02901 wf.data = strdup(str); 02902 if (l->chan) ast_write(l->chan,&wf); 02903 return; 02904 } 02905 l = l->next; 02906 } 02907 l = myrpt->links.next; 02908 /* if not, give it to everyone */ 02909 while(l != &myrpt->links) 02910 { 02911 wf.data = strdup(str); 02912 if (l->chan) ast_write(l->chan,&wf); 02913 l = l->next; 02914 } 02915 return; 02916 }
static int send_morse | ( | struct ast_channel * | chan, | |
const char * | string, | |||
int | speed, | |||
int | freq, | |||
int | amplitude | |||
) | [static] |
Definition at line 1526 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().
01527 { 01528 01529 static struct morse_bits mbits[] = { 01530 {0, 0}, /* SPACE */ 01531 {0, 0}, 01532 {6, 18},/* " */ 01533 {0, 0}, 01534 {7, 72},/* $ */ 01535 {0, 0}, 01536 {0, 0}, 01537 {6, 30},/* ' */ 01538 {5, 13},/* ( */ 01539 {6, 29},/* ) */ 01540 {0, 0}, 01541 {5, 10},/* + */ 01542 {6, 51},/* , */ 01543 {6, 33},/* - */ 01544 {6, 42},/* . */ 01545 {5, 9}, /* / */ 01546 {5, 31},/* 0 */ 01547 {5, 30},/* 1 */ 01548 {5, 28},/* 2 */ 01549 {5, 24},/* 3 */ 01550 {5, 16},/* 4 */ 01551 {5, 0}, /* 5 */ 01552 {5, 1}, /* 6 */ 01553 {5, 3}, /* 7 */ 01554 {5, 7}, /* 8 */ 01555 {5, 15},/* 9 */ 01556 {6, 7}, /* : */ 01557 {6, 21},/* ; */ 01558 {0, 0}, 01559 {5, 33},/* = */ 01560 {0, 0}, 01561 {6, 12},/* ? */ 01562 {0, 0}, 01563 {2, 2}, /* A */ 01564 {4, 1}, /* B */ 01565 {4, 5}, /* C */ 01566 {3, 1}, /* D */ 01567 {1, 0}, /* E */ 01568 {4, 4}, /* F */ 01569 {3, 3}, /* G */ 01570 {4, 0}, /* H */ 01571 {2, 0}, /* I */ 01572 {4, 14},/* J */ 01573 {3, 5}, /* K */ 01574 {4, 2}, /* L */ 01575 {2, 3}, /* M */ 01576 {2, 1}, /* N */ 01577 {3, 7}, /* O */ 01578 {4, 6}, /* P */ 01579 {4, 11},/* Q */ 01580 {3, 2}, /* R */ 01581 {3, 0}, /* S */ 01582 {1, 1}, /* T */ 01583 {3, 4}, /* U */ 01584 {4, 8}, /* V */ 01585 {3, 6}, /* W */ 01586 {4, 9}, /* X */ 01587 {4, 13},/* Y */ 01588 {4, 3} /* Z */ 01589 }; 01590 01591 01592 int dottime; 01593 int dashtime; 01594 int intralettertime; 01595 int interlettertime; 01596 int interwordtime; 01597 int len, ddcomb; 01598 int res; 01599 int c; 01600 int i; 01601 int flags; 01602 01603 res = 0; 01604 01605 /* Approximate the dot time from the speed arg. */ 01606 01607 dottime = 900/speed; 01608 01609 /* Establish timing relationships */ 01610 01611 dashtime = 3 * dottime; 01612 intralettertime = dottime; 01613 interlettertime = dottime * 4 ; 01614 interwordtime = dottime * 7; 01615 01616 for(;(*string) && (!res); string++){ 01617 01618 c = *string; 01619 01620 /* Convert lower case to upper case */ 01621 01622 if((c >= 'a') && (c <= 'z')) 01623 c -= 0x20; 01624 01625 /* Can't deal with any char code greater than Z, skip it */ 01626 01627 if(c > 'Z') 01628 continue; 01629 01630 /* If space char, wait the inter word time */ 01631 01632 if(c == ' '){ 01633 if(!res) 01634 res = play_silence(chan, interwordtime); 01635 continue; 01636 } 01637 01638 /* Subtract out control char offset to match our table */ 01639 01640 c -= 0x20; 01641 01642 /* Get the character data */ 01643 01644 len = mbits[c].len; 01645 ddcomb = mbits[c].ddcomb; 01646 01647 /* Send the character */ 01648 01649 for(; len ; len--){ 01650 if(!res) 01651 res = play_tone(chan, freq, (ddcomb & 1) ? dashtime : dottime, amplitude); 01652 if(!res) 01653 res = play_silence(chan, intralettertime); 01654 ddcomb >>= 1; 01655 } 01656 01657 /* Wait the interletter time */ 01658 01659 if(!res) 01660 res = play_silence(chan, interlettertime - intralettertime); 01661 } 01662 01663 /* Wait for all the frames to be sent */ 01664 01665 if (!res) 01666 res = ast_waitstream(chan, ""); 01667 ast_stopstream(chan); 01668 01669 /* 01670 * Wait for the zaptel driver to physically write the tone blocks to the hardware 01671 */ 01672 01673 for(i = 0; i < 20 ; i++){ 01674 flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT; 01675 res = ioctl(chan->fds[0], ZT_IOMUX, &flags); 01676 if(flags & ZT_IOMUX_WRITEEMPTY) 01677 break; 01678 if( ast_safe_sleep(chan, 50)){ 01679 res = -1; 01680 break; 01681 } 01682 } 01683 01684 01685 return res; 01686 }
static int send_tone_telemetry | ( | struct ast_channel * | chan, | |
const char * | tonestring | |||
) | [static] |
Definition at line 1688 of file app_rpt.c.
References ast_safe_sleep(), ast_stopstream(), ast_strdupa, ast_waitstream(), ast_channel::fds, play_tone_pair(), and strsep().
Referenced by telem_any().
01689 { 01690 char *stringp; 01691 char *tonesubset; 01692 int f1,f2; 01693 int duration; 01694 int amplitude; 01695 int res; 01696 int i; 01697 int flags; 01698 01699 res = 0; 01700 01701 stringp = ast_strdupa(tonestring); 01702 01703 for(;tonestring;){ 01704 tonesubset = strsep(&stringp,")"); 01705 if(!tonesubset) 01706 break; 01707 if(sscanf(tonesubset,"(%d,%d,%d,%d", &f1, &f2, &duration, &litude) != 4) 01708 break; 01709 res = play_tone_pair(chan, f1, f2, duration, amplitude); 01710 if(res) 01711 break; 01712 } 01713 if(!res) 01714 res = play_tone_pair(chan, 0, 0, 100, 0); /* This is needed to ensure the last tone segment is timed correctly */ 01715 01716 if (!res) 01717 res = ast_waitstream(chan, ""); 01718 ast_stopstream(chan); 01719 01720 /* 01721 * Wait for the zaptel driver to physically write the tone blocks to the hardware 01722 */ 01723 01724 for(i = 0; i < 20 ; i++){ 01725 flags = ZT_IOMUX_WRITEEMPTY | ZT_IOMUX_NOWAIT; 01726 res = ioctl(chan->fds[0], ZT_IOMUX, &flags); 01727 if(flags & ZT_IOMUX_WRITEEMPTY) 01728 break; 01729 if( ast_safe_sleep(chan, 50)){ 01730 res = -1; 01731 break; 01732 } 01733 } 01734 01735 return res; 01736 01737 }
static int serial_remote_io | ( | struct rpt * | myrpt, | |
unsigned char * | txbuf, | |||
int | txbytes, | |||
char * | rxbuf, | |||
int | rxmaxbytes, | |||
int | asciiflag | |||
) | [static] |
Definition at line 4128 of file app_rpt.c.
References ast_channel::fds, and rpt::rxchannel.
Referenced by set_ctcss_freq_ft897(), set_ctcss_mode_ft897(), set_freq_ft897(), set_mode_ft897(), set_offset_ft897(), and simple_command_ft897().
04130 { 04131 int i; 04132 struct zt_radio_param prm; 04133 04134 if(debug){ 04135 printf("String output was: "); 04136 for(i = 0; i < txbytes; i++) 04137 printf("%02X ", (unsigned char ) txbuf[i]); 04138 printf("\n"); 04139 } 04140 04141 prm.radpar = ZT_RADPAR_REMMODE; 04142 if (asciiflag) prm.data = ZT_RADPAR_REM_SERIAL_ASCII; 04143 else prm.data = ZT_RADPAR_REM_SERIAL; 04144 if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 04145 prm.radpar = ZT_RADPAR_REMCOMMAND; 04146 prm.data = rxmaxbytes; 04147 memcpy(prm.buf,txbuf,txbytes); 04148 prm.index = txbytes; 04149 if (ioctl(myrpt->rxchannel->fds[0],ZT_RADIO_SETPARAM,&prm) == -1) return -1; 04150 if (rxbuf) 04151 { 04152 *rxbuf = 0; 04153 memcpy(rxbuf,prm.buf,prm.index); 04154 } 04155 return(prm.index); 04156 }
static int service_scan | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 4786 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(), split_freq(), and stop_scan().
04787 { 04788 int res, interval; 04789 char mhz[MAXREMSTR], decimals[MAXREMSTR], k10=0i, k100=0; 04790 04791 switch(myrpt->hfscanmode){ 04792 04793 case HF_SCAN_DOWN_SLOW: 04794 interval = -10; /* 100Hz /sec */ 04795 break; 04796 04797 case HF_SCAN_DOWN_QUICK: 04798 interval = -50; /* 500Hz /sec */ 04799 break; 04800 04801 case HF_SCAN_DOWN_FAST: 04802 interval = -200; /* 2KHz /sec */ 04803 break; 04804 04805 case HF_SCAN_UP_SLOW: 04806 interval = 10; /* 100Hz /sec */ 04807 break; 04808 04809 case HF_SCAN_UP_QUICK: 04810 interval = 50; /* 500 Hz/sec */ 04811 break; 04812 04813 case HF_SCAN_UP_FAST: 04814 interval = 200; /* 2KHz /sec */ 04815 break; 04816 04817 default: 04818 myrpt->hfscanmode = 0; /* Huh? */ 04819 return -1; 04820 } 04821 04822 res = split_freq(mhz, decimals, myrpt->freq); 04823 04824 if(!res){ 04825 k100 =decimals[0]; 04826 k10 = decimals[1]; 04827 res = multimode_bump_freq(myrpt, interval); 04828 } 04829 04830 if(!res) 04831 res = split_freq(mhz, decimals, myrpt->freq); 04832 04833 04834 if(res){ 04835 stop_scan(myrpt,1); 04836 return -1; 04837 } 04838 04839 /* Announce 10KHz boundaries */ 04840 if(k10 != decimals[1]){ 04841 int myhund = (interval < 0) ? k100 : decimals[0]; 04842 int myten = (interval < 0) ? k10 : decimals[1]; 04843 myrpt->hfscanstatus = (myten == '0') ? (myhund - '0') * 100 : (myten - '0') * 10; 04844 } 04845 return res; 04846 04847 }
static int set_ctcss_freq_ft897 | ( | struct rpt * | myrpt, | |
char * | txtone, | |||
char * | rxtone | |||
) | [static] |
Definition at line 4566 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_ctcss_freq().
Referenced by set_ft897().
04567 { 04568 unsigned char cmdstr[5]; 04569 char hertz[MAXREMSTR],decimal[MAXREMSTR]; 04570 int h,d; 04571 04572 memset(cmdstr, 0, 5); 04573 04574 if(split_ctcss_freq(hertz, decimal, txtone)) 04575 return -1; 04576 04577 h = atoi(hertz); 04578 d = atoi(decimal); 04579 04580 cmdstr[0] = ((h / 100) << 4) + (h % 100)/ 10; 04581 cmdstr[1] = ((h % 10) << 4) + (d % 10); 04582 04583 if(rxtone){ 04584 04585 if(split_ctcss_freq(hertz, decimal, rxtone)) 04586 return -1; 04587 04588 h = atoi(hertz); 04589 d = atoi(decimal); 04590 04591 cmdstr[2] = ((h / 100) << 4) + (h % 100)/ 10; 04592 cmdstr[3] = ((h % 10) << 4) + (d % 10); 04593 } 04594 cmdstr[4] = 0x0B; 04595 04596 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 04597 }
static int set_ctcss_mode_ft897 | ( | struct rpt * | myrpt, | |
char | txplon, | |||
char | rxplon | |||
) | [static] |
Definition at line 4543 of file app_rpt.c.
References serial_remote_io().
Referenced by set_ft897().
04544 { 04545 unsigned char cmdstr[5]; 04546 04547 memset(cmdstr, 0, 5); 04548 04549 if(rxplon && txplon) 04550 cmdstr[0] = 0x2A; /* Encode and Decode */ 04551 else if (!rxplon && txplon) 04552 cmdstr[0] = 0x4A; /* Encode only */ 04553 else if (rxplon && !txplon) 04554 cmdstr[0] = 0x3A; /* Encode only */ 04555 else 04556 cmdstr[0] = 0x8A; /* OFF */ 04557 04558 cmdstr[4] = 0x0A; 04559 04560 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 04561 }
static int set_freq_ft897 | ( | struct rpt * | myrpt, | |
char * | newfreq | |||
) | [static] |
Definition at line 4435 of file app_rpt.c.
References MAXREMSTR, serial_remote_io(), and split_freq().
Referenced by multimode_bump_freq_ft897(), and set_ft897().
04436 { 04437 char mhz[MAXREMSTR]; 04438 char decimals[MAXREMSTR]; 04439 unsigned char cmdstr[5]; 04440 int fd,m,d; 04441 04442 fd = 0; 04443 if(debug) 04444 printf("New frequency: %s\n",newfreq); 04445 04446 if(split_freq(mhz, decimals, newfreq)) 04447 return -1; 04448 04449 m = atoi(mhz); 04450 d = atoi(decimals); 04451 04452 /* The FT-897 likes packed BCD frequencies */ 04453 04454 cmdstr[0] = ((m / 100) << 4) + ((m % 100)/10); /* 100MHz 10Mhz */ 04455 cmdstr[1] = ((m % 10) << 4) + (d / 10000); /* 1MHz 100KHz */ 04456 cmdstr[2] = (((d % 10000)/1000) << 4) + ((d % 1000)/ 100); /* 10KHz 1KHz */ 04457 cmdstr[3] = (((d % 100)/10) << 4) + (d % 10); /* 100Hz 10Hz */ 04458 cmdstr[4] = 0x01; /* command */ 04459 04460 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 04461 04462 }
static int set_ft897 | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 4601 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 setrem().
04602 { 04603 int res; 04604 04605 if(debug) 04606 printf("@@@@ lock on\n"); 04607 04608 res = simple_command_ft897(myrpt, 0x00); /* LOCK on */ 04609 04610 if(debug) 04611 printf("@@@@ ptt off\n"); 04612 04613 if(!res) 04614 res = simple_command_ft897(myrpt, 0x88); /* PTT off */ 04615 04616 if(debug) 04617 printf("Modulation mode\n"); 04618 04619 if(!res) 04620 res = set_mode_ft897(myrpt, myrpt->remmode); /* Modulation mode */ 04621 04622 if(debug) 04623 printf("Split off\n"); 04624 04625 if(!res) 04626 simple_command_ft897(myrpt, 0x82); /* Split off */ 04627 04628 if(debug) 04629 printf("Frequency\n"); 04630 04631 if(!res) 04632 res = set_freq_ft897(myrpt, myrpt->freq); /* Frequency */ 04633 if((myrpt->remmode == REM_MODE_FM)){ 04634 if(debug) 04635 printf("Offset\n"); 04636 if(!res) 04637 res = set_offset_ft897(myrpt, myrpt->offset); /* Offset if FM */ 04638 if((!res)&&(myrpt->rxplon || myrpt->txplon)){ 04639 if(debug) 04640 printf("CTCSS tone freqs.\n"); 04641 res = set_ctcss_freq_ft897(myrpt, myrpt->txpl, myrpt->rxpl); /* CTCSS freqs if CTCSS is enabled */ 04642 } 04643 if(!res){ 04644 if(debug) 04645 printf("CTCSS mode\n"); 04646 res = set_ctcss_mode_ft897(myrpt, myrpt->txplon, myrpt->rxplon); /* CTCSS mode */ 04647 } 04648 } 04649 if((myrpt->remmode == REM_MODE_USB)||(myrpt->remmode == REM_MODE_LSB)){ 04650 if(debug) 04651 printf("Clarifier off\n"); 04652 simple_command_ft897(myrpt, 0x85); /* Clarifier off if LSB or USB */ 04653 } 04654 return res; 04655 }
static int set_mode_ft897 | ( | struct rpt * | myrpt, | |
char | newmode | |||
) | [static] |
Definition at line 4510 of file app_rpt.c.
References REM_MODE_AM, REM_MODE_FM, REM_MODE_LSB, REM_MODE_USB, and serial_remote_io().
Referenced by set_ft897().
04511 { 04512 unsigned char cmdstr[5]; 04513 04514 memset(cmdstr, 0, 5); 04515 04516 switch(newmode){ 04517 case REM_MODE_FM: 04518 cmdstr[0] = 0x08; 04519 break; 04520 04521 case REM_MODE_USB: 04522 cmdstr[0] = 0x01; 04523 break; 04524 04525 case REM_MODE_LSB: 04526 cmdstr[0] = 0x00; 04527 break; 04528 04529 case REM_MODE_AM: 04530 cmdstr[0] = 0x04; 04531 break; 04532 04533 default: 04534 return -1; 04535 } 04536 cmdstr[4] = 0x07; 04537 04538 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 04539 }
static int set_offset_ft897 | ( | struct rpt * | myrpt, | |
char | offset | |||
) | [static] |
Definition at line 4480 of file app_rpt.c.
References REM_MINUS, REM_PLUS, REM_SIMPLEX, and serial_remote_io().
Referenced by set_ft897().
04481 { 04482 unsigned char cmdstr[5]; 04483 04484 memset(cmdstr, 0, 5); 04485 04486 switch(offset){ 04487 case REM_SIMPLEX: 04488 cmdstr[0] = 0x89; 04489 break; 04490 04491 case REM_MINUS: 04492 cmdstr[0] = 0x09; 04493 break; 04494 04495 case REM_PLUS: 04496 cmdstr[0] = 0x49; 04497 break; 04498 04499 default: 04500 return -1; 04501 } 04502 04503 cmdstr[4] = 0x09; 04504 04505 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 04506 }
static int setrbi | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 4158 of file app_rpt.c.
References rpt::freq, MAXREMSTR, rpt::offset, rpt::powerlevel, rbi_mhztoband(), rbi_out(), rbi_pltocode(), REM_HIPWR, REM_LOWPWR, REM_MEDPWR, REM_MINUS, REM_PLUS, REM_SIMPLEX, rpt::remote, rpt::rxplon, s, rpt::txpl, and rpt::txplon.
Referenced by setrem().
04159 { 04160 char tmp[MAXREMSTR] = "",*s; 04161 unsigned char rbicmd[5]; 04162 int band,txoffset = 0,txpower = 0,txpl; 04163 04164 /* must be a remote system */ 04165 if (!myrpt->remote) return(0); 04166 /* must have rbi hardware */ 04167 if (strncmp(myrpt->remote,remote_rig_rbi,3)) return(0); 04168 ast_copy_string(tmp, myrpt->freq, sizeof(tmp)); 04169 s = strchr(tmp,'.'); 04170 /* if no decimal, is invalid */ 04171 04172 if (s == NULL){ 04173 if(debug) 04174 printf("@@@@ Frequency needs a decimal\n"); 04175 return -1; 04176 } 04177 04178 *s++ = 0; 04179 if (strlen(tmp) < 2){ 04180 if(debug) 04181 printf("@@@@ Bad MHz digits: %s\n", tmp); 04182 return -1; 04183 } 04184 04185 if (strlen(s) < 3){ 04186 if(debug) 04187 printf("@@@@ Bad KHz digits: %s\n", s); 04188 return -1; 04189 } 04190 04191 if ((s[2] != '0') && (s[2] != '5')){ 04192 if(debug) 04193 printf("@@@@ KHz must end in 0 or 5: %c\n", s[2]); 04194 return -1; 04195 } 04196 04197 band = rbi_mhztoband(tmp); 04198 if (band == -1){ 04199 if(debug) 04200 printf("@@@@ Bad Band: %s\n", tmp); 04201 return -1; 04202 } 04203 04204 txpl = rbi_pltocode(myrpt->txpl); 04205 04206 if (txpl == -1){ 04207 if(debug) 04208 printf("@@@@ Bad TX PL: %s\n", myrpt->txpl); 04209 return -1; 04210 } 04211 04212 04213 switch(myrpt->offset) 04214 { 04215 case REM_MINUS: 04216 txoffset = 0; 04217 break; 04218 case REM_PLUS: 04219 txoffset = 0x10; 04220 break; 04221 case REM_SIMPLEX: 04222 txoffset = 0x20; 04223 break; 04224 } 04225 switch(myrpt->powerlevel) 04226 { 04227 case REM_LOWPWR: 04228 txpower = 0; 04229 break; 04230 case REM_MEDPWR: 04231 txpower = 0x20; 04232 break; 04233 case REM_HIPWR: 04234 txpower = 0x10; 04235 break; 04236 } 04237 rbicmd[0] = 0; 04238 rbicmd[1] = band | txpower | 0xc0; 04239 rbicmd[2] = (*(s - 2) - '0') | txoffset | 0x80; 04240 if (s[2] == '5') rbicmd[2] |= 0x40; 04241 rbicmd[3] = ((*s - '0') << 4) + (s[1] - '0'); 04242 rbicmd[4] = txpl; 04243 if (myrpt->txplon) rbicmd[4] |= 0x40; 04244 if (myrpt->rxplon) rbicmd[4] |= 0x80; 04245 rbi_out(myrpt,rbicmd); 04246 return 0; 04247 }
static int setrem | ( | struct rpt * | myrpt | ) | [static] |
Definition at line 4713 of file app_rpt.c.
References rpt::remote, set_ft897(), and setrbi().
Referenced by function_remote(), and rpt_exec().
04714 { 04715 return 0; /* XXX BROKEN!! */ 04716 if(!strcmp(myrpt->remote, remote_rig_ft897)) 04717 return set_ft897(myrpt); 04718 else if(!strcmp(myrpt->remote, remote_rig_rbi)) 04719 return setrbi(myrpt); 04720 else 04721 return -1; 04722 }
static int simple_command_ft897 | ( | struct rpt * | myrpt, | |
char | command | |||
) | [static] |
Definition at line 4466 of file app_rpt.c.
References serial_remote_io().
Referenced by closerem_ft897(), and set_ft897().
04467 { 04468 unsigned char cmdstr[5]; 04469 04470 memset(cmdstr, 0, 5); 04471 04472 cmdstr[4] = command; 04473 04474 return serial_remote_io(myrpt, cmdstr, 5, NULL, 0, 0); 04475 04476 }
static char* skipchars | ( | char * | string, | |
char * | charlist | |||
) | [static] |
Definition at line 884 of file app_rpt.c.
Referenced by function_autopatchup().
00885 { 00886 int i; 00887 while(*string){ 00888 for(i = 0; charlist[i] ; i++){ 00889 if(*string == charlist[i]){ 00890 string++; 00891 break; 00892 } 00893 } 00894 if(!charlist[i]) 00895 return string; 00896 } 00897 return string; 00898 }
static int split_ctcss_freq | ( | char * | hertz, | |
char * | decimal, | |||
char * | freq | |||
) | [static] |
Definition at line 4315 of file app_rpt.c.
References ast_strdupa, and MAXREMSTR.
Referenced by set_ctcss_freq_ft897().
04316 { 04317 char *decp; 04318 04319 freq = ast_strdupa(freq); 04320 if ((decp = strchr(freq, '.'))) { 04321 *decp++ = 0; 04322 ast_copy_string(hertz, freq, MAXREMSTR); 04323 ast_copy_string(decimal, decp, sizeof(decimal)); 04324 return 0; 04325 } 04326 else 04327 return -1; 04328 }
static int split_freq | ( | char * | mhz, | |
char * | decimals, | |||
char * | freq | |||
) | [static] |
Definition at line 4294 of file app_rpt.c.
References ast_strdupa, and MAXREMSTR.
Referenced by function_remote(), multimode_bump_freq_ft897(), service_scan(), and set_freq_ft897().
04295 { 04296 char *decp; 04297 04298 freq = ast_strdupa(freq); 04299 if ((decp = strchr(freq, '.'))) { 04300 *decp++ = 0; 04301 ast_copy_string(mhz, freq, MAXREMSTR); 04302 strcpy(decimals, "00000"); 04303 ast_copy_string(decimals, decp, 6); 04304 return 0; 04305 } 04306 else 04307 return -1; 04308 04309 }
static void stop_scan | ( | struct rpt * | myrpt, | |
int | flag | |||
) | [static] |
Definition at line 4775 of file app_rpt.c.
References rpt::hfscanmode, and rpt::hfscanstatus.
Referenced by handle_remote_dtmf_digit(), and service_scan().
04776 { 04777 myrpt->hfscanmode = 0; 04778 myrpt->hfscanstatus = ((flag) ? -2 : -1); 04779 }
static int telem_any | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
const char * | entry | |||
) | [static] |
Definition at line 1779 of file app_rpt.c.
References MORSE, retrieve_astcfgint(), sayfile(), send_morse(), and send_tone_telemetry().
Referenced by rpt_tele_thread(), and telem_lookup().
01780 { 01781 int res; 01782 char c; 01783 01784 static int morsespeed; 01785 static int morsefreq; 01786 static int morseampl; 01787 static int morseidfreq = 0; 01788 static int morseidampl; 01789 static char mcat[] = MORSE; 01790 01791 res = 0; 01792 01793 if(!morseidfreq){ /* Get the morse parameters if not already loaded */ 01794 morsespeed = retrieve_astcfgint(myrpt, mcat, "speed", 5, 20, 20); 01795 morsefreq = retrieve_astcfgint(myrpt, mcat, "frequency", 300, 3000, 800); 01796 morseampl = retrieve_astcfgint(myrpt, mcat, "amplitude", 200, 8192, 4096); 01797 morseidampl = retrieve_astcfgint(myrpt, mcat, "idamplitude", 200, 8192, 2048); 01798 morseidfreq = retrieve_astcfgint(myrpt, mcat, "idfrequency", 300, 3000, 330); 01799 } 01800 01801 /* Is it a file, or a tone sequence? */ 01802 01803 if(entry[0] == '|'){ 01804 c = entry[1]; 01805 if((c >= 'a')&&(c <= 'z')) 01806 c -= 0x20; 01807 01808 switch(c){ 01809 case 'I': /* Morse ID */ 01810 res = send_morse(chan, entry + 2, morsespeed, morseidfreq, morseidampl); 01811 break; 01812 01813 case 'M': /* Morse Message */ 01814 res = send_morse(chan, entry + 2, morsespeed, morsefreq, morseampl); 01815 break; 01816 01817 case 'T': /* Tone sequence */ 01818 res = send_tone_telemetry(chan, entry + 2); 01819 break; 01820 default: 01821 res = -1; 01822 } 01823 } 01824 else 01825 res = sayfile(chan, entry); /* File */ 01826 return res; 01827 }
static int telem_lookup | ( | struct rpt * | myrpt, | |
struct ast_channel * | chan, | |||
char * | node, | |||
char * | name | |||
) | [static] |
Definition at line 1835 of file app_rpt.c.
References ast_log(), ast_strdupa, ast_variable_retrieve(), rpt::cfg, LOG_WARNING, tele_defs, telem_any(), and TELEMETRY.
Referenced by handle_remote_data(), handle_remote_phone_dtmf(), and rpt_tele_thread().
01836 { 01837 01838 int res; 01839 int i; 01840 const char *entry; 01841 const char *telemetry; 01842 char *telemetry_save; 01843 01844 res = 0; 01845 telemetry_save = NULL; 01846 entry = NULL; 01847 01848 /* Retrieve the section name for telemetry from the node section */ 01849 telemetry = ast_variable_retrieve(myrpt->cfg, node, TELEMETRY); 01850 if(telemetry ){ 01851 telemetry_save = ast_strdupa(telemetry); 01852 if(!telemetry_save){ 01853 ast_log(LOG_WARNING,"ast_strdupa() failed in telem_lookup()\n"); 01854 return res; 01855 } 01856 entry = ast_variable_retrieve(myrpt->cfg, telemetry_save, name); 01857 } 01858 01859 /* Try to look up the telemetry name */ 01860 01861 if(!entry){ 01862 /* Telemetry name wasn't found in the config file, use the default */ 01863 for(i = 0; i < sizeof(tele_defs)/sizeof(struct telem_defaults) ; i++){ 01864 if(!strcasecmp(tele_defs[i].name, name)) 01865 entry = tele_defs[i].value; 01866 } 01867 } 01868 if(entry){ 01869 if(strlen(entry)) 01870 telem_any(myrpt,chan, entry); 01871 } 01872 else{ 01873 res = -1; 01874 } 01875 return res; 01876 }
static int unload_module | ( | void | ) | [static] |
Definition at line 8014 of file app_rpt.c.
References ast_cli_unregister_multiple(), ast_module_user_hangup_all, ast_mutex_destroy(), ast_unregister_application(), cli_rpt, lock, name, rpt::nodes, and rpt_vars.
08015 { 08016 int i; 08017 08018 ast_module_user_hangup_all(); 08019 for(i = 0; i < nrpts; i++) { 08020 if (!strcmp(rpt_vars[i].name,rpt_vars[i].p.nodes)) continue; 08021 ast_mutex_destroy(&rpt_vars[i].lock); 08022 } 08023 i = ast_unregister_application(app); 08024 08025 /* Unregister cli extensions */ 08026 ast_cli_unregister_multiple(cli_rpt, sizeof(cli_rpt) / sizeof(struct ast_cli_entry)); 08027 08028 return i; 08029 }
static void wait_interval | ( | struct rpt * | myrpt, | |
int | type, | |||
struct ast_channel * | chan | |||
) | [static] |
Definition at line 1939 of file app_rpt.c.
References ast_log(), ast_safe_sleep(), get_wait_interval(), and LOG_NOTICE.
Referenced by rpt_tele_thread().
01940 { 01941 int interval; 01942 interval = get_wait_interval(myrpt, type); 01943 if(debug) 01944 ast_log(LOG_NOTICE," Delay interval = %d\n", interval); 01945 if(interval) 01946 ast_safe_sleep(chan,interval); 01947 if(debug) 01948 ast_log(LOG_NOTICE,"Delay complete\n"); 01949 return; 01950 }
struct ast_cli_entry cli_rpt[] [static] |
int debug = 0 [static] |
Definition at line 286 of file app_rpt.c.
Referenced by add_sdp(), add_t38_sdp(), aji_load_config(), check_user_full(), dladdr(), dlclose(), dlsymIntern(), error(), findFile(), get_mach_header_from_NSModule(), getSearchPath(), handle_request(), insertStatus(), loadModule(), lookupStatus(), process_sdp(), promoteLocalToGlobal(), reference(), search_linked_libs(), set_destination(), and sip_sendtext().
char debug_usage[] [static] |
char dump_lstats[] [static] |
char dump_stats[] [static] |
char dump_usage[] [static] |
struct function_table_tag function_table[] [static] |
char reload_usage[] [static] |
char* remote_rig_ft897 = "ft897" [static] |
char* remote_rig_rbi = "rbi" [static] |
char restart_usage[] [static] |
pthread_t rpt_master_thread [static] |
Referenced by load_rpt_vars(), reload(), rpt(), rpt_do_dump(), rpt_do_lstats(), rpt_do_reload(), rpt_do_restart(), rpt_do_stats(), rpt_exec(), rpt_master(), and unload_module().
char* synopsis = "Radio Repeater/Remote Base Control System" [static] |
struct telem_defaults tele_defs[] [static] |