no wxWidgits!

pull/1/head
Tom Early 10 years ago
parent 6078a5b124
commit 89756075e7

@ -1,47 +1,24 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_IRCAPPLICATION_H)
#define _IRCAPPLICATION_H
#include <wx/wx.h>
#pragma once
#include <string>
#include "IRCMessageQueue.h"
class IRCApplication
{
public:
virtual void userJoin (const wxString& nick, const wxString& name, const wxString& host) = 0;
virtual void userLeave (const wxString& nick) = 0;
virtual void userChanOp (const wxString& nick, bool op) = 0;
virtual void userJoin(const std::string& nick, const std::string& name, const std::string& host) = 0;
virtual void userLeave(const std::string& nick) = 0;
virtual void userChanOp(const std::string& nick, bool op) = 0;
virtual void userListReset(void) = 0;
virtual void msgChannel(IRCMessage * m) = 0;
virtual void msgQuery(IRCMessage * m) = 0;
virtual void setCurrentNick(const wxString& nick) = 0;
virtual void setTopic(const wxString& topic) = 0;
virtual void setCurrentNick(const std::string& nick) = 0;
virtual void setTopic(const std::string& topic) = 0;
virtual void setBestServer(const wxString& ircUser) = 0;
virtual void setBestServer(const std::string& ircUser) = 0;
virtual void setSendQ(IRCMessageQueue *s) = 0;
virtual IRCMessageQueue *getSendQ(void) = 0;
@ -49,6 +26,3 @@ public:
virtual ~IRCApplication() {}
};
#endif

@ -1,74 +1,32 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010-2011 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif
#include <unistd.h>
#include <string.h>
#include "IRCClient.h"
#include "IRCutils.h"
#include <wx/wx.h>
#include <fcntl.h>
#include <errno.h>
IRCClient::IRCClient( IRCApplication * app, const wxString& update_channel,
const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password,
const wxString& versionInfo, const wxString& localAddr )
: wxThread(wxTHREAD_JOINABLE)
IRCClient::IRCClient(IRCApplication *app, const std::string &update_channel, const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password,
const std::string &versionInfo, const std::string &localAddr)
{
safeStringCopy(host_name, hostName.mb_str(), sizeof host_name);
safeStringCopy(host_name, hostName.c_str(), sizeof host_name);
this -> callsign = callsign.Lower();
this->callsign = callsign;
ToLower(this->callsign);
this->port = port;
this->password = password;
this->app = app;
if (localAddr.IsEmpty()) {
if (localAddr.empty())
safeStringCopy(local_addr, "0.0.0.0", sizeof local_addr);
} else {
safeStringCopy(local_addr, localAddr.mb_str(), sizeof local_addr);
}
else
safeStringCopy(local_addr, localAddr.c_str(), sizeof local_addr);
proto = new IRCProtocol(app, this->callsign, password, update_channel, versionInfo);
@ -86,34 +44,23 @@ IRCClient::~IRCClient()
bool IRCClient::startWork()
{
if (Create() != wxTHREAD_NO_ERROR) {
wxLogError(wxT("IRCClient::startWork: Could not create the worker thread!"));
return false;
}
terminateThread = false;
if (Run() != wxTHREAD_NO_ERROR) {
wxLogError(wxT("IRCClient::startWork: Could not run the worker thread!"));
return false;
}
client_thread = std::async(std::launch::async, &IRCClient::Entry, this);
return true;
}
void IRCClient::stopWork()
{
terminateThread = true;
Wait();
client_thread.get();
}
wxThread::ExitCode IRCClient::Entry ()
#define MAXIPV4ADDR 10
void IRCClient::Entry()
{
unsigned int numAddr;
#define MAXIPV4ADDR 10
struct sockaddr_in addr[MAXIPV4ADDR];
struct sockaddr_in myaddr;
@ -123,15 +70,12 @@ wxThread::ExitCode IRCClient::Entry ()
int sock = 0;
unsigned int currentAddr = 0;
int result;
numAddr = 0;
result = getAllIPV4Addresses(local_addr, 0, &numAddr, &myaddr, 1);
int result = getAllIPV4Addresses(local_addr, 0, &numAddr, &myaddr, 1);
if ((result != 0) || (numAddr != 1)) {
wxLogVerbose(wxT("IRCClient::Entry: local address not parseable, using 0.0.0.0"));
traceit("IRCClient::Entry: local address not parseable, using 0.0.0.0\n");
memset(&myaddr, 0x00, sizeof(struct sockaddr_in));
}
@ -144,15 +88,15 @@ wxThread::ExitCode IRCClient::Entry ()
switch (state) {
case 0:
if (terminateThread) {
wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state);
return 0;
traceit("IRCClient::Entry: thread terminated at state=%d\n", state);
return;
}
if (timer == 0) {
timer = 30;
if (getAllIPV4Addresses(host_name, port, &numAddr, addr, MAXIPV4ADDR) == 0) {
wxLogVerbose(wxT("IRCClient::Entry: number of DNS entries %d"), numAddr);
//traceit("IRCClient::Entry: number of DNS entries %d\n", numAddr);
if (numAddr > 0) {
currentAddr = 0;
state = 1;
@ -164,53 +108,36 @@ wxThread::ExitCode IRCClient::Entry ()
case 1:
if (terminateThread) {
wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state);
return 0;
traceit("IRCClient::Entry: thread terminated at state=%d\n", state);
return;
}
if (timer == 0) {
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
wxLogSysError(wxT("IRCClient::Entry: socket"));
traceit("IRCClient::Entry: could not create socket!\n");
timer = 30;
state = 0;
} else {
#if defined(__WINDOWS__)
u_long nonBlock = 1UL;
if (ioctlsocket( sock, FIONBIO, &nonBlock ) != 0) {
wxLogSysError(wxT("IRCClient::Entry: ioctlsocket"));
closesocket(sock);
timer = 30;
state = 0;
}
#else
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
wxLogSysError(wxT("IRCClient::Entry: fcntl"));
traceit("IRCClient::Entry: fcntl error\n");
close(sock);
timer = 30;
state = 0;
}
#endif
else {
unsigned char *h = (unsigned char *) &(myaddr.sin_addr);
int res;
if ((h[0] != 0) || (h[1] != 0) || (h[2] != 0) || (h[3] != 0)) {
wxLogVerbose(wxT("IRCClient::Entry: bind: local address %d.%d.%d.%d"),
h[0], h[1], h[2], h[3]);
}
if ((h[0] != 0) || (h[1] != 0) || (h[2] != 0) || (h[3] != 0))
traceit("IRCClient::Entry: bind: local address %d.%d.%d.%d\n", h[0], h[1], h[2], h[3]);
res = bind(sock, (struct sockaddr *) &myaddr, sizeof (struct sockaddr_in));
if (res != 0) {
wxLogSysError(wxT("IRCClient::Entry: bind"));
#if defined(__WINDOWS__)
closesocket(sock);
#else
traceit("IRCClient::Entry: bind error\n");
close(sock);
#endif
state = 0;
timer = 30;
break;
@ -218,31 +145,21 @@ wxThread::ExitCode IRCClient::Entry ()
h = (unsigned char *) &(addr[currentAddr].sin_addr);
wxLogVerbose(wxT("IRCClient::Entry: trying to connect to %d.%d.%d.%d"),
h[0], h[1], h[2], h[3]);
//traceit("IRCClient::Entry: trying to connect to %d.%d.%d.%d\n", h[0], h[1], h[2], h[3]);
res = connect(sock, (struct sockaddr *) (addr + currentAddr), sizeof (struct sockaddr_in));
if (res == 0) {
wxLogVerbose(wxT("IRCClient::Entry: connected"));
traceit("IRCClient::Entry: connected to %d.%d.%d.%d\n", h[0], h[1], h[2], h[3]);
state = 4;
} else {
#if defined(__WINDOWS__)
if (WSAGetLastError() == WSAEWOULDBLOCK)
#else
if (errno == EINPROGRESS)
#endif
{
wxLogVerbose(wxT("IRCClient::Entry: connect in progress"));
if (errno == EINPROGRESS) {
//traceit("IRCClient::Entry: connect in progress\n");
state = 3;
timer = 10; // 5 second timeout
} else {
wxLogSysError(wxT("IRCClient::Entry: connect"));
#if defined(__WINDOWS__)
closesocket(sock);
#else
traceit("IRCClient::Entry: connect\n");
close(sock);
#endif
currentAddr++;
if (currentAddr >= numAddr) {
state = 0;
@ -265,45 +182,28 @@ wxThread::ExitCode IRCClient::Entry ()
fd_set myset;
FD_ZERO(&myset);
FD_SET(sock, &myset);
int res;
res = select(sock+1, NULL, &myset, NULL, &tv);
int res = select(sock+1, NULL, &myset, NULL, &tv);
if (res < 0) {
wxLogSysError(wxT("IRCClient::Entry: select"));
#if defined(__WINDOWS__)
closesocket(sock);
#else
traceit("IRCClient::Entry: select\n");
close(sock);
#endif
state = 0;
timer = 30;
} else if (res > 0) { // connect is finished
#if defined(__WINDOWS__)
int val_len;
#else
socklen_t val_len;
#endif
int value;
val_len = sizeof value;
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *) &value, &val_len) < 0) {
wxLogSysError(wxT("IRCClient::Entry: getsockopt"));
#if defined(__WINDOWS__)
closesocket(sock);
#else
traceit("IRCClient::Entry: getsockopt error\n");
close(sock);
#endif
state = 0;
timer = 30;
} else {
if (value != 0) {
wxLogWarning(wxT("IRCClient::Entry: SO_ERROR=%d"), value);
#if defined(__WINDOWS__)
closesocket(sock);
#else
traceit("IRCClient::Entry: SO_ERROR=%d\n", value);
close(sock);
#endif
currentAddr ++;
if (currentAddr >= numAddr) {
state = 0;
@ -313,19 +213,15 @@ wxThread::ExitCode IRCClient::Entry ()
timer = 2;
}
} else {
wxLogVerbose(wxT("IRCClient::Entry: connected2"));
traceit("IRCClient::Entry: connected2\n");
state = 4;
}
}
} else if (timer == 0) {
// select timeout and timer timeout
wxLogVerbose(wxT("IRCClient::Entry: connect timeout"));
#if defined(__WINDOWS__)
closesocket(sock);
#else
//traceit("IRCClient::Entry: connect timeout\n");
close(sock);
#endif
currentAddr++;
if (currentAddr >= numAddr) {
state = 0;
@ -370,29 +266,29 @@ wxThread::ExitCode IRCClient::Entry ()
while ((state == 5) && sendQ->messageAvailable()) {
IRCMessage * m = sendQ->getMessage();
wxString out;
std::string out;
m->composeMessage(out);
char buf[200];
safeStringCopy(buf, out.mb_str(wxConvUTF8), sizeof buf);
safeStringCopy(buf, out.c_str(), sizeof buf);
int len = strlen(buf);
if (buf[len - 1] == 10) { // is there a NL char at the end?
int r = send(sock, buf, len, 0);
if (r != len) {
wxLogVerbose(wxT("IRCClient::Entry: short write %d < %d"), r, len);
traceit("IRCClient::Entry: short write %d < %d\n", r, len);
timer = 0;
state = 6;
}
/* else
{
wxLogVerbose(wxT("write %d bytes (") + out + wxT(")"), len );
traceit("write %d bytes (%s)\n", len, out.c_str());
} */
} else {
wxLogVerbose(wxT("IRCClient::Entry: no NL at end, len=%d"), len);
traceit("IRCClient::Entry: no NL at end, len=%d\n", len);
timer = 0;
state = 6;
@ -412,38 +308,26 @@ wxThread::ExitCode IRCClient::Entry ()
proto->setNetworkReady(false);
recv->stopWork();
wxThread::Sleep(2000);
sleep(2);
delete recv;
delete recvQ;
delete sendQ;
#if defined(__WINDOWS__)
closesocket(sock);
#else
close(sock);
#endif
if (terminateThread) { // request to end the thread
wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state);
return 0;
traceit("IRCClient::Entry: thread terminated at state=%d\n", state);
return;
}
timer = 30;
state = 0; // reconnect to IRC server
}
break;
} // switch
usleep(500000);
}
wxThread::Sleep(500);
}
return 0;
return;
}

@ -1,65 +1,31 @@
/*
#pragma once
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010-2011 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_IRCCLIENT_H)
#define _IRCCLIENT_H
#include <future>
#include "IRCReceiver.h"
#include "IRCMessageQueue.h"
#include "IRCProtocol.h"
#include "IRCApplication.h"
#include <wx/wx.h>
class IRCClient : public wxThread
class IRCClient
{
public:
IRCClient(IRCApplication *app, const std::string &update_channel, const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password,
const std::string &versionInfo, const std::string &localAddr);
IRCClient( IRCApplication * app, const wxString& update_channel,
const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password,
const wxString& versionInfo, const wxString& localAddr );
~IRCClient();
virtual ~IRCClient();
bool startWork();
void stopWork();
protected:
virtual wxThread::ExitCode Entry();
virtual void Entry();
private:
char host_name[100];
char local_addr[100];
unsigned int port;
wxString callsign;
wxString password;
std::string callsign;
std::string password;
bool terminateThread;
@ -67,10 +33,7 @@ private:
IRCMessageQueue *recvQ;
IRCMessageQueue *sendQ;
IRCProtocol *proto;
std::future<void> client_thread;
IRCApplication *app;
};
#endif

@ -1,32 +1,8 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010-2011 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#include "IRCDDB.h"
#include "IRCClient.h"
#include "IRCDDBApp.h"
#include <wx/wx.h>
#include "IRCutils.h"
struct CIRCDDBPrivate {
IRCClient *client;
@ -34,17 +10,15 @@ struct CIRCDDBPrivate {
};
CIRCDDB::CIRCDDB(const wxString& hostName, unsigned int port,
const wxString& callsign, const wxString& password,
const wxString& versionInfo, const wxString& localAddr ) : d( new CIRCDDBPrivate )
CIRCDDB::CIRCDDB(const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo, const std::string &localAddr)
: d(new CIRCDDBPrivate)
{
wxString update_channel = wxT("#dstar");
std::string update_channel = "#dstar";
d->app = new IRCDDBApp(update_channel);
d->client = new IRCClient( d->app, update_channel, hostName, port, callsign,
password, versionInfo, localAddr );
d->client = new IRCClient(d->app, update_channel, hostName, port, callsign, password, versionInfo, localAddr);
}
CIRCDDB::~CIRCDDB()
@ -58,7 +32,7 @@ CIRCDDB::~CIRCDDB()
// A false return implies a network error, or unable to log in
bool CIRCDDB::open()
{
wxLogVerbose(wxT("start"));
traceit("start");
return d->client->startWork() && d->app->startWork();
}
@ -69,229 +43,215 @@ int CIRCDDB::getConnectionState()
}
void CIRCDDB::rptrQTH(const wxString& rptrcall, double latitude, double longitude, const wxString& desc1, const wxString& desc2, const wxString& infoURL, const wxString &swVersion)
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);
}
void CIRCDDB::rptrQRG(const wxString& rptrcall, double txFrequency, double duplexShift, double range, double agl)
void CIRCDDB::rptrQRG(const std::string &rptrcall, double txFrequency, double duplexShift, double range, double agl)
{
d->app->rptrQRG(rptrcall, txFrequency, duplexShift, range, agl);
}
void CIRCDDB::kickWatchdog ( const wxString& wdInfo )
void CIRCDDB::kickWatchdog(const std::string &wdInfo)
{
d->app->kickWatchdog(wdInfo);
}
// Send heard data, a false return implies a network error
bool CIRCDDB::sendHeard( const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3 )
bool CIRCDDB::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)
{
if (myCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8"));
if (myCall.size() != 8) {
traceit("CIRCDDB::sendHeard:myCall: len != 8");
return false;
}
if (myCallExt.Len() != 4) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4"));
if (myCallExt.size() != 4) {
traceit("CIRCDDB::sendHeard:myCallExt: len != 4");
return false;
}
if (yourCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8"));
if (yourCall.size() != 8) {
traceit("CIRCDDB::sendHeard:yourCall: len != 8");
return false;
}
if (rpt1.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8"));
if (rpt1.size() != 8) {
traceit("CIRCDDB::sendHeard:rpt1: len != 8");
return false;
}
if (rpt2.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8"));
if (rpt2.size() != 8) {
traceit("CIRCDDB::sendHeard:rpt2: len != 8");
return false;
}
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
wxT(" "), wxT(""), wxT(""));
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, " ", "", "");
}
// Send heard data, a false return implies a network error
bool CIRCDDB::sendHeardWithTXMsg( const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3,
const wxString& network_destination,
const wxString& tx_message )
bool CIRCDDB::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)
{
if (myCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8"));
if (myCall.size() != 8) {
traceit("CIRCDDB::sendHeard:myCall: len != 8");
return false;
}
if (myCallExt.Len() != 4) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4"));
if (myCallExt.size() != 4) {
traceit("CIRCDDB::sendHeard:myCallExt: len != 4");
return false;
}
if (yourCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8"));
if (yourCall.size() != 8) {
traceit("CIRCDDB::sendHeard:yourCall: len != 8");
return false;
}
if (rpt1.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8"));
if (rpt1.size() != 8) {
traceit("CIRCDDB::sendHeard:rpt1: len != 8");
return false;
}
if (rpt2.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8"));
if (rpt2.size() != 8) {
traceit("CIRCDDB::sendHeard:rpt2: len != 8");
return false;
}
wxString dest = network_destination;
std::string dest = network_destination;
if (dest.Len() == 0) {
dest = wxT(" ");
}
if (dest.size() == 0)
dest = " ";
if (dest.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:network_destination: len != 8"));
if (dest.size() != 8) {
traceit("CIRCDDB::sendHeard:network_destination: len != 8");
return false;
}
wxString msg;
std::string msg;
if (tx_message.Len() == 20) {
unsigned int i;
for (i=0; i < tx_message.Len(); i++) {
wxChar ch = tx_message.GetChar(i);
if (tx_message.length() == 20) {
for (unsigned int i=0; i < tx_message.size(); i++) {
char ch = tx_message.at(i);
if ((ch > 32) && (ch < 127)) {
msg.Append(ch);
if (ch>32 && ch<127) {
msg.push_back(ch);
} else {
msg.Append(wxT('_'));
msg.push_back('_');
}
}
}
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
dest, msg, wxT(""));
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3, dest, msg, "");
}
bool CIRCDDB::sendHeardWithTXStats( const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3,
int num_dv_frames,
int num_dv_silent_frames,
int num_bit_errors )
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)
{
if ((num_dv_frames <= 0) || (num_dv_frames > 65535)) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:num_dv_frames not in range 1-65535"));
if (num_dv_frames<= 0 || num_dv_frames>65535) {
traceit("CIRCDDB::sendHeard:num_dv_frames not in range 1-65535");
return false;
}
if (num_dv_silent_frames > num_dv_frames) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:num_dv_silent_frames > num_dv_frames"));
traceit("CIRCDDB::sendHeard:num_dv_silent_frames > num_dv_frames");
return false;
}
if (num_bit_errors > (4*num_dv_frames)) { // max 4 bit errors per frame
wxLogVerbose(wxT("CIRCDDB::sendHeard:num_bit_errors > (4*num_dv_frames)"));
if (num_bit_errors > 4*num_dv_frames) { // max 4 bit errors per frame
traceit("CIRCDDB::sendHeard:num_bit_errors > (4*num_dv_frames)");
return false;
}
if (myCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8"));
if (myCall.size() != 8) {
traceit("CIRCDDB::sendHeard:myCall: len != 8");
return false;
}
if (myCallExt.Len() != 4) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4"));
if (myCallExt.size() != 4) {
traceit("CIRCDDB::sendHeard:myCallExt: len != 4");
return false;
}
if (yourCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8"));
if (yourCall.size() != 8) {
traceit("CIRCDDB::sendHeard:yourCall: len != 8");
return false;
}
if (rpt1.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8"));
if (rpt1.size() != 8) {
traceit("CIRCDDB::sendHeard:rpt1: len != 8");
return false;
}
if (rpt2.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8"));
if (rpt2.size() != 8) {
traceit("CIRCDDB::sendHeard:rpt2: len != 8");
return false;
}
wxString stats = wxString::Format(wxT("%04x"), num_dv_frames);
char buf[16];
snprintf(buf, 16, "%04x", num_dv_frames);
std::string stats = buf;
if (num_dv_silent_frames >= 0) {
wxString s = wxString::Format(wxT("%02x"), (num_dv_silent_frames * 100) / num_dv_frames);
stats.Append(s);
snprintf(buf, 16, "%02x", num_dv_silent_frames * 100 / num_dv_frames);
stats.append(buf);
if (num_bit_errors >= 0) {
s = wxString::Format(wxT("%02x"), (num_bit_errors * 125) / (num_dv_frames * 3));
stats.Append(s);
snprintf(buf,16, "%02x", num_bit_errors * 125 / (num_dv_frames * 3));
stats.append(buf);
} else {
stats.Append(wxT("__"));
stats.append("__");
}
} else {
stats.Append(wxT("____"));
stats.append("____");
}
stats.Append(wxT("____________")); // stats string should have 20 chars
stats.append("____________"); // stats string should have 20 chars
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
wxT(" "), wxT(""), 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
bool CIRCDDB::findGateway(const wxString& gatewayCallsign)
bool CIRCDDB::findGateway(const std::string &gatewayCallsign)
{
if (gatewayCallsign.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::findGateway: len != 8"));
if (gatewayCallsign.size() != 8) {
traceit("CIRCDDB::findGateway: len != 8");
return false;
}
return d->app->findGateway( gatewayCallsign.Upper());
std::string gcs = gatewayCallsign;
ToUpper(gcs);
return d->app->findGateway(gcs);
}
bool CIRCDDB::findRepeater(const wxString& repeaterCallsign)
bool CIRCDDB::findRepeater(const std::string &repeaterCallsign)
{
if (repeaterCallsign.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::findRepeater: len != 8"));
if (repeaterCallsign.size() != 8) {
traceit("CIRCDDB::findRepeater: len != 8");
return false;
}
return d->app->findRepeater( repeaterCallsign.Upper());
std::string rcs = repeaterCallsign;
ToUpper(rcs);
return d->app->findRepeater(rcs);
}
// Send query for a user, a false return implies a network error
bool CIRCDDB::findUser(const wxString& userCallsign)
bool CIRCDDB::findUser(const std::string &userCallsign)
{
if (userCallsign.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::findUser: len != 8"));
if (userCallsign.size() != 8) {
traceit("CIRCDDB::findUser: len != 8");
return false;
}
return d->app->findUser( userCallsign.Upper());
std::string ucs = userCallsign;
ToUpper(ucs);
return d->app->findUser(ucs);
}
// The following functions are for processing received messages
@ -304,29 +264,29 @@ IRCDDB_RESPONSE_TYPE CIRCDDB::getMessageType()
// Get a gateway message, as a result of IDRT_REPEATER returned from getMessageType()
// A false return implies a network error
bool CIRCDDB::receiveRepeater(wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address, DSTAR_PROTOCOL& /*protocol*/)
bool CIRCDDB::receiveRepeater(std::string &repeaterCallsign, std::string &gatewayCallsign, std::string &address, DSTAR_PROTOCOL &/*protocol*/)
{
IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType();
if (rt != IDRT_REPEATER) {
wxLogError(wxT("CIRCDDB::receiveRepeater: unexpected response type"));
traceit("CIRCDDB::receiveRepeater: unexpected response type");
return false;
}
IRCMessage * m = d->app->getReplyMessage();
if (m == NULL) {
wxLogError(wxT("CIRCDDB::receiveRepeater: no message"));
traceit("CIRCDDB::receiveRepeater: no message");
return false;
}
if (!m->getCommand().IsSameAs(wxT("IDRT_REPEATER"))) {
wxLogError(wxT("CIRCDDB::receiveRepeater: wrong message type"));
if (m->getCommand().compare("IDRT_REPEATER")) {
traceit("CIRCDDB::receiveRepeater: wrong message type");
return false;
}
if (m->getParamCount() != 3) {
wxLogError(wxT("CIRCDDB::receiveRepeater: unexpected number of message parameters"));
traceit("CIRCDDB::receiveRepeater: unexpected number of message parameters");
return false;
}
@ -341,29 +301,29 @@ bool CIRCDDB::receiveRepeater(wxString& repeaterCallsign, wxString& gatewayCalls
// Get a gateway message, as a result of IDRT_GATEWAY returned from getMessageType()
// A false return implies a network error
bool CIRCDDB::receiveGateway(wxString& gatewayCallsign, wxString& address, DSTAR_PROTOCOL& /*protocol*/)
bool CIRCDDB::receiveGateway(std::string &gatewayCallsign, std::string &address, DSTAR_PROTOCOL& /*protocol*/)
{
IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType();
if (rt != IDRT_GATEWAY) {
wxLogError(wxT("CIRCDDB::receiveGateway: unexpected response type"));
traceit("CIRCDDB::receiveGateway: unexpected response type");
return false;
}
IRCMessage * m = d->app->getReplyMessage();
if (m == NULL) {
wxLogError(wxT("CIRCDDB::receiveGateway: no message"));
traceit("CIRCDDB::receiveGateway: no message");
return false;
}
if (!m->getCommand().IsSameAs(wxT("IDRT_GATEWAY"))) {
wxLogError(wxT("CIRCDDB::receiveGateway: wrong message type"));
if (m->getCommand().compare("IDRT_GATEWAY")) {
traceit("CIRCDDB::receiveGateway: wrong message type");
return false;
}
if (m->getParamCount() != 2) {
wxLogError(wxT("CIRCDDB::receiveGateway: unexpected number of message parameters"));
traceit("CIRCDDB::receiveGateway: unexpected number of message parameters");
return false;
}
@ -377,36 +337,36 @@ bool CIRCDDB::receiveGateway(wxString& gatewayCallsign, wxString& address, DSTAR
// Get a user message, as a result of IDRT_USER returned from getMessageType()
// A false return implies a network error
bool CIRCDDB::receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address)
bool CIRCDDB::receiveUser(std::string &userCallsign, std::string &repeaterCallsign, std::string &gatewayCallsign, std::string &address)
{
wxString dummy;
std::string dummy;
return receiveUser(userCallsign, repeaterCallsign, gatewayCallsign, address, dummy);
}
bool CIRCDDB::receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address,
wxString& timeStamp)
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();
if (rt != IDRT_USER) {
wxLogError(wxT("CIRCDDB::receiveUser: unexpected response type"));
traceit("CIRCDDB::receiveUser: unexpected response type");
return false;
}
IRCMessage * m = d->app->getReplyMessage();
if (m == NULL) {
wxLogError(wxT("CIRCDDB::receiveUser: no message"));
traceit("CIRCDDB::receiveUser: no message");
return false;
}
if (!m->getCommand().IsSameAs(wxT("IDRT_USER"))) {
wxLogError(wxT("CIRCDDB::receiveUser: wrong message type"));
if (m->getCommand().compare("IDRT_USER")) {
traceit("CIRCDDB::receiveUser: wrong message type");
return false;
}
if (m->getParamCount() != 5) {
wxLogError(wxT("CIRCDDB::receiveUser: unexpected number of message parameters"));
traceit("CIRCDDB::receiveUser: unexpected number of message parameters");
return false;
}

@ -1,29 +1,6 @@
/*
#pragma once
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010-2011 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_IRCDDB_H)
#define _IRCDDB_H
#include <wx/wx.h>
#include <string>
enum IRCDDB_RESPONSE_TYPE {
IDRT_NONE,
@ -44,8 +21,7 @@ struct CIRCDDBPrivate;
class CIRCDDB
{
public:
CIRCDDB(const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password,
const wxString& versionInfo, const wxString& localAddr = wxEmptyString );
CIRCDDB(const std::string &hostName, unsigned int port, const std::string &callsign, const std::string &password, const std::string &versionInfo, const std::string &localAddr = "");
~CIRCDDB();
// A false return implies a network error, or unable to log in
@ -58,7 +34,7 @@ public:
// longitude WGS84 position of antenna in degrees, positive value -> EAST
// desc1, desc2 20-character description of QTH
void rptrQTH(const wxString& rptrcall, double latitude, double longitude, const wxString& desc1, const wxString& desc2, const wxString& infoURL, const wxString &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);
@ -69,7 +45,7 @@ public:
// range range of the repeater in meters (meters = miles * 1609.344)
// agl height of the antenna above ground in meters (meters = feet * 0.3048)
void rptrQRG(const wxString& 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
@ -80,7 +56,7 @@ public:
// version of the RF decoding software. For example, the ircDDB java software sets this
// to "rpm_ircddbmhd-x.z-z". The string wdInfo must contain at least one non-space character.
void kickWatchdog(const wxString& wdInfo);
void kickWatchdog(const std::string &wdInfo);
@ -94,10 +70,7 @@ public:
// 10 = some network error occured, next state is "0" (new connection attempt)
// Send heard data, a false return implies a network error
bool sendHeard(const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1,
const wxString& 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:
@ -105,12 +78,8 @@ public:
// or reflector, where this transmission is relayed to.
// tx_message: 20-char TX message or empty string, if the user did not
// send a TX message
bool sendHeardWithTXMsg(const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3,
const wxString& network_destination,
const wxString& 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,
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
// num_dv_frames: number of DV frames sent out (96 bit frames, 20ms)
@ -122,24 +91,19 @@ public:
// So, the overall bit error rate is calculated like this:
// BER = num_bit_errors / (num_dv_frames * 24)
// Set num_bit_errors = -1, if the error information is not available.
bool sendHeardWithTXStats(const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3,
int num_dv_frames,
int num_dv_silent_frames,
int num_bit_errors );
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);
// The following three functions don't block waiting for a reply, they just send the data
// Send query for a gateway/reflector, a false return implies a network error
bool findGateway(const wxString& gatewayCallsign);
bool findGateway(const std::string &gatewayCallsign);
// Send query for a repeater module, a false return implies a network error
bool findRepeater(const wxString& repeaterCallsign);
bool findRepeater(const std::string &repeaterCallsign);
// Send query for a user, a false return implies a network error
bool findUser(const wxString& userCallsign);
bool findUser(const std::string &userCallsign);
// The following functions are for processing received messages
@ -148,18 +112,17 @@ public:
// Get a gateway message, as a result of IDRT_REPEATER returned from getMessageType()
// A false return implies a network error
bool receiveRepeater(wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address, DSTAR_PROTOCOL& protocol);
bool receiveRepeater(std::string &repeaterCallsign, std::string &gatewayCallsign, std::string &address, DSTAR_PROTOCOL& protocol);
// Get a gateway message, as a result of IDRT_GATEWAY returned from getMessageType()
// A false return implies a network error
bool receiveGateway(wxString& gatewayCallsign, wxString& address, DSTAR_PROTOCOL& protocol);
bool receiveGateway(std::string &gatewayCallsign, std::string &address, DSTAR_PROTOCOL &protocol);
// Get a user message, as a result of IDRT_USER returned from getMessageType()
// A false return implies a network error
bool receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address);
bool receiveUser(std::string &userCallsign, std::string &repeaterCallsign, std::string &gatewayCallsign, std::string &address);
bool receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address,
wxString& 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
@ -168,6 +131,3 @@ private:
struct CIRCDDBPrivate * const d;
};
#endif // _IRCDDB_H

File diff suppressed because it is too large Load Diff

@ -1,56 +1,34 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010-2011 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_IRCDDBAPP_H)
#define _IRCDDBAPP_H
#pragma once
#include <string>
#include <future>
#include "IRCDDB.h"
#include "IRCApplication.h"
#include <wx/wx.h>
class IRCDDBAppPrivate;
class IRCDDBApp : public IRCApplication, wxThread
class IRCDDBApp : public IRCApplication
{
public:
IRCDDBApp(const wxString& update_channel);
IRCDDBApp(const std::string &update_channel);
virtual ~IRCDDBApp();
virtual void userJoin (const wxString& nick, const wxString& name, const wxString& host);
virtual void userJoin(const std::string &nick, const std::string &name, const std::string &host);
virtual void userLeave (const wxString& nick);
virtual void userLeave(const std::string &nick);
virtual void userChanOp (const wxString& nick, bool op);
virtual void userChanOp(const std::string &nick, bool op);
virtual void userListReset();
virtual void msgChannel(IRCMessage *m);
virtual void msgQuery(IRCMessage *m);
virtual void setCurrentNick(const wxString& nick);
virtual void setTopic(const wxString& topic);
virtual void setCurrentNick(const std::string &nick);
virtual void setTopic(const std::string &topic);
virtual void setBestServer(const wxString& ircUser);
virtual void setBestServer(const std::string &ircUser);
virtual void setSendQ(IRCMessageQueue *s);
virtual IRCMessageQueue *getSendQ();
@ -62,35 +40,30 @@ public:
IRCMessage *getReplyMessage();
bool findUser ( const wxString& s );
bool findRepeater ( const wxString& s );
bool findGateway ( const wxString& s );
bool findUser(const std::string &s);
bool findRepeater(const std::string &s);
bool findGateway(const std::string &s);
bool sendHeard(const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3,
const wxString& destination, const wxString& tx_msg,
const wxString& tx_stats);
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);
int getConnectionState();
void rptrQRG(const wxString& rptrcall, double txFrequency, double duplexShift, double range, double agl);
void rptrQRG(const std::string &rptrcall, double txFrequency, double duplexShift, double range, double agl);
void rptrQTH(const wxString& rtprcall, double latitude, double longitude, const wxString& desc1, const wxString& desc2, const wxString& infoURL, const wxString &swVersion);
void rptrQTH(const std::string &rtprcall, double latitude, double longitude, const std::string &desc1, const std::string &desc2, const std::string &infoURL, const std::string &swVersion);
void kickWatchdog( const wxString& wdInfo );
void kickWatchdog(const std::string &wdInfo);
protected:
virtual wxThread::ExitCode Entry();
virtual void Entry();
private:
void doUpdate ( wxString& msg );
void doNotFound ( wxString& msg, wxString& retval );
wxString getIPAddress( wxString& zonerp_cs );
void doUpdate(std::string &msg);
void doNotFound(std::string &msg, std::string &retval);
std::string getIPAddress(std::string &zonerp_cs);
bool findServerUser();
IRCDDBAppPrivate *d;
std::future<void> worker_thread;
};
#endif

@ -1,44 +1,24 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010-2011 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
//#include <string>
//#include <list>
#include "IRCMessage.h"
IRCMessage::IRCMessage()
{
numParams = 0;
prefixParsed = false;
}
IRCMessage::IRCMessage ( const wxString& toNick, const wxString& msg )
IRCMessage::IRCMessage(const std::string &toNick, const std::string &msg)
{
command = wxT("PRIVMSG");
command = "PRIVMSG";
numParams = 2;
params.Add( toNick );
params.Add( msg );
params.push_back(toNick);
params.push_back(msg);
prefixParsed = false;
}
IRCMessage::IRCMessage ( const wxString& cmd )
IRCMessage::IRCMessage(const std::string &cmd)
{
command = cmd;
numParams = 0;
@ -50,23 +30,23 @@ IRCMessage::~IRCMessage()
}
void IRCMessage::addParam( const wxString& p )
void IRCMessage::addParam(const std::string &p)
{
params.Add( p );
numParams = params.GetCount();
params.push_back(p);
numParams = params.size();
}
int IRCMessage::getParamCount()
{
return params.GetCount();
return params.size();
}
wxString IRCMessage::getParam( int pos )
std::string IRCMessage::getParam(int pos)
{
return params[pos];
}
wxString IRCMessage::getCommand()
std::string IRCMessage::getCommand()
{
return command;
}
@ -77,25 +57,25 @@ void IRCMessage::parsePrefix()
unsigned int i;
for (i=0; i < 3; i++) {
prefixComponents.Add(wxT(""));
prefixComponents.push_back("");
}
int state = 0;
for (i=0; i < prefix.Len(); i++) {
wxChar c = prefix.GetChar(i);
for (i=0; i < prefix.length(); i++) {
char c = prefix.at(i);
switch (c) {
case wxT('!'):
case '!':
state = 1; // next is name
break;
case wxT('@'):
case '@':
state = 2; // next is host
break;
default:
prefixComponents[state].Append(c);
prefixComponents[state].append(1, c);
break;
}
}
@ -103,7 +83,7 @@ void IRCMessage::parsePrefix()
prefixParsed = true;
}
wxString& IRCMessage::getPrefixNick()
std::string &IRCMessage::getPrefixNick()
{
if (!prefixParsed) {
parsePrefix();
@ -112,7 +92,7 @@ wxString& IRCMessage::getPrefixNick()
return prefixComponents[0];
}
wxString& IRCMessage::getPrefixName()
std::string &IRCMessage::getPrefixName()
{
if (!prefixParsed) {
parsePrefix();
@ -121,7 +101,7 @@ wxString& IRCMessage::getPrefixName()
return prefixComponents[1];
}
wxString& IRCMessage::getPrefixHost()
std::string &IRCMessage::getPrefixHost()
{
if (!prefixParsed) {
parsePrefix();
@ -130,36 +110,25 @@ wxString& IRCMessage::getPrefixHost()
return prefixComponents[2];
}
void IRCMessage::composeMessage ( wxString& output )
void IRCMessage::composeMessage(std::string &output)
{
#if defined(DEBUG_IRC)
wxString d = wxT("T [") + prefix + wxT("] [") + command + wxT("]");
for (int i=0; i < numParams; i++) {
d.Append(wxT(" [") + params[i] + wxT("]") );
}
d.Replace(wxT("%"), wxT("%%"), true);
d.Replace(wxT("\\"), wxT("\\\\"), true);
wxLogVerbose(d);
#endif
wxString o;
std::string o;
if (prefix.Len() > 0) {
o = wxT(":") + prefix + wxT(" ");
if (prefix.length() > 0) {
o = std::string(":") + prefix + ' ';
}
o.Append(command);
o += command;
for (int i=0; i < numParams; i++) {
if (i == (numParams - 1)) {
o.Append(wxT(" :") + params[i]);
o += (std::string(" :") + params[i]);
} else {
o.Append(wxT(" ") + params[i]);
o += (std::string(" ") + params[i]);
}
}
o.Append(wxT("\r\n"));
o += std::string("\r\n");
output = o;
}

@ -1,71 +1,38 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_IRC_MESSAGE_H)
#define _IRC_MESSAGE_H
#include <wx/wx.h>
#pragma once
#include <string>
#include <vector>
class IRCMessage
{
public:
IRCMessage();
IRCMessage( const wxString& toNick, const wxString& msg );
IRCMessage( const wxString& command );
IRCMessage(const std::string& toNick, const std::string& msg);
IRCMessage(const std::string& command);
~IRCMessage();
wxString prefix;
wxString command;
wxArrayString params;
std::string prefix;
std::string command;
std::vector<std::string> params;
int numParams;
wxString& getPrefixNick();
wxString& getPrefixName();
wxString& getPrefixHost();
std::string &getPrefixNick();
std::string &getPrefixName();
std::string &getPrefixHost();
void composeMessage ( wxString& output );
void composeMessage (std::string& output);
void addParam( const wxString& p );
void addParam(const std::string &p);
wxString getCommand();
std::string getCommand();
wxString getParam( int pos );
std::string getParam(int pos);
int getParamCount();
private:
void parsePrefix();
wxArrayString prefixComponents;
std::vector<std::string> prefixComponents;
bool prefixParsed;
};
#endif

@ -1,24 +1,3 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#include "IRCMessageQueue.h"
@ -54,18 +33,24 @@ void IRCMessageQueue::signalEOF()
bool IRCMessageQueue::messageAvailable()
{
wxMutexLocker lock(accessMutex);
accessMutex.lock();
IRCMessageQueueItem *m = first;
return (first != NULL);
accessMutex.unlock();
return (m != NULL);
}
IRCMessage * IRCMessageQueue::peekFirst()
{
wxMutexLocker lock(accessMutex);
accessMutex.lock();
IRCMessageQueueItem * k = first;
accessMutex.unlock();
if ( k == NULL ) {
return NULL;
}
@ -76,7 +61,7 @@ IRCMessage * IRCMessageQueue::peekFirst()
IRCMessage * IRCMessageQueue::getMessage()
{
wxMutexLocker lock(accessMutex);
accessMutex.lock();
IRCMessageQueueItem * k;
@ -99,15 +84,17 @@ IRCMessage * IRCMessageQueue::getMessage()
delete k;
accessMutex.unlock();
return msg;
}
void IRCMessageQueue::putMessage( IRCMessage * m )
{
wxMutexLocker lock(accessMutex);
accessMutex.lock();
// wxLogVerbose(wxT("IRCMessageQueue::putMessage"));
//traceit("IRCMessageQueue::putMessage\n");
IRCMessageQueueItem * k = new IRCMessageQueueItem(m);
@ -121,8 +108,7 @@ void IRCMessageQueue::putMessage( IRCMessage * m )
}
last = k;
}
accessMutex.unlock();
}

@ -1,28 +1,6 @@
/*
#pragma once
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_IRCMESSAGEQUEUE_H)
#define _IRCMESSAGEQUEUE_H
#include <wx/wx.h>
#include <mutex>
#include "IRCMessage.h"
@ -70,8 +48,6 @@ private:
IRCMessageQueueItem * first;
IRCMessageQueueItem * last;
wxMutex accessMutex;
std::mutex accessMutex;
};
#endif

@ -1,63 +1,45 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010-2011 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#include <string>
#include <vector>
#include <regex>
#include <mutex>
#include "IRCutils.h"
#include "IRCProtocol.h"
#include <wx/regex.h>
extern void traceit(const char *fmt,...);
#define CIRCDDB_VERSION "1.2.4"
#define CIRCDDB_VERSION "2.0.0"
IRCProtocol::IRCProtocol ( IRCApplication * app,
const wxString& callsign, const wxString& password, const wxString& channel,
const wxString& versionInfo )
IRCProtocol::IRCProtocol(IRCApplication *app, const std::string &callsign, const std::string &password, const std::string &channel, const std::string &versionInfo)
{
this->password = password;
this->channel = channel;
this->app = app;
this->versionInfo = wxT("CIRCDDB:");
this->versionInfo.Append(wxT(CIRCDDB_VERSION));
this->versionInfo = "CIRCDDB:";
this->versionInfo.append(CIRCDDB_VERSION);
if (versionInfo.Len() > 0) {
this->versionInfo.Append(wxT(" "));
this->versionInfo.Append(versionInfo);
if (versionInfo.length() > 0) {
this->versionInfo.append(" ");
this->versionInfo.append(versionInfo);
}
int hyphenPos = callsign.find(wxT('-'));
int hyphenPos = callsign.find('-');
if (hyphenPos == wxNOT_FOUND) {
wxString n;
if (hyphenPos < 0) {
std::string n;
n = callsign + wxT("-1");
nicks.Add(n);
n = callsign + wxT("-2");
nicks.Add(n);
n = callsign + wxT("-3");
nicks.Add(n);
n = callsign + wxT("-4");
nicks.Add(n);
n = callsign + "-1";
nicks.push_back(n);
n = callsign + "-2";
nicks.push_back(n);
n = callsign + "-3";
nicks.push_back(n);
n = callsign + "-4";
nicks.push_back(n);
} else {
nicks.Add(callsign);
nicks.push_back(callsign);
}
name = callsign;
@ -76,7 +58,7 @@ IRCProtocol::~IRCProtocol()
void IRCProtocol::chooseNewNick()
{
int r = rand() % nicks.GetCount();
int r = rand() % nicks.size();
currentNick = nicks[r];
}
@ -84,9 +66,8 @@ void IRCProtocol::chooseNewNick()
void IRCProtocol::setNetworkReady(bool b)
{
if (b == true) {
if (state != 0) {
wxLogError(wxT("IRCProtocol::setNetworkReady: unexpected state"));
}
if (state != 0)
traceit("IRCProtocol::setNetworkReady: unexpected state");
state = 1;
chooseNewNick();
@ -106,39 +87,39 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
IRCMessage *m = recvQ->getMessage();
#if defined(DEBUG_IRC)
wxString d = wxT("R [") + m->prefix + wxT("] [") + m->command + wxT("]");
std::string d = std::string("R [") + m->prefix + std::string("] [") + m->command + std::string("]");
for (int i=0; i < m->numParams; i++) {
d.Append(wxT(" [") + m->params[i] + wxT("]") );
d.append(std::string(" [") + m->params[i] + std::string("]") );
}
d.Replace(wxT("%"), wxT("%%"), true);
d.Replace(wxT("\\"), wxT("\\\\"), true);
wxLogVerbose(d);
// d.Replace(std::string("%"), std::string("%%"), true);
// d.Replace(std::string("\\"), std::string("\\\\"), true);
traceit("%s\n", d.c_str());
#endif
if (m->command.IsSameAs(wxT("004"))) {
if (0 == m->command.compare("004")) {
if (state == 4) {
if (m->params.GetCount() > 1) {
wxRegEx serverNamePattern(wxT("^grp[1-9]s[1-9].ircDDB$"));
if (m->params.size() > 1) {
std::regex serverNamePattern("^grp[1-9]s[1-9].ircDDB$");
if (serverNamePattern.Matches( m->params[1] )) {
app->setBestServer(wxT("s-") + m->params[1].Mid(0,6));
if (std::regex_match(m->params[1], serverNamePattern)) {
app->setBestServer(std::string("s-") + m->params[1].substr(0,6));
}
}
state = 5; // next: JOIN
app->setCurrentNick(currentNick);
}
} else if (m->command.IsSameAs(wxT("PING"))) {
} else if (0 == m->command.compare("PING")) {
IRCMessage *m2 = new IRCMessage();
m2->command = wxT("PONG");
if (m->params.GetCount() > 0) {
m2->command = "PONG";
if (m->params.size() > 0) {
m2->numParams = 1;
m2->params.Add( m->params[0] );
m2->params.push_back( m->params[0] );
}
sendQ -> putMessage(m2);
} else if (m->command.IsSameAs(wxT("JOIN"))) {
if ((m->numParams >= 1) && m->params[0].IsSameAs(channel)) {
if (m->getPrefixNick().IsSameAs(currentNick) && (state == 6)) {
if (debugChannel.Len() > 0) {
} else if (0 == m->command.compare("JOIN")) {
if ((m->numParams >= 1) && 0==m->params[0].compare(channel)) {
if (0==m->getPrefixNick().compare(currentNick) && (state == 6)) {
if (debugChannel.length() > 0) {
state = 7; // next: join debug_channel
} else {
state = 10; // next: WHO *
@ -148,25 +129,25 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
}
}
if ((m->numParams >= 1) && m->params[0].IsSameAs(debugChannel)) {
if (m->getPrefixNick().IsSameAs(currentNick) && (state == 8)) {
if ((m->numParams >= 1) && 0==m->params[0].compare(debugChannel)) {
if (0==m->getPrefixNick().compare(currentNick) && (state == 8)) {
state = 10; // next: WHO *
}
}
} else if (m->command.IsSameAs(wxT("PONG"))) {
} else if (0 == m->command.compare("PONG")) {
if (state == 12) {
timer = pingTimer;
state = 11;
}
} else if (m->command.IsSameAs(wxT("PART"))) {
if ((m->numParams >= 1) && m->params[0].IsSameAs(channel)) {
} else if (0 == m->command.compare("PART")) {
if ((m->numParams >= 1) && 0==m->params[0].compare(channel)) {
if (app != NULL) {
app->userLeave( m->getPrefixNick() );
}
}
} else if (m->command.IsSameAs(wxT("KICK"))) {
if ((m->numParams >= 2) && m->params[0].IsSameAs(channel)) {
if (m->params[1].IsSameAs(currentNick)) {
} else if (0 == m->command.compare("KICK")) {
if ((m->numParams >= 2) && 0==m->params[0].compare(channel)) {
if (0 == m->params[1].compare(currentNick)) {
// i was kicked!!
delete m;
return false;
@ -174,52 +155,49 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
app->userLeave( m->params[1] );
}
}
} else if (m->command.IsSameAs(wxT("QUIT"))) {
} else if (0 == m->command.compare("QUIT")) {
if (app != NULL) {
app->userLeave( m->getPrefixNick() );
}
} else if (m->command.IsSameAs(wxT("MODE"))) {
if ((m->numParams >= 3) && m->params[0].IsSameAs(channel)) {
} else if (0 == m->command.compare("MODE")) {
if ((m->numParams >= 3) && 0==m->params[0].compare(channel)) {
if (app != NULL) {
size_t i;
wxString mode = m->params[1];
std::string mode = m->params[1];
for (i = 1; (i < mode.Len()) && ((size_t) m->numParams >= (i+2)); i++) {
if ( mode[i] == wxT('o') ) {
if ( mode[0] == wxT('+') ) {
for (i=1; i<mode.length() && (size_t)m->numParams>=(i+2); i++) {
if (mode[i] == 'o') {
if (mode[0] == '+') {
app->userChanOp(m->params[i+1], true);
} else if ( mode[0] == wxT('-') ) {
} else if (mode[0] == '-') {
app->userChanOp(m->params[i+1], false);
}
}
} // for
}
}
} else if (m->command.IsSameAs(wxT("PRIVMSG"))) {
} else if (0 == m->command.compare("PRIVMSG")) {
if ((m->numParams == 2) && (app != NULL)) {
if (m->params[0].IsSameAs(channel)) {
if (0 == m->params[0].compare(channel)) {
app->msgChannel(m);
} else if (m->params[0].IsSameAs(currentNick)) {
} else if (0 == m->params[0].compare(currentNick)) {
app->msgQuery(m);
}
}
} else if (m->command.IsSameAs(wxT("352"))) { // WHO list
if ((m->numParams >= 7) && m->params[0].IsSameAs(currentNick)
&& m->params[1].IsSameAs(channel)) {
} 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 (app != NULL) {
app->userJoin(m->params[5], m->params[2], m->params[3]);
app->userChanOp ( m->params[5], m->params[6].IsSameAs(wxT("H@")));
app->userChanOp (m->params[5], 0==m->params[6].compare("H@"));
}
}
} else if (m->command.IsSameAs(wxT("433"))) { // nick collision
} else if (0 == m->command.compare("433")) { // nick collision
if (state == 2) {
state = 3; // nick collision, choose new nick
timer = 10; // wait 5 seconds..
}
} else if (m->command.IsSameAs(wxT("332")) ||
m->command.IsSameAs(wxT("TOPIC"))) { // topic
if ((m->numParams == 2) && (app != NULL) &&
m->params[0].IsSameAs(channel) ) {
} else if (0==m->command.compare("332") || 0==m->command.compare("TOPIC")) { // topic
if ((m->numParams == 2) && (app != NULL) && 0==m->params[0].compare(channel)) {
app->setTopic(m->params[1]);
}
}
@ -232,15 +210,15 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
switch (state) {
case 1:
m = new IRCMessage();
m->command = wxT("PASS");
m->command = "PASS";
m->numParams = 1;
m->params.Add(password);
m->params.push_back(password);
sendQ->putMessage(m);
m = new IRCMessage();
m->command = wxT("NICK");
m->command = "NICK";
m->numParams = 1;
m->params.Add(currentNick);
m->params.push_back(currentNick);
sendQ->putMessage(m);
timer = 10; // wait for possible nick collision message
@ -250,12 +228,12 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
case 2:
if (timer == 0) {
m = new IRCMessage();
m->command = wxT("USER");
m->command = "USER";
m->numParams = 4;
m->params.Add(name);
m->params.Add(wxT("0"));
m->params.Add(wxT("*"));
m->params.Add(versionInfo);
m->params.push_back(name);
m->params.push_back("0");
m->params.push_back("*");
m->params.push_back(versionInfo);
sendQ->putMessage(m);
timer = 30;
@ -267,9 +245,9 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
if (timer == 0) {
chooseNewNick();
m = new IRCMessage();
m->command = wxT("NICK");
m->command = "NICK";
m->numParams = 1;
m->params.Add(currentNick);
m->params.push_back(currentNick);
sendQ->putMessage(m);
timer = 10; // wait for possible nick collision message
@ -286,9 +264,9 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
case 5:
m = new IRCMessage();
m->command = wxT("JOIN");
m->command = "JOIN";
m->numParams = 1;
m->params.Add(channel);
m->params.push_back(channel);
sendQ->putMessage(m);
timer = 30;
@ -303,14 +281,14 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
break;
case 7:
if (debugChannel.Len() == 0) {
if (debugChannel.length() == 0) {
return false; // this state cannot be processed if there is no debug_channel
}
m = new IRCMessage();
m->command = wxT("JOIN");
m->command = "JOIN";
m->numParams = 1;
m->params.Add(debugChannel);
m->params.push_back(debugChannel);
sendQ->putMessage(m);
timer = 30;
@ -326,10 +304,10 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
case 10:
m = new IRCMessage();
m->command = wxT("WHO");
m->command = "WHO";
m->numParams = 2;
m->params.Add(channel);
m->params.Add(wxT("*"));
m->params.push_back(channel);
m->params.push_back("*");
sendQ->putMessage(m);
timer = pingTimer;
@ -343,9 +321,9 @@ bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sen
case 11:
if (timer == 0) {
m = new IRCMessage();
m->command = wxT("PING");
m->command = "PING";
m->numParams = 1;
m->params.Add(currentNick);
m->params.push_back(currentNick);
sendQ->putMessage(m);
timer = pingTimer;

@ -1,39 +1,12 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_IRCPROTOCOL_H)
#define _IRCPROTOCOL_H
#include <wx/wx.h>
#pragma once
#include "IRCMessageQueue.h"
#include "IRCApplication.h"
class IRCProtocol
{
public:
IRCProtocol ( IRCApplication * app,
const wxString& callsign, const wxString& password, const wxString& channel,
const wxString& versionInfo );
IRCProtocol(IRCApplication * app, const std::string &callsign, const std::string &password, const std::string &channel, const std::string &versionInfo);
~IRCProtocol();
@ -44,22 +17,19 @@ public:
private:
void chooseNewNick();
wxArrayString nicks;
wxString password;
wxString channel;
wxString name;
wxString currentNick;
wxString versionInfo;
std::vector<std::string> nicks;
std::string password;
std::string channel;
std::string name;
std::string currentNick;
std::string versionInfo;
int state;
int timer;
int pingTimer;
wxString debugChannel;
std::string debugChannel;
IRCApplication *app;
};
#endif

@ -1,81 +1,11 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#endif
#include "IRCutils.h"
#include "IRCMessage.h"
#include "IRCReceiver.h"
#include <wx/wx.h>
IRCReceiver::IRCReceiver(int sock, IRCMessageQueue * q )
: wxThread(wxTHREAD_JOINABLE)
{
this->sock = sock;
recvQ = q;
}
IRCReceiver::~IRCReceiver()
{
}
bool IRCReceiver::startWork()
{
if (Create() != wxTHREAD_NO_ERROR) {
wxLogError(wxT("IRCReceiver::startWork: Could not create the worker thread!"));
return false;
}
terminateThread = false;
if (Run() != wxTHREAD_NO_ERROR) {
wxLogError(wxT("IRCReceiver::startWork: Could not run the worker thread!"));
return false;
}
return true;
}
void IRCReceiver::stopWork()
{
terminateThread = true;
Wait();
}
static int doRead(int sock, char * buf, int buf_size)
{
struct timeval tv;
@ -94,11 +24,11 @@ static int doRead( int sock, char * buf, int buf_size )
res = select(sock+1, &rdset, NULL, &errset, &tv);
if ( res < 0 ) {
wxLogSysError(wxT("IRCReceiver::doRead: select"));
traceit("IRCReceiver::doread: select() error.\n");
return -1;
} else if ( res > 0 ) {
if (FD_ISSET(sock, &errset)) {
wxLogVerbose(wxT("IRCReceiver::doRead: select (FD_ISSET(sock, exceptfds))"));
traceit("IRCReceiver::doRead: FD_ISSET error\n");
return -1;
}
@ -106,22 +36,21 @@ static int doRead( int sock, char * buf, int buf_size )
res = recv(sock, buf, buf_size, 0);
if (res < 0) {
wxLogSysError(wxT("IRCReceiver::doRead: read"));
traceit("IRCReceiver::doRead: recv error\n");
return -1;
} else if (res == 0) {
wxLogVerbose(wxT("IRCReceiver::doRead: EOF read==0"));
traceit("IRCReceiver::doRead: EOF read==0\n");
return -1;
} else {
} else
return res;
}
}
}
return 0;
}
wxThread::ExitCode IRCReceiver::Entry ()
void IRCReceiver::Entry()
{
IRCMessage *m = new IRCMessage();
@ -129,9 +58,6 @@ wxThread::ExitCode IRCReceiver::Entry ()
int state = 0;
while (!terminateThread) {
// wxLogVerbose(wxT("IRCReceiver: tick"));
char buf[200];
int r = doRead(sock, buf, sizeof buf);
@ -145,67 +71,87 @@ wxThread::ExitCode IRCReceiver::Entry ()
char b = buf[i];
if (b > 0) {
if (b == 10) {
if (b == '\n') {
recvQ->putMessage(m);
m = new IRCMessage();
state = 0;
} else if (b == 13) {
} else if (b == '\r') {
// do nothing
} else switch (state) {
case 0:
if (b == ':') {
state = 1; // prefix
} else if (b == 32) {
} else if (b == ' ') {
// do nothing
} else {
m -> command.Append(wxChar(b));
m->command.push_back(b);
state = 2; // command
}
break;
case 1:
if (b == 32) {
if (b == ' ') {
state = 2; // command is next
} else {
m -> prefix.Append(wxChar(b));
m->prefix.push_back(b);
}
break;
case 2:
if (b == 32) {
if (b == ' ') {
state = 3; // params
m->numParams = 1;
m -> params.Add(wxT(""));
m->params.push_back("");
} else {
m -> command.Append(wxChar(b));
m->command.push_back(b);
}
break;
case 3:
if (b == 32) {
if (b == ' ') {
m->numParams++;
if (m->numParams >= 15) {
state = 5; // ignore the rest
}
m -> params.Add(wxT(""));
} else if ((b == ':') && (m -> params[ m -> numParams-1 ].Len() == 0)) {
m->params.push_back("");
} else if ((b == ':') && (m->params[m->numParams - 1].length() == 0)) {
state = 4; // rest of line is this param
} else {
m -> params[ m -> numParams-1 ].Append(wxChar(b));
m->params[m->numParams - 1].push_back(b);
}
break;
case 4:
m -> params[ m -> numParams-1 ].Append(wxChar(b));
m->params[m->numParams - 1].push_back(b);
break;
} // switch
} // if
} // for
} // while
return 0;
return;
}
IRCReceiver::IRCReceiver(int sock, IRCMessageQueue *q)
{
this->sock = 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();
}

@ -1,62 +1,21 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if !defined(_IRCRECEIVER_H)
#define _IRCRECEIVER_H
#include <wx/wx.h>
#pragma once
#include <future>
#include "IRCMessageQueue.h"
class IRCReceiver : public wxThread
class IRCReceiver
{
public:
IRCReceiver(int sock, IRCMessageQueue *q);
~IRCReceiver();
virtual ~IRCReceiver();
bool startWork();
void stopWork();
protected:
virtual wxThread::ExitCode Entry();
virtual void Entry();
private:
bool terminateThread;
int sock;
IRCMessageQueue *recvQ;
std::future<void> rec_thread;
};
#endif

@ -1,49 +1,41 @@
/*
CIRCDDB - ircDDB client library in C++
Copyright (C) 2010-2011 Michael Dirska, DL1BFF (dl1bff@mdx.de)
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, see <http://www.gnu.org/licenses/>.
*/
#if defined(WIN32)
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif
#include <wx/wx.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cstdarg>
#include <ctime>
#include <string>
#include <vector>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
#include <sstream>
#include <algorithm>
#include "IRCutils.h"
// not needed, defined in /usr/include/features.h
//#define _XOPEN_SOURCE
time_t parseTime(const std::string str)
{
struct tm stm;
strptime(str.c_str(), "%Y-%m-%d %H:%M:%S", &stm);
return mktime(&stm);
}
int getAllIPV4Addresses ( const char * name, unsigned short port,
unsigned int * num, struct sockaddr_in * addr, unsigned int max_addr )
std::vector<std::string> stringTokenizer(const std::string &s)
{
std::stringstream ss(s);
std::istream_iterator<std::string> it(ss);
std::istream_iterator<std::string> end;
std::vector<std::string> result(it, end);
return result;
}
int getAllIPV4Addresses(const char * name, unsigned short port, unsigned int * num, struct sockaddr_in * addr, unsigned int max_addr)
{
struct addrinfo hints;
@ -60,23 +52,20 @@ int getAllIPV4Addresses ( const char * name, unsigned short port,
unsigned int numAddr = 0;
for (rp = res; rp != NULL; rp = rp->ai_next) {
if (rp->ai_family == AF_INET) {
if (rp->ai_family == AF_INET)
numAddr ++;
}
}
if (numAddr > 0) {
if (numAddr > max_addr) {
if (numAddr > max_addr)
numAddr = max_addr;
}
int * shuffle = new int[numAddr];
unsigned int i;
for (i=0; i < numAddr; i++) {
for (i=0; i < numAddr; i++)
shuffle[i] = i;
}
for (i=0; i < (numAddr - 1); i++) {
if (rand() & 1) {
@ -116,9 +105,7 @@ int getAllIPV4Addresses ( const char * name, unsigned short port,
return 0;
} else {
wxString e( gai_strerror(r), wxConvUTF8);
wxLogWarning(wxT("getaddrinfo: ") + e );
traceit("getaddrinfo: %s\n", gai_strerror(r));
return 1;
}
@ -126,15 +113,11 @@ int getAllIPV4Addresses ( const char * name, unsigned short port,
}
void safeStringCopy (char *dest, const char *src, unsigned int buf_size)
{
unsigned int i = 0;
while (i < (buf_size - 1) && (src[i] != 0)) {
while (i<(buf_size - 1) && src[i] != 0) {
dest[i] = src[i];
i++;
}
@ -142,24 +125,65 @@ void safeStringCopy (char * dest, const char * src, unsigned int buf_size)
dest[i] = 0;
}
wxString getCurrentTime(void)
char *getCurrentTime(void)
{
time_t now = time(NULL);
struct tm* tm;
struct tm tm_buf;
char buffer[25];
static char buffer[25];
#if defined(__WINDOWS__)
gmtime_s(&tm_buf, &now);
tm = &tm_buf;
#else
gmtime_r(&now, &tm_buf);
tm = &tm_buf;
#endif
strftime(buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", tm);
return wxString(buffer, wxConvLocal);
return buffer;
}
void traceit(const char *fmt,...)
{
time_t ltime;
struct tm tm;
const short BFSZ = 512;
char buf[BFSZ];
time(&ltime);
localtime_r(&ltime, &tm);
snprintf(buf,BFSZ - 1,"%02d/%02d/%02d %d:%02d:%02d:",
tm.tm_mon+1,tm.tm_mday,tm.tm_year % 100,
tm.tm_hour,tm.tm_min,tm.tm_sec);
va_list args;
va_start(args,fmt);
vsnprintf(buf + strlen(buf), BFSZ - strlen(buf) -1, fmt, args);
va_end(args);
fprintf(stdout, "%s", buf);
return;
}
void ToUpper(std::string &str)
{
for (auto it=str.begin(); it!=str.end(); it++) {
if (islower(*it))
*it = toupper(*it);
}
}
void ToLower(std::string &str)
{
for (auto it=str.begin(); it!=str.end(); it++) {
if (isupper(*it))
*it = tolower(*it);
}
}
void ReplaceChar(std::string &str, char from, char to)
{
for (auto it=str.begin(); it!=str.end(); it++) {
if (from == *it)
*it = to;
}
}

@ -1,31 +1,23 @@
/*
#pragma once
CIRCDDB - ircDDB client library in C++
#include <string>
#include <vector>
#include <ctime>
Copyright (C) 2010 Michael Dirska, DL1BFF (dl1bff@mdx.de)
time_t parseTime(const std::string str);
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, see <http://www.gnu.org/licenses/>.
*/
std::vector<std::string> stringTokenizer(const std::string &str);
int getAllIPV4Addresses(const char *name, unsigned short port, unsigned int *num, struct sockaddr_in *addr, unsigned int max_addr);
void safeStringCopy (char * dest, const char * src, unsigned int buf_size);
int getAllIPV4Addresses ( const char * name, unsigned short port,
unsigned int * num, struct sockaddr_in * addr, unsigned int max_addr );
char *getCurrentTime(void);
void traceit(const char *fmt,...);
void safeStringCopy (char * dest, const char * src, unsigned int buf_size);
void ToUpper(std::string &str);
wxString getCurrentTime(void);
void ToLower(std::string &str);
void ReplaceChar(std::string &str, char from, char to);

@ -20,8 +20,8 @@ BINDIR=/usr/local/bin
CFGDIR=/usr/local/etc
LOGDIR=/var/log
CPPFLAGS=-W -Wall -I/usr/include `wx-config --cppflags base`
LDFLAGS=-L/usr/lib `wx-config --libs base` -lconfig++
CPPFLAGS=-W -Wall -I/usr/include -std=c++11
LDFLAGS=-L/usr/lib -lconfig++
PROGRAMS=g2_ircddb g2_link dvap_rptr dvrptr g2link_test g2link_test_audio
@ -41,19 +41,22 @@ dvap_rptr : dvap_rptr.cpp dstar_dv.o golay23.o versions.h
dvrptr : dvrptr.cpp dstar_dv.o golay23.o
g++ -W -Wall -o dvrptr dvrptr.cpp golay23.o dstar_dv.o -I/usr/include -L/usr/lib -lconfig++ -lrt
IRCDDB.o : IRCDDB.cpp IRCDDB.h
g++ $(CPPFLAGS) -c $(CPPFLAGS) IRCDDB.cpp
IRCutils.o : IRCutils.cpp IRCutils.h
g++ -c $(CPPFLAGS) IRCutils.cpp
IRCDDB.o : IRCDDB.cpp IRCDDB.h IRCutils.h
g++ -c $(CPPFLAGS) IRCDDB.cpp
IRCClient.o : IRCClient.cpp IRCClient.h IRCutils.h
g++ -c $(CPPFLAGS) IRCClient.cpp
IRCReceiver.o : IRCReceiver.cpp IRCReceiver.h IRCMessageQueue.h
IRCReceiver.o : IRCReceiver.cpp IRCReceiver.h IRCMessageQueue.h IRCutils.h
g++ -c $(CPPFLAGS) IRCReceiver.cpp
IRCMessageQueue.o : IRCMessageQueue.cpp IRCMessageQueue.h IRCMessage.h
g++ -c $(CPPFLAGS) IRCMessageQueue.cpp
IRCProtocol.o : IRCProtocol.cpp IRCProtocol.h
IRCProtocol.o : IRCProtocol.cpp IRCProtocol.h IRCutils.h
g++ -c $(CPPFLAGS) IRCProtocol.cpp
IRCMessage.o : IRCMessage.cpp IRCMessage.h

@ -43,7 +43,6 @@
#include <string>
#include <libconfig.h++>
using namespace std;
using namespace libconfig;
#define VERSION DVAP_VERSION
@ -394,7 +393,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, string &value, int min, int max, const char *default_value)
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();
@ -428,7 +427,7 @@ static int read_config(const char *cfgFile)
return 1;
}
string dvap_path, value;
std::string dvap_path, value;
for (i=0; i<3; i++) {
dvap_path = "module.";
dvap_path += ('a' + i);
@ -443,7 +442,7 @@ static int read_config(const char *cfgFile)
}
RPTR_MOD = 'A' + i;
if (cfg.lookupValue(string(dvap_path+".callsign").c_str(), value) || cfg.lookupValue("ircddb.login", value)) {
if (cfg.lookupValue(std::string(dvap_path+".callsign").c_str(), value) || cfg.lookupValue("ircddb.login", value)) {
int l = value.length();
if (l<3 || l>CALL_SIZE-2) {
traceit("Call '%s' is invalid length!\n", value.c_str());
@ -481,7 +480,7 @@ static int read_config(const char *cfgFile)
return 1;
}
if (get_value(cfg, string(dvap_path+".invalid_prefix").c_str(), value, 1, CALL_SIZE, "XXX")) {
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, ' ');
@ -489,13 +488,13 @@ static int read_config(const char *cfgFile)
} else
return 1;
if (get_value(cfg, string(dvap_path+".internal_ip").c_str(), value, 7, IP_SIZE, "0.0.0.0"))
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, string(dvap_path+".port").c_str(), RPTR_PORT, 10000, 65535, i);
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());
@ -506,7 +505,7 @@ static int read_config(const char *cfgFile)
get_value(cfg, "gateway.internal.port", G2_PORT, 10000, 65535, 19000);
if (get_value(cfg, string(dvap_path+".serial_number").c_str(), value, 8, 10, "APXXXXXX"))
if (get_value(cfg, std::string(dvap_path+".serial_number").c_str(), value, 8, 10, "APXXXXXX"))
strcpy(DVP_SERIAL, value.c_str());
else {
traceit("%s.serial_number '%s' is invalid!\n", dvap_path.c_str(), value.c_str());
@ -514,19 +513,19 @@ static int read_config(const char *cfgFile)
}
double f;
get_value(cfg, string(dvap_path+".frequency").c_str(), f, 100.0, 1400.0, 145.5);
get_value(cfg, std::string(dvap_path+".frequency").c_str(), f, 100.0, 1400.0, 145.5);
DVP_FREQ = (u_int32_t)(1.0e6*f);
get_value(cfg, string(dvap_path+".power").c_str(), i, -12, 10, 10);
get_value(cfg, std::string(dvap_path+".power").c_str(), i, -12, 10, 10);
DVP_PWR = (int16_t)i;
get_value(cfg, string(dvap_path+".squelch").c_str(), i, -128, -45, -100);
get_value(cfg, std::string(dvap_path+".squelch").c_str(), i, -128, -45, -100);
DVP_SQL = (char)i;
get_value(cfg, string(dvap_path+".offset").c_str(), i, -2000, 2000, 0.0);
get_value(cfg, std::string(dvap_path+".offset").c_str(), i, -2000, 2000, 0.0);
DVP_OFF = (int16_t)i;
get_value(cfg, string(dvap_path+".packet_wait").c_str(), WAIT_FOR_PACKETS, 6, 100, 25);
get_value(cfg, std::string(dvap_path+".packet_wait").c_str(), WAIT_FOR_PACKETS, 6, 100, 25);
get_value(cfg, "timing.timeout.remote_g2", REMOTE_TIMEOUT, 1, 10, 2);
@ -534,7 +533,7 @@ static int read_config(const char *cfgFile)
get_value(cfg, "timing.play.wait", DELAY_BEFORE, 1, 10, 2);
get_value(cfg, string(dvap_path+".acknowledge").c_str(), RPTR_ACK, false);
get_value(cfg, std::string(dvap_path+".acknowledge").c_str(), RPTR_ACK, false);
inactiveMax = (REMOTE_TIMEOUT * 1000) / WAIT_FOR_PACKETS;
traceit("Max loops = %d\n", inactiveMax);

@ -25,7 +25,6 @@
#include <string>
#include <libconfig.h++>
using namespace std;
using namespace libconfig;
#define VERSION DVRPTR_VERSION
@ -1837,7 +1836,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, string &value, int min, int max, const char *default_value)
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();
@ -1871,7 +1870,7 @@ static int read_config(const char *cfgFile)
return 1;
}
string path, value;
std::string path, value;
for (i=0; i<3; i++) {
path = "module.";
path += ('a' + i);
@ -1886,7 +1885,7 @@ static int read_config(const char *cfgFile)
}
DVRPTR_MOD = 'A' + i;
if (cfg.lookupValue(string(path+".callsign").c_str(), value) || cfg.lookupValue("ircddb.login", value)) {
if (cfg.lookupValue(std::string(path+".callsign").c_str(), value) || cfg.lookupValue("ircddb.login", value)) {
int l = value.length();
if (l<3 || l>CALL_SIZE-2) {
logdata("Call '%s' is invalid length!\n", value.c_str());
@ -1924,12 +1923,12 @@ static int read_config(const char *cfgFile)
return 1;
}
if (get_value(cfg, string(path+".rf_control.on").c_str(), value, 0, CALL_SIZE, " "))
if (get_value(cfg, std::string(path+".rf_control.on").c_str(), value, 0, CALL_SIZE, " "))
strcpy(ENABLE_RF, value.c_str());
else
logdata("%s.rf_control.on '%s' is invalid, rejected.\n", path.c_str(), value.c_str());
if (get_value(cfg, string(path+".rf_control.off").c_str(), value, 0, CALL_SIZE, " "))
if (get_value(cfg, std::string(path+".rf_control.off").c_str(), value, 0, CALL_SIZE, " "))
strcpy(DISABLE_RF, value.c_str());
else
logdata("%s.rf_control.off '%s' is invalid, rejected.\n", path.c_str(), value.c_str());
@ -1942,7 +1941,7 @@ static int read_config(const char *cfgFile)
REMOTE_TIMEOUT = 3;
logdata("timing.timeout.remote_g2 = [%d]\n", REMOTE_TIMEOUT);
if (get_value(cfg, string(path+".invalid_prefix").c_str(), value, 1, CALL_SIZE, "XXX")) {
if (get_value(cfg, std::string(path+".invalid_prefix").c_str(), value, 1, CALL_SIZE, "XXX")) {
value.resize(CALL_SIZE, ' ');
for (i=0; i<CALL_SIZE; i++) {
if (islower(value[i]))
@ -1954,21 +1953,21 @@ static int read_config(const char *cfgFile)
return 1;
}
if (get_value(cfg, string(path+".serial_number").c_str(), value, 11, 11, "00.00.00.00"))
if (get_value(cfg, std::string(path+".serial_number").c_str(), value, 11, 11, "00.00.00.00"))
strcpy(DVRPTR_SERIAL, value.c_str());
else {
logdata("%s.serial_number '%s' is invalid!\n", path.c_str(), value.c_str());
return 1;
}
if (get_value(cfg, string(path+".internal_ip").c_str(), value, 7, IP_SIZE, "0.0.0.0"))
if (get_value(cfg, std::string(path+".internal_ip").c_str(), value, 7, IP_SIZE, "0.0.0.0"))
strcpy(DVRPTR_INTERNAL_IP, value.c_str());
else {
logdata("%s.internal_ip '%s' is invalid!\n", path.c_str(), value.c_str());
return 1;
}
get_value(cfg, string(path+".port").c_str(), DVRPTR_INTERNAL_PORT, 10000, 65535, 19998 + (DVRPTR_MOD - 'A'));
get_value(cfg, std::string(path+".port").c_str(), DVRPTR_INTERNAL_PORT, 10000, 65535, 19998 + (DVRPTR_MOD - 'A'));
if (get_value(cfg, "gateway.ip", value, 7, IP_SIZE, "127.0.0.1"))
strcpy(GATEWAY_IP, value.c_str());
@ -1979,26 +1978,26 @@ static int read_config(const char *cfgFile)
get_value(cfg, "gateway.internal.port", GATEWAY_PORT, 10000, 65535, 19000);
get_value(cfg, string(path+".rf_tx_level").c_str(), RF_AUDIO_Level, 1, 100, 80);
get_value(cfg, std::string(path+".rf_tx_level").c_str(), RF_AUDIO_Level, 1, 100, 80);
get_value(cfg, string(path+".duplex").c_str(), DUPLEX, false);
get_value(cfg, std::string(path+".duplex").c_str(), DUPLEX, false);
get_value(cfg, string(path+".acknowledge").c_str(), RPTR_ACK, false);
get_value(cfg, std::string(path+".acknowledge").c_str(), RPTR_ACK, false);
get_value(cfg, string(path+".ack_delay").c_str(), i, 1, 999, 300);
get_value(cfg, std::string(path+".ack_delay").c_str(), i, 1, 999, 300);
ACK_DELAY = (long)i;
get_value(cfg, "timing.play.delay", DELAY_BETWEEN, 10, 25, 19);
DELAY_BETWEEN *= 1000;
get_value(cfg, string(path+".tx_delay").c_str(), TX_DELAY, 0, 6000, 250);
get_value(cfg, std::string(path+".tx_delay").c_str(), TX_DELAY, 0, 6000, 250);
Modem_Init2[8] = TX_DELAY & 0xFF;
Modem_Init2[9] = TX_DELAY >> 8;
get_value(cfg, string(path+".rqst_count").c_str(), RQST_COUNT, 6, 20, 10);
get_value(cfg, std::string(path+".rqst_count").c_str(), RQST_COUNT, 6, 20, 10);
get_value(cfg, string(path+".inverse.rx").c_str(), RX_Inverse, true);
get_value(cfg, string(path+".inverse.tx").c_str(), TX_Inverse, true);
get_value(cfg, std::string(path+".inverse.rx").c_str(), RX_Inverse, true);
get_value(cfg, std::string(path+".inverse.tx").c_str(), TX_Inverse, true);
inactiveMax = (REMOTE_TIMEOUT * 1000000) / 400;
logdata("... computed max number of loops %d, each loop is 400 microseconds\n", inactiveMax);

@ -5,7 +5,7 @@ ircddb = {
# If you are not using rr.openquad.net, you need to specify the host and possibly the password.
#
# host = "some.server.host" // others include group1-irc.ircddb.net
# password = "1111111111111" // not needed for rr.penquad.net
# password = "1111111111111" // not needed for rr.openquad.net
}
module = {

@ -53,14 +53,12 @@
#include <string>
#include <map>
#include <libconfig.h++>
using namespace std;
using namespace libconfig;
#include <pthread.h>
#include <wx/hashmap.h>
#include "IRCDDB.h"
#include "IRCutils.h"
#include "versions.h"
#define IP_SIZE 15
@ -75,19 +73,19 @@ using namespace libconfig;
/* configuration data */
typedef struct portip_tag {
string ip;
std::string ip;
int port;
} PORTIP;
/* Gateway callsign */
static string OWNER;
static string owner;
static string local_irc_ip;
static string status_file;
static string dtmf_dir;
static string dtmf_file;
static string echotest_dir;
static string irc_pass;
static std::string OWNER;
static std::string owner;
static std::string local_irc_ip;
static std::string status_file;
static std::string dtmf_dir;
static std::string dtmf_file;
static std::string echotest_dir;
static std::string irc_pass;
PORTIP g2_internal, g2_external, g2_link, ircddb;
@ -125,17 +123,17 @@ static socklen_t aprs_addr_len;
/* data needed for aprs login and aprs beacon */
static struct rptr_struct{
PORTIP aprs;
string aprs_filter;
std::string aprs_filter;
int aprs_hash;
int aprs_interval;
/* 0=A, 1=B, 2=C */
struct mod_struct {
string call; /* KJ4NHF-B */
std::string call; /* KJ4NHF-B */
bool defined;
string band; /* 23cm ... */
std::string band; /* 23cm ... */
double frequency, offset, latitude, longitude, range, agl;
string desc1, desc2, desc, url, package_version;
std::string desc1, desc2, desc, url, package_version;
PORTIP portip;
} mod[3];
} rptr;
@ -274,14 +272,8 @@ static regex_t preg;
CACHE used to cache users, repeaters,
gateways, IP numbers coming from the irc server
*/
WX_DECLARE_STRING_HASH_MAP(wxString, user2rptr_type);
static user2rptr_type user2rptr_map;
WX_DECLARE_STRING_HASH_MAP(wxString, rptr2gwy_type);
static rptr2gwy_type rptr2gwy_map;
WX_DECLARE_STRING_HASH_MAP(wxString, gwy2ip_type);
static gwy2ip_type gwy2ip_map;
static std::map<std::string, std::string> user2rptr_map, rptr2gwy_map, gwy2ip_map;
static pthread_mutex_t irc_data_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -328,7 +320,6 @@ static int get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_
char *mod, char *ip, char RoU);
static bool get_yrcall_rptr(char *call, char *arearp_cs, char *zonerp_cs,
char *mod, char *ip, char RoU);
static void traceit(const char *fmt,...);
static int read_config(char *);
static void runit();
static void sigCatch(int signum);
@ -478,30 +469,6 @@ static void calcPFCS(unsigned char *packet, int len)
return;
}
/* log the event */
static void traceit(const char *fmt,...)
{
time_t ltime;
struct tm tm;
const short BFSZ = 512;
char buf[BFSZ];
time(&ltime);
localtime_r(&ltime, &tm);
snprintf(buf,BFSZ - 1,"%02d/%02d/%02d %d:%02d:%02d:",
tm.tm_mon+1,tm.tm_mday,tm.tm_year % 100,
tm.tm_hour,tm.tm_min,tm.tm_sec);
va_list args;
va_start(args,fmt);
vsnprintf(buf + strlen(buf), BFSZ - strlen(buf) -1, fmt, args);
va_end(args);
fprintf(stdout, "%s", buf);
return;
}
bool get_value(const Config &cfg, const char *path, int &value, int min, int max, int default_value)
{
if (cfg.lookupValue(path, value)) {
@ -532,7 +499,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, string &value, int min, int max, const char *default_value)
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();
@ -549,7 +516,6 @@ bool get_value(const Config &cfg, const char *path, string &value, int min, int
/* process configuration file */
static int read_config(char *cfgFile)
{
unsigned short i;
Config cfg;
traceit("Reading file %s\n", cfgFile);
@ -569,20 +535,16 @@ static int read_config(char *cfgFile)
if (! get_value(cfg, "ircddb.login", owner, 3, CALL_SIZE-2, "UNDEFINED"))
return 1;
OWNER = owner;
for (i=0; i<owner.length(); i++) {
if (islower(owner[i]))
OWNER[i] = toupper(OWNER[i]);
else
owner[i] = tolower(owner[i]);
}
ToLower(owner);
ToUpper(OWNER);
traceit("OWNER=[%s]\n", OWNER.c_str());
OWNER.resize(CALL_SIZE, ' ');
for (short int m=0; m<3; m++) {
string path = "module.";
std::string path = "module.";
path += m + 'a';
string type;
if (cfg.lookupValue(string(path+".type").c_str(), type)) {
std::string type;
if (cfg.lookupValue(std::string(path+".type").c_str(), type)) {
if (strcasecmp(type.c_str(), "dvap") && strcasecmp(type.c_str(), "dvrptr")) {
traceit("%s.type '%s' is invalid\n", type.c_str());
return 1;
@ -592,20 +554,20 @@ static int read_config(char *cfgFile)
rptr.mod[m].package_version = DVAP_VERSION;
else
rptr.mod[m].package_version = DVRPTR_VERSION;
if (! get_value(cfg, string(path+".ip").c_str(), rptr.mod[m].portip.ip, 7, IP_SIZE, "127.0.0.1"))
if (! get_value(cfg, std::string(path+".ip").c_str(), rptr.mod[m].portip.ip, 7, IP_SIZE, "127.0.0.1"))
return 1;
get_value(cfg, string(path+".port").c_str(), rptr.mod[m].portip.port, 16000, 65535, 19998+m);
get_value(cfg, string(path+".frequency").c_str(), rptr.mod[m].frequency, 0.0, 1.0e12, 0.0);
get_value(cfg, string(path+".offset").c_str(), rptr.mod[m].offset,-1.0e12, 1.0e12, 0.0);
get_value(cfg, string(path+".range").c_str(), rptr.mod[m].range, 0.0, 1609344.0, 0.0);
get_value(cfg, string(path+".agl").c_str(), rptr.mod[m].agl, 0.0, 1000.0, 0.0);
get_value(cfg, string(path+".latitude").c_str(), rptr.mod[m].latitude, -90.0, 90.0, 0.0);
get_value(cfg, string(path+".longitude").c_str(), rptr.mod[m].longitude, -180.0, 180.0, 0.0);
get_value(cfg, std::string(path+".port").c_str(), rptr.mod[m].portip.port, 16000, 65535, 19998+m);
get_value(cfg, std::string(path+".frequency").c_str(), rptr.mod[m].frequency, 0.0, 1.0e12, 0.0);
get_value(cfg, std::string(path+".offset").c_str(), rptr.mod[m].offset,-1.0e12, 1.0e12, 0.0);
get_value(cfg, std::string(path+".range").c_str(), rptr.mod[m].range, 0.0, 1609344.0, 0.0);
get_value(cfg, std::string(path+".agl").c_str(), rptr.mod[m].agl, 0.0, 1000.0, 0.0);
get_value(cfg, std::string(path+".latitude").c_str(), rptr.mod[m].latitude, -90.0, 90.0, 0.0);
get_value(cfg, std::string(path+".longitude").c_str(), rptr.mod[m].longitude, -180.0, 180.0, 0.0);
if (! cfg.lookupValue(path+".desc1", rptr.mod[m].desc1))
rptr.mod[m].desc1 = "";
if (! cfg.lookupValue(path+".desc2", rptr.mod[m].desc2))
rptr.mod[m].desc2 = "";
if (! get_value(cfg, string(path+".url").c_str(), rptr.mod[m].url, 0, 80, "github.com/ac2ie/g2_ircddb"))
if (! get_value(cfg, std::string(path+".url").c_str(), rptr.mod[m].url, 0, 80, "github.com/ac2ie/g2_ircddb"))
return 1;
// truncate strings
if (rptr.mod[m].desc1.length() > 20)
@ -755,10 +717,10 @@ static void *get_irc_data(void *arg)
{
struct timespec req;
wxString user;
wxString rptr;
wxString gateway;
wxString ipaddr;
std::string user;
std::string rptr;
std::string gateway;
std::string ipaddr;
DSTAR_PROTOCOL proto;
IRCDDB_RESPONSE_TYPE type;
int rc = 0;
@ -817,10 +779,10 @@ static void *get_irc_data(void *arg)
while (((type = ii->getMessageType()) != IDRT_NONE) && keep_running) {
if (type == IDRT_USER) {
ii->receiveUser(user, rptr, gateway, ipaddr);
if (!user.IsEmpty()) {
if (!rptr.IsEmpty() && !gateway.IsEmpty() && !ipaddr.IsEmpty()) {
if (!user.empty()) {
if (!rptr.empty() && !gateway.empty() && !ipaddr.empty()) {
if (bool_irc_debug)
traceit("C-u:%s,%s,%s,%s\n", user.mb_str(), rptr.mb_str(), gateway.mb_str(), ipaddr.mb_str());
traceit("C-u:%s,%s,%s,%s\n", user.c_str(), rptr.c_str(), gateway.c_str(), ipaddr.c_str());
pthread_mutex_lock(&irc_data_mutex);
@ -836,10 +798,10 @@ static void *get_irc_data(void *arg)
}
} else if (type == IDRT_REPEATER) {
ii->receiveRepeater(rptr, gateway, ipaddr, proto);
if (!rptr.IsEmpty()) {
if (!gateway.IsEmpty() && !ipaddr.IsEmpty()) {
if (!rptr.empty()) {
if (!gateway.empty() && !ipaddr.empty()) {
if (bool_irc_debug)
traceit("C-r:%s,%s,%s\n", rptr.mb_str(), gateway.mb_str(), ipaddr.mb_str());
traceit("C-r:%s,%s,%s\n", rptr.c_str(), gateway.c_str(), ipaddr.c_str());
pthread_mutex_lock(&irc_data_mutex);
@ -854,9 +816,9 @@ static void *get_irc_data(void *arg)
}
} else if (type == IDRT_GATEWAY) {
ii->receiveGateway(gateway, ipaddr, proto);
if (!gateway.IsEmpty() && !ipaddr.IsEmpty()) {
if (!gateway.empty() && !ipaddr.empty()) {
if (bool_irc_debug)
traceit("C-g:%s,%s\n", gateway.mb_str(),ipaddr.mb_str());
traceit("C-g:%s,%s\n", gateway.c_str(),ipaddr.c_str());
pthread_mutex_lock(&irc_data_mutex);
@ -881,9 +843,9 @@ static void *get_irc_data(void *arg)
static int get_yrcall_rptr_from_cache(char *call, char *arearp_cs, char *zonerp_cs,
char *mod, char *ip, char RoU)
{
user2rptr_type::iterator user_pos = user2rptr_map.end();
rptr2gwy_type::iterator rptr_pos = rptr2gwy_map.end();
gwy2ip_type::iterator gwy_pos = gwy2ip_map.end();
std::map<std::string, std::string>::iterator user_pos = user2rptr_map.end();
std::map<std::string, std::string>::iterator rptr_pos = rptr2gwy_map.end();
std::map<std::string, std::string>::iterator gwy_pos = gwy2ip_map.end();
char temp[CALL_SIZE + 1];
memset(arearp_cs, ' ', CALL_SIZE);
@ -2033,7 +1995,10 @@ static void runit()
if ((readBuffer[16] & 0x40) != 0) {
if (dtmf_buf_count[i] > 0) {
dtmf_file = dtmf_dir + "/" + ('A'+i) + "_mod_DTMF_NOTIFY";
dtmf_file = dtmf_dir;
dtmf_file.push_back('/');
dtmf_file.push_back('A'+i);
dtmf_file += "_mod_DTMF_NOTIFY";
if (bool_dtmf_debug)
traceit("Saving dtmfs=[%s] into file: [%s]\n", dtmf_buf[i], dtmf_file.c_str());
dtmf_fp = fopen(dtmf_file.c_str(), "w");
@ -3111,7 +3076,7 @@ static void *echotest(void *arg)
static void qrgs_and_maps()
{
for(int i=0; i<3; i++) {
string rptrcall = OWNER;
std::string rptrcall = OWNER;
rptrcall.resize(CALL_SIZE-1);
rptrcall += i + 'A';
if (rptr.mod[i].latitude || rptr.mod[i].longitude || rptr.mod[i].desc1.length() || rptr.mod[i].url.length())
@ -3127,7 +3092,6 @@ int main(int argc, char **argv)
{
short int i;
struct sigaction act;
bool ok;
int rc = 0;
@ -3230,17 +3194,10 @@ int main(int argc, char **argv)
aprs_init();
compute_aprs_hash();
ok = ::wxInitialize();
if (!ok) {
traceit("Failed to initialize wx\n");
return 1;
}
ii = new CIRCDDB(ircddb.ip, ircddb.port, owner, irc_pass, IRCDDB_VERSION, local_irc_ip);
ok = ii->open();
bool ok = ii->open();
if (!ok) {
traceit("irc open failed\n");
::wxUninitialize();
return 1;
}
@ -3402,7 +3359,6 @@ int main(int argc, char **argv)
}
ii->close();
::wxUninitialize();
traceit("g2_ircddb exiting\n");
return rc;
}

@ -53,7 +53,6 @@
#include <utility>
#include <libconfig.h++>
#include "versions.h"
using namespace std;
using namespace libconfig;
/*** version number must be x.xx ***/
@ -71,25 +70,25 @@ using namespace libconfig;
#define FILE_REFRESH_GWYS_CODE 'F'
/* configuration data */
static string login_call;
static std::string login_call;
static bool only_admin_login;
static bool only_link_unlink;
static string owner;
static std::string owner;
static int rmt_xrf_port;
static int rmt_ref_port;
static int rmt_dcs_port;
static string my_g2_link_ip;
static std::string my_g2_link_ip;
static int my_g2_link_port;
static string to_g2_external_ip;
static std::string to_g2_external_ip;
static int to_g2_external_port;
static bool qso_details;
static string gwys;
static string status_file;
static std::string gwys;
static std::string status_file;
static bool bool_rptr_ack;
static int delay_between;
static int delay_before;
static bool announce;
static string announce_dir;
static std::string announce_dir;
static char link_at_startup[CALL_SIZE+1];
static unsigned int max_dongles;
static unsigned int saved_max_dongles;
@ -120,17 +119,17 @@ struct inbound {
};
/* the Key in this inbound_list map is the unique IP address of the remote */
typedef map<string, inbound *> inbound_type;
typedef std::map<std::string, inbound *> inbound_type;
static inbound_type inbound_list;
typedef set<string> admin_type;
typedef std::set<std::string> admin_type;
static admin_type admin;
typedef set<string> link_unlink_user_type;
typedef std::set<std::string> link_unlink_user_type;
static link_unlink_user_type link_unlink_user;
#define LH_MAX_SIZE 39
typedef map<string, string> dt_lh_type;
typedef std::map<std::string, std::string> dt_lh_type;
static dt_lh_type dt_lh_list;
/*
@ -248,7 +247,7 @@ static unsigned short crc_tabccitt[256] = {
/* the map of remotes */
/* key is the callsign, data is the host */
typedef map<string, string> gwy_list_type;
typedef std::map<std::string, std::string> gwy_list_type;
static gwy_list_type gwy_list;
static unsigned char queryCommand[QUERY_SIZE];
@ -270,7 +269,7 @@ static struct {
{ {0x00, 0x00} }
};
static bool load_gwys(const string &filename);
static bool load_gwys(const std::string &filename);
static void calcPFCS(unsigned char *packet, int len);
static void traceit(const char *fmt,...);
static bool read_config(char *);
@ -617,7 +616,7 @@ static void print_status_file()
}
/* Open text file of repeaters, reflectors */
static bool load_gwys(const string &filename)
static bool load_gwys(const std::string &filename)
{
FILE *fp = NULL;
char inbuf[1024];
@ -634,7 +633,7 @@ static bool load_gwys(const string &filename)
unsigned short j;
gwy_list_type::iterator gwy_pos;
pair<gwy_list_type::iterator,bool> gwy_insert_pair;
std::pair<gwy_list_type::iterator,bool> gwy_insert_pair;
traceit("Trying to open file %s\n", filename.c_str());
fp = fopen(filename.c_str(), "r");
@ -708,7 +707,7 @@ static bool load_gwys(const string &filename)
gwy_pos = gwy_list.find(call);
if (gwy_pos == gwy_list.end()) {
gwy_insert_pair = gwy_list.insert(pair<string,string>(call,payload));
gwy_insert_pair = gwy_list.insert(std::pair<std::string,std::string>(call,payload));
if (gwy_insert_pair.second)
traceit("Added Call=[%s], payload=[%s]\n",call, payload);
else
@ -813,7 +812,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, string &value, int min, int max, const char *default_value)
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();
@ -849,8 +848,8 @@ static bool read_config(char *cfgFile)
return 1;
}
string value;
string key = "g2_link.ref_login";
std::string value;
std::string key = "g2_link.ref_login";
if (cfg.lookupValue(key, login_call) || cfg.lookupValue("ircddb.login", login_call)) {
int l = login_call.length();
if (l<3 || l>CALL_SIZE-2) {
@ -986,7 +985,7 @@ static bool read_config(char *cfgFile)
get_value(cfg, "timing.play.wait", delay_before, 1, 10, 2);
if (! get_value(cfg, "g2_link.link_at_start", value, 5, CALL_SIZE, "NONE")) {
if (get_value(cfg, "g2_link.link_at_start", value, 5, CALL_SIZE, "NONE")) {
if (strcasecmp(value.c_str(), "none"))
strcpy(link_at_startup, value.c_str());
} else
@ -1367,7 +1366,7 @@ static void runit()
int max_nfds = 0;
char tmp1[CALL_SIZE + 1];
char tmp2[36]; // 8 for rpt1 + 24 for time_t in string format
char tmp2[36]; // 8 for rpt1 + 24 for time_t in std::string format
dt_lh_type::iterator dt_lh_pos;
dt_lh_type::reverse_iterator r_dt_lh_pos;
@ -1377,9 +1376,9 @@ static void runit()
char ip[IP_SIZE + 1];
inbound *inbound_ptr;
inbound_type::iterator pos;
pair<inbound_type::iterator,bool> insert_pair;
std::pair<inbound_type::iterator,bool> insert_pair;
bool found = false;
set<string>::iterator it;
std::set<std::string>::iterator it;
char cmd_2_dcs[23];
unsigned char dcs_seq[3] = { 0x00, 0x00, 0x00 };
@ -2882,7 +2881,7 @@ static void runit()
else
inbound_ptr->client = 'D'; /* dongle */
insert_pair = inbound_list.insert(pair<string, inbound *>(ip, inbound_ptr));
insert_pair = inbound_list.insert(std::pair<std::string, inbound *>(ip, inbound_ptr));
if (insert_pair.second) {
if (memcmp(inbound_ptr->call, "1NFO", 4) != 0)
traceit("new CALL=%s, DONGLE-p, ip=%s, users=%d\n",

@ -1,5 +1,5 @@
// version strings must be 55 characters or less!
#define IRCDDB_VERSION "linux-g2_ircddb-4.1.0"
#define LINK_VERSION "4.01"
#define DVAP_VERSION "linux-dvap_rptr-3.0.0"
#define DVRPTR_VERSION "linux-dvrptr-2.0.0"
#define IRCDDB_VERSION "linux-g2_ircddb-5.0.0"
#define LINK_VERSION "5.00"
#define DVAP_VERSION "linux-dvap_rptr-5.0.0"
#define DVRPTR_VERSION "linux-dvrptr-5.0.0"

Loading…
Cancel
Save

Powered by TurnKey Linux.