parent
d61154d754
commit
5910117048
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (C) 2019 by Thomas A. Early N7TAE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "ConfigureBase.h"
|
||||
|
||||
CConfigureBase::CConfigureBase()
|
||||
{
|
||||
}
|
||||
|
||||
CConfigureBase::~CConfigureBase()
|
||||
{
|
||||
defaults.empty();
|
||||
}
|
||||
|
||||
char *CConfigureBase::Trim(char *s)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
while (len && isspace(s[len-1]))
|
||||
s[--len] = '\0';
|
||||
while (*s && len && isspace(*s))
|
||||
len = strlen(++s);
|
||||
return s;
|
||||
}
|
||||
|
||||
bool CConfigureBase::ReadConfigFile(const char *configfile, std::map<std::string, std::string> &amap)
|
||||
{
|
||||
FILE *fp = fopen(configfile, "r");
|
||||
if (fp) {
|
||||
char line[128];
|
||||
if (fgets(line, 128, fp)) {
|
||||
char *key = strtok(line, "=");
|
||||
key = Trim(key);
|
||||
if (strlen(key) && '#' != *key) {
|
||||
char *val = strtok(NULL, "\r\n");
|
||||
char *val2 = Trim(val);
|
||||
if ('\'' == *val2)
|
||||
val = strtok(val2, "'");
|
||||
else
|
||||
val = strtok(val2, "# \t");
|
||||
amap[key] = val;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
fprintf(stderr, "could not open file %s\n", configfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConfigureBase::Initialize(const char *file)
|
||||
{
|
||||
std::string filename(CFG_DIR);
|
||||
filename.append("/qndefaults");
|
||||
if (ReadConfigFile(filename.c_str(), defaults))
|
||||
return true;
|
||||
return ReadConfigFile(file, cfg);
|
||||
}
|
||||
|
||||
bool CConfigureBase::GetDefaultBool(const std::string &path, const std::string &mod, bool &dvalue)
|
||||
{
|
||||
std::string value;
|
||||
if (GetDefaultString(path, mod, value))
|
||||
return true; // No default value defined!
|
||||
if ('0'==value.at(0) || 'f'==value.at(0) || 'F'==value.at(0))
|
||||
dvalue = false;
|
||||
else if ('1'==value.at(0) || 't'==value.at(0) || 'T'==value.at(0))
|
||||
dvalue = true;
|
||||
else {
|
||||
fprintf(stderr, "%s=%s doesn't seem to be a boolean!\n", path.c_str(), value.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CConfigureBase::GetDefaultDouble(const std::string &path, const std::string &mod, double &dvalue)
|
||||
{
|
||||
std::string value;
|
||||
if (GetDefaultString(path, mod, value))
|
||||
return true; // No default value defined!
|
||||
dvalue = std::stod(value);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CConfigureBase::GetDefaultInt(const std::string &path, const std::string &mod, int &dvalue)
|
||||
{
|
||||
std::string value;
|
||||
if (GetDefaultString(path, mod, value))
|
||||
return true; // No default value defined!
|
||||
dvalue = std::stoi(value);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CConfigureBase::GetDefaultString(const std::string &path, const std::string &mod, std::string &dvalue)
|
||||
{
|
||||
std::string search, search_again;
|
||||
if (mod.empty()) {
|
||||
search = path + "_d"; // there is no mod, so this is a simple search
|
||||
} else {
|
||||
search_again = mod; // we're looking from a module value. We may have to look for non-generic module parameters
|
||||
if (0==path.compare(0, 7, "module_") && ('a'==path.at(7) || 'b'==path.at(7) || 'c'==path.at(7)) && '_'==path.at(8)) {
|
||||
// path begins with module_{a|b|c}_
|
||||
if (0==mod.compare("dvrptr") || 0==mod.compare("dvap") || 0==mod.compare("mmdvm") || 0==mod.compare("itap")) {
|
||||
// and the module is recognized
|
||||
search = path;
|
||||
search.replace(7, 1, 1, 'x');
|
||||
search_again += path.substr(8); // now the search_again path might look like dvap_frequency, for example.
|
||||
} else {
|
||||
fprintf(stderr, "Unrecognized module type = '%s'\n", mod.c_str());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s looks like an ilformed request from module '%s'\n", path.c_str(), mod.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
auto it = defaults.find(search);
|
||||
if (defaults.end() == it) {
|
||||
it = defaults.find(search_again);
|
||||
if (defaults.end() == it) {
|
||||
fprintf(stderr, "%s has no default value!\n", path.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
dvalue = it->second;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CConfigureBase::GetValue(const std::string &path, const std::string &mod, bool &value)
|
||||
{
|
||||
auto it = cfg.find(path);
|
||||
if (cfg.end() == it) {
|
||||
bool dvalue;
|
||||
if (GetDefaultBool(path, mod, dvalue)) {
|
||||
fprintf(stderr, "%s not found in either the cfg file or the defaults file!\n", path.c_str());
|
||||
return true;
|
||||
}
|
||||
value = dvalue; // found a value in the defaults
|
||||
} else { // found a value in the cfg file
|
||||
char c = it->second.at(0);
|
||||
if ('0'==c || 'f'==c || 'F'==c)
|
||||
value = false;
|
||||
else if ('1'==c || 't'==c || 'T'==c)
|
||||
value = true;
|
||||
else {
|
||||
fprintf(stderr, "%s=%s doesn't seem to define a boolean\n", path.c_str(), it->second.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
printf("%s = %s\n", path.c_str(), value ? "true" : "false");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CConfigureBase::GetValue(const std::string &path, const std::string &mod, double &value, const double min, const double max)
|
||||
{
|
||||
auto it = cfg.find(path);
|
||||
if (cfg.end() == it) {
|
||||
double dvalue;
|
||||
if (GetDefaultDouble(path, mod, dvalue)) {
|
||||
fprintf(stderr, "%s not found in either the cfg file or the defaults file!\n", path.c_str());
|
||||
return true;
|
||||
}
|
||||
if (dvalue < min || dvalue > max) {
|
||||
fprintf(stderr, "Default value %s=%g is out of acceptable range\n", path.c_str(), value);
|
||||
return true;
|
||||
}
|
||||
value = dvalue;
|
||||
} else {
|
||||
value = std::stod(it->second);
|
||||
if (value < min || value > max) {
|
||||
fprintf(stderr, "%s=%g is out of acceptable range\n", path.c_str(), value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
printf("%s = %g\n", path.c_str(), value);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CConfigureBase::GetValue(const std::string &path, const std::string &mod, int &value, const int min, const int max)
|
||||
{
|
||||
auto it = cfg.find(path);
|
||||
if (cfg.end() == it) {
|
||||
int dvalue;
|
||||
if (GetDefaultInt(path, mod, dvalue)) {
|
||||
fprintf(stderr, "%s not found in either the cfg file or the defaults file\n", path.c_str());
|
||||
return true;
|
||||
}
|
||||
if (dvalue < min || dvalue > max) {
|
||||
fprintf(stderr, "Default value %s=%d is out of acceptable range\n", path.c_str(), value);
|
||||
return true;
|
||||
}
|
||||
value = dvalue;
|
||||
} else {
|
||||
value = std::stoi(it->second);
|
||||
if (value < min || value > max) {
|
||||
fprintf(stderr, "%s=%s is out of acceptable range\n", path.c_str(), it->second.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
printf("%s = %d\n", path.c_str(), value);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CConfigureBase::GetValue(const std::string &path, const std::string &mod, std::string &value, int min, int max)
|
||||
{
|
||||
auto it = cfg.find(path);
|
||||
if (cfg.end() != it) {
|
||||
std::string dvalue;
|
||||
if (GetDefaultString(path, mod, dvalue)) {
|
||||
fprintf(stderr, "%s not found in either the cfg file for the defaults file\n", path.c_str());
|
||||
return true;
|
||||
}
|
||||
int l = dvalue.length();
|
||||
if (l<min || l>max) {
|
||||
printf("Default value %s='%s' is wrong size\n", path.c_str(), value.c_str());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
value = it->second;
|
||||
int l = value.length();
|
||||
if (l<min || l>max) {
|
||||
printf("%s='%s' is wrong size\n", path.c_str(), value.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
printf("%s = '%s'\n", path.c_str(), value.c_str());
|
||||
return false;
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2019 by Thomas A. Early N7TAE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class CConfigureBase {
|
||||
public:
|
||||
CConfigureBase();
|
||||
virtual ~CConfigureBase();
|
||||
virtual bool ReadCfgFile() = 0;
|
||||
bool Initialize(const char *configfile);
|
||||
|
||||
protected:
|
||||
std::map<std::string, std::string> cfg;
|
||||
|
||||
char *Trim(char *s);
|
||||
bool ReadConfigFile(const char *file, std::map<std::string, std::string> &amap);
|
||||
bool GetValue(const std::string &path, const std::string &mod, bool &value);
|
||||
bool GetValue(const std::string &path, const std::string &mod, double &value, const double min, const double max);
|
||||
bool GetValue(const std::string &path, const std::string &mod, int &value, const int min, const int max);
|
||||
bool GetValue(const std::string &path, const std::string &mod, std::string &value, const int min, const int max);
|
||||
private:
|
||||
std::map<std::string, std::string> defaults;
|
||||
|
||||
bool GetDefaultBool (const std::string &key, const std::string &mod, bool &dval);
|
||||
bool GetDefaultDouble(const std::string &key, const std::string &mod, double &dval);
|
||||
bool GetDefaultInt (const std::string &key, const std::string &mod, int &dval);
|
||||
bool GetDefaultString(const std::string &key, const std::string &mod, std::string &dval);
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 by Thomas Early N7TAE
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <libconfig.h++>
|
||||
#include "QnetTypeDefs.h"
|
||||
#include "SEcho.h"
|
||||
|
||||
#include "aprs.h"
|
||||
|
||||
using namespace libconfig;
|
||||
|
||||
#define IP_SIZE 15
|
||||
#define MAXHOSTNAMELEN 64
|
||||
#define CALL_SIZE 8
|
||||
#define MAX_DTMF_BUF 32
|
||||
|
||||
typedef struct to_remote_g2_tag {
|
||||
unsigned short streamid;
|
||||
struct sockaddr_in toDst4;
|
||||
time_t last_time;
|
||||
} STOREMOTEG2;
|
||||
|
||||
typedef struct torepeater_tag {
|
||||
// help with header re-generation
|
||||
unsigned char saved_hdr[58]; // repeater format
|
||||
uint32_t saved_adr;
|
||||
|
||||
unsigned short streamid;
|
||||
uint32_t adr;
|
||||
struct sockaddr_in band_addr;
|
||||
time_t last_time;
|
||||
std::atomic<unsigned short> G2_COUNTER;
|
||||
unsigned char sequence;
|
||||
} STOREPEATER;
|
||||
|
||||
typedef struct band_txt_tag {
|
||||
unsigned short streamID;
|
||||
unsigned char flags[3];
|
||||
char lh_mycall[CALL_SIZE + 1];
|
||||
char lh_sfx[5];
|
||||
char lh_yrcall[CALL_SIZE + 1];
|
||||
char lh_rpt1[CALL_SIZE + 1];
|
||||
char lh_rpt2[CALL_SIZE + 1];
|
||||
time_t last_time;
|
||||
char txt[64]; // Only 20 are used
|
||||
unsigned short txt_cnt;
|
||||
bool sent_key_on_msg;
|
||||
|
||||
char dest_rptr[CALL_SIZE + 1];
|
||||
|
||||
// try to process GPS mode: GPRMC and ID
|
||||
char temp_line[256];
|
||||
unsigned short temp_line_cnt;
|
||||
char gprmc[256];
|
||||
char gpid[256];
|
||||
bool is_gps_sent;
|
||||
time_t gps_last_time;
|
||||
|
||||
int num_dv_frames;
|
||||
int num_dv_silent_frames;
|
||||
int num_bit_errors;
|
||||
} SBANDTXT;
|
||||
|
||||
class CQnetGateway {
|
||||
public:
|
||||
CQnetGateway();
|
||||
~CQnetGateway();
|
||||
void Process();
|
||||
int Init(char *cfgfile);
|
||||
|
||||
private:
|
||||
// text stuff
|
||||
bool new_group[3] = { true, true, true };
|
||||
unsigned char header_type = 0;
|
||||
short to_print[3] = { 0, 0, 0 };
|
||||
bool ABC_grp[3] = { false, false, false };
|
||||
bool C_seen[3] = { false, false, false };
|
||||
|
||||
SPORTIP g2_internal, g2_external, g2_link, ircddb;
|
||||
|
||||
std::string OWNER, owner, local_irc_ip, status_file, dtmf_dir, dtmf_file, echotest_dir, irc_pass, qnvoicefile;
|
||||
|
||||
bool bool_send_qrgs, bool_irc_debug, bool_dtmf_debug, bool_regen_header, bool_qso_details, bool_send_aprs, playNotInCache;
|
||||
|
||||
int play_wait, play_delay, echotest_rec_timeout, voicemail_rec_timeout, from_remote_g2_timeout, from_local_rptr_timeout, dtmf_digit;
|
||||
|
||||
unsigned int vPacketCount;
|
||||
|
||||
std::map <uint32_t, uint16_t> portmap;
|
||||
|
||||
// data needed for aprs login and aprs beacon
|
||||
// RPTR defined in aprs.h
|
||||
SRPTR rptr;
|
||||
|
||||
// local repeater modules being recorded
|
||||
// This is for echotest and voicemail
|
||||
SECHO recd[3], vm[3];
|
||||
SDSVT recbuf; // 56 or 27, max is 56
|
||||
|
||||
// the streamids going to remote Gateways from each local module
|
||||
STOREMOTEG2 to_remote_g2[3]; // 0=A, 1=B, 2=C
|
||||
|
||||
// input from remote G2 gateway
|
||||
int g2_sock = -1;
|
||||
struct sockaddr_in fromDst4;
|
||||
|
||||
// Incoming data from remote systems
|
||||
// must be fed into our local repeater modules.
|
||||
STOREPEATER toRptr[3]; // 0=A, 1=B, 2=C
|
||||
|
||||
// input from our own local repeater modules
|
||||
int srv_sock = -1;
|
||||
SDSTR rptrbuf; // 58 or 29 or 32, max is 58
|
||||
struct sockaddr_in fromRptr;
|
||||
|
||||
SDSTR end_of_audio;
|
||||
|
||||
// send packets to g2_link
|
||||
struct sockaddr_in plug;
|
||||
|
||||
// for talking with the irc server
|
||||
CIRCDDB *ii;
|
||||
// for handling APRS stuff
|
||||
CAPRS *aprs;
|
||||
|
||||
// text coming from local repeater bands
|
||||
SBANDTXT band_txt[3]; // 0=A, 1=B, 2=C
|
||||
|
||||
/* Used to validate MYCALL input */
|
||||
regex_t preg;
|
||||
|
||||
// CACHE used to cache users, repeaters,
|
||||
// gateways, IP numbers coming from the irc server
|
||||
|
||||
std::map<std::string, std::string> user2rptr_map, rptr2gwy_map, gwy2ip_map;
|
||||
|
||||
pthread_mutex_t irc_data_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
int open_port(const SPORTIP &pip);
|
||||
void calcPFCS(unsigned char *packet, int len);
|
||||
void GetIRCDataThread();
|
||||
int get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_cs, char *mod, char *ip, char RoU);
|
||||
bool get_yrcall_rptr(char *call, char *arearp_cs, char *zonerp_cs, char *mod, char *ip, char RoU);
|
||||
void PlayFileThread(SECHO &edata);
|
||||
void compute_aprs_hash();
|
||||
void APRSBeaconThread();
|
||||
void ProcessTimeouts();
|
||||
void ProcessSlowData(unsigned char *data, unsigned short sid);
|
||||
bool Flag_is_ok(unsigned char flag);
|
||||
|
||||
// read configuration file
|
||||
bool read_config(char *);
|
||||
bool get_value(const Config &cfg, const std::string path, int &value, int min, int max, int default_value);
|
||||
bool get_value(const Config &cfg, const std::string path, double &value, double min, double max, double default_value);
|
||||
bool get_value(const Config &cfg, const std::string path, bool &value, bool default_value);
|
||||
bool get_value(const Config &cfg, const std::string path, std::string &value, int min, int max, const char *default_value);
|
||||
|
||||
/* aprs functions, borrowed from my retired IRLP node 4201 */
|
||||
void gps_send(short int rptr_idx);
|
||||
bool verify_gps_csum(char *gps_text, char *csum_text);
|
||||
void build_aprs_from_gps_and_send(short int rptr_idx);
|
||||
|
||||
void qrgs_and_maps();
|
||||
|
||||
void set_dest_rptr(int mod_ndx, char *dest_rptr);
|
||||
bool validate_csum(SBANDTXT &bt, bool is_gps);
|
||||
};
|
||||
@ -0,0 +1,166 @@
|
||||
#
|
||||
# Copyright (c) 2019 by Thomas A. Early N7TAE
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#########################################################################################################################
|
||||
# #
|
||||
# QnetGateway Default Parameter Values #
|
||||
# #
|
||||
#########################################################################################################################
|
||||
# What follows need to also be valid bash shell variable definitions, therefore:
|
||||
# No white space on either side of the equal sign (=)
|
||||
# String values should be quoted if they contain any special chars, including white space
|
||||
# If a string value is a simple word, it doesn't need to be quoted
|
||||
# Use the single quote (') for quoting strings, not the double quote(")
|
||||
# Comments can come after a key=value definition, introduced by a pound-sign (#)
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# IRCDDB - You MUST use a legal callsign for logging into any IRC network
|
||||
#
|
||||
ircddb_login_d='' # login callsign for the ircDDB network
|
||||
ircddb_host_d='rr.openquad.net' # other irc networks include group1-irc.ircddb.net
|
||||
ircddb_port_d=9007 # not a good idea to change!
|
||||
ircddb_password_d='1111111111111' # not needed for rr.openquad.net
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# GATEWAY
|
||||
#
|
||||
gateway_regen_header_d=true # regenerate headers from incoming data
|
||||
gateway_send_qrgs_maps_d=true # send frequency, offset, coordinates and url to irc-server
|
||||
gateway_external_ip_d='0.0.0.0' # this means accept a connection from any source
|
||||
gateway_external_port_d=40000 # don't change
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# APRS - for tracking users and also this repeater.
|
||||
#
|
||||
aprs_enable_d=true # send info to APRS
|
||||
aprs_host_d='rotate.aprs.net' # the APRS network server
|
||||
aprs_port_d=14580 # and port
|
||||
aprs_interval_d=40 # keep-alive in minutes
|
||||
aprs_filter_d='' # advanced feature
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# LINK - controls the behaviour of QnetLink (qnlink)
|
||||
#
|
||||
link_admin_d='' # these comma-separated list of users can execute scripts, block dongles, reload the gwys.txt
|
||||
link_link_unlink_d='' # if defined, comma-separated list of users that can link and unlink a repeater
|
||||
#link_no_link_unlink_d='' # if defined, comma-separated list of users that cannot link or unlink, it's a blacklist
|
||||
# if the blacklist is defined (even if it's empty), the link_unlink will not be read
|
||||
link_incoming_ip_d='0.0.0.0' # incoming ip address of qnlink, '0.0.0.0' means accepts any connection.
|
||||
link_ref_port_d=20001 # port for REF linking, don't change
|
||||
link_xrf_port_d=30001 # port for XRF linking, don't change
|
||||
link_dcs_port_d=30051 # port for DCS linking, don't change
|
||||
link_announce_d=true # do link, unlink, etc. announcements
|
||||
link_acknowledge_d=true # send text acknowledgment on key-up
|
||||
link_max_dongles_d=5 # maximum number of linked hot-spots
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# GENERIC MODULE - These will be defined for any and all defined modules
|
||||
#
|
||||
module_x_link_at_start='' # For example, set to 'REF001CL' to link module to 1-charlie when the module starts.
|
||||
module_x_inactivity=0 # if no activity for this many minutes unlink reflector. Zero means no timer.
|
||||
module_x_callsign='' # if you operate in a 'restriction mode', use your personal callsign. Usually leave this empty.
|
||||
module_x_packet_wait=25 # how many milliseconds to wait on packets in a voicestream
|
||||
module_x_acknowledge=false # Do you want an ACK back?
|
||||
module_x_ack_delay=250 # millisecond delay before acknowledgement
|
||||
module_x_frequency=0 # if you specify here, this frequency will show up on the QuadNet USER GATEWAYS webpage
|
||||
module_x_offset=0 # usually the duplex tx-rx offset, but for dvap, it's a frequency tweak
|
||||
module_x_range=0 # the range of this repeater, in meters 1609.344 meters is 1.0 miles
|
||||
module_x_agl=0 # the height above ground level for this repeater's antenna
|
||||
module_x_latitude=0 # you can leave this unspecified for a mobile rig
|
||||
module_x_longitude=0 # like the latitude
|
||||
module_x_desc1='' # maximum of 20 characters, most special symbols are not allowed
|
||||
module_x_desc2='' # just like desc1
|
||||
module_x_url='github.com/n7tae/g2_ircddb' # 80 characters max
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# DVAP - Special parameters when: module.x='dvap'
|
||||
#
|
||||
dvap_power=10 # TX power level: -12 to 10, 10 is maximum power
|
||||
dvap_squelch=-100 # RX Squelch: -128 to -45, -100 to -80 usually works best
|
||||
dvap_serial_number='APXXXXXX' # The serial number of your DVAP is visible through the bottom of the case
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# MMDVM - Special parameters when: module_x='mmdvm'
|
||||
#
|
||||
mmdvm_internal_ip='0.0.0.0' # where MMDVMHost will find the QnetRelay program
|
||||
mmdvm_gateway_port=20010 # which port will QnetRelay be sending on
|
||||
mmdvm_local_port=20011 # which port will MMDVMHost be sending on
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# DVRPTR - Special parameters when: module_x='dvrptr'
|
||||
#
|
||||
# if you don't know what your DVRPTR serial number is, look in the log file after running qndvrptr
|
||||
dvrptr_serial_number='00.00.00.00' # the DVRPTR serial number
|
||||
dvrptr_rf_on='RFON' # put this in YRCALL to disable the channel
|
||||
dvrptr_rf_off='RFOFF' # put this in YRCALL to enable the channel
|
||||
dvrptr_rf_rx_level=80 # see the DVRPTR V1 manual
|
||||
dvrptr_duplex=false # set to true if the module is duplex
|
||||
dvrptr_tx_delay=250 # milliseconds to allow for switching from rx to tx
|
||||
dvrptr_rqst_count=10 # number of 2-sec intervals before the an unresponsive system is killed
|
||||
dvrptr_inverse_rx=true # if you're not hearing anything, try false
|
||||
dvrptr_inverse_tx=true # if you're not being heard, try false
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# LOGGING - Control extra logging - useful for debugging
|
||||
#
|
||||
log_qso_d=false # QSO info goes into the log
|
||||
log_irc_d=false # IRC debug info
|
||||
log_dtmf_d=false # DTMF debug info
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# DPLUS - Control of dplus (trust system) linking to repeaters and REF reflectors
|
||||
#
|
||||
# The following settings do not affect your ability to use dplus linking to XRF or XLX reflectors!
|
||||
# You must be registered on the DPlus system, see www.dstargateway.org, otherwise authorization will fail,
|
||||
# even if QnetLink reports a successful authorization.
|
||||
dplus_ref_login_d='' # for logging into REF reflectors, if undefined or empty, ircddb_login will be used
|
||||
dplus_authorize_d=false # set to true if you want to use the closed-source DPlus reflectors and/or repeaters
|
||||
dplus_use_reflectors_d=true # set to false if you are not going to link to DPlus reflectors
|
||||
dplus_use_repeaters_d=true # set to false if you are not going to link to DPlus repeaters
|
||||
# any gateways in your gwys.txt file will override any reflectors or repeaters that DPlus authorization returns.
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# FILE - where important QnetGateway files and directories are found.
|
||||
#
|
||||
file_status_d='/usr/local/etc/rptr_status' # where repeater status info is passed between services
|
||||
file_dtmf_d='/tmp' # where DTMF is decoded
|
||||
file_echotest_d='/tmp' # echo dat files will end up here
|
||||
file_qnvoicefile_d='/tmp/qnvoice.txt' # where qnvoice will create the play command
|
||||
file_gwys_d='/usr/local/etc/gwys.txt' # where the list of gateways and reflectors (with ports) is.
|
||||
file_announce_dir_d='/usr/local/etc' # where the *.dat files are for the verbal link, unlink, etc. announcements
|
||||
|
||||
##########################################################################################################################
|
||||
#
|
||||
# TIMINGS - for controlling how to deal with timing issues
|
||||
#
|
||||
# most users will not have to override any of these default values
|
||||
timing_timeout_echo_d=1 # seconds before we assume echo has timed out
|
||||
timing_timeout_voicemail_d=1 # seconds before we assume voicemail has timed out
|
||||
timing_timeout_remote_g2_d=2 # after this many seconds with no packets, we assume the tx is closed
|
||||
timing_timeout_local_rptr_d=1 # local repeater timeout, in seconds
|
||||
timing_play_wait_d=1 # seconds before echo or voicemail playback occurs, between 1 and 10
|
||||
timing_play_delay_d=19 # microseconds between frames playback, if echo sounds bad, adjust this up or down 1 or 2 ms
|
||||
Loading…
Reference in new issue