Compare commits

..

12 Commits

Author SHA1 Message Date
Tom Early f24eac8344 Merge branch 'master' into dev
3 weeks ago
Tom Early f1c4557115 minor update
3 weeks ago
nullobsi f4fcc355bf
fix: only query valid FDs (#21)
11 months ago
Colby Ross 4d8cc8bd9d Move DPlus disconnect debug statement and disconnect packet.
1 year ago
Tom Early 78248cab5f log LINKSTATUS table updates
1 year ago
Colby Ross 91cb2d5ce1 Correct RPT2 sent to linked reflectors.
1 year ago
Tom Early 425e007aa1 added ircddb menu item for Quadnet dual-stack operation
1 year ago
Colby Ross 3e3a4d9c8a
Fix dongle connection bug. (#20)
1 year ago
Tom Early d363e3ce80 README
1 year ago
Tom Early 01df29d053 bumped qnlink version
2 years ago
Tom Early 2e3f3608ad dcs link qndb bug
2 years ago
Tom Early 93c66029ce fixed dashboard install problems
2 years ago

@ -1,5 +1,15 @@
##### DASHBOARD.README ##### ##### DASHBOARD.README #####
--------------------------------------------------------------------------
IMPORTANT!
This document describes how to install a dashboard server based on a php
mini-server and should not be used to publish a QnetGateway dashboard on
the world-wide-web. This mini-server for operating behind a firewall on
a local network. If you need your QnetGateway dashboard on the WWW, install
a real web server, like apache2. The mini-server described here is not
suitable for the WWW!
--------------------------------------------------------------------------
A web-based dashboard can be enabled. The dashboard has several sections A web-based dashboard can be enabled. The dashboard has several sections
that you can display in any order. You can also control the refresh rate and that you can display in any order. You can also control the refresh rate and
how many rows you want in the Last Heard section. You can configure these how many rows you want in the Last Heard section. You can configure these
@ -13,6 +23,10 @@ cp system/qndash.service.80 system/qndash.service
and edit your new file *before* installing the dashboard. and edit your new file *before* installing the dashboard.
You also need several php libraries:
sudo apt install -y php-common php-fpm sqlite3 php-sqlite3 dnsutils
To install the dashboard system, run the following command: To install the dashboard system, run the following command:
sudo make installdash sudo make installdash
@ -53,7 +67,3 @@ The responsive dashboard currently has the following features
hidden, however, simply rotate your mobile device to landscape view and they hidden, however, simply rotate your mobile device to landscape view and they
should appear should appear
* QnRemote section (aka URCall section) has improved design for mobile device use * QnRemote section (aka URCall section) has improved design for mobile device use
Future improvements will be made to
* The layout to respect order of the dash_show_order configuration item
* Misc performance enhancements

@ -30,8 +30,8 @@ public:
private: private:
// functions // functions
long get_syndrome(long pattern); long get_syndrome(long pattern);
long arr2int(int a[], int r); long arr2int(int *a, int r);
void nextcomb(int n, int r, int a[]); void nextcomb(int n, int r, int *a);
int golay2412(int data, int *decoded); int golay2412(int data, int *decoded);
// data // data

@ -99,8 +99,6 @@ installbase : $(BASE_PROGRAMS) gwys.txt qn.cfg
/bin/cp -f qngateway $(BINDIR) /bin/cp -f qngateway $(BINDIR)
/bin/cp -f qnremote qnvoice $(BINDIR) /bin/cp -f qnremote qnvoice $(BINDIR)
/bin/ln -f -s $(shell pwd)/qn.cfg $(CFGDIR) /bin/ln -f -s $(shell pwd)/qn.cfg $(CFGDIR)
/bin/ln -f -s $(shell pwd)/index.php $(WWWDIR)
/bin/ln -f -s $(shell pwd)/dashboardV2 $(WWWDIR)
/bin/cp -f defaults $(CFGDIR) /bin/cp -f defaults $(CFGDIR)
/bin/cp -f system/qngateway.service $(SYSDIR) /bin/cp -f system/qngateway.service $(SYSDIR)
systemctl enable qngateway.service systemctl enable qngateway.service
@ -204,12 +202,9 @@ installdtmf : qndtmf
systemctl start qndtmf.service systemctl start qndtmf.service
installdash : index.php installdash : index.php
/usr/bin/apt update
/usr/bin/apt install -y php-common php-fpm sqlite3 php-sqlite3 dnsutils
mkdir -p $(WWWDIR) mkdir -p $(WWWDIR)
mkdir -p dashboardV2/jsonData /bin/rm -f $(WWWDIR)/*
/bin/ln -f -s $(shell pwd)/index.php $(WWWDIR) /bin/ln -f -s $(shell pwd)/index.php $(shell pwd)/dashboardV2 $(WWWDIR)
/bin/ln -f -s $(shell pwd)/dashboardV2 $(WWWDIR)
if [ ! -e system/qndash.service ]; then cp system/qndash.service.80 system/qndash.service; fi if [ ! -e system/qndash.service ]; then cp system/qndash.service.80 system/qndash.service; fi
/bin/cp -f system/qndash.service $(SYSDIR) /bin/cp -f system/qndash.service $(SYSDIR)
systemctl enable qndash.service systemctl enable qndash.service
@ -328,7 +323,5 @@ uninstalldash :
systemctl disable qndash.service systemctl disable qndash.service
/bin/rm -f $(SYSDIR)/qndash.service /bin/rm -f $(SYSDIR)/qndash.service
systemctl daemon-reload systemctl daemon-reload
/bin/rm -f $(WWWDIR)/index.php /bin/rm -f $(WWWDIR)/*
/bin/rm -f $(WWWDIR)/dashboardV2 /bin/rm -f dashboardV2/jsonData/*.json
/bin/rm -f $(CFGDIR)/qn.db
/bin/rm -rf dashboardV2/jsonData

@ -178,7 +178,7 @@ bool CQnetDB::UpdateLS(const char *address, const char from_mod, const char *to_
return false; return false;
std::stringstream sql; std::stringstream sql;
sql << "INSERT OR REPLACE INTO LINKSTATUS (ip_address, from_mod, to_callsign, to_mod, linked_time) VALUES ('" << address << "', '" << from_mod << "', '" << to_callsign << "', '" << to_mod << "', " << linked_time << ");"; sql << "INSERT OR REPLACE INTO LINKSTATUS (ip_address, from_mod, to_callsign, to_mod, linked_time) VALUES ('" << address << "', '" << from_mod << "', '" << to_callsign << "', '" << to_mod << "', " << linked_time << ");";
printf("%s\n", sql.str().c_str()); // log these updates
char *eMsg; char *eMsg;
if (SQLITE_OK != sqlite3_exec(db, sql.str().c_str(), NULL, 0, &eMsg)) if (SQLITE_OK != sqlite3_exec(db, sql.str().c_str(), NULL, 0, &eMsg))
{ {

@ -2127,7 +2127,7 @@ void CQnetGateway::Run()
// process packets coming from local repeater module(s) // process packets coming from local repeater module(s)
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
if (keep_running && FD_ISSET(FromModem[i].GetFD(), &fdset)) if (keep_running && Rptr.mod[i].defined && FD_ISSET(FromModem[i].GetFD(), &fdset))
{ {
SDSVT dsvt; SDSVT dsvt;
const ssize_t len = FromModem[i].Read(dsvt.title, 56); const ssize_t len = FromModem[i].Read(dsvt.title, 56);

@ -54,7 +54,7 @@
#include "QnetLink.h" #include "QnetLink.h"
#include "Utilities.h" #include "Utilities.h"
#define LINK_VERSION "QnetLink-40411" #define LINK_VERSION "QnetLink-50330"
CQnetLink::CQnetLink() : CBase() CQnetLink::CQnetLink() : CBase()
{ {
@ -1831,7 +1831,7 @@ void CQnetLink::ProcessDCS(unsigned char *dcs_buf, const int length)
to_remote_g2[i].is_connected = true; to_remote_g2[i].is_connected = true;
printf("Connected from: %.*s\n", 8, to_remote_g2[i].cs); printf("Connected from: %.*s\n", 8, to_remote_g2[i].cs);
qnDB.UpdateLS(to_remote_g2[i].addr.GetAddress(), to_remote_g2[i].from_mod, to_remote_g2[i].cs, to_remote_g2[i].from_mod, tracing[i].last_time); qnDB.UpdateLS(to_remote_g2[i].addr.GetAddress(), to_remote_g2[i].from_mod, to_remote_g2[i].cs, to_remote_g2[i].to_mod, tracing[i].last_time);
char linked_remote_system[CALL_SIZE + 1]; char linked_remote_system[CALL_SIZE + 1];
strcpy(linked_remote_system, to_remote_g2[i].cs); strcpy(linked_remote_system, to_remote_g2[i].cs);
@ -2183,15 +2183,15 @@ void CQnetLink::ProcessREF(unsigned char *buf, const int length)
} }
else if (length==5 && buf[0]==5 && buf[1]==0 && buf[2]==24 && buf[3]==0 && buf[4]==0) else if (length==5 && buf[0]==5 && buf[1]==0 && buf[2]==24 && buf[3]==0 && buf[4]==0)
{ {
if (log_debug)
printf("Got a disconnect request!!\n");
/* reply with the same DISCONNECT */
REFWrite(buf, 5, fromDst4);
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
if (fromDst4==to_remote_g2[i].addr && to_remote_g2[i].addr.GetPort()==rmt_ref_port) if (fromDst4==to_remote_g2[i].addr && to_remote_g2[i].addr.GetPort()==rmt_ref_port)
{ {
if (log_debug)
printf("Got a disconnect request!!\n");
/* reply with the same DISCONNECT */
REFWrite(buf, 5, fromDst4);
printf("Call %s disconnected\n", to_remote_g2[i].cs); printf("Call %s disconnected\n", to_remote_g2[i].cs);
to_remote_g2[i].cs[0] = '\0'; to_remote_g2[i].cs[0] = '\0';
@ -2411,7 +2411,7 @@ void CQnetLink::ProcessREF(unsigned char *buf, const int length)
printf("new CALL=%s, DONGLE-p, ip=%s, users=%d\n", inbound->call, ip.c_str(), (int)inbound_list.size()); printf("new CALL=%s, DONGLE-p, ip=%s, users=%d\n", inbound->call, ip.c_str(), (int)inbound_list.size());
buf[0] = 8; buf[0] = 8;
memcpy(buf+4, "OKAY", 4); memcpy(buf+4, "OKRW", 4);
REFWrite(buf, 8, fromDst4); REFWrite(buf, 8, fromDst4);
qnDB.UpdateLS(ip.c_str(), 'p', inbound->call, 'p', time(NULL)); qnDB.UpdateLS(ip.c_str(), 'p', inbound->call, 'p', time(NULL));
@ -3176,8 +3176,8 @@ void CQnetLink::Run()
memcpy(rdsvt.dsvt.hdr.rpt1, to_remote_g2[i].cs, strlen(to_remote_g2[i].cs)); memcpy(rdsvt.dsvt.hdr.rpt1, to_remote_g2[i].cs, strlen(to_remote_g2[i].cs));
rdsvt.dsvt.hdr.rpt1[7] = to_remote_g2[i].to_mod; rdsvt.dsvt.hdr.rpt1[7] = to_remote_g2[i].to_mod;
memset(rdsvt.dsvt.hdr.rpt2, ' ', CALL_SIZE); memset(rdsvt.dsvt.hdr.rpt2, ' ', CALL_SIZE);
memcpy(rdsvt.dsvt.hdr.rpt2, to_remote_g2[i].cs, strlen(to_remote_g2[i].cs)); memcpy(rdsvt.dsvt.hdr.rpt2, owner.c_str(), 7);
rdsvt.dsvt.hdr.rpt2[7] = 'G'; rdsvt.dsvt.hdr.rpt2[7] = dsvt.hdr.rpt1[7];
memcpy(rdsvt.dsvt.hdr.urcall, "CQCQCQ ", CALL_SIZE); memcpy(rdsvt.dsvt.hdr.urcall, "CQCQCQ ", CALL_SIZE);
calcPFCS(rdsvt.dsvt.title, 56); calcPFCS(rdsvt.dsvt.title, 56);

@ -3,12 +3,20 @@ QnetGateway
The QnetGateway is an D-Star IRCDDB gateway application that supports MMDVMHost (and all of its supported repeater modems) as well as the DVAP Dongle, the DVRPTR_V1. It is *incredibly easy* to build and install the system. The QnetGateway is an D-Star IRCDDB gateway application that supports MMDVMHost (and all of its supported repeater modems) as well as the DVAP Dongle, the DVRPTR_V1. It is *incredibly easy* to build and install the system.
QnetGateway now includes a dashboard with a last heard section. The lastheard section uses SQLite3, a light-weight database, so you will need a package to compile the gateway: QnetGateway includes a dashboard with a last heard section. The lastheard section uses SQLite3, a light-weight database, so you will need a package to compile the gateway:
```bash ```
sudo apt install libsqlite3-dev sudo apt install libsqlite3-dev
``` ```
If you are going to install the dashboard, you need several libraries for php:
```
sudo apt install -y php-common php-fpm sqlite3 php-sqlite3 dnsutils
```
Be sure to read the DASHBOARD.README for more information.
QnetGateway is dual-stack capable. This means it can simultaneously connect to ircv4.openquad.net, which is IPv4 based (using 32-bit internet addresses) and to ircv6.openquad.net which is IPv6 based (using 128-bit internet address). If your hot-spot/reapeater has IPv6 access you can enable dual-stack operation (it's IPv4-only by default) and then take advantage of direct world-routable address. The potential benefit of IPv6 to routing is significant. QnetGateway is dual-stack capable. This means it can simultaneously connect to ircv4.openquad.net, which is IPv4 based (using 32-bit internet addresses) and to ircv6.openquad.net which is IPv6 based (using 128-bit internet address). If your hot-spot/reapeater has IPv6 access you can enable dual-stack operation (it's IPv4-only by default) and then take advantage of direct world-routable address. The potential benefit of IPv6 to routing is significant.
The QnetGateway program includes support for Icom's Terminal Mode and Access Point mode. For more information, Terminal Mode turns off the RF portion of you radio and just uses the AMBE vocoder to convert between audio and AMBE data and then sends and receives that data through a USB serial cable. Access Point mode turns your Icom radio into a high power, simplex hot-spot. The QnetGateway program includes support for Icom's Terminal Mode and Access Point mode. For more information, Terminal Mode turns off the RF portion of you radio and just uses the AMBE vocoder to convert between audio and AMBE data and then sends and receives that data through a USB serial cable. Access Point mode turns your Icom radio into a high power, simplex hot-spot.
@ -19,7 +27,7 @@ For building a QnetGateway + MMDVMHost system, see the MMDVM.README file. To bui
To get started with an MMDVM-modem, DVAP, DVRPTR or Icom Terminal and/or Access Point system, clone this software to your Linux device: To get started with an MMDVM-modem, DVAP, DVRPTR or Icom Terminal and/or Access Point system, clone this software to your Linux device:
```bash ```
git clone https://github.com/n7tae/QnetGateway.git git clone https://github.com/n7tae/QnetGateway.git
``` ```
@ -29,18 +37,16 @@ QnetGateway includes a "remote control" program, called `qnremote`. After you bu
For other details of interesting things QnetGatway can do, see the OPERATING file. For example, with QnetGateway, you can execute up to 36 different Linux scripts from you radio. Two scripts are include: For other details of interesting things QnetGatway can do, see the OPERATING file. For example, with QnetGateway, you can execute up to 36 different Linux scripts from you radio. Two scripts are include:
```text ```
YourCall = " HX" will halt your system. YourCall = " HX" will halt your system.
YourCall = " RX" will reboot your system. YourCall = " RX" will reboot your system.
YourCall - " GX" will restart QnetGateway YourCall = " GX" will restart QnetGateway.
``` ```
QnetGateway is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. QnetGateway is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file for more details. QnetGateway is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. QnetGateway is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file for more details.
Many thanks go to **Colby W1BSB**, **Will W4WWM** and **Carty KA2Y** for recent help, suggestions, discussion and criticisms of the Qnet*/MMDVMHost phase of this long-term project! Also thanks to Jonathan G4KLX for MMDVMHost. It gave QnetGateway access to a large number of D-Star compatible modems! Many thanks go to **Colby W1BSB**, **Will W4WWM** and **Carty KA2Y** for recent help, suggestions, discussion and criticisms of the Qnet*/MMDVMHost phase of this long-term project! Also thanks to Jonathan G4KLX for MMDVMHost. It gave QnetGateway access to a large number of D-Star compatible modems!
Finally, QnetGateway is brought to you by the folks at **QuadNet2 USA IRC Network**, but it should work on *any* IRCDDB network.
73 73
Tom Tom

@ -0,0 +1 @@
This folder is for temporary data used by dashboardV2

@ -28,7 +28,7 @@
# This file should not contain any tab characters. Use spaces instead. # This file should not contain any tab characters. Use spaces instead.
# #
# if a definition is commented out, it means that key has no default value. And it is # if a definition is commented out, it means that key has no default value. And it is
# include here just as a reference. The 'ircddb_login' value is requred for every # include here just as a reference. The 'ircddb_login' value is required for every
# configure file # configure file
########################################################################################################################## ##########################################################################################################################
@ -52,7 +52,7 @@ gateway_send_qrgs_maps_d=true # send frequency, offset, coordinates and u
gateway_ip_d='ANY_PORT' # the g2 port gateway_ip_d='ANY_PORT' # the g2 port
gateway_port_d=40000 # don't change gateway_port_d=40000 # don't change
gateway_ipv6_ip_d='ANY_PORT' gateway_ipv6_ip_d='ANY_PORT'
gateway_ipv6_port_d=9011 # IANA-approved DStar rouing port gateway_ipv6_port_d=9011 # IANA-approved DStar routing port
gateway_latitude_d=0 # you can leave this unspecified for a mobile rig gateway_latitude_d=0 # you can leave this unspecified for a mobile rig
gateway_longitude_d=0 # like the latitude gateway_longitude_d=0 # like the latitude
gateway_desc1_d='' # maximum of 20 characters, most special symbols are not allowed gateway_desc1_d='' # maximum of 20 characters, most special symbols are not allowed
@ -93,7 +93,7 @@ module_x_link_at_start='' # For example, set to 'REF001 C' to link module to 1-
module_x_auto_link=true # attempt to automatically re-link if the link should time out. module_x_auto_link=true # attempt to automatically re-link if the link should time out.
module_x_inactivity=0 # if no activity for this many minutes unlink reflector. Zero means no timer. module_x_inactivity=0 # if no activity for this many minutes unlink reflector. Zero means no timer.
module_x_callsign='' # if you operate in a 'restriction mode', use your personal callsign. Usually leave this empty. module_x_callsign='' # if you operate in a 'restriction mode', use your personal callsign. Usually leave this empty.
module_x_packet_wait=25 # how many milliseconds to wait on packets in a voicestream module_x_packet_wait=25 # how many milliseconds to wait on packets in a voice-stream
module_x_acknowledge=false # Do you want an ACK back? module_x_acknowledge=false # Do you want an ACK back?
module_x_ack_delay=250 # millisecond delay before acknowledgment module_x_ack_delay=250 # millisecond delay before acknowledgment
module_x_range=0 # the range of this repeater, in meters 1609.344 meters is 1.0 miles module_x_range=0 # the range of this repeater, in meters 1609.344 meters is 1.0 miles

@ -251,6 +251,9 @@ IrcddbMenu () {
echo "Routes to other clients using IRC Server A will be searched first" echo "Routes to other clients using IRC Server A will be searched first"
echo echo
echo "l : Login - must be a legal callsign = '${ircddb_login}'" echo "l : Login - must be a legal callsign = '${ircddb_login}'"
echo
echo "d : Setup dual-stack (IPv4 & IPv6) QuadNet irc servers for me!"
echo
echo -n "ha : Hostname for IRC Server A = "; EvaluateVar ircddb0_host{,_d} echo -n "ha : Hostname for IRC Server A = "; EvaluateVar ircddb0_host{,_d}
if [ -n "$em" ]; then if [ -n "$em" ]; then
echo -n "oa : IRC TCP port A = "; EvaluateVar ircddb0_port{,_d} echo -n "oa : IRC TCP port A = "; EvaluateVar ircddb0_port{,_d}
@ -264,6 +267,10 @@ IrcddbMenu () {
EndMenu EndMenu
if [[ "$key" == l* ]]; then ircddb_login="${value^^}" if [[ "$key" == l* ]]; then ircddb_login="${value^^}"
elif [[ "$key" == d* ]]; then
ircddb0_host='ircv6.openquad.net'
ircddb1_host='ircv4.openquad.net'
unset ircddb{0,1}_port ircddb{0,1}_password
elif [[ "$key" == ha* ]]; then elif [[ "$key" == ha* ]]; then
if [ -z "$value"]; then if [ -z "$value"]; then
if [ -z "${ircddb1_host+x}" ]; then if [ -z "${ircddb1_host+x}" ]; then

Loading…
Cancel
Save

Powered by TurnKey Linux.