diff --git a/ircddb/IRCClient.cpp b/ircddb/IRCClient.cpp index a40db35..2ed3d86 100644 --- a/ircddb/IRCClient.cpp +++ b/ircddb/IRCClient.cpp @@ -5,6 +5,7 @@ #include #include "IRCClient.h" +#include "IRCProtocol.h" #include "IRCutils.h" diff --git a/ircddb/IRCClient.h b/ircddb/IRCClient.h index 12edf83..200da5b 100644 --- a/ircddb/IRCClient.h +++ b/ircddb/IRCClient.h @@ -6,7 +6,9 @@ #include "IRCReceiver.h" #include "IRCMessageQueue.h" -#include "IRCProtocol.h" + +class IRCProtocol; +class IRCDDBApp; class IRCClient { diff --git a/ircddb/IRCDDB.cpp b/ircddb/IRCDDB.cpp index 9c076b7..3c203c0 100644 --- a/ircddb/IRCDDB.cpp +++ b/ircddb/IRCDDB.cpp @@ -4,32 +4,25 @@ #include "IRCDDBApp.h" #include "IRCutils.h" -struct CIRCDDBPrivate { - IRCClient *client; - IRCDDBApp *app; -}; - CIRCDDB::CIRCDDB(const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo) - : d(new CIRCDDBPrivate) { std::string update_channel = "#dstar"; - d->app = new IRCDDBApp(update_channel); + app = new IRCDDBApp(update_channel); - d->client = new IRCClient(d->app, update_channel, hostName, port, callsign, password, versionInfo); + client = new IRCClient(app, update_channel, hostName, port, callsign, password, versionInfo); } CIRCDDB::~CIRCDDB() { - delete d->client; - delete d->app; - delete d; + delete client; + delete app; } int CIRCDDB::GetFamily() { - return d->client->GetFamily(); + return client->GetFamily(); } @@ -37,31 +30,31 @@ int CIRCDDB::GetFamily() bool CIRCDDB::open() { printf("starting CIRCDDB\n"); - return d->client->startWork() && d->app->startWork(); + return client->startWork() && app->startWork(); } int CIRCDDB::getConnectionState() { - return d->app->getConnectionState(); + return app->getConnectionState(); } void CIRCDDB::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) { - d->app->rptrQTH(rptrcall, latitude, longitude, desc1, desc2, infoURL, swVersion); + app->rptrQTH(rptrcall, latitude, longitude, desc1, desc2, infoURL, swVersion); } void CIRCDDB::rptrQRG(const std::string &rptrcall, double txFrequency, double duplexShift, double range, double agl) { - d->app->rptrQRG(rptrcall, txFrequency, duplexShift, range, agl); + app->rptrQRG(rptrcall, txFrequency, duplexShift, range, agl); } void CIRCDDB::kickWatchdog(const std::string &wdInfo) { - d->app->kickWatchdog(wdInfo); + app->kickWatchdog(wdInfo); } // Send heard data, a false return implies a network error @@ -92,7 +85,7 @@ bool CIRCDDB::sendHeard(const std::string &myCall, const std::string &myCallExt, return false; } - return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, " ", "", ""); + return app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, " ", "", ""); } // Send heard data, a false return implies a network error @@ -147,7 +140,7 @@ 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 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, @@ -213,7 +206,7 @@ bool CIRCDDB::sendHeardWithTXStats(const std::string &myCall, const std::string stats.append("____________"); // stats string should have 20 chars - return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, " ", "", stats); + return app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, " ", "", stats); } // Send query for a gateway/reflector, a false return implies a network error @@ -225,7 +218,7 @@ bool CIRCDDB::findGateway(const std::string &gatewayCallsign) } std::string gcs = gatewayCallsign; ToUpper(gcs); - return d->app->findGateway(gcs); + return app->findGateway(gcs); } bool CIRCDDB::findRepeater(const std::string &repeaterCallsign) @@ -236,7 +229,7 @@ bool CIRCDDB::findRepeater(const std::string &repeaterCallsign) } std::string rcs = repeaterCallsign; ToUpper(rcs); - return d->app->findRepeater(rcs); + return app->findRepeater(rcs); } // Send query for a user, a false return implies a network error @@ -248,7 +241,7 @@ bool CIRCDDB::findUser(const std::string &userCallsign) } std::string ucs = userCallsign; ToUpper(ucs); - return d->app->findUser(ucs); + return app->findUser(ucs); } // The following functions are for processing received messages @@ -256,21 +249,21 @@ bool CIRCDDB::findUser(const std::string &userCallsign) // Get the waiting message type IRCDDB_RESPONSE_TYPE CIRCDDB::getMessageType() { - return d->app->getReplyMessageType(); + return app->getReplyMessageType(); } // Get a gateway message, as a result of IDRT_REPEATER returned from getMessageType() // A false return implies a network error bool CIRCDDB::receiveRepeater(std::string &repeaterCallsign, std::string &gatewayCallsign, std::string &address, DSTAR_PROTOCOL &/*protocol*/) { - IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType(); + IRCDDB_RESPONSE_TYPE rt = app->getReplyMessageType(); if (rt != IDRT_REPEATER) { printf("CIRCDDB::receiveRepeater: unexpected response type\n"); return false; } - IRCMessage *m = d->app->getReplyMessage(); + IRCMessage *m = app->getReplyMessage(); if (m == NULL) { printf("CIRCDDB::receiveRepeater: no message\n"); @@ -300,14 +293,14 @@ bool CIRCDDB::receiveRepeater(std::string &repeaterCallsign, std::string &gatewa // A false return implies a network error bool CIRCDDB::receiveGateway(std::string &gatewayCallsign, std::string &address, DSTAR_PROTOCOL& /*protocol*/) { - IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType(); + IRCDDB_RESPONSE_TYPE rt = app->getReplyMessageType(); if (rt != IDRT_GATEWAY) { printf("CIRCDDB::receiveGateway: unexpected response type\n"); return false; } - IRCMessage *m = d->app->getReplyMessage(); + IRCMessage *m = app->getReplyMessage(); if (m == NULL) { printf("CIRCDDB::receiveGateway: no message\n"); @@ -342,14 +335,14 @@ bool CIRCDDB::receiveUser(std::string &userCallsign, std::string &repeaterCallsi bool CIRCDDB::receiveUser(std::string &userCallsign, std::string &repeaterCallsign, std::string &gatewayCallsign, std::string &address, std::string &timeStamp) { - IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType(); + IRCDDB_RESPONSE_TYPE rt = app->getReplyMessageType(); if (rt != IDRT_USER) { printf("CIRCDDB::receiveUser: unexpected response type\n"); return false; } - IRCMessage *m = d->app->getReplyMessage(); + IRCMessage *m = app->getReplyMessage(); if (m == NULL) { printf("CIRCDDB::receiveUser: no message\n"); @@ -379,14 +372,14 @@ bool CIRCDDB::receiveUser(std::string &userCallsign, std::string &repeaterCallsi bool CIRCDDB::receivePing(std::string &repeaterCallsign) { - IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType(); + IRCDDB_RESPONSE_TYPE rt = app->getReplyMessageType(); if (rt != IDRT_PING) { printf("CIRCDDB::receivePing: unexpected response type\n"); return false; } - IRCMessage *m = d->app->getReplyMessage(); + IRCMessage *m = app->getReplyMessage(); if (NULL == m) { printf("CIRCDDB::receivePing: no message\n"); @@ -412,11 +405,11 @@ bool CIRCDDB::receivePing(std::string &repeaterCallsign) void CIRCDDB::sendPing(const std::string &to, const std::string &from) { - d->app->sendPing(to, from); + app->sendPing(to, from); } void CIRCDDB::close() // Implictely kills any threads in the IRC code { - d->client->stopWork(); - d->app->stopWork(); + client->stopWork(); + app->stopWork(); } diff --git a/ircddb/IRCDDB.h b/ircddb/IRCDDB.h index 4ba7858..ff18167 100644 --- a/ircddb/IRCDDB.h +++ b/ircddb/IRCDDB.h @@ -16,7 +16,8 @@ enum DSTAR_PROTOCOL { DP_DPLUS }; -struct CIRCDDBPrivate; +class IRCDDBApp; +class IRCClient; class CIRCDDB { @@ -125,5 +126,6 @@ public: void close(); // Implictely kills any threads in the IRC code private: - struct CIRCDDBPrivate * const d; + IRCDDBApp *app; + IRCClient *client; }; diff --git a/ircddb/IRCDDBApp.cpp b/ircddb/IRCDDBApp.cpp index a9fb9d9..5a2bb08 100644 --- a/ircddb/IRCDDBApp.cpp +++ b/ircddb/IRCDDBApp.cpp @@ -2,137 +2,42 @@ #include #include #include -#include -#include #include -#include #include "IRCDDBApp.h" #include "IRCutils.h" -class IRCDDBAppUserObject -{ -public: - - std::string nick; - std::string name; - std::string host; - bool op; - unsigned int usn; - - IRCDDBAppUserObject() {} - - IRCDDBAppUserObject(const std::string &n, const std::string &nm, const std::string &h) { - nick = n; - name = nm; - host = h; - op = false; - usn = counter; - counter++; - } - static unsigned int counter; -}; - -unsigned int IRCDDBAppUserObject::counter = 0; - -class IRCDDBAppRptrObject -{ -public: - - std::string arearp_cs; - time_t lastChanged; - std::string zonerp_cs; - - IRCDDBAppRptrObject() { - } - - IRCDDBAppRptrObject(time_t dt, std::string &repeaterCallsign, std::string &gatewayCallsign) { - arearp_cs = repeaterCallsign; - lastChanged = dt; - zonerp_cs = gatewayCallsign; - - if (dt > maxTime) { - maxTime = dt; - } - } - - static time_t maxTime; -}; +unsigned int IRCDDBAppGateObject::counter = 0; time_t IRCDDBAppRptrObject::maxTime((time_t)950000000); // February 2000 -class IRCDDBAppPrivate -{ -public: - IRCDDBAppPrivate() - { - wdTimer = -1; - } - - IRCMessageQueue *sendQ; - IRCMessageQueue replyQ; - - std::map user; - std::mutex userMapMutex; - std::map rptrMap; - std::mutex rptrMapMutex; - std::map moduleMap; - std::mutex moduleMapMutex; - std::map locationMap; - std::mutex locationMapMutex; - std::map urlMap; - std::mutex urlMapMutex; - std::map swMap; - std::mutex swMapMutex; - - std::string currentServer; - std::string myNick; - - std::regex tablePattern, datePattern, timePattern, dbPattern, modulePattern; - - int state; - int timer; - int infoTimer; - int wdTimer; - - std::string updateChannel; - std::string channelTopic; - std::string bestServer; - std::string wdInfo; - - bool initReady; - bool terminateThread; -}; - IRCDDBApp::IRCDDBApp(const std::string &u_chan) - : d(new IRCDDBAppPrivate) { - - d->sendQ = NULL; - d->initReady = false; + wdTimer = -1; + sendQ = NULL; + initReady = false; userListReset(); - d->state = 0; - d->timer = 0; - d->myNick = "none"; + state = 0; + timer = 0; + myNick = "none"; - d->updateChannel = u_chan; + updateChannel = u_chan; - d->terminateThread = false; - d->tablePattern = std::regex("^[0-9]$"); - d->datePattern = std::regex("^20[0-9][0-9]-((1[0-2])|(0[1-9]))-((3[01])|([12][0-9])|(0[1-9]))$"); - d->timePattern = std::regex("^((2[0-3])|([01][0-9])):[0-5][0-9]:[0-5][0-9]$"); - d->dbPattern = std::regex("^[0-9A-Z_]{8}$"); - d->modulePattern = std::regex("^.*[ABCD]D?$"); + terminateThread = false; + tablePattern = std::regex("^[0-9]$"); + datePattern = std::regex("^20[0-9][0-9]-((1[0-2])|(0[1-9]))-((3[01])|([12][0-9])|(0[1-9]))$"); + timePattern = std::regex("^((2[0-3])|([01][0-9])):[0-5][0-9]:[0-5][0-9]$"); + dbPattern = std::regex("^[0-9A-Z_]{8}$"); + modulePattern = std::regex("^.*[ABCD]D?$"); } IRCDDBApp::~IRCDDBApp() { - if (d->sendQ != NULL) { - delete d->sendQ; + if (sendQ != NULL) { + delete sendQ; } - delete d; } void IRCDDBApp::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) @@ -161,9 +66,9 @@ void IRCDDBApp::rptrQTH(const std::string &rptrcall, double latitude, double lon std::string aspace(" "); std::string f = rcall + aspace + std::string(pos) + aspace + d1 + aspace + d2; - d->locationMapMutex.lock(); - d->locationMap[rptrcall] = f; - d->locationMapMutex.unlock(); + locationMapMutex.lock(); + locationMap[rptrcall] = f; + locationMapMutex.unlock(); //printf("IRCDDB RPTRQTH: %s\n", f.c_str()); @@ -175,9 +80,9 @@ void IRCDDBApp::rptrQTH(const std::string &rptrcall, double latitude, double lon std::string g = rcall + aspace + url; - d->urlMapMutex.lock(); - d->urlMap[rptrcall] = g; - d->urlMapMutex.unlock(); + urlMapMutex.lock(); + urlMap[rptrcall] = g; + urlMapMutex.unlock(); //printf("IRCDDB RPTRURL: %s\n", g.c_str()); @@ -186,19 +91,19 @@ void IRCDDBApp::rptrQTH(const std::string &rptrcall, double latitude, double lon sw.erase(sm.position(0), sm.length()); std::string h = rcall + std::string(" ") + sw; - d->swMapMutex.lock(); - d->swMap[rptrcall] = h; - d->swMapMutex.unlock(); + swMapMutex.lock(); + swMap[rptrcall] = h; + swMapMutex.unlock(); //printf("IRCDDB RPTRSW: %s\n", h.c_str()); - d->infoTimer = 5; // send info in 5 seconds + infoTimer = 5; // send info in 5 seconds } void IRCDDBApp::rptrQRG(const std::string &rptrcall, double txFrequency, double duplexShift, double range, double agl) { - if (std::regex_match(rptrcall, d->modulePattern)) { + if (std::regex_match(rptrcall, modulePattern)) { std::string c = rptrcall; ReplaceChar(c, ' ', '_'); @@ -207,13 +112,13 @@ void IRCDDBApp::rptrQRG(const std::string &rptrcall, double txFrequency, double snprintf(f, 48, "%011.5f %+010.5f %06.2f %06.1f", txFrequency, duplexShift, range / 1609.344, agl); std::string g = c + std::string(" ") + f; - d->moduleMapMutex.lock(); - d->moduleMap[rptrcall] = g; - d->moduleMapMutex.unlock(); + moduleMapMutex.lock(); + moduleMap[rptrcall] = g; + moduleMapMutex.unlock(); //printf("IRCDDB RPTRQRG: %s\n", g.c_str()); - d->infoTimer = 5; // send info in 5 seconds + infoTimer = 5; // send info in 5 seconds } } @@ -226,21 +131,21 @@ void IRCDDBApp::kickWatchdog(const std::string &s) std::string u = s; while (std::regex_search(u, sm, nonValid)) u.erase(sm.position(0), sm.length()); - d->wdInfo = u; + wdInfo = u; if (u.length() > 0) - d->wdTimer = 1; + wdTimer = 1; } } int IRCDDBApp::getConnectionState() { - return d->state; + return state; } IRCDDB_RESPONSE_TYPE IRCDDBApp::getReplyMessageType() { - IRCMessage * m = d->replyQ.peekFirst(); + IRCMessage * m = replyQ.peekFirst(); if (m == NULL) { return IDRT_NONE; } @@ -264,24 +169,24 @@ IRCDDB_RESPONSE_TYPE IRCDDBApp::getReplyMessageType() IRCMessage *IRCDDBApp::getReplyMessage() { - return d->replyQ.getMessage(); + return replyQ.getMessage(); } void IRCDDBApp::putReplyMessage(IRCMessage *m) { - d->replyQ.putMessage(m); + replyQ.putMessage(m); } bool IRCDDBApp::startWork() { - d->terminateThread = false; + terminateThread = false; worker_thread = std::async(std::launch::async, &IRCDDBApp::Entry, this); return true; } void IRCDDBApp::stopWork() { - d->terminateThread = true; + terminateThread = true; worker_thread.get(); } @@ -290,15 +195,15 @@ void IRCDDBApp::userJoin(const std::string &nick, const std::string &name, const std::string lnick = nick; ToLower(lnick); - IRCDDBAppUserObject u(lnick, name, host); + IRCDDBAppGateObject u(lnick, name, host); - d->userMapMutex.lock(); - d->user[lnick] = u; - d->userMapMutex.unlock(); + userMapMutex.lock(); + user[lnick] = u; + userMapMutex.unlock(); - //printf("add %d: (%s) (%s)\n", d->user.size(), nick.c_str(), host.c_str()); + //printf("add %d: (%s) (%s)\n", user.size(), nick.c_str(), host.c_str()); - if (d->initReady) { + if (initReady) { unsigned hyphenPos = nick.find('-'); if ((hyphenPos >= 4) && (hyphenPos <= 6)) { @@ -310,7 +215,7 @@ void IRCDDBApp::userJoin(const std::string &nick, const std::string &name, const IRCMessage *m2 = new IRCMessage("IDRT_GATEWAY"); m2->addParam(gatewayCallsign); m2->addParam(host); - d->replyQ.putMessage(m2); + replyQ.putMessage(m2); } } //printf("user %d\n", u.usn); @@ -321,28 +226,28 @@ void IRCDDBApp::userLeave(const std::string &nick) std::string lnick = nick; ToLower(lnick); - d->userMapMutex.lock(); - d->user.erase(lnick); - d->userMapMutex.unlock(); + userMapMutex.lock(); + user.erase(lnick); + userMapMutex.unlock(); - // printf("rm %d: %s\n" d->user.size(), nick.c_str()); + // printf("rm %d: %s\n" user.size(), nick.c_str()); - if (d->currentServer.length() > 0) { - if (d->user.count(d->myNick) != 1) { + if (currentServer.length() > 0) { + if (user.count(myNick) != 1) { printf("IRCDDBApp::userLeave: could not find own nick\n"); return; } - IRCDDBAppUserObject me = d->user[d->myNick]; + IRCDDBAppGateObject me = user[myNick]; if (me.op == false) { // if I am not op, then look for new server - if (d->currentServer == lnick) { + if (currentServer == lnick) { // currentServer = null; - d->state = 2; // choose new server - d->timer = 200; - d->initReady = false; + state = 2; // choose new server + timer = 200; + initReady = false; } } } @@ -350,55 +255,55 @@ void IRCDDBApp::userLeave(const std::string &nick) void IRCDDBApp::userListReset() { - d->userMapMutex.lock(); - d->user.clear(); - d->userMapMutex.unlock(); + userMapMutex.lock(); + user.clear(); + userMapMutex.unlock(); } void IRCDDBApp::setCurrentNick(const std::string &nick) { - d->myNick = nick; + myNick = nick; printf("IRCDDBApp::setCurrentNick %s\n", nick.c_str()); } void IRCDDBApp::setBestServer(const std::string &ircUser) { - d->bestServer = ircUser; + bestServer = ircUser; printf("IRCDDBApp::setBestServer %s\n", ircUser.c_str()); } void IRCDDBApp::setTopic(const std::string &topic) { - d->channelTopic = topic; + channelTopic = topic; } bool IRCDDBApp::findServerUser() { - d->userMapMutex.lock(); + userMapMutex.lock(); bool found = false; - std::map::iterator it; + std::map::iterator it; - for (it=d->user.begin(); it!=d->user.end(); ++it) { - IRCDDBAppUserObject u = it->second; - if (0==u.nick.compare(0, 2, "s-") && u.op && d->myNick.compare(u.nick) && 0==u.nick.compare(d->bestServer)) { - d->currentServer = u.nick; + for (it=user.begin(); it!=user.end(); ++it) { + IRCDDBAppGateObject u = it->second; + if (0==u.nick.compare(0, 2, "s-") && u.op && myNick.compare(u.nick) && 0==u.nick.compare(bestServer)) { + currentServer = u.nick; found = true; break; } } if (found) { - d->userMapMutex.unlock(); + userMapMutex.unlock(); return true; } - if (d->bestServer.length() == 8) { - for(it=d->user.begin(); it!=d->user.end(); ++it) { - IRCDDBAppUserObject u = it->second; - if (0==u.nick.compare(0, 7, d->bestServer) && u.op && d->myNick.compare(u.nick) ) { - d->currentServer = u.nick; + if (bestServer.length() == 8) { + for(it=user.begin(); it!=user.end(); ++it) { + IRCDDBAppGateObject u = it->second; + if (0==u.nick.compare(0, 7, bestServer) && u.op && myNick.compare(u.nick) ) { + currentServer = u.nick; found = true; break; } @@ -406,20 +311,20 @@ bool IRCDDBApp::findServerUser() } if (found) { - d->userMapMutex.unlock(); + userMapMutex.unlock(); return true; } - for(it = d->user.begin(); it != d->user.end(); ++it) { - IRCDDBAppUserObject u = it->second; - if (0==u.nick.compare(0, 2, "s-") && u.op && d->myNick.compare(u.nick)) { - d->currentServer = u.nick; + for(it = user.begin(); it != user.end(); ++it) { + IRCDDBAppGateObject u = it->second; + if (0==u.nick.compare(0, 2, "s-") && u.op && myNick.compare(u.nick)) { + currentServer = u.nick; found = true; break; } } - d->userMapMutex.unlock(); + userMapMutex.unlock(); return found; } @@ -428,11 +333,11 @@ void IRCDDBApp::userChanOp(const std::string &nick, bool op) std::string lnick = nick; ToLower(lnick); - d->userMapMutex.lock(); - if (d->user.count(lnick) == 1) { - d->user[lnick].op = op; + userMapMutex.lock(); + if (user.count(lnick) == 1) { + user[lnick].op = op; } - d->userMapMutex.unlock(); + userMapMutex.unlock(); } void IRCDDBApp::sendPing(const std::string &to, const std::string &from) @@ -444,11 +349,11 @@ void IRCDDBApp::sendPing(const std::string &to, const std::string &from) t.pop_back(); ToLower(t); - d->userMapMutex.lock(); + 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)) { + if (1 == user.count(ircUser)) { std::string f(from); ReplaceChar(f, ' ', '_'); IRCMessage *rm = new IRCMessage(ircUser, "IDRT_PING"); @@ -458,11 +363,11 @@ void IRCDDBApp::sendPing(const std::string &to, const std::string &from) out.pop_back(); out.pop_back(); //printf("IRCDDBApp::sendPing: %s\n", out.c_str()); - d->sendQ->putMessage(rm); + sendQ->putMessage(rm); break; } } - d->userMapMutex.unlock(); + userMapMutex.unlock(); } @@ -470,7 +375,7 @@ static const int numberOfTables = 2; std::string IRCDDBApp::getIPAddress(std::string &zonerp_cs) { - d->userMapMutex.lock(); + userMapMutex.lock(); std::string gw = zonerp_cs; ReplaceChar(gw, '_', ' '); @@ -484,8 +389,8 @@ std::string IRCDDBApp::getIPAddress(std::string &zonerp_cs) for (int j=1; j <= 4; j++) { std::string ircUser = gw + std::string("-") + std::to_string(j); - if (d->user.count(ircUser) == 1) { - IRCDDBAppUserObject o = d->user[ircUser]; + if (user.count(ircUser) == 1) { + IRCDDBAppGateObject o = user[ircUser]; if (o.usn >= max_usn) { max_usn = o.usn; @@ -495,7 +400,7 @@ std::string IRCDDBApp::getIPAddress(std::string &zonerp_cs) // printf("getIP %d (%s) (%s)\n", i, ircUser.c_str(), ipAddr.c_str()); } - d->userMapMutex.unlock(); + userMapMutex.unlock(); return ipAddr; } @@ -505,7 +410,7 @@ bool IRCDDBApp::findGateway(const std::string &gwCall) IRCMessage *m2 = new IRCMessage("IDRT_GATEWAY"); m2->addParam(gwCall); m2->addParam(getIPAddress(s)); - d->replyQ.putMessage(m2); + replyQ.putMessage(m2); return true; } @@ -517,24 +422,24 @@ bool IRCDDBApp::findRepeater(const std::string &rptrCall) std::string zonerp_cs; - d->rptrMapMutex.lock(); + rptrMapMutex.lock(); std::string s("NONE"); - if (d->rptrMap.count(arearp_cs) == 1) { - IRCDDBAppRptrObject o = d->rptrMap[arearp_cs]; + if (rptrMap.count(arearp_cs) == 1) { + IRCDDBAppRptrObject o = rptrMap[arearp_cs]; zonerp_cs = o.zonerp_cs; ReplaceChar(zonerp_cs, '_', ' '); zonerp_cs[7] = 'G'; s = o.zonerp_cs; } - d->rptrMapMutex.unlock(); + rptrMapMutex.unlock(); IRCMessage *m2 = new IRCMessage("IDRT_REPEATER"); m2->addParam(rptrCall); m2->addParam(zonerp_cs); m2->addParam(getIPAddress(s)); - d->replyQ.putMessage(m2); + replyQ.putMessage(m2); return true; } @@ -576,10 +481,10 @@ bool IRCDDBApp::sendHeard(const std::string &myCall, bool statsMsg = (tx_stats.length() > 0); - std::string srv = d->currentServer; + std::string srv = currentServer; IRCMessageQueue *q = getSendQ(); - if ((srv.length() > 0) && (d->state >= 6) && (q != NULL)) { + if ((srv.length() > 0) && (state >= 6) && (q != NULL)) { std::string cmd("UPDATE "); cmd.append(getCurrentTime()); @@ -629,10 +534,10 @@ bool IRCDDBApp::sendHeard(const std::string &myCall, bool IRCDDBApp::findUser(const std::string &usrCall) { - std::string srv = d->currentServer; + std::string srv = currentServer; IRCMessageQueue *q = getSendQ(); - if ((srv.length() > 0) && (d->state >= 6) && (q != NULL)) { + if ((srv.length() > 0) && (state >= 6) && (q != NULL)) { std::string usr = usrCall; ReplaceChar(usr, ' ', '_'); @@ -647,7 +552,7 @@ bool IRCDDBApp::findUser(const std::string &usrCall) m2->addParam(""); m2->addParam(""); m2->addParam(""); - d->replyQ.putMessage(m2); + replyQ.putMessage(m2); } return true; @@ -673,7 +578,7 @@ void IRCDDBApp::doNotFound(std::string &msg, std::string &retval) tkz.erase(tkz.begin()); - if (std::regex_match(tk, d->tablePattern)) { + if (std::regex_match(tk, tablePattern)) { long tableID = std::stol(tk); if ((tableID < 0) || (tableID >= numberOfTables)) { @@ -689,7 +594,7 @@ void IRCDDBApp::doNotFound(std::string &msg, std::string &retval) } if (tableID == 0) { - if (! std::regex_match(tk, d->dbPattern)) + if (! std::regex_match(tk, dbPattern)) return; // no valid key retval = tk; @@ -708,7 +613,7 @@ void IRCDDBApp::doUpdate(std::string &msg) std::string tk = tkz.front(); tkz.erase(tkz.begin()); - if (std::regex_match(tk, d->tablePattern)) { + if (std::regex_match(tk, tablePattern)) { tableID = stol(tk); if ((tableID < 0) || (tableID >= numberOfTables)) { printf("invalid table ID %d", tableID); @@ -722,14 +627,14 @@ void IRCDDBApp::doUpdate(std::string &msg) tkz.erase(tkz.begin()); } - if (std::regex_match(tk, d->datePattern)) { + if (std::regex_match(tk, datePattern)) { if (0 == tkz.size()) return; // nothing after date string std::string timeToken = tkz.front(); tkz.erase(tkz.begin()); - if (! std::regex_match(timeToken, d->timePattern)) + if (! std::regex_match(timeToken, timePattern)) return; // no time string after date string time_t dt = parseTime(std::string(tk + " " + timeToken)); @@ -741,7 +646,7 @@ void IRCDDBApp::doUpdate(std::string &msg) std::string key = tkz.front(); tkz.erase(tkz.begin()); - if (! std::regex_match(key, d->dbPattern)) + if (! std::regex_match(key, dbPattern)) return; // no valid key if (0 == tkz.size()) @@ -750,19 +655,19 @@ void IRCDDBApp::doUpdate(std::string &msg) std::string value = tkz.front(); tkz.erase(tkz.begin()); - if (! std::regex_match(value, d->dbPattern)) + if (! std::regex_match(value, dbPattern)) return; // no valid key //printf("TABLE %d %s %s\n", tableID, key.c_str(), value.c_str()); if (tableID == 1) { - d->rptrMapMutex.lock(); + rptrMapMutex.lock(); IRCDDBAppRptrObject newRptr(dt, key, value); - d->rptrMap[key] = newRptr; + rptrMap[key] = newRptr; - if (d->initReady) { + if (initReady) { std::string arearp_cs = key; std::string zonerp_cs = value; @@ -774,11 +679,11 @@ void IRCDDBApp::doUpdate(std::string &msg) m2->addParam(arearp_cs); m2->addParam(zonerp_cs); m2->addParam(getIPAddress(value)); - d->replyQ.putMessage(m2); + replyQ.putMessage(m2); } - d->rptrMapMutex.unlock(); - } else if ((tableID == 0) && d->initReady) { - d->rptrMapMutex.lock(); + rptrMapMutex.unlock(); + } else if ((tableID == 0) && initReady) { + rptrMapMutex.lock(); std::string userCallsign = key; std::string arearp_cs = value; @@ -788,8 +693,8 @@ void IRCDDBApp::doUpdate(std::string &msg) ReplaceChar(userCallsign, '_', ' '); ReplaceChar(arearp_cs, '_', ' '); - if (d->rptrMap.end() != d->rptrMap.find(value)) { - IRCDDBAppRptrObject o = d->rptrMap[value]; + if (rptrMap.end() != rptrMap.find(value)) { + IRCDDBAppRptrObject o = rptrMap[value]; zonerp_cs = o.zonerp_cs; ReplaceChar(zonerp_cs, '_', ' '); zonerp_cs[7] = 'G'; @@ -803,9 +708,9 @@ void IRCDDBApp::doUpdate(std::string &msg) m2->addParam(zonerp_cs); m2->addParam(ip_addr); m2->addParam(tk + std::string(" ") + timeToken); - d->replyQ.putMessage(m2); + replyQ.putMessage(m2); - d->rptrMapMutex.unlock(); + rptrMapMutex.unlock(); } } @@ -850,12 +755,12 @@ void IRCDDBApp::msgQuery(IRCMessage *m) } doUpdate(restOfLine); } else if (cmd == std::string("LIST_END")) { - if (d->state == 5) { // if in sendlist processing state - d->state = 3; // get next table + if (state == 5) { // if in sendlist processing state + state = 3; // get next table } } else if (cmd == std::string("LIST_MORE")) { - if (d->state == 5) { // if in sendlist processing state - d->state = 4; // send next SENDLIST + if (state == 5) { // if in sendlist processing state + state = 4; // send next SENDLIST } } else if (cmd == std::string("NOT_FOUND")) { std::string callsign; @@ -877,7 +782,7 @@ void IRCDDBApp::msgQuery(IRCMessage *m) m2->addParam(""); m2->addParam(""); m2->addParam(""); - d->replyQ.putMessage(m2); + replyQ.putMessage(m2); } } } @@ -885,12 +790,12 @@ void IRCDDBApp::msgQuery(IRCMessage *m) void IRCDDBApp::setSendQ(IRCMessageQueue *s) { - d->sendQ = s; + sendQ = s; } IRCMessageQueue *IRCDDBApp::getSendQ() { - return d->sendQ; + return sendQ; } static std::string getLastEntryTime(int tableID) @@ -911,37 +816,37 @@ void IRCDDBApp::Entry() { int sendlistTableID = 0; - while (!d->terminateThread) { + while (!terminateThread) { - if (d->timer > 0) { - d->timer--; + if (timer > 0) { + timer--; } - switch(d->state) { + switch(state) { case 0: // wait for network to start if (getSendQ() != NULL) { - d->state = 1; + state = 1; } break; case 1: // connect to db - d->state = 2; - d->timer = 200; + state = 2; + timer = 200; break; case 2: // choose server printf("IRCDDBApp: state=2 choose new 's-'-user\n"); if (getSendQ() == NULL) { - d->state = 10; + state = 10; } else { if (findServerUser()) { sendlistTableID = numberOfTables; - d->state = 3; // next: send "SENDLIST" - } else if (d->timer == 0) { - d->state = 10; + state = 3; // next: send "SENDLIST" + } else if (timer == 0) { + state = 10; IRCMessage *m = new IRCMessage("QUIT"); m->addParam("no op user with 's-' found."); @@ -956,42 +861,42 @@ void IRCDDBApp::Entry() case 3: if (getSendQ() == NULL) { - d->state = 10; // disconnect DB + state = 10; // disconnect DB } else { sendlistTableID --; if (sendlistTableID < 0) { - d->state = 6; // end of sendlist + state = 6; // end of sendlist } else { printf("IRCDDBApp: state=3 tableID=%d\n", sendlistTableID); - d->state = 4; // send "SENDLIST" - d->timer = 900; // 15 minutes max for update + state = 4; // send "SENDLIST" + timer = 900; // 15 minutes max for update } } break; case 4: if (getSendQ() == NULL) { - d->state = 10; // disconnect DB + state = 10; // disconnect DB } else { if (1 == sendlistTableID) { - IRCMessage *m = new IRCMessage(d->currentServer, std::string("SENDLIST") + getTableIDString(sendlistTableID, true) + IRCMessage *m = new IRCMessage(currentServer, std::string("SENDLIST") + getTableIDString(sendlistTableID, true) + std::string(" ") + getLastEntryTime(sendlistTableID)); IRCMessageQueue *q = getSendQ(); if (q != NULL) q->putMessage(m); - d->state = 5; // wait for answers + state = 5; // wait for answers } else - d->state = 3; // don't send SENDLIST for this table (tableID 0), go to next table + state = 3; // don't send SENDLIST for this table (tableID 0), go to next table } break; case 5: // sendlist processing if (getSendQ() == NULL) { - d->state = 10; // disconnect DB - } else if (d->timer == 0) { - d->state = 10; // disconnect DB + state = 10; // disconnect DB + } else if (timer == 0) { + state = 10; // disconnect DB IRCMessage *m = new IRCMessage("QUIT"); m->addParam("timeout SENDLIST"); @@ -1006,31 +911,31 @@ void IRCDDBApp::Entry() case 6: if (getSendQ() == NULL) { - d->state = 10; // disconnect DB + state = 10; // disconnect DB } else { printf("IRCDDBApp: state=6 initialization completed\n"); - d->infoTimer = 2; + infoTimer = 2; - d->initReady = true; - d->state = 7; + initReady = true; + state = 7; } break; case 7: // standby state after initialization if (getSendQ() == NULL) - d->state = 10; // disconnect DB + state = 10; // disconnect DB - if (d->infoTimer > 0) { - d->infoTimer--; + if (infoTimer > 0) { + infoTimer--; - if (d->infoTimer == 0) { - d->moduleMapMutex.lock(); + if (infoTimer == 0) { + moduleMapMutex.lock(); - for (auto itl = d->locationMap.begin(); itl != d->locationMap.end(); itl++) { + for (auto itl = locationMap.begin(); itl != locationMap.end(); itl++) { std::string value = itl->second; - IRCMessage *m = new IRCMessage(d->currentServer, std::string("IRCDDB RPTRQTH: ") + value); + IRCMessage *m = new IRCMessage(currentServer, std::string("IRCDDB RPTRQTH: ") + value); IRCMessageQueue * q = getSendQ(); if (q != NULL) { @@ -1038,9 +943,9 @@ void IRCDDBApp::Entry() } } - for (auto itu = d->urlMap.begin(); itu != d->urlMap.end(); itu++) { + for (auto itu = urlMap.begin(); itu != urlMap.end(); itu++) { std::string value = itu->second; - IRCMessage * m = new IRCMessage(d->currentServer, std::string("IRCDDB RPTRURL: ") + value); + IRCMessage * m = new IRCMessage(currentServer, std::string("IRCDDB RPTRURL: ") + value); IRCMessageQueue * q = getSendQ(); if (q != NULL) { @@ -1048,9 +953,9 @@ void IRCDDBApp::Entry() } } - for(auto itm = d->moduleMap.begin(); itm != d->moduleMap.end(); itm++) { + for(auto itm = moduleMap.begin(); itm != moduleMap.end(); itm++) { std::string value = itm->second; - IRCMessage * m = new IRCMessage(d->currentServer, std::string("IRCDDB RPTRQRG: ") + value); + IRCMessage * m = new IRCMessage(currentServer, std::string("IRCDDB RPTRQRG: ") + value); IRCMessageQueue *q = getSendQ(); if (q != NULL) { @@ -1058,9 +963,9 @@ void IRCDDBApp::Entry() } } - for(auto its = d->swMap.begin(); its != d->swMap.end(); its++) { + for(auto its = swMap.begin(); its != swMap.end(); its++) { std::string value = its->second; - IRCMessage * m = new IRCMessage(d->currentServer, std::string("IRCDDB RPTRSW: ") + value); + IRCMessage * m = new IRCMessage(currentServer, std::string("IRCDDB RPTRSW: ") + value); IRCMessageQueue *q = getSendQ(); if (q != NULL) { @@ -1068,17 +973,17 @@ void IRCDDBApp::Entry() } } - d->moduleMapMutex.unlock(); + moduleMapMutex.unlock(); } } - if (d->wdTimer > 0) { - d->wdTimer--; - if (d->wdTimer <= 0) { - d->wdTimer = 900; // 15 minutes + if (wdTimer > 0) { + wdTimer--; + if (wdTimer <= 0) { + wdTimer = 900; // 15 minutes - IRCMessage *m = new IRCMessage(d->currentServer, std::string("IRCDDB WATCHDOG: ") + - getCurrentTime() + std::string(" ") + d->wdInfo + std::string(" 1")); + IRCMessage *m = new IRCMessage(currentServer, std::string("IRCDDB WATCHDOG: ") + + getCurrentTime() + std::string(" ") + wdInfo + std::string(" 1")); IRCMessageQueue *q = getSendQ(); if (q != NULL) @@ -1091,9 +996,9 @@ void IRCDDBApp::Entry() case 10: // disconnect db - d->state = 0; - d->timer = 0; - d->initReady = false; + state = 0; + timer = 0; + initReady = false; break; } diff --git a/ircddb/IRCDDBApp.h b/ircddb/IRCDDBApp.h index 30b1d88..532abd3 100644 --- a/ircddb/IRCDDBApp.h +++ b/ircddb/IRCDDBApp.h @@ -2,11 +2,59 @@ #include #include +#include +#include +#include #include "IRCDDB.h" #include "IRCMessageQueue.h" -class IRCDDBAppPrivate; +class IRCDDBAppGateObject +{ +public: + + std::string nick; + std::string name; + std::string host; + bool op; + unsigned int usn; + + IRCDDBAppGateObject() {} + + IRCDDBAppGateObject(const std::string &n, const std::string &nm, const std::string &h) { + nick = n; + name = nm; + host = h; + op = false; + usn = counter; + counter++; + } + static unsigned int counter; +}; + +class IRCDDBAppRptrObject +{ +public: + + std::string arearp_cs; + time_t lastChanged; + std::string zonerp_cs; + + IRCDDBAppRptrObject() { + } + + IRCDDBAppRptrObject(time_t dt, std::string &repeaterCallsign, std::string &gatewayCallsign) { + arearp_cs = repeaterCallsign; + lastChanged = dt; + zonerp_cs = gatewayCallsign; + + if (dt > maxTime) { + maxTime = dt; + } + } + + static time_t maxTime; +}; class IRCDDBApp { @@ -64,6 +112,38 @@ private: void doNotFound(std::string &msg, std::string &retval); std::string getIPAddress(std::string &zonerp_cs); bool findServerUser(); - IRCDDBAppPrivate *d; std::future worker_thread; + IRCMessageQueue *sendQ; + IRCMessageQueue replyQ; + + std::map user; + std::mutex userMapMutex; + std::map rptrMap; + std::mutex rptrMapMutex; + std::map moduleMap; + std::mutex moduleMapMutex; + std::map locationMap; + std::mutex locationMapMutex; + std::map urlMap; + std::mutex urlMapMutex; + std::map swMap; + std::mutex swMapMutex; + + std::string currentServer; + std::string myNick; + + std::regex tablePattern, datePattern, timePattern, dbPattern, modulePattern; + + int state; + int timer; + int infoTimer; + int wdTimer; + + std::string updateChannel; + std::string channelTopic; + std::string bestServer; + std::string wdInfo; + + bool initReady; + bool terminateThread; }; diff --git a/ircddb/IRCReceiver.cpp b/ircddb/IRCReceiver.cpp index 25d0a59..ae2c12f 100644 --- a/ircddb/IRCReceiver.cpp +++ b/ircddb/IRCReceiver.cpp @@ -6,7 +6,30 @@ #include "IRCMessage.h" #include "IRCReceiver.h" -static int doRead(CTCPReaderWriterClient *ircSock, char *buf, int buf_size) +IRCReceiver::IRCReceiver(CTCPReaderWriterClient *sock, IRCMessageQueue *q) +{ + ircSock = sock; + recvQ = q; +} + +IRCReceiver::~IRCReceiver() +{ +} + +bool IRCReceiver::startWork() +{ + terminateThread = false; + rec_thread = std::async(std::launch::async, &IRCReceiver::Entry, this); + return true; +} + +void IRCReceiver::stopWork() +{ + terminateThread = true; + rec_thread.get(); +} + +int IRCReceiver::doRead(CTCPReaderWriterClient *ircSock, char *buf, int buf_size) { struct timeval tv; tv.tv_sec = 1; @@ -133,26 +156,3 @@ void IRCReceiver::Entry() return; } - -IRCReceiver::IRCReceiver(CTCPReaderWriterClient *sock, IRCMessageQueue *q) -{ - ircSock = sock; - recvQ = q; -} - -IRCReceiver::~IRCReceiver() -{ -} - -bool IRCReceiver::startWork() -{ - terminateThread = false; - rec_thread = std::async(std::launch::async, &IRCReceiver::Entry, this); - return true; -} - -void IRCReceiver::stopWork() -{ - terminateThread = true; - rec_thread.get(); -} diff --git a/ircddb/IRCReceiver.h b/ircddb/IRCReceiver.h index e1241cd..f09c237 100644 --- a/ircddb/IRCReceiver.h +++ b/ircddb/IRCReceiver.h @@ -15,6 +15,8 @@ protected: virtual void Entry(); private: + static int doRead(CTCPReaderWriterClient *ircSock, char *buf, int buf_size); + CTCPReaderWriterClient *ircSock; bool terminateThread; int sock;