pull/14/head
Tom Early 7 years ago
parent bdb80e0586
commit 532e65f928

@ -452,7 +452,8 @@ void CQnetGateway::GetIRCDataThread()
} }
while (((type = ii->getMessageType()) != IDRT_NONE) && keep_running) { while (((type = ii->getMessageType()) != IDRT_NONE) && keep_running) {
if (type == IDRT_USER) { switch (type) {
case IDRT_USER:
ii->receiveUser(user, rptr, gateway, ipaddr); ii->receiveUser(user, rptr, gateway, ipaddr);
if (!user.empty()) { if (!user.empty()) {
if (!rptr.empty() && !gateway.empty() && !ipaddr.empty()) { if (!rptr.empty() && !gateway.empty() && !ipaddr.empty()) {
@ -471,7 +472,8 @@ void CQnetGateway::GetIRCDataThread()
} }
} }
} else if (type == IDRT_REPEATER) { break;
case IDRT_REPEATER:
ii->receiveRepeater(rptr, gateway, ipaddr, proto); ii->receiveRepeater(rptr, gateway, ipaddr, proto);
if (!rptr.empty()) { if (!rptr.empty()) {
if (!gateway.empty() && !ipaddr.empty()) { if (!gateway.empty() && !ipaddr.empty()) {
@ -489,7 +491,8 @@ void CQnetGateway::GetIRCDataThread()
} }
} }
} else if (type == IDRT_GATEWAY) { break;
case IDRT_GATEWAY:
ii->receiveGateway(gateway, ipaddr, proto); ii->receiveGateway(gateway, ipaddr, proto);
if (!gateway.empty() && !ipaddr.empty()) { if (!gateway.empty() && !ipaddr.empty()) {
if (LOG_IRC) if (LOG_IRC)
@ -504,8 +507,28 @@ void CQnetGateway::GetIRCDataThread()
// printf("%d gateways\n", gwy2ip_map.size()); // printf("%d gateways\n", gwy2ip_map.size());
} }
break;
case IDRT_PING:
ii->receivePing(rptr);
if (! rptr.empty()) {
pthread_mutex_lock(&irc_data_mutex);
auto git = rptr2gwy_map.find(rptr);
if (rptr2gwy_map.end() == git)
break;
gateway = git->second;
auto ait = gwy2ip_map.find(gateway);
if (gwy2ip_map.end() != ait)
break;
ipaddr = ait->second;
pthread_mutex_unlock(&irc_data_mutex);
CSockAddress to(af_family, (unsigned short)g2_external.port, ipaddr.c_str());
sendto(g2_sock, "PONG", 4, 0, to.GetPointer(), to.GetSize());
} }
} break;
default:
break;
} // switch (type)
} // while (keep_running)
std::this_thread::sleep_for(std::chrono::milliseconds(500)); std::this_thread::sleep_for(std::chrono::milliseconds(500));
} }
printf("GetIRCDataThread exiting...\n"); printf("GetIRCDataThread exiting...\n");
@ -572,7 +595,7 @@ bool CQnetGateway::get_yrcall_rptr(const std::string &call, std::string &arearp_
int rc = get_yrcall_rptr_from_cache(call, arearp_cs, zonerp_cs, mod, ip, RoU); int rc = get_yrcall_rptr_from_cache(call, arearp_cs, zonerp_cs, mod, ip, RoU);
pthread_mutex_unlock(&irc_data_mutex); pthread_mutex_unlock(&irc_data_mutex);
if (rc == 0) { if (rc == 0) {
//printf("get_yrcall_rptr_from_cache: call='%s' arearp_cs='%s' zonerp_cs='%s', mod=%c ip='%s' RoU=%c\n", call.c_str(), arearp_cs.c_str(), zonerp_cs.c_str(), *mod, ip.c_str(), RoU); printf("get_yrcall_rptr_from_cache: call='%s' arearp_cs='%s' zonerp_cs='%s', mod=%c ip='%s' RoU=%c\n", call.c_str(), arearp_cs.c_str(), zonerp_cs.c_str(), *mod, ip.c_str(), RoU);
return true; return true;
} else if (rc == 2) } else if (rc == 2)
return false; return false;
@ -1872,6 +1895,9 @@ void CQnetGateway::Process()
SDSVT dsvt; SDSVT dsvt;
socklen_t fromlen = sizeof(struct sockaddr_storage); socklen_t fromlen = sizeof(struct sockaddr_storage);
ssize_t g2buflen = recvfrom(g2_sock, dsvt.title, 56, 0, fromDstar.GetPointer(), &fromlen); ssize_t g2buflen = recvfrom(g2_sock, dsvt.title, 56, 0, fromDstar.GetPointer(), &fromlen);
if (4==g2buflen && 0==memcmp(dsvt.title, "PONG", 4))
printf("Got a pong from [%s]:%u\n", fromDstar.GetAddress(), fromDstar.GetPort());
else
ProcessG2(g2buflen, dsvt, true); ProcessG2(g2buflen, dsvt, true);
FD_CLR(g2_sock, &fdset); FD_CLR(g2_sock, &fdset);
} }

