Fix aprs and improve almost everything

master
Tom Early 4 days ago
parent 39468e999e
commit 76bf523f97

@ -310,7 +310,7 @@ the "copyright" line and a pointer to where the full notice is found.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
If the program is interactive, make it output a int16_t notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author

@ -47,7 +47,7 @@ CDPlusAuthenticator::~CDPlusAuthenticator()
int CDPlusAuthenticator::Process(CQnetDB &db, const bool reflectors, const bool repeaters)
// return true if everything went okay
{
int result = client.Open(m_address, AF_UNSPEC, "20001");
int result = client.Open(m_address, AF_UNSPEC, "20001", false);
if (result)
{
fprintf(stderr, "DPlus Authorization failed: %s\n", gai_strerror(result));
@ -58,7 +58,7 @@ int CDPlusAuthenticator::Process(CQnetDB &db, const bool reflectors, const bool
int CDPlusAuthenticator::authenticate(CQnetDB &db, const bool reflectors, const bool repeaters)
{
unsigned char buffer[4096U];
uint8_t buffer[4096U];
::memset(buffer, ' ', 56U);
buffer[0U] = 0x38U;

@ -219,7 +219,7 @@ int CDStarDecode::golay2412(int data, int *decoded)
return errs;
}
int CDStarDecode::Decode(const unsigned char *d, int data[3])
int CDStarDecode::Decode(const uint8_t *d, int data[3])
{
int bits[3];
int i;

@ -20,12 +20,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <cstdint>
class CDStarDecode
{
public:
CDStarDecode();
~CDStarDecode() {}
int Decode(const unsigned char *d, int data[3]);
int Decode(const uint8_t *d, int data[3]);
private:
// functions

@ -243,10 +243,10 @@ REPLY_TYPE CDVAPDongle::GetReply(SDVAP_REGISTER &dr)
bool CDVAPDongle::syncit()
{
unsigned char data[7];
uint8_t data[7];
struct timeval tv;
fd_set fds;
short cnt = 0;
int16_t cnt = 0;
printf("Starting syncing dvap\n");
memset(data, 0x00, 7);
@ -271,7 +271,7 @@ bool CDVAPDongle::syncit()
}
else
{
unsigned char c;
uint8_t c;
n = read_from_dvp(&c, 1);
if (n > 0)
{

@ -73,18 +73,18 @@ using SDVAP_REGISTER = struct dvp_register_tag
{
struct
{
unsigned char flag[3];
unsigned char rpt2[8];
unsigned char rpt1[8];
unsigned char urcall[8];
unsigned char mycall[8];
unsigned char sfx[4];
unsigned char pfcs[2];
uint8_t flag[3];
uint8_t rpt2[8];
uint8_t rpt1[8];
uint8_t urcall[8];
uint8_t mycall[8];
uint8_t sfx[4];
uint8_t pfcs[2];
} hdr;
struct
{
unsigned char voice;
unsigned char sdata;
uint8_t voice;
uint8_t sdata;
} vad;
};
} frame;

@ -35,7 +35,7 @@ public:
port = from.port;
}
CHost(const std::string n, const std::string a, unsigned short p)
CHost(const std::string n, const std::string a, uint16_t p)
{
name.assign(n);
addr.assign(a);
@ -51,7 +51,7 @@ public:
}
std::string name, addr;
unsigned short port;
uint16_t port;
};
template <class T> class CTQueue

@ -119,9 +119,9 @@ const char *CLocation::APRS(std::string &call, const char *station)
double lon = modf(fabs(longitude), &lonmin);
lonmin *= 60.0;
if (last == ' ')
snprintf(aprs, 128, "%s>APDPRS,DSTAR*,qAR,%s:!%02d%04.2f%c/%03d%04.2f%c/A\r\n", call.c_str(), station, int(lat), latmin, (latitude>=0) ? 'N' : 'S', int(lon), lonmin, (longitude>=0) ? 'E' : 'W');
snprintf(aprs, 128, "%s>APDPRS,DSTAR*,qAR,%s:!%02d%04.2f%c/%03d%04.2f%c/A", call.c_str(), station, int(lat), latmin, (latitude>=0) ? 'N' : 'S', int(lon), lonmin, (longitude>=0) ? 'E' : 'W');
else
snprintf(aprs, 128, "%s-%c>APDPRS,DSTAR*,qAR,%s:!%02d%04.2f%c/%03d%04.2f%c/A\r\n", call.c_str(), last, station, int(lat), latmin, (latitude>=0) ? 'N' : 'S', int(lon), lonmin, (longitude>=0) ? 'E' : 'W');
snprintf(aprs, 128, "%s-%c>APDPRS,DSTAR*,qAR,%s:!%02d%04.2f%c/%03d%04.2f%c/A", call.c_str(), last, station, int(lat), latmin, (latitude>=0) ? 'N' : 'S', int(lon), lonmin, (longitude>=0) ? 'E' : 'W');
return aprs;
}

@ -29,10 +29,10 @@ SYSDIR=/etc/systemd/system
IRC=ircddb
# use this if you want debugging help in the case of a crash
#CPPFLAGS=-ggdb -W -std=c++11 -Iircddb -DCFG_DIR=\"$(CFGDIR)\" -DBIN_DIR=\"$(BINDIR)\"
#CPPFLAGS=-ggdb -W -std=c++17 -Iircddb -DCFG_DIR=\"$(CFGDIR)\" -DBIN_DIR=\"$(BINDIR)\"
# or, you can choose this for a much smaller executable without debugging help
CPPFLAGS=-W -std=c++11 -Iircddb -DCFG_DIR=\"$(CFGDIR)\" -DBIN_DIR=\"$(BINDIR)\"
CPPFLAGS=-W -std=c++17 -Iircddb -DCFG_DIR=\"$(CFGDIR)\" -DBIN_DIR=\"$(BINDIR)\"
LDFLAGS=-L/usr/lib -lrt

@ -190,7 +190,7 @@ bool CQnetDB::UpdateLS(const char *address, const char from_mod, const char *to_
return false;
}
bool CQnetDB::UpdateGW(const char *name, const char *address, unsigned short port)
bool CQnetDB::UpdateGW(const char *name, const char *address, uint16_t port)
{
if (NULL == db)
return true;
@ -287,7 +287,7 @@ bool CQnetDB::FindLS(const char mod, std::list<CLink> &linklist)
return false;
}
bool CQnetDB::FindGW(const char *name, std::string &address, unsigned short &port)
bool CQnetDB::FindGW(const char *name, std::string &address, uint16_t &port)
// returns true if NOT found
{
if (NULL == db)
@ -308,7 +308,7 @@ bool CQnetDB::FindGW(const char *name, std::string &address, unsigned short &por
if (SQLITE_ROW == sqlite3_step(stmt))
{
address.assign((const char *)sqlite3_column_text(stmt, 0));
port = (unsigned short)(sqlite3_column_int(stmt, 1));
port = (uint16_t)(sqlite3_column_int(stmt, 1));
sqlite3_finalize(stmt);
return false;
}

@ -27,7 +27,7 @@
class CLink
{
public:
CLink(const std::string &call, const unsigned char *addr, time_t ltime) : callsign(call), address((const char *)addr), linked_time(ltime) {}
CLink(const std::string &call, const uint8_t *addr, time_t ltime) : callsign(call), address((const char *)addr), linked_time(ltime) {}
CLink(const CLink &from)
{
@ -63,7 +63,7 @@ public:
bool UpdateGW(CHostQueue &);
bool DeleteLS(const char *address);
bool FindLS(const char mod, std::list<CLink> &linklist);
bool FindGW(const char *name, std::string &address, unsigned short &port);
bool FindGW(const char *name, std::string &address, uint16_t &port);
bool FindGW(const char *name);
void ClearLH();
void ClearLS();
@ -72,6 +72,6 @@ public:
private:
bool Init();
bool UpdateGW(const char *name, const char *address, unsigned short port);
bool UpdateGW(const char *name, const char *address, uint16_t port);
sqlite3 *db;
};

@ -53,11 +53,11 @@
#define CALL_SIZE 8
#define IP_SIZE 15
void CQnetDVAP::calcPFCS(unsigned char *packet, unsigned char *pfcs)
void CQnetDVAP::calcPFCS(uint8_t *packet, uint8_t *pfcs)
{
unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp, short_c;
unsigned short crc_tabccitt[256] =
uint16_t crc_dstar_ffff = 0xffff;
uint16_t tmp, short_c;
uint16_t 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,
@ -79,15 +79,15 @@ void CQnetDVAP::calcPFCS(unsigned char *packet, unsigned char *pfcs)
for (int i = 0; i < 39 ; i++)
{
short_c = 0x00ff & (unsigned short)packet[i];
short_c = 0x00ff & (uint16_t)packet[i];
tmp = (crc_dstar_ffff & 0x00ff) ^ short_c;
crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp];
}
crc_dstar_ffff = ~crc_dstar_ffff;
tmp = crc_dstar_ffff;
pfcs[0] = (unsigned char)(crc_dstar_ffff & 0xff);
pfcs[1] = (unsigned char)((tmp >> 8) & 0xff);
pfcs[0] = (uint8_t)(crc_dstar_ffff & 0xff);
pfcs[1] = (uint8_t)((tmp >> 8) & 0xff);
return;
}
@ -209,20 +209,20 @@ bool CQnetDVAP::ReadConfig(const std::string &cfgFile)
void CQnetDVAP::ReadFromGateway()
{
unsigned short streamid = 0U;
uint16_t streamid = 0U;
int inactive = 0;
int len = 0;
fd_set readfd;
struct timeval tv;
short seq_no = 0;
unsigned char sync_codes[3] = {0x55, 0x2d, 0x16};
int16_t seq_no = 0;
uint8_t sync_codes[3] = {0x55, 0x2d, 0x16};
SDSVT dsvt;
unsigned char frame_pos_to_dvap = 0;
unsigned char seq_to_dvap = 0;
unsigned char silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
uint8_t frame_pos_to_dvap = 0;
uint8_t seq_to_dvap = 0;
uint8_t silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
bool written_to_q = false;
unsigned char ctrl_in = 0x80;
uint8_t ctrl_in = 0x80;
while (keep_running)
{
@ -248,7 +248,7 @@ void CQnetDVAP::ReadFromGateway()
if ('G' == dsvt.hdr.rpt1[7])
{
unsigned char tmp[8];
uint8_t tmp[8];
memcpy(tmp, dsvt.hdr.rpt1, 8);
memcpy(dsvt.hdr.rpt1, dsvt.hdr.rpt2, 8);
memcpy(dsvt.hdr.rpt2, tmp, 8);
@ -505,7 +505,7 @@ void CQnetDVAP::RptrAckThread(SDVAP_ACK_ARG *parg)
sprintf(RADIO_ID, "%20.2f", ber);
memcpy(RADIO_ID, "BER%", 4);
unsigned char silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
uint8_t silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
sleep(TIMING_PLAY_WAIT);
@ -525,7 +525,7 @@ void CQnetDVAP::RptrAckThread(SDVAP_ACK_ARG *parg)
memcpy(dr.frame.hdr.rpt1, RPTR_and_G, 8);
memcpy(dr.frame.hdr.urcall, mycall, 8);
memcpy(dr.frame.hdr.mycall, RPTR_and_MOD, 8);
memcpy(dr.frame.hdr.sfx, (unsigned char *)"DVAP", 4);
memcpy(dr.frame.hdr.sfx, (uint8_t *)"DVAP", 4);
calcPFCS(dr.frame.hdr.flag, dr.frame.hdr.pfcs);
dongle.SendRegister(dr);
std::this_thread::sleep_for(std::chrono::milliseconds(TIMING_PLAY_DELAY));
@ -615,9 +615,9 @@ void CQnetDVAP::ReadDVAPThread()
bool ok = true;
int i = 0;
u_int16_t streamid_raw = 0;
short int sequence = 0;
int16_t sequence = 0;
char mycall[8];
short int status_cntr = 3000;
int16_t status_cntr = 3000;
int num_dv_frames = 0;
int num_bit_errors = 0;
@ -790,7 +790,7 @@ void CQnetDVAP::ReadDVAPThread()
dsvt.streamid = streamid_raw;
dsvt.ctrl = 0x80;
sequence = 0;
calcPFCS((unsigned char *)&(dsvt.hdr), dsvt.hdr.pfcs);
calcPFCS((uint8_t *)&(dsvt.hdr), dsvt.hdr.pfcs);
ToGate.Write(dsvt.title, 56);
// local RF user keying up, start timer

@ -41,7 +41,7 @@ public:
private:
bool ReadConfig(const std::string &path);
void ReadFromGateway();
void calcPFCS(unsigned char *packet, unsigned char *pfcs);
void calcPFCS(uint8_t *packet, uint8_t *pfcs);
void ReadDVAPThread();
void RptrAckThread(SDVAP_ACK_ARG *parg);
@ -78,7 +78,7 @@ private:
int inactiveMax = 25;
/* helper data */
unsigned char SND_TERM_ID;
uint8_t SND_TERM_ID;
char RPTR_and_G[9];
char RPTR_and_MOD[9];
int serfd = -1;

@ -1198,7 +1198,7 @@ void CQnetDVRPTR::ambefec_regenerate(tambevoicefec voice)
ambefec_interleave(voice, decoded);
}
const unsigned char silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
const uint8_t silence[12] = { 0x9e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
void CQnetDVRPTR::CleanCall(std::string &callsign)
{
@ -1208,7 +1208,7 @@ void CQnetDVRPTR::CleanCall(std::string &callsign)
callsign.resize(CALL_SIZE, ' ');
}
const unsigned short crc_tabccitt[256] =
const uint16_t 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,
@ -1228,23 +1228,23 @@ const unsigned short crc_tabccitt[256] =
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
};
void CQnetDVRPTR::calcPFCS(unsigned char *packet) //Netzwerk CRC
void CQnetDVRPTR::calcPFCS(uint8_t *packet) //Netzwerk CRC
{
unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp, short_c;
uint16_t crc_dstar_ffff = 0xffff;
uint16_t tmp, short_c;
int i;
for (i = 17; i < 56 ; i++)
{
short_c = 0x00ff & (unsigned short)packet[i];
short_c = 0x00ff & (uint16_t)packet[i];
tmp = (crc_dstar_ffff & 0x00ff) ^ short_c;
crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp];
}
crc_dstar_ffff = ~crc_dstar_ffff;
tmp = crc_dstar_ffff;
packet[56] = (unsigned char)(crc_dstar_ffff & 0xff);
packet[57] = (unsigned char)((tmp >> 8) & 0xff);
packet[56] = (uint8_t)(crc_dstar_ffff & 0xff);
packet[57] = (uint8_t)((tmp >> 8) & 0xff);
return;
}
@ -1416,7 +1416,7 @@ int CQnetDVRPTR::open_port(char *dvrptr_device)
return fd_ser;
}
int CQnetDVRPTR::read_port(int *fd_ser,unsigned char* buffera)
int CQnetDVRPTR::read_port(int *fd_ser,uint8_t* buffera)
{
int a;
fd_set rfds;
@ -1632,9 +1632,9 @@ void CQnetDVRPTR::readFrom20000()
fd_set readfd;
struct timeval tv;
int inactive = 0;
short seq_no = 0;
int16_t seq_no = 0;
unsigned char ctrl_in = 0x80;
uint8_t ctrl_in = 0x80;
bool written_to_q = false;
int fd = FromGate.GetFD();
@ -1869,7 +1869,7 @@ bool CQnetDVRPTR::check_serial()
char dvrptr_device[FILENAME_MAX + 1];
InitCount = 1;
bool match = false;
unsigned char puffer[200];
uint8_t puffer[200];
for (int i = 0; i < 32; i++)
{
@ -2093,7 +2093,7 @@ void CQnetDVRPTR::Run()
InitCount = 2;
}
unsigned char puffer[200];
uint8_t puffer[200];
int bytes2 = read_port(&fd_ser, puffer);
char Temp_Text[200];
int seq_no = 0;
@ -2523,8 +2523,8 @@ void CQnetDVRPTR::Run()
puffer[0] = 0x00;
if (last_RF_time > 0)
{
const unsigned char silence[12] = { 0x9EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x70U,0x4FU,0x93U };
const unsigned char silsync[12] = { 0x9EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x55U,0x2DU,0x16U };
const uint8_t silence[12] = { 0x9EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x70U,0x4FU,0x93U };
const uint8_t silsync[12] = { 0x9EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x55U,0x2DU,0x16U };
memcpy(Send_Network_Audio.title, "DSVT", 4);
Send_Network_Audio.config = 0x20U;
memset(Send_Network_Audio.flaga, 0U, 3U);

@ -25,8 +25,8 @@
#include "QnetTypeDefs.h"
#include "Base.h"
using tambevoicefec = unsigned char[9];
using tambevoice = unsigned char[6];
using tambevoicefec = uint8_t[9];
using tambevoice = uint8_t[6];
#define interleaveambe12(bp) { bp+=12; if (bp>71) bp -= 71; }
#define CALL_SIZE 8
@ -57,10 +57,10 @@ private:
unsigned int gorlay_decode23127(unsigned int code);
unsigned int gorlay_encode24128(unsigned int data);
unsigned int gorlay_decode24128(unsigned int code);
void calcPFCS(unsigned char *packet);
void calcPFCS(uint8_t *packet);
char *cleanstr(char *Text);
int open_port(char *dvrptr_device);
int read_port(int *fd_ser, unsigned char *buffera);
int read_port(int *fd_ser, uint8_t *buffera);
void send_ack(char *a_call, float ber);
/*** BER stuff ***/
int ber_data[3];
@ -68,19 +68,19 @@ private:
int num_dv_frames;
int num_bit_errors;
short block = 0;
short old_seq_no = 0;
int16_t block = 0;
int16_t old_seq_no = 0;
short seq_no1 = 1;
short seq_no2 = 1;
short seq_no3 = 0;
int16_t seq_no1 = 1;
int16_t seq_no2 = 1;
int16_t seq_no3 = 0;
int fd_ser = -1;
bool busy20000 = false;
int rqst_count = 6;
unsigned short streamid = 0x0;
unsigned char start_Header[8]= {0xD0,0x03,0x00,0x16,0x01,0x00,0x00,0x00};
unsigned char ptt_off[8]= {0xD0,0x03,0x00,0x1A,0x01,0xff,0x00,0x00};
uint16_t streamid = 0x0;
uint8_t start_Header[8]= {0xD0,0x03,0x00,0x16,0x01,0x00,0x00,0x00};
uint8_t ptt_off[8]= {0xD0,0x03,0x00,0x1A,0x01,0xff,0x00,0x00};
SDSVT Send_Network_Header;
@ -88,17 +88,17 @@ private:
int inactiveMax = 3200;
unsigned char Send_Modem_Header[52];
uint8_t Send_Modem_Header[52];
unsigned char writevoice[24];
unsigned char writevoice1[24];
uint8_t writevoice[24];
uint8_t writevoice1[24];
// Modem INIT
unsigned char Modem_Init0[6]= {0xD0,0x01,0x00,0x11,0x00,0x00};
unsigned char Modem_Init1[7]= {0xD0,0x02,0x00,0x10,0x03,0x00,0x00}; // RX TX Enable
unsigned char Modem_Init2[12]= {0xD0,0x07,0x00,0x14,0xC0,0x04,0x00,0x57,0x53,0x00,0x00,0x00}; // Modem Init
unsigned char Modem_STATUS[6]= {0xD0,0x01,0x00,0x10,0x00,0x00}; // Status Abfragr
unsigned char Modem_SERIAL[6]= {0xD0,0x01,0x00,0x12,0x00,0x00};
uint8_t Modem_Init0[6]= {0xD0,0x01,0x00,0x11,0x00,0x00};
uint8_t Modem_Init1[7]= {0xD0,0x02,0x00,0x10,0x03,0x00,0x00}; // RX TX Enable
uint8_t Modem_Init2[12]= {0xD0,0x07,0x00,0x14,0xC0,0x04,0x00,0x57,0x53,0x00,0x00,0x00}; // Modem Init
uint8_t Modem_STATUS[6]= {0xD0,0x01,0x00,0x10,0x00,0x00}; // Status Abfragr
uint8_t Modem_SERIAL[6]= {0xD0,0x01,0x00,0x12,0x00,0x00};
CUnixDgramWriter ToGate;
CUnixDgramReader FromGate;
@ -118,7 +118,7 @@ private:
bool RX_Inverse = true;
bool TX_Inverse = true;
int TX_DELAY; /* in milliseconds */
unsigned char SND_TERM_ID = 0x00;
uint8_t SND_TERM_ID = 0x00;
char DVCALL_and_G[9];
char DVCALL_and_MOD[9];
int REMOTE_TIMEOUT = 1; /* 1 second */

@ -35,6 +35,7 @@
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <poll.h>
#include <regex>
#include <future>
@ -43,6 +44,7 @@
#include <thread>
#include <chrono>
#include <csignal>
#include <iomanip>
#include "IRCDDB.h"
#include "IRCutils.h"
@ -50,7 +52,7 @@
#include "QnetGateway.h"
#include "Utilities.h"
const std::string GW_VERSION("QnetGateway-60706");
const std::string GW_VERSION("QnetGateway-261107");
int CQnetGateway::FindIndex(const int i) const
{
@ -71,7 +73,7 @@ int CQnetGateway::FindIndex(const int i) const
return index;
}
bool CQnetGateway::Printable(unsigned char *s)
bool CQnetGateway::Printable(uint8_t *s)
{
bool rval = false;
for (unsigned i=0; s[i]; i++)
@ -85,7 +87,7 @@ bool CQnetGateway::Printable(unsigned char *s)
return rval;
}
bool CQnetGateway::VoicePacketIsSync(const unsigned char *text) const
bool CQnetGateway::VoicePacketIsSync(const uint8_t *text) const
{
return *text==0x55U && *(text+1)==0x2DU && *(text+2)==0x16U;
}
@ -140,9 +142,9 @@ void CQnetGateway::set_dest_rptr(const char mod, std::string &call)
}
/* compute checksum */
void CQnetGateway::calcPFCS(unsigned char *packet, int len)
void CQnetGateway::calcPFCS(uint8_t *packet, int len)
{
const unsigned short crc_tabccitt[256] =
const uint16_t 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,
@ -161,9 +163,9 @@ void CQnetGateway::calcPFCS(unsigned char *packet, int len)
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
};
unsigned short crc_dstar_ffff = 0xffff;
short int low, high;
unsigned short tmp;
uint16_t crc_dstar_ffff = 0xffff;
int16_t low, high;
uint16_t tmp;
switch (len)
{
@ -179,9 +181,9 @@ void CQnetGateway::calcPFCS(unsigned char *packet, int len)
return;
}
for (unsigned short int i = low; i < high ; i++)
for (uint16_t i = low; i < high ; i++)
{
unsigned short short_c = 0x00ff & (unsigned short)packet[i];
uint16_t short_c = 0x00ff & (uint16_t)packet[i];
tmp = (crc_dstar_ffff & 0x00ff) ^ short_c;
crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp];
}
@ -190,13 +192,13 @@ void CQnetGateway::calcPFCS(unsigned char *packet, int len)
if (len == 56)
{
packet[54] = (unsigned char)(crc_dstar_ffff & 0xff);
packet[55] = (unsigned char)((tmp >> 8) & 0xff);
packet[54] = (uint8_t)(crc_dstar_ffff & 0xff);
packet[55] = (uint8_t)((tmp >> 8) & 0xff);
}
else
{
packet[56] = (unsigned char)(crc_dstar_ffff & 0xff);
packet[57] = (unsigned char)((tmp >> 8) & 0xff);
packet[56] = (uint8_t)(crc_dstar_ffff & 0xff);
packet[57] = (uint8_t)((tmp >> 8) & 0xff);
}
return;
@ -335,6 +337,7 @@ bool CQnetGateway::ReadConfig(const std::string &cfgFile)
cfg.GetValue(path+"irc", estr, LOG_IRC);
cfg.GetValue(path+"dtmf", estr, LOG_DTMF);
cfg.GetValue(path+"debug", estr, LOG_DEBUG);
cfg.GetValue(path+"aprs", estr, LOG_APRS);
// file
path.assign("file_");
@ -393,9 +396,9 @@ int CQnetGateway::open_port(const SPORTIP *pip, int family)
void CQnetGateway::GetIRCDataThread(const int i)
{
IRCDDB_RESPONSE_TYPE type;
short last_status = 0;
int16_t last_status = 0;
short threshold = 0;
int16_t threshold = 0;
bool not_announced[3];
for (int i=0; i<3; i++)
not_announced[i] = Rptr.mod[i].defined; // announce to all modules that are defined!
@ -489,9 +492,9 @@ void CQnetGateway::GetIRCDataThread(const int i)
break;
CSockAddress to;
if (addr.npos == addr.find(':'))
to.Initialize(AF_INET, (unsigned short)g2_external.port, addr.c_str());
to.Initialize(AF_INET, (uint16_t)g2_external.port, addr.c_str());
else
to.Initialize(AF_INET6, (unsigned short)g2_ipv6_external.port, addr.c_str());
to.Initialize(AF_INET6, (uint16_t)g2_ipv6_external.port, addr.c_str());
sendto(g2_sock[i], "PONG", 4, 0, to.GetCPointer(), to.GetSize());
if (LOG_QSO)
printf("Sent 'PONG' to %s\n", addr.c_str());
@ -586,7 +589,7 @@ int CQnetGateway::get_yrcall_rptr(const std::string &call, std::string &rptr, st
return 0;
}
bool CQnetGateway::Flag_is_ok(unsigned char flag)
bool CQnetGateway::Flag_is_ok(uint8_t flag)
{
// normal break emr emr+break
return 0x00U==flag || 0x08U==flag || 0x20U==flag || 0x28U==flag;
@ -685,17 +688,17 @@ void CQnetGateway::ProcessTimeouts()
}
}
bool CQnetGateway::ProcessG2Msg(const unsigned char *data, const int mod, std::string &smrtgrp)
bool CQnetGateway::ProcessG2Msg(const uint8_t *data, const int mod, std::string &smrtgrp)
{
static unsigned int part[3] = { 0 };
static char txt[3][21];
if ((data[0] != 0x55u) || (data[1] != 0x2du) || (data[2] != 0x16u))
{
const unsigned char c[3] =
const uint8_t c[3] =
{
static_cast<unsigned char>(data[0] ^ 0x70u),
static_cast<unsigned char>(data[1] ^ 0x4fu),
static_cast<unsigned char>(data[2] ^ 0x93u)
static_cast<uint8_t>(data[0] ^ 0x70u),
static_cast<uint8_t>(data[1] ^ 0x4fu),
static_cast<uint8_t>(data[2] ^ 0x93u)
}; // unscramble
if (part[mod])
{
@ -764,11 +767,11 @@ void CQnetGateway::ProcessIncomingSD(const SDSVT &dsvt, const int source_sock)
return;
}
const unsigned char c[3] =
const uint8_t c[3] =
{
static_cast<unsigned char>(dsvt.vasd.text[0] ^ 0x70u),
static_cast<unsigned char>(dsvt.vasd.text[1] ^ 0x4fu),
static_cast<unsigned char>(dsvt.vasd.text[2] ^ 0x93u)
static_cast<uint8_t>(dsvt.vasd.text[0] ^ 0x70u),
static_cast<uint8_t>(dsvt.vasd.text[1] ^ 0x4fu),
static_cast<uint8_t>(dsvt.vasd.text[2] ^ 0x93u)
}; // unscramble
if (sd.first)
@ -850,7 +853,7 @@ void CQnetGateway::ProcessIncomingSD(const SDSVT &dsvt, const int source_sock)
if (mod >= 0 && mod < 3 && Rptr.mod[mod].defined)
{
printf("Got a slow data header: %36.36s\n", sd.header+3);
unsigned char call[CALL_SIZE]; // swap rpt1 and rpt2
uint8_t call[CALL_SIZE]; // swap rpt1 and rpt2
memcpy(call, sdheader.hdr.rpt1, CALL_SIZE);
memcpy(sdheader.hdr.rpt1, sdheader.hdr.rpt2, CALL_SIZE);
memcpy(sdheader.hdr.rpt2, call, CALL_SIZE);
@ -952,11 +955,11 @@ void CQnetGateway::ProcessOutGoingSD(const SDSVT &dsvt, const int i)
return;
}
const unsigned char c[3] =
const uint8_t c[3] =
{
static_cast<unsigned char>(dsvt.vasd.text[0] ^ 0x70u),
static_cast<unsigned char>(dsvt.vasd.text[1] ^ 0x4fu),
static_cast<unsigned char>(dsvt.vasd.text[2] ^ 0x93u)
static_cast<uint8_t>(dsvt.vasd.text[0] ^ 0x70u),
static_cast<uint8_t>(dsvt.vasd.text[1] ^ 0x4fu),
static_cast<uint8_t>(dsvt.vasd.text[2] ^ 0x93u)
}; // unscramble
if (sd.first)
@ -990,8 +993,10 @@ void CQnetGateway::ProcessOutGoingSD(const SDSVT &dsvt, const int i)
if (APRS_ENABLE && (! band_txt[i].is_gps_sent) && (time(NULL) - band_txt[i].gps_last_time > 30))
{
std::string call(band_txt[i].mycall);
const char *s = gps.APRS(call, Rptr.mod[i].call.c_str());
if (! aprs->aprs_sock.Write((unsigned char *)s, strlen(s)))
std::string s(gps.APRS(call, Rptr.mod[i].call.c_str()));
if (aprs->m_debug)
printf("Outgoing SD: %s\n", s.c_str());
if (aprs->aprs_sock.WriteLine(s))
{
time(&band_txt[i].gps_last_time);
band_txt[i].is_gps_sent = true;
@ -1069,9 +1074,12 @@ void CQnetGateway::ProcessOutGoingSD(const SDSVT &dsvt, const int i)
if (APRS_ENABLE && (! band_txt[i].is_gps_sent) && (time(NULL) - band_txt[i].gps_last_time > 30))
{
std::string call(band_txt[i].mycall);
const char *s = gps.APRS(call, Rptr.mod[i].call.c_str());
if (! aprs->aprs_sock.Write((unsigned char *)s, strlen(s)))
{
std::string s(gps.APRS(call, Rptr.mod[i].call.c_str()));
if (aprs->m_debug)
printf("Outgoing position: %s\n", s.c_str());
if (aprs->aprs_sock.WriteLine(s)) {
fprintf(stderr, "ERROR: could not write Outgoing position\n");
} else {
time(&band_txt[i].gps_last_time);
band_txt[i].is_gps_sent = true;
}
@ -1228,7 +1236,7 @@ void CQnetGateway::ProcessG2(const ssize_t g2buflen, SDSVT &g2buf, const int sou
fprintf(stderr, "Warning: inserting %d missing voice frame(s)\n", diff);
SDSVT dsvt;
memcpy(dsvt.title, g2buf.title, 14U); // everything but the ctrl and voice data
const unsigned char quite[9] = { 0x9EU, 0x8DU, 0x32U, 0x88U, 0x26U, 0x1AU, 0x3FU, 0x61U, 0xE8U };
const uint8_t quite[9] = { 0x9EU, 0x8DU, 0x32U, 0x88U, 0x26U, 0x1AU, 0x3FU, 0x61U, 0xE8U };
memcpy(dsvt.vasd.voice, quite, 9U);
while (diff-- > 0)
{
@ -1236,12 +1244,12 @@ void CQnetGateway::ProcessG2(const ssize_t g2buflen, SDSVT &g2buf, const int sou
nextctrl[i] %= 21U;
if (dsvt.ctrl)
{
const unsigned char silence[3] = { 0x70U, 0x4FU, 0x93U };
const uint8_t silence[3] = { 0x70U, 0x4FU, 0x93U };
memcpy(dsvt.vasd.voice, silence, 3U);
}
else
{
const unsigned char sync[3] = { 0x55U, 0x2DU, 0x16U };
const uint8_t sync[3] = { 0x55U, 0x2DU, 0x16U };
memcpy(dsvt.vasd.voice, sync, 3U);
}
ToModem[i].Write(dsvt.title, 27);
@ -1902,7 +1910,7 @@ void CQnetGateway::ProcessModem(const ssize_t recvlen, SDSVT &dsvt)
dtmf_buf_count[i]++;
}
}
const unsigned char silence[9] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8 };
const uint8_t silence[9] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8 };
memcpy(dsvt.vasd.voice, silence, 9);
}
else
@ -2153,7 +2161,7 @@ void CQnetGateway::Run()
void CQnetGateway::compute_aprs_hash()
{
short hash = 0x73e2;
int16_t hash = 0x73e2;
char rptr_sign[CALL_SIZE + 1];
strcpy(rptr_sign, OWNER.c_str());
@ -2165,9 +2173,9 @@ void CQnetGateway::compute_aprs_hash()
}
*p = '\0';
p = rptr_sign;
short int len = strlen(rptr_sign);
int16_t len = strlen(rptr_sign);
for (short int i=0; i < len; i+=2)
for (int16_t i=0; i < len; i+=2)
{
hash ^= (*p++) << 8;
hash ^= (*p++);
@ -2180,190 +2188,75 @@ void CQnetGateway::compute_aprs_hash()
void CQnetGateway::APRSBeaconThread()
{
char snd_buf[512];
char rcv_buf[512];
unsigned kaCount = 0;
time_t tnow = 0;
/*
Every 20 seconds, the remote APRS host sends a KEEPALIVE packet-comment
on the TCP/APRS port.
If we have not received any KEEPALIVE packet-comment after 5 minutes
we must assume that the remote APRS host is down or disappeared
or has dropped the connection. In these cases, we must re-connect.
There are 3 keepalive packets in one minute, or every 20 seconds.
In 5 minutes, we should have received a total of 15 keepalive packets.
*/
short THRESHOLD_COUNTDOWN = 15;
time_t last_keepalive_time;
time(&last_keepalive_time);
time_t last_beacon_time = 0;
/* This thread is also saying to the APRS_HOST that we are ALIVE */
while (keep_running)
{
if (aprs->aprs_sock.GetFD() == -1)
// start up the aprs client
while (keep_running and (aprs->aprs_sock.GetFD() < 0))
{
aprs->Open(OWNER);
aprs->Open(OWNER, GW_VERSION);
if (aprs->aprs_sock.GetFD() == -1)
sleep(1);
else
THRESHOLD_COUNTDOWN = 15;
sleep(5);
}
// see if it's time to update aprs beacon
time(&tnow);
if ((tnow - last_beacon_time) > (Rptr.aprs_interval * 60))
if ((tnow - last_beacon_time) >= (Rptr.aprs_interval * 60))
{
for (short int i=0; i<3; i++)
// update each channel, A B C
for (int i=0; i<3; i++)
{
if (Rptr.mod[i].defined)
if (Rptr.mod[i].defined and aprs->aprs_sock.GetFD() >= 0)
{
float tmp_lat = fabs(Rptr.mod[i].latitude);
float tmp_lon = fabs(Rptr.mod[i].longitude);
float lat = floor(tmp_lat);
float lon = floor(tmp_lon);
lat = (tmp_lat - lat) * 60.0F + lat * 100.0F;
lon = (tmp_lon - lon) * 60.0F + lon * 100.0F;
char lat_s[15], lon_s[15];
if (lat >= 1000.0F)
sprintf(lat_s, "%.2f", lat);
else if (lat >= 100.0F)
sprintf(lat_s, "0%.2f", lat);
else if (lat >= 10.0F)
sprintf(lat_s, "00%.2f", lat);
else
sprintf(lat_s, "000%.2f", lat);
if (lon >= 10000.0F)
sprintf(lon_s, "%.2f", lon);
else if (lon >= 1000.0F)
sprintf(lon_s, "0%.2f", lon);
else if (lon >= 100.0F)
sprintf(lon_s, "00%.2f", lon);
else if (lon >= 10.0F)
sprintf(lon_s, "000%.2f", lon);
else
sprintf(lon_s, "0000%.2f", lon);
/* send to aprs */
sprintf(snd_buf, "%s>APJI23,TCPIP*,qAC,%sS:!%s%cD%s%c&RNG%04u %s %s",
Rptr.mod[i].call.c_str(), Rptr.mod[i].call.c_str(),
lat_s, (Rptr.mod[i].latitude < 0.0) ? 'S' : 'N',
lon_s, (Rptr.mod[i].longitude < 0.0) ? 'W' : 'E',
(unsigned int)Rptr.mod[i].range, Rptr.mod[i].band.c_str(), GW_VERSION.c_str());
if (LOG_DEBUG)
printf("APRS Beacon =[%s]\n", snd_buf);
strcat(snd_buf, "\r\n");
while (keep_running)
{
if (aprs->aprs_sock.GetFD() == -1)
{
aprs->Open(OWNER);
if (aprs->aprs_sock.GetFD() == -1)
sleep(1);
else
THRESHOLD_COUNTDOWN = 15;
}
else
{
int rc = aprs->aprs_sock.Write((unsigned char *)snd_buf, strlen(snd_buf));
if (rc < 0)
{
if ((errno == EPIPE) ||
(errno == ECONNRESET) ||
(errno == ETIMEDOUT) ||
(errno == ECONNABORTED) ||
(errno == ESHUTDOWN) ||
(errno == EHOSTUNREACH) ||
(errno == ENETRESET) ||
(errno == ENETDOWN) ||
(errno == ENETUNREACH) ||
(errno == EHOSTDOWN) ||
(errno == ENOTCONN))
{
printf("send_aprs_beacon: APRS_HOST closed connection,error=%d\n",errno);
aprs->aprs_sock.Close();
}
else if (errno == EWOULDBLOCK)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
else
{
/* Cant do nothing about it */
printf("send_aprs_beacon failed, error=%d\n", errno);
break;
}
}
else
{
// printf("APRS beacon sent\n");
break;
auto line = Rptr.mod[i].position_ss.str();
printf("APRS Beacon: %s\n", line.c_str());
if (aprs->aprs_sock.WriteLine(line)) {
aprs->aprs_sock.Close();
} else {
if (aprs->aprs_sock.ReadLine(line)) {
aprs->aprs_sock.Close();
} else {
if (aprs->m_debug) {
printf("APRS Beacon ackn: %s\n", line.c_str());
}
time(&last_beacon_time);
kaCount = 0;
}
int rc = aprs->aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf));
if (rc > 0)
THRESHOLD_COUNTDOWN = 15;
}
}
int rc = aprs->aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf));
if (rc > 0)
THRESHOLD_COUNTDOWN = 15;
}
time(&last_beacon_time);
}
/*
Are we still receiving from APRS host ?
*/
int rc = aprs->aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf));
if (rc < 0)
{
if ((errno == EPIPE) ||
(errno == ECONNRESET) ||
(errno == ETIMEDOUT) ||
(errno == ECONNABORTED) ||
(errno == ESHUTDOWN) ||
(errno == EHOSTUNREACH) ||
(errno == ENETRESET) ||
(errno == ENETDOWN) ||
(errno == ENETUNREACH) ||
(errno == EHOSTDOWN) ||
(errno == ENOTCONN))
{
printf("send_aprs_beacon: recv error: APRS_HOST closed connection,error=%d\n",errno);
aprs->aprs_sock.Close();
}
}
else if (rc == 0)
{
printf("send_aprs_beacon: recv: APRS shutdown\n");
aprs->aprs_sock.Close();
}
else
THRESHOLD_COUNTDOWN = 15;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
/* 20 seconds passed already ? */
time(&tnow);
if ((tnow - last_keepalive_time) > 20)
{
/* we should be receving keepalive packets ONLY if the connection is alive */
if (aprs->aprs_sock.GetFD() >= 0)
{
if (THRESHOLD_COUNTDOWN > 0)
THRESHOLD_COUNTDOWN--;
if (THRESHOLD_COUNTDOWN == 0)
{
printf("APRS host keepalive timeout\n");
// Are we still receiving keepalives from APRS host ?
if (keep_running and aprs->aprs_sock.GetFD() >= 0) {
struct pollfd pfd;
pfd.fd = aprs->aprs_sock.GetFD();
pfd.events = POLLIN;
auto rtv = poll(&pfd, 1, 5000);
if (rtv < 0) {
fprintf(stderr, "APRS poll ERROR: %s\n", strerror(errno));
aprs->aprs_sock.Close();
continue;
} else if (0 == rtv) {
// nothing to read;
continue;
} else if (pfd.revents & POLLIN) {
std::string line;
if (aprs->aprs_sock.ReadLine(line)) {
aprs->aprs_sock.Close();
} else {
if (aprs->m_debug and (++kaCount%15 == 0))
printf("APRS keep alive #%u: %s\n", kaCount, line.c_str());
}
} else if (pfd.revents & ( POLL_ERR | POLLHUP | POLLNVAL)) {
fprintf(stderr, "ERROR: aprs poll detected bad socket state\n");
aprs->aprs_sock.Close();
continue;
}
/* reset timer */
time(&last_keepalive_time);
}
}
printf("APRS beacon thread exiting...\n");
@ -2373,8 +2266,8 @@ void CQnetGateway::APRSBeaconThread()
void CQnetGateway::PlayFileThread(SECHO &edata)
{
SDSVT dsvt;
const unsigned char sdsilence[3] = { 0x16U, 0x29U, 0xF5U };
const unsigned char sdsync[3] = { 0x55U, 0x2DU, 0x16U };
const uint8_t sdsilence[3] = { 0x16U, 0x29U, 0xF5U };
const uint8_t sdsync[3] = { 0x55U, 0x2DU, 0x16U };
printf("File to playback:[%s]\n", edata.file);
@ -2440,7 +2333,7 @@ void CQnetGateway::PlayFileThread(SECHO &edata)
int nread = fread(dsvt.vasd.voice, 9, 1, fp);
if (nread == 1)
{
dsvt.ctrl = (unsigned char)(i % 21);
dsvt.ctrl = (uint8_t)(i % 21);
if (0x0U == dsvt.ctrl)
{
memcpy(dsvt.vasd.text, sdsync, 3);
@ -2535,9 +2428,31 @@ void CQnetGateway::qrgs_and_maps()
return;
}
// Helper to convert decimal degrees to APRS DDMM.hh format
std::string CQnetGateway::convertToAprsCoordinate(double decimalDegrees, bool isLatitude)
{
double absolute = std::abs(decimalDegrees);
int degrees = static_cast<int>(absolute);
double minutes = (absolute - degrees) * 60.0;
std::stringstream ss;
if (isLatitude) {
// DDMM.hh (2 digits for degrees)
ss << std::setw(2) << std::setfill('0') << degrees;
ss << std::setw(5) << std::setfill('0') << std::fixed << std::setprecision(2) << minutes;
ss << (decimalDegrees >= 0 ? 'N' : 'S');
} else {
// DDDMM.hh (3 digits for degrees)
ss << std::setw(3) << std::setfill('0') << degrees;
ss << std::setw(5) << std::setfill('0') << std::fixed << std::setprecision(2) << minutes;
ss << (decimalDegrees >= 0 ? 'E' : 'W');
}
return ss.str();
}
bool CQnetGateway::Initialize(const std::string &path)
{
short int i;
int16_t i;
/* Used to validate MYCALL input */
preg = std::regex("^[A-PR-Z0-9]{1}[A-Z0-9]{0,1}[0-9]{1,2}[A-Z]{1,4} {0,4}[ A-Z]{1}$", std::regex::extended);
@ -2631,7 +2546,7 @@ bool CQnetGateway::Initialize(const std::string &path)
if (APRS_ENABLE)
{
aprs = new CAPRS(&Rptr);
aprs = new CAPRS(&Rptr, LOG_APRS);
if (aprs)
aprs->Init();
else
@ -2639,8 +2554,17 @@ bool CQnetGateway::Initialize(const std::string &path)
printf("aprs class init failed!\nAPRS will be turned off");
APRS_ENABLE = false;
}
for (int i=0; i<3; i++) {
if (Rptr.mod[i].defined) {
Rptr.mod[i].position_ss << Rptr.mod[i].call << ">APRS,TCPIP*:"
<< '!' << convertToAprsCoordinate(Rptr.mod[i].latitude, true) << 'D' << convertToAprsCoordinate(Rptr.mod[i].longitude,false) << '&'
<< Rptr.mod[i].band << " Voice (DStar) "
<< std::fixed << std::setprecision(4) << std::showpos
<< Rptr.mod[i].frequency << "MHz " << Rptr.mod[i].offset << "MHz QnetGateway";
}
}
compute_aprs_hash();
}
compute_aprs_hash();
for (int j=0; j<2; j++)
{

@ -37,7 +37,7 @@
using STOREMOTEG2 = struct to_remote_g2_tag
{
unsigned short streamid;
uint16_t streamid;
CSockAddress toDstar;
time_t last_time;
};
@ -47,13 +47,13 @@ using STOREPEATER = struct torepeater_tag
// help with header re-generation
SDSVT saved_hdr; // repeater format
time_t last_time;
unsigned char sequence;
uint8_t sequence;
};
using SBANDTXT = struct band_txt_tag
{
unsigned short streamID;
unsigned char flags[3];
uint16_t streamID;
uint8_t flags[3];
std::string mycall, sfx, urcall, rpt1, rpt2, txt, dest_rptr;
time_t last_time, gps_last_time;
bool sent_key_on_msg, is_gps_sent;
@ -81,11 +81,11 @@ using SBANDTXT = struct band_txt_tag
using SSD = struct sd_tag
{
unsigned char header[41];
unsigned char message[21];
unsigned char gps[256];
uint8_t header[41];
uint8_t message[21];
uint8_t gps[256];
unsigned int ih, im, ig;
unsigned char type;
uint8_t type;
bool first;
unsigned int size;
void Init() { ih = im = ig = 0; first = true; }
@ -115,7 +115,7 @@ private:
std::string OWNER, owner, FILE_DTMF, FILE_ECHOTEST, IRCDDB_PASSWORD[2], FILE_QNVOICE_FILE, DASH_SHOW_ORDER;
bool GATEWAY_SEND_QRGS_MAP, GATEWAY_HEADER_REGEN, APRS_ENABLE, playNotInCache, showLastHeard;
bool LOG_DEBUG, LOG_IRC, LOG_DTMF, LOG_QSO, IS_HF[3];
bool LOG_APRS, LOG_DEBUG, LOG_IRC, LOG_DTMF, LOG_QSO, IS_HF[3];
int DASH_REFRESH, TIMING_PLAY_WAIT, TIMING_PLAY_DELAY, TIMING_TIMEOUT_ECHO, TIMING_TIMEOUT_VOICEMAIL, TIMING_TIMEOUT_REMOTE_G2, TIMING_TIMEOUT_LOCAL_RPTR, dtmf_digit;
@ -169,7 +169,7 @@ private:
// g2 data
std::string lhcallsign[3], lhsfx[3];
unsigned char nextctrl[3] = { 0U, 0U, 0U };
uint8_t nextctrl[3] = { 0U, 0U, 0U };
std::string superframe[3];
// dtmf stuff
@ -178,24 +178,27 @@ private:
int dtmf_last_frame[3];
unsigned int dtmf_counter[3];
bool VoicePacketIsSync(const unsigned char *text) const;
// helper
std::string convertToAprsCoordinate(double decimalDegrees, bool isLatitude);
bool VoicePacketIsSync(const uint8_t *text) const;
int open_port(const SPORTIP *pip, int family);
void calcPFCS(unsigned char *packet, int len);
void calcPFCS(uint8_t *packet, int len);
void GetIRCDataThread(const int i);
int get_yrcall_rptr_from_cache(const int i, const std::string &call, std::string &rptr, std::string &gate, std::string &addr, char RoU);
int get_yrcall_rptr(const std::string &call, std::string &rptr, std::string &gate, std::string &addr, char RoU);
void PlayFileThread(SECHO &edata);
void compute_aprs_hash();
void APRSBeaconThread();
bool Printable(unsigned char *string);
bool Printable(uint8_t *string);
void ProcessTimeouts();
void ProcessIncomingSD(const SDSVT &dsvt, const int source_sock);
void ProcessOutGoingSD(const SDSVT &dsvt, const int mod);
bool ProcessG2Msg(const unsigned char *data, const int mod, std::string &smrtgrp);
bool ProcessG2Msg(const uint8_t *data, const int mod, std::string &smrtgrp);
void ProcessG2(const ssize_t g2buflen, SDSVT &g2buf, const int sock_source);
void ProcessG2Header(const SDSVT &g2buf, const int source_sock);
void ProcessModem(const ssize_t len, SDSVT &dsvt);
bool Flag_is_ok(unsigned char flag);
bool Flag_is_ok(uint8_t flag);
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);
int FindIndex(const int i) const;

@ -115,7 +115,7 @@ int CQnetITAP::OpenITAP()
return fd;
}
void CQnetITAP::DumpSerialPacket(const char *title, const unsigned char *buf)
void CQnetITAP::DumpSerialPacket(const char *title, const uint8_t *buf)
{
printf("%s: ", title);
if (buf[0] > 41)
@ -152,7 +152,7 @@ void CQnetITAP::DumpSerialPacket(const char *title, const unsigned char *buf)
}
}
REPLY_TYPE CQnetITAP::GetITAPData(unsigned char *buf)
REPLY_TYPE CQnetITAP::GetITAPData(uint8_t *buf)
{
// Some methods adapted from Jonathan G4KLX's CIcomController::GetResponse()
// and CSerialController::read()
@ -258,20 +258,20 @@ void CQnetITAP::Run()
{
if (poll_counter < 18 )
{
const unsigned char poll[2] = { 0xffu, 0xffu };
const uint8_t poll[2] = { 0xffu, 0xffu };
SendToIcom(poll);
if (poll_counter++ == 17)
pingtime = 1.0;
}
else
{
const unsigned char ping[2] = { 0x02u, 0x02u };
const uint8_t ping[2] = { 0x02u, 0x02u };
SendToIcom(ping);
}
pingTimer.start();
}
unsigned char buf[100];
uint8_t buf[100];
if (keep_running && FD_ISSET(serfd, &readfds)) // there is something to read from the Icom!
{
@ -282,7 +282,7 @@ void CQnetITAP::Run()
break;
case RT_HEADER:
{
unsigned char ack_header[3] = { 0x03U, 0x11U, 0x0U };
uint8_t ack_header[3] = { 0x03U, 0x11U, 0x0U };
SendToIcom(ack_header);
}
if (ProcessITAP(buf))
@ -291,7 +291,7 @@ void CQnetITAP::Run()
break;
case RT_DATA:
{
unsigned char ack_voice[4] = { 0x04U, 0x13U, 0x0U, 0x0U };
uint8_t ack_voice[4] = { 0x04U, 0x13U, 0x0U, 0x0U };
ack_voice[2] = buf[2];
SendToIcom(ack_voice);
}
@ -423,7 +423,7 @@ void CQnetITAP::Close()
FromGate.Close();
}
void CQnetITAP::SendToIcom(const unsigned char *buf)
void CQnetITAP::SendToIcom(const uint8_t *buf)
{
ssize_t n;
unsigned int ptr = 0;
@ -446,7 +446,7 @@ void CQnetITAP::SendToIcom(const unsigned char *buf)
n = 0; // send an ending 0xffu
while (0 == n)
{
const unsigned char push = 0xffu;
const uint8_t push = 0xffu;
n = write(serfd, &push, 1);
if (n < 0)
{
@ -458,9 +458,9 @@ void CQnetITAP::SendToIcom(const unsigned char *buf)
}
}
bool CQnetITAP::ProcessGateway(const int len, const unsigned char *raw)
bool CQnetITAP::ProcessGateway(const int len, const uint8_t *raw)
{
static unsigned char counter = 0;
static uint8_t counter = 0;
if (27==len || 56==len) //here is dstar data
{
SDSVT dsvt;
@ -509,9 +509,9 @@ bool CQnetITAP::ProcessGateway(const int len, const unsigned char *raw)
return false;
}
bool CQnetITAP::ProcessITAP(const unsigned char *buf)
bool CQnetITAP::ProcessITAP(const uint8_t *buf)
{
static short stream_id = 0U;
static int16_t stream_id = 0U;
SITAP itap;
unsigned int len = (0x10U == buf[1]) ? 41 : 16;
memcpy(&itap.length, buf, len); // transfer raw data to SITAP struct
@ -548,7 +548,7 @@ bool CQnetITAP::ProcessITAP(const unsigned char *buf)
if (' '==itap.header.ur[2] && ' '!=itap.header.ur[0])
{
// it's a command because it has as space in the 3rd position, we have to right-justify it!
// Terminal Mode left justifies short commands.
// Terminal Mode left justifies int16_t commands.
memset(dsvt.hdr.urcall, ' ', 8); // first file ur with spaces
if (' ' == itap.header.ur[1])
dsvt.hdr.urcall[7] = itap.header.ur[0]; // one char command, like "E" or "I"
@ -689,11 +689,11 @@ bool CQnetITAP::ReadConfig(const std::string &cfgFile)
return false;
}
void CQnetITAP::calcPFCS(const unsigned char *packet, unsigned char *pfcs)
void CQnetITAP::calcPFCS(const uint8_t *packet, uint8_t *pfcs)
{
unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp, short_c;
unsigned short crc_tabccitt[256] =
uint16_t crc_dstar_ffff = 0xffff;
uint16_t tmp, short_c;
uint16_t 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,
@ -715,15 +715,15 @@ void CQnetITAP::calcPFCS(const unsigned char *packet, unsigned char *pfcs)
for (int i = 0; i < 39 ; i++)
{
short_c = 0x00ff & (unsigned short)packet[i];
short_c = 0x00ff & (uint16_t)packet[i];
tmp = (crc_dstar_ffff & 0x00ff) ^ short_c;
crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp];
}
crc_dstar_ffff = ~crc_dstar_ffff;
tmp = crc_dstar_ffff;
pfcs[0] = (unsigned char)(crc_dstar_ffff & 0xff);
pfcs[1] = (unsigned char)((tmp >> 8) & 0xff);
pfcs[0] = (uint8_t)(crc_dstar_ffff & 0xff);
pfcs[1] = (uint8_t)((tmp >> 8) & 0xff);
return;
}

@ -47,10 +47,10 @@ enum REPLY_TYPE
#pragma pack(push, 1)
using SITAP = struct itap_tag
{
unsigned char length;
uint8_t length;
// 41 for header
// 16 for voice
unsigned char type;
uint8_t type;
// 0x03U pong
// 0x10U header from icom
// 0x11U acknowledgment
@ -64,19 +64,19 @@ using SITAP = struct itap_tag
{
struct
{
unsigned char flag[3];
unsigned char r2[8];
unsigned char r1[8];
unsigned char ur[8];
unsigned char my[8];
unsigned char nm[4];
uint8_t flag[3];
uint8_t r2[8];
uint8_t r1[8];
uint8_t ur[8];
uint8_t my[8];
uint8_t nm[4];
} header;
struct
{
unsigned char counter; // ordinal counter is reset with each header
unsigned char sequence; // is modulo 21
unsigned char ambe[9];
unsigned char text[3];
uint8_t counter; // ordinal counter is reset with each header
uint8_t sequence; // is modulo 21
uint8_t ambe[9];
uint8_t text[3];
} voice;
};
};
@ -85,7 +85,7 @@ using SITAP = struct itap_tag
class CFrame
{
public:
CFrame(const unsigned char *buf)
CFrame(const uint8_t *buf)
{
memcpy(&frame.length, buf, buf[0]);
}
@ -99,7 +99,7 @@ public:
size_t size() const { return (size_t)frame.length; }
const unsigned char *data() const { return &frame.length; }
const uint8_t *data() const { return &frame.length; }
private:
SITAP frame;
@ -119,13 +119,13 @@ public:
private:
// functions
bool ProcessGateway(const int len, const unsigned char *raw);
bool ProcessITAP(const unsigned char *raw);
bool ProcessGateway(const int len, const uint8_t *raw);
bool ProcessITAP(const uint8_t *raw);
int OpenITAP();
void SendToIcom(const unsigned char *buf);
REPLY_TYPE GetITAPData(unsigned char *buf);
void calcPFCS(const unsigned char *packet, unsigned char *pfcs);
void DumpSerialPacket(const char *title, const unsigned char *);
void SendToIcom(const uint8_t *buf);
REPLY_TYPE GetITAPData(uint8_t *buf);
void calcPFCS(const uint8_t *packet, uint8_t *pfcs);
void DumpSerialPacket(const char *title, const uint8_t *);
// read configuration file
bool ReadConfig(const std::string &path);
@ -137,7 +137,7 @@ private:
// parameters
int serfd;
unsigned char tapcounter;
uint8_t tapcounter;
// helpers
CRandom random;

@ -89,7 +89,7 @@ void CQnetLink::XRFWrite(const void *buf, const size_t size, const CSockAddress
XRFSock6.Write(buf, size, addr);
}
bool CQnetLink::resolve_rmt(const char *name, const unsigned short port, CSockAddress &addr)
bool CQnetLink::resolve_rmt(const char *name, const uint16_t port, CSockAddress &addr)
{
struct addrinfo hints;
struct addrinfo *res;
@ -357,9 +357,9 @@ void CQnetLink::RptrAckThread(char *arg)
char from_mod = arg[0];
char RADIO_ID[21];
memcpy(RADIO_ID, arg + 1, 21);
unsigned char silence[12] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x16, 0x29, 0xf5 };
uint8_t silence[12] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x16, 0x29, 0xf5 };
short int streamid_raw = Random.NewStreamID();
int16_t streamid_raw = Random.NewStreamID();
sleep(delay_before);
@ -403,7 +403,7 @@ void CQnetLink::RptrAckThread(char *arg)
for (int i=0; i<10; i++)
{
dsvt.ctrl = (unsigned char)i;
dsvt.ctrl = (uint8_t)i;
switch (i)
{
case 0:
@ -494,7 +494,7 @@ void CQnetLink::LoadGateways(const std::string &filename)
{
std::istringstream iss(line);
std::string host, address;
unsigned short port;
uint16_t port;
iss >> host >> address >> port;
hqueue.Push(CHost(host, address, port));
count++;
@ -534,9 +534,9 @@ void CQnetLink::LoadGateways(const std::string &filename)
}
/* compute checksum */
void CQnetLink::calcPFCS(unsigned char *packet, int len)
void CQnetLink::calcPFCS(uint8_t *packet, int len)
{
unsigned short crc_tabccitt[256] =
uint16_t 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,
@ -556,9 +556,9 @@ void CQnetLink::calcPFCS(unsigned char *packet, int len)
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
};
unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp;
short int low, high;
uint16_t crc_dstar_ffff = 0xffff;
uint16_t tmp;
int16_t low, high;
if (len == 56)
{
@ -573,9 +573,9 @@ void CQnetLink::calcPFCS(unsigned char *packet, int len)
else
return;
for (short int i=low; i<high ; i++)
for (int16_t i=low; i<high ; i++)
{
unsigned short short_c = 0x00ff & (unsigned short)packet[i];
uint16_t short_c = 0x00ff & (uint16_t)packet[i];
tmp = (crc_dstar_ffff & 0x00ff) ^ short_c;
crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp];
}
@ -584,13 +584,13 @@ void CQnetLink::calcPFCS(unsigned char *packet, int len)
if (len == 56)
{
packet[54] = (unsigned char)(crc_dstar_ffff & 0xff);
packet[55] = (unsigned char)((tmp >> 8) & 0xff);
packet[54] = (uint8_t)(crc_dstar_ffff & 0xff);
packet[55] = (uint8_t)((tmp >> 8) & 0xff);
}
else
{
packet[56] = (unsigned char)(crc_dstar_ffff & 0xff);
packet[57] = (unsigned char)((tmp >> 8) & 0xff);
packet[56] = (uint8_t)(crc_dstar_ffff & 0xff);
packet[57] = (uint8_t)((tmp >> 8) & 0xff);
}
return;
}
@ -718,11 +718,11 @@ bool CQnetLink::ReadConfig(const std::string &cfgFile)
key.assign("link_");
int port;
cfg.GetValue(key+"ref_port", estr, port, 10000, 65535);
rmt_ref_port = (unsigned short)port;
rmt_ref_port = (uint16_t)port;
cfg.GetValue(key+"xrf_port", estr, port, 10000, 65535);
rmt_xrf_port = (unsigned short)port;
rmt_xrf_port = (uint16_t)port;
cfg.GetValue(key+"dcs_port", estr, port, 10000, 65535);
rmt_dcs_port = (unsigned short)port;
rmt_dcs_port = (uint16_t)port;
cfg.GetValue(key+"acknowledge", estr, bool_rptr_ack);
cfg.GetValue(key+"announce", estr, announce);
int maxdongle;
@ -848,7 +848,7 @@ void CQnetLink::g2link(const char from_mod, const char *call, const char to_mod)
to_remote_g2[i].to_mod = '\0';
std::string address;
unsigned short port;
uint16_t port;
if (qnDB.FindGW(call, address, port))
{
sprintf(notify_msg[i], "%c_gatewaynotfound.dat_GATEWAY_NOT_FOUND", from_mod);
@ -976,7 +976,7 @@ void CQnetLink::g2link(const char from_mod, const char *call, const char to_mod)
return;
}
void CQnetLink::ProcessXRF(unsigned char *buf, const int length)
void CQnetLink::ProcessXRF(uint8_t *buf, const int length)
{
const std::string ip(fromDst4.GetAddress());
char call[CALL_SIZE + 1];
@ -1566,7 +1566,7 @@ void CQnetLink::ProcessXRF(unsigned char *buf, const int length)
}
else if (to_remote_g2[i].addr.GetPort() == rmt_dcs_port)
{
unsigned char dcs_buf[1000];
uint8_t dcs_buf[1000];
memset(dcs_buf, 0x00, 600);
dcs_buf[0] = dcs_buf[1] = dcs_buf[2] = '0';
dcs_buf[3] = '1';
@ -1605,7 +1605,7 @@ void CQnetLink::ProcessXRF(unsigned char *buf, const int length)
}
}
void CQnetLink::ProcessDCS(unsigned char *dcs_buf, const int length)
void CQnetLink::ProcessDCS(uint8_t *dcs_buf, const int length)
{
const std::string ip(fromDst4.GetAddress());
@ -1859,7 +1859,7 @@ void CQnetLink::ProcessDCS(unsigned char *dcs_buf, const int length)
}
}
void CQnetLink::ProcessREF(unsigned char *buf, const int length)
void CQnetLink::ProcessREF(uint8_t *buf, const int length)
{
const std::string ip(fromDst4.GetAddress());
@ -1868,9 +1868,9 @@ void CQnetLink::ProcessREF(unsigned char *buf, const int length)
/* LH */
if (length==4 && buf[0]==4 && buf[1]==192 && buf[2]==7 && buf[3]==0)
{
unsigned short j_idx = 0;
unsigned short k_idx = 0;
unsigned char tmp[2];
uint16_t j_idx = 0;
uint16_t k_idx = 0;
uint8_t tmp[2];
auto pos = inbound_list.find(ip);
if (pos != inbound_list.end())
@ -1959,11 +1959,11 @@ void CQnetLink::ProcessREF(unsigned char *buf, const int length)
{
if (log_debug)
printf("Got a linked repeater request!\n");
unsigned short i_idx = 0;
unsigned short j_idx = 0;
unsigned short k_idx = 0;
unsigned char tmp[2];
unsigned short total = 0;
uint16_t i_idx = 0;
uint16_t j_idx = 0;
uint16_t k_idx = 0;
uint8_t tmp[2];
uint16_t total = 0;
auto pos = inbound_list.find(ip);
if (pos != inbound_list.end())
@ -2052,11 +2052,11 @@ void CQnetLink::ProcessREF(unsigned char *buf, const int length)
{
if (log_debug)
printf("Got a linked dongle request!!\n");
unsigned short i_idx = 0;
unsigned short j_idx = 0;
unsigned short k_idx = 0;
unsigned char tmp[2];
unsigned short total = 0;
uint16_t i_idx = 0;
uint16_t j_idx = 0;
uint16_t k_idx = 0;
uint8_t tmp[2];
uint16_t total = 0;
auto pos = inbound_list.find(ip);
if (pos != inbound_list.end())
@ -2667,7 +2667,7 @@ void CQnetLink::ProcessREF(unsigned char *buf, const int length)
REFWrite(rdsvt.head, rdsvt.head[0], to_remote_g2[i].addr);
else if (to_remote_g2[i].addr.GetPort() == rmt_dcs_port)
{
unsigned char dcs_buf[600];
uint8_t dcs_buf[600];
memset(dcs_buf, 0x00, 600);
dcs_buf[0] = dcs_buf[1] = dcs_buf[2] = '0';
dcs_buf[3] = '1';
@ -2791,7 +2791,7 @@ void CQnetLink::Run()
keep_running = false;
}
unsigned char buffer[1000];
uint8_t buffer[1000];
if (keep_running && FD_ISSET(XRFSock4.GetSocket(), &fdset))
{
socklen_t fromlen = sizeof(struct sockaddr_storage);
@ -2845,7 +2845,7 @@ void CQnetLink::Run()
if (keep_running && FD_ISSET(FromGate.GetFD(), &fdset))
{
unsigned char your[3] = { 'C', 'C', 'C' };
uint8_t your[3] = { 'C', 'C', 'C' };
SDSVT dsvt;
int length = FromGate.Read(dsvt.title, 56);
@ -3264,7 +3264,7 @@ void CQnetLink::Run()
}
else if (to_remote_g2[i].addr.GetPort() == rmt_dcs_port)
{
unsigned char dcs_buf[600];
uint8_t dcs_buf[600];
memset(dcs_buf, 0x0, 600);
dcs_buf[0] = dcs_buf[1] = dcs_buf[2] = '0';
dcs_buf[3] = '1';
@ -3503,14 +3503,14 @@ void CQnetLink::AudioNotifyThread(SECHO &edata)
edata.header.config = 0x20U;
int count;
const unsigned char sdsync[3] = { 0x55U, 0x2DU, 0x16U };
const unsigned char sdsilence[3] = { 0x16U, 0x29U, 0xF5U };
const uint8_t sdsync[3] = { 0x55U, 0x2DU, 0x16U };
const uint8_t sdsilence[3] = { 0x16U, 0x29U, 0xF5U };
for (count=0; count<ambeblocks && keep_running; count++)
{
int nread = fread(edata.header.vasd.voice, 9, 1, fp);
if (nread == 1)
{
edata.header.ctrl = (unsigned char)(count % 21);
edata.header.ctrl = (uint8_t)(count % 21);
if (0x0U == edata.header.ctrl)
{
memcpy(edata.header.vasd.text, sdsync, 3);

@ -46,7 +46,7 @@
using SREFDSVT = struct refdsvt_tag
{
unsigned char head[2];
uint8_t head[2];
SDSVT dsvt;
};
@ -55,10 +55,10 @@ using STOREMOTE = struct to_remote_g2_tag
char cs[CALL_SIZE + 1];
CSockAddress addr;
char from_mod, to_mod;
short countdown;
int16_t countdown;
bool auto_link, is_connected;
unsigned short in_streamid; // incoming from remote systems
unsigned short out_streamid; // outgoing to remote systems
uint16_t in_streamid; // incoming from remote systems
uint16_t out_streamid; // outgoing to remote systems
};
// This is the data payload in the map: inbound_list
@ -67,14 +67,14 @@ using SINBOUND = struct inbound_tag
{
char call[CALL_SIZE + 1]; // the callsign of the remote
CSockAddress addr; // IP and port of remote
short countdown; // if countdown expires, the connection is terminated
int16_t countdown; // if countdown expires, the connection is terminated
char mod; // A B C This user talked on this module
char client; // dvap, dvdongle
};
using STRACING = struct tracing_tag
{
unsigned short streamid;
uint16_t streamid;
time_t last_time; // last time RF user talked
};
@ -94,20 +94,20 @@ private:
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);
void LoadGateways(const std::string &filename);
void calcPFCS(unsigned char *packet, int len);
void calcPFCS(uint8_t *packet, int len);
bool ReadConfig(const std::string &path);
bool srv_open();
void srv_close();
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);
bool resolve_rmt(const char *name, const uint16_t port, CSockAddress &addr);
void rptr_ack(int i);
void PlayAudioNotifyThread(char *msg);
void AudioNotifyThread(SECHO &edata);
void RptrAckThread(char *arg);
void ProcessXRF(unsigned char *buf, const int length);
void ProcessDCS(unsigned char *buf, const int length);
void ProcessREF(unsigned char *buf, const int length);
void ProcessXRF(uint8_t *buf, const int length);
void ProcessDCS(uint8_t *buf, const int length);
void ProcessREF(uint8_t *buf, const int length);
void REFWrite(const void *buf, const size_t size, const CSockAddress &addr);
void DCSWrite(const void *buf, const size_t size, const CSockAddress &addr);
void XRFWrite(const void *buf, const size_t size, const CSockAddress &addr);
@ -116,12 +116,12 @@ private:
std::string login_call, owner, to_g2_external_ip, gwys, qnvoice_file, announce_dir;
bool only_admin_login, only_link_unlink, qso_details, log_debug, bool_rptr_ack, announce;
bool dplus_authorize, dplus_reflectors, dplus_repeaters, dplus_priority, uses_ipv6;
unsigned short rmt_xrf_port, rmt_ref_port, rmt_dcs_port, my_g2_link_port, to_g2_external_port;
uint16_t rmt_xrf_port, rmt_ref_port, rmt_dcs_port, my_g2_link_port, to_g2_external_port;
int delay_between, delay_before;
std::string link_at_startup[3];
unsigned int max_dongles, saved_max_dongles;
int rf_inactivity_timer[3];
const unsigned char REF_ACK[3] = { 3, 96, 0 };
const uint8_t REF_ACK[3] = { 3, 96, 0 };
// the Key in this inbound_list map is the unique IP address of the remote
std::map<std::string, SINBOUND *> inbound_list;
@ -137,20 +137,20 @@ private:
// broadcast for data arriving from xrf to local rptr
struct brd_from_xrf_tag
{
unsigned short xrf_streamid; // streamid from xrf
unsigned short rptr_streamid[2]; // generated streamid to rptr(s)
uint16_t xrf_streamid; // streamid from xrf
uint16_t rptr_streamid[2]; // generated streamid to rptr(s)
} brd_from_xrf;
SDSVT from_xrf_torptr_brd;
short brd_from_xrf_idx;
int16_t brd_from_xrf_idx;
// broadcast for data arriving from local rptr to xrf
struct brd_from_rptr_tag
{
unsigned short from_rptr_streamid;
unsigned short to_rptr_streamid[2];
uint16_t from_rptr_streamid;
uint16_t to_rptr_streamid[2];
} brd_from_rptr;
SDSVT fromrptr_torptr_brd;
short brd_from_rptr_idx;
int16_t brd_from_rptr_idx;
STRACING tracing[3];
@ -168,21 +168,21 @@ private:
// Used to validate incoming donglers
regex_t preg;
unsigned char queryCommand[QUERY_SIZE];
uint8_t queryCommand[QUERY_SIZE];
// START: TEXT crap
char dtmf_mycall[3][CALL_SIZE + 1];
bool new_group[3];
int header_type;
bool GPS_seen[3];
unsigned char tmp_txt[3];
uint8_t tmp_txt[3];
char *p_tmp2;
// END: TEXT crap
// this is used for the "dashboard and qso_details" to avoid processing multiple headers
struct old_sid_tag
{
unsigned short sid;
uint16_t sid;
} old_sid[3];
CRandom Random;
@ -190,9 +190,9 @@ private:
std::vector<unsigned long> speak;
// used for processing loop
const unsigned char endbytes[6] = { 0x55U, 0x55U, 0x55U, 0x55U, 0xC8U, 0x7AU };
const uint8_t endbytes[6] = { 0x55U, 0x55U, 0x55U, 0x55U, 0xC8U, 0x7AU };
time_t tnow;
unsigned char dcs_seq[3] = { 0x00, 0x00, 0x00 };
uint8_t dcs_seq[3] = { 0x00, 0x00, 0x00 };
struct
{
char mycall[9];

@ -48,25 +48,25 @@
#define MODEM_VERSION "QnetModem-60706"
#define MAX_RESPONSES 30
const unsigned char FRAME_START = 0xE0U;
const uint8_t FRAME_START = 0xE0U;
const unsigned char TYPE_VERSION = 0x00U;
const unsigned char TYPE_STATUS = 0x01U;
const unsigned char TYPE_CONFIG = 0x02U;
const unsigned char TYPE_MODE = 0x03U;
const unsigned char TYPE_FREQ = 0x04U;
const uint8_t TYPE_VERSION = 0x00U;
const uint8_t TYPE_STATUS = 0x01U;
const uint8_t TYPE_CONFIG = 0x02U;
const uint8_t TYPE_MODE = 0x03U;
const uint8_t TYPE_FREQ = 0x04U;
const unsigned char TYPE_CWID = 0x0AU;
const uint8_t TYPE_CWID = 0x0AU;
const unsigned char TYPE_HEADER = 0x10U;
const unsigned char TYPE_DATA = 0x11U;
const unsigned char TYPE_LOST = 0x12U;
const unsigned char TYPE_EOT = 0x13U;
const uint8_t TYPE_HEADER = 0x10U;
const uint8_t TYPE_DATA = 0x11U;
const uint8_t TYPE_LOST = 0x12U;
const uint8_t TYPE_EOT = 0x13U;
const unsigned char TYPE_ACK = 0x70U;
const unsigned char TYPE_NACK = 0x7FU;
const uint8_t TYPE_ACK = 0x70U;
const uint8_t TYPE_NACK = 0x7FU;
bool CQnetModem::VoicePacketIsSync(const unsigned char *text)
bool CQnetModem::VoicePacketIsSync(const uint8_t *text)
{
return *text==0x55U && *(text+1)==0x2DU && *(text+2)==0x16U;
}
@ -170,7 +170,7 @@ bool CQnetModem::SetFrequency()
frame.length = 12U;
else
{
frame.frequency.level = (unsigned char)RF_LEVEL;
frame.frequency.level = (uint8_t)RF_LEVEL;
frame.frequency.ps = __builtin_bswap32(htonl(pocsagFrequency));
frame.length = 17U;
@ -264,11 +264,11 @@ bool CQnetModem::SetConfiguration()
frame.config.flags |= 0x80U;
frame.config.mode = 0x1U; // Only D-Star is enabled!
frame.config.tx_delay = (unsigned char)(TX_DELAY / 10); // In 10ms units
frame.config.tx_delay = (uint8_t)(TX_DELAY / 10); // In 10ms units
frame.config.init_mode = 0x1U; // yup, just D-Star
frame.config.rx_level = (unsigned char)RX_LEVEL;
frame.config.rx_level = (uint8_t)RX_LEVEL;
frame.config.osc_offset = 128U; // Was OscOffset
frame.config.dstar_tx_level = (unsigned char)TX_LEVEL;
frame.config.dstar_tx_level = (uint8_t)TX_LEVEL;
frame.config.tx_dc_offset = 128U;
frame.config.rx_dc_offset = 128U;
@ -349,7 +349,7 @@ int CQnetModem::OpenModem()
return fd;
}
EModemResponse CQnetModem::GetModemData(unsigned char *buf, unsigned int size)
EModemResponse CQnetModem::GetModemData(uint8_t *buf, unsigned int size)
{
if (size < 4U)
{
@ -421,7 +421,7 @@ EModemResponse CQnetModem::GetModemData(unsigned char *buf, unsigned int size)
while (junk_count)
{
unsigned char junk[8];
uint8_t junk[8];
ret = read(serfd, junk, (junk_count > 8U) ? 8U : junk_count);
if (ret < 0)
{
@ -569,7 +569,7 @@ void CQnetModem::Run()
{
// send queued D-Star frames to modem
CFrame cframe = queue.front();
const unsigned char type = cframe.type();
const uint8_t type = cframe.type();
if ((type==TYPE_HEADER && dstarSpace>3U) || ((type==TYPE_DATA || type==TYPE_EOT || type==TYPE_LOST) && dstarSpace>0U))
{
SendToModem(cframe.data());
@ -596,7 +596,7 @@ void CQnetModem::Close()
FromGate.Close();
}
int CQnetModem::SendToModem(const unsigned char *buf)
int CQnetModem::SendToModem(const uint8_t *buf)
{
ssize_t n;
size_t sent = 0;
@ -643,7 +643,7 @@ void CQnetModem::ProcessGateway(const SDSVT &dsvt)
}
else // write a voice data packet
{
//const unsigned char sdsync[3] = { 0x55U, 0x2DU, 0x16U };
//const uint8_t sdsync[3] = { 0x55U, 0x2DU, 0x16U };
if (dsvt.ctrl & 0x40U)
{
if (LOG_DEBUG && superframe.size())
@ -687,8 +687,8 @@ bool CQnetModem::ProcessModem(const SMODEM &frame)
{
static bool in_stream = false;
static bool first_voice_packet = false;
static short stream_id = 0U;
static unsigned char nextctrl = 21U;
static int16_t stream_id = 0U;
static uint8_t nextctrl = 21U;
// create a stream id if this is a header
if (frame.type == TYPE_HEADER)
@ -730,8 +730,8 @@ bool CQnetModem::ProcessModem(const SMODEM &frame)
}
else if (in_stream && (frame.type==TYPE_DATA || frame.type==TYPE_EOT || frame.type==TYPE_LOST)) // ambe
{
const unsigned char sync[12] = { 0x9EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x55U,0x2DU,0x16U };
const unsigned char silence[12] = { 0x9EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x70U,0x4FU,0x93U };
const uint8_t sync[12] = { 0x9EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x55U,0x2DU,0x16U };
const uint8_t silence[12] = { 0x9EU,0x8DU,0x32U,0x88U,0x26U,0x1AU,0x3FU,0x61U,0xE8U,0x70U,0x4FU,0x93U };
dsvt.config = 0x20U;
if (frame.type == TYPE_DATA)
{

@ -63,18 +63,18 @@ enum class EHardwareType
#pragma pack(push, 1)
using SVERSION = struct version_tag
{
unsigned char start;
unsigned char length;
unsigned char type;
unsigned char protocol;
unsigned char version[251];
uint8_t start;
uint8_t length;
uint8_t type;
uint8_t protocol;
uint8_t version[251];
};
using SMODEM = struct mmodem_tag
{
unsigned char start; // always 0xEOU
unsigned char length; // 3 - 255
unsigned char type;
uint8_t start; // always 0xEOU
uint8_t length; // 3 - 255
uint8_t type;
// 0x70U acknowledge from modem, ACK
// 0x7FU error from modem, NACK
// 0x00U version
@ -88,12 +88,12 @@ using SMODEM = struct mmodem_tag
// 0x13U transmission end
union
{
unsigned char ack; // the type being acknowledged
unsigned char mode; // 0 idle, 1 dstar, 2 dmr, 3 ysf, 99 calibration
uint8_t ack; // the type being acknowledged
uint8_t mode; // 0 idle, 1 dstar, 2 dmr, 3 ysf, 99 calibration
struct
{
unsigned char ack; // the type being acknowledged
unsigned char reason; // reason for the NAK
uint8_t ack; // the type being acknowledged
uint8_t reason; // reason for the NAK
// 1 - invalid command
// 2 - wrong mode
// 3 - command too long
@ -102,62 +102,62 @@ using SMODEM = struct mmodem_tag
} nack;
// don't want to inflate the struct size, so it's here for reference only
//struct {
// unsigned char protocol_version;
// unsigned char version[250];
// uint8_t protocol_version;
// uint8_t version[250];
//} version;
struct
{
unsigned char modes; // 0x1U dstar | 0x2 dmr | 0x4 system fusion
unsigned char status; // 0 idle, 1 dstar, 2 dmr, 3 system fusion, 99 calibration
unsigned char flags; // 0x1 Tx on, 0x2 adc overflow
unsigned char dsrsize; // dstar buffersize
unsigned char dm1size; // drm timeslot 1 buffersize
unsigned char dm2size; // dmr timeslot 2 buffersize
unsigned char ysfsize; // ysf buffersize
uint8_t modes; // 0x1U dstar | 0x2 dmr | 0x4 system fusion
uint8_t status; // 0 idle, 1 dstar, 2 dmr, 3 system fusion, 99 calibration
uint8_t flags; // 0x1 Tx on, 0x2 adc overflow
uint8_t dsrsize; // dstar buffersize
uint8_t dm1size; // drm timeslot 1 buffersize
uint8_t dm2size; // dmr timeslot 2 buffersize
uint8_t ysfsize; // ysf buffersize
} status;
struct
{
unsigned char flags; // 0x1 rx 0x2 tx 0x4 ptt 0x8 ysf lodev 0x10 debug 0x80 not duplex
unsigned char mode; // 0x1 dstar 0x2 drm 0x4 ysf 0x8 p25 0x10 nxdx 0x20 pocsag
unsigned char tx_delay; // tx delay in 10 millisecond increments
unsigned char init_mode; // inital state 0 idle 1 dstar 2 dmr 3 ysf 99 calibration
unsigned char rx_level; // rx input level 0-255
unsigned char cw_tx_level; // cw tx output
unsigned char color; // dmr color 0-15
unsigned char drm_delay;
unsigned char osc_offset; // 128U
unsigned char dstar_tx_level;
unsigned char dmr_tx_level;
unsigned char ysf_tx_level;
unsigned char p25_tx_level;
unsigned char tx_dc_offset;
unsigned char rx_dc_offset;
unsigned char nxdn_tx_level;
unsigned char ysf_tx_hang;
unsigned char pocsag_tx;
uint8_t flags; // 0x1 rx 0x2 tx 0x4 ptt 0x8 ysf lodev 0x10 debug 0x80 not duplex
uint8_t mode; // 0x1 dstar 0x2 drm 0x4 ysf 0x8 p25 0x10 nxdx 0x20 pocsag
uint8_t tx_delay; // tx delay in 10 millisecond increments
uint8_t init_mode; // inital state 0 idle 1 dstar 2 dmr 3 ysf 99 calibration
uint8_t rx_level; // rx input level 0-255
uint8_t cw_tx_level; // cw tx output
uint8_t color; // dmr color 0-15
uint8_t drm_delay;
uint8_t osc_offset; // 128U
uint8_t dstar_tx_level;
uint8_t dmr_tx_level;
uint8_t ysf_tx_level;
uint8_t p25_tx_level;
uint8_t tx_dc_offset;
uint8_t rx_dc_offset;
uint8_t nxdn_tx_level;
uint8_t ysf_tx_hang;
uint8_t pocsag_tx;
} config;
struct
{
unsigned char zero; // should be zero;
uint8_t zero; // should be zero;
uint32_t rx; // receive frequency
uint32_t tx; // transmitter frequency
unsigned char level; // rf level
uint8_t level; // rf level
uint32_t ps; // pocsag frequency, default 433000000U
} frequency;
struct
{
unsigned char flag[3];
unsigned char r2[8];
unsigned char r1[8];
unsigned char ur[8];
unsigned char my[8];
unsigned char nm[4];
unsigned char pfcs[2];
uint8_t flag[3];
uint8_t r2[8];
uint8_t r1[8];
uint8_t ur[8];
uint8_t my[8];
uint8_t nm[4];
uint8_t pfcs[2];
} header;
struct
{
unsigned char ambe[9];
unsigned char text[3];
uint8_t ambe[9];
uint8_t text[3];
} voice;
};
};
@ -166,7 +166,7 @@ using SMODEM = struct mmodem_tag
class CFrame
{
public:
CFrame(const unsigned char *buf)
CFrame(const uint8_t *buf)
{
memcpy(&frame.start, buf, buf[1]);
}
@ -186,8 +186,8 @@ public:
size_t size() const { return (size_t)frame.length; }
const unsigned char *data() const { return &frame.start; }
unsigned char type() { return frame.type; }
const uint8_t *data() const { return &frame.start; }
uint8_t type() { return frame.type; }
private:
SMODEM frame;
@ -207,12 +207,12 @@ private:
unsigned int dstarSpace;
// functions
bool VoicePacketIsSync(const unsigned char *);
bool VoicePacketIsSync(const uint8_t *);
void ProcessGateway(const SDSVT &dsvt);
bool ProcessModem(const SMODEM &frame);
int OpenModem();
int SendToModem(const unsigned char *buf);
EModemResponse GetModemData(unsigned char *buf, unsigned int size);
int SendToModem(const uint8_t *buf);
EModemResponse GetModemData(uint8_t *buf, unsigned int size);
bool GetVersion();
bool GetBufferSize();
bool SetFrequency();

@ -61,7 +61,7 @@ bool CQnetRelay::Initialize(const std::string &cfgfile)
return false;
}
int CQnetRelay::OpenSocket(const std::string &address, unsigned short port)
int CQnetRelay::OpenSocket(const std::string &address, uint16_t port)
{
if (! port)
{
@ -139,7 +139,7 @@ void CQnetRelay::Run()
continue;
// there is something to read!
unsigned char buf[100];
uint8_t buf[100];
sockaddr_in addr;
memset(&addr, 0, sizeof(sockaddr_in));
socklen_t size = sizeof(sockaddr);
@ -206,7 +206,7 @@ void CQnetRelay::Close()
FromGate.Close();
}
int CQnetRelay::SendTo(const int fd, const unsigned char *buf, const int size, const std::string &address, const unsigned short port)
int CQnetRelay::SendTo(const int fd, const uint8_t *buf, const int size, const std::string &address, const uint16_t port)
{
sockaddr_in addr;
::memset(&addr, 0, sizeof(sockaddr_in));
@ -222,7 +222,7 @@ int CQnetRelay::SendTo(const int fd, const unsigned char *buf, const int size, c
return len;
}
bool CQnetRelay::ProcessGateway(const int len, const unsigned char *raw)
bool CQnetRelay::ProcessGateway(const int len, const uint8_t *raw)
{
if (27==len || 56==len) //here is dstar data
{
@ -290,9 +290,9 @@ bool CQnetRelay::ProcessGateway(const int len, const unsigned char *raw)
return false;
}
bool CQnetRelay::ProcessMMDVM(const int len, const unsigned char *raw)
bool CQnetRelay::ProcessMMDVM(const int len, const uint8_t *raw)
{
static unsigned short id = 0U;
static uint16_t id = 0U;
SDSRP dsrp;
if (len < 65)
::memcpy(dsrp.title, raw, len); // transfer raw data to SDSRP struct
@ -427,9 +427,9 @@ bool CQnetRelay::ReadConfig(const std::string &cfgFile)
int i;
cfg.GetValue(mmdvm_path+"_local_port", type, i, 10000, 65535);
MMDVM_IN_PORT = (unsigned short)i;
MMDVM_IN_PORT = (uint16_t)i;
cfg.GetValue(mmdvm_path+"_gateway_port", type, i, 10000, 65535);
MMDVM_OUT_PORT = (unsigned short)i;
MMDVM_OUT_PORT = (uint16_t)i;
cfg.GetValue(mmdvm_path+"_is_dstarrepeater", type, IS_DSTARREPEATER);
cfg.GetValue("log_qso", estr, log_qso);

@ -40,10 +40,10 @@ public:
private:
// functions
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);
int SendTo(const int fd, const unsigned char *buf, const int size, const std::string &address, const unsigned short port);
bool ProcessGateway(const int len, const uint8_t *raw);
bool ProcessMMDVM(const int len, const uint8_t *raw);
int OpenSocket(const std::string &address, uint16_t port);
int SendTo(const int fd, const uint8_t *buf, const int size, const std::string &address, const uint16_t port);
// read configuration file
bool ReadConfig(const std::string &);
@ -55,11 +55,11 @@ private:
// config data
char RPTR_MOD;
std::string MMDVM_INTERNAL_IP, MMDVM_TARGET_IP;
unsigned short MMDVM_IN_PORT, MMDVM_OUT_PORT;
uint16_t MMDVM_IN_PORT, MMDVM_OUT_PORT;
bool log_qso, IS_DSTARREPEATER;
// parameters
int msock;
unsigned int seed;
unsigned short COUNTER;
uint16_t COUNTER;
};

@ -43,14 +43,14 @@
static int module;
static time_t tNow = 0;
static short streamid_raw = 0;
static int16_t streamid_raw = 0;
static std::string REPEATER, togateway;
static int PLAY_WAIT, PLAY_DELAY;
static unsigned char silence[9] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8 };
static uint8_t silence[9] = { 0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8 };
static unsigned short crc_tabccitt[256] =
static uint16_t 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,
@ -102,23 +102,23 @@ static bool ReadCfgFile()
return false;
}
static void calcPFCS(unsigned char rawbytes[56])
static void calcPFCS(uint8_t rawbytes[56])
{
unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp, short_c;
short int i;
uint16_t crc_dstar_ffff = 0xffff;
uint16_t tmp, short_c;
int16_t i;
for (i = 15; i < 54 ; i++)
{
short_c = 0x00ff & (unsigned short)rawbytes[i];
short_c = 0x00ff & (uint16_t)rawbytes[i];
tmp = (crc_dstar_ffff & 0x00ff) ^ short_c;
crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp];
}
crc_dstar_ffff = ~crc_dstar_ffff;
tmp = crc_dstar_ffff;
rawbytes[54] = (unsigned char)(crc_dstar_ffff & 0xff);
rawbytes[55] = (unsigned char)((tmp >> 8) & 0xff);
rawbytes[54] = (uint8_t)(crc_dstar_ffff & 0xff);
rawbytes[55] = (uint8_t)((tmp >> 8) & 0xff);
return;
}

@ -21,49 +21,49 @@
#pragma pack(push, 1) // used internally by Icom stacks
using SDSTR = struct dstr_tag
{
unsigned char pkt_id[4]; // 0 "DSTR"
unsigned short counter; // 4
unsigned char flag[3]; // 6 { 0x73, 0x12, 0x00 }
unsigned char remaining; // 9 the number of bytes left in the packet
uint8_t pkt_id[4]; // 0 "DSTR"
uint16_t counter; // 4
uint8_t flag[3]; // 6 { 0x73, 0x12, 0x00 }
uint8_t remaining; // 9 the number of bytes left in the packet
union
{
struct
{
unsigned char mycall[8]; // 10
unsigned char rpt[8]; // 18
uint8_t mycall[8]; // 10
uint8_t rpt[8]; // 18
} spkt; // total 26
struct
{
unsigned char icm_id; // 10
unsigned char dst_rptr_id; // 11
unsigned char snd_rptr_id; // 12
unsigned char snd_term_id; // 13
unsigned short streamid; // 14
unsigned char ctrl; // 16 sequence number hdr=0, voice%21, end|=0x40
uint8_t icm_id; // 10
uint8_t dst_rptr_id; // 11
uint8_t snd_rptr_id; // 12
uint8_t snd_term_id; // 13
uint16_t streamid; // 14
uint8_t ctrl; // 16 sequence number hdr=0, voice%21, end|=0x40
union
{
struct
{
unsigned char flag[3]; // 17
unsigned char r2[8]; // 20
unsigned char r1[8]; // 28
unsigned char ur[8]; // 36
unsigned char my[8]; // 44
unsigned char nm[4]; // 52
unsigned char pfcs[2]; // 56
uint8_t flag[3]; // 17
uint8_t r2[8]; // 20
uint8_t r1[8]; // 28
uint8_t ur[8]; // 36
uint8_t my[8]; // 44
uint8_t nm[4]; // 52
uint8_t pfcs[2]; // 56
} hdr; // total 58
union
{
struct
{
unsigned char voice[9]; // 17
unsigned char text[3]; // 26
uint8_t voice[9]; // 17
uint8_t text[3]; // 26
} vasd; // total 29
struct
{
unsigned char UNKNOWN[3]; // 17 not sure what this is, but g2_ doesn't seem to need it
unsigned char voice[9]; // 20
unsigned char text[3]; // 29
uint8_t UNKNOWN[3]; // 17 not sure what this is, but g2_ doesn't seem to need it
uint8_t voice[9]; // 20
uint8_t text[3]; // 29
} vasd1; // total 32
};
};
@ -76,34 +76,34 @@ using SDSTR = struct dstr_tag
#pragma pack(push, 1)
using SDSVT = struct dsvt_tag
{
unsigned char title[4]; // 0 "DSVT"
unsigned char config; // 4 0x10 is hdr 0x20 is vasd
unsigned char flaga[3]; // 5 zeros
unsigned char id; // 8 0x20
unsigned char flagb[3]; // 9 0x0 0x1 (A:0x3 B:0x1 C:0x2)
unsigned short streamid;// 12
unsigned char ctrl; // 14 hdr: 0x80 vsad: framecounter (mod 21)
uint8_t title[4]; // 0 "DSVT"
uint8_t config; // 4 0x10 is hdr 0x20 is vasd
uint8_t flaga[3]; // 5 zeros
uint8_t id; // 8 0x20
uint8_t flagb[3]; // 9 0x0 0x1 (A:0x3 B:0x1 C:0x2)
uint16_t streamid;// 12
uint8_t ctrl; // 14 hdr: 0x80 vsad: framecounter (mod 21)
union
{
struct // index
{
unsigned char flag[3]; // 15
unsigned char rpt1[8]; // 18
unsigned char rpt2[8]; // 26
unsigned char urcall[8];// 34
unsigned char mycall[8];// 42
unsigned char sfx[4]; // 50
unsigned char pfcs[2]; // 54
uint8_t flag[3]; // 15
uint8_t rpt1[8]; // 18
uint8_t rpt2[8]; // 26
uint8_t urcall[8];// 34
uint8_t mycall[8];// 42
uint8_t sfx[4]; // 50
uint8_t pfcs[2]; // 54
} hdr; // total 56
struct
{
unsigned char voice[9]; // 15
unsigned char text[3]; // 24
uint8_t voice[9]; // 15
uint8_t text[3]; // 24
} vasd; // voice and slow data total 27
struct
{
unsigned char voice[9]; // 15
unsigned char textend[6]; // 24
uint8_t voice[9]; // 15
uint8_t textend[6]; // 24
} vend; // voice and end seq total 32 (for DPlus)
};
};
@ -113,42 +113,42 @@ using SDSVT = struct dsvt_tag
#pragma pack(push, 1)
using SDSRP = struct dsrp_tag // offset size
{
unsigned char title[4]; // "DSRP" 0
unsigned char tag; // Poll : 0xA 4
uint8_t title[4]; // "DSRP" 0
uint8_t tag; // Poll : 0xA 4
// Header : busy ? 0x22 : 0x20
// Voice : busy ? 0x23 : 0x21
union
{
unsigned char poll_msg[59]; // space for text 5 variable, max is 64, including trailing null
uint8_t poll_msg[59]; // space for text 5 variable, max is 64, including trailing null
struct
{
unsigned short id; // random id number 5
unsigned char seq; // 0x0 7
unsigned char flag[3]; // 0x80 Dstar Data 8
uint16_t id; // random id number 5
uint8_t seq; // 0x0 7
uint8_t flag[3]; // 0x80 Dstar Data 8
// 0x40 Dstar Repeater
// 0x01 Dstar Relay Unavailable
unsigned char r2[8]; // Repeater 2 11
unsigned char r1[8]; // Repeater 1 19
unsigned char ur[8]; // Your Call 27
unsigned char my[8]; // My Call 35
unsigned char nm[4]; // Name 43
unsigned char pfcs[2]; // checksum 47 49
uint8_t r2[8]; // Repeater 2 11
uint8_t r1[8]; // Repeater 1 19
uint8_t ur[8]; // Your Call 27
uint8_t my[8]; // My Call 35
uint8_t nm[4]; // Name 43
uint8_t pfcs[2]; // checksum 47 49
} header;
struct
{
unsigned short id; // random id number 5
unsigned char seq; // sequence from 0 to 0x14 7
uint16_t id; // random id number 5
uint8_t seq; // sequence from 0 to 0x14 7
// if end then sequence |= 0x40
unsigned char err; // # of errors? 8
unsigned char ambe[12]; // voice + slow data 9 21
uint8_t err; // # of errors? 8
uint8_t ambe[12]; // voice + slow data 9 21
} voice;
struct
{
unsigned short id; // random id number 5
unsigned char seq; // sequence from 0 to 0x14 7
uint16_t id; // random id number 5
uint8_t seq; // sequence from 0 to 0x14 7
// if end then sequence |= 0x40
unsigned char err; // # of errors? 8
unsigned char ambe[15]; // voice + slow data 9 24
uint8_t err; // # of errors? 8
uint8_t ambe[15]; // voice + slow data 9 24
} endvoice;
};
};

@ -28,9 +28,9 @@ public:
~CRandom() {}
unsigned short NewStreamID()
uint16_t NewStreamID()
{
unsigned short r = 0;
uint16_t r = 0;
while (0 == r)
r = 0xffffU & random();
return r;

@ -25,7 +25,7 @@ using SECHO = struct echo_tag
{
bool is_linked;
time_t last_time;
unsigned short streamid;
uint16_t streamid;
int fd;
char message[24];
SDSVT header; // only used in qnlink (qngateway writes the header to the file)

@ -33,7 +33,7 @@ public:
Clear();
}
CSockAddress(const int family, const unsigned short port = 0, const char *address = NULL)
CSockAddress(const int family, const uint16_t port = 0, const char *address = NULL)
{
Initialize(family, port, address);
}
@ -192,7 +192,7 @@ public:
return addr.ss_family;
}
unsigned short GetPort() const
uint16_t GetPort() const
{
if (AF_INET == addr.ss_family)
{

@ -1,6 +1,6 @@
/*
* Copyright (C) 2010-2013 by Jonathan Naylor G4KLX
* Copyright (C) 2019 by Thomas A. Early N7TAE
* Copyright (C) 2019,2026 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
@ -23,69 +23,49 @@
#include <cassert>
#include <cstring>
CTCPReaderWriterClient::CTCPReaderWriterClient(const std::string &address, int family, const std::string &port) :
m_address(address),
m_family(family),
m_port(port),
m_fd(-1)
{
}
CTCPReaderWriterClient::CTCPReaderWriterClient() : m_fd(-1)
{
}
CTCPReaderWriterClient::~CTCPReaderWriterClient()
{
}
bool CTCPReaderWriterClient::Open(const std::string &address, int family, const std::string &port)
bool CTCPReaderWriterClient::Open(const std::string &address, int family, const std::string &port, const bool debug)
{
const char *where { "TCP Open ERROR:" };
m_address = address;
m_family = family;
m_port = port;
return Open();
}
bool CTCPReaderWriterClient::Open()
{
if (m_fd != -1)
{
fprintf(stderr, "ERROR: port for '%s' is already open!\n", m_address.c_str());
fprintf(stderr, "%s port for '%s' is already open!\n", where, m_address.c_str());
return true;
}
if (0 == m_address.size() || 0 == m_port.size() || 0 == std::stoul(m_port))
{
fprintf(stderr, "ERROR: '[%s]:%s' is malformed!\n", m_address.c_str(), m_port.c_str());
fprintf(stderr, "%s '[%s]:%s' is malformed!\n", where, m_address.c_str(), m_port.c_str());
return true;
}
if (AF_INET!=m_family && AF_INET6!=m_family && AF_UNSPEC!=m_family)
if (AF_INET!=family and AF_INET6!=family and AF_UNSPEC!=family)
{
fprintf(stderr, "ERROR: family must be AF_INET, AF_INET6 or AF_UNSPEC\n");
fprintf(stderr, "%s family must be AF_INET, AF_INET6 or AF_UNSPEC\n", where);
return true;
}
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = m_family;
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
//hints.ai_flags = AI_PASSIVE;
hints.ai_protocol = IPPROTO_TCP;
struct addrinfo *res;
int s = EAI_AGAIN;
int count = 0;
while (EAI_AGAIN==s and count++<20)
while (s and count++<20)
{
// connecting to a server, so we can wait until it's ready
s = getaddrinfo(m_address.c_str(), m_port.c_str(), &hints, &res);
if (s && s != EAI_AGAIN)
{
fprintf(stderr, "ERROR: getaddrinfo of %s: %s\n", m_address.c_str(), gai_strerror(s));
fprintf(stderr, "%s getaddrinfo of %s: %s\n", where, m_address.c_str(), gai_strerror(s));
return true;
}
std::this_thread::sleep_for(std::chrono::seconds(3));
@ -93,7 +73,7 @@ bool CTCPReaderWriterClient::Open()
if (EAI_AGAIN == s)
{
fprintf(stderr, "ERROR getaddrinfo of %s failed 20 times\n", m_address.c_str());
fprintf(stderr, "%s getaddrinfo of %s failed 20 times\n", where, m_address.c_str());
return true;
}
@ -102,10 +82,21 @@ bool CTCPReaderWriterClient::Open()
{
m_fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (m_fd == -1)
{
if (debug) fprintf(stderr, "%s socket() error - %s\n", where, strerror(errno));
continue;
}
int flag = 1;
if (setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)))
{
if (debug) fprintf(stderr, "%s setsockopt(TCP_NODELAY) - %s\n", where, strerror(errno));
Close();
continue;
}
if (connect(m_fd, rp->ai_addr, rp->ai_addrlen))
{
if (debug) fprintf(stderr, "%s connect() - %s\n", where, strerror(errno));
Close();
continue;
}
@ -124,7 +115,7 @@ bool CTCPReaderWriterClient::Open()
addr = &(addr6->sin6_addr);
}
if (inet_ntop(rp->ai_family, addr, buf, INET6_ADDRSTRLEN))
fprintf(stderr, "Successfully connected to %s at [%s]:%s\n", m_address.c_str(), buf, m_port.c_str());
printf("Successfully connected to %s at [%s]:%s\n", m_address.c_str(), buf, m_port.c_str());
break;
}
}
@ -132,7 +123,7 @@ bool CTCPReaderWriterClient::Open()
if (rp == NULL)
{
fprintf(stderr, "Could not connect to any system returned by %s\n", m_address.c_str());
fprintf(stderr, "%s Could not connect to %s\n", where, m_address.c_str());
m_fd = -1;
return true;
}
@ -140,24 +131,22 @@ bool CTCPReaderWriterClient::Open()
return false;
}
int CTCPReaderWriterClient::ReadExact(unsigned char *buf, const unsigned int length)
int CTCPReaderWriterClient::ReadExact(uint8_t *buf, const unsigned int length)
{
unsigned int offset = 0U;
unsigned int read = 0U;
do
{
int n = Read(buf + offset, length - offset);
if (n < 0)
do {
int n = Read(buf + read, length - read);
if (n < 1)
return n;
offset += n;
}
while ((length - offset) > 0U);
read += n;
} while ((length - read) > 0U);
return length;
}
int CTCPReaderWriterClient::Read(unsigned char* buffer, const unsigned int length)
int CTCPReaderWriterClient::Read(uint8_t* buffer, const unsigned int length)
{
assert(buffer != NULL);
assert(length > 0U);
@ -167,68 +156,58 @@ int CTCPReaderWriterClient::Read(unsigned char* buffer, const unsigned int lengt
if (len <= 0)
{
if (len < 0)
fprintf(stderr, "Error returned from recv, err=%d\n", errno);
fprintf(stderr, "TCP Read() ERROR: %s\n", strerror(errno));
else
fprintf(stderr, "TCP Read() ERROR: Port closed by server\n");
return -1;
}
return len;
}
int CTCPReaderWriterClient::ReadLine(std::string& line)
bool CTCPReaderWriterClient::ReadLine(std::string& line)
{
unsigned char c;
int resultCode;
int len = 0;
line = "";
do
{
resultCode = Read(&c, 1);
if(resultCode == 1)
{
uint8_t c;
int rtv;
if (line.size())
line.clear();
do {
rtv = Read(&c, 1);
if (('\r' != c) and ('\n' != c) and (rtv == 1))
line += c;
len++;
}
}
while(c != '\n' && resultCode == 1);
} while(c != '\n' and rtv == 1);
return resultCode <= 0 ? resultCode : len;
return (rtv <= 0) ? true : false;
}
bool CTCPReaderWriterClient::Write(const unsigned char *buffer, const unsigned int length)
bool CTCPReaderWriterClient::Write(const void *pvoid, const unsigned int length)
{
assert(buffer != NULL);
assert(pvoid != NULL);
assert(length > 0U);
assert(m_fd != -1);
unsigned int wrote = 0;
uint8_t *buffer = (uint8_t *)pvoid;
ssize_t ret = send(m_fd, (char *)buffer, length, 0);
if (ret != ssize_t(length))
{
if (ret < 0)
fprintf(stderr, "Error returned from send, err=%s\n", strerror(errno));
else
fprintf(stderr, "Error only wrote %d of %d bytes\n", int(ret), int(length));
return true;
while (wrote < length) {
ssize_t ret = send(m_fd, buffer+wrote, length-wrote, 0);
if (ret <= 0)
{
if (ret < 0)
fprintf(stderr, "ERROR - TCP Write send(): %s\n", strerror(errno));
else
fprintf(stderr, "ERROR - TCP Write: port closed by server\n");
return true;
}
wrote += ret;
}
return false;
}
bool CTCPReaderWriterClient::WriteLine(const std::string& line)
bool CTCPReaderWriterClient::WriteLine(std::string& line)
{
std::string lineCopy(line);
if(lineCopy.size() > 0 && lineCopy.at(lineCopy.size() - 1) != '\n')
lineCopy.append("\n");
size_t len = lineCopy.size();
bool result = true;
for(size_t i = 0; i < len && result; i++)
{
unsigned char c = lineCopy.at(i);
result = Write(&c, 1);
}
return result;
line.append("\r\n");
return Write(line.c_str(), line.size());
}
void CTCPReaderWriterClient::Close()

@ -3,7 +3,7 @@
/* end of inma once */
/*
* Copyright (C) 2010,2011,2012,2013 by Jonathan Naylor G4KLX
* Copyright (C) 2019 by Thomas A. Early N7TAE
* Copyright (C) 2019,2026 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
@ -36,25 +36,20 @@
class CTCPReaderWriterClient
{
public:
CTCPReaderWriterClient(const std::string &address, int family, const std::string &port);
CTCPReaderWriterClient();
~CTCPReaderWriterClient();
bool Open(const std::string &address, int family, const std::string &port);
bool Open();
int ReadExact(unsigned char *buffer, const unsigned int length);
int Read(unsigned char *buffer, const unsigned int length);
int ReadLine(std::string &line);
bool Write(const unsigned char* buffer, const unsigned int length);
bool WriteLine(const std::string &line);
bool Open(const std::string &address, int family, const std::string &port, bool debug);
int ReadExact(uint8_t *buffer, const unsigned int length);
int Read(uint8_t *buffer, const unsigned int length);
bool ReadLine(std::string &line);
bool Write(const void* buffer, const unsigned int length);
bool WriteLine(std::string &line);
int GetFD() { return m_fd; }
void Close();
private:
std::string m_address;
int m_family;
std::string m_port;
int m_fd;
};

@ -98,7 +98,7 @@ void CUDPSocket::Close(void)
////////////////////////////////////////////////////////////////////////////////////////
// read
size_t CUDPSocket::Read(unsigned char *buf, const size_t size, CSockAddress &Ip)
size_t CUDPSocket::Read(uint8_t *buf, const size_t size, CSockAddress &Ip)
{
if ( 0 > m_fd )
return 0;

@ -33,9 +33,9 @@ public:
void Close(void);
int GetSocket(void) const { return m_fd; }
unsigned short GetPort() const { return m_addr.GetPort(); }
uint16_t GetPort() const { return m_addr.GetPort(); }
size_t Read(unsigned char *buf, const size_t size, CSockAddress &addr);
size_t Read(uint8_t *buf, const size_t size, CSockAddress &addr);
void Write(const void *buf, const size_t size, const CSockAddress &addr) const;
protected:

@ -1,5 +1,5 @@
/*
* Copyright (C) 2016-2020 by Thomas A. Early N7TAE
* Copyright (C) 2016-2020,2026 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
@ -26,11 +26,19 @@
#include <thread>
#include <chrono>
#include <sstream>
#include "aprs.h"
CAPRS::CAPRS(SRPTR *prptr, bool debug) : m_rptr(prptr), m_debug(debug) {}
CAPRS::~CAPRS()
{
aprs_sock.Close();
}
// This is called when header comes in from repeater
void CAPRS::SelectBand(short int rptr_idx, unsigned short streamID)
void CAPRS::SelectBand(int16_t rptr_idx, uint16_t streamID)
{
if ((rptr_idx < 0) || (rptr_idx > 2))
{
@ -51,15 +59,15 @@ void CAPRS::SelectBand(short int rptr_idx, unsigned short streamID)
// 12 bytes(packet from repeater was 29 bytes) or
// 15 bytes(packet from repeater was 32 bytes)
// Paramter seq is the byte at pos# 16(counting from zero) in the repeater data
void CAPRS::ProcessText(unsigned short streamID, unsigned char seq, unsigned char *buf)
void CAPRS::ProcessText(uint16_t streamID, uint8_t seq, uint8_t *buf)
{
unsigned char aprs_data[200];
uint8_t aprs_data[200];
char aprs_buf[1024];
time_t tnow = 0;
short int rptr_idx = -1;
int16_t rptr_idx = -1;
for (short int i = 0; i < 3; i++)
for (int16_t i = 0; i < 3; i++)
{
if (streamID == aprs_streamID[i].streamID)
{
@ -114,30 +122,13 @@ void CAPRS::ProcessText(unsigned short streamID, unsigned char seq, unsigned cha
p = strchr(aud, '\r');
*p = '\0';
sprintf(aprs_buf, "%s,qAR,%s:%s\r\n", hdr, m_rptr->mod[rptr_idx].call.c_str(), aud);
// printf("GPS-A=%s", aprs_buf);
int rc = aprs_sock.Write((unsigned char *)aprs_buf, strlen(aprs_buf));
if (rc == -1)
{
if ((errno == EPIPE) ||
(errno == ECONNRESET) ||
(errno == ETIMEDOUT) ||
(errno == ECONNABORTED) ||
(errno == ESHUTDOWN) ||
(errno == EHOSTUNREACH) ||
(errno == ENETRESET) ||
(errno == ENETDOWN) ||
(errno == ENETUNREACH) ||
(errno == EHOSTDOWN) ||
(errno == ENOTCONN))
{
printf("CAPRS::ProcessText(): APRS_HOST closed connection, error=%d\n",errno);
aprs_sock.Close();
}
else /* if it is WOULDBLOCK, we will not go into a loop here */
printf("CAPRS::ProcessText(): send error=%d\n", errno);
sprintf(aprs_buf, "%s,qAR,%s:%s", hdr, m_rptr->mod[rptr_idx].call.c_str(), aud);
std::string gpsA(aprs_buf);
if (m_debug)
printf("GPS-A: %s\n", aprs_buf);
if (aprs_sock.WriteLine(gpsA)) {
fprintf(stderr, "ERROR: could not write %s\n", aprs_buf);
}
time(&aprs_streamID[rptr_idx].last_time);
return;
@ -146,17 +137,17 @@ void CAPRS::ProcessText(unsigned short streamID, unsigned char seq, unsigned cha
void CAPRS::Init()
{
/* Initialize the statistics on the APRS packets */
for (short int rptr_idx = 0; rptr_idx < 3; rptr_idx++)
for (int16_t rptr_idx = 0; rptr_idx < 3; rptr_idx++)
{
aprs_pack[rptr_idx].al = al_none;
aprs_pack[rptr_idx].data[0] = '\0';
aprs_pack[rptr_idx].al = EAprsLevel::none;
memset(aprs_pack[rptr_idx].data, 0, sizeof(aprs_pack[rptr_idx].data));
aprs_pack[rptr_idx].len = 0;
aprs_pack[rptr_idx].buf[0] = '\0';
aprs_pack[rptr_idx].sl = sl_first;
memset(aprs_pack[rptr_idx].buf, 0, sizeof(aprs_pack[rptr_idx].buf));
aprs_pack[rptr_idx].sl = ESlowLevel::first;
aprs_pack[rptr_idx].is_sent = false;
}
for (short int i = 0; i < 3; i++)
for (int16_t i = 0; i < 3; i++)
{
aprs_streamID[i].streamID = 0;
aprs_streamID[i].last_time = 0;
@ -165,7 +156,7 @@ void CAPRS::Init()
return;
}
bool CAPRS::WriteData(short int rptr_idx, unsigned char *data)
bool CAPRS::WriteData(int16_t rptr_idx, uint8_t *data)
{
if ((rptr_idx < 0) || (rptr_idx > 2))
@ -179,18 +170,18 @@ bool CAPRS::WriteData(short int rptr_idx, unsigned char *data)
switch (aprs_pack[rptr_idx].sl)
{
case sl_first:
case ESlowLevel::first:
aprs_pack[rptr_idx].buf[0] = data[0] ^ 0x70;
aprs_pack[rptr_idx].buf[1] = data[1] ^ 0x4f;
aprs_pack[rptr_idx].buf[2] = data[2] ^ 0x93;
aprs_pack[rptr_idx].sl = sl_second;
aprs_pack[rptr_idx].sl = ESlowLevel::second;
return false;
case sl_second:
case ESlowLevel::second:
aprs_pack[rptr_idx].buf[3] = data[0] ^ 0x70;
aprs_pack[rptr_idx].buf[4] = data[1] ^ 0x4f;
aprs_pack[rptr_idx].buf[5] = data[2] ^ 0x93;
aprs_pack[rptr_idx].sl = sl_first;
aprs_pack[rptr_idx].sl = ESlowLevel::first;
break;
}
@ -201,7 +192,7 @@ bool CAPRS::WriteData(short int rptr_idx, unsigned char *data)
}
void CAPRS::SyncIt(short int rptr_idx)
void CAPRS::SyncIt(int16_t rptr_idx)
{
if ((rptr_idx < 0) || (rptr_idx > 2))
{
@ -209,11 +200,11 @@ void CAPRS::SyncIt(short int rptr_idx)
return;
}
aprs_pack[rptr_idx].sl = sl_first;
aprs_pack[rptr_idx].sl = ESlowLevel::first;
return;
}
void CAPRS::Reset(short int rptr_idx)
void CAPRS::Reset(int16_t rptr_idx)
{
if ((rptr_idx < 0) || (rptr_idx > 2))
{
@ -221,15 +212,15 @@ void CAPRS::Reset(short int rptr_idx)
return;
}
aprs_pack[rptr_idx].al = al_none;
aprs_pack[rptr_idx].al = EAprsLevel::none;
aprs_pack[rptr_idx].len = 0;
aprs_pack[rptr_idx].sl = sl_first;
aprs_pack[rptr_idx].sl = ESlowLevel::first;
aprs_pack[rptr_idx].is_sent = false;
return;
}
unsigned int CAPRS::GetData(short int rptr_idx, unsigned char *data, unsigned int len)
unsigned int CAPRS::GetData(int16_t rptr_idx, uint8_t *data, unsigned int len)
{
if ((rptr_idx < 0) || (rptr_idx > 2))
{
@ -244,18 +235,16 @@ unsigned int CAPRS::GetData(short int rptr_idx, unsigned char *data, unsigned in
memcpy(data, aprs_pack[rptr_idx].data + 10, l);
aprs_pack[rptr_idx].al = al_none;
aprs_pack[rptr_idx].al = EAprsLevel::none;
aprs_pack[rptr_idx].len = 0;
aprs_pack[rptr_idx].is_sent = true;
return l;
}
void CAPRS::Open(const std::string OWNER)
void CAPRS::Open(const std::string &OWNER, const std::string &NAME)
{
char snd_buf[512];
char rcv_buf[512];
while (aprs_sock.Open(m_rptr->aprs.ip, AF_UNSPEC, std::to_string(m_rptr->aprs.port)))
while (aprs_sock.Open(m_rptr->aprs.ip, AF_UNSPEC, std::to_string(m_rptr->aprs.port), m_debug))
{
fprintf(stderr, "Failed to open %s, retry in 10 seconds...\n", m_rptr->aprs.ip.c_str());
std::this_thread::sleep_for(std::chrono::seconds(10));
@ -263,45 +252,36 @@ void CAPRS::Open(const std::string OWNER)
/* login to aprs */
//sprintf(snd_buf, "user %s pass %d vers QnetGateway 9 UDP 5 ", OWNER.c_str(), m_rptr->aprs_hash);
sprintf(snd_buf, "user %s pass %d vers QnetGateway-9 ", OWNER.c_str(), m_rptr->aprs_hash);
std::stringstream ss;
ss << "user " << OWNER << " pass " << m_rptr->aprs_hash << " version " << NAME;
/* add the user's filter */
if (m_rptr->aprs_filter.length())
{
strcat(snd_buf, "filter ");
strcat(snd_buf, m_rptr->aprs_filter.c_str());
ss << " filter " << m_rptr->aprs_filter;
}
//printf("APRS Login command:[%s]\n", snd_buf);
strcat(snd_buf, "\r\n");
std::string str(ss.str());
if (m_debug)
printf("APRS Login: %s\n", str.c_str());
while (true)
{
int rc = aprs_sock.Write((unsigned char *)snd_buf, strlen(snd_buf));
if (rc < 0)
{
if (errno == EWOULDBLOCK)
{
aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
else
{
printf("APRS Login command failed, error=%d\n", errno);
break;
}
}
else
{
// printf("APRS Login command sent\n");
break;
if (aprs_sock.WriteLine(str)) {
fprintf(stderr, "Could write login into aprs\n");
aprs_sock.Close();
return;
} else { // successfully wrote login packet
if (aprs_sock.ReadLine(str)) {
fprintf(stderr, "Did not receive aprs login ackn\n");
aprs_sock.Close();
return;
} else {
if (m_debug)
printf("APRS Login returned: %s\n", str.c_str());
}
}
aprs_sock.Read((unsigned char *)rcv_buf, sizeof(rcv_buf));
//printf("APRS Login returned: %s", rcv_buf);
return;
}
bool CAPRS::AddData(short int rptr_idx, unsigned char *data)
bool CAPRS::AddData(int16_t rptr_idx, uint8_t *data)
{
if ((rptr_idx < 0) || (rptr_idx > 2))
{
@ -311,109 +291,125 @@ bool CAPRS::AddData(short int rptr_idx, unsigned char *data)
for (unsigned int i = 0; i < 5; i++)
{
unsigned char c = data[i];
uint8_t c = data[i];
if ((aprs_pack[rptr_idx].al == al_none) && (c == '$'))
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_$1;
}
else if ((aprs_pack[rptr_idx].al == al_$1) && (c == '$'))
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_$2;
}
else if ((aprs_pack[rptr_idx].al == al_$2) && (c == 'C'))
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_c1;
}
else if ((aprs_pack[rptr_idx].al == al_c1) && (c == 'R'))
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_r1;
}
else if ((aprs_pack[rptr_idx].al == al_r1) && (c == 'C'))
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_c2;
}
else if (aprs_pack[rptr_idx].al == al_c2)
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_csum1;
}
else if (aprs_pack[rptr_idx].al == al_csum1)
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_csum2;
}
else if (aprs_pack[rptr_idx].al == al_csum2)
switch (aprs_pack[rptr_idx].al)
{
case EAprsLevel::none:
if (c == '$')
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = EAprsLevel::one;
}
break;
case EAprsLevel::one:
if (c == '$')
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = EAprsLevel::two;
}
break;
case EAprsLevel::two:
if (c == 'C')
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = EAprsLevel::c1;
}
break;
case EAprsLevel::c1:
if (c == 'R')
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = EAprsLevel::r1;
}
break;
case EAprsLevel::r1:
if (c == 'C')
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = EAprsLevel::c2;
}
break;
case EAprsLevel::c2:
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_csum3;
}
else if (aprs_pack[rptr_idx].al == al_csum3)
{
aprs_pack[rptr_idx].al = EAprsLevel::csum1;
break;
case EAprsLevel::csum1:
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_csum4;
}
else if ((aprs_pack[rptr_idx].al == al_csum4) && (c == ','))
{
aprs_pack[rptr_idx].al = EAprsLevel::csum2;
break;
case EAprsLevel::csum2:
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = al_data;
}
else if ((aprs_pack[rptr_idx].al == al_data) && (c != '\r'))
{
aprs_pack[rptr_idx].al = EAprsLevel::csum3;
break;
case EAprsLevel::csum3:
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
if (aprs_pack[rptr_idx].len >= 300)
aprs_pack[rptr_idx].al = EAprsLevel::csum4;
break;
case EAprsLevel::csum4:
if (c == ',')
{
printf("ERROR in aprs_add_data: Expected END of APRS data\n");
aprs_pack[rptr_idx].len = 0;
aprs_pack[rptr_idx].al = al_none;
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
aprs_pack[rptr_idx].al = EAprsLevel::data;
}
}
else if ((aprs_pack[rptr_idx].al == al_data) && (c == '\r'))
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
bool ok = CheckData(rptr_idx);
if (ok)
break;
case EAprsLevel::data:
if (c != '\r')
{
aprs_pack[rptr_idx].al = al_end;
return true;
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
if (aprs_pack[rptr_idx].len >= 300)
{
printf("ERROR in aprs_add_data: Expected END of APRS data\n");
aprs_pack[rptr_idx].len = 0;
aprs_pack[rptr_idx].al = EAprsLevel::none;
}
}
break;
case EAprsLevel::end:
if (c == '\r')
{
aprs_pack[rptr_idx].data[aprs_pack[rptr_idx].len] = c;
aprs_pack[rptr_idx].len++;
bool ok = CheckData(rptr_idx);
if (ok)
{
aprs_pack[rptr_idx].al = EAprsLevel::end;
return true;
}
else
{
printf("BAD checksum in APRS data\n");
aprs_pack[rptr_idx].al = EAprsLevel::none;
aprs_pack[rptr_idx].len = 0;
return true;
}
}
else
{
printf("BAD checksum in APRS data\n");
aprs_pack[rptr_idx].al = al_none;
aprs_pack[rptr_idx].al = EAprsLevel::none;
aprs_pack[rptr_idx].len = 0;
}
}
else
{
aprs_pack[rptr_idx].al = al_none;
aprs_pack[rptr_idx].len = 0;
break;
}
}
return false;
}
bool CAPRS::CheckData(short int rptr_idx)
bool CAPRS::CheckData(int16_t rptr_idx)
{
unsigned int my_sum;
char buf[5];
@ -430,7 +426,7 @@ bool CAPRS::CheckData(short int rptr_idx)
return (0 == memcmp(buf, aprs_pack[rptr_idx].data + 5, 4));
}
unsigned int CAPRS::CalcCRC(unsigned char* buf, unsigned int len)
unsigned int CAPRS::CalcCRC(uint8_t* buf, unsigned int len)
{
unsigned int my_crc = 0xffff;
@ -457,18 +453,3 @@ unsigned int CAPRS::CalcCRC(unsigned char* buf, unsigned int len)
}
return (~my_crc & 0xffff);
}
CAPRS::CAPRS(SRPTR *prptr)
{
m_rptr = prptr;
}
CAPRS::~CAPRS()
{
aprs_sock.Close();
}
void CAPRS::CloseSock()
{
aprs_sock.Close();
}

@ -1,7 +1,6 @@
#pragma once
/*
* Copyright (C) 2016 by Thomas A. Early N7TAE
/* Copyright (C) 2016,2026 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
@ -19,6 +18,7 @@
*/
#include <string>
#include <sstream>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
@ -26,9 +26,9 @@
#include "TCPReaderWriterClient.h"
#include "IRCutils.h"
enum aprs_level { al_none, al_$1, al_$2, al_c1, al_r1, al_c2, al_csum1, al_csum2, al_csum3, al_csum4, al_data, al_end };
enum class EAprsLevel { none, one, two, c1, r1, c2, csum1, csum2, csum3, csum4, data, end };
enum slow_level { sl_first, sl_second };
enum class ESlowLevel { first, second };
using SPORTIP = struct portip_tag
{
@ -43,6 +43,7 @@ using SMOD = struct aprs_module
std::string band; /* 23cm ... */
double frequency, offset, latitude, longitude, range, agl;
std::string desc1, desc2, url, package_version;
std::stringstream position_ss;
};
using SRPTR = struct aprs_info
@ -59,41 +60,42 @@ using SRPTR = struct aprs_info
class CAPRS
{
public:
// data
const bool m_debug;
// functions
CAPRS(SRPTR *prptr);
CAPRS(SRPTR *prptr, bool debug);
~CAPRS();
SRPTR *m_rptr;
void SelectBand(short int rptr_idx, unsigned short streamID);
void ProcessText(unsigned short streamID, unsigned char seq, unsigned char *buf);
void Open(const std::string OWNER);
void SelectBand(int16_t rptr_idx, uint16_t streamID);
void ProcessText(uint16_t streamID, uint8_t seq, uint8_t *buf);
void Open(const std::string &OWNER, const std::string &NAME);
void Init();
void CloseSock();
CTCPReaderWriterClient aprs_sock;
private:
// data
struct
{
aprs_level al;
unsigned char data[300];
EAprsLevel al;
uint8_t data[300];
unsigned int len;
unsigned char buf[6];
slow_level sl;
uint8_t buf[6];
ESlowLevel sl;
bool is_sent;
} aprs_pack[3];
// lock down a stream per band
struct
{
unsigned short streamID;
uint16_t streamID;
time_t last_time;
} aprs_streamID[3];
// functions
bool WriteData(short int rptr_idx, unsigned char *data);
void SyncIt(short int rptr_idx);
void Reset(short int rptr_idx);
unsigned int GetData(short int rptr_idx, unsigned char *data, unsigned int len);
bool AddData(short int rptr_idx, unsigned char *data);
bool CheckData(short int rptr_idx);
unsigned int CalcCRC(unsigned char* buf, unsigned int len);
bool WriteData(int16_t rptr_idx, uint8_t *data);
void SyncIt(int16_t rptr_idx);
void Reset(int16_t rptr_idx);
unsigned int GetData(int16_t rptr_idx, uint8_t *data, unsigned int len);
bool AddData(int16_t rptr_idx, uint8_t *data);
bool CheckData(int16_t rptr_idx);
unsigned int CalcCRC(uint8_t* buf, unsigned int len);
};

@ -174,6 +174,7 @@ log_qso_d=false # QSO info goes into the log
log_irc_d=false # IRC debug info
log_dtmf_d=false # DTMF debug info
log_debug_d=false # WARNING, can produce a large number of log entries!
log_aprs_d=false # APRS debug info
##########################################################################################################################
#

@ -8,8 +8,9 @@
#include "IRCutils.h"
#include "IRCDDBApp.h"
IRCClient::IRCClient(IRCDDBApp *app, const std::string &update_channel, const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo)
IRCClient::IRCClient(IRCDDBApp *app, const std::string &update_channel, const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo, bool logirc)
{
logIRC = logirc;
safeStringCopy(host_name, hostName.c_str(), sizeof host_name);
@ -79,7 +80,7 @@ void IRCClient::Entry()
else if (0 == strcmp(host_name, "ircv6.openquad.net"))
fam = AF_INET6;
if (! ircSock.Open(host_name, fam, std::to_string(port)))
if (! ircSock.Open(host_name, fam, std::to_string(port), logIRC))
{
state = 4;
timer = 0;
@ -136,7 +137,7 @@ void IRCClient::Entry()
if (buf[len - 1] == 10) // is there a NL char at the end?
{
if (ircSock.Write((unsigned char *)buf, len))
if (ircSock.Write((uint8_t *)buf, len))
{
printf("IRCClient::Entry: short write\n");

@ -14,7 +14,7 @@ class IRCDDBApp;
class IRCClient
{
public:
IRCClient(IRCDDBApp *app, const std::string &update_channel, const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo);
IRCClient(IRCDDBApp *app, const std::string &update_channel, const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo, bool logirc);
virtual ~IRCClient();
bool startWork();
@ -34,6 +34,7 @@ private:
std::string password;
bool terminateThread;
bool logIRC;
IRCReceiver receiver;
IRCMessageQueue *recvQ;

@ -10,7 +10,7 @@ CIRCDDB::CIRCDDB(const std::string &hostName, unsigned int port, const std::stri
const std::string update_channel("#dstar");
app = new IRCDDBApp(update_channel, &cache, log_irc);
client = new IRCClient(app, update_channel, hostName, port, callsign, password, versionInfo);
client = new IRCClient(app, update_channel, hostName, port, callsign, password, versionInfo, log_irc);
}
CIRCDDB::~CIRCDDB()
@ -57,7 +57,7 @@ void CIRCDDB::kickWatchdog(const std::string &wdInfo)
}
// Send heard data, a false return implies a network error
bool CIRCDDB::sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, unsigned char flag1, unsigned char flag2, unsigned char flag3)
bool CIRCDDB::sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, uint8_t flag1, uint8_t flag2, uint8_t flag3)
{
if (myCall.size() != 8)
{
@ -93,7 +93,7 @@ bool CIRCDDB::sendHeard(const std::string &myCall, const std::string &myCallExt,
}
// Send heard data, a false return implies a network error
bool CIRCDDB::sendHeardWithTXMsg(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, unsigned char flag1, unsigned char flag2, unsigned char flag3, const std::string &network_destination, const std::string &tx_message)
bool CIRCDDB::sendHeardWithTXMsg(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, uint8_t flag1, uint8_t flag2, uint8_t flag3, const std::string &network_destination, const std::string &tx_message)
{
if (myCall.size() != 8)
{
@ -158,8 +158,8 @@ bool CIRCDDB::sendHeardWithTXMsg(const std::string &myCall, const std::string &m
return app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, dest, msg, "");
}
bool CIRCDDB::sendHeardWithTXStats(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3, int num_dv_frames, int num_dv_silent_frames, int num_bit_errors)
bool CIRCDDB::sendHeardWithTXStats(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, uint8_t flag1,
uint8_t flag2, uint8_t flag3, int num_dv_frames, int num_dv_silent_frames, int num_bit_errors)
{
if (num_dv_frames<= 0 || num_dv_frames>65535)
{

@ -69,14 +69,14 @@ public:
// 10 = some network error occured, next state is "0" (new connection attempt)
// Send heard data, a false return implies a network error
bool sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, unsigned char flag1, unsigned char flag2, unsigned char flag3);
bool sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, uint8_t flag1, uint8_t flag2, uint8_t flag3);
// same as sendHeard with two new fields:
// network_destination: empty string or 8-char call sign of the repeater
// or reflector, where this transmission is relayed to.
// tx_message: 20-char TX message or empty string, if the user did not
// send a TX message
bool sendHeardWithTXMsg(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, unsigned char flag1, unsigned char flag2, unsigned char flag3, const std::string &network_destination, const std::string &tx_message);
bool sendHeardWithTXMsg(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, uint8_t flag1, uint8_t flag2, uint8_t flag3, const std::string &network_destination, const std::string &tx_message);
// this method should be called at the end of a transmission
// num_dv_frames: number of DV frames sent out (96 bit frames, 20ms)
@ -88,7 +88,7 @@ public:
// So, the overall bit error rate is calculated like this:
// BER = num_bit_errors / (num_dv_frames * 24)
// Set num_bit_errors = -1, if the error information is not available.
bool sendHeardWithTXStats(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, unsigned char flag1, unsigned char flag2, unsigned char flag3, int num_dv_frames, int num_dv_silent_frames, int num_bit_errors);
bool sendHeardWithTXStats(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, uint8_t flag1, uint8_t flag2, uint8_t flag3, int num_dv_frames, int num_dv_silent_frames, int num_bit_errors);
// The following three functions don't block waiting for a reply, they just send the data

@ -272,7 +272,7 @@ void IRCDDBApp::sendPing(const std::string &to, const std::string &from)
}
}
bool IRCDDBApp::sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, unsigned char flag1, unsigned char flag2, unsigned char flag3, const std::string &destination, const std::string &tx_msg, const std::string &tx_stats)
bool IRCDDBApp::sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, uint8_t flag1, uint8_t flag2, uint8_t flag3, const std::string &destination, const std::string &tx_msg, const std::string &tx_stats)
{
std::string my = myCall;

@ -43,7 +43,7 @@ public:
bool findUser(const std::string &s);
bool sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, unsigned char flag1, unsigned char flag2, unsigned char flag3, const std::string &destination, const std::string &tx_msg, const std::string &tx_stats);
bool sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, const std::string &rpt2, uint8_t flag1, uint8_t flag2, uint8_t flag3, const std::string &destination, const std::string &tx_msg, const std::string &tx_stats);
int getConnectionState();

@ -62,7 +62,7 @@ int IRCReceiver::doRead(CTCPReaderWriterClient *ircSock, char *buf, int buf_size
if (FD_ISSET(fd, &rdset))
{
res = ircSock->Read((unsigned char *)buf, buf_size);
res = ircSock->Read((uint8_t *)buf, buf_size);
if (res < 0)
{

@ -178,6 +178,7 @@ FileMenu () {
fi
echo
echo " Additional entries in log files (in /usr/local/var)"
echo -n "al : APRS logging = "; EvaluateVar log_aprs{,_d}
echo -n "cl : Call(QSO) logging = "; EvaluateVar log_qso{,_d}
echo -n "il : IRC logging = "; EvaluateVar log_irc{,_d}
echo -n "dl : DTMF logging = "; EvaluateVar log_dtmf{,_d}
@ -209,6 +210,7 @@ FileMenu () {
elif [[ "$key" == vf* ]]; then file_qnvoicefile="$value"
elif [[ "$key" == gf* ]]; then file_gwys="$value"
elif [[ "$key" == ad* ]]; then file_announce_dir="$value"
elif [[ "$key" == al* ]]; then SetBooleanValue log_aprs "$value"
elif [[ "$key" == cl* ]]; then SetBooleanValue log_qso "$value"
elif [[ "$key" == il* ]]; then SetBooleanValue log_irc "$value"
elif [[ "$key" == dl* ]]; then SetBooleanValue log_dtmf "$value"
@ -226,6 +228,7 @@ FileMenu () {
elif [[ "$value" == vf* ]]; then unset file_qnvoicefile
elif [[ "$value" == gf* ]]; then unset file_gwys
elif [[ "$value" == ad* ]]; then unset file_announce_dir
elif [[ "$value" == al* ]]; then unset log_aprs
elif [[ "$value" == cl* ]]; then unset log_qso
elif [[ "$value" == il* ]]; then unset log_irc
elif [[ "$value" == dl* ]]; then unset log_dtmf
@ -690,6 +693,7 @@ WriteCFGFile () {
[ -z "${link_acknowledge+x}" ] || echo "link_acknowledge=${link_acknowledge}" >> $outFile
[ -z "${link_max_dongles+x}" ] || echo "link_max_dongles=${link_max_dongles}" >> $outFile
# log_ section
[ -z "${log_aprs+x}" ] || echo "log_aprs=${log_aprs}" >> $outFile
[ -z "${log_qso+x}" ] || echo "log_qso=${log_qso}" >> $outFile
[ -z "${log_irc+x}" ] || echo "log_irc=${log_irc}" >> $outFile
[ -z "${log_dtmf+x}" ] || echo "log_dtmf=${log_dtmf}" >> $outFile

Loading…
Cancel
Save

Powered by TurnKey Linux.