-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathQnetLink.h
229 lines (201 loc) · 6.19 KB
/
QnetLink.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#pragma once
/*
* Copyright (C) 2018-2019 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <regex.h>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <future>
#include <netinet/in.h>
#include "QnetTypeDefs.h"
#include "SEcho.h"
#include "Random.h"
#include "UnixDgramSocket.h"
#include "UDPSocket.h"
#include "UDPSocket.h"
#include "Timer.h"
#include "QnetDB.h"
#include "Base.h"
/*** version number must be x.xx ***/
#define CALL_SIZE 8
#define IP_SIZE 15
#define QUERY_SIZE 56
#define MAXHOSTNAMELEN 64
#define TIMEOUT 50
#define LH_MAX_SIZE 39
using SREFDSVT = struct refdsvt_tag
{
unsigned char head[2];
SDSVT dsvt;
};
using STOREMOTE = struct to_remote_g2_tag
{
char cs[CALL_SIZE + 1];
CSockAddress addr;
char from_mod, to_mod;
short countdown;
bool auto_link, is_connected;
unsigned short in_streamid; // incoming from remote systems
unsigned short out_streamid; // outgoing to remote systems
};
// This is the data payload in the map: inbound_list
// This is for inbound dongles
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
char mod; // A B C This user talked on this module
char client; // dvap, dvdongle
};
using STRACING = struct tracing_tag
{
unsigned short streamid;
time_t last_time; // last time RF user talked
};
class CQnetLink : public CBase
{
public:
// functions
CQnetLink();
~CQnetLink();
bool Initialize(const std::string &path);
void Run();
void Close();
private:
// functions
void ToUpper(std::string &s);
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);
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);
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 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);
/* configuration data */
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;
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 };
// the Key in this inbound_list map is the unique IP address of the remote
std::map<std::string, SINBOUND *> inbound_list;
std::set<std::string> admin, link_unlink_user, link_blacklist;
std::map<std::string, std::string> dt_lh_list;
char notify_msg[3][64];
STOREMOTE to_remote_g2[3];
// 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)
} brd_from_xrf;
SDSVT from_xrf_torptr_brd;
short 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];
} brd_from_rptr;
SDSVT fromrptr_torptr_brd;
short brd_from_rptr_idx;
STRACING tracing[3];
// input from remote
//int xrf_g2_sock, ref_g2_sock, dcs_g2_sock;
CUDPSocket XRFSock4, XRFSock6, DCSSock4, DCSSock6, REFSock4, REFSock6;
CSockAddress fromDst4;
// unix sockets to gateway
CUnixDgramWriter ToGate;
CUnixDgramReader FromGate;
struct timeval tv;
// Used to validate incoming donglers
regex_t preg;
unsigned char 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];
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;
} old_sid[3];
CRandom Random;
CQnetDB qnDB;
std::vector<unsigned long> speak;
// used for processing loop
const unsigned char endbytes[6] = { 0x55U, 0x55U, 0x55U, 0x55U, 0xC8U, 0x7AU };
time_t tnow;
unsigned char dcs_seq[3] = { 0x00, 0x00, 0x00 };
struct
{
char mycall[9];
char sfx[5];
unsigned int dcs_rptr_seq;
} rptr_2_dcs[3] =
{
{" ", " ", 0},
{" ", " ", 0},
{" ", " ", 0}
};
struct
{
char mycall[9];
char sfx[5];
unsigned int dcs_rptr_seq;
} ref_2_dcs[3] =
{
{" ", " ", 0},
{" ", " ", 0},
{" ", " ", 0}
};
struct
{
char mycall[9];
char sfx[5];
unsigned int dcs_rptr_seq;
} xrf_2_dcs[3] =
{
{" ", " ", 0},
{" ", " ", 0},
{" ", " ", 0}
};
};