qndvap uses unix sockets

pull/12/head
Tom Early 7 years ago
parent 1549de9d20
commit 20419fa3c5

@ -67,7 +67,7 @@ qnitap : QnetITAP.o Random.o UnixDgramSocket.o
g++ $(CPPFLAGS) -o qnitap QnetITAP.o Random.o $(LDFLAGS)
qndvap : QnetDVAP.o DVAPDongle.o Random.o $(DSTROBJS) UnixDgramSocket.o
g++ $(CPPFLAGS) -o qndvap QnetDVAP.o DVAPDongle.o Random.o $(DSTROBJS) $(LDFLAGS) -pthread
g++ $(CPPFLAGS) -o qndvap QnetDVAP.o DVAPDongle.o Random.o UnixDgramSocket.o $(DSTROBJS) $(LDFLAGS) -pthread
qndvrptr : QnetDVRPTR.o $(DSTROBJS) Random.o UnixDgramSocket.o
g++ $(CPPFLAGS) -o qndvrptr QnetDVRPTR.o Random.o $(DSTROBJS) $(LDFLAGS)

@ -51,6 +51,7 @@ using namespace libconfig;
#include "DVAPDongle.h"
#include "QnetTypeDefs.h"
#include "Random.h"
#include "UnixDgramSocket.h"
#define VERSION DVAP_VERSION
#define CALL_SIZE 8
@ -62,15 +63,17 @@ typedef struct dvap_ack_arg_tag {
float ber;
} SDVAP_ACK_ARG;
// assigned module, must be A, B or C
static int assigned_module;
// unix sockets
static std::string modem2gate("modem2gate"), gate2modem("gate2modem");
static CUnixDgramReader Gate2Modem;
static CUnixDgramWriter Modem2Gate;
/* Default configuration data */
static char RPTR[RPTR_SIZE + 1];
static char OWNER[RPTR_SIZE + 1];
static char RPTR_MOD;
static char RPTR_VIRTUAL_IP[IP_SIZE + 1];
static int RPTR_PORT;
static char G2_INTERNAL_IP[IP_SIZE + 1];
static int G2_PORT;
static char DVP_SERIAL[64]; /* APxxxxxx */
static int DVP_FREQ; /* between 144000000 and 148000000 */
static int DVP_PWR; /* between -12 and 10 */
@ -81,15 +84,12 @@ static int REMOTE_TIMEOUT; /* 1 second */
static int DELAY_BETWEEN;
static int DELAY_BEFORE;
static bool RPTR_ACK;
static char INVALID_YRCALL_KEY[CALL_SIZE + 1];
static int inactiveMax = 25;
/* helper data */
static unsigned char SND_TERM_ID;
static char RPTR_and_G[9];
static char RPTR_and_MOD[9];
static int insock = -1;
static struct sockaddr_in outaddr;
static int serfd = -1;
static bool busy20000 = false;
std::atomic<bool> keep_running(true);
@ -157,7 +157,7 @@ static void sig_catch(int signum)
exit(0);
}
bool get_value(const Config &cfg, const char *path, int &value, int min, int max, int default_value)
static bool get_value(const Config &cfg, const char *path, int &value, int min, int max, int default_value)
{
if (cfg.lookupValue(path, value)) {
if (value < min || value > max)
@ -168,7 +168,7 @@ bool get_value(const Config &cfg, const char *path, int &value, int min, int max
return true;
}
bool get_value(const Config &cfg, const char *path, double &value, double min, double max, double default_value)
static bool get_value(const Config &cfg, const char *path, double &value, double min, double max, double default_value)
{
if (cfg.lookupValue(path, value)) {
if (value < min || value > max)
@ -179,7 +179,7 @@ bool get_value(const Config &cfg, const char *path, double &value, double min, d
return true;
}
bool get_value(const Config &cfg, const char *path, bool &value, bool default_value)
static bool get_value(const Config &cfg, const char *path, bool &value, bool default_value)
{
if (! cfg.lookupValue(path, value))
value = default_value;
@ -187,7 +187,7 @@ bool get_value(const Config &cfg, const char *path, bool &value, bool default_va
return true;
}
bool get_value(const Config &cfg, const char *path, std::string &value, int min, int max, const char *default_value)
static bool get_value(const Config &cfg, const char *path, std::string &value, int min, int max, const char *default_value)
{
if (cfg.lookupValue(path, value)) {
int l = value.length();
@ -204,7 +204,6 @@ bool get_value(const Config &cfg, const char *path, std::string &value, int min,
/* process configuration file */
static int read_config(const char *cfgFile)
{
int i;
Config cfg;
printf("Reading file %s\n", cfgFile);
@ -213,28 +212,32 @@ static int read_config(const char *cfgFile)
cfg.readFile(cfgFile);
}
catch(const FileIOException &fioex) {
printf("Can't read %s\n", cfgFile);
fprintf(stderr, "Can't read %s\n", cfgFile);
return 1;
}
catch(const ParseException &pex) {
printf("Parse error at %s:%d - %s\n", pex.getFile(), pex.getLine(), pex.getError());
fprintf(stderr, "Parse error at %s:%d - %s\n", pex.getFile(), pex.getLine(), pex.getError());
return 1;
}
std::string dvap_path, value;
for (i=0; i<3; i++) {
dvap_path = "module.";
dvap_path += ('a' + i);
if (cfg.lookupValue(dvap_path + ".type", value)) {
if (0 == strcasecmp(value.c_str(), "dvap"))
break;
std::string value;
std::string dvap_path("module.");
dvap_path.append(1, 'a' + assigned_module);
if (cfg.lookupValue(dvap_path + ".type", value)) {
if (value.compare("dvap")) {
fprintf(stderr, "assigned module '%c' type is not 'dvap'\n", 'a' + assigned_module);
return 1;
}
}
if (i >= 3) {
printf("dvap not defined in any module!\n");
} else {
fprintf(stderr, "%s is not defined!\n", dvap_path.c_str());
return 1;
}
RPTR_MOD = 'A' + i;
RPTR_MOD = 'A' + assigned_module;
char unixsockname[16];
snprintf(unixsockname, 16, "gate2modem%d", assigned_module);
get_value(cfg, std::string(dvap_path+".fromgateway").c_str(), gate2modem, 1, FILENAME_MAX, unixsockname);
snprintf(unixsockname, 16, "modem2gate%d", assigned_module);
get_value(cfg, std::string(dvap_path+".togateway").c_str(), modem2gate, 1, FILENAME_MAX, unixsockname);
if (cfg.lookupValue(std::string(dvap_path+".callsign").c_str(), value) || cfg.lookupValue("ircddb.login", value)) {
int l = value.length();
@ -242,7 +245,7 @@ static int read_config(const char *cfgFile)
printf("Call '%s' is invalid length!\n", value.c_str());
return 1;
} else {
for (i=0; i<l; i++) {
for (int i=0; i<l; i++) {
if (islower(value[i]))
value[i] = toupper(value[i]);
}
@ -261,7 +264,7 @@ static int read_config(const char *cfgFile)
printf("Call '%s' is invalid length!\n", value.c_str());
return 1;
} else {
for (i=0; i<l; i++) {
for (int i=0; i<l; i++) {
if (islower(value[i]))
value[i] = toupper(value[i]);
}
@ -274,31 +277,6 @@ static int read_config(const char *cfgFile)
return 1;
}
if (get_value(cfg, std::string(dvap_path+".invalid_prefix").c_str(), value, 1, CALL_SIZE, "XXX")) {
if (islower(value[i]))
value[i] = toupper(value[i]);
value.resize(CALL_SIZE, ' ');
strcpy(INVALID_YRCALL_KEY, value.c_str());
} else
return 1;
if (get_value(cfg, std::string(dvap_path+".internal_ip").c_str(), value, 7, IP_SIZE, "0.0.0.0"))
strcpy(RPTR_VIRTUAL_IP, value.c_str());
else
return 1;
i = 19998 + (RPTR_MOD - 'A');
get_value(cfg, std::string(dvap_path+".port").c_str(), RPTR_PORT, 10000, 65535, i);
if (get_value(cfg, "gateway.ip", value, 7, IP_SIZE, "127.0.0.1"))
strcpy(G2_INTERNAL_IP, value.c_str());
else {
printf("gateway.ip '%s' is invalid!\\n", value.c_str());
return 1;
}
get_value(cfg, "gateway.internal.port", G2_PORT, 10000, 65535, 19000);
if (get_value(cfg, std::string(dvap_path+".serial_number").c_str(), value, 8, 10, "APXXXXXX"))
strcpy(DVP_SERIAL, value.c_str());
else {
@ -337,40 +315,16 @@ static int read_config(const char *cfgFile)
static int open_sock()
{
struct sockaddr_in inaddr;
insock = socket(PF_INET, SOCK_DGRAM, 0);
if (insock == -1) {
printf("Failed to create insock, error=%d, message=%s\n",errno, strerror(errno));
return -1;
}
memset(&inaddr, 0, sizeof(inaddr));
inaddr.sin_family = AF_INET;
inaddr.sin_port = htons(RPTR_PORT);
inaddr.sin_addr.s_addr = inet_addr(RPTR_VIRTUAL_IP);
int rc = bind(insock, (struct sockaddr *)&inaddr, sizeof(inaddr));
if (rc == -1) {
printf("Failed to bind server socket, error=%d, message=%s\n", errno, strerror(errno));
close(insock);
insock = -1;
return -1;
}
fcntl(insock, F_SETFL, O_NONBLOCK);
memset(&outaddr, 0, sizeof(outaddr));
outaddr.sin_family = AF_INET;
outaddr.sin_port = htons(G2_PORT);
outaddr.sin_addr.s_addr = inet_addr(G2_INTERNAL_IP);
if (Gate2Modem.Open(gate2modem.c_str()) || Modem2Gate.Open(modem2gate.c_str()))
return 1;
return 0;
}
static void readFrom20000()
{
int len;
fd_set readfd;
struct timeval tv;
fd_set readfd;
struct timeval tv;
int inactive = 0;
short seq_no = 0;
uint16_t streamid;
@ -390,14 +344,15 @@ static void readFrom20000()
tv.tv_sec = 0;
tv.tv_usec = WAIT_FOR_PACKETS;
FD_ZERO (&readfd);
FD_SET (insock, &readfd);
select(insock + 1, &readfd, NULL, NULL, &tv);
int fd = Gate2Modem.GetFD();
FD_SET (fd, &readfd);
select(fd + 1, &readfd, NULL, NULL, &tv);
if (FD_ISSET(insock, &readfd)) {
len = recv(insock, (char *)&net_buf, 58, 0);
if (FD_ISSET(fd, &readfd)) {
len = Gate2Modem.Read(net_buf.pkt_id, 58);
if (len == 58) {
if (busy20000) {
FD_CLR (insock, &readfd);
FD_CLR (fd, &readfd);
continue;
}
@ -410,7 +365,7 @@ static void readFrom20000()
/* check the module and gateway */
if (net_buf.vpkt.hdr.r1[7] != RPTR_MOD) {
FD_CLR(insock, &readfd);
FD_CLR(fd, &readfd);
break;
}
memcpy(net_buf.vpkt.hdr.r2, OWNER, 7);
@ -433,7 +388,7 @@ static void readFrom20000()
(net_buf.vpkt.hdr.flag[0] != 0x20) &&
(net_buf.vpkt.hdr.flag[0] != 0x28) &&
(net_buf.vpkt.hdr.flag[0] != 0x40)) {
FD_CLR(insock, &readfd);
FD_CLR(fd, &readfd);
break;
}
@ -441,7 +396,7 @@ static void readFrom20000()
(net_buf.flag[0] != 0x73) ||
(net_buf.flag[1] != 0x12) ||
(net_buf.vpkt.icm_id != 0x20)) { /* voice type */
FD_CLR(insock, &readfd);
FD_CLR(fd, &readfd);
break;
}
@ -551,7 +506,7 @@ static void readFrom20000()
streamid = 0;
inactive = 0;
FD_CLR (insock, &readfd);
FD_CLR (fd, &readfd);
// maybe put a sleep here to prevent fast voice-overs
busy20000 = false;
@ -560,16 +515,16 @@ static void readFrom20000()
}
}
} else { // net_buf.vpkt.sreamid != streamid
FD_CLR (insock, &readfd);
FD_CLR (fd, &readfd);
break;
}
} else { // len is not 58 or 29
if (!busy20000) {
FD_CLR (insock, &readfd);
FD_CLR (fd, &readfd);
break;
}
}
FD_CLR (insock, &readfd);
FD_CLR (fd, &readfd);
}
// If we received a dup or select() timed out or streamids dont match,
@ -633,12 +588,33 @@ int main(int argc, const char **argv)
setvbuf(stdout, NULL, _IOLBF, 0);
printf("dvap_rptr VERSION %s\n", VERSION);
if (argc != 2) {
printf("Usage: dvap_rptr dvap_rptr.cfg\n");
if (argc != 3) {
fprintf(stderr, "Usage: %s assigned_module dvap_rptr.cfg\n", argv[0]);
return 1;
}
rc = read_config(argv[1]);
switch (argv[1][0]) {
case '0':
case 'a':
case 'A':
assigned_module = 0;
break;
case '1':
case 'b':
case 'B':
assigned_module = 1;
break;
case '2':
case 'c':
case 'C':
assigned_module = 2;
break;
default:
fprintf(stderr, "ERROR: '%s' is not a valid module\nassigned module must be 0, a, A, 1, b, B, 2, c or C\n", argv[1]);
return 1;
}
rc = read_config(argv[2]);
if (rc != 0) {
printf("Failed to process config file %s\n", argv[1]);
return 1;
@ -724,7 +700,8 @@ int main(int argc, const char **argv)
}
readthread.get();
close(insock);
Gate2Modem.Close();
Modem2Gate.Close();
printf("dvap_rptr exiting\n");
return 0;
}
@ -875,8 +852,6 @@ static void ReadDVAPThread()
short int sequence = 0;
char mycall[8];
short int status_cntr = 3000;
char temp_yrcall[CALL_SIZE + 1];
char *temp_ptr = NULL;
int num_dv_frames = 0;
int num_bit_errors = 0;
@ -917,7 +892,7 @@ static void ReadDVAPThread()
spack.spkt.mycall[7] = 'S';
memcpy(spack.spkt.rpt, OWNER, 7);
spack.spkt.rpt[7] = 'S';
sendto(insock, spack.pkt_id, 26, 0, (struct sockaddr *)&outaddr, sizeof(outaddr));
Modem2Gate.Write(spack.pkt_id, 26);
S_ctrl_msg_time = tnow;
}
@ -966,18 +941,6 @@ static void ReadDVAPThread()
ok = false;
}
/* Reject those stupid STN stations */
if (ok) {
memcpy(temp_yrcall, dr.frame.hdr.urcall, CALL_SIZE);
temp_yrcall[CALL_SIZE] = '\0';
temp_ptr = strstr(temp_yrcall, INVALID_YRCALL_KEY);
if (temp_ptr == temp_yrcall) { // found it at first position
printf("YRCALL value [%s] starts with the INVALID_YRCALL_KEY [%s], resetting to CQCQCQ\n",
temp_yrcall, INVALID_YRCALL_KEY);
memcpy(dr.frame.hdr.urcall, "CQCQCQ ", 8);
}
}
memcpy(&net_buf.vpkt.hdr, dr.frame.hdr.flag, 41); // copy the header, but...
memcpy(net_buf.vpkt.hdr.r1, dr.frame.hdr.rpt1, 8); // swap r1 <--> r2
memcpy(net_buf.vpkt.hdr.r2, dr.frame.hdr.rpt2, 8); // Internet Labs DVAP Dongle Tech. Ref. V 1.01 has it backwards!
@ -1073,7 +1036,7 @@ static void ReadDVAPThread()
memcpy(spack.spkt.mycall, net_buf.vpkt.hdr.my, 8);
memcpy(spack.spkt.rpt, OWNER, 7);
spack.spkt.rpt[7] = RPTR_MOD;
sendto(insock, spack.pkt_id, 26, 0, (struct sockaddr *)&outaddr, sizeof(outaddr));
Modem2Gate.Write(spack.pkt_id, 26);
// Before we send the data to the local gateway,
// set RPT1, RPT2 to be the local gateway
@ -1096,7 +1059,7 @@ static void ReadDVAPThread()
net_buf.vpkt.ctrl = 0x80;
sequence = 0;
calcPFCS((unsigned char *)&(net_buf.vpkt.hdr), net_buf.vpkt.hdr.pfcs);
sendto(insock, &net_buf, 58, 0, (struct sockaddr *)&outaddr, sizeof(outaddr));
Modem2Gate.Write(net_buf.pkt_id, 58);
// local RF user keying up, start timer
dvap_busy = true;
@ -1117,7 +1080,7 @@ static void ReadDVAPThread()
if (the_end)
net_buf.vpkt.ctrl = sequence | 0x40;
memcpy(&net_buf.vpkt.vasd, &dr.frame.vad.voice, 12);
sendto(insock, &net_buf, 29, 0, (struct sockaddr *)&outaddr, sizeof(outaddr));
Modem2Gate.Write(net_buf.pkt_id, 29);
int ber_data[3];
int ber_errs = dstar_dv_decode(net_buf.vpkt.vasd.voice, ber_data);

Loading…
Cancel
Save

Powered by TurnKey Linux.