@ -23,6 +23,9 @@ public:
virtual void setSendQ(IRCMessageQueue *s) = 0; virtual void setSendQ(IRCMessageQueue *s) = 0;
virtual IRCMessageQueue *getSendQ(void) = 0; virtual IRCMessageQueue *getSendQ(void) = 0;
virtual void putReplyMessage(IRCMessage *m) = 0;
virtual void sendPing(const std::string &to, const std::string &from) = 0;
virtual ~IRCApplication() {} virtual ~IRCApplication() {}
}; };

@ -150,8 +150,6 @@ bool CIRCDDB::sendHeardWithTXMsg(const std::string &myCall, const std::string &m
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, dest, msg, ""); return d->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, 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) unsigned char flag2, unsigned char flag3, int num_dv_frames, int num_dv_silent_frames, int num_bit_errors)
{ {
@ -218,8 +216,6 @@ bool CIRCDDB::sendHeardWithTXStats(const std::string &myCall, const std::string
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, " ", "", stats); return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, " ", "", stats);
} }
// Send query for a gateway/reflector, a false return implies a network error // Send query for a gateway/reflector, a false return implies a network error
bool CIRCDDB::findGateway(const std::string &gatewayCallsign) bool CIRCDDB::findGateway(const std::string &gatewayCallsign)
{ {
@ -232,7 +228,6 @@ bool CIRCDDB::findGateway(const std::string &gatewayCallsign)
return d->app->findGateway(gcs); return d->app->findGateway(gcs);
} }
bool CIRCDDB::findRepeater(const std::string &repeaterCallsign) bool CIRCDDB::findRepeater(const std::string &repeaterCallsign)
{ {
if (repeaterCallsign.size() != 8) { if (repeaterCallsign.size() != 8) {
@ -275,7 +270,7 @@ bool CIRCDDB::receiveRepeater(std::string &repeaterCallsign, std::string &gatewa
return false; return false;
} }
IRCMessage * m = d->app->getReplyMessage(); IRCMessage *m = d->app->getReplyMessage();
if (m == NULL) { if (m == NULL) {
printf("CIRCDDB::receiveRepeater: no message\n"); printf("CIRCDDB::receiveRepeater: no message\n");
@ -312,7 +307,7 @@ bool CIRCDDB::receiveGateway(std::string &gatewayCallsign, std::string &address,
return false; return false;
} }
IRCMessage * m = d->app->getReplyMessage(); IRCMessage *m = d->app->getReplyMessage();
if (m == NULL) { if (m == NULL) {
printf("CIRCDDB::receiveGateway: no message\n"); printf("CIRCDDB::receiveGateway: no message\n");
@ -354,7 +349,7 @@ bool CIRCDDB::receiveUser(std::string &userCallsign, std::string &repeaterCallsi
return false; return false;
} }
IRCMessage * m = d->app->getReplyMessage(); IRCMessage *m = d->app->getReplyMessage();
if (m == NULL) { if (m == NULL) {
printf("CIRCDDB::receiveUser: no message\n"); printf("CIRCDDB::receiveUser: no message\n");
@ -382,6 +377,44 @@ bool CIRCDDB::receiveUser(std::string &userCallsign, std::string &repeaterCallsi
return true; return true;
} }
bool CIRCDDB::receivePing(std::string &repeaterCallsign)
{
IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType();
if (rt != IDRT_PING) {
printf("CIRCDDB::receivePing: unexpected response type\n");
return false;
}
IRCMessage *m = d->app->getReplyMessage();
if (NULL == m) {
printf("CIRCDDB::receivePing: no message\n");
return false;
}
if (m->getCommand().compare("IDRT_PING")) {
printf("CIRCDDB::receivePing: wrong messsage type\n");
return false;
}
if (1 != m->getParamCount()) {
printf("CIRCDDB::receivePing: unexpected number of message parameters\n");
return false;
}
repeaterCallsign = m->getParam(0);
delete m;
return true;
}
void CIRCDDB::sendPing(const std::string &to, const std::string &from)
{
d->app->sendPing(to, from);
}
void CIRCDDB::close() // Implictely kills any threads in the IRC code void CIRCDDB::close() // Implictely kills any threads in the IRC code
{ {
d->client->stopWork(); d->client->stopWork();

@ -6,7 +6,8 @@ enum IRCDDB_RESPONSE_TYPE {
IDRT_NONE, IDRT_NONE,
IDRT_USER, IDRT_USER,
IDRT_GATEWAY, IDRT_GATEWAY,
IDRT_REPEATER IDRT_REPEATER,
IDRT_PING
}; };
enum DSTAR_PROTOCOL { enum DSTAR_PROTOCOL {
@ -15,7 +16,6 @@ enum DSTAR_PROTOCOL {
DP_DPLUS DP_DPLUS
}; };
struct CIRCDDBPrivate; struct CIRCDDBPrivate;
class CIRCDDB class CIRCDDB
@ -24,12 +24,12 @@ public:
CIRCDDB(const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo); CIRCDDB(const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo);
~CIRCDDB(); ~CIRCDDB();
// returns the socket family type
int GetFamily(); int GetFamily();
// A false return implies a network error, or unable to log in // A false return implies a network error, or unable to log in
bool open(); bool open();
// rptrQTH can be called multiple times if necessary // rptrQTH can be called multiple times if necessary
// rptrcall callsign of the repeater // rptrcall callsign of the repeater
// latitude WGS84 position of antenna in degrees, positive value -> NORTH // latitude WGS84 position of antenna in degrees, positive value -> NORTH
@ -38,8 +38,6 @@ public:
void rptrQTH(const std::string &rptrcall, double latitude, double longitude, const std::string &desc1, const std::string &desc2, const std::string &infoURL, const std::string &swVersion); void rptrQTH(const std::string &rptrcall, double latitude, double longitude, const std::string &desc1, const std::string &desc2, const std::string &infoURL, const std::string &swVersion);
// rptrQRG can be called multiple times if necessary // rptrQRG can be called multiple times if necessary
// module letter of the module, valid values: "A", "B", "C", "D", "AD", "BD", "CD", "DD" // module letter of the module, valid values: "A", "B", "C", "D", "AD", "BD", "CD", "DD"
// txFrequency repeater TX frequency in MHz // txFrequency repeater TX frequency in MHz
@ -49,7 +47,6 @@ public:
void rptrQRG(const std::string &rptrcall, double txFrequency, double duplexShift, double range, double agl); void rptrQRG(const std::string &rptrcall, double txFrequency, double duplexShift, double range, double agl);
// If you call this method once, watchdog messages will be sent to the // If you call this method once, watchdog messages will be sent to the
// to the ircDDB network every 15 minutes. Invoke this method every 1-2 minutes to indicate // to the ircDDB network every 15 minutes. Invoke this method every 1-2 minutes to indicate
// that the gateway is working properly. After activating the watchdog, a red LED will be displayed // that the gateway is working properly. After activating the watchdog, a red LED will be displayed
@ -60,8 +57,6 @@ public:
void kickWatchdog(const std::string &wdInfo); void kickWatchdog(const std::string &wdInfo);
// get internal network status // get internal network status
int getConnectionState(); int getConnectionState();
// one of these values is returned: // one of these values is returned:
@ -74,14 +69,12 @@ public:
// Send heard data, a false return implies a network error // 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, unsigned char flag1, unsigned char flag2, unsigned char flag3);
// same as sendHeard with two new fields: // same as sendHeard with two new fields:
// network_destination: empty string or 8-char call sign of the repeater // network_destination: empty string or 8-char call sign of the repeater
// or reflector, where this transmission is relayed to. // or reflector, where this transmission is relayed to.
// tx_message: 20-char TX message or empty string, if the user did not // tx_message: 20-char TX message or empty string, if the user did not
// send a TX message // 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, 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);
unsigned char flag2, unsigned char flag3, const std::string &network_destination, const std::string &tx_message);
// this method should be called at the end of a transmission // this method should be called at the end of a transmission
// num_dv_frames: number of DV frames sent out (96 bit frames, 20ms) // num_dv_frames: number of DV frames sent out (96 bit frames, 20ms)
@ -93,8 +86,7 @@ public:
// So, the overall bit error rate is calculated like this: // So, the overall bit error rate is calculated like this:
// BER = num_bit_errors / (num_dv_frames * 24) // BER = num_bit_errors / (num_dv_frames * 24)
// Set num_bit_errors = -1, if the error information is not available. // 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, 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);
unsigned char flag2, unsigned char 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 // The following three functions don't block waiting for a reply, they just send the data
@ -126,10 +118,12 @@ public:
bool receiveUser(std::string &userCallsign, std::string &repeaterCallsign, std::string &gatewayCallsign, std::string &address, std::string &timeStamp); bool receiveUser(std::string &userCallsign, std::string &repeaterCallsign, std::string &gatewayCallsign, std::string &address, std::string &timeStamp);
void close(); // Implictely kills any threads in the IRC code bool receivePing(std::string &repeaterCallsign);
void sendPing(const std::string &to, const std::string &from);
void close(); // Implictely kills any threads in the IRC code
private: private:
struct CIRCDDBPrivate * const d; struct CIRCDDBPrivate * const d;
}; };

@ -265,6 +265,11 @@ IRCMessage *IRCDDBApp::getReplyMessage()
return d->replyQ.getMessage(); return d->replyQ.getMessage();
} }
void IRCDDBApp::putReplyMessage(IRCMessage *m)
{
d->replyQ.putMessage(m);
}
bool IRCDDBApp::startWork() bool IRCDDBApp::startWork()
{ {
d->terminateThread = false; d->terminateThread = false;
@ -428,6 +433,30 @@ void IRCDDBApp::userChanOp(const std::string &nick, bool op)
d->userMapMutex.unlock(); d->userMapMutex.unlock();
} }
void IRCDDBApp::sendPing(const std::string &to, const std::string &from)
{
std::string t = to.substr(0, 7);
ReplaceChar(t, '_', ' ');
while (isspace(t[t.length()-1]))
t.pop_back();
ToLower(t);
d->userMapMutex.lock();
for (int j=1; j <= 4; j++) {
std::string ircUser = t + std::string("-") + std::to_string(j);
if (1 == d->user.count(ircUser)) {
IRCMessage *rm = new IRCMessage(t, "IDRT_PING");
rm->addParam(from);
d->sendQ->putMessage(rm);
break;
}
}
d->userMapMutex.unlock();
}
static const int numberOfTables = 2; static const int numberOfTables = 2;
std::string IRCDDBApp::getIPAddress(std::string &zonerp_cs) std::string IRCDDBApp::getIPAddress(std::string &zonerp_cs)

@ -33,6 +33,9 @@ public:
virtual void setSendQ(IRCMessageQueue *s); virtual void setSendQ(IRCMessageQueue *s);
virtual IRCMessageQueue *getSendQ(); virtual IRCMessageQueue *getSendQ();
virtual void putReplyMessage(IRCMessage *m);
virtual void sendPing(const std::string &to, const std::string &from);
bool startWork(); bool startWork();
void stopWork(); void stopWork();
@ -44,9 +47,7 @@ public:
bool findRepeater(const std::string &s); bool findRepeater(const std::string &s);
bool findGateway(const std::string &s); bool findGateway(const std::string &s);
bool sendHeard(const std::string &myCall, const std::string &myCallExt, const std::string &yourCall, const std::string &rpt1, 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);
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);
int getConnectionState(); int getConnectionState();

@ -176,12 +176,20 @@ bool IRCProtocol::processQueues(IRCMessageQueue *recvQ, IRCMessageQueue *sendQ)
} }
} }
} else if (0 == m->command.compare("PRIVMSG")) { } else if (0 == m->command.compare("PRIVMSG")) {
if ((m->numParams == 2) && (app != NULL)) { if (app) {
if (2 == m->numParams) {
if (0 == m->params[0].compare(channel)) { if (0 == m->params[0].compare(channel)) {
app->msgChannel(m); app->msgChannel(m);
} else if (0 == m->params[0].compare(currentNick)) { } else if (0 == m->params[0].compare(currentNick)) {
app->msgQuery(m); app->msgQuery(m);
} }
} else if (3 == m->numParams) {
// pass this on to the replyQ so the gateway can PONG the sender
if (0==m->params[0].compare(currentNick) && 0==m->params[1].compare("IDRT_PING")) {
IRCMessage *rm = new IRCMessage(m->params[1], m->params[2]);
app->putReplyMessage(rm);
}
}
} }
} else if (0 == m->command.compare("352")) { // WHO list } else if (0 == m->command.compare("352")) { // WHO list
if ((m->numParams >= 7) && 0==m->params[0].compare(currentNick) && 0==m->params[1].compare(channel)) { if ((m->numParams >= 7) && 0==m->params[0].compare(currentNick) && 0==m->params[1].compare(channel)) {
@ -343,5 +351,3 @@ bool IRCProtocol::processQueues(IRCMessageQueue *recvQ, IRCMessageQueue *sendQ)
return true; return true;
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.