keep running base class

pull/14/head
Tom Early 6 years ago
parent 0f6f764e86
commit be803ca069

@ -26,10 +26,10 @@ SYSDIR=/lib/systemd/system
IRC=ircddb
# use this if you want debugging help in the case of a crash
#CPPFLAGS=-g -ggdb -W -Wall -std=c++11 -Iircddb -DCFG_DIR=\"$(CFGDIR)\" -DBIN_DIR=\"$(BINDIR)\"
#CPPFLAGS=-ggdb -W -std=c++11 -Iircddb -DCFG_DIR=\"$(CFGDIR)\" -DBIN_DIR=\"$(BINDIR)\"
# or, you can choose this for a much smaller executable without debugging help
CPPFLAGS=-W -Wall -std=c++11 -Iircddb -DCFG_DIR=\"$(CFGDIR)\" -DBIN_DIR=\"$(BINDIR)\"
CPPFLAGS=-W -std=c++11 -Iircddb -DCFG_DIR=\"$(CFGDIR)\" -DBIN_DIR=\"$(BINDIR)\"
LDFLAGS=-L/usr/lib -lrt
@ -49,32 +49,32 @@ dvrptr : qndvrptr
itap : qnitap
modem : qnmodem
qngateway : QnetGateway.o aprs.o UnixDgramSocket.o UnixPacketSock.o TCPReaderWriterClient.o QnetConfigure.o QnetDB.o CacheManager.o DStarDecode.o $(IRCOBJS)
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS) -l sqlite3 -pthread
qngateway : QnetGateway.o KRBase.o aprs.o UnixDgramSocket.o UnixPacketSock.o TCPReaderWriterClient.o QnetConfigure.o QnetDB.o CacheManager.o DStarDecode.o $(IRCOBJS)
g++ -o $@ $^ $(LDFLAGS) -l sqlite3 -pthread
qnlink : QnetLink.o DPlusAuthenticator.o TCPReaderWriterClient.o UnixPacketSock.o QnetConfigure.o QnetDB.o
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS) -l sqlite3 -pthread
qnlink : QnetLink.o KRBase.o DPlusAuthenticator.o TCPReaderWriterClient.o UnixPacketSock.o QnetConfigure.o QnetDB.o
g++ -o $@ $^ $(LDFLAGS) -l sqlite3 -pthread
qnrelay : QnetRelay.o UnixPacketSock.o QnetConfigure.o
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
qnrelay : QnetRelay.o KRBase.o UnixPacketSock.o QnetConfigure.o
g++ -o $@ $^ $(LDFLAGS)
qnitap : QnetITAP.o UnixPacketSock.o QnetConfigure.o
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
qnitap : QnetITAP.o KRBase.o UnixPacketSock.o QnetConfigure.o
g++ -o $@ $^ $(LDFLAGS)
qnmodem : QnetModem.o UnixPacketSock.o QnetConfigure.o
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
qnmodem : QnetModem.o KRBase.o UnixPacketSock.o QnetConfigure.o
g++ -o $@ $^ $(LDFLAGS)
qndvap : QnetDVAP.o DVAPDongle.o UnixPacketSock.o QnetConfigure.o DStarDecode.o
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS) -pthread
qndvap : QnetDVAP.o KRBase.o DVAPDongle.o UnixPacketSock.o QnetConfigure.o DStarDecode.o
g++ -o $@ $^ $(LDFLAGS) -pthread
qndvrptr : QnetDVRPTR.o UnixPacketSock.o QnetConfigure.o DStarDecode.o
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
qndvrptr : QnetDVRPTR.o KRBase.o UnixPacketSock.o QnetConfigure.o DStarDecode.o
g++ -o $@ $^ $(LDFLAGS)
qnremote : QnetRemote.o UnixDgramSocket.o QnetConfigure.o
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
g++ -o $@ $^ $(LDFLAGS)
qnvoice : QnetVoice.o QnetConfigure.o
g++ $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
g++ -o $@ $^ $(LDFLAGS)
%.o : %.cpp
g++ $(CPPFLAGS) -MMD -MD -c $< -o $@

@ -51,67 +51,14 @@
#include "QnetConfigure.h"
#include "Timer.h"
#include "DStarDecode.h"
#define DVAP_VERSION "QnetDVAP-523"
#include "QnetDVAP.h"
#define DVAP_VERSION "QnetDVAP-526"
#define CALL_SIZE 8
#define IP_SIZE 15
typedef struct dvap_ack_arg_tag {
char mycall[8];
float ber;
} SDVAP_ACK_ARG;
// assigned module, must be A, B or C
static int assigned_module;
// unix sockets
static std::string togate;
static CUnixPacketClient ToGate;
/* Default configuration data */
static std::string RPTR;
static std::string OWNER;
static char RPTR_MOD;
static std::string MODULE_SERIAL_NUMBER; /* APxxxxxx */
static int MODULE_FREQUENCY; /* between 144000000 and 148000000 */
static int MODULE_POWER; /* between -12 and 10 */
static int MODULE_SQUELCH; /* between -128 and -45 */
static int MODULE_OFFSET; /* between -2000 and 2000 */
static int MODULE_PACKET_WAIT; /* wait 25 ms in reading from local G2 */
static int TIMING_TIMEOUT_REMOTE_G2; /* 1 second */
static int TIMING_PLAY_DELAY;
static int TIMING_PLAY_WAIT;
static bool MODULE_ACKNOWLEDGE;
static double TIMING_TIMEOUT_LOCAL_RPTR;
static bool LOG_DEBUG;
static bool LOG_QSO;
static int inactiveMax = 25;
/* helper data */
static unsigned char SND_TERM_ID;
static char RPTR_and_G[9];
static char RPTR_and_MOD[9];
static int serfd = -1;
static bool busy20000 = false;
std::atomic<bool> keep_running(true);
static unsigned int space = 0;
/* helper routines */
static bool ReadConfig(const char *cfgFile);
static void sig_catch(int signum);
static int open_sock();
static void ReadFromGateway();
static void calcPFCS(unsigned char *packet, unsigned char *pfcs);
static void ReadDVAPThread();
static void RptrAckThread(SDVAP_ACK_ARG *parg);
/*** BER stuff ***/
static CDStarDecode decode;
static CDVAPDongle dongle;
static CRandom Random;
static void calcPFCS(unsigned char *packet, unsigned char *pfcs)
void CQnetDVAP::calcPFCS(unsigned char *packet, unsigned char *pfcs)
{
unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp, short_c;
@ -148,13 +95,8 @@ static void calcPFCS(unsigned char *packet, unsigned char *pfcs)
return;
}
static void sig_catch(int)
{
keep_running = false;
}
/* process configuration file */
static bool ReadConfig(const char *cfgFile)
bool CQnetDVAP::ReadConfig(const char *cfgFile)
{
CQnetConfigure cfg;
@ -250,17 +192,10 @@ static bool ReadConfig(const char *cfgFile)
return false;
}
static int open_sock()
void CQnetDVAP::ReadFromGateway()
{
if (ToGate.Open(togate.c_str()))
return 1;
return 0;
}
static void ReadFromGateway()
{
static unsigned short streamid = 0U;
static int inactive = 0;
unsigned short streamid = 0U;
int inactive = 0;
int len = 0;
fd_set readfd;
struct timeval tv;
@ -507,7 +442,7 @@ static void ReadFromGateway()
return;
}
static void RptrAckThread(SDVAP_ACK_ARG *parg)
void CQnetDVAP::RptrAckThread(SDVAP_ACK_ARG *parg)
{
char mycall[8];
memcpy(mycall, parg->mycall, 8);
@ -520,10 +455,6 @@ static void RptrAckThread(SDVAP_ACK_ARG *parg)
unsigned char silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
std::signal(SIGTERM, sig_catch);
std::signal(SIGINT, sig_catch);
std::signal(SIGHUP, sig_catch);
sleep(TIMING_PLAY_WAIT);
uint16_t sid = Random.NewStreamID();
@ -618,7 +549,7 @@ static void RptrAckThread(SDVAP_ACK_ARG *parg)
return;
}
static void ReadDVAPThread()
void CQnetDVAP::ReadDVAPThread()
{
REPLY_TYPE reply;
SDSVT dsvt;
@ -637,10 +568,6 @@ static void ReadDVAPThread()
int num_dv_frames = 0;
int num_bit_errors = 0;
std::signal(SIGTERM, sig_catch);
std::signal(SIGINT, sig_catch);
std::signal(SIGHUP, sig_catch);
while (keep_running) {
// local RF user went away ?
@ -824,7 +751,7 @@ static void ReadDVAPThread()
if (the_end) {
// local RF user stopped talking
dvap_busy = false;
static SDVAP_ACK_ARG dvap_ack_arg;
SDVAP_ACK_ARG dvap_ack_arg;
dvap_ack_arg.ber = (num_dv_frames==0) ? 0.f : 100.f * (float)num_bit_errors / (float)(num_dv_frames * 24);
if (LOG_QSO)
printf("End of dvap audio, ber=%.02f\n", dvap_ack_arg.ber);
@ -832,7 +759,7 @@ static void ReadDVAPThread()
if (MODULE_ACKNOWLEDGE && !busy20000) {
memcpy(dvap_ack_arg.mycall, mycall, 8);
try {
std::async(std::launch::async, RptrAckThread, &dvap_ack_arg);
std::async(std::launch::async, &CQnetDVAP::RptrAckThread, this, &dvap_ack_arg);
} catch (const std::exception &e) {
printf("Failed to start RptrAckThread(). Exception: %s\n", e.what());
}
@ -856,63 +783,22 @@ static void ReadDVAPThread()
return;
}
int main(int argc, const char **argv)
bool CQnetDVAP::Init(const char *file, const int amod)
{
int rc = -1;
short cnt = 0;
setvbuf(stdout, NULL, _IOLBF, 0);
printf("dvap_rptr VERSION %s\n", DVAP_VERSION);
if (argc != 2) {
fprintf(stderr, "Usage: %s dvap_rptr.cfg\n", argv[0]);
return 1;
}
if ('-' == argv[1][0]) {
printf("\nQnetDVAP Version #%s Copyright (C) 2018-2019 by Thomas A. Early N7TAE\n", DVAP_VERSION);
printf("QnetDVAP comes with ABSOLUTELY NO WARRANTY; see the LICENSE for details.\n");
printf("This is free software, and you are welcome to distribute it\nunder certain conditions that are discussed in the LICENSE file.\n\n");
return 0;
}
assigned_module = amod;
const char *qn = strstr(argv[0], "qndvap");
if (NULL == qn) {
fprintf(stderr, "Error finding 'qndvap' in %s!\n", argv[0]);
return 1;
}
qn += 6;
switch (*qn) {
case NULL:
assigned_module = -1;
break;
case 'a':
assigned_module = 0;
break;
case 'b':
assigned_module = 1;
break;
case 'c':
assigned_module = 2;
break;
default:
fprintf(stderr, "ERROR: '%s' is not a valid module\nassigned module must be a, b or c\n", argv[1]);
return 1;
}
if (ReadConfig(argv[1])) {
printf("Failed to process config file %s\n", argv[2]);
return 1;
if (ReadConfig(file)) {
printf("Failed to process config file %s\n", file);
return true;
}
if (RPTR.length() != 8) {
printf("Bad RPTR value, length must be exactly 8 bytes\n");
return 1;
return true;
}
if ((RPTR_MOD != 'A') && (RPTR_MOD != 'B') && (RPTR_MOD != 'C')) {
printf("Bad RPTR_MOD value, must be one of A or B or C\n");
return 1;
return true;
}
if (RPTR_MOD == 'A')
@ -928,36 +814,35 @@ int main(int argc, const char **argv)
strcpy(RPTR_and_MOD, RPTR.c_str());
RPTR_and_MOD[7] = RPTR_MOD;
CTimer ackpoint;
std::signal(SIGTERM, sig_catch);
std::signal(SIGINT, sig_catch);
std::signal(SIGHUP, sig_catch);
/* open dvp */
if (!dongle.Initialize(MODULE_SERIAL_NUMBER.c_str(), MODULE_FREQUENCY, MODULE_OFFSET, MODULE_POWER, MODULE_SQUELCH))
return 1;
return true;
rc = open_sock();
if (rc != 0) {
if (ToGate.Open(togate.c_str(), this)) {
dongle.Stop();
close(serfd);
return 1;
return true;
}
printf("DVAP opened and initialized!\n");
return false;
}
void CQnetDVAP::Run()
{
CTimer ackpoint;
std::future<void> readthread;
try {
readthread = std::async(std::launch::async, ReadDVAPThread);
readthread = std::async(std::launch::async, &CQnetDVAP::ReadDVAPThread, this);
} catch (const std::exception &e) {
printf("Unable to start ReadDVAPThread(). Exception: %s\n", e.what());
keep_running = false;
}
printf("Started ReadDVAPThread()\n");
int cnt = 0;
while (keep_running) {
if (ackpoint.time() > 2.5) {
rc = dongle.KeepAlive();
int rc = dongle.KeepAlive();
if (rc < 0) {
cnt ++;
if (cnt > 5) {
@ -974,5 +859,55 @@ int main(int argc, const char **argv)
readthread.get();
ToGate.Close();
printf("QnetDVAP exiting\n");
return 0;
return;
}
int main(int argc, char *argv[])
{
setvbuf(stdout, NULL, _IOLBF, 0);
printf("dvap_rptr VERSION %s\n", DVAP_VERSION);
if (argc != 2) {
fprintf(stderr, "Usage: %s dvap_rptr.cfg\n", argv[0]);
return EXIT_FAILURE;
}
if ('-' == argv[1][0]) {
printf("\nQnetDVAP Version #%s Copyright (C) 2018-2020 by Thomas A. Early N7TAE\n", DVAP_VERSION);
printf("QnetDVAP comes with ABSOLUTELY NO WARRANTY; see the LICENSE for details.\n");
printf("This is free software, and you are welcome to distribute it\nunder certain conditions that are discussed in the LICENSE file.\n\n");
return EXIT_SUCCESS;
}
const char *qn = strstr(argv[0], "qndvap");
if (NULL == qn) {
fprintf(stderr, "Error finding 'qndvap' in %s!\n", argv[0]);
return EXIT_FAILURE;
}
qn += 6;
int mod;
switch (*qn) {
case NULL:
mod = -1;
break;
case 'a':
mod = 0;
break;
case 'b':
mod = 1;
break;
case 'c':
mod = 2;
break;
default:
fprintf(stderr, "ERROR: '%s' is not a valid module\nassigned module must be a, b or c\n", argv[1]);
return 1;
}
CQnetDVAP dvap;
if (dvap.Init(argv[1], mod))
return EXIT_FAILURE;
dvap.Run();
return EXIT_SUCCESS;
}

@ -1,8 +1,21 @@
/*
* DVRPTR Repeater for Linux
* Autor: DG1HT DH2YBE KI4LKF N7TAE
* Copyright (C) 2020 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 <stdio.h>
#include <ctype.h>
#include <string.h>
@ -21,104 +34,17 @@
#include <termios.h>
#include <wchar.h>
#include <sys/file.h>
#include <string>
#include "Random.h"
#include "UnixPacketSock.h"
#include "QnetConfigure.h"
#include "QnetTypeDefs.h"
#include "DStarDecode.h"
#include "QnetDVRPTR.h"
#define DVRPTR_VERSION "QnetDVRPTR-523"
#define DVRPTR_VERSION "QnetDVRPTR-526"
#define BAUD B115200
#define CALL_SIZE 8
#define IP_SIZE 15
/*** BER stuff ***/
static int ber_data[3];
static int ber_errs;
static int num_dv_frames;
static int num_bit_errors;
short block = 0;
short old_seq_no = 0;
short seq_no1 = 1;
short seq_no2 = 1;
short seq_no3 = 0;
int fd_ser = -1;
bool busy20000 = false;
static int rqst_count = 6;
static unsigned short streamid = 0x0;
static unsigned char start_Header[8]= {0xD0,0x03,0x00,0x16,0x01,0x00,0x00,0x00};
static unsigned char ptt_off[8]= {0xD0,0x03,0x00,0x1A,0x01,0xff,0x00,0x00};
static bool ReadConfig(const char *cfgFile);
static void readFrom20000();
static bool check_serial();
SDSVT Send_Network_Header;
SDSVT Send_Network_Audio;
static int inactiveMax = 3200;
static unsigned char Send_Modem_Header[52];
static unsigned char writevoice[24];
static unsigned char writevoice1[24];
// Modem INIT
static unsigned char Modem_Init0[6]= {0xD0,0x01,0x00,0x11,0x00,0x00};
static unsigned char Modem_Init1[7]= {0xD0,0x02,0x00,0x10,0x03,0x00,0x00}; // RX TX Enable
static unsigned char Modem_Init2[12]= {0xD0,0x07,0x00,0x14,0xC0,0x04,0x00,0x57,0x53,0x00,0x00,0x00}; // Modem Init
static unsigned char Modem_STATUS[6]= {0xD0,0x01,0x00,0x10,0x00,0x00}; // Status Abfragr
static unsigned char Modem_SERIAL[6]= {0xD0,0x01,0x00,0x12,0x00,0x00};
static int assigned_module;
static std::string togate;
CUnixPacketClient ToGate;
static std::string DVRPTR_SERIAL;
static char DVCALL[CALL_SIZE + 1];
static char RPTR[CALL_SIZE + 1];
static char DVRPTR_MOD = 'B';
static int RF_AUDIO_Level = 10;
static bool DUPLEX = true;
static int ACK_DELAY = 200000;
static int DELAY_BETWEEN = 20000;
static bool RPTR_ACK = false;
static char ENABLE_RF[CALL_SIZE + 1];
static char DISABLE_RF[CALL_SIZE + 1];
static bool IS_ENABLED = true;
static bool ok = false;
static bool RX_Inverse = true;
static bool TX_Inverse = true;
static int TX_DELAY; /* in milliseconds */
static unsigned char SND_TERM_ID = 0x00;
static char DVCALL_and_G[9];
static char DVCALL_and_MOD[9];
static int REMOTE_TIMEOUT = 1; /* 1 second */
static int RQST_COUNT = 6;
static u_int16_t streamid_raw = 0;
static char myRPT2[10]; //RX from HF RPT2
static char myRPT1[10]; //RX from HF RPT1
static char myUR[10];
static char myCall[10];
static char myCall2[10];
char cbuf[250];
static SDSVT recv_buf;
//! 32-bit union.
typedef union {
uint32_t u32;
uint16_t u16[2];
uint8_t u8[4];
} Union32;
static const uint32_t ENCODING_TABLE_24128[] = {
0x000000U, 0x0018EBU, 0x00293EU, 0x0031D5U, 0x004A97U, 0x00527CU, 0x0063A9U, 0x007B42U, 0x008DC6U, 0x00952DU,
0x00A4F8U, 0x00BC13U, 0x00C751U, 0x00DFBAU, 0x00EE6FU, 0x00F684U, 0x010367U, 0x011B8CU, 0x012A59U, 0x0132B2U,
@ -532,8 +458,31 @@ static const uint32_t ENCODING_TABLE_24128[] = {
0xFFAD83U, 0xFFB568U, 0xFFCE2AU, 0xFFD6C1U, 0xFFE714U, 0xFFFFFFU
};
/*
* Compute the syndrome corresponding to the given pattern, i.e., the
* remainder after dividing the pattern (when considering it as the vector
* representation of a polynomial) by the generator polynomial, GENPOL.
* In the program this pattern has several meanings: (1) pattern = infomation
* bits, when constructing the encoding table; (2) pattern = error pattern,
* when constructing the decoding table; and (3) pattern = received vector, to
* obtain its syndrome in decoding.
*/
uint32_t CQnetDVRPTR::get_syndrome_23127(uint32_t pattern)
{
uint32_t aux = GORLAY_X22;
if (pattern >= GORLAY_X11) {
while (pattern & GORLAY_MASK12) {
while ((aux & pattern)==0) aux >>= 1;
pattern ^= (aux / GORLAY_X11) * GORLAY_GENPOL;
}
}
return pattern;
}
static const uint32_t DECODING_TABLE_23127[] = {
unsigned int CQnetDVRPTR::gorlay_decode23127(unsigned int code)
{
const uint32_t DECODING_TABLE_23127[] = {
0x000000U, 0x000001U, 0x000002U, 0x000003U, 0x000004U, 0x000005U, 0x000006U, 0x000007U, 0x000008U, 0x000009U,
0x00000AU, 0x00000BU, 0x00000CU, 0x00000DU, 0x00000EU, 0x024020U, 0x000010U, 0x000011U, 0x000012U, 0x000013U,
0x000014U, 0x000015U, 0x000016U, 0x412000U, 0x000018U, 0x000019U, 0x00001AU, 0x180800U, 0x00001CU, 0x200300U,
@ -741,52 +690,23 @@ static const uint32_t DECODING_TABLE_23127[] = {
0x011001U, 0x011000U, 0x080420U, 0x011002U, 0x100048U, 0x011004U, 0x204200U, 0x028080U
};
#define GORLAY_X22 0x00400000 // vector representation of X^{22}
#define GORLAY_X11 0x00000800 // vector representation of X^{11}
#define GORLAY_MASK12 0xfffff800 // auxiliary vector for testing
#define GORLAY_GENPOL 0x00000c75 // generator polinomial, g(x)
/*
* Compute the syndrome corresponding to the given pattern, i.e., the
* remainder after dividing the pattern (when considering it as the vector
* representation of a polynomial) by the generator polynomial, GENPOL.
* In the program this pattern has several meanings: (1) pattern = infomation
* bits, when constructing the encoding table; (2) pattern = error pattern,
* when constructing the decoding table; and (3) pattern = received vector, to
* obtain its syndrome in decoding.
*/
static uint32_t get_syndrome_23127(uint32_t pattern)
{
uint32_t aux = GORLAY_X22;
if (pattern >= GORLAY_X11) {
while (pattern & GORLAY_MASK12) {
while ((aux & pattern)==0) aux >>= 1;
pattern ^= (aux / GORLAY_X11) * GORLAY_GENPOL;
} // ehliw
} // fi pattern doesn't fit
return pattern;
}
unsigned int gorlay_decode23127(unsigned int code)
{
uint32_t syndrome = get_syndrome_23127(code);
uint32_t error_pattern = DECODING_TABLE_23127[syndrome];
code ^= error_pattern;
return code >> 11;
}
__inline unsigned int gorlay_encode24128(unsigned int data)
unsigned int CQnetDVRPTR::gorlay_encode24128(unsigned int data)
{
return ENCODING_TABLE_24128[data];
}
__inline unsigned int gorlay_decode24128(unsigned int code)
unsigned int CQnetDVRPTR::gorlay_decode24128(unsigned int code)
{
return gorlay_decode23127(code >> 1);
}
static const uint32_t PRNG_TABLE[] = {
const uint32_t PRNG_TABLE[] = {
0x42CC47U, 0x19D6FEU, 0x304729U, 0x6B2CD0U, 0x60BF47U, 0x39650EU, 0x7354F1U, 0xEACF60U, 0x819C9FU, 0xDE25CEU,
0xD7B745U, 0x8CC8B8U, 0x8D592BU, 0xF71257U, 0xBCA084U, 0xA5B329U, 0xEE6AFAU, 0xF7D9A7U, 0xBCC21CU, 0x4712D9U,
0x4F2922U, 0x14FA37U, 0x5D43ECU, 0x564115U, 0x299A92U, 0x20A9EBU, 0x7B707DU, 0x3BE3A4U, 0x20D95BU, 0x6B085AU,
@ -1199,15 +1119,7 @@ static const uint32_t PRNG_TABLE[] = {
0xF9A540U, 0x205ED9U, 0x634EB6U, 0x5A9567U, 0x11A6D8U, 0x0B3F09U
};
typedef unsigned char tambevoicefec[9];
typedef unsigned char tambevoice[6];
#define interleaveambe12(bp) { bp+=12; if (bp>71) bp -= 71; }
static CDStarDecode decode;
static void ambefec_deinterleave(tambevoicefec result, const tambevoicefec voice)
void CQnetDVRPTR::ambefec_deinterleave(tambevoicefec result, const tambevoicefec voice)
{
uint32_t bitpos, bytcnt;
memset(result, 0, sizeof(tambevoicefec)); // init result
@ -1233,7 +1145,7 @@ static void ambefec_deinterleave(tambevoicefec result, const tambevoicefec voice
} // rof
}
static void ambefec_interleave(tambevoicefec result, const tambevoicefec raw_voice)
void CQnetDVRPTR::ambefec_interleave(tambevoicefec result, const tambevoicefec raw_voice)
{
uint32_t bitpos, bytcnt;
bitpos = 0;
@ -1258,7 +1170,7 @@ static void ambefec_interleave(tambevoicefec result, const tambevoicefec raw_voi
} // rof
}
void ambefec_regenerate(tambevoicefec voice)
void CQnetDVRPTR::ambefec_regenerate(tambevoicefec voice)
{
tambevoicefec decoded;
uint32_t data, datb, encoded_dat;
@ -1277,51 +1189,35 @@ void ambefec_regenerate(tambevoicefec voice)
ambefec_interleave(voice, decoded);
}
static unsigned char silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
static unsigned short crc_tabccitt[256] = {
0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
};
const unsigned char silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
static void CleanCall(std::string &callsign) {
void CQnetDVRPTR::CleanCall(std::string &callsign) {
for (auto it=callsign.begin(); it!=callsign.end(); it++)
if (islower(*it))
*it = toupper(*it);
callsign.resize(CALL_SIZE, ' ');
}
static void calcPFCS(unsigned char packet[58])//Netzwerk CRC
const unsigned short crc_tabccitt[256] = {
0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
};
void CQnetDVRPTR::calcPFCS(unsigned char *packet) //Netzwerk CRC
{
unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp, short_c;
@ -1342,7 +1238,7 @@ static void calcPFCS(unsigned char packet[58])//Netzwerk CRC
}
/* process configuration file */
static bool ReadConfig(const char *cfgFile)
bool CQnetDVRPTR::ReadConfig(const char *cfgFile)
{
CQnetConfigure cfg;
@ -1444,7 +1340,7 @@ static bool ReadConfig(const char *cfgFile)
return 0;
}
char *cleanstr (char *Text)
char *CQnetDVRPTR::cleanstr(char *Text)
{
static char cbuf[250];
memset(cbuf, 0U, 250U);
@ -1466,7 +1362,7 @@ char *cleanstr (char *Text)
return (cbuf);
}
int open_port(char *dvrptr_device)
int CQnetDVRPTR::open_port(char *dvrptr_device)
{
int fd_ser = -1;
struct termios terminal;
@ -1491,7 +1387,7 @@ int open_port(char *dvrptr_device)
return fd_ser;
}
int read_port(int *fd_ser,unsigned char* buffera)
int CQnetDVRPTR::read_port(int *fd_ser,unsigned char* buffera)
{
int a;
fd_set rfds;
@ -1510,7 +1406,7 @@ int read_port(int *fd_ser,unsigned char* buffera)
return 0;
}
static void send_ack(char *a_call, float ber)
void CQnetDVRPTR::send_ack(char *a_call, float ber)
{
int i;
@ -1678,7 +1574,7 @@ static void send_ack(char *a_call, float ber)
return;
}
static void readFrom20000()
void CQnetDVRPTR::readFrom20000()
{
int len;
fd_set readfd;
@ -1690,7 +1586,7 @@ static void readFrom20000()
bool written_to_q = false;
int fd = ToGate.GetFD();
while (true) {
while (keep_running) {
written_to_q = false;
tv.tv_sec = 0;
@ -1889,18 +1785,14 @@ static void readFrom20000()
return;
}
bool check_serial()
bool CQnetDVRPTR::check_serial()
{
int i;
char dvrptr_device[FILENAME_MAX + 1];
int InitCount = 1;
InitCount = 1;
bool match = false;
unsigned char puffer[200];
// int bytes2;
short loop_count = 0;
char temp_dvrptr_serial[16];
for (i = 0; i < 32; i++) {
for (int i = 0; i < 32; i++) {
sprintf(dvrptr_device, "/dev/ttyACM%d", i);
if (access(dvrptr_device, R_OK | W_OK) != 0)
continue;
@ -1927,7 +1819,7 @@ bool check_serial()
}
printf("Device %s now locked for exclusive use\n", dvrptr_device);
loop_count = 0;
int loop_count = 0;
while (true) {
if (InitCount == 4 ) {
write(fd_ser, Modem_SERIAL, sizeof (Modem_SERIAL));
@ -1967,6 +1859,7 @@ bool check_serial()
(puffer[2] == 0x00) &&
(puffer[3] == 0x92)) {
puffer[1] = 0x00;
char temp_dvrptr_serial[16];
sprintf(temp_dvrptr_serial, "%02X.%02X.%02X.%02X", puffer[4], puffer[5], puffer[6], puffer[7]);
printf("Device %s has serial=[%s]\n", dvrptr_device, temp_dvrptr_serial);
if (strcmp(temp_dvrptr_serial, DVRPTR_SERIAL.c_str()) == 0) {
@ -1999,24 +1892,11 @@ bool check_serial()
int main(int argc, const char **argv)
{
int bytes2;
int i;
int InitCount = 1;
short seq_no = 0;
unsigned char puffer[200];
char Temp_Text[200];
time_t last_RF_time = 0;
time_t tNow = 0;
time_t time_rqst = 0;
int fw_version;
char fw_string[10];
setvbuf(stdout, NULL, _IOLBF, 0);
printf("dvrptr VERSION %s\n", DVRPTR_VERSION);
if (argc != 2) {
fprintf(stderr, "Usage: %s dvrptr.cfg\n", argv[0]);
fprintf(stderr, "Usage: %s <config_file>\n", argv[0]);
return 1;
}
@ -2034,41 +1914,53 @@ int main(int argc, const char **argv)
}
qn += 8;
int mod;
switch (*qn) {
case NULL:
assigned_module = -1;
mod = -1;
break;
case 'a':
assigned_module = 0;
mod = 0;
break;
case 'b':
assigned_module = 1;
mod = 1;
break;
case 'c':
assigned_module = 2;
mod = 2;
break;
default:
fprintf(stderr, "ERROR: '%s' is not a valid module\nassigned module must be a, b or c\n", argv[1]);
return 1;
}
if (ReadConfig(argv[1])) {
fprintf(stderr, "Failed to process config file %s\n", argv[2]);
return 1;
CQnetDVRPTR dvrptr;
if (dvrptr.Init(argv[1], mod))
return EXIT_FAILURE;
dvrptr.Run();
return EXIT_SUCCESS;
}
bool CQnetDVRPTR::Init(const char *file, int mod)
{
assigned_module = mod;
if (ReadConfig(file)) {
fprintf(stderr, "Failed to process config file %s\n", file);
return true;
}
if (!check_serial()) {
fprintf(stderr, "Cant find any FREE ACMx device that matches\n");
return 1;
return true;
}
if (strlen(DVCALL) != 8) {
fprintf(stderr, "Bad DVCALL value, length must be exactly 8 bytes\n");
return 1;
return true;
}
if ((DVRPTR_MOD != 'A') && (DVRPTR_MOD != 'B') && (DVRPTR_MOD != 'C')) {
fprintf(stderr, "Bad DVCALL_MOD value, must be one of A or B or C\n");
return 1;
return true;
}
if (DVRPTR_MOD == 'A')
@ -2084,8 +1976,8 @@ int main(int argc, const char **argv)
strcpy(DVCALL_and_MOD, DVCALL);
DVCALL_and_MOD[7] = DVRPTR_MOD;
if (ToGate.Open(togate.c_str()))
return 1;
if (ToGate.Open(togate.c_str(), this))
return true;
if (RX_Inverse == true) {
Modem_Init2[6]=0x01;
@ -2097,13 +1989,18 @@ int main(int argc, const char **argv)
else
Modem_Init2[6]=0x02;
}
return false;
}
time(&tNow);
void CQnetDVRPTR::Run()
{
time_t tNow = time(NULL);
CRandom Random;
time(&time_rqst);
time_t time_rqst = tNow;
time_t last_RF_time = tNow;
while (true) {
while (keep_running) {
time(&tNow);
if ((tNow - time_rqst) > 2) {
if (rqst_count < (RQST_COUNT - 2))
@ -2137,7 +2034,11 @@ int main(int argc, const char **argv)
InitCount = 2;
}
bytes2 = read_port(&fd_ser,puffer);
unsigned char puffer[200];
int bytes2 = read_port(&fd_ser, puffer);
char Temp_Text[200];
int seq_no = 0;
bool ok = false;
if (bytes2 > 0) {
switch (bytes2) {
@ -2263,7 +2164,7 @@ int main(int argc, const char **argv)
}
if (ok) {
for (i = 0; i < 8; i++) {
for (int i = 0; i < 8; i++) {
if (!isupper(myCall[i]) &&
!isdigit(myCall[i]) &&
(myCall[i] != ' ')) {
@ -2274,7 +2175,7 @@ int main(int argc, const char **argv)
}
}
for (i = 0; i < 4; i++) {
for (int i = 0; i < 4; i++) {
if (!isupper(myCall2[i]) &&
!isdigit(myCall2[i]) &&
(myCall2[i] != ' ')) {
@ -2283,7 +2184,7 @@ int main(int argc, const char **argv)
}
}
for (i = 0; i < 8; i++) {
for (int i = 0; i < 8; i++) {
if (!isupper(myUR[i]) &&
!isdigit(myUR[i]) &&
(myUR[i] != ' ') &&
@ -2469,7 +2370,8 @@ int main(int argc, const char **argv)
printf("DVRPTR Hardware ver: %.20s\n",puffer+6 );
fw_version = puffer[4] + (puffer[5] << 8);
int fw_version = puffer[4] + (puffer[5] << 8);
char fw_string[10];
fw_string[0] = ((fw_version >> 12) & 0x0f) + '0';
fw_string[1] = '.';
fw_string[2] = ((fw_version >> 8) & 0x0f) + '0';
@ -2554,5 +2456,5 @@ int main(int argc, const char **argv)
ToGate.Close();
printf("dvrptr exiting...\n");
return 0;
return;
}

@ -54,15 +54,7 @@
#define CFG_DIR "/usr/local/etc"
#endif
const std::string GW_VERSION("QnetGateway-523");
static std::atomic<bool> keep_running(true);
/* signal catching function */
static void sigCatch(int)
{
keep_running = false;
}
const std::string GW_VERSION("QnetGateway-526");
int CQnetGateway::FindIndex(const int i) const
{
@ -364,10 +356,10 @@ void CQnetGateway::GetIRCDataThread(const int i)
short threshold = 0;
bool not_announced[3];
for (int i=0; i<3; i++)
not_announced[i] = this->Rptr.mod[i].defined; // announce to all modules that are defined!
not_announced[i] = Rptr.mod[i].defined; // announce to all modules that are defined!
bool is_quadnet = (std::string::npos != ircddb[i].ip.find(".openquad.net"));
bool doFind = true;
while (keep_running) {
while (IsRunning()) {
int rc = ii[i]->getConnectionState();
if (rc > 5 && rc < 8 && is_quadnet) {
char ch = '\0';
@ -422,7 +414,7 @@ void CQnetGateway::GetIRCDataThread(const int i)
threshold = 0;
}
while (((type = ii[i]->getMessageType()) != IDRT_NONE) && keep_running) {
while (((type = ii[i]->getMessageType()) != IDRT_NONE) && IsRunning()) {
switch (type) {
case IDRT_PING: {
std::string rptr, gate, addr;
@ -446,7 +438,7 @@ void CQnetGateway::GetIRCDataThread(const int i)
default:
break;
} // switch (type)
} // while (keep_running)
} // while (IsRunning())
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
printf("GetIRCDataThread[%i] exiting...\n", i);
@ -1841,16 +1833,16 @@ void CQnetGateway::Process()
irc_data_future[i] = std::async(std::launch::async, &CQnetGateway::GetIRCDataThread, this, i);
} catch (const std::exception &e) {
printf("Failed to start GetIRCDataThread[%d]. Exception: %s\n", i, e.what());
keep_running = false;
SetState(false);
}
if (keep_running)
if (IsRunning())
printf("get_irc_data thread[%d] started\n", i);
ii[i]->kickWatchdog(GW_VERSION);
}
}
while (keep_running) {
while (IsRunning()) {
ProcessTimeouts();
// wait 20 ms max
@ -1876,7 +1868,7 @@ void CQnetGateway::Process()
for (int i=0; i<2; i++) {
if (g2_sock[i] < 0)
continue;
if (keep_running && FD_ISSET(g2_sock[i], &fdset)) {
if (IsRunning() && FD_ISSET(g2_sock[i], &fdset)) {
SDSVT dsvt;
socklen_t fromlen = sizeof(struct sockaddr_storage);
ssize_t g2buflen = recvfrom(g2_sock[i], dsvt.title, 56, 0, fromDstar.GetPointer(), &fromlen);
@ -1889,7 +1881,7 @@ void CQnetGateway::Process()
}
// process packets from qnremote
if (keep_running && FD_ISSET(FromRemote.GetFD(), &fdset)) {
if (IsRunning() && FD_ISSET(FromRemote.GetFD(), &fdset)) {
SDSVT dsvt;
const ssize_t len = FromRemote.Read(dsvt.title, 56);
ProcessModem(len, dsvt);
@ -1897,7 +1889,7 @@ void CQnetGateway::Process()
}
// process packets from qnlink
if (keep_running && FD_ISSET(ToLink.GetFD(), &fdset)) {
if (IsRunning() && FD_ISSET(ToLink.GetFD(), &fdset)) {
SDSVT dsvt;
ssize_t g2buflen = ToLink.Read(dsvt.title, 56);
if (16==g2buflen && 0==memcmp(dsvt.title, "LINK", 4)) {
@ -1919,7 +1911,7 @@ void CQnetGateway::Process()
// process packets coming from local repeater module(s)
for (int i=0; i<3; i++) {
if (keep_running && FD_ISSET(ToModem[i].GetFD(), &fdset)) {
if (IsRunning() && FD_ISSET(ToModem[i].GetFD(), &fdset)) {
SDSVT dsvt;
const ssize_t len = ToModem[i].Read(dsvt.title, 56);
if (Rptr.mod[i].defined)
@ -1987,7 +1979,7 @@ void CQnetGateway::APRSBeaconThread()
time_t last_beacon_time = 0;
/* This thread is also saying to the APRS_HOST that we are ALIVE */
while (keep_running) {
while (IsRunning()) {
if (aprs->aprs_sock.GetFD() == -1) {
aprs->Open(OWNER);
if (aprs->aprs_sock.GetFD() == -1)
@ -2038,7 +2030,7 @@ void CQnetGateway::APRSBeaconThread()
printf("APRS Beacon =[%s]\n", snd_buf);
strcat(snd_buf, "\r\n");
while (keep_running) {
while (IsRunning()) {
if (aprs->aprs_sock.GetFD() == -1) {
aprs->Open(OWNER);
if (aprs->aprs_sock.GetFD() == -1)
@ -2289,16 +2281,7 @@ bool CQnetGateway::Init(char *cfgfile)
/* Used to validate MYCALL input */
try {
preg = std::regex("^(([1-9][A-Z])|([A-PR-Z][0-9])|([A-PR-Z][A-Z][0-9]))[0-9A-Z]*[A-Z][ ]*[ A-RT-Z]$", std::regex::extended);
} catch (std::regex_error &e) {
printf("Regular expression error: %s\n", e.what());
return true;
}
std::signal(SIGTERM, sigCatch);
std::signal(SIGINT, sigCatch);
std::signal(SIGHUP, sigCatch);
for (i=0; i<3; i++) {
band_txt[i].streamID = 0;
@ -2339,7 +2322,7 @@ bool CQnetGateway::Init(char *cfgfile)
// Open unix sockets between qngateway and qnremote
printf("Connecting to qnlink at %s\n", tolink.c_str());
if (ToLink.Open(tolink.c_str()))
if (ToLink.Open(tolink.c_str(), this))
return true;
printf("Opening remote port at %s\n", fromremote.c_str());
if (FromRemote.Open(fromremote.c_str()))
@ -2348,7 +2331,7 @@ bool CQnetGateway::Init(char *cfgfile)
for (i=0; i<3; i++) {
if (Rptr.mod[i].defined) { // open unix sockets between qngateway and each defined modem
printf("Connecting to modem at %s\n", tomodem[i].c_str());
if (ToModem[i].Open(tomodem[i].c_str()))
if (ToModem[i].Open(tomodem[i].c_str(), this))
return true;
}
// recording for echotest on local repeater modules
@ -2437,7 +2420,7 @@ bool CQnetGateway::Init(char *cfgfile)
} else
break;
if (!keep_running)
if (!IsRunning())
break;
if (i > 5) {
@ -2764,7 +2747,6 @@ int main(int argc, char **argv)
}
CQnetGateway QnetGateway;
if (QnetGateway.Init(argv[1])) {
keep_running = false; // shutdown any processes that may have been started
return 1;
}
QnetGateway.Process();

@ -28,6 +28,7 @@
#include "SockAddress.h"
#include "QnetDB.h"
#include "DStarDecode.h"
#include "KRBase.h"
#define MAXHOSTNAMELEN 64
#define CALL_SIZE 8
@ -78,7 +79,8 @@ using SBANDTXT = struct band_txt_tag {
int num_bit_errors;
};
class CQnetGateway {
class CQnetGateway : public CKRBase
{
public:
CQnetGateway();
~CQnetGateway();

@ -45,9 +45,7 @@
#include "QnetConfigure.h"
#include "Timer.h"
#define ITAP_VERSION "QnetITAP-523"
std::atomic<bool> CQnetITAP::keep_running(true);
#define ITAP_VERSION "QnetITAP-526"
CQnetITAP::CQnetITAP(int mod)
: assigned_module(mod)
@ -63,11 +61,7 @@ bool CQnetITAP::Initialize(const char *cfgfile)
if (ReadConfig(cfgfile))
return true;
std::signal(SIGTERM, CQnetITAP::SignalCatch);
std::signal(SIGHUP, CQnetITAP::SignalCatch);
std::signal(SIGINT, CQnetITAP::SignalCatch);
if (ToGate.Open(togate.c_str()))
if (ToGate.Open(togate.c_str(), this))
return true;
return false;
@ -614,12 +608,6 @@ bool CQnetITAP::ReadConfig(const char *cfgFile)
return false;
}
void CQnetITAP::SignalCatch(const int signum)
{
if ((signum == SIGTERM) || (signum == SIGINT) || (signum == SIGHUP))
keep_running = false;
}
void CQnetITAP::calcPFCS(const unsigned char *packet, unsigned char *pfcs)
{
unsigned short crc_dstar_ffff = 0xffff;

@ -26,6 +26,7 @@
#include <netinet/in.h>
#include "Random.h" // for streamid generation
#include "UnixPacketSock.h"
#include "KRBase.h"
#define CALL_SIZE 8
#define IP_SIZE 15
@ -97,7 +98,7 @@ private:
SITAP frame;
};
class CQnetITAP
class CQnetITAP : CKRBase
{
public:
// functions
@ -111,8 +112,6 @@ private:
int assigned_module;
// functions
bool Initialize(const char *cfgfile);
static std::atomic<bool> keep_running;
static void SignalCatch(const int signum);
bool ProcessGateway(const int len, const unsigned char *raw);
bool ProcessITAP(const unsigned char *raw);
int OpenITAP();

@ -54,7 +54,7 @@
#include "QnetLink.h"
#include "Utilities.h"
#define LINK_VERSION "QnetLink-523"
#define LINK_VERSION "QnetLink-526"
#ifndef BIN_DIR
#define BIN_DIR "/usr/local/bin"
#endif
@ -62,13 +62,8 @@
#define CFG_DIR "/usr/local/etc"
#endif
std::atomic<bool> CQnetLink::keep_running(true);
CQnetLink::CQnetLink()
{
memset(tracing, 0, 3 * sizeof(struct tracing_tag));
memset(dtmf_mycall, 0, 3 * (CALL_SIZE+1));
memset(old_sid, 0, 6);
}
CQnetLink::~CQnetLink()
@ -182,10 +177,6 @@ void CQnetLink::RptrAckThread(char *arg)
memcpy(RADIO_ID, arg + 1, 21);
unsigned char silence[12] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x16, 0x29, 0xf5 };
std::signal(SIGTERM, sigCatch);
std::signal(SIGINT, sigCatch);
std::signal(SIGHUP, sigCatch);
short int streamid_raw = Random.NewStreamID();
sleep(delay_before);
@ -605,7 +596,7 @@ bool CQnetLink::srv_open()
/* create our gateway unix sockets */
printf("Connecting to qngateway at %s\n", togate.c_str());
if (ToGate.Open(togate.c_str())) {
if (ToGate.Open(togate.c_str(), this)) {
close(dcs_g2_sock);
dcs_g2_sock = -1;
close(xrf_g2_sock);
@ -794,12 +785,6 @@ void CQnetLink::g2link(const char from_mod, const char *call, const char to_mod)
return;
}
/* signal catching function */
void CQnetLink::sigCatch(int)
{
keep_running = false;
}
void CQnetLink::Process()
{
time_t tnow = 0, hb = 0;
@ -3089,10 +3074,6 @@ void CQnetLink::PlayAudioNotifyThread(char *msg)
void CQnetLink::AudioNotifyThread(SECHO &edata)
{
std::signal(SIGTERM, sigCatch);
std::signal(SIGINT, sigCatch);
std::signal(SIGHUP, sigCatch);
char mod = edata.header.hdr.rpt1[7];
if ((mod != 'A') && (mod != 'B') && (mod != 'C')) {
@ -3249,7 +3230,9 @@ bool CQnetLink::Init(const char *cfgfile)
{
tzset();
setvbuf(stdout, (char *)NULL, _IOLBF, 0);
memset(tracing, 0, 3 * sizeof(struct tracing_tag));
memset(dtmf_mycall, 0, 3 * (CALL_SIZE+1));
memset(old_sid, 0, 6);
int rc = regcomp(&preg, "^(([1-9][A-Z])|([A-Z][0-9])|([A-Z][A-Z][0-9]))[0-9A-Z]*[A-Z][ ]*[ A-RT-Z]$", REG_EXTENDED | REG_NOSUB);
if (rc != 0) {
@ -3257,10 +3240,6 @@ bool CQnetLink::Init(const char *cfgfile)
return true;
}
std::signal(SIGTERM, sigCatch);
std::signal(SIGINT, sigCatch);
std::signal(SIGHUP, sigCatch);
for (int i=0; i<3; i++) {
notify_msg[i][0] = '\0';
to_remote_g2[i].cs[0] = '\0';

@ -23,7 +23,6 @@
#include <map>
#include <vector>
#include <set>
#include <atomic>
#include <netinet/in.h>
#include "QnetTypeDefs.h"
@ -33,6 +32,7 @@
#include "SockAddress.h"
#include "Timer.h"
#include "QnetDB.h"
#include "KRBase.h"
/*** version number must be x.xx ***/
#define CALL_SIZE 8
@ -73,7 +73,7 @@ using STRACING = struct tracing_tag {
};
class CQnetLink {
class CQnetLink : CKRBase {
public:
// functions
CQnetLink();
@ -91,7 +91,6 @@ private:
bool ReadConfig(const char *);
bool srv_open();
void srv_close();
static void sigCatch(int signum);
void g2link(const char from_mod, const char *call, const char to_mod);
void send_heartbeat();
bool resolve_rmt(const char *name, const unsigned short port, CSockAddress &addr);
@ -154,8 +153,6 @@ private:
fd_set fdset;
struct timeval tv;
static std::atomic<bool> keep_running;
// Used to validate incoming donglers
regex_t preg;

@ -44,11 +44,9 @@
#include "QnetModem.h"
#include "QnetConfigure.h"
#define MODEM_VERSION "QnetModem-523"
#define MODEM_VERSION "QnetModem-526"
#define MAX_RESPONSES 30
std::atomic<bool> CQnetModem::keep_running(true);
const unsigned char FRAME_START = 0xE0U;
const unsigned char TYPE_VERSION = 0x00U;
@ -218,12 +216,8 @@ bool CQnetModem::Initialize(const char *cfgfile)
if (ReadConfig(cfgfile))
return true;
std::signal(SIGTERM, SignalCatch);
std::signal(SIGINT, SignalCatch);
std::signal(SIGHUP, SignalCatch);
printf("Connecting to qngateway at %s\n", togate.c_str());
if (ToGate.Open(togate.c_str()))
if (ToGate.Open(togate.c_str(), this))
return true;
serfd = OpenModem();
@ -837,11 +831,6 @@ bool CQnetModem::ReadConfig(const char *cfgFile)
return false;
}
void CQnetModem::SignalCatch(const int)
{
keep_running = false;
}
int main(int argc, const char **argv)
{
setbuf(stdout, NULL);

@ -18,7 +18,6 @@
#pragma once
#include <atomic>
#include <cstring>
#include <string>
#include <queue>
@ -28,6 +27,7 @@
#include "UnixPacketSock.h"
#include "QnetTypeDefs.h"
#include "Timer.h"
#include "KRBase.h"
#define CALL_SIZE 8
#define IP_SIZE 15
@ -179,7 +179,7 @@ private:
SMODEM frame;
};
class CQnetModem
class CQnetModem : CKRBase
{
public:
// functions
@ -187,9 +187,6 @@ public:
~CQnetModem();
void Run(const char *cfgfile);
// data
static std::atomic<bool> keep_running;
private:
int assigned_module;
unsigned int dstarSpace;
@ -198,7 +195,6 @@ private:
// functions
bool VoicePacketIsSync(const unsigned char *);
bool Initialize(const char *cfgfile);
static void SignalCatch(const int signum);
void ProcessGateway(const SDSVT &dsvt);
bool ProcessModem(const SMODEM &frame);
int OpenModem();

@ -36,9 +36,7 @@
#include "QnetTypeDefs.h"
#include "QnetConfigure.h"
#define RELAY_VERSION "QnetRelay-523"
std::atomic<bool> CQnetRelay::keep_running(true);
#define RELAY_VERSION "QnetRelay-526"
CQnetRelay::CQnetRelay(int mod) :
assigned_module(mod),
@ -56,10 +54,6 @@ bool CQnetRelay::Initialize(const char *cfgfile)
if (ReadConfig(cfgfile))
return true;
std::signal(SIGTERM, SignalCatch);
std::signal(SIGINT, SignalCatch);
std::signal(SIGHUP, SignalCatch);
return false;
}
@ -116,7 +110,7 @@ bool CQnetRelay::Run(const char *cfgfile)
if (msock < 0)
return true;
if (ToGate.Open(togate.c_str()))
if (ToGate.Open(togate.c_str(), this))
return true;
int fd = ToGate.GetFD();
@ -389,11 +383,6 @@ bool CQnetRelay::ReadConfig(const char *cfgFile)
return false;
}
void CQnetRelay::SignalCatch(const int)
{
keep_running = false;
}
int main(int argc, const char **argv)
{
setbuf(stdout, NULL);

@ -23,11 +23,12 @@
#include <netinet/in.h>
#include "UnixPacketSock.h"
#include "KRBase.h"
#define CALL_SIZE 8
#define IP_SIZE 15
class CQnetRelay
class CQnetRelay : CKRBase
{
public:
// functions
@ -35,13 +36,9 @@ public:
~CQnetRelay();
bool Run(const char *cfgfile);
// data
static std::atomic<bool> keep_running;
private:
// functions
bool Initialize(const char *cfgfile);
static void SignalCatch(const int signum);
bool ProcessGateway(const int len, const unsigned char *raw);
bool ProcessMMDVM(const int len, const unsigned char *raw);
int OpenSocket(const std::string &address, unsigned short port);

@ -26,10 +26,12 @@
#include "UnixPacketSock.h"
CUnixPacket::CUnixPacket() : m_fd(-1) {}
CUnixPacket::CUnixPacket() : m_fd(-1), m_host(NULL) {}
ssize_t CUnixPacket::Read(void *buffer, const ssize_t size)
{
if (0 > m_fd)
return -1;
ssize_t len = read(m_fd, buffer, size);
if (len < 1) {
if (-1 == len) {
@ -47,6 +49,8 @@ ssize_t CUnixPacket::Read(void *buffer, const ssize_t size)
bool CUnixPacket::Write(const void *buffer, const ssize_t size)
{
if (0 > m_fd)
return true;
ssize_t written = write(m_fd, buffer, size);
if (written != size) {
if (-1 == written) {
@ -64,7 +68,7 @@ bool CUnixPacket::Restart()
std::cout << "Restarting '" << m_name << "'... " << std::endl;
Close();
std::string name(m_name);
return Open(name.c_str());
return Open(name.c_str(), m_host);
}
int CUnixPacket::GetFD()
@ -79,7 +83,7 @@ CUnixPacketServer::~CUnixPacketServer()
Close();
}
bool CUnixPacketServer::Open(const char *name)
bool CUnixPacketServer::Open(const char *name, CKRBase *host)
{
m_server = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (m_server < 0) {
@ -110,6 +114,7 @@ bool CUnixPacketServer::Open(const char *name)
return true;
}
m_host = host;
strncpy(m_name, name, 108);
return false;
}
@ -131,7 +136,7 @@ CUnixPacketClient::~CUnixPacketClient()
Close();
}
bool CUnixPacketClient::Open(const char *name)
bool CUnixPacketClient::Open(const char *name, CKRBase *host)
{
m_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
if (m_fd < 0) {
@ -158,8 +163,13 @@ bool CUnixPacketClient::Open(const char *name)
return true;
}
}
if (! m_host->IsRunning()) {
Close();
return true;
}
}
m_host = host;
strncpy(m_name, name, 108);
return false;
}

@ -20,10 +20,12 @@
#include <sys/types.h>
#include "KRBase.h"
class CUnixPacket {
public:
CUnixPacket();
virtual bool Open(const char *name) = 0;
virtual bool Open(const char *name, CKRBase *host) = 0;
virtual void Close() = 0;
bool Write(const void *buffer, const ssize_t size);
ssize_t Read(void *buffer, const ssize_t size);
@ -31,6 +33,7 @@ public:
protected:
bool Restart();
int m_fd;
CKRBase *m_host;
char m_name[108];
};
@ -38,7 +41,7 @@ class CUnixPacketServer : public CUnixPacket {
public:
CUnixPacketServer();
~CUnixPacketServer();
bool Open(const char *name);
bool Open(const char *name, CKRBase *host);
void Close();
protected:
int m_server;
@ -47,6 +50,6 @@ protected:
class CUnixPacketClient : public CUnixPacket {
public:
~CUnixPacketClient();
bool Open(const char *name);
bool Open(const char *name, CKRBase *host);
void Close();
};

Loading…
Cancel
Save

Powered by TurnKey Linux.