qndvap uses QnetConfigure

pull/12/head
Tom Early 7 years ago
parent 1563af8e27
commit 70bdffbf3f

@ -36,7 +36,7 @@ CDVAPDongle::~CDVAPDongle()
{ {
} }
bool CDVAPDongle::Initialize(char *serialno, int frequency, int offset, int power, int squelch) bool CDVAPDongle::Initialize(const char *serialno, const int frequency, const int offset, int const power, const int squelch)
{ {
bool ok = false; bool ok = false;
char device[128]; char device[128];
@ -276,7 +276,7 @@ bool CDVAPDongle::syncit()
return false; return false;
} }
bool CDVAPDongle::get_ser(char *dvp, char *dvap_serial_number) bool CDVAPDongle::get_ser(const char *dvp, const char *dvap_serial_number)
{ {
unsigned cnt = 0; unsigned cnt = 0;
REPLY_TYPE reply; REPLY_TYPE reply;

@ -88,7 +88,7 @@ class CDVAPDongle
public: public:
CDVAPDongle(); CDVAPDongle();
~CDVAPDongle(); ~CDVAPDongle();
bool Initialize(char *serialno, int frequency, int offset, int power, int squelch); bool Initialize(const char *serialno, const int frequency, const int offset, const int power, const int squelch);
REPLY_TYPE GetReply(SDVAP_REGISTER &dr); REPLY_TYPE GetReply(SDVAP_REGISTER &dr);
void Stop(); void Stop();
int KeepAlive(); int KeepAlive();
@ -107,7 +107,7 @@ class CDVAPDongle
int read_from_dvp(void* buf, unsigned int len); int read_from_dvp(void* buf, unsigned int len);
int write_to_dvp(const void* buf, const unsigned int len); int write_to_dvp(const void* buf, const unsigned int len);
bool syncit(); bool syncit();
bool get_ser(char *dvp, char *dvap_serial_number); bool get_ser(const char *dvp, const char *dvap_serial_number);
bool get_name(); bool get_name();
bool get_fw(); bool get_fw();
bool set_modu(); bool set_modu();

@ -45,17 +45,15 @@
#include <thread> #include <thread>
#include <chrono> #include <chrono>
#include <string> #include <string>
#include <libconfig.h++>
using namespace libconfig;
#include "DVAPDongle.h" #include "DVAPDongle.h"
#include "QnetTypeDefs.h" #include "QnetTypeDefs.h"
#include "Random.h" #include "Random.h"
#include "UnixDgramSocket.h" #include "UnixDgramSocket.h"
#include "QnetConfigure.h"
#define VERSION DVAP_VERSION #define VERSION DVAP_VERSION
#define CALL_SIZE 8 #define CALL_SIZE 8
#define RPTR_SIZE 8
#define IP_SIZE 15 #define IP_SIZE 15
typedef struct dvap_ack_arg_tag { typedef struct dvap_ack_arg_tag {
@ -71,10 +69,10 @@ static std::string modem2gate, gate2modem;
static CUnixDgramReader Gate2Modem; static CUnixDgramReader Gate2Modem;
static CUnixDgramWriter Modem2Gate; static CUnixDgramWriter Modem2Gate;
/* Default configuration data */ /* Default configuration data */
static char RPTR[RPTR_SIZE + 1]; static std::string RPTR;
static char OWNER[RPTR_SIZE + 1]; static std::string OWNER;
static char RPTR_MOD; static char RPTR_MOD;
static char DVP_SERIAL[64]; /* APxxxxxx */ static std::string DVP_SERIAL; /* APxxxxxx */
static int DVP_FREQ; /* between 144000000 and 148000000 */ static int DVP_FREQ; /* between 144000000 and 148000000 */
static int DVP_PWR; /* between -12 and 10 */ static int DVP_PWR; /* between -12 and 10 */
static int DVP_SQL; /* between -128 and -45 */ static int DVP_SQL; /* between -128 and -45 */
@ -98,7 +96,7 @@ static unsigned int space = 0;
static unsigned int aseed = 0; static unsigned int aseed = 0;
/* helper routines */ /* helper routines */
static int read_config(const char *cfgFile); static bool read_config(const char *cfgFile);
static void sig_catch(int signum); static void sig_catch(int signum);
static int open_sock(); static int open_sock();
static void readFrom20000(); static void readFrom20000();
@ -157,152 +155,68 @@ static void sig_catch(int signum)
exit(0); exit(0);
} }
static bool get_value(const Config &cfg, const char *path, int &value, int min, int max, int default_value)
{
if (cfg.lookupValue(path, value)) {
if (value < min || value > max)
value = default_value;
} else
value = default_value;
printf("%s = [%d]\n", path, value);
return true;
}
static bool get_value(const Config &cfg, const char *path, double &value, double min, double max, double default_value)
{
if (cfg.lookupValue(path, value)) {
if (value < min || value > max)
value = default_value;
} else
value = default_value;
printf("%s = [%lg]\n", path, value);
return true;
}
static bool get_value(const Config &cfg, const char *path, bool &value, bool default_value)
{
if (! cfg.lookupValue(path, value))
value = default_value;
printf("%s = [%s]\n", path, value ? "true" : "false");
return true;
}
static bool get_value(const Config &cfg, const char *path, std::string &value, int min, int max, const char *default_value)
{
if (cfg.lookupValue(path, value)) {
int l = value.length();
if (l<min || l>max) {
printf("%s is invalid\n", path);
return false;
}
} else
value = default_value;
printf("%s = [%s]\n", path, value.c_str());
return true;
}
/* process configuration file */ /* process configuration file */
static int read_config(const char *cfgFile) static bool read_config(const char *cfgFile)
{ {
Config cfg; CQnetConfigure cfg;
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 { return true;
cfg.readFile(cfgFile);
}
catch(const FileIOException &fioex) {
fprintf(stderr, "Can't read %s\n", cfgFile);
return 1;
}
catch(const ParseException &pex) {
fprintf(stderr, "Parse error at %s:%d - %s\n", pex.getFile(), pex.getLine(), pex.getError());
return 1;
}
std::string value; const std::string estr; // an empty string
std::string dvap_path("module."); std::string type;
std::string dvap_path("module_");
dvap_path.append(1, 'a' + assigned_module); dvap_path.append(1, 'a' + assigned_module);
if (cfg.lookupValue(dvap_path + ".type", value)) { if (cfg.KeyExists(dvap_path)) {
if (value.compare("dvap")) { cfg.GetValue(dvap_path, estr, type, 1, 16);
if (type.compare("dvap")) {
fprintf(stderr, "assigned module '%c' type is not 'dvap'\n", 'a' + assigned_module); fprintf(stderr, "assigned module '%c' type is not 'dvap'\n", 'a' + assigned_module);
return 1; return true;
} }
} else { } else {
fprintf(stderr, "%s is not defined!\n", dvap_path.c_str()); fprintf(stderr, "%s is not defined!\n", dvap_path.c_str());
return 1; return true;
} }
RPTR_MOD = 'A' + assigned_module; RPTR_MOD = 'A' + assigned_module;
char unixsockname[16]; cfg.GetValue(dvap_path+"_gate2modem"+std::to_string(assigned_module), type, gate2modem, 1, FILENAME_MAX);
snprintf(unixsockname, 16, "gate2modem%d", assigned_module); cfg.GetValue(dvap_path+"_modem2gate"+std::to_string(assigned_module), type, modem2gate, 1, FILENAME_MAX);
get_value(cfg, std::string(dvap_path+".fromgateway").c_str(), gate2modem, 1, FILENAME_MAX, unixsockname); if (cfg.KeyExists(dvap_path+"_callsign")) {
snprintf(unixsockname, 16, "modem2gate%d", assigned_module); if (cfg.GetValue(dvap_path+"_callsign", type, RPTR, 3, 6))
get_value(cfg, std::string(dvap_path+".togateway").c_str(), modem2gate, 1, FILENAME_MAX, unixsockname); return true;
if (cfg.lookupValue(std::string(dvap_path+".callsign").c_str(), value) || cfg.lookupValue("ircddb.login", value)) {
int l = value.length();
if (l<3 || l>CALL_SIZE-2) {
printf("Call '%s' is invalid length!\n", value.c_str());
return 1;
} else {
for (int i=0; i<l; i++) {
if (islower(value[i]))
value[i] = toupper(value[i]);
}
value.resize(CALL_SIZE, ' ');
}
strcpy(RPTR, value.c_str());
printf("%s.login = [%s]\n", dvap_path.c_str(), RPTR);
} else {
printf("%s.login is not defined!\n", dvap_path.c_str());
return 1;
} }
if (cfg.GetValue("ircddb_login", estr, OWNER, 3, 6))
if (cfg.lookupValue("ircddb.login", value)) { return true;
int l = value.length(); if (RPTR.empty())
if (l<3 || l>CALL_SIZE-2) { RPTR.assign(OWNER);
printf("Call '%s' is invalid length!\n", value.c_str());
return 1; for (unsigned long i=0; i<RPTR.length(); i++) {
} else { if (islower(RPTR.at(i)))
for (int i=0; i<l; i++) { RPTR.at(i) = toupper(RPTR.at(i));
if (islower(value[i]))
value[i] = toupper(value[i]);
}
value.resize(CALL_SIZE, ' ');
}
strcpy(OWNER, value.c_str());
printf("ircddb.login = [%s]\n", OWNER);
} else {
printf("ircddb.login is not defined!\n");
return 1;
} }
for (unsigned long i=0; i<OWNER.length(); i++) {
if (get_value(cfg, std::string(dvap_path+".serial_number").c_str(), value, 8, 10, "APXXXXXX")) if (islower(OWNER.at(i)))
strcpy(DVP_SERIAL, value.c_str()); OWNER.at(i) = toupper(OWNER.at(i));
else {
printf("%s.serial_number '%s' is invalid!\n", dvap_path.c_str(), value.c_str());
return 1;
} }
RPTR.resize(CALL_SIZE, ' ');
OWNER.resize(CALL_SIZE, ' ');
cfg.GetValue(dvap_path+"_serial_number", type, DVP_SERIAL, 8, 10);
double f; double f;
get_value(cfg, std::string(dvap_path+".frequency").c_str(), f, 100.0, 1400.0, 145.5); cfg.GetValue(dvap_path+"_frequency", type, f, 100.0, 1400.0);
DVP_FREQ = (int)(1.0e6*f); DVP_FREQ = (int)(1.0e6*f);
cfg.GetValue(dvap_path+"_power", type, DVP_PWR, -12, 10);
cfg.GetValue(dvap_path+"_squelch", type, DVP_SQL, -128, -45);
cfg.GetValue(dvap_path+"_offset", type, DVP_OFF, -2000, 2000);
cfg.GetValue(dvap_path+"_packet_wait", type, WAIT_FOR_PACKETS, 6, 100);
cfg.GetValue(dvap_path+"_acknowledge", type, RPTR_ACK);
get_value(cfg, std::string(dvap_path+".power").c_str(), DVP_PWR, -12, 10, 10); dvap_path.assign("timing_");
cfg.GetValue(dvap_path+"timeout_remote_g2", estr, REMOTE_TIMEOUT, 1, 10);
get_value(cfg, std::string(dvap_path+".squelch").c_str(), DVP_SQL, -128, -45, -100); dvap_path.append("play_");
cfg.GetValue(dvap_path+"delay", estr, DELAY_BETWEEN, 9, 25);
get_value(cfg, std::string(dvap_path+".offset").c_str(), DVP_OFF, -2000, 2000, 0.0); cfg.GetValue(dvap_path+"wait", estr, DELAY_BEFORE, 1, 10);
get_value(cfg, std::string(dvap_path+".packet_wait").c_str(), WAIT_FOR_PACKETS, 6, 100, 25);
get_value(cfg, "timing.timeout.remote_g2", REMOTE_TIMEOUT, 1, 10, 2);
get_value(cfg, "timing.play.delay", DELAY_BETWEEN, 9, 25, 19);
get_value(cfg, "timing.play.wait", DELAY_BEFORE, 1, 10, 2);
get_value(cfg, std::string(dvap_path+".acknowledge").c_str(), RPTR_ACK, false);
inactiveMax = (REMOTE_TIMEOUT * 1000) / WAIT_FOR_PACKETS; inactiveMax = (REMOTE_TIMEOUT * 1000) / WAIT_FOR_PACKETS;
printf("Max loops = %d\n", inactiveMax); printf("Max loops = %d\n", inactiveMax);
@ -310,7 +224,7 @@ static int read_config(const char *cfgFile)
/* convert to Microseconds */ /* convert to Microseconds */
WAIT_FOR_PACKETS *= 1000; WAIT_FOR_PACKETS *= 1000;
return 0; return false;
} }
static int open_sock() static int open_sock()
@ -368,17 +282,17 @@ static void readFrom20000()
FD_CLR(fd, &readfd); FD_CLR(fd, &readfd);
break; break;
} }
memcpy(net_buf.vpkt.hdr.r2, OWNER, 7); memcpy(net_buf.vpkt.hdr.r2, OWNER.c_str(), 7);
net_buf.vpkt.hdr.r2[7] = 'G'; net_buf.vpkt.hdr.r2[7] = 'G';
if (memcmp(RPTR, OWNER, RPTR_SIZE) != 0) { if (RPTR.compare(OWNER)) {
// restriction mode // restriction mode
memcpy(net_buf.vpkt.hdr.r1, RPTR, 7); memcpy(net_buf.vpkt.hdr.r1, RPTR.c_str(), 7);
memcpy(net_buf.vpkt.hdr.r2, RPTR, 7); memcpy(net_buf.vpkt.hdr.r2, RPTR.c_str(), 7);
if (memcmp(net_buf.vpkt.hdr.my, OWNER, 7) == 0) { if (memcmp(net_buf.vpkt.hdr.my, OWNER.c_str(), 7) == 0) {
/* this is an ACK back */ /* this is an ACK back */
memcpy(net_buf.vpkt.hdr.my, RPTR, 7); memcpy(net_buf.vpkt.hdr.my, RPTR.c_str(), 7);
} }
} }
@ -614,13 +528,12 @@ int main(int argc, const char **argv)
return 1; return 1;
} }
rc = read_config(argv[2]); if (read_config(argv[2])) {
if (rc != 0) {
printf("Failed to process config file %s\n", argv[2]); printf("Failed to process config file %s\n", argv[2]);
return 1; return 1;
} }
if (strlen(RPTR) != 8) { if (RPTR.length() != 8) {
printf("Bad RPTR value, length must be exactly 8 bytes\n"); printf("Bad RPTR value, length must be exactly 8 bytes\n");
return 1; return 1;
} }
@ -636,10 +549,10 @@ int main(int argc, const char **argv)
else if (RPTR_MOD == 'C') else if (RPTR_MOD == 'C')
SND_TERM_ID = 0x02; SND_TERM_ID = 0x02;
strcpy(RPTR_and_G, RPTR); strcpy(RPTR_and_G, RPTR.c_str());
RPTR_and_G[7] = 'G'; RPTR_and_G[7] = 'G';
strcpy(RPTR_and_MOD, RPTR); strcpy(RPTR_and_MOD, RPTR.c_str());
RPTR_and_MOD[7] = RPTR_MOD; RPTR_and_MOD[7] = RPTR_MOD;
time(&tnow); time(&tnow);
@ -661,7 +574,7 @@ int main(int argc, const char **argv)
} }
/* open dvp */ /* open dvp */
if (!dongle.Initialize(DVP_SERIAL, DVP_FREQ, DVP_OFF, DVP_PWR, DVP_SQL)) if (!dongle.Initialize(DVP_SERIAL.c_str(), DVP_FREQ, DVP_OFF, DVP_PWR, DVP_SQL))
return 1; return 1;
rc = open_sock(); rc = open_sock();
@ -888,9 +801,9 @@ static void ReadDVAPThread()
/* send the S packet if needed */ /* send the S packet if needed */
if ((tnow - S_ctrl_msg_time) > 60) { if ((tnow - S_ctrl_msg_time) > 60) {
spack.counter = C_COUNTER++; spack.counter = C_COUNTER++;
memcpy(spack.spkt.mycall, OWNER, 7); memcpy(spack.spkt.mycall, OWNER.c_str(), 7);
spack.spkt.mycall[7] = 'S'; spack.spkt.mycall[7] = 'S';
memcpy(spack.spkt.rpt, OWNER, 7); memcpy(spack.spkt.rpt, OWNER.c_str(), 7);
spack.spkt.rpt[7] = 'S'; spack.spkt.rpt[7] = 'S';
Modem2Gate.Write(spack.pkt_id, 26); Modem2Gate.Write(spack.pkt_id, 26);
S_ctrl_msg_time = tnow; S_ctrl_msg_time = tnow;
@ -955,7 +868,7 @@ static void ReadDVAPThread()
(net_buf.vpkt.hdr.r2[7] == 'B') || (net_buf.vpkt.hdr.r2[7] == 'B') ||
(net_buf.vpkt.hdr.r2[7] == 'C') || (net_buf.vpkt.hdr.r2[7] == 'C') ||
(net_buf.vpkt.hdr.r2[7] == 'G')) (net_buf.vpkt.hdr.r2[7] == 'G'))
memcpy(net_buf.vpkt.hdr.r2, RPTR, 7); memcpy(net_buf.vpkt.hdr.r2, RPTR.c_str(), 7);
else else
memset(net_buf.vpkt.hdr.r2, ' ', 8); memset(net_buf.vpkt.hdr.r2, ' ', 8);
@ -973,9 +886,9 @@ static void ReadDVAPThread()
that means that mycall, rpt1, rpt2 must be equal to RPTR that means that mycall, rpt1, rpt2 must be equal to RPTR
otherwise we drop the rf data otherwise we drop the rf data
*/ */
if (memcmp(RPTR, OWNER, RPTR_SIZE) != 0) { if (RPTR.compare(OWNER)) {
if (memcmp(net_buf.vpkt.hdr.my, RPTR, RPTR_SIZE) != 0) { if (memcmp(net_buf.vpkt.hdr.my, RPTR.c_str(), CALL_SIZE) != 0) {
printf("mycall=[%.8s], not equal to %s\n", net_buf.vpkt.hdr.my, RPTR); printf("mycall=[%.8s], not equal to %s\n", net_buf.vpkt.hdr.my, RPTR.c_str());
ok = false; ok = false;
} }
} else if (memcmp(net_buf.vpkt.hdr.my, " ", 8) == 0) { } else if (memcmp(net_buf.vpkt.hdr.my, " ", 8) == 0) {
@ -1034,15 +947,15 @@ static void ReadDVAPThread()
/* for icom g2 */ /* for icom g2 */
spack.counter = C_COUNTER++; spack.counter = C_COUNTER++;
memcpy(spack.spkt.mycall, net_buf.vpkt.hdr.my, 8); memcpy(spack.spkt.mycall, net_buf.vpkt.hdr.my, 8);
memcpy(spack.spkt.rpt, OWNER, 7); memcpy(spack.spkt.rpt, OWNER.c_str(), 7);
spack.spkt.rpt[7] = RPTR_MOD; spack.spkt.rpt[7] = RPTR_MOD;
Modem2Gate.Write(spack.pkt_id, 26); Modem2Gate.Write(spack.pkt_id, 26);
// Before we send the data to the local gateway, // Before we send the data to the local gateway,
// set RPT1, RPT2 to be the local gateway // set RPT1, RPT2 to be the local gateway
memcpy(net_buf.vpkt.hdr.r1, OWNER, 7); memcpy(net_buf.vpkt.hdr.r1, OWNER.c_str(), 7);
if (net_buf.vpkt.hdr.r2[7] != ' ') if (net_buf.vpkt.hdr.r2[7] != ' ')
memcpy(net_buf.vpkt.hdr.r2, OWNER, 7); memcpy(net_buf.vpkt.hdr.r2, OWNER.c_str(), 7);
memcpy(net_buf.pkt_id, "DSTR", 4); memcpy(net_buf.pkt_id, "DSTR", 4);
net_buf.counter = C_COUNTER++; net_buf.counter = C_COUNTER++;

@ -102,14 +102,6 @@ module_x_modem2gate1='modem2gate1'
module_x_modem2gate2='modem2gate2' module_x_modem2gate2='modem2gate2'
module_x_url='github.com/n7tae/g2_ircddb' # 80 characters max 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 - Special parameters when: module_x='mmdvm'
@ -118,6 +110,20 @@ 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_gateway_port=20010 # which port will QnetRelay be sending on
mmdvm_local_port=20011 # which port will MMDVMHost be sending on mmdvm_local_port=20011 # which port will MMDVMHost be sending on
##########################################################################################################################
#
# ITAP - Special parameters when: module_x='itap'
#
device='/dev/ttyUSB0' # where the serial-to-USB cable show up
##########################################################################################################################
#
# 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
########################################################################################################################## ##########################################################################################################################
# #
# DVRPTR - Special parameters when: module_x='dvrptr' # DVRPTR - Special parameters when: module_x='dvrptr'

Loading…
Cancel
Save

Powered by TurnKey Linux.