diff --git a/src/cysfprotocol.cpp b/src/cysfprotocol.cpp index 0905276..12be9dd 100644 --- a/src/cysfprotocol.cpp +++ b/src/cysfprotocol.cpp @@ -200,7 +200,14 @@ void CYsfProtocol::Task(void) // and post it to hadler's queue m_WiresxCmdHandler.GetCmdQueue()->push(WiresxCmd); m_WiresxCmdHandler.ReleaseCmdQueue(); - } + } + else if ( IsValidServerStatusPacket(Buffer) ) + { + std::cout << "YSF server status enquiry from " << Ip << std::endl; + // reply + EncodeServerStatusPacket(&Buffer); + m_Socket.Send(Buffer, Ip); + } else { // invalid packet @@ -927,6 +934,63 @@ bool CYsfProtocol::IsValidwirexPacket(const CBuffer &Buffer, CYSFFICH *Fich, CCa return valid; } +// server status packet decoding helpers + +bool CYsfProtocol::IsValidServerStatusPacket(const CBuffer &Buffer) const +{ + uint8 tag[] = { 'Y','S','F','S' }; + + return ( (Buffer.size() >= 4) && (Buffer.Compare(tag, sizeof(tag)) == 0) ); +} + +// server status packet encoding helpers + +bool CYsfProtocol::EncodeServerStatusPacket(CBuffer *Buffer) const +{ + uint8 tag[] = { 'Y','S','F','S' }; + uint8 callsign[16]; + + // tag + Buffer->Set(tag, sizeof(tag)); + // hash + ::memset(callsign, ' ', sizeof(callsign)); + g_Reflector.GetCallsign().GetCallsign(callsign); + char sz[16]; + ::sprintf(sz, "%05u", CalcHash(callsign, 16) % 100000U); + Buffer->Append((uint8 *)sz, 5); + // name + Buffer->Append(callsign, 16); + // desscription + Buffer->Append(' ', 14); + // connected clients + CClients *clients = g_Reflector.GetClients(); + int count = MIN(999, clients->GetSize()); + g_Reflector.ReleaseClients(); + ::sprintf(sz, "%03u", count); + Buffer->Append((uint8 *)sz, 3); + + // done + return true; +} + +uint32 CYsfProtocol::CalcHash(const uint8 *buffer, int len) const +{ + uint32 hash = 0U; + + for ( int i = 0; i < len; i++) + { + hash += buffer[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return hash; +} + + //////////////////////////////////////////////////////////////////////////////////////// // uiStreamId helpers diff --git a/src/cysfprotocol.h b/src/cysfprotocol.h index fb06184..77725e9 100644 --- a/src/cysfprotocol.h +++ b/src/cysfprotocol.h @@ -112,6 +112,13 @@ protected: // Wires-X packet decoding helpers bool IsValidwirexPacket(const CBuffer &, CYSFFICH *, CCallsign *, int *, int*); + // server status packet decoding helpers + bool IsValidServerStatusPacket(const CBuffer &) const; + uint32 CalcHash(const uint8 *, int) const; + + // server status packet encoding helpers + bool EncodeServerStatusPacket(CBuffer *) const; + // uiStreamId helpers uint32 IpToStreamId(const CIp &) const; diff --git a/src/main.h b/src/main.h index e9f627e..96023fd 100644 --- a/src/main.h +++ b/src/main.h @@ -49,7 +49,7 @@ #define VERSION_MAJOR 2 #define VERSION_MINOR 3 -#define VERSION_REVISION 3 +#define VERSION_REVISION 4 // global ------------------------------------------------------