K&R formating and warnings fixed.

ki4klf
ac2ie 12 years ago
parent dd4fb774e2
commit 90862645f6

@ -28,25 +28,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class IRCApplication class IRCApplication
{ {
public: public:
virtual void userJoin (const wxString& nick, const wxString& name, const wxString& host) = 0; virtual void userJoin (const wxString& nick, const wxString& name, const wxString& host) = 0;
virtual void userLeave (const wxString& nick) = 0; virtual void userLeave (const wxString& nick) = 0;
virtual void userChanOp (const wxString& nick, bool op) = 0; virtual void userChanOp (const wxString& nick, bool op) = 0;
virtual void userListReset(void) = 0; virtual void userListReset(void) = 0;
virtual void msgChannel (IRCMessage * m) = 0; virtual void msgChannel (IRCMessage * m) = 0;
virtual void msgQuery (IRCMessage * m) = 0; virtual void msgQuery (IRCMessage * m) = 0;
virtual void setCurrentNick(const wxString& nick) = 0; virtual void setCurrentNick(const wxString& nick) = 0;
virtual void setTopic(const wxString& topic) = 0; virtual void setTopic(const wxString& topic) = 0;
virtual void setBestServer(const wxString& ircUser) = 0; virtual void setBestServer(const wxString& ircUser) = 0;
virtual void setSendQ( IRCMessageQueue * s ) = 0; virtual void setSendQ( IRCMessageQueue * s ) = 0;
virtual IRCMessageQueue * getSendQ (void) = 0; virtual IRCMessageQueue * getSendQ (void) = 0;
virtual ~IRCApplication() {} virtual ~IRCApplication() {}
}; };

@ -52,458 +52,395 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
IRCClient::IRCClient( IRCApplication * app, const wxString& update_channel, IRCClient::IRCClient( IRCApplication * app, const wxString& update_channel,
const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password, const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password,
const wxString& versionInfo, const wxString& localAddr ) const wxString& versionInfo, const wxString& localAddr )
: wxThread(wxTHREAD_JOINABLE) : wxThread(wxTHREAD_JOINABLE)
{ {
safeStringCopy(host_name, hostName.mb_str(), sizeof host_name); safeStringCopy(host_name, hostName.mb_str(), sizeof host_name);
this -> callsign = callsign.Lower(); this -> callsign = callsign.Lower();
this -> port = port; this -> port = port;
this -> password = password; this -> password = password;
this -> app = app; this -> app = app;
if (localAddr.IsEmpty()) if (localAddr.IsEmpty()) {
{ safeStringCopy(local_addr, "0.0.0.0", sizeof local_addr);
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.mb_str(), sizeof local_addr);
}
proto = new IRCProtocol ( app, this->callsign, password, update_channel, versionInfo ); proto = new IRCProtocol ( app, this->callsign, password, update_channel, versionInfo );
recvQ = NULL; recvQ = NULL;
sendQ = NULL; sendQ = NULL;
recv = NULL; recv = NULL;
} }
IRCClient::~IRCClient() IRCClient::~IRCClient()
{ {
delete proto; delete proto;
} }
bool IRCClient::startWork() bool IRCClient::startWork()
{ {
if (Create() != wxTHREAD_NO_ERROR) if (Create() != wxTHREAD_NO_ERROR) {
{ wxLogError(wxT("IRCClient::startWork: Could not create the worker thread!"));
wxLogError(wxT("IRCClient::startWork: Could not create the worker thread!")); return false;
return false; }
}
terminateThread = false; terminateThread = false;
if (Run() != wxTHREAD_NO_ERROR) if (Run() != wxTHREAD_NO_ERROR) {
{ wxLogError(wxT("IRCClient::startWork: Could not run the worker thread!"));
wxLogError(wxT("IRCClient::startWork: Could not run the worker thread!")); return false;
return false; }
}
return true; return true;
} }
void IRCClient::stopWork() void IRCClient::stopWork()
{ {
terminateThread = true; terminateThread = true;
Wait(); Wait();
} }
wxThread::ExitCode IRCClient::Entry () wxThread::ExitCode IRCClient::Entry ()
{ {
unsigned int numAddr; unsigned int numAddr;
#define MAXIPV4ADDR 10 #define MAXIPV4ADDR 10
struct sockaddr_in addr[MAXIPV4ADDR]; struct sockaddr_in addr[MAXIPV4ADDR];
struct sockaddr_in myaddr;
int state = 0;
int timer = 0;
int sock = 0;
unsigned int currentAddr = 0;
int result; struct sockaddr_in myaddr;
int state = 0;
int timer = 0;
int sock = 0;
unsigned int currentAddr = 0;
numAddr = 0; int result;
result = getAllIPV4Addresses(local_addr, 0, &numAddr, &myaddr, 1);
if ((result != 0) || (numAddr != 1)) numAddr = 0;
{
wxLogVerbose(wxT("IRCClient::Entry: local address not parseable, using 0.0.0.0"));
memset(&myaddr, 0x00, sizeof(struct sockaddr_in));
}
while (true) result = getAllIPV4Addresses(local_addr, 0, &numAddr, &myaddr, 1);
{
if (timer > 0) if ((result != 0) || (numAddr != 1)) {
{ wxLogVerbose(wxT("IRCClient::Entry: local address not parseable, using 0.0.0.0"));
timer --; memset(&myaddr, 0x00, sizeof(struct sockaddr_in));
}
switch (state)
{
case 0:
if (terminateThread)
{
wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state);
return 0;
}
if (timer == 0)
{
timer = 30;
if (getAllIPV4Addresses(host_name, port, &numAddr, addr, MAXIPV4ADDR) == 0)
{
wxLogVerbose(wxT("IRCClient::Entry: number of DNS entries %d"), numAddr);
if (numAddr > 0)
{
currentAddr = 0;
state = 1;
timer = 0;
}
} }
}
break;
case 1: while (true) {
if (terminateThread)
{
wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state);
return 0;
}
if (timer == 0) if (timer > 0) {
{ timer --;
sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP); }
if (sock < 0) switch (state) {
{ case 0:
wxLogSysError(wxT("IRCClient::Entry: socket")); if (terminateThread) {
timer = 30; wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state);
state = 0; return 0;
} }
else
{ if (timer == 0) {
timer = 30;
if (getAllIPV4Addresses(host_name, port, &numAddr, addr, MAXIPV4ADDR) == 0) {
wxLogVerbose(wxT("IRCClient::Entry: number of DNS entries %d"), numAddr);
if (numAddr > 0) {
currentAddr = 0;
state = 1;
timer = 0;
}
}
}
break;
case 1:
if (terminateThread) {
wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state);
return 0;
}
if (timer == 0) {
sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
wxLogSysError(wxT("IRCClient::Entry: socket"));
timer = 30;
state = 0;
} else {
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
u_long nonBlock = 1UL; u_long nonBlock = 1UL;
if (ioctlsocket( sock, FIONBIO, &nonBlock ) != 0) if (ioctlsocket( sock, FIONBIO, &nonBlock ) != 0) {
{ wxLogSysError(wxT("IRCClient::Entry: ioctlsocket"));
wxLogSysError(wxT("IRCClient::Entry: ioctlsocket")); closesocket(sock);
closesocket(sock); timer = 30;
timer = 30; state = 0;
state = 0; }
}
#else #else
if (fcntl( sock, F_SETFL, O_NONBLOCK ) < 0) if (fcntl( sock, F_SETFL, O_NONBLOCK ) < 0) {
{ wxLogSysError(wxT("IRCClient::Entry: fcntl"));
wxLogSysError(wxT("IRCClient::Entry: fcntl")); close(sock);
close(sock); timer = 30;
timer = 30; state = 0;
state = 0; }
}
#endif #endif
else else {
{ unsigned char * h = (unsigned char *) &(myaddr.sin_addr);
unsigned char * h = (unsigned char *) &(myaddr.sin_addr); int res;
int res;
if ((h[0] != 0) || (h[1] != 0) || (h[2] != 0) || (h[3] != 0)) if ((h[0] != 0) || (h[1] != 0) || (h[2] != 0) || (h[3] != 0)) {
{ wxLogVerbose(wxT("IRCClient::Entry: bind: local address %d.%d.%d.%d"),
wxLogVerbose(wxT("IRCClient::Entry: bind: local address %d.%d.%d.%d"), h[0], h[1], h[2], h[3]);
h[0], h[1], h[2], h[3]); }
}
res = bind(sock, (struct sockaddr *) &myaddr, sizeof (struct sockaddr_in)); res = bind(sock, (struct sockaddr *) &myaddr, sizeof (struct sockaddr_in));
if (res != 0) if (res != 0) {
{
wxLogSysError(wxT("IRCClient::Entry: bind")); wxLogSysError(wxT("IRCClient::Entry: bind"));
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
closesocket(sock); closesocket(sock);
#else #else
close(sock); close(sock);
#endif #endif
state = 0; state = 0;
timer = 30; timer = 30;
break; break;
} }
h = (unsigned char *) &(addr[currentAddr].sin_addr); h = (unsigned char *) &(addr[currentAddr].sin_addr);
wxLogVerbose(wxT("IRCClient::Entry: trying to connect to %d.%d.%d.%d"), wxLogVerbose(wxT("IRCClient::Entry: trying to connect to %d.%d.%d.%d"),
h[0], h[1], h[2], h[3]); h[0], h[1], h[2], h[3]);
res = connect(sock, (struct sockaddr *) (addr + currentAddr), sizeof (struct sockaddr_in)); res = connect(sock, (struct sockaddr *) (addr + currentAddr), sizeof (struct sockaddr_in));
if (res == 0) if (res == 0) {
{ wxLogVerbose(wxT("IRCClient::Entry: connected"));
wxLogVerbose(wxT("IRCClient::Entry: connected")); state = 4;
state = 4; } else {
}
else
{
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
if (WSAGetLastError() == WSAEWOULDBLOCK) if (WSAGetLastError() == WSAEWOULDBLOCK)
#else #else
if (errno == EINPROGRESS) if (errno == EINPROGRESS)
#endif #endif
{ {
wxLogVerbose(wxT("IRCClient::Entry: connect in progress")); wxLogVerbose(wxT("IRCClient::Entry: connect in progress"));
state = 3; state = 3;
timer = 10; // 5 second timeout timer = 10; // 5 second timeout
} } else {
else wxLogSysError(wxT("IRCClient::Entry: connect"));
{
wxLogSysError(wxT("IRCClient::Entry: connect"));
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
closesocket(sock); closesocket(sock);
#else #else
close(sock); close(sock);
#endif #endif
currentAddr ++; currentAddr ++;
if (currentAddr >= numAddr) if (currentAddr >= numAddr) {
{ state = 0;
state = 0; timer = 30;
timer = 30; } else {
} state = 1;
else timer = 4;
{ }
state = 1; }
timer = 4; }
} } // connect
} }
} }
} // connect break;
}
} case 3: {
break; struct timeval tv;
tv.tv_sec = 0;
case 3: tv.tv_usec = 0;
{ fd_set myset;
struct timeval tv; FD_ZERO(&myset);
tv.tv_sec = 0; FD_SET(sock, &myset);
tv.tv_usec = 0; int res;
fd_set myset; res = select(sock+1, NULL, &myset, NULL, &tv);
FD_ZERO(&myset);
FD_SET(sock, &myset); if (res < 0) {
int res; wxLogSysError(wxT("IRCClient::Entry: select"));
res = select(sock+1, NULL, &myset, NULL, &tv);
if (res < 0)
{
wxLogSysError(wxT("IRCClient::Entry: select"));
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
closesocket(sock); closesocket(sock);
#else #else
close(sock); close(sock);
#endif #endif
state = 0; state = 0;
timer = 30; timer = 30;
} } else if (res > 0) { // connect is finished
else if (res > 0) // connect is finished
{
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
int val_len; int val_len;
#else #else
socklen_t val_len; socklen_t val_len;
#endif #endif
int value; int value;
val_len = sizeof value; val_len = sizeof value;
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *) &value, &val_len) < 0) if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *) &value, &val_len) < 0) {
{ wxLogSysError(wxT("IRCClient::Entry: getsockopt"));
wxLogSysError(wxT("IRCClient::Entry: getsockopt"));
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
closesocket(sock); closesocket(sock);
#else #else
close(sock); close(sock);
#endif #endif
state = 0; state = 0;
timer = 30; timer = 30;
} } else {
else if (value != 0) {
{ wxLogWarning(wxT("IRCClient::Entry: SO_ERROR=%d"), value);
if (value != 0)
{
wxLogWarning(wxT("IRCClient::Entry: SO_ERROR=%d"), value);
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
closesocket(sock); closesocket(sock);
#else #else
close(sock); close(sock);
#endif #endif
currentAddr ++; currentAddr ++;
if (currentAddr >= numAddr) if (currentAddr >= numAddr) {
{ state = 0;
state = 0; timer = 30;
timer = 30; } else {
} state = 1;
else timer = 2;
{ }
state = 1; } else {
timer = 2; wxLogVerbose(wxT("IRCClient::Entry: connected2"));
} state = 4;
} }
else }
{
wxLogVerbose(wxT("IRCClient::Entry: connected2")); } else if (timer == 0) {
state = 4; // select timeout and timer timeout
} wxLogVerbose(wxT("IRCClient::Entry: connect timeout"));
}
}
else if (timer == 0)
{ // select timeout and timer timeout
wxLogVerbose(wxT("IRCClient::Entry: connect timeout"));
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
closesocket(sock); closesocket(sock);
#else #else
close(sock); close(sock);
#endif #endif
currentAddr ++; currentAddr ++;
if (currentAddr >= numAddr) if (currentAddr >= numAddr) {
{ state = 0;
state = 0; timer = 30;
timer = 30; } else {
} state = 1; // open new socket
else timer = 2;
{ }
state = 1; // open new socket }
timer = 2;
}
}
} }
break; break;
case 4: case 4: {
{ recvQ = new IRCMessageQueue();
recvQ = new IRCMessageQueue(); sendQ = new IRCMessageQueue();
sendQ = new IRCMessageQueue();
recv = new IRCReceiver(sock, recvQ); recv = new IRCReceiver(sock, recvQ);
recv->startWork(); recv->startWork();
proto->setNetworkReady(true); proto->setNetworkReady(true);
state = 5; state = 5;
timer = 0; timer = 0;
} }
break; break;
case 5: case 5:
if (terminateThread) if (terminateThread) {
{ state = 6;
state = 6; } else {
}
else
{
if (recvQ -> isEOF()) if (recvQ -> isEOF()) {
{ timer = 0;
timer = 0; state = 6;
state = 6; } else if (proto -> processQueues(recvQ, sendQ) == false) {
} timer = 0;
else if (proto -> processQueues(recvQ, sendQ) == false) state = 6;
{ }
timer = 0;
state = 6;
}
while ((state == 5) && sendQ->messageAvailable()) while ((state == 5) && sendQ->messageAvailable()) {
{ IRCMessage * m = sendQ -> getMessage();
IRCMessage * m = sendQ -> getMessage();
wxString out; wxString out;
m -> composeMessage ( out ); m -> composeMessage ( out );
char buf[200]; char buf[200];
safeStringCopy(buf, out.mb_str(wxConvUTF8), sizeof buf); safeStringCopy(buf, out.mb_str(wxConvUTF8), sizeof buf);
int len = strlen(buf); int len = strlen(buf);
if (buf[len - 1] == 10) // is there a NL char at the end? if (buf[len - 1] == 10) { // is there a NL char at the end?
{ int r = send(sock, buf, len, 0);
int r = send(sock, buf, len, 0);
if (r != len) if (r != len) {
{ wxLogVerbose(wxT("IRCClient::Entry: short write %d < %d"), r, len);
wxLogVerbose(wxT("IRCClient::Entry: short write %d < %d"), r, len);
timer = 0; timer = 0;
state = 6; state = 6;
} }
/* else /* else
{ {
wxLogVerbose(wxT("write %d bytes (") + out + wxT(")"), len ); wxLogVerbose(wxT("write %d bytes (") + out + wxT(")"), len );
} */ } */
} } else {
else wxLogVerbose(wxT("IRCClient::Entry: no NL at end, len=%d"), len);
{
wxLogVerbose(wxT("IRCClient::Entry: no NL at end, len=%d"), len);
timer = 0; timer = 0;
state = 6; state = 6;
} }
delete m; delete m;
} }
} }
break; break;
case 6: case 6: {
{ if (app != NULL) {
if (app != NULL) app->setSendQ(NULL);
{ app->userListReset();
app->setSendQ(NULL); }
app->userListReset();
}
proto->setNetworkReady(false); proto->setNetworkReady(false);
recv->stopWork(); recv->stopWork();
wxThread::Sleep(2000); wxThread::Sleep(2000);
delete recv; delete recv;
delete recvQ; delete recvQ;
delete sendQ; delete sendQ;
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
closesocket(sock); closesocket(sock);
#else #else
close(sock); close(sock);
#endif #endif
if (terminateThread) // request to end the thread if (terminateThread) { // request to end the thread
{ wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state);
wxLogVerbose(wxT("IRCClient::Entry: thread terminated at state=%d"), state); return 0;
return 0; }
}
timer = 30; timer = 30;
state = 0; // reconnect to IRC server state = 0; // reconnect to IRC server
} }
break; break;
} }
wxThread::Sleep(500); wxThread::Sleep(500);
} }
return 0; return 0;
} }

@ -33,42 +33,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class IRCClient : public wxThread class IRCClient : public wxThread
{ {
public: public:
IRCClient( IRCApplication * app, const wxString& update_channel, IRCClient( IRCApplication * app, const wxString& update_channel,
const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password, const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password,
const wxString& versionInfo, const wxString& localAddr ); const wxString& versionInfo, const wxString& localAddr );
~IRCClient(); ~IRCClient();
bool startWork(); bool startWork();
void stopWork(); void stopWork();
protected: protected:
virtual wxThread::ExitCode Entry(); virtual wxThread::ExitCode Entry();
private: private:
char host_name[100]; char host_name[100];
char local_addr[100]; char local_addr[100];
unsigned int port; unsigned int port;
wxString callsign; wxString callsign;
wxString password; wxString password;
bool terminateThread; bool terminateThread;
IRCReceiver * recv; IRCReceiver * recv;
IRCMessageQueue * recvQ; IRCMessageQueue * recvQ;
IRCMessageQueue * sendQ; IRCMessageQueue * sendQ;
IRCProtocol * proto; IRCProtocol * proto;
IRCApplication * app; IRCApplication * app;
}; };

@ -28,269 +28,237 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <wx/wx.h> #include <wx/wx.h>
struct CIRCDDBPrivate struct CIRCDDBPrivate {
{ IRCClient * client;
IRCClient * client; IRCDDBApp * app;
IRCDDBApp * app;
}; };
CIRCDDB::CIRCDDB(const wxString& hostName, unsigned int port, CIRCDDB::CIRCDDB(const wxString& hostName, unsigned int port,
const wxString& callsign, const wxString& password, const wxString& callsign, const wxString& password,
const wxString& versionInfo, const wxString& localAddr ) : d( new CIRCDDBPrivate ) const wxString& versionInfo, const wxString& localAddr ) : d( new CIRCDDBPrivate )
{ {
wxString update_channel = wxT("#dstar"); wxString update_channel = wxT("#dstar");
d->app = new IRCDDBApp(update_channel); d->app = new IRCDDBApp(update_channel);
d->client = new IRCClient( d->app, update_channel, hostName, port, callsign, d->client = new IRCClient( d->app, update_channel, hostName, port, callsign,
password, versionInfo, localAddr ); password, versionInfo, localAddr );
} }
CIRCDDB::~CIRCDDB() CIRCDDB::~CIRCDDB()
{ {
delete d->client; delete d->client;
delete d->app; delete d->app;
delete d; delete d;
} }
// A false return implies a network error, or unable to log in // A false return implies a network error, or unable to log in
bool CIRCDDB::open() bool CIRCDDB::open()
{ {
wxLogVerbose(wxT("start")); wxLogVerbose(wxT("start"));
return d->client -> startWork() && d->app->startWork(); return d->client -> startWork() && d->app->startWork();
} }
int CIRCDDB::getConnectionState() int CIRCDDB::getConnectionState()
{ {
return d->app->getConnectionState(); return d->app->getConnectionState();
} }
void CIRCDDB::rptrQTH( double latitude, double longitude, const wxString& desc1, void CIRCDDB::rptrQTH( double latitude, double longitude, const wxString& desc1,
const wxString& desc2, const wxString& infoURL ) const wxString& desc2, const wxString& infoURL )
{ {
d->app->rptrQTH(latitude, longitude, desc1, desc2, infoURL); d->app->rptrQTH(latitude, longitude, desc1, desc2, infoURL);
} }
void CIRCDDB::rptrQRG( const wxString& module, double txFrequency, double duplexShift, void CIRCDDB::rptrQRG( const wxString& module, double txFrequency, double duplexShift,
double range, double agl ) double range, double agl )
{ {
d->app->rptrQRG(module, txFrequency, duplexShift, range, agl); d->app->rptrQRG(module, txFrequency, duplexShift, range, agl);
} }
void CIRCDDB::kickWatchdog ( const wxString& wdInfo ) void CIRCDDB::kickWatchdog ( const wxString& wdInfo )
{ {
d->app->kickWatchdog( wdInfo ); d->app->kickWatchdog( wdInfo );
} }
// Send heard data, a false return implies a network error // Send heard data, a false return implies a network error
bool CIRCDDB::sendHeard( const wxString& myCall, const wxString& myCallExt, bool CIRCDDB::sendHeard( const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1, const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1, const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3 ) unsigned char flag2, unsigned char flag3 )
{ {
if (myCall.Len() != 8) if (myCall.Len() != 8) {
{ wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8"));
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8")); return false;
return false; }
}
if (myCallExt.Len() != 4) {
if (myCallExt.Len() != 4) wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4"));
{ return false;
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4")); }
return false;
} if (yourCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8"));
if (yourCall.Len() != 8) return false;
{ }
wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8"));
return false; if (rpt1.Len() != 8) {
} wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8"));
return false;
if (rpt1.Len() != 8) }
{
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8")); if (rpt2.Len() != 8) {
return false; wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8"));
} return false;
}
if (rpt2.Len() != 8)
{ return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8")); wxT(" "), wxT(""), wxT(""));
return false;
}
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
wxT(" "), wxT(""), wxT(""));
} }
// Send heard data, a false return implies a network error // Send heard data, a false return implies a network error
bool CIRCDDB::sendHeardWithTXMsg( const wxString& myCall, const wxString& myCallExt, bool CIRCDDB::sendHeardWithTXMsg( const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1, const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1, const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3, unsigned char flag2, unsigned char flag3,
const wxString& network_destination, const wxString& network_destination,
const wxString& tx_message ) const wxString& tx_message )
{ {
if (myCall.Len() != 8) if (myCall.Len() != 8) {
{ wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8"));
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8")); return false;
return false; }
}
if (myCallExt.Len() != 4) {
if (myCallExt.Len() != 4) wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4"));
{ return false;
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4")); }
return false;
} if (yourCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8"));
if (yourCall.Len() != 8) return false;
{ }
wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8"));
return false; if (rpt1.Len() != 8) {
} wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8"));
return false;
if (rpt1.Len() != 8) }
{
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8")); if (rpt2.Len() != 8) {
return false; wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8"));
} return false;
}
if (rpt2.Len() != 8)
{ wxString dest = network_destination;
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8"));
return false; if (dest.Len() == 0) {
} dest = wxT(" ");
}
wxString dest = network_destination;
if (dest.Len() != 8) {
if (dest.Len() == 0) wxLogVerbose(wxT("CIRCDDB::sendHeard:network_destination: len != 8"));
{ return false;
dest = wxT(" "); }
}
wxString msg;
if (dest.Len() != 8)
{ if (tx_message.Len() == 20) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:network_destination: len != 8")); unsigned int i;
return false; for (i=0; i < tx_message.Len(); i++) {
} wxChar ch = tx_message.GetChar(i);
wxString msg; if ((ch > 32) && (ch < 127)) {
msg.Append(ch);
if (tx_message.Len() == 20) } else {
{ msg.Append(wxT('_'));
unsigned int i; }
for (i=0; i < tx_message.Len(); i++) }
{ }
wxChar ch = tx_message.GetChar(i);
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
if ((ch > 32) && (ch < 127)) dest, msg, wxT(""));
{
msg.Append(ch);
}
else
{
msg.Append(wxT('_'));
}
}
}
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
dest, msg, wxT(""));
} }
bool CIRCDDB::sendHeardWithTXStats( const wxString& myCall, const wxString& myCallExt, bool CIRCDDB::sendHeardWithTXStats( const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1, const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1, const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3, unsigned char flag2, unsigned char flag3,
int num_dv_frames, int num_dv_frames,
int num_dv_silent_frames, int num_dv_silent_frames,
int num_bit_errors ) int num_bit_errors )
{ {
if ((num_dv_frames <= 0) || (num_dv_frames > 65535)) if ((num_dv_frames <= 0) || (num_dv_frames > 65535)) {
{ wxLogVerbose(wxT("CIRCDDB::sendHeard:num_dv_frames not in range 1-65535"));
wxLogVerbose(wxT("CIRCDDB::sendHeard:num_dv_frames not in range 1-65535")); return false;
return false; }
}
if (num_dv_silent_frames > num_dv_frames) {
if (num_dv_silent_frames > num_dv_frames) wxLogVerbose(wxT("CIRCDDB::sendHeard:num_dv_silent_frames > num_dv_frames"));
{ return false;
wxLogVerbose(wxT("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 return false;
{ }
wxLogVerbose(wxT("CIRCDDB::sendHeard:num_bit_errors > (4*num_dv_frames)"));
return false; if (myCall.Len() != 8) {
} wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8"));
return false;
if (myCall.Len() != 8) }
{
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCall: len != 8")); if (myCallExt.Len() != 4) {
return false; wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4"));
} return false;
}
if (myCallExt.Len() != 4)
{ if (yourCall.Len() != 8) {
wxLogVerbose(wxT("CIRCDDB::sendHeard:myCallExt: len != 4")); wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8"));
return false; return false;
} }
if (yourCall.Len() != 8) if (rpt1.Len() != 8) {
{ wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8"));
wxLogVerbose(wxT("CIRCDDB::sendHeard:yourCall: len != 8")); return false;
return false; }
}
if (rpt2.Len() != 8) {
if (rpt1.Len() != 8) wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8"));
{ return false;
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt1: len != 8")); }
return false;
} wxString stats = wxString::Format(wxT("%04x"), num_dv_frames);
if (rpt2.Len() != 8) if (num_dv_silent_frames >= 0) {
{ wxString s = wxString::Format(wxT("%02x"), (num_dv_silent_frames * 100) / num_dv_frames);
wxLogVerbose(wxT("CIRCDDB::sendHeard:rpt2: len != 8")); stats.Append(s);
return false;
} if (num_bit_errors >= 0) {
s = wxString::Format(wxT("%02x"), (num_bit_errors * 125) / (num_dv_frames * 3));
wxString stats = wxString::Format(wxT("%04x"), num_dv_frames); stats.Append(s);
} else {
if (num_dv_silent_frames >= 0) stats.Append(wxT("__"));
{ }
wxString s = wxString::Format(wxT("%02x"), (num_dv_silent_frames * 100) / num_dv_frames); } else {
stats.Append(s); stats.Append(wxT("____"));
}
if (num_bit_errors >= 0)
{ stats.Append(wxT("____________")); // stats string should have 20 chars
s = wxString::Format(wxT("%02x"), (num_bit_errors * 125) / (num_dv_frames * 3));
stats.Append(s); return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
} wxT(" "), wxT(""), stats);
else
{
stats.Append(wxT("__"));
}
}
else
{
stats.Append(wxT("____"));
}
stats.Append(wxT("____________")); // stats string should have 20 chars
return d->app->sendHeard( myCall, myCallExt, yourCall, rpt1, rpt2, flag1, flag2, flag3,
wxT(" "), wxT(""), stats);
} }
@ -298,37 +266,34 @@ bool CIRCDDB::sendHeardWithTXStats( const wxString& myCall, const wxString& myCa
// Send query for a gateway/reflector, a false return implies a network error // Send query for a gateway/reflector, a false return implies a network error
bool CIRCDDB::findGateway(const wxString& gatewayCallsign) bool CIRCDDB::findGateway(const wxString& gatewayCallsign)
{ {
if (gatewayCallsign.Len() != 8) if (gatewayCallsign.Len() != 8) {
{ wxLogVerbose(wxT("CIRCDDB::findGateway: len != 8"));
wxLogVerbose(wxT("CIRCDDB::findGateway: len != 8")); return false;
return false; }
}
return d->app->findGateway( gatewayCallsign.Upper()); return d->app->findGateway( gatewayCallsign.Upper());
} }
bool CIRCDDB::findRepeater(const wxString& repeaterCallsign) bool CIRCDDB::findRepeater(const wxString& repeaterCallsign)
{ {
if (repeaterCallsign.Len() != 8) if (repeaterCallsign.Len() != 8) {
{ wxLogVerbose(wxT("CIRCDDB::findRepeater: len != 8"));
wxLogVerbose(wxT("CIRCDDB::findRepeater: len != 8")); return false;
return false; }
}
return d->app->findRepeater( repeaterCallsign.Upper()); return d->app->findRepeater( repeaterCallsign.Upper());
} }
// Send query for a user, a false return implies a network error // Send query for a user, a false return implies a network error
bool CIRCDDB::findUser(const wxString& userCallsign) bool CIRCDDB::findUser(const wxString& userCallsign)
{ {
if (userCallsign.Len() != 8) if (userCallsign.Len() != 8) {
{ wxLogVerbose(wxT("CIRCDDB::findUser: len != 8"));
wxLogVerbose(wxT("CIRCDDB::findUser: len != 8")); return false;
return false; }
}
return d->app->findUser( userCallsign.Upper()); return d->app->findUser( userCallsign.Upper());
} }
// The following functions are for processing received messages // The following functions are for processing received messages
@ -336,143 +301,131 @@ bool CIRCDDB::findUser(const wxString& userCallsign)
// Get the waiting message type // Get the waiting message type
IRCDDB_RESPONSE_TYPE CIRCDDB::getMessageType() IRCDDB_RESPONSE_TYPE CIRCDDB::getMessageType()
{ {
return d->app->getReplyMessageType(); return d->app->getReplyMessageType();
} }
// Get a gateway message, as a result of IDRT_REPEATER returned from getMessageType() // Get a gateway message, as a result of IDRT_REPEATER returned from getMessageType()
// A false return implies a network error // A false return implies a network error
bool CIRCDDB::receiveRepeater(wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address, DSTAR_PROTOCOL& protocol) bool CIRCDDB::receiveRepeater(wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address, DSTAR_PROTOCOL& /*protocol*/)
{ {
IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType(); IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType();
if (rt != IDRT_REPEATER) if (rt != IDRT_REPEATER) {
{ wxLogError(wxT("CIRCDDB::receiveRepeater: unexpected response type"));
wxLogError(wxT("CIRCDDB::receiveRepeater: unexpected response type")); return false;
return false; }
}
IRCMessage * m = d->app->getReplyMessage(); IRCMessage * m = d->app->getReplyMessage();
if (m == NULL) if (m == NULL) {
{ wxLogError(wxT("CIRCDDB::receiveRepeater: no message"));
wxLogError(wxT("CIRCDDB::receiveRepeater: no message")); return false;
return false; }
}
if (!m->getCommand().IsSameAs(wxT("IDRT_REPEATER"))) if (!m->getCommand().IsSameAs(wxT("IDRT_REPEATER"))) {
{ wxLogError(wxT("CIRCDDB::receiveRepeater: wrong message type"));
wxLogError(wxT("CIRCDDB::receiveRepeater: wrong message type")); return false;
return false; }
}
if (m->getParamCount() != 3) if (m->getParamCount() != 3) {
{ wxLogError(wxT("CIRCDDB::receiveRepeater: unexpected number of message parameters"));
wxLogError(wxT("CIRCDDB::receiveRepeater: unexpected number of message parameters")); return false;
return false; }
}
repeaterCallsign = m->getParam(0); repeaterCallsign = m->getParam(0);
gatewayCallsign = m->getParam(1); gatewayCallsign = m->getParam(1);
address = m->getParam(2); address = m->getParam(2);
delete m; delete m;
return true; return true;
} }
// Get a gateway message, as a result of IDRT_GATEWAY returned from getMessageType() // Get a gateway message, as a result of IDRT_GATEWAY returned from getMessageType()
// A false return implies a network error // A false return implies a network error
bool CIRCDDB::receiveGateway(wxString& gatewayCallsign, wxString& address, DSTAR_PROTOCOL& protocol) bool CIRCDDB::receiveGateway(wxString& gatewayCallsign, wxString& address, DSTAR_PROTOCOL& /*protocol*/)
{ {
IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType(); IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType();
if (rt != IDRT_GATEWAY) if (rt != IDRT_GATEWAY) {
{ wxLogError(wxT("CIRCDDB::receiveGateway: unexpected response type"));
wxLogError(wxT("CIRCDDB::receiveGateway: unexpected response type")); return false;
return false; }
}
IRCMessage * m = d->app->getReplyMessage(); IRCMessage * m = d->app->getReplyMessage();
if (m == NULL) if (m == NULL) {
{ wxLogError(wxT("CIRCDDB::receiveGateway: no message"));
wxLogError(wxT("CIRCDDB::receiveGateway: no message")); return false;
return false; }
}
if (!m->getCommand().IsSameAs(wxT("IDRT_GATEWAY"))) if (!m->getCommand().IsSameAs(wxT("IDRT_GATEWAY"))) {
{ wxLogError(wxT("CIRCDDB::receiveGateway: wrong message type"));
wxLogError(wxT("CIRCDDB::receiveGateway: wrong message type")); return false;
return false; }
}
if (m->getParamCount() != 2) if (m->getParamCount() != 2) {
{ wxLogError(wxT("CIRCDDB::receiveGateway: unexpected number of message parameters"));
wxLogError(wxT("CIRCDDB::receiveGateway: unexpected number of message parameters")); return false;
return false; }
}
gatewayCallsign = m->getParam(0); gatewayCallsign = m->getParam(0);
address = m->getParam(1); address = m->getParam(1);
delete m; delete m;
return true; return true;
} }
// Get a user message, as a result of IDRT_USER returned from getMessageType() // Get a user message, as a result of IDRT_USER returned from getMessageType()
// A false return implies a network error // A false return implies a network error
bool CIRCDDB::receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address) bool CIRCDDB::receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address)
{ {
wxString dummy; wxString dummy;
return receiveUser(userCallsign, repeaterCallsign, gatewayCallsign, address, dummy); return receiveUser(userCallsign, repeaterCallsign, gatewayCallsign, address, dummy);
} }
bool CIRCDDB::receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address, bool CIRCDDB::receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address,
wxString& timeStamp) wxString& timeStamp)
{ {
IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType(); IRCDDB_RESPONSE_TYPE rt = d->app->getReplyMessageType();
if (rt != IDRT_USER) if (rt != IDRT_USER) {
{ wxLogError(wxT("CIRCDDB::receiveUser: unexpected response type"));
wxLogError(wxT("CIRCDDB::receiveUser: unexpected response type")); return false;
return false; }
}
IRCMessage * m = d->app->getReplyMessage();
IRCMessage * m = d->app->getReplyMessage();
if (m == NULL) {
if (m == NULL) wxLogError(wxT("CIRCDDB::receiveUser: no message"));
{ return false;
wxLogError(wxT("CIRCDDB::receiveUser: no message")); }
return false;
} if (!m->getCommand().IsSameAs(wxT("IDRT_USER"))) {
wxLogError(wxT("CIRCDDB::receiveUser: wrong message type"));
if (!m->getCommand().IsSameAs(wxT("IDRT_USER"))) return false;
{ }
wxLogError(wxT("CIRCDDB::receiveUser: wrong message type"));
return false; if (m->getParamCount() != 5) {
} wxLogError(wxT("CIRCDDB::receiveUser: unexpected number of message parameters"));
return false;
if (m->getParamCount() != 5) }
{
wxLogError(wxT("CIRCDDB::receiveUser: unexpected number of message parameters")); userCallsign = m->getParam(0);
return false; repeaterCallsign = m->getParam(1);
} gatewayCallsign = m->getParam(2);
address = m->getParam(3);
userCallsign = m->getParam(0); timeStamp = m->getParam(4);
repeaterCallsign = m->getParam(1);
gatewayCallsign = m->getParam(2); delete m;
address = m->getParam(3);
timeStamp = m->getParam(4); return true;
delete m;
return true;
} }
void CIRCDDB::close() // Implictely kills any threads in the IRC code void CIRCDDB::close() // Implictely kills any threads in the IRC code
{ {
d->client -> stopWork(); d->client -> stopWork();
d->app -> stopWork(); d->app -> stopWork();
} }

@ -41,10 +41,11 @@ enum DSTAR_PROTOCOL {
struct CIRCDDBPrivate; struct CIRCDDBPrivate;
class CIRCDDB { class CIRCDDB
{
public: public:
CIRCDDB(const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password, CIRCDDB(const wxString& hostName, unsigned int port, const wxString& callsign, const wxString& password,
const wxString& versionInfo, const wxString& localAddr = wxEmptyString ); const wxString& versionInfo, const wxString& localAddr = wxEmptyString );
~CIRCDDB(); ~CIRCDDB();
// A false return implies a network error, or unable to log in // A false return implies a network error, or unable to log in
@ -58,7 +59,7 @@ public:
// infoURL URL of a web page with information about the repeater // infoURL URL of a web page with information about the repeater
void rptrQTH( double latitude, double longitude, const wxString& desc1, void rptrQTH( double latitude, double longitude, const wxString& desc1,
const wxString& desc2, const wxString& infoURL ); const wxString& desc2, const wxString& infoURL );
@ -95,9 +96,9 @@ public:
// Send heard data, a false return implies a network error // Send heard data, a false return implies a network error
bool sendHeard(const wxString& myCall, const wxString& myCallExt, bool sendHeard(const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1, const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1, const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3 ); unsigned char flag2, unsigned char flag3 );
// same as sendHeard with two new fields: // same as sendHeard with two new fields:
@ -106,11 +107,11 @@ public:
// tx_message: 20-char TX message or empty string, if the user did not // tx_message: 20-char TX message or empty string, if the user did not
// send a TX message // send a TX message
bool sendHeardWithTXMsg(const wxString& myCall, const wxString& myCallExt, bool sendHeardWithTXMsg(const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1, const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1, const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3, unsigned char flag2, unsigned char flag3,
const wxString& network_destination, const wxString& network_destination,
const wxString& tx_message ); const wxString& tx_message );
// this method should be called at the end of a transmission // this method should be called at the end of a transmission
// num_dv_frames: number of DV frames sent out (96 bit frames, 20ms) // num_dv_frames: number of DV frames sent out (96 bit frames, 20ms)
@ -123,12 +124,12 @@ public:
// BER = num_bit_errors / (num_dv_frames * 24) // BER = num_bit_errors / (num_dv_frames * 24)
// Set num_bit_errors = -1, if the error information is not available. // Set num_bit_errors = -1, if the error information is not available.
bool sendHeardWithTXStats(const wxString& myCall, const wxString& myCallExt, bool sendHeardWithTXStats(const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1, const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1, const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3, unsigned char flag2, unsigned char flag3,
int num_dv_frames, int num_dv_frames,
int num_dv_silent_frames, int num_dv_silent_frames,
int num_bit_errors ); int num_bit_errors );
// The following three functions don't block waiting for a reply, they just send the data // The following three functions don't block waiting for a reply, they just send the data
@ -159,7 +160,7 @@ public:
bool receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address); bool receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address);
bool receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address, bool receiveUser(wxString& userCallsign, wxString& repeaterCallsign, wxString& gatewayCallsign, wxString& address,
wxString& timeStamp ); wxString& timeStamp );
void close(); // Implictely kills any threads in the IRC code void close(); // Implictely kills any threads in the IRC code

File diff suppressed because it is too large Load Diff

@ -32,66 +32,66 @@ class IRCDDBAppPrivate;
class IRCDDBApp : public IRCApplication, wxThread class IRCDDBApp : public IRCApplication, wxThread
{ {
public: public:
IRCDDBApp(const wxString& update_channel); IRCDDBApp(const wxString& update_channel);
virtual ~IRCDDBApp(); virtual ~IRCDDBApp();
virtual void userJoin (const wxString& nick, const wxString& name, const wxString& host); virtual void userJoin (const wxString& nick, const wxString& name, const wxString& host);
virtual void userLeave (const wxString& nick); virtual void userLeave (const wxString& nick);
virtual void userChanOp (const wxString& nick, bool op); virtual void userChanOp (const wxString& nick, bool op);
virtual void userListReset(); virtual void userListReset();
virtual void msgChannel (IRCMessage * m); virtual void msgChannel (IRCMessage * m);
virtual void msgQuery (IRCMessage * m); virtual void msgQuery (IRCMessage * m);
virtual void setCurrentNick(const wxString& nick); virtual void setCurrentNick(const wxString& nick);
virtual void setTopic(const wxString& topic); virtual void setTopic(const wxString& topic);
virtual void setBestServer(const wxString& ircUser); virtual void setBestServer(const wxString& ircUser);
virtual void setSendQ( IRCMessageQueue * s ); virtual void setSendQ( IRCMessageQueue * s );
virtual IRCMessageQueue * getSendQ (); virtual IRCMessageQueue * getSendQ ();
bool startWork(); bool startWork();
void stopWork(); void stopWork();
IRCDDB_RESPONSE_TYPE getReplyMessageType(); IRCDDB_RESPONSE_TYPE getReplyMessageType();
IRCMessage * getReplyMessage(); IRCMessage * getReplyMessage();
bool findUser ( const wxString& s ); bool findUser ( const wxString& s );
bool findRepeater ( const wxString& s ); bool findRepeater ( const wxString& s );
bool findGateway ( const wxString& s ); bool findGateway ( const wxString& s );
bool sendHeard(const wxString& myCall, const wxString& myCallExt, bool sendHeard(const wxString& myCall, const wxString& myCallExt,
const wxString& yourCall, const wxString& rpt1, const wxString& yourCall, const wxString& rpt1,
const wxString& rpt2, unsigned char flag1, const wxString& rpt2, unsigned char flag1,
unsigned char flag2, unsigned char flag3, unsigned char flag2, unsigned char flag3,
const wxString& destination, const wxString& tx_msg, const wxString& destination, const wxString& tx_msg,
const wxString& tx_stats); const wxString& tx_stats);
int getConnectionState(); int getConnectionState();
void rptrQRG( const wxString& module, double txFrequency, double duplexShift, void rptrQRG( const wxString& module, double txFrequency, double duplexShift,
double range, double agl ); double range, double agl );
void rptrQTH( double latitude, double longitude, const wxString& desc1, void rptrQTH( double latitude, double longitude, const wxString& desc1,
const wxString& desc2, const wxString& infoURL ); const wxString& desc2, const wxString& infoURL );
void kickWatchdog( const wxString& wdInfo ); void kickWatchdog( const wxString& wdInfo );
protected: protected:
virtual wxThread::ExitCode Entry(); virtual wxThread::ExitCode Entry();
private: private:
void doUpdate ( wxString& msg ); void doUpdate ( wxString& msg );
void doNotFound ( wxString& msg, wxString& retval ); void doNotFound ( wxString& msg, wxString& retval );
wxString getIPAddress( wxString& zonerp_cs ); wxString getIPAddress( wxString& zonerp_cs );
bool findServerUser(); bool findServerUser();
IRCDDBAppPrivate * d; IRCDDBAppPrivate * d;
}; };

@ -25,24 +25,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
IRCMessage::IRCMessage () IRCMessage::IRCMessage ()
{ {
numParams = 0; numParams = 0;
prefixParsed = false; prefixParsed = false;
} }
IRCMessage::IRCMessage ( const wxString& toNick, const wxString& msg ) IRCMessage::IRCMessage ( const wxString& toNick, const wxString& msg )
{ {
command = wxT("PRIVMSG"); command = wxT("PRIVMSG");
numParams = 2; numParams = 2;
params.Add( toNick ); params.Add( toNick );
params.Add( msg ); params.Add( msg );
prefixParsed = false; prefixParsed = false;
} }
IRCMessage::IRCMessage ( const wxString& cmd ) IRCMessage::IRCMessage ( const wxString& cmd )
{ {
command = cmd; command = cmd;
numParams = 0; numParams = 0;
prefixParsed = false; prefixParsed = false;
} }
IRCMessage::~IRCMessage() IRCMessage::~IRCMessage()
@ -52,126 +52,114 @@ IRCMessage::~IRCMessage()
void IRCMessage::addParam( const wxString& p ) void IRCMessage::addParam( const wxString& p )
{ {
params.Add( p ); params.Add( p );
numParams = params.GetCount(); numParams = params.GetCount();
} }
int IRCMessage::getParamCount() int IRCMessage::getParamCount()
{ {
return params.GetCount(); return params.GetCount();
} }
wxString IRCMessage::getParam( int pos ) wxString IRCMessage::getParam( int pos )
{ {
return params[pos]; return params[pos];
} }
wxString IRCMessage::getCommand() wxString IRCMessage::getCommand()
{ {
return command; return command;
} }
void IRCMessage::parsePrefix() void IRCMessage::parsePrefix()
{ {
unsigned int i; unsigned int i;
for (i=0; i < 3; i++) for (i=0; i < 3; i++) {
{ prefixComponents.Add(wxT(""));
prefixComponents.Add(wxT("")); }
}
int state = 0; int state = 0;
for (i=0; i < prefix.Len(); i++) for (i=0; i < prefix.Len(); i++) {
{ wxChar c = prefix.GetChar(i);
wxChar c = prefix.GetChar(i);
switch (c) switch (c) {
{ case wxT('!'):
case wxT('!'): state = 1; // next is name
state = 1; // next is name break;
break;
case wxT('@'): case wxT('@'):
state = 2; // next is host state = 2; // next is host
break; break;
default: default:
prefixComponents[state].Append(c); prefixComponents[state].Append(c);
break; break;
} }
} }
prefixParsed = true; prefixParsed = true;
} }
wxString& IRCMessage::getPrefixNick() wxString& IRCMessage::getPrefixNick()
{ {
if (!prefixParsed) if (!prefixParsed) {
{ parsePrefix();
parsePrefix(); }
}
return prefixComponents[0]; return prefixComponents[0];
} }
wxString& IRCMessage::getPrefixName() wxString& IRCMessage::getPrefixName()
{ {
if (!prefixParsed) if (!prefixParsed) {
{ parsePrefix();
parsePrefix(); }
}
return prefixComponents[1]; return prefixComponents[1];
} }
wxString& IRCMessage::getPrefixHost() wxString& IRCMessage::getPrefixHost()
{ {
if (!prefixParsed) if (!prefixParsed) {
{ parsePrefix();
parsePrefix(); }
}
return prefixComponents[2]; return prefixComponents[2];
} }
void IRCMessage::composeMessage ( wxString& output ) void IRCMessage::composeMessage ( wxString& output )
{ {
#if defined(DEBUG_IRC) #if defined(DEBUG_IRC)
wxString d = wxT("T [") + prefix + wxT("] [") + command + wxT("]"); wxString d = wxT("T [") + prefix + wxT("] [") + command + wxT("]");
for (int i=0; i < numParams; i++) for (int i=0; i < numParams; i++) {
{ d.Append(wxT(" [") + params[i] + wxT("]") );
d.Append(wxT(" [") + params[i] + wxT("]") ); }
} d.Replace(wxT("%"), wxT("%%"), true);
d.Replace(wxT("%"), wxT("%%"), true); d.Replace(wxT("\\"), wxT("\\\\"), true);
d.Replace(wxT("\\"), wxT("\\\\"), true); wxLogVerbose(d);
wxLogVerbose(d);
#endif #endif
wxString o; wxString o;
if (prefix.Len() > 0) if (prefix.Len() > 0) {
{ o = wxT(":") + prefix + wxT(" ");
o = wxT(":") + prefix + wxT(" "); }
}
o.Append(command); o.Append(command);
for (int i=0; i < numParams; i++) for (int i=0; i < numParams; i++) {
{ if (i == (numParams - 1)) {
if (i == (numParams - 1)) o.Append(wxT(" :") + params[i]);
{ } else {
o.Append(wxT(" :") + params[i]); o.Append(wxT(" ") + params[i]);
} }
else }
{
o.Append(wxT(" ") + params[i]);
}
}
o.Append(wxT("\r\n")); o.Append(wxT("\r\n"));
output = o; output = o;
} }

@ -27,44 +27,44 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class IRCMessage class IRCMessage
{ {
public: public:
IRCMessage(); IRCMessage();
IRCMessage( const wxString& toNick, const wxString& msg ); IRCMessage( const wxString& toNick, const wxString& msg );
IRCMessage( const wxString& command ); IRCMessage( const wxString& command );
~IRCMessage(); ~IRCMessage();
wxString prefix; wxString prefix;
wxString command; wxString command;
wxArrayString params; wxArrayString params;
int numParams; int numParams;
wxString& getPrefixNick(); wxString& getPrefixNick();
wxString& getPrefixName(); wxString& getPrefixName();
wxString& getPrefixHost(); wxString& getPrefixHost();
void composeMessage ( wxString& output ); void composeMessage ( wxString& output );
void addParam( const wxString& p ); void addParam( const wxString& p );
wxString getCommand(); wxString getCommand();
wxString getParam( int pos ); wxString getParam( int pos );
int getParamCount(); int getParamCount();
private: private:
void parsePrefix(); void parsePrefix();
wxArrayString prefixComponents; wxArrayString prefixComponents;
bool prefixParsed; bool prefixParsed;
}; };

@ -24,112 +24,103 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
IRCMessageQueue::IRCMessageQueue() IRCMessageQueue::IRCMessageQueue()
{ {
eof = false; eof = false;
first = NULL; first = NULL;
last = NULL; last = NULL;
} }
IRCMessageQueue::~IRCMessageQueue() IRCMessageQueue::~IRCMessageQueue()
{ {
while (messageAvailable()) while (messageAvailable()) {
{ IRCMessage * m = getMessage();
IRCMessage * m = getMessage();
delete m; delete m;
} }
} }
bool IRCMessageQueue::isEOF() bool IRCMessageQueue::isEOF()
{ {
return eof; return eof;
} }
void IRCMessageQueue::signalEOF() void IRCMessageQueue::signalEOF()
{ {
eof = true; eof = true;
} }
bool IRCMessageQueue::messageAvailable() bool IRCMessageQueue::messageAvailable()
{ {
wxMutexLocker lock(accessMutex); wxMutexLocker lock(accessMutex);
return (first != NULL); return (first != NULL);
} }
IRCMessage * IRCMessageQueue::peekFirst() IRCMessage * IRCMessageQueue::peekFirst()
{ {
wxMutexLocker lock(accessMutex); wxMutexLocker lock(accessMutex);
IRCMessageQueueItem * k = first; IRCMessageQueueItem * k = first;
if ( k == NULL ) if ( k == NULL ) {
{ return NULL;
return NULL; }
}
return k->msg; return k->msg;
} }
IRCMessage * IRCMessageQueue::getMessage() IRCMessage * IRCMessageQueue::getMessage()
{ {
wxMutexLocker lock(accessMutex); wxMutexLocker lock(accessMutex);
IRCMessageQueueItem * k; IRCMessageQueueItem * k;
if (first == NULL) if (first == NULL) {
{ return NULL;
return NULL; }
}
k = first; k = first;
first = k -> next; first = k -> next;
if (k -> next == NULL) if (k -> next == NULL) {
{ last = NULL;
last = NULL; } else {
} k -> next -> prev = NULL;
else }
{
k -> next -> prev = NULL;
}
IRCMessage * msg = k -> msg; IRCMessage * msg = k -> msg;
delete k; delete k;
return msg; return msg;
} }
void IRCMessageQueue::putMessage( IRCMessage * m ) void IRCMessageQueue::putMessage( IRCMessage * m )
{ {
wxMutexLocker lock(accessMutex); wxMutexLocker lock(accessMutex);
// wxLogVerbose(wxT("IRCMessageQueue::putMessage")); // wxLogVerbose(wxT("IRCMessageQueue::putMessage"));
IRCMessageQueueItem * k = new IRCMessageQueueItem(m); IRCMessageQueueItem * k = new IRCMessageQueueItem(m);
k -> prev = last; k -> prev = last;
k -> next = NULL; k -> next = NULL;
if (last == NULL) if (last == NULL) {
{ first = k;
first = k; } else {
} last -> next = k;
else }
{
last -> next = k;
}
last = k; last = k;
} }

@ -29,50 +29,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class IRCMessageQueueItem class IRCMessageQueueItem
{ {
public: public:
IRCMessageQueueItem( IRCMessage * m ) IRCMessageQueueItem( IRCMessage * m ) {
{ msg = m;
msg = m; }
}
~IRCMessageQueueItem() ~IRCMessageQueueItem() {
{ }
}
IRCMessage * msg; IRCMessage * msg;
IRCMessageQueueItem * prev; IRCMessageQueueItem * prev;
IRCMessageQueueItem * next; IRCMessageQueueItem * next;
}; };
class IRCMessageQueue class IRCMessageQueue
{ {
public: public:
IRCMessageQueue(); IRCMessageQueue();
~IRCMessageQueue(); ~IRCMessageQueue();
bool isEOF(); bool isEOF();
void signalEOF(); void signalEOF();
bool messageAvailable(); bool messageAvailable();
IRCMessage * getMessage(); IRCMessage * getMessage();
IRCMessage * peekFirst(); IRCMessage * peekFirst();
void putMessage ( IRCMessage * m ); void putMessage ( IRCMessage * m );
private: private:
bool eof; bool eof;
IRCMessageQueueItem * first; IRCMessageQueueItem * first;
IRCMessageQueueItem * last; IRCMessageQueueItem * last;
wxMutex accessMutex; wxMutex accessMutex;
}; };

@ -27,51 +27,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define CIRCDDB_VERSION "1.2.4" #define CIRCDDB_VERSION "1.2.4"
IRCProtocol::IRCProtocol ( IRCApplication * app, IRCProtocol::IRCProtocol ( IRCApplication * app,
const wxString& callsign, const wxString& password, const wxString& channel, const wxString& callsign, const wxString& password, const wxString& channel,
const wxString& versionInfo ) const wxString& versionInfo )
{ {
this -> password = password; this -> password = password;
this -> channel = channel; this -> channel = channel;
this -> app = app; this -> app = app;
this->versionInfo = wxT("CIRCDDB:"); this->versionInfo = wxT("CIRCDDB:");
this->versionInfo.Append(wxT(CIRCDDB_VERSION)); this->versionInfo.Append(wxT(CIRCDDB_VERSION));
if (versionInfo.Len() > 0) if (versionInfo.Len() > 0) {
{ this->versionInfo.Append(wxT(" "));
this->versionInfo.Append(wxT(" ")); this->versionInfo.Append(versionInfo);
this->versionInfo.Append(versionInfo); }
}
int hyphenPos = callsign.find(wxT('-')); int hyphenPos = callsign.find(wxT('-'));
if (hyphenPos == wxNOT_FOUND) if (hyphenPos == wxNOT_FOUND) {
{ wxString n;
wxString n;
n = callsign + wxT("-1"); n = callsign + wxT("-1");
nicks.Add(n); nicks.Add(n);
n = callsign + wxT("-2"); n = callsign + wxT("-2");
nicks.Add(n); nicks.Add(n);
n = callsign + wxT("-3"); n = callsign + wxT("-3");
nicks.Add(n); nicks.Add(n);
n = callsign + wxT("-4"); n = callsign + wxT("-4");
nicks.Add(n); nicks.Add(n);
} } else {
else nicks.Add(callsign);
{ }
nicks.Add(callsign);
}
name = callsign; name = callsign;
pingTimer = 60; // 30 seconds pingTimer = 60; // 30 seconds
state = 0; state = 0;
timer = 0; timer = 0;
chooseNewNick(); chooseNewNick();
} }
IRCProtocol::~IRCProtocol() IRCProtocol::~IRCProtocol()
@ -80,368 +76,292 @@ IRCProtocol::~IRCProtocol()
void IRCProtocol::chooseNewNick() void IRCProtocol::chooseNewNick()
{ {
int r = rand() % nicks.GetCount(); int r = rand() % nicks.GetCount();
currentNick = nicks[r]; currentNick = nicks[r];
} }
void IRCProtocol::setNetworkReady( bool b ) void IRCProtocol::setNetworkReady( bool b )
{ {
if (b == true) if (b == true) {
{ if (state != 0) {
if (state != 0) wxLogError(wxT("IRCProtocol::setNetworkReady: unexpected state"));
{ }
wxLogError(wxT("IRCProtocol::setNetworkReady: unexpected state"));
} state = 1;
chooseNewNick();
state = 1; } else {
chooseNewNick(); state = 0;
} }
else
{
state = 0;
}
} }
bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sendQ ) bool IRCProtocol::processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sendQ )
{ {
if (timer > 0) if (timer > 0) {
{ timer --;
timer --; }
}
while (recvQ->messageAvailable()) while (recvQ->messageAvailable()) {
{ IRCMessage * m = recvQ -> getMessage();
IRCMessage * m = recvQ -> getMessage();
#if defined(DEBUG_IRC) #if defined(DEBUG_IRC)
wxString d = wxT("R [") + m->prefix + wxT("] [") + m->command + wxT("]"); wxString d = wxT("R [") + m->prefix + wxT("] [") + m->command + wxT("]");
for (int i=0; i < m->numParams; i++) for (int i=0; i < m->numParams; i++) {
{ d.Append(wxT(" [") + m->params[i] + wxT("]") );
d.Append(wxT(" [") + m->params[i] + wxT("]") ); }
} d.Replace(wxT("%"), wxT("%%"), true);
d.Replace(wxT("%"), wxT("%%"), true); d.Replace(wxT("\\"), wxT("\\\\"), true);
d.Replace(wxT("\\"), wxT("\\\\"), true); wxLogVerbose(d);
wxLogVerbose(d);
#endif #endif
if (m->command.IsSameAs(wxT("004"))) if (m->command.IsSameAs(wxT("004"))) {
{ if (state == 4) {
if (state == 4) if (m->params.GetCount() > 1) {
{ wxRegEx serverNamePattern(wxT("^grp[1-9]s[1-9].ircDDB$"));
if (m->params.GetCount() > 1)
{ if (serverNamePattern.Matches( m->params[1] )) {
wxRegEx serverNamePattern(wxT("^grp[1-9]s[1-9].ircDDB$")); app->setBestServer(wxT("s-") + m->params[1].Mid(0,6));
}
if (serverNamePattern.Matches( m->params[1] )) }
{ state = 5; // next: JOIN
app->setBestServer(wxT("s-") + m->params[1].Mid(0,6)); app->setCurrentNick(currentNick);
} }
} } else if (m->command.IsSameAs(wxT("PING"))) {
state = 5; // next: JOIN IRCMessage * m2 = new IRCMessage();
app->setCurrentNick(currentNick); m2->command = wxT("PONG");
} if (m->params.GetCount() > 0) {
} m2->numParams = 1;
else if (m->command.IsSameAs(wxT("PING"))) m2->params.Add( m->params[0] );
{ }
IRCMessage * m2 = new IRCMessage(); sendQ -> putMessage(m2);
m2->command = wxT("PONG"); } else if (m->command.IsSameAs(wxT("JOIN"))) {
if (m->params.GetCount() > 0) if ((m->numParams >= 1) && m->params[0].IsSameAs(channel)) {
{ if (m->getPrefixNick().IsSameAs(currentNick) && (state == 6)) {
m2->numParams = 1; if (debugChannel.Len() > 0) {
m2->params.Add( m->params[0] ); state = 7; // next: join debug_channel
} } else {
sendQ -> putMessage(m2); state = 10; // next: WHO *
} }
else if (m->command.IsSameAs(wxT("JOIN"))) } else if (app != NULL) {
{ app->userJoin( m->getPrefixNick(), m->getPrefixName(), m->getPrefixHost());
if ((m->numParams >= 1) && m->params[0].IsSameAs(channel)) }
{ }
if (m->getPrefixNick().IsSameAs(currentNick) && (state == 6))
{ if ((m->numParams >= 1) && m->params[0].IsSameAs(debugChannel)) {
if (debugChannel.Len() > 0) if (m->getPrefixNick().IsSameAs(currentNick) && (state == 8)) {
{ state = 10; // next: WHO *
state = 7; // next: join debug_channel }
} }
else } else if (m->command.IsSameAs(wxT("PONG"))) {
{ if (state == 12) {
state = 10; // next: WHO * timer = pingTimer;
} state = 11;
} }
else if (app != NULL) } else if (m->command.IsSameAs(wxT("PART"))) {
{ if ((m->numParams >= 1) && m->params[0].IsSameAs(channel)) {
app->userJoin( m->getPrefixNick(), m->getPrefixName(), m->getPrefixHost()); 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)) {
// i was kicked!!
delete m;
return false;
} else if (app != NULL) {
app->userLeave( m->params[1] );
}
}
} else if (m->command.IsSameAs(wxT("QUIT"))) {
if (app != NULL) {
app->userLeave( m->getPrefixNick() );
}
} else if (m->command.IsSameAs(wxT("MODE"))) {
if ((m->numParams >= 3) && m->params[0].IsSameAs(channel)) {
if (app != NULL) {
size_t i;
wxString 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('+') ) {
app->userChanOp(m->params[i+1], true);
} else if ( mode[0] == wxT('-') ) {
app->userChanOp(m->params[i+1], false);
}
}
} // for
}
}
} else if (m->command.IsSameAs(wxT("PRIVMSG"))) {
if ((m->numParams == 2) && (app != NULL)) {
if (m->params[0].IsSameAs(channel)) {
app->msgChannel(m);
} else if (m->params[0].IsSameAs(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)) {
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@")));
}
}
} else if (m->command.IsSameAs(wxT("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) ) {
app->setTopic(m->params[1]);
}
}
if ((m->numParams >= 1) && m->params[0].IsSameAs(debugChannel))
{
if (m->getPrefixNick().IsSameAs(currentNick) && (state == 8))
{
state = 10; // next: WHO *
}
}
}
else if (m->command.IsSameAs(wxT("PONG")))
{
if (state == 12)
{
timer = pingTimer;
state = 11;
}
}
else if (m->command.IsSameAs(wxT("PART")))
{
if ((m->numParams >= 1) && m->params[0].IsSameAs(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))
{
// i was kicked!!
delete m; delete m;
return false;
}
else if (app != NULL)
{
app->userLeave( m->params[1] );
}
}
}
else if (m->command.IsSameAs(wxT("QUIT")))
{
if (app != NULL)
{
app->userLeave( m->getPrefixNick() );
}
}
else if (m->command.IsSameAs(wxT("MODE")))
{
if ((m->numParams >= 3) && m->params[0].IsSameAs(channel))
{
if (app != NULL)
{
size_t i;
wxString 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('+') )
{
app->userChanOp(m->params[i+1], true);
}
else if ( mode[0] == wxT('-') )
{
app->userChanOp(m->params[i+1], false);
}
}
} // for
}
}
}
else if (m->command.IsSameAs(wxT("PRIVMSG")))
{
if ((m->numParams == 2) && (app != NULL))
{
if (m->params[0].IsSameAs(channel))
{
app->msgChannel(m);
} }
else if (m->params[0].IsSameAs(currentNick))
{ IRCMessage * m;
app->msgQuery(m);
} switch (state) {
} case 1:
} m = new IRCMessage();
else if (m->command.IsSameAs(wxT("352"))) // WHO list m->command = wxT("PASS");
{ m->numParams = 1;
if ((m->numParams >= 7) && m->params[0].IsSameAs(currentNick) m->params.Add(password);
&& m->params[1].IsSameAs(channel)) sendQ->putMessage(m);
{
if (app != NULL) m = new IRCMessage();
{ m->command = wxT("NICK");
app->userJoin( m->params[5], m->params[2], m->params[3]); m->numParams = 1;
app->userChanOp ( m->params[5], m->params[6].IsSameAs(wxT("H@"))); m->params.Add(currentNick);
sendQ->putMessage(m);
timer = 10; // wait for possible nick collision message
state = 2;
break;
case 2:
if (timer == 0) {
m = new IRCMessage();
m->command = wxT("USER");
m->numParams = 4;
m->params.Add(name);
m->params.Add(wxT("0"));
m->params.Add(wxT("*"));
m->params.Add(versionInfo);
sendQ->putMessage(m);
timer = 30;
state = 4; // wait for login message
}
break;
case 3:
if (timer == 0) {
chooseNewNick();
m = new IRCMessage();
m->command = wxT("NICK");
m->numParams = 1;
m->params.Add(currentNick);
sendQ->putMessage(m);
timer = 10; // wait for possible nick collision message
state = 2;
}
break;
case 4:
if (timer == 0) {
// no login message received -> disconnect
return false;
}
break;
case 5:
m = new IRCMessage();
m->command = wxT("JOIN");
m->numParams = 1;
m->params.Add(channel);
sendQ->putMessage(m);
timer = 30;
state = 6; // wait for join message
break;
case 6:
if (timer == 0) {
// no join message received -> disconnect
return false;
}
break;
case 7:
if (debugChannel.Len() == 0) {
return false; // this state cannot be processed if there is no debug_channel
}
m = new IRCMessage();
m->command = wxT("JOIN");
m->numParams = 1;
m->params.Add(debugChannel);
sendQ->putMessage(m);
timer = 30;
state = 8; // wait for join message
break;
case 8:
if (timer == 0) {
// no join message received -> disconnect
return false;
}
break;
case 10:
m = new IRCMessage();
m->command = wxT("WHO");
m->numParams = 2;
m->params.Add(channel);
m->params.Add(wxT("*"));
sendQ->putMessage(m);
timer = pingTimer;
state = 11; // wait for timer and then send ping
if (app != NULL) {
app->setSendQ(sendQ); // this switches the application on
}
break;
case 11:
if (timer == 0) {
m = new IRCMessage();
m->command = wxT("PING");
m->numParams = 1;
m->params.Add(currentNick);
sendQ->putMessage(m);
timer = pingTimer;
state = 12; // wait for pong
}
break;
case 12:
if (timer == 0) {
// no pong message received -> disconnect
return false;
}
break;
} }
}
} return true;
else if (m->command.IsSameAs(wxT("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) )
{
app->setTopic(m->params[1]);
}
}
delete m;
}
IRCMessage * m;
switch (state)
{
case 1:
m = new IRCMessage();
m->command = wxT("PASS");
m->numParams = 1;
m->params.Add(password);
sendQ->putMessage(m);
m = new IRCMessage();
m->command = wxT("NICK");
m->numParams = 1;
m->params.Add(currentNick);
sendQ->putMessage(m);
timer = 10; // wait for possible nick collision message
state = 2;
break;
case 2:
if (timer == 0)
{
m = new IRCMessage();
m->command = wxT("USER");
m->numParams = 4;
m->params.Add(name);
m->params.Add(wxT("0"));
m->params.Add(wxT("*"));
m->params.Add(versionInfo);
sendQ->putMessage(m);
timer = 30;
state = 4; // wait for login message
}
break;
case 3:
if (timer == 0)
{
chooseNewNick();
m = new IRCMessage();
m->command = wxT("NICK");
m->numParams = 1;
m->params.Add(currentNick);
sendQ->putMessage(m);
timer = 10; // wait for possible nick collision message
state = 2;
}
break;
case 4:
if (timer == 0)
{
// no login message received -> disconnect
return false;
}
break;
case 5:
m = new IRCMessage();
m->command = wxT("JOIN");
m->numParams = 1;
m->params.Add(channel);
sendQ->putMessage(m);
timer = 30;
state = 6; // wait for join message
break;
case 6:
if (timer == 0)
{
// no join message received -> disconnect
return false;
}
break;
case 7:
if (debugChannel.Len() == 0)
{
return false; // this state cannot be processed if there is no debug_channel
}
m = new IRCMessage();
m->command = wxT("JOIN");
m->numParams = 1;
m->params.Add(debugChannel);
sendQ->putMessage(m);
timer = 30;
state = 8; // wait for join message
break;
case 8:
if (timer == 0)
{
// no join message received -> disconnect
return false;
}
break;
case 10:
m = new IRCMessage();
m->command = wxT("WHO");
m->numParams = 2;
m->params.Add(channel);
m->params.Add(wxT("*"));
sendQ->putMessage(m);
timer = pingTimer;
state = 11; // wait for timer and then send ping
if (app != NULL)
{
app->setSendQ(sendQ); // this switches the application on
}
break;
case 11:
if (timer == 0)
{
m = new IRCMessage();
m->command = wxT("PING");
m->numParams = 1;
m->params.Add(currentNick);
sendQ->putMessage(m);
timer = pingTimer;
state = 12; // wait for pong
}
break;
case 12:
if (timer == 0)
{
// no pong message received -> disconnect
return false;
}
break;
}
return true;
} }

@ -30,34 +30,34 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class IRCProtocol class IRCProtocol
{ {
public: public:
IRCProtocol ( IRCApplication * app, IRCProtocol ( IRCApplication * app,
const wxString& callsign, const wxString& password, const wxString& channel, const wxString& callsign, const wxString& password, const wxString& channel,
const wxString& versionInfo ); const wxString& versionInfo );
~IRCProtocol(); ~IRCProtocol();
void setNetworkReady( bool state ); void setNetworkReady( bool state );
bool processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sendQ ); bool processQueues ( IRCMessageQueue * recvQ, IRCMessageQueue * sendQ );
private: private:
void chooseNewNick(); void chooseNewNick();
wxArrayString nicks; wxArrayString nicks;
wxString password; wxString password;
wxString channel; wxString channel;
wxString name; wxString name;
wxString currentNick; wxString currentNick;
wxString versionInfo; wxString versionInfo;
int state; int state;
int timer; int timer;
int pingTimer; int pingTimer;
wxString debugChannel; wxString debugChannel;
IRCApplication * app; IRCApplication * app;
}; };

@ -40,11 +40,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <wx/wx.h> #include <wx/wx.h>
IRCReceiver::IRCReceiver(int sock, IRCMessageQueue * q ) IRCReceiver::IRCReceiver(int sock, IRCMessageQueue * q )
: wxThread(wxTHREAD_JOINABLE) : wxThread(wxTHREAD_JOINABLE)
{ {
this->sock = sock; this->sock = sock;
recvQ = q; recvQ = q;
} }
IRCReceiver::~IRCReceiver() IRCReceiver::~IRCReceiver()
@ -54,196 +54,158 @@ IRCReceiver::~IRCReceiver()
bool IRCReceiver::startWork() bool IRCReceiver::startWork()
{ {
if (Create() != wxTHREAD_NO_ERROR) if (Create() != wxTHREAD_NO_ERROR) {
{ wxLogError(wxT("IRCReceiver::startWork: Could not create the worker thread!"));
wxLogError(wxT("IRCReceiver::startWork: Could not create the worker thread!")); return false;
return false; }
}
terminateThread = false; terminateThread = false;
if (Run() != wxTHREAD_NO_ERROR) if (Run() != wxTHREAD_NO_ERROR) {
{ wxLogError(wxT("IRCReceiver::startWork: Could not run the worker thread!"));
wxLogError(wxT("IRCReceiver::startWork: Could not run the worker thread!")); return false;
return false; }
}
return true; return true;
} }
void IRCReceiver::stopWork() void IRCReceiver::stopWork()
{ {
terminateThread = true; terminateThread = true;
Wait(); Wait();
} }
static int doRead( int sock, char * buf, int buf_size ) static int doRead( int sock, char * buf, int buf_size )
{ {
struct timeval tv; struct timeval tv;
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
fd_set rdset; fd_set rdset;
fd_set errset; fd_set errset;
FD_ZERO(&rdset); FD_ZERO(&rdset);
FD_ZERO(&errset); FD_ZERO(&errset);
FD_SET(sock, &rdset); FD_SET(sock, &rdset);
FD_SET(sock, &errset); FD_SET(sock, &errset);
int res; int res;
res = select(sock+1, &rdset, NULL, &errset, &tv); res = select(sock+1, &rdset, NULL, &errset, &tv);
if ( res < 0 ) if ( res < 0 ) {
{ wxLogSysError(wxT("IRCReceiver::doRead: select"));
wxLogSysError(wxT("IRCReceiver::doRead: select")); return -1;
return -1; } else if ( res > 0 ) {
} if (FD_ISSET(sock, &errset)) {
else if ( res > 0 ) wxLogVerbose(wxT("IRCReceiver::doRead: select (FD_ISSET(sock, exceptfds))"));
{ return -1;
if (FD_ISSET(sock, &errset)) }
{
wxLogVerbose(wxT("IRCReceiver::doRead: select (FD_ISSET(sock, exceptfds))")); if (FD_ISSET(sock, &rdset)) {
return -1; res = recv(sock, buf, buf_size, 0);
}
if (res < 0) {
if (FD_ISSET(sock, &rdset)) wxLogSysError(wxT("IRCReceiver::doRead: read"));
{ return -1;
res = recv(sock, buf, buf_size, 0); } else if (res == 0) {
wxLogVerbose(wxT("IRCReceiver::doRead: EOF read==0"));
if (res < 0) return -1;
{ } else {
wxLogSysError(wxT("IRCReceiver::doRead: read")); return res;
return -1; }
} }
else if (res == 0)
{ }
wxLogVerbose(wxT("IRCReceiver::doRead: EOF read==0"));
return -1; return 0;
}
else
{
return res;
}
}
}
return 0;
} }
wxThread::ExitCode IRCReceiver::Entry () wxThread::ExitCode IRCReceiver::Entry ()
{ {
IRCMessage * m = new IRCMessage(); IRCMessage * m = new IRCMessage();
int i; int i;
int state = 0; int state = 0;
while (!terminateThread) while (!terminateThread) {
{
// wxLogVerbose(wxT("IRCReceiver: tick"));
// wxLogVerbose(wxT("IRCReceiver: tick"));
char buf[200];
char buf[200]; int r = doRead( sock, buf, sizeof buf );
int r = doRead( sock, buf, sizeof buf );
if (r < 0) {
if (r < 0) recvQ -> signalEOF();
{ delete m; // delete unfinished IRCMessage
recvQ -> signalEOF(); break;
delete m; // delete unfinished IRCMessage }
break;
} for (i=0; i < r; i++) {
char b = buf[i];
for (i=0; i < r; i++)
{ if (b > 0) {
char b = buf[i]; if (b == 10) {
recvQ -> putMessage(m);
if (b > 0) m = new IRCMessage();
{ state = 0;
if (b == 10) } else if (b == 13) {
{ // do nothing
recvQ -> putMessage(m); } else switch (state) {
m = new IRCMessage(); case 0:
state = 0; if (b == ':') {
} state = 1; // prefix
else if (b == 13) } else if (b == 32) {
{ // do nothing
// do nothing } else {
} m -> command.Append(wxChar(b));
else switch (state) state = 2; // command
{ }
case 0: break;
if (b == ':')
{ case 1:
state = 1; // prefix if (b == 32) {
} state = 2; // command is next
else if (b == 32) } else {
{ m -> prefix.Append(wxChar(b));
// do nothing }
} break;
else
{ case 2:
m -> command.Append(wxChar(b)); if (b == 32) {
state = 2; // command state = 3; // params
} m -> numParams = 1;
break; m -> params.Add(wxT(""));
} else {
case 1: m -> command.Append(wxChar(b));
if (b == 32) }
{ break;
state = 2; // command is next
} case 3:
else if (b == 32) {
{ m -> numParams ++;
m -> prefix.Append(wxChar(b)); if (m -> numParams >= 15) {
} state = 5; // ignore the rest
break; }
case 2: m -> params.Add(wxT(""));
if (b == 32) } else if ((b == ':') && (m -> params[ m -> numParams-1 ].Len() == 0)) {
{ state = 4; // rest of line is this param
state = 3; // params } else {
m -> numParams = 1; m -> params[ m -> numParams-1 ].Append(wxChar(b));
m -> params.Add(wxT("")); }
} break;
else
{ case 4:
m -> command.Append(wxChar(b)); m -> params[ m -> numParams-1 ].Append(wxChar(b));
} break;
break;
case 3: } // switch
if (b == 32) } // if
{ } // for
m -> numParams ++; } // while
if (m -> numParams >= 15)
{ return 0;
state = 5; // ignore the rest
}
m -> params.Add(wxT(""));
}
else if ((b == ':') && (m -> params[ m -> numParams-1 ].Len() == 0))
{
state = 4; // rest of line is this param
}
else
{
m -> params[ m -> numParams-1 ].Append(wxChar(b));
}
break;
case 4:
m -> params[ m -> numParams-1 ].Append(wxChar(b));
break;
} // switch
} // if
} // for
} // while
return 0;
} }

@ -31,30 +31,30 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
class IRCReceiver : public wxThread class IRCReceiver : public wxThread
{ {
public: public:
IRCReceiver(int sock, IRCMessageQueue * q); IRCReceiver(int sock, IRCMessageQueue * q);
~IRCReceiver(); ~IRCReceiver();
bool startWork(); bool startWork();
void stopWork(); void stopWork();
protected: protected:
virtual wxThread::ExitCode Entry(); virtual wxThread::ExitCode Entry();
private: private:
bool terminateThread; bool terminateThread;
int sock; int sock;
IRCMessageQueue * recvQ; IRCMessageQueue * recvQ;
}; };

@ -43,99 +43,85 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
int getAllIPV4Addresses ( const char * name, unsigned short port, int getAllIPV4Addresses ( const char * name, unsigned short port,
unsigned int * num, struct sockaddr_in * addr, unsigned int max_addr ) unsigned int * num, struct sockaddr_in * addr, unsigned int max_addr )
{ {
struct addrinfo hints; struct addrinfo hints;
struct addrinfo * res; struct addrinfo * res;
memset(&hints, 0x00, sizeof(struct addrinfo)); memset(&hints, 0x00, sizeof(struct addrinfo));
hints.ai_family = AF_INET; hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
int r = getaddrinfo( name, NULL, &hints, &res ); int r = getaddrinfo( name, NULL, &hints, &res );
if (r == 0) if (r == 0) {
{ struct addrinfo * rp;
struct addrinfo * rp; unsigned int numAddr = 0;
unsigned int numAddr = 0;
for (rp = res; rp != NULL; rp = rp->ai_next) for (rp = res; rp != NULL; rp = rp->ai_next) {
{ if (rp->ai_family == AF_INET) {
if (rp->ai_family == AF_INET) numAddr ++;
{ }
numAddr ++; }
}
}
if (numAddr > 0) if (numAddr > 0) {
{ if (numAddr > max_addr) {
if (numAddr > max_addr) numAddr = max_addr;
{ }
numAddr = max_addr;
}
int * shuffle = new int[numAddr]; int * shuffle = new int[numAddr];
unsigned int i; unsigned int i;
for (i=0; i < numAddr; i++) for (i=0; i < numAddr; i++) {
{ shuffle[i] = i;
shuffle[i] = i; }
}
for (i=0; i < (numAddr - 1); i++) for (i=0; i < (numAddr - 1); i++) {
{ if (rand() & 1) {
if (rand() & 1) int tmp;
{ tmp = shuffle[i];
int tmp; shuffle[i] = shuffle[i+1];
tmp = shuffle[i]; shuffle[i+1] = tmp;
shuffle[i] = shuffle[i+1]; }
shuffle[i+1] = tmp; }
}
}
for (i=(numAddr - 1); i > 0; i--) for (i=(numAddr - 1); i > 0; i--) {
{ if (rand() & 1) {
if (rand() & 1) int tmp;
{ tmp = shuffle[i];
int tmp; shuffle[i] = shuffle[i-1];
tmp = shuffle[i]; shuffle[i-1] = tmp;
shuffle[i] = shuffle[i-1]; }
shuffle[i-1] = tmp; }
}
}
for (rp = res, i=0 ; (rp != NULL) && (i < numAddr); rp = rp->ai_next) for (rp = res, i=0 ; (rp != NULL) && (i < numAddr); rp = rp->ai_next) {
{ if (rp->ai_family == AF_INET) {
if (rp->ai_family == AF_INET) memcpy( addr+shuffle[i], rp->ai_addr, sizeof (struct sockaddr_in) );
{
memcpy( addr+shuffle[i], rp->ai_addr, sizeof (struct sockaddr_in) );
addr[shuffle[i]].sin_port = htons(port); addr[shuffle[i]].sin_port = htons(port);
i++; i++;
} }
} }
delete[] shuffle; delete[] shuffle;
} }
*num = numAddr; *num = numAddr;
freeaddrinfo(res); freeaddrinfo(res);
return 0; return 0;
} } else {
else wxString e( gai_strerror(r), wxConvUTF8);
{
wxString e( gai_strerror(r), wxConvUTF8);
wxLogWarning(wxT("getaddrinfo: ") + e ); wxLogWarning(wxT("getaddrinfo: ") + e );
return 1; return 1;
} }
} }
@ -146,35 +132,34 @@ int getAllIPV4Addresses ( const char * name, unsigned short port,
void safeStringCopy (char * dest, const char * src, unsigned int buf_size) void safeStringCopy (char * dest, const char * src, unsigned int buf_size)
{ {
unsigned int i = 0; unsigned int i = 0;
while (i < (buf_size - 1) && (src[i] != 0)) while (i < (buf_size - 1) && (src[i] != 0)) {
{ dest[i] = src[i];
dest[i] = src[i]; i++;
i++; }
}
dest[i] = 0; dest[i] = 0;
} }
wxString getCurrentTime(void) wxString getCurrentTime(void)
{ {
time_t now = time(NULL); time_t now = time(NULL);
struct tm* tm; struct tm* tm;
struct tm tm_buf; struct tm tm_buf;
char buffer[25]; char buffer[25];
#if defined(__WINDOWS__) #if defined(__WINDOWS__)
gmtime_s(&tm_buf, &now); gmtime_s(&tm_buf, &now);
tm = &tm_buf; tm = &tm_buf;
#else #else
gmtime_r(&now, &tm_buf); gmtime_r(&now, &tm_buf);
tm = &tm_buf; tm = &tm_buf;
#endif #endif
strftime(buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", tm); strftime(buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", tm);
return wxString(buffer, wxConvLocal); return wxString(buffer, wxConvLocal);
} }

@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
int getAllIPV4Addresses ( const char * name, unsigned short port, int getAllIPV4Addresses ( const char * name, unsigned short port,
unsigned int * num, struct sockaddr_in * addr, unsigned int max_addr ); unsigned int * num, struct sockaddr_in * addr, unsigned int max_addr );
void safeStringCopy (char * dest, const char * src, unsigned int buf_size); void safeStringCopy (char * dest, const char * src, unsigned int buf_size);

@ -22,72 +22,70 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "dstar_dv.h" #include "dstar_dv.h"
#include "golay23.h" #include "golay23.h"
int bit_pos1[] = int bit_pos1[] = {
{ 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2,
0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2
0, 0, 1, 1, 2, 2
}; };
int bit_pos2[] = int bit_pos2[] = {
{ 23, 11,
23, 11, 23, 11,
23, 11, 23, 11,
23, 11,
22, 10, 22, 10,
22, 10, 22, 10,
22, 10, 22, 10,
21, 9, 21, 9,
21, 9, 21, 9,
21, 9, 21, 9,
20, 8, 20, 8,
20, 8, 20, 8,
20, 8, 20, 8,
19, 7, 19, 7,
19, 7, 19, 7,
19, 7, 19, 7,
18, 6, 18, 6,
18, 6, 18, 6,
18, 6, 18, 6,
17, 5, 17, 5,
17, 5, 17, 5,
17, 5, 17, 5,
16, 4, 16, 4,
16, 4, 16, 4,
16, 4, 16, 4,
15, 3, 15, 3,
15, 3, 15, 3,
15, 3, 15, 3,
14, 2, 14, 2,
14, 2, 14, 2,
14, 2, 14, 2,
13, 1, 13, 1,
13, 1, 13, 1,
13, 1, 13, 1,
12, 0, 12, 0,
12, 0, 12, 0,
12, 0 12, 0
}; };
@ -98,156 +96,142 @@ static int prng[4096];
static void init_prng(void) static void init_prng(void)
{ {
int i; int i;
for (i=0; i < 4096; i++) for (i=0; i < 4096; i++) {
{ int mask = 0x800000;
int mask = 0x800000; int j;
int j; int pr;
int pr;
prng[i] = 0; prng[i] = 0;
pr = i << 4; pr = i << 4;
for (j=0; j < 24; j++) for (j=0; j < 24; j++) {
{ pr = ((173 * pr) + 13849) & 0xFFFF;
pr = ((173 * pr) + 13849) & 0xFFFF;
if ((pr & 0x8000) != 0) if ((pr & 0x8000) != 0) {
{ prng[i] |= mask;
prng[i] |= mask; }
}
mask = mask >> 1; mask = mask >> 1;
} }
} }
} }
void dstar_dv_init(void) void dstar_dv_init(void)
{ {
long temp; long temp;
int i; int i;
int a[4]; int a[4];
decoding_table[0] = 0; decoding_table[0] = 0;
decoding_table[1] = 1; decoding_table[1] = 1;
temp = 1; temp = 1;
for (i=2; i<= 23; i++) for (i=2; i<= 23; i++) {
{ temp = temp << 1;
temp = temp << 1; decoding_table[get_syndrome(temp)] = temp;
decoding_table[get_syndrome(temp)] = temp; }
}
a[1] = 1;
a[1] = 1; a[2] = 2;
a[2] = 2; temp = arr2int(a,2);
temp = arr2int(a,2); decoding_table[get_syndrome(temp)] = temp;
decoding_table[get_syndrome(temp)] = temp; for (i=1; i<253; i++) {
for (i=1; i<253; i++) nextcomb(23,2,a);
{ temp = arr2int(a,2);
nextcomb(23,2,a); decoding_table[get_syndrome(temp)] = temp;
temp = arr2int(a,2); }
decoding_table[get_syndrome(temp)] = temp;
} a[1] = 1;
a[2] = 2;
a[1] = 1; a[3] = 3;
a[2] = 2; temp = arr2int(a,3);
a[3] = 3; decoding_table[get_syndrome(temp)] = temp;
temp = arr2int(a,3); for (i=1; i<1771; i++) {
decoding_table[get_syndrome(temp)] = temp; nextcomb(23,3,a);
for (i=1; i<1771; i++) temp = arr2int(a,3);
{ decoding_table[get_syndrome(temp)] = temp;
nextcomb(23,3,a); }
temp = arr2int(a,3);
decoding_table[get_syndrome(temp)] = temp; init_prng();
}
init_prng();
} }
static int golay2412 (int data, int *decoded) static int golay2412 (int data, int *decoded)
{ {
int block = (data >> 1) & 0x07fffff; int block = (data >> 1) & 0x07fffff;
int corrected_block = block ^ decoding_table[get_syndrome(block)]; int corrected_block = block ^ decoding_table[get_syndrome(block)];
int errs = 0; int errs = 0;
int parity_corr = 0; int parity_corr = 0;
int i; int i;
for (i = 0; i < 23; i++) for (i = 0; i < 23; i++) {
{ int mask = 1 << i;
int mask = 1 << i;
int bit_rcvd = block & mask; int bit_rcvd = block & mask;
int bit_corr = corrected_block & mask; int bit_corr = corrected_block & mask;
if (bit_corr != 0) if (bit_corr != 0) {
{ parity_corr ++;
parity_corr ++; }
}
if (bit_rcvd != bit_corr) if (bit_rcvd != bit_corr) {
{ errs ++;
errs ++; }
} }
}
if ((parity_corr & 0x01) != (data & 0x01)) if ((parity_corr & 0x01) != (data & 0x01)) {
{ errs ++;
errs ++; }
}
*decoded = corrected_block >> 11; *decoded = corrected_block >> 11;
return errs; return errs;
} }
int dstar_dv_decode_first_block (const unsigned char * d, int * errs) int dstar_dv_decode_first_block (const unsigned char * d, int * errs)
{ {
int bits[3]; int bits[3];
int i; int i;
int data; int data;
for (i=0; i < 3; i++) for (i=0; i < 3; i++) {
{ bits[i] = 0;
bits[i] = 0; }
}
for (i=0; i < 72; i++) for (i=0; i < 72; i++) {
{ bits[ bit_pos1[i] ] |= (d[ i >> 3 ] & (0x80 >> (i & 0x07))) ? (1 << bit_pos2[i]) : 0;
bits[ bit_pos1[i] ] |= (d[ i >> 3 ] & (0x80 >> (i & 0x07))) ? (1 << bit_pos2[i]) : 0; }
}
*errs = golay2412( bits[0], & data ); *errs = golay2412( bits[0], & data );
return data; return data;
} }
int dstar_dv_decode (const unsigned char * d, int data[3]) int dstar_dv_decode (const unsigned char * d, int data[3])
{ {
int bits[3]; int bits[3];
int i; int i;
int errs; int errs;
for (i=0; i < 3; i++) for (i=0; i < 3; i++) {
{ bits[i] = 0;
bits[i] = 0; }
}
for (i=0; i < 72; i++) for (i=0; i < 72; i++) {
{ bits[ bit_pos1[i] ] |= (d[ i >> 3 ] & (0x80 >> (i & 0x07))) ? (1 << bit_pos2[i]) : 0;
bits[ bit_pos1[i] ] |= (d[ i >> 3 ] & (0x80 >> (i & 0x07))) ? (1 << bit_pos2[i]) : 0; }
}
errs = golay2412( bits[0], data ); errs = golay2412( bits[0], data );
errs += golay2412( bits[1] ^ prng[ data[0] & 0x0fff ], data + 1 ); errs += golay2412( bits[1] ^ prng[ data[0] & 0x0fff ], data + 1 );
data[2] = bits[2]; data[2] = bits[2];
return errs; return errs;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -46,361 +46,338 @@ static void calcPFCS(unsigned char rawbytes[58]);
static time_t tNow = 0; static time_t tNow = 0;
static short streamid_raw = 0; static short streamid_raw = 0;
/*** //static unsigned char silence[12] = { 0x4e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,0x70,0x4f,0x93 };
static char silence[12] = static unsigned char silence[12] = { 0xfa,0x87,0x1e,0x32,0x30,0x2f,0xea,0x45,0x66,0x70,0x4f,0x93 };
{
0x4e,0x8d,0x32,0x88,0x26,0x1a,0x3f,0x61,0xe8,
0x70,0x4f,0x93 static unsigned short crc_tabccitt[256] = {
}; 0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
***/ 0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
static char silence[12] = 0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
{ 0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
0xfa,0x87,0x1e,0x32,0x30,0x2f,0xea,0x45,0x66, 0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
0x70,0x4f,0x93 0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
}; 0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
static unsigned short crc_tabccitt[256] = 0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
{ 0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf, 0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7, 0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e, 0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876, 0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd, 0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5, 0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c, 0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974, 0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb, 0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3, 0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a, 0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72, 0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9, 0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1, 0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738, 0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70, 0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7, 0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff, 0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036, 0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e, 0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
}; };
static void calcPFCS(unsigned char rawbytes[58]) static void calcPFCS(unsigned char rawbytes[58])
{ {
unsigned short crc_dstar_ffff = 0xffff; unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp, short_c; unsigned short tmp, short_c;
short int i; short int i;
for (i = 17; i < 56 ; i++) for (i = 17; i < 56 ; i++) {
{ short_c = 0x00ff & (unsigned short)rawbytes[i];
short_c = 0x00ff & (unsigned short)rawbytes[i]; tmp = (crc_dstar_ffff & 0x00ff) ^ short_c;
tmp = (crc_dstar_ffff & 0x00ff) ^ short_c; crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp];
crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp]; }
} crc_dstar_ffff = ~crc_dstar_ffff;
crc_dstar_ffff = ~crc_dstar_ffff; tmp = crc_dstar_ffff;
tmp = crc_dstar_ffff;
rawbytes[56] = (unsigned char)(crc_dstar_ffff & 0xff);
rawbytes[56] = (unsigned char)(crc_dstar_ffff & 0xff); rawbytes[57] = (unsigned char)((tmp >> 8) & 0xff);
rawbytes[57] = (unsigned char)((tmp >> 8) & 0xff); return;
return;
} }
static bool dst_open(char *ip, int port) static bool dst_open(char *ip, int port)
{ {
int reuse = 1; int reuse = 1;
sockDst = socket(PF_INET,SOCK_DGRAM,0); sockDst = socket(PF_INET,SOCK_DGRAM,0);
if (sockDst == -1) if (sockDst == -1) {
{ printf("Failed to create DSTAR socket\n");
printf("Failed to create DSTAR socket\n"); return false;
return false; }
} if (setsockopt(sockDst,SOL_SOCKET,SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
if (setsockopt(sockDst,SOL_SOCKET,SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) close(sockDst);
{ sockDst = -1;
close(sockDst); sockDst = -1; printf("setsockopt DSTAR REUSE failed\n");
printf("setsockopt DSTAR REUSE failed\n"); return false;
return false; }
} memset(&toDst,0,sizeof(struct sockaddr_in));
memset(&toDst,0,sizeof(struct sockaddr_in)); toDst.sin_family = AF_INET;
toDst.sin_family = AF_INET; toDst.sin_port = htons(port);
toDst.sin_port = htons(port); toDst.sin_addr.s_addr = inet_addr(ip);
toDst.sin_addr.s_addr = inet_addr(ip);
fcntl(sockDst,F_SETFL,O_NONBLOCK);
fcntl(sockDst,F_SETFL,O_NONBLOCK); return true;
return true;
} }
static void dst_close() static void dst_close()
{ {
if (sockDst != -1) if (sockDst != -1) {
{ close(sockDst);
close(sockDst); sockDst = -1;
sockDst = -1; }
} return;
return;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
unsigned char dstar_buf[58]; unsigned char dstar_buf[58];
static unsigned short G2_COUNTER = 0; static unsigned short G2_COUNTER = 0;
unsigned long delay; unsigned long delay;
char RADIO_ID[21]; char RADIO_ID[21];
short int i; short int i;
if (argc != 10) if (argc != 10) {
{ printf("Usage: g2link_test <IPaddress> <port> <textMessage> <repeaterCallsign> <module> <delay_between> <delay_before> <MYCALL> <YRCALL>\n");
printf("Usage: g2link_test <IPaddress> <port> <textMessage> <repeaterCallsign> <module> <delay_between> <delay_before> <MYCALL> <YRCALL>\n"); printf("Example: g2link_test 127.0.0.1 19000 \"HELLO\" KJ4NHF B 20 2 KI4LKF XRF005AL\n");
printf("Example: g2link_test 127.0.0.1 19000 \"HELLO\" KJ4NHF B 20 2 KI4LKF XRF005AL\n"); printf("Where...\n\n");
printf("Where...\n\n"); printf(" 127.0.0.1 is the G2 INTERNAL IP of the G2 gateway\n");
printf(" 127.0.0.1 is the G2 INTERNAL IP of the G2 gateway\n"); printf(" 19000 is the the G2 INTERNAL port of the G2 gateway\n");
printf(" 19000 is the the G2 INTERNAL port of the G2 gateway\n"); printf(" HELLO is the text message that we will send, no more than 20 characters\n");
printf(" HELLO is the text message that we will send, no more than 20 characters\n"); printf(" Note: the text message will be converted to UPPERCASE\n");
printf(" Note: the text message will be converted to UPPERCASE\n"); printf(" KJ4NHF is your dstar repeater callsign\n");
printf(" KJ4NHF is your dstar repeater callsign\n"); printf(" B is the local repeater module\n");
printf(" B is the local repeater module\n"); printf(" 20 millisecond delay before each packet is sent\n");
printf(" 20 millisecond delay before each packet is sent\n"); printf(" 2 second delay before the program starts processing your input \n");
printf(" 2 second delay before the program starts processing your input \n"); printf(" KI4LKF is the value of mycall\n");
printf(" KI4LKF is the value of mycall\n"); printf(" XRF005AL is the value of yrcall, in this case this is a Link command\n\n");
printf(" XRF005AL is the value of yrcall, in this case this is a Link command\n\n"); return 0;
return 0; }
}
if (strlen(argv[4]) > 6) {
if (strlen(argv[4]) > 6) printf("repeaterCallsign can not be more than 6 characters, %s is invalid\n", argv[4]);
{ return 0;
printf("repeaterCallsign can not be more than 6 characters, %s is invalid\n", argv[4]); }
return 0; for (i = 0; i < 6; i++)
} argv[4][i] = toupper(argv[4][i]);
for (i = 0; i < 6; i++)
argv[4][i] = toupper(argv[4][i]);
if (strlen(argv[8]) > 8) {
printf("MYCALL can not be nore than 8 characters, %s is invalid\n", argv[8]);
if (strlen(argv[8]) > 8) return 0;
{ }
printf("MYCALL can not be nore than 8 characters, %s is invalid\n", argv[8]); for (i = 0; i < 8; i++)
return 0; argv[8][i] = toupper(argv[8][i]);
}
for (i = 0; i < 8; i++)
argv[8][i] = toupper(argv[8][i]); if (strlen(argv[9]) > 8) {
printf("YRCALL can not be nore than 8 characters, %s is invalid\n", argv[9]);
return 0;
if (strlen(argv[9]) > 8) }
{ for (i = 0; i < 8; i++)
printf("YRCALL can not be nore than 8 characters, %s is invalid\n", argv[9]); argv[9][i] = toupper(argv[9][i]);
return 0;
} if ((argv[5][0] != 'A') && (argv[5][0] != 'B') && (argv[5][0] != 'C')) {
for (i = 0; i < 8; i++) printf("module must be one of A B C\n");
argv[9][i] = toupper(argv[9][i]); return 0;
}
if ((argv[5][0] != 'A') && (argv[5][0] != 'B') && (argv[5][0] != 'C'))
{ delay = atol(argv[6]) * 1000L;
printf("module must be one of A B C\n"); sleep(atoi(argv[7]));
return 0;
} memset(RADIO_ID, ' ', 20);
RADIO_ID[20] = '\0';
delay = atol(argv[6]) * 1000L; memcpy(RADIO_ID, argv[3], (strlen(argv[3]) > 20)?20:strlen(argv[3]));
sleep(atoi(argv[7]));
/***
memset(RADIO_ID, ' ', 20); for (i = 0; i < 20; i++)
RADIO_ID[20] = '\0'; RADIO_ID[i] = toupper(RADIO_ID[i]);
memcpy(RADIO_ID, argv[3], (strlen(argv[3]) > 20)?20:strlen(argv[3])); ***/
/*** time(&tNow);
for (i = 0; i < 20; i++) srand(tNow + getpid());
RADIO_ID[i] = toupper(RADIO_ID[i]);
***/ if (dst_open(argv[1], atoi(argv[2]))) {
streamid_raw = (short)(::rand() & 0xFFFF);
time(&tNow); memcpy(dstar_buf,"DSTR", 4);
srand(tNow + getpid()); dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
if (dst_open(argv[1], atoi(argv[2]))) dstar_buf[6] = 0x73;
{ dstar_buf[7] = 0x12;
streamid_raw = (short)(::rand() & 0xFFFF); dstar_buf[8] = 0x00;
memcpy(dstar_buf,"DSTR", 4); dstar_buf[9] = 0x30;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); dstar_buf[10] = 0x20;
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[6] = 0x73; dstar_buf[11] = 0x00;
dstar_buf[7] = 0x12; dstar_buf[12] = 0x01;
dstar_buf[8] = 0x00; if (argv[5][0] == 'A')
dstar_buf[9] = 0x30; dstar_buf[13] = 0x03;
dstar_buf[10] = 0x20; else if (argv[5][0] == 'B')
dstar_buf[13] = 0x01;
dstar_buf[11] = 0x00; else if (argv[5][0] == 'C')
dstar_buf[12] = 0x01; dstar_buf[13] = 0x02;
if (argv[5][0] == 'A') else
dstar_buf[13] = 0x03; dstar_buf[13] = 0x00;
else
if (argv[5][0] == 'B') dstar_buf[14] = (unsigned char)(streamid_raw & 0xFF);
dstar_buf[13] = 0x01; dstar_buf[15] = (unsigned char)((streamid_raw >> 8) & 0xFF);
else dstar_buf[16] = 0x80;
if (argv[5][0] == 'C') dstar_buf[17] = 0x00;
dstar_buf[13] = 0x02; dstar_buf[18] = 0x00;
else dstar_buf[19] = 0x00;
dstar_buf[13] = 0x00;
/* RPT2 */
dstar_buf[14] = (unsigned char)(streamid_raw & 0xFF); memcpy(dstar_buf + 20, argv[4], strlen(argv[4]));
dstar_buf[15] = (unsigned char)((streamid_raw >> 8) & 0xFF); if (strlen(argv[4]) < 6)
dstar_buf[16] = 0x80; memset(dstar_buf + 20 + strlen(argv[4]), ' ', 6 - strlen(argv[4]));
dstar_buf[17] = 0x00; dstar_buf[26] = ' ';
dstar_buf[18] = 0x00; dstar_buf[27] = 'G';
dstar_buf[19] = 0x00;
/* RPT1 */
/* RPT2 */ memcpy(dstar_buf + 28, argv[4], strlen(argv[4]));
memcpy(dstar_buf + 20, argv[4], strlen(argv[4])); if (strlen(argv[4]) < 6)
if (strlen(argv[4]) < 6) memset(dstar_buf + 28 + strlen(argv[4]), ' ', 6 - strlen(argv[4]));
memset(dstar_buf + 20 + strlen(argv[4]), ' ', 6 - strlen(argv[4])); dstar_buf[34] = ' ';
dstar_buf[26] = ' '; dstar_buf[35] = argv[5][0];
dstar_buf[27] = 'G';
/* YRCALL */
/* RPT1 */ memcpy(dstar_buf + 36, argv[9], strlen(argv[9]));
memcpy(dstar_buf + 28, argv[4], strlen(argv[4])); if (strlen(argv[9]) < 8)
if (strlen(argv[4]) < 6) memset(dstar_buf + 36 + strlen(argv[9]), ' ', 8 - strlen(argv[9]));
memset(dstar_buf + 28 + strlen(argv[4]), ' ', 6 - strlen(argv[4]));
dstar_buf[34] = ' '; /* MYCALL */
dstar_buf[35] = argv[5][0]; memcpy(dstar_buf + 44, argv[8], strlen(argv[8]));
if (strlen(argv[8]) < 8)
/* YRCALL */ memset(dstar_buf + 44 + strlen(argv[8]), ' ', 8 - strlen(argv[8]));
memcpy(dstar_buf + 36, argv[9], strlen(argv[9]));
if (strlen(argv[9]) < 8) /* suffix */
memset(dstar_buf + 36 + strlen(argv[9]), ' ', 8 - strlen(argv[9])); memcpy(dstar_buf + 52, " ", 4);
calcPFCS(dstar_buf);
/* MYCALL */ (void)sendto(sockDst,(char *)dstar_buf,58,0,(struct sockaddr *)&toDst,sizeof(toDst));
memcpy(dstar_buf + 44, argv[8], strlen(argv[8])); G2_COUNTER ++;
if (strlen(argv[8]) < 8) usleep(delay);
memset(dstar_buf + 44 + strlen(argv[8]), ' ', 8 - strlen(argv[8]));
dstar_buf[9] = 0x13;
/* suffix */ memcpy((char *)dstar_buf + 17, silence, 9);
memcpy(dstar_buf + 52, " ", 4);
calcPFCS(dstar_buf); /* start sending silence + text */
(void)sendto(sockDst,(char *)dstar_buf,58,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++; /* SYNC */
usleep(delay); dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[9] = 0x13; dstar_buf[16] = 0x00;
memcpy((char *)dstar_buf + 17, silence, 9); dstar_buf[26] = 0x55;
dstar_buf[27] = 0x2d;
/* start sending silence + text */ dstar_buf[28] = 0x16;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
/* SYNC */ G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x00; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = 0x55; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = 0x2d; dstar_buf[16] = 0x01;
dstar_buf[28] = 0x16; dstar_buf[26] = '@' ^ 0x70;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); dstar_buf[27] = RADIO_ID[0] ^ 0x4f;
G2_COUNTER ++; dstar_buf[28] = RADIO_ID[1] ^ 0x93;
usleep(delay); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x01; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = '@' ^ 0x70; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = RADIO_ID[0] ^ 0x4f; dstar_buf[16] = 0x02;
dstar_buf[28] = RADIO_ID[1] ^ 0x93; dstar_buf[26] = RADIO_ID[2] ^ 0x70;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); dstar_buf[27] = RADIO_ID[3] ^ 0x4f;
G2_COUNTER ++; dstar_buf[28] = RADIO_ID[4] ^ 0x93;
usleep(delay); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x02; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = RADIO_ID[2] ^ 0x70; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = RADIO_ID[3] ^ 0x4f; dstar_buf[16] = 0x03;
dstar_buf[28] = RADIO_ID[4] ^ 0x93; dstar_buf[26] = 'A' ^ 0x70;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); dstar_buf[27] = RADIO_ID[5] ^ 0x4f;
G2_COUNTER ++; dstar_buf[28] = RADIO_ID[6] ^ 0x93;
usleep(delay); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x03; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = 'A' ^ 0x70; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = RADIO_ID[5] ^ 0x4f; dstar_buf[16] = 0x04;
dstar_buf[28] = RADIO_ID[6] ^ 0x93; dstar_buf[26] = RADIO_ID[7] ^ 0x70;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); dstar_buf[27] = RADIO_ID[8] ^ 0x4f;
G2_COUNTER ++; dstar_buf[28] = RADIO_ID[9] ^ 0x93;
usleep(delay); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x04; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = RADIO_ID[7] ^ 0x70; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = RADIO_ID[8] ^ 0x4f; dstar_buf[16] = 0x05;
dstar_buf[28] = RADIO_ID[9] ^ 0x93; dstar_buf[26] = 'B' ^ 0x70;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); dstar_buf[27] = RADIO_ID[10] ^ 0x4f;
G2_COUNTER ++; dstar_buf[28] = RADIO_ID[11] ^ 0x93;
usleep(delay); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x05; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = 'B' ^ 0x70; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = RADIO_ID[10] ^ 0x4f; dstar_buf[16] = 0x06;
dstar_buf[28] = RADIO_ID[11] ^ 0x93; dstar_buf[26] = RADIO_ID[12] ^ 0x70;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); dstar_buf[27] = RADIO_ID[13] ^ 0x4f;
G2_COUNTER ++; dstar_buf[28] = RADIO_ID[14] ^ 0x93;
usleep(delay); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x06; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = RADIO_ID[12] ^ 0x70; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = RADIO_ID[13] ^ 0x4f; dstar_buf[16] = 0x07;
dstar_buf[28] = RADIO_ID[14] ^ 0x93; dstar_buf[26] = 'C' ^ 0x70;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); dstar_buf[27] = RADIO_ID[15] ^ 0x4f;
G2_COUNTER ++; dstar_buf[28] = RADIO_ID[16] ^ 0x93;
usleep(delay); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x07; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = 'C' ^ 0x70; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = RADIO_ID[15] ^ 0x4f; dstar_buf[16] = 0x08;
dstar_buf[28] = RADIO_ID[16] ^ 0x93; dstar_buf[26] = RADIO_ID[17] ^ 0x70;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); dstar_buf[27] = RADIO_ID[18] ^ 0x4f;
G2_COUNTER ++; dstar_buf[28] = RADIO_ID[19] ^ 0x93;
usleep(delay); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); usleep(delay);
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[16] = 0x08; dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
dstar_buf[26] = RADIO_ID[17] ^ 0x70; dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
dstar_buf[27] = RADIO_ID[18] ^ 0x4f; dstar_buf[16] = 0x09 | 0x40;
dstar_buf[28] = RADIO_ID[19] ^ 0x93;
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); memset((char *)dstar_buf + 17, '\0', 9);
G2_COUNTER ++;
usleep(delay); dstar_buf[26] = 0x70;
dstar_buf[27] = 0x4f;
dstar_buf[5] = (unsigned char)(G2_COUNTER & 0xff); dstar_buf[28] = 0x93;
dstar_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff); (void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst));
dstar_buf[16] = 0x09 | 0x40; G2_COUNTER ++;
usleep(delay);
memset((char *)dstar_buf + 17, '\0', 9);
dst_close();
dstar_buf[26] = 0x70; }
dstar_buf[27] = 0x4f;
dstar_buf[28] = 0x93; printf("g2link_test exiting...\n");
(void)sendto(sockDst,(char *)dstar_buf,29,0,(struct sockaddr *)&toDst,sizeof(toDst)); return 0;
G2_COUNTER ++;
usleep(delay);
dst_close();
}
printf("g2link_test exiting...\n");
return 0;
} }

@ -29,371 +29,321 @@ static FILE *fp = NULL;
static time_t tNow = 0; static time_t tNow = 0;
static short streamid_raw = 0; static short streamid_raw = 0;
static unsigned short crc_tabccitt[256] = static unsigned short crc_tabccitt[256] = {
{ 0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf, 0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7, 0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e, 0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876, 0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd, 0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5, 0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c, 0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974, 0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb, 0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3, 0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a, 0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72, 0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9, 0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1, 0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738, 0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70, 0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7, 0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff, 0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036, 0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e, 0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5, 0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd, 0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134, 0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c, 0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3, 0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb, 0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232, 0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a, 0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1, 0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9, 0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330, 0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
}; };
static void calcPFCS(unsigned char rawbytes[58]) static void calcPFCS(unsigned char rawbytes[58])
{ {
unsigned short crc_dstar_ffff = 0xffff; unsigned short crc_dstar_ffff = 0xffff;
unsigned short tmp, short_c; unsigned short tmp, short_c;
short int i; short int i;
for (i = 17; i < 56 ; i++) for (i = 17; i < 56 ; i++) {
{ short_c = 0x00ff & (unsigned short)rawbytes[i];
short_c = 0x00ff & (unsigned short)rawbytes[i]; tmp = (crc_dstar_ffff & 0x00ff) ^ short_c;
tmp = (crc_dstar_ffff & 0x00ff) ^ short_c; crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp];
crc_dstar_ffff = (crc_dstar_ffff >> 8) ^ crc_tabccitt[tmp]; }
} crc_dstar_ffff = ~crc_dstar_ffff;
crc_dstar_ffff = ~crc_dstar_ffff; tmp = crc_dstar_ffff;
tmp = crc_dstar_ffff;
rawbytes[56] = (unsigned char)(crc_dstar_ffff & 0xff);
rawbytes[56] = (unsigned char)(crc_dstar_ffff & 0xff); rawbytes[57] = (unsigned char)((tmp >> 8) & 0xff);
rawbytes[57] = (unsigned char)((tmp >> 8) & 0xff); return;
return;
} }
static bool dst_open(char *ip, int port) static bool dst_open(char *ip, int port)
{ {
int reuse = 1; int reuse = 1;
sockDst = socket(PF_INET,SOCK_DGRAM,0); sockDst = socket(PF_INET,SOCK_DGRAM,0);
if (sockDst == -1) if (sockDst == -1) {
{ printf("Failed to create DSTAR socket\n");
printf("Failed to create DSTAR socket\n"); return false;
return false; }
} if (setsockopt(sockDst,SOL_SOCKET,SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
if (setsockopt(sockDst,SOL_SOCKET,SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) close(sockDst);
{ sockDst = -1;
close(sockDst); sockDst = -1; printf("setsockopt DSTAR REUSE failed\n");
printf("setsockopt DSTAR REUSE failed\n"); return false;
return false; }
} memset(&toDst,0,sizeof(struct sockaddr_in));
memset(&toDst,0,sizeof(struct sockaddr_in)); toDst.sin_family = AF_INET;
toDst.sin_family = AF_INET; toDst.sin_port = htons(port);
toDst.sin_port = htons(port); toDst.sin_addr.s_addr = inet_addr(ip);
toDst.sin_addr.s_addr = inet_addr(ip);
fcntl(sockDst,F_SETFL,O_NONBLOCK);
fcntl(sockDst,F_SETFL,O_NONBLOCK); return true;
return true;
} }
static void dst_close() static void dst_close()
{ {
if (sockDst != -1) if (sockDst != -1) {
{ close(sockDst);
close(sockDst); sockDst = -1;
sockDst = -1; }
} return;
return;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
unsigned short rlen = 0; unsigned short rlen = 0;
static unsigned short G2_COUNTER = 0; static unsigned short G2_COUNTER = 0;
size_t nread = 0; size_t nread = 0;
unsigned char dstar_buf[56]; unsigned char dstar_buf[56];
unsigned char rptr_buf[58]; unsigned char rptr_buf[58];
unsigned long delay; unsigned long delay;
unsigned short i; unsigned short i;
char RADIO_ID[21]; char RADIO_ID[21];
short int TEXT_idx = 0; short int TEXT_idx = 0;
if (argc != 10) if (argc != 10) {
{ printf("Usage: g2link_test_audio <IPaddress> <port> <dvtoolFile> <repeaterCallsign> <module> <delay_between> <delay_before> <MYCALL> <YRCALL>\n");
printf("Usage: g2link_test_audio <IPaddress> <port> <dvtoolFile> <repeaterCallsign> <module> <delay_between> <delay_before> <MYCALL> <YRCALL>\n"); printf("Example: g2link_test_audio 127.0.0.1 19000 somefile.dvtool KJ4NHF B 19 2 KI4LKF CQCQCQ\n");
printf("Example: g2link_test_audio 127.0.0.1 19000 somefile.dvtool KJ4NHF B 19 2 KI4LKF CQCQCQ\n"); printf("Where...\n");
printf("Where...\n"); printf(" 127.0.0.1 is the IP address of the local G2\n");
printf(" 127.0.0.1 is the IP address of the local G2\n"); printf(" 19000 is the port of the INTERNAL G2\n");
printf(" 19000 is the port of the INTERNAL G2\n"); printf(" somefile.dvtool is a dvtool file\n");
printf(" somefile.dvtool is a dvtool file\n"); printf(" KJ4NHF is your G2 callsign, dont use KJ4NHF\n");
printf(" KJ4NHF is your G2 callsign, dont use KJ4NHF\n"); printf(" B is one of your modules\n");
printf(" B is one of your modules\n"); printf(" 19 millisecond delay between each packet\n");
printf(" 19 millisecond delay between each packet\n"); printf(" 2 second delay before we begin this test\n");
printf(" 2 second delay before we begin this test\n"); printf(" mycall is KI4LKF, your personal callsign, do not use KI4LKF\n");
printf(" mycall is KI4LKF, your personal callsign, do not use KI4LKF\n"); printf(" yrcall is CQCQCQ\n");
printf(" yrcall is CQCQCQ\n"); return 0;
return 0; }
}
if (strlen(argv[4]) > 6) {
if (strlen(argv[4]) > 6) printf("repeaterCallsign can not be more than 6 characters, %s is invalid\n", argv[4]);
{ return 0;
printf("repeaterCallsign can not be more than 6 characters, %s is invalid\n", argv[4]); }
return 0; for (i = 0; i < strlen(argv[4]); i++)
} argv[4][i] = toupper(argv[4][i]);
for (i = 0; i < strlen(argv[4]); i++)
argv[4][i] = toupper(argv[4][i]); if ((argv[5][0] != 'A') && (argv[5][0] != 'B') && (argv[5][0] != 'C')) {
printf("module must be one of A B C\n");
if ((argv[5][0] != 'A') && (argv[5][0] != 'B') && (argv[5][0] != 'C')) return 0;
{ }
printf("module must be one of A B C\n");
return 0; if (strlen(argv[8]) > 8) {
} printf("No more than 8 characters in MYCALL\n");
return 0;
if (strlen(argv[8]) > 8) }
{ for (i = 0; i < strlen(argv[8]); i++)
printf("No more than 8 characters in MYCALL\n"); argv[8][i] = toupper(argv[8][i]);
return 0;
} if (strlen(argv[9]) > 8) {
for (i = 0; i < strlen(argv[8]); i++) printf("No more than 8 characters in YRCALL\n");
argv[8][i] = toupper(argv[8][i]); return 0;
}
if (strlen(argv[9]) > 8) for (i = 0; i < strlen(argv[9]); i++)
{ argv[9][i] = toupper(argv[9][i]);
printf("No more than 8 characters in YRCALL\n");
return 0;
} fp = fopen(argv[3], "rb");
for (i = 0; i < strlen(argv[9]); i++) if (!fp) {
argv[9][i] = toupper(argv[9][i]); printf("Failed to open file %s for reading\n", argv[3]);
return 0;
}
fp = fopen(argv[3], "rb");
if (!fp) /* stupid DVTOOL + 4 byte num_of_records */
{ nread = fread(dstar_buf, 10, 1, fp);
printf("Failed to open file %s for reading\n", argv[3]); if (nread != 1) {
return 0; printf("Cant read first 10 bytes\n");
} fclose(fp);
return 0;
/* stupid DVTOOL + 4 byte num_of_records */ }
nread = fread(dstar_buf, 10, 1, fp); if (memcmp(dstar_buf, "DVTOOL", 6) != 0) {
if (nread != 1) printf("DVTOOL not found\n");
{ fclose(fp);
printf("Cant read first 10 bytes\n"); return 0;
fclose(fp); }
return 0;
} memset(RADIO_ID, ' ', 20);
if (memcmp(dstar_buf, "DVTOOL", 6) != 0) RADIO_ID[20] = '\0';
{
printf("DVTOOL not found\n"); memcpy(RADIO_ID, "TEST", 4);
fclose(fp);
return 0; delay = atol(argv[6]) * 1000L;
} sleep(atoi(argv[7]));
memset(RADIO_ID, ' ', 20); time(&tNow);
RADIO_ID[20] = '\0'; srand(tNow + getpid());
memcpy(RADIO_ID, "TEST", 4); if (dst_open(argv[1], atoi(argv[2]))) {
while (true) {
delay = atol(argv[6]) * 1000L; /* 2 byte length */
sleep(atoi(argv[7])); nread = fread(&rlen, 2, 1, fp);
if (nread != 1) {
time(&tNow); printf("End-Of-File\n");
srand(tNow + getpid()); break;
}
if (dst_open(argv[1], atoi(argv[2]))) if (rlen == 56)
{ streamid_raw = (short)(::rand() & 0xFFFF);
while (true) else if (rlen == 27)
{ ;
/* 2 byte length */ else {
nread = fread(&rlen, 2, 1, fp); printf("Not 56-byte and not 27-byte\n");
if (nread != 1) break;
{ }
printf("End-Of-File\n");
break; /* read the packet */
} nread = fread(dstar_buf, rlen, 1, fp);
if (rlen == 56) if (nread == 1) {
streamid_raw = (short)(::rand() & 0xFFFF); if (memcmp(dstar_buf, "DSVT", 4) != 0) {
else printf("DVST not found\n");
if (rlen == 27) break;
; }
else
{ if (dstar_buf[8] != 0x20) {
printf("Not 56-byte and not 27-byte\n"); printf("Not Voice type\n");
break; break;
} }
/* read the packet */ if (dstar_buf[4] == 0x10)
nread = fread(dstar_buf, rlen, 1, fp); ;
if (nread == 1) else if (dstar_buf[4] == 0x20)
{ ;
if (memcmp(dstar_buf, "DSVT", 4) != 0) else {
{ printf("Not a valid record type\n");
printf("DVST not found\n"); break;
break; }
}
if (rlen == 56) {
if (dstar_buf[8] != 0x20) memcpy(rptr_buf, "DSTR", 4);
{ rptr_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
printf("Not Voice type\n"); rptr_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
break; rptr_buf[6] = 0x73;
} rptr_buf[7] = 0x12;
rptr_buf[8] = 0x00;
if (dstar_buf[4] == 0x10) rptr_buf[9] = 0x30;
; rptr_buf[10] = 0x20;
else memcpy(rptr_buf + 11, dstar_buf + 9, 47);
if (dstar_buf[4] == 0x20)
; rptr_buf[14] = (unsigned char)(streamid_raw & 0xFF);
else rptr_buf[15] = (unsigned char)((streamid_raw >> 8) & 0xFF);
{
printf("Not a valid record type\n"); memcpy(rptr_buf + 20, argv[4], strlen(argv[4]));
break; if (strlen(argv[4]) < 6)
} memset(rptr_buf + 20 + strlen(argv[4]), ' ', 6 - strlen(argv[4]));
rptr_buf[26] = ' ';
if (rlen == 56) rptr_buf[27] = 'G';
{
memcpy(rptr_buf, "DSTR", 4); memcpy(rptr_buf + 28, argv[4], strlen(argv[4]));
rptr_buf[5] = (unsigned char)(G2_COUNTER & 0xff); if (strlen(argv[4]) < 6)
rptr_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff); memset(rptr_buf + 28 + strlen(argv[4]), ' ', 6 - strlen(argv[4]));
rptr_buf[6] = 0x73; rptr_buf[34] = ' ';
rptr_buf[7] = 0x12; rptr_buf[35] = argv[5][0];
rptr_buf[8] = 0x00;
rptr_buf[9] = 0x30; /* yrcall */
rptr_buf[10] = 0x20; memcpy(rptr_buf + 36, argv[9], strlen(argv[9]));
memcpy(rptr_buf + 11, dstar_buf + 9, 47); if (strlen(argv[9]) < 8)
memset(rptr_buf + 36 + strlen(argv[9]), ' ', 8 - strlen(argv[9]));
rptr_buf[14] = (unsigned char)(streamid_raw & 0xFF);
rptr_buf[15] = (unsigned char)((streamid_raw >> 8) & 0xFF); /* mycall */
memcpy(rptr_buf + 44, argv[8], strlen(argv[8]));
memcpy(rptr_buf + 20, argv[4], strlen(argv[4])); if (strlen(argv[8]) < 8)
if (strlen(argv[4]) < 6) memset(rptr_buf + 44 + strlen(argv[8]), ' ', 8 - strlen(argv[8]));
memset(rptr_buf + 20 + strlen(argv[4]), ' ', 6 - strlen(argv[4]));
rptr_buf[26] = ' '; memcpy(rptr_buf + 52, "TEST", 4);
rptr_buf[27] = 'G';
calcPFCS(rptr_buf);
memcpy(rptr_buf + 28, argv[4], strlen(argv[4])); } else {
if (strlen(argv[4]) < 6) rptr_buf[5] = (unsigned char)(G2_COUNTER & 0xff);
memset(rptr_buf + 28 + strlen(argv[4]), ' ', 6 - strlen(argv[4])); rptr_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff);
rptr_buf[34] = ' '; rptr_buf[9] = 0x13;
rptr_buf[35] = argv[5][0];
if ((dstar_buf[24] != 0x55) ||
/* yrcall */ (dstar_buf[25] != 0x2d) ||
memcpy(rptr_buf + 36, argv[9], strlen(argv[9])); (dstar_buf[26] != 0x16)) {
if (strlen(argv[9]) < 8) if (TEXT_idx == 0) {
memset(rptr_buf + 36 + strlen(argv[9]), ' ', 8 - strlen(argv[9])); dstar_buf[24] = '@' ^ 0x70;
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
/* mycall */ dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
memcpy(rptr_buf + 44, argv[8], strlen(argv[8])); } else if (TEXT_idx == 2) {
if (strlen(argv[8]) < 8) dstar_buf[24] = RADIO_ID[TEXT_idx++] ^ 0x70;
memset(rptr_buf + 44 + strlen(argv[8]), ' ', 8 - strlen(argv[8])); dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
memcpy(rptr_buf + 52, "TEST", 4); } else if (TEXT_idx == 5) {
dstar_buf[24] = 'A' ^ 0x70;
calcPFCS(rptr_buf); dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
} dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
else } else if (TEXT_idx == 7) {
{ dstar_buf[24] = RADIO_ID[TEXT_idx++] ^ 0x70;
rptr_buf[5] = (unsigned char)(G2_COUNTER & 0xff); dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
rptr_buf[4] = (unsigned char)((G2_COUNTER >> 8) & 0xff); dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
rptr_buf[9] = 0x13; } else if (TEXT_idx == 10) {
dstar_buf[24] = 'B' ^ 0x70;
if ((dstar_buf[24] != 0x55) || dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
(dstar_buf[25] != 0x2d) || dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
(dstar_buf[26] != 0x16)) } else if (TEXT_idx == 12) {
{ dstar_buf[24] = RADIO_ID[TEXT_idx++] ^ 0x70;
if (TEXT_idx == 0) dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
{ dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
dstar_buf[24] = '@' ^ 0x70; } else if (TEXT_idx == 15) {
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f; dstar_buf[24] = 'C' ^ 0x70;
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93; dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
} dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
else } else if (TEXT_idx == 17) {
if (TEXT_idx == 2) dstar_buf[24] = RADIO_ID[TEXT_idx++] ^ 0x70;
{ dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
dstar_buf[24] = RADIO_ID[TEXT_idx++] ^ 0x70; dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f; } else {
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93; dstar_buf[24] = 0x70;
} dstar_buf[25] = 0x4f;
else dstar_buf[26] = 0x93;
if (TEXT_idx == 5) }
{ }
dstar_buf[24] = 'A' ^ 0x70; memcpy(rptr_buf + 11, dstar_buf + 9, 18);
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f; rptr_buf[14] = (unsigned char)(streamid_raw & 0xFF);
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93; rptr_buf[15] = (unsigned char)((streamid_raw >> 8) & 0xFF);
} }
else
if (TEXT_idx == 7) sendto(sockDst,(char *)rptr_buf,rlen + 2,0,
{ (struct sockaddr *)&toDst,sizeof(toDst));
dstar_buf[24] = RADIO_ID[TEXT_idx++] ^ 0x70; G2_COUNTER ++;
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93; }
} usleep(delay);
else }
if (TEXT_idx == 10) dst_close();
{ }
dstar_buf[24] = 'B' ^ 0x70; fclose(fp);
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93; printf("g2link_test_audio exiting...\n");
} return 0;
else
if (TEXT_idx == 12)
{
dstar_buf[24] = RADIO_ID[TEXT_idx++] ^ 0x70;
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
}
else
if (TEXT_idx == 15)
{
dstar_buf[24] = 'C' ^ 0x70;
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
}
else
if (TEXT_idx == 17)
{
dstar_buf[24] = RADIO_ID[TEXT_idx++] ^ 0x70;
dstar_buf[25] = RADIO_ID[TEXT_idx++] ^ 0x4f;
dstar_buf[26] = RADIO_ID[TEXT_idx++] ^ 0x93;
}
else
{
dstar_buf[24] = 0x70;
dstar_buf[25] = 0x4f;
dstar_buf[26] = 0x93;
}
}
memcpy(rptr_buf + 11, dstar_buf + 9, 18);
rptr_buf[14] = (unsigned char)(streamid_raw & 0xFF);
rptr_buf[15] = (unsigned char)((streamid_raw >> 8) & 0xFF);
}
sendto(sockDst,(char *)rptr_buf,rlen + 2,0,
(struct sockaddr *)&toDst,sizeof(toDst));
G2_COUNTER ++;
}
usleep(delay);
}
dst_close();
}
fclose(fp);
printf("g2link_test_audio exiting...\n");
return 0;
} }

@ -15,7 +15,9 @@ rm -f gwys.va2uv.txt
wget -nv -O gwys.va3uv.txt http://www.va3uv.com/gwys.txt wget -nv -O gwys.va3uv.txt http://www.va3uv.com/gwys.txt
if [ -e gwys.va3uv.txt ]; then if [ -e gwys.va3uv.txt ]; then
awk '$1~/^REF|XRF/&&$2~/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/{print $1, $2, 20001}' gwys.va3uv.txt > gwys.txt # Move DPlus and DExtra to port 20001
awk '$1~/^REF|XRF/{print $1, $2, 20001}' gwys.va3uv.txt > gwys.txt
# Get the DCS reflectors too
awk '$1~/^DCS/{print $1, $2, $3}' gwys.va3uv.txt >> gwys.txt awk '$1~/^DCS/{print $1, $2, $3}' gwys.va3uv.txt >> gwys.txt
else else
echo "Could not get gateways list from www.va3uv.com!" echo "Could not get gateways list from www.va3uv.com!"

@ -94,17 +94,17 @@ long arr2int(int *a, int r)
* array a[1]...a[r], to a long integer \sum_{i=1}^r 2^{a[i]-1}. * array a[1]...a[r], to a long integer \sum_{i=1}^r 2^{a[i]-1}.
*/ */
{ {
int i; int i;
long mul, result = 0, temp; long mul, result = 0, temp;
for (i=1; i<=r; i++) { for (i=1; i<=r; i++) {
mul = 1; mul = 1;
temp = a[i]-1; temp = a[i]-1;
while (temp--) while (temp--)
mul = mul << 1; mul = mul << 1;
result += mul; result += mul;
} }
return(result); return(result);
} }
void nextcomb(int n, int r, int *a) void nextcomb(int n, int r, int *a)
@ -112,17 +112,17 @@ void nextcomb(int n, int r, int *a)
* Calculate next r-combination of an n-set. * Calculate next r-combination of an n-set.
*/ */
{ {
int i, j; int i, j;
a[r]++; a[r]++;
if (a[r] <= n) if (a[r] <= n)
return; return;
j = r - 1; j = r - 1;
while (a[j] == n - r + j) while (a[j] == n - r + j)
j--; j--;
for (i = r; i >= j; i--) for (i = r; i >= j; i--)
a[i] = a[j] + i - j + 1; a[i] = a[j] + i - j + 1;
return; return;
} }
long get_syndrome(long pattern) long get_syndrome(long pattern)
@ -137,15 +137,15 @@ long get_syndrome(long pattern)
*/ */
{ {
// long aux = X22, aux2; // long aux = X22, aux2;
long aux = X22; long aux = X22;
if (pattern >= X11) if (pattern >= X11)
while (pattern & MASK12) { while (pattern & MASK12) {
while (!(aux & pattern)) while (!(aux & pattern))
aux = aux >> 1; aux = aux >> 1;
pattern ^= (aux/X11) * GENPOL; pattern ^= (aux/X11) * GENPOL;
} }
return(pattern); return(pattern);
} }
// main() // main()

@ -17,7 +17,6 @@ REF019 208.87.120.144 20001
REF020 50.199.88.20 20001 REF020 50.199.88.20 20001
REF024 69.41.0.15 20001 REF024 69.41.0.15 20001
REF025 173.10.178.226 20001 REF025 173.10.178.226 20001
REF026 206.12.104.8 20001
REF027 194.116.29.72 20001 REF027 194.116.29.72 20001
REF028 193.190.240.229 20001 REF028 193.190.240.229 20001
REF029 129.123.7.138 20001 REF029 129.123.7.138 20001
@ -31,7 +30,6 @@ REF037 208.111.3.181 20001
REF038 66.6.171.227 20001 REF038 66.6.171.227 20001
REF039 208.93.191.20 20001 REF039 208.93.191.20 20001
REF045 195.251.201.194 20001 REF045 195.251.201.194 20001
REF046 208.111.3.182 20001
REF047 157.7.142.13 20001 REF047 157.7.142.13 20001
REF048 208.88.66.244 20001 REF048 208.88.66.244 20001
REF050 75.147.26.195 20001 REF050 75.147.26.195 20001
@ -68,7 +66,7 @@ XRF021 74.204.50.67 20001
XRF023 141.75.245.225 20001 XRF023 141.75.245.225 20001
XRF025 63.133.189.2 20001 XRF025 63.133.189.2 20001
XRF026 139.13.100.34 20001 XRF026 139.13.100.34 20001
XRF027 194.116.29.66 20001 XRF027 194.116.29.78 20001
XRF028 193.190.240.228 20001 XRF028 193.190.240.228 20001
XRF031 83.241.141.245 20001 XRF031 83.241.141.245 20001
XRF033 46.226.178.81 20001 XRF033 46.226.178.81 20001
@ -87,11 +85,12 @@ XRF123 213.126.90.100 20001
XRF310 199.167.193.147 20001 XRF310 199.167.193.147 20001
XRF333 37.187.103.98 20001 XRF333 37.187.103.98 20001
XRF353 94.173.206.53 20001 XRF353 94.173.206.53 20001
XRF444 71.40.84.59 20001 XRF444 70.125.157.44 20001
XRF500 125.63.57.138 20001
XRF555 199.167.193.205 20001 XRF555 199.167.193.205 20001
XRF559 98.239.113.175 20001
XRF580 67.20.31.79 20001 XRF580 67.20.31.79 20001
XRF603 74.104.179.159 20001 XRF603 74.104.179.159 20001
XRF666 125.63.57.138 20001
XRF719 199.227.117.121 20001 XRF719 199.227.117.121 20001
XRF727 108.33.72.83 20001 XRF727 108.33.72.83 20001
XRF777 62.167.15.53 20001 XRF777 62.167.15.53 20001
@ -101,3 +100,28 @@ XRF858 198.57.255.30 20001
XRF901 199.167.196.109 20001 XRF901 199.167.196.109 20001
XRF905 199.212.121.20 20001 XRF905 199.212.121.20 20001
XRF978 74.104.179.159 20001 XRF978 74.104.179.159 20001
DCS001 dcs001.xreflector.net 30051
DCS002 dcs002.xreflector.net 30051
DCS003 dcs003.xreflector.net 30051
DCS004 dcs004.xreflector.net 30051
DCS005 dcs005.xreflector.net 30051
DCS006 dcs006.xreflector.net 30051
DCS007 dcs007.xreflector.net 30051
DCS008 dcs008.xreflector.net 30051
DCS009 dcs009.xreflector.net 30051
DCS010 dcs010.xreflector.net 30051
DCS011 dcs011.xreflector.net 30051
DCS012 dcs012.xreflector.net 30051
DCS013 dcs013.xreflector.net 30051
DCS014 dcs014.xreflector.net 30051
DCS015 dcs015.xreflector.net 30051
DCS016 dcs016.xreflector.net 30051
DCS017 dcs017.xreflector.net 30051
DCS018 dcs018.xreflector.net 30051
DCS019 dcs019.xreflector.net 30051
DCS020 dcs020.xreflector.net 30051
DCS021 dcs021.xreflector.net 30051
DCS022 dcs022.xreflector.net 30051
DCS023 dcs023.xreflector.net 30051
DCS024 dcs024.xreflector.net 30051
DCS025 dcs025.xreflector.net 30051

Loading…
Cancel
Save

Powered by TurnKey Linux.