qnlink uses CQnetConfigure

pull/12/head
Tom Early 7 years ago
parent b4dc0cfb2c
commit f1eb7897d6

@ -74,6 +74,11 @@ bool CQnetConfigure::Initialize(const char *file)
return ReadConfigFile(file, cfg); return ReadConfigFile(file, cfg);
} }
bool CQnetConfigure::KeyExists(const std::string &key)
{
return (cfg.end() != cfg.find(key));
}
bool CQnetConfigure::GetDefaultBool(const std::string &path, const std::string &mod, bool &dvalue) bool CQnetConfigure::GetDefaultBool(const std::string &path, const std::string &mod, bool &dvalue)
{ {
std::string value; std::string value;
@ -134,10 +139,8 @@ bool CQnetConfigure::GetDefaultString(const std::string &path, const std::string
auto it = defaults.find(search); auto it = defaults.find(search);
if (defaults.end() == it) { if (defaults.end() == it) {
it = defaults.find(search_again); it = defaults.find(search_again);
if (defaults.end() == it) { if (defaults.end() == it)
fprintf(stderr, "%s has no default value!\n", path.c_str());
return true; return true;
}
} }
dvalue = it->second; dvalue = it->second;
return false; return false;
@ -221,7 +224,7 @@ bool CQnetConfigure::GetValue(const std::string &path, const std::string &mod, i
bool CQnetConfigure::GetValue(const std::string &path, const std::string &mod, std::string &value, int min, int max) bool CQnetConfigure::GetValue(const std::string &path, const std::string &mod, std::string &value, int min, int max)
{ {
auto it = cfg.find(path); auto it = cfg.find(path);
if (cfg.end() != it) { if (cfg.end() == it) {
std::string dvalue; std::string dvalue;
if (GetDefaultString(path, mod, dvalue)) { if (GetDefaultString(path, mod, dvalue)) {
fprintf(stderr, "%s not found in either the cfg file for the defaults file\n", path.c_str()); fprintf(stderr, "%s not found in either the cfg file for the defaults file\n", path.c_str());
@ -232,8 +235,9 @@ bool CQnetConfigure::GetValue(const std::string &path, const std::string &mod, s
printf("Default value %s='%s' is wrong size\n", path.c_str(), value.c_str()); printf("Default value %s='%s' is wrong size\n", path.c_str(), value.c_str());
return true; return true;
} }
value.assign(dvalue);
} else { } else {
value = it->second; value.assign(it->second);
int l = value.length(); int l = value.length();
if (l<min || l>max) { if (l<min || l>max) {
printf("%s='%s' is wrong size\n", path.c_str(), value.c_str()); printf("%s='%s' is wrong size\n", path.c_str(), value.c_str());

@ -31,6 +31,7 @@ public:
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, 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, 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); bool GetValue(const std::string &path, const std::string &mod, std::string &value, const int min, const int max);
bool KeyExists(const std::string &key);
private: private:
std::map<std::string, std::string> defaults; std::map<std::string, std::string> defaults;

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2010 by Scott Lawson KI4LKF * Copyright (C) 2010 by Scott Lawson KI4LKF
* Copyright (C) 2017-2018 by Thomas Early N7TAE * Copyright (C) 2017-2019 by Thomas Early N7TAE
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018 by Thomas Early N7TAE * Copyright (C) 2018,2019 by Thomas Early N7TAE
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

@ -1,7 +1,7 @@
/* /*
* Copyright (C) 2010 by Scott Lawson KI4LKF * Copyright (C) 2010 by Scott Lawson KI4LKF
* Copyright (C) 2015,2018 by Thomas A. Early N7TAE * Copyright (C) 2015,2018,2019 by Thomas A. Early N7TAE
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -51,6 +51,7 @@
#include "versions.h" #include "versions.h"
#include "DPlusAuthenticator.h" #include "DPlusAuthenticator.h"
#include "QnetConfigure.h"
#include "QnetLink.h" #include "QnetLink.h"
using namespace libconfig; using namespace libconfig;
@ -468,256 +469,137 @@ void CQnetLink::calcPFCS(unsigned char *packet, int len)
return; return;
} }
bool CQnetLink::get_value(const Config &cfg, const char *path, int &value, int min, int max, int default_value) void CQnetLink::ToUpper(std::string &s)
{ {
if (cfg.lookupValue(path, value)) { for (auto it=s.begin(); it!=s.end(); it++)
if (value < min || value > max) if (islower(*it))
value = default_value; *it = toupper(*it);
} else
value = default_value;
printf("%s = [%u]\n", path, value);
return true;
} }
bool CQnetLink::get_value(const Config &cfg, const char *path, double &value, double min, double max, double default_value) void CQnetLink::UnpackCallsigns(const std::string &str, std::set<std::string> &set, const std::string &delimiters)
{ {
if (cfg.lookupValue(path, value)) { std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Skip delimiters at beginning.
if (value < min || value > max) std::string::size_type pos = str.find_first_of(delimiters, lastPos); // Find first non-delimiter.
value = default_value;
} else while (std::string::npos != pos || std::string::npos != lastPos) {
value = default_value; std::string element = str.substr(lastPos, pos-lastPos);
printf("%s = [%lg]\n", path, value); if (element.length()>=3 && element.length()<=6) {
return true; ToUpper(element);
} element.resize(CALL_SIZE, ' ');
set.insert(element); // Found a token, add it to the list.
bool CQnetLink::get_value(const Config &cfg, const char *path, bool &value, bool default_value) } else
{ fprintf(stderr, "found bad callsign in list: %s\n", str.c_str());
if (! cfg.lookupValue(path, value)) lastPos = str.find_first_not_of(delimiters, pos); // Skip delimiters.
value = default_value; pos = str.find_first_of(delimiters, lastPos); // Find next non-delimiter.
printf("%s = [%s]\n", path, value ? "true" : "false"); }
return true;
} }
bool CQnetLink::get_value(const Config &cfg, const char *path, std::string &value, int min, int max, const char *default_value) void CQnetLink::PrintCallsigns(const std::string &key, const std::set<std::string> &set)
{ {
if (cfg.lookupValue(path, value)) { printf("%s = [ ", key.c_str());
int l = value.length(); for (auto it=set.begin(); it!=set.end(); it++) {
if (l<min || l>max) { if (it != set.begin())
printf("%s='%s' is has to be between %d and %d characters\n", path, value.c_str(), min, max); printf(", ");
return false; printf("%s", (*it).c_str());
} }
} else printf(" ]");
value = default_value;
printf("%s = [%s]\n", path, value.c_str());
return true;
} }
/* process configuration file */ /* process configuration file */
bool CQnetLink::read_config(const char *cfgFile) bool CQnetLink::read_config(const char *cfgFile)
{ {
unsigned short i; CQnetConfigure cfg;
Config cfg; const std::string estr; // an empty string
printf("Reading file %s\n", cfgFile); printf("Reading file %s\n", cfgFile);
// Read the file. If there is an error, report it and exit. if (cfg.Initialize(cfgFile))
try {
cfg.readFile(cfgFile);
}
catch(const FileIOException &fioex) {
printf("Can't read %s\n", cfgFile);
return true; return true;
}
catch(const ParseException &pex) { std::string key("ircddb_login");
printf("Parse error at %s:%d - %s\n", pex.getFile(), pex.getLine(), pex.getError()); if (cfg.GetValue(key, estr, owner, 3, 6))
return true; return true;
ToUpper(owner);
owner.resize(CALL_SIZE, ' ');
if (cfg.GetValue("dplus_ref_login", estr, login_call, 3, 6))
login_call.assign(owner);
else {
ToUpper(login_call);
login_call.resize(CALL_SIZE, ' ');
} }
std::string value; int modules = 0;
std::string key = "link.ref_login"; key.assign("module_");
if (cfg.lookupValue(key, login_call) || cfg.lookupValue("ircddb.login", login_call)) { for (int i=0; i<3; i++) {
int l = login_call.length(); key.append(1, 'a'+i);
if (l<3 || l>CALL_SIZE-2) { if (cfg.KeyExists(key)) {
printf("Call '%s' is invalid length!\n", login_call.c_str()); std::string modem_type;
return true; cfg.GetValue(key, estr, modem_type, 1, 16);
} else { modules++;
for (i=0; i<l; i++) { cfg.GetValue(key+"_inactivity", modem_type, rf_inactivity_timer[i], 0, 300);
if (islower(login_call[i])) rf_inactivity_timer[i] *= 60;
login_call[i] = toupper(login_call[i]); cfg.GetValue(key+"_link_at_start", modem_type, link_at_startup[i], 8, 8);
}
login_call.resize(CALL_SIZE, ' ');
printf("%s = [\"%s\"]\n", key.c_str(), login_call.c_str());
} }
} else { }
printf("%s is not defined.\n", key.c_str()); if (0 == modules) {
fprintf(stderr, "no rf modules defined!\n");
return true; return true;
} }
key = "link.admin"; std::string csv;
if (cfg.exists(key)) { key.assign("link_admin");
Setting &userlist = cfg.lookup(key); if (cfg.KeyExists(key)) {
if (userlist.isArray()) { cfg.GetValue(key, estr, csv, 0, 10240);
for (i=0; i<userlist.getLength(); i++) { UnpackCallsigns(csv, admin);
value = (const char *)userlist[i]; PrintCallsigns(key, admin);
int l = value.length();
if (l>2 && l<=CALL_SIZE-2) {
for (unsigned int j=0; j<value.length(); j++) {
if (islower(value[j]))
value[j] = toupper(value[j]);
}
value.resize(CALL_SIZE, ' ');
if (admin.end() == admin.find(value)) {
admin.insert(value).second;
} else
printf("aready added '%s' as user.\n", value.c_str());
} else
printf("'%s' is the wrong length!\n", value.c_str());
}
} else {
printf("%s is not an array!\n", key.c_str());
return true;
}
printf("%s = [ ", key.c_str());
for (auto pos=admin.begin(); pos!=admin.end(); pos++) {
if (pos != admin.begin())
printf(", ");
printf("\"%s\"", (*pos).c_str());
}
printf(" ]\n");
} }
key = "link.no_link_unlink"; csv.clear();
if (cfg.exists(key)) { key.assign("link_no_link_unlink");
Setting &linkblacklist = cfg.lookup(key); if (cfg.KeyExists(key)) {
if (linkblacklist.isArray()) { cfg.GetValue(key, estr, csv, 0, 10250);
for (i=0; i<linkblacklist.getLength(); i++) { UnpackCallsigns(csv, link_blacklist);
value = (const char *)linkblacklist[i]; PrintCallsigns(key, link_blacklist);
int l = value.length();
if (l>2 && l<CALL_SIZE-2) {
for (unsigned int j=0; j<value.length(); j++) {
if (islower(value[j]))
value[j] = toupper(value[j]);
}
value.resize(CALL_SIZE, ' ');
if (link_blacklist.end() == link_blacklist.find(value)) {
link_blacklist.insert(value).second;
} else
printf("already added '%s' to link-blacklist.\n", value.c_str());
} else
printf("'%s' is the wrong length!\n", value.c_str());
}
} else {
printf("%s is not an array!\n", key.c_str());
return true;
}
printf("%s = [ ", key.c_str());
for (auto pos=link_blacklist.begin(); pos!=link_blacklist.end(); pos++) {
if (pos != link_blacklist.begin())
printf(", ");
printf("\"%s\"", (*pos).c_str());
}
printf(" ]\n");
} else { } else {
key = "link.link_unlink"; csv.clear();
if (cfg.exists(key)) { key.assign("link_link_unlink");
Setting &unlinklist = cfg.lookup(key); if (cfg.KeyExists(key)) {
if (unlinklist.isArray()) { cfg.GetValue(key, estr, csv, 0, 10240);
for (i=0; i<unlinklist.getLength(); i++) { UnpackCallsigns(csv, link_unlink_user);
value = (const char *)unlinklist[i]; PrintCallsigns(key, link_unlink_user);
int l = value.length();
if (l>2 && l<CALL_SIZE-2) {
for (unsigned int j=0; j<value.length(); j++) {
if (islower(value[j]))
value[j] = toupper(value[j]);
}
value.resize(CALL_SIZE, ' ');
if (link_unlink_user.end() == link_unlink_user.find(value)) {
link_unlink_user.insert(value).second;
} else
printf("already added '%s' to link-unlink.\n", value.c_str());
} else
printf("'%s' is the wrong length!\n", value.c_str());
}
} else {
printf("%s is not an array!\n", key.c_str());
return true;
}
printf("%s = [ ", key.c_str());
for (auto pos=link_unlink_user.begin(); pos!=link_unlink_user.end(); pos++) {
if (pos != link_unlink_user.begin())
printf(", ");
printf("\"%s\"", (*pos).c_str());
}
printf(" ]\n");
}
}
key = "ircddb.login";
if (cfg.lookupValue(key, owner)) {
int l = owner.length();
if (l>2 && l<=CALL_SIZE-2) {
for (i=0; i<l; i++) {
if (islower(owner[i]))
owner[i] = toupper(owner[i]);
}
owner.resize(CALL_SIZE, ' ');
printf("%s = [%s]\n", key.c_str(), owner.c_str());
} else {
printf("%s '%s' is wrong size.\n", key.c_str(), owner.c_str());
return true;
} }
} }
get_value(cfg, "link.ref_port", rmt_ref_port, 10000, 65535, 20001); key.assign("link_");
get_value(cfg, "link.xrf_port", rmt_xrf_port, 10000, 65535, 30001); cfg.GetValue(key+"ref_port", estr, rmt_ref_port, 10000, 65535);
get_value(cfg, "link.dcs_port", rmt_dcs_port, 10000, 65535, 30051); cfg.GetValue(key+"xrf_port", estr, rmt_xrf_port, 10000, 65535);
cfg.GetValue(key+"dcs_port", estr, rmt_dcs_port, 10000, 65535);
get_value(cfg, "gateway.tolink", gate2link, 1, FILENAME_MAX, "gate2link"); cfg.GetValue(key+"acknowledge", estr, bool_rptr_ack);
get_value(cfg, "gateway.fromlink", link2gate, 1, FILENAME_MAX, "link2gate"); cfg.GetValue(key+"announce", estr, announce);
int maxdongle;
get_value(cfg, "log.qso", qso_details, true); cfg.GetValue(key+"max_dongles", estr, maxdongle, 0, 10);
saved_max_dongles = max_dongles = (unsigned int)maxdongle;
if (! get_value(cfg, "file.gwys", gwys, 2, FILENAME_MAX, "/usr/local/etc/gwys.txt"))
return true;
if (! get_value(cfg, "file.status", status_file, 2, FILENAME_MAX, "/usr/local/etc/RPTR_STATUS.txt"))
return true;
get_value(cfg, "file.qnvoicefile", qnvoice_file, 2, FILENAME_MAX, "/tmp/qnvoice.txt");
get_value(cfg, "timing.play.delay", delay_between, 9, 25, 19);
get_value(cfg, "link.acknowledge", bool_rptr_ack, true);
get_value(cfg, "link.announce", announce, true);
if (! get_value(cfg, "file.announce_dir", announce_dir, 2, FILENAME_MAX, "/usr/local/etc"))
return true;
get_value(cfg, "timing.play.wait", delay_before, 1, 10, 1); key.assign("gateway_");
cfg.GetValue(key+"tolink", estr, gate2link, 1, FILENAME_MAX);
cfg.GetValue(key+"fromlink", estr, link2gate, 1, FILENAME_MAX);
memset(link_at_startup, 0, CALL_SIZE+1); cfg.GetValue("log.qso", estr, qso_details);
if (get_value(cfg, "link.link_at_start", value, 5, CALL_SIZE, "NONE")) {
if (strcasecmp(value.c_str(), "none"))
strcpy(link_at_startup, value.c_str());
} else
return true;
int maxdongle; key.assign("file_");
get_value(cfg, "link.max_dongles", maxdongle, 0, 10, 5); cfg.GetValue(key+"gwys", estr, gwys, 2, FILENAME_MAX);
saved_max_dongles = max_dongles = (unsigned int)maxdongle; cfg.GetValue(key+"status", estr, status_file, 2, FILENAME_MAX);
cfg.GetValue(key+"qnvoicefile", estr, qnvoice_file, 2, FILENAME_MAX);
cfg.GetValue(key+"announce_dir", estr, announce_dir, 2, FILENAME_MAX);
for (i=0; i<3; i++) { key.assign("timing_play_");
int timer; cfg.GetValue(key+"wait", estr, delay_before, 1, 10);
key = "timing.inactivity."; cfg.GetValue(key+"delay", estr, delay_between, 9, 25);
key += ('a' + i);
get_value(cfg, key.c_str(), timer, 0, 300, 0);
timer *= 60;
rf_inactivity_timer[i] = timer;
}
get_value(cfg, "dplus.authorize", dplus_authorize, false); key.assign("dplus_");
get_value(cfg, "dplus.use_reflectors", dplus_reflectors, true); cfg.GetValue(key+"authorize", estr, dplus_authorize);
get_value(cfg, "dplus.use_repeaters", dplus_repeaters, true); cfg.GetValue(key+"use_reflectors", estr, dplus_reflectors);
cfg.GetValue(key+"use_repeaters", estr, dplus_repeaters);
return false; return false;
} }
@ -836,7 +718,7 @@ void CQnetLink::srv_close()
} }
/* find the repeater IP by callsign and link to it */ /* find the repeater IP by callsign and link to it */
void CQnetLink::g2link(char from_mod, char *call, char to_mod) void CQnetLink::g2link(const char from_mod, const char *call, const char to_mod)
{ {
short i,j, counter; short i,j, counter;
@ -1069,17 +951,17 @@ void CQnetLink::Process()
printf("xrf=%d, dcs=%d, ref=%d, gateway=%d, MAX+1=%d\n", xrf_g2_sock, dcs_g2_sock, ref_g2_sock, Gate2Link.GetFD(), max_nfds + 1); printf("xrf=%d, dcs=%d, ref=%d, gateway=%d, MAX+1=%d\n", xrf_g2_sock, dcs_g2_sock, ref_g2_sock, Gate2Link.GetFD(), max_nfds + 1);
if (strlen(link_at_startup) >= 8) { // initialize all request links
if ((link_at_startup[0] == 'A') || (link_at_startup[0] == 'B') || (link_at_startup[0] == 'C')) { bool first = true;
char temp_repeater[CALL_SIZE + 1]; for (int i=0; i<3; i++) {
memset(temp_repeater, ' ', CALL_SIZE); if (8 == link_at_startup[i].length()) {
memcpy(temp_repeater, link_at_startup + 1, 6); if (first) {
temp_repeater[CALL_SIZE] = '\0'; printf("sleep for 15 sec before link at startup\n");
printf("sleep for 15 before link at startup\n"); sleep(15);
sleep(15); first = false;
g2link(link_at_startup[0], temp_repeater, link_at_startup[7]); }
g2link('A'+i, link_at_startup[i].substr(0, 6).c_str(), link_at_startup[i].at(7));
} }
memset(link_at_startup, '\0', sizeof(link_at_startup));
} }
while (keep_running) { while (keep_running) {
@ -2944,12 +2826,19 @@ void CQnetLink::Process()
sprintf(notify_msg[i], "%c_id.dat_%s_NOT_LINKED", dstr.vpkt.hdr.r1[7], owner.c_str()); sprintf(notify_msg[i], "%c_id.dat_%s_NOT_LINKED", dstr.vpkt.hdr.r1[7], owner.c_str());
} }
} }
else if (0==memcmp(dstr.vpkt.hdr.ur, " ", 6) && dstr.vpkt.hdr.ur[7]=='X' && admin.find(call)!=admin.end()) { // only ADMIN can execute scripts else if (0==memcmp(dstr.vpkt.hdr.ur, " ", 6) && dstr.vpkt.hdr.ur[7]=='X') { // execute a script
if (dstr.vpkt.hdr.ur[6] != ' ') { if (dstr.vpkt.hdr.ur[6] != ' ') { // there has to be a char here
memset(system_cmd, '\0', sizeof(system_cmd)); bool user_ok = true;
snprintf(system_cmd, FILENAME_MAX, "%s/exec_%c.sh %s %c &", announce_dir.c_str(), dstr.vpkt.hdr.ur[6], call, dstr.vpkt.hdr.r1[7]); if (admin.size()>0 && admin.end()==admin.find(call)) { // only admins (if defined) can execute scripts
printf("Executing %s\n", system_cmd); printf("%s not found in the link_admin list!\n", call);
system(system_cmd); user_ok = false;
}
if (user_ok) {
memset(system_cmd, '\0', sizeof(system_cmd));
snprintf(system_cmd, FILENAME_MAX, "%s/exec_%c.sh %s %c &", announce_dir.c_str(), dstr.vpkt.hdr.ur[6], call, dstr.vpkt.hdr.r1[7]);
printf("Executing %s\n", system_cmd);
system(system_cmd);
}
} }
} }
else if (0==memcmp(dstr.vpkt.hdr.ur, " ", 6) && dstr.vpkt.hdr.ur[6]=='D' && admin.find(call)!=admin.end()) { // only ADMIN can block dongle users else if (0==memcmp(dstr.vpkt.hdr.ur, " ", 6) && dstr.vpkt.hdr.ur[6]=='D' && admin.find(call)!=admin.end()) { // only ADMIN can block dongle users

@ -1,7 +1,7 @@
#pragma once #pragma once
/* /*
* Copyright (C) 2018 by Thomas A. Early N7TAE * Copyright (C) 2018-2019 by Thomas A. Early N7TAE
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -25,15 +25,12 @@
#include <set> #include <set>
#include <atomic> #include <atomic>
#include <netinet/in.h> #include <netinet/in.h>
#include <libconfig.h++>
#include "versions.h" #include "versions.h"
#include "QnetTypeDefs.h" #include "QnetTypeDefs.h"
#include "SEcho.h" #include "SEcho.h"
#include "Random.h" #include "Random.h"
#include "UnixDgramSocket.h" #include "UnixDgramSocket.h"
using namespace libconfig;
/*** version number must be x.xx ***/ /*** version number must be x.xx ***/
#define VERSION LINK_VERSION #define VERSION LINK_VERSION
#define CALL_SIZE 8 #define CALL_SIZE 8
@ -68,13 +65,16 @@ public:
void Shutdown(); void Shutdown();
private: private:
// functions // functions
void ToUpper(std::string &s);
void UnpackCallsigns(const std::string &str, std::set<std::string> &set, const std::string &delimiters = ",");
void PrintCallsigns(const std::string &key, const std::set<std::string> &set);
bool load_gwys(const std::string &filename); bool load_gwys(const std::string &filename);
void calcPFCS(unsigned char *packet, int len); void calcPFCS(unsigned char *packet, int len);
bool read_config(const char *); bool read_config(const char *);
bool srv_open(); bool srv_open();
void srv_close(); void srv_close();
static void sigCatch(int signum); static void sigCatch(int signum);
void g2link(char from_mod, char *call, char to_mod); void g2link(const char from_mod, const char *call, const char to_mod);
void print_status_file(); void print_status_file();
void send_heartbeat(); void send_heartbeat();
bool resolve_rmt(char *name, int type, struct sockaddr_in *addr); bool resolve_rmt(char *name, int type, struct sockaddr_in *addr);
@ -82,19 +82,15 @@ private:
void PlayAudioNotifyThread(char *msg); void PlayAudioNotifyThread(char *msg);
void AudioNotifyThread(SECHO &edata); void AudioNotifyThread(SECHO &edata);
void RptrAckThread(char *arg); void RptrAckThread(char *arg);
bool get_value(const Config &cfg, const char *path, int &value, int min, int max, int default_value);
bool get_value(const Config &cfg, const char *path, double &value, double min, double max, double default_value);
bool get_value(const Config &cfg, const char *path, bool &value, bool default_value);
bool get_value(const Config &cfg, const char *path, std::string &value, int min, int max, const char *default_value);
/* configuration data */ /* configuration data */
std::string login_call, owner, to_g2_external_ip, my_g2_link_ip, gwys, status_file, qnvoice_file, announce_dir; std::string login_call, owner, to_g2_external_ip, my_g2_link_ip, gwys, status_file, qnvoice_file, announce_dir;
bool only_admin_login, only_link_unlink, qso_details, bool_rptr_ack, announce; bool only_admin_login, only_link_unlink, qso_details, bool_rptr_ack, announce;
bool dplus_authorize, dplus_reflectors, dplus_repeaters; bool dplus_authorize, dplus_reflectors, dplus_repeaters;
int rmt_xrf_port, rmt_ref_port, rmt_dcs_port, my_g2_link_port, to_g2_external_port, delay_between, delay_before; int rmt_xrf_port, rmt_ref_port, rmt_dcs_port, my_g2_link_port, to_g2_external_port, delay_between, delay_before;
char link_at_startup[CALL_SIZE+1]; std::string link_at_startup[3];
unsigned int max_dongles, saved_max_dongles; unsigned int max_dongles, saved_max_dongles;
long rf_inactivity_timer[3]; int rf_inactivity_timer[3];
const unsigned char REF_ACK[3] = { 3, 96, 0 }; const unsigned char REF_ACK[3] = { 3, 96, 0 };
// the Key in this inbound_list map is the unique IP address of the remote // the Key in this inbound_list map is the unique IP address of the remote

@ -25,12 +25,15 @@
# If a string value is a simple word, it doesn't need to be quoted # 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(") # Use the single quote (') for quoting strings, not the double quote(")
# Comments can come after a key=value definition, introduced by a pound-sign (#) # Comments can come after a key=value definition, introduced by a pound-sign (#)
#
# if a definition is commented out, it means that key has no default value. And it is
# include here just as a reference.
########################################################################################################################## ##########################################################################################################################
# #
# IRCDDB - You MUST use a legal callsign for logging into any IRC network # IRCDDB - You MUST use a legal callsign for logging into any IRC network
# #
ircddb_login_d='' # login callsign for the ircDDB 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_host_d='rr.openquad.net' # other irc networks include group1-irc.ircddb.net
ircddb_port_d=9007 # not a good idea to change! ircddb_port_d=9007 # not a good idea to change!
ircddb_password_d='1111111111111' # not needed for rr.openquad.net ircddb_password_d='1111111111111' # not needed for rr.openquad.net
@ -61,8 +64,8 @@ aprs_filter_d='' # advanced feature
# #
# LINK - controls the behaviour of QnetLink (qnlink) # 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_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_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 #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 # 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_incoming_ip_d='0.0.0.0' # incoming ip address of qnlink, '0.0.0.0' means accepts any connection.
@ -77,7 +80,7 @@ link_max_dongles_d=5 # maximum number of linked hot-spots
# #
# GENERIC MODULE - These will be defined for any and all defined modules # 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_link_at_start='' # For example, set to 'REF001 C' 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_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_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_packet_wait=25 # how many milliseconds to wait on packets in a voicestream
@ -145,7 +148,7 @@ log_dtmf_d=false # DTMF debug info
# The following settings do not affect your ability to use dplus linking to XRF or XLX 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, # You must be registered on the DPlus system, see www.dstargateway.org, otherwise authorization will fail,
# even if QnetLink reports a successful authorization. # 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_ref_login_d='' # for logging into REF reflectors, if 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_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_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 dplus_use_repeaters_d=true # set to false if you are not going to link to DPlus repeaters

Loading…
Cancel
Save

Powered by TurnKey Linux.