diff --git a/src/protocol.cpp b/src/protocol.cpp index a595a24e45..374a5bdce7 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -459,6 +459,19 @@ CONNECTION LESS MESSAGES five times for one registration request at 500ms intervals. Beyond this, it should "ping" every 15 minutes (standard re-registration timeout). + + +- PROTMESSID_CLM_SERVER_INFO: Bitmask of enabled server features + + +------------------+ + | 4 bytes number n | + +------------------+ + + +- PROTMESSID_CLM_REQ_SERVER_INFO: Request bitmask of enabled server features + + note: does not have any data -> n = 0 + */ #include "protocol.h" @@ -947,6 +960,10 @@ void CProtocol::ParseConnectionLessMessageBody ( const CVector& vecbyMe case PROTMESSID_CLM_REGISTER_SERVER_RESP: EvaluateCLRegisterServerResp ( InetAddr, vecbyMesBodyData ); break; + + case PROTMESSID_CLM_REQ_SERVER_INFO: + EvaluateCLReqServerInfoMes ( InetAddr ); + break; } } @@ -2620,6 +2637,24 @@ bool CProtocol::EvaluateCLRegisterServerResp ( const CHostAddress& InetAddr, con return false; // no error } +bool CProtocol::EvaluateCLReqServerInfoMes ( const CHostAddress& InetAddr ) +{ + // invoke message action + emit CLReqServerInfo ( InetAddr ); + + return false; // no error +} + +void CProtocol::CreateCLServerInfoMes ( const CHostAddress& InetAddr, const uint32_t iFeatures ) +{ + int iPos = 0; // init position pointer + CVector vecData ( 1 ); + + PutValOnStream ( vecData, iPos, iFeatures, 4 ); + + CreateAndImmSendConLessMessage ( PROTMESSID_CLM_SERVER_INFO, vecData, InetAddr ); +} + /******************************************************************************\ * Message generation and parsing * \******************************************************************************/ diff --git a/src/protocol.h b/src/protocol.h index 4621fe31b7..61b654f03e 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -106,6 +106,8 @@ #define PROTMESSID_CLM_REGISTER_SERVER_RESP 1016 // status of server registration request #define PROTMESSID_CLM_REGISTER_SERVER_EX 1017 // register server with extended information #define PROTMESSID_CLM_RED_SERVER_LIST 1018 // reduced server list +#define PROTMESSID_CLM_SERVER_INFO 1019 // server info message +#define PROTMESSID_CLM_REQ_SERVER_INFO 1020 // request server info // special IDs #define PROTMESSID_SPECIAL_SPLIT_MESSAGE 2001 // a container for split messages @@ -177,6 +179,7 @@ class CProtocol : public QObject void CreateCLReqConnClientsListMes ( const CHostAddress& InetAddr ); void CreateCLChannelLevelListMes ( const CHostAddress& InetAddr, const CVector& vecLevelList, const int iNumClients ); void CreateCLRegisterServerResp ( const CHostAddress& InetAddr, const ESvrRegResult eResult ); + void CreateCLServerInfoMes ( const CHostAddress& InetAddr, const uint32_t iResult ); static bool ParseMessageFrame ( const CVector& vecbyData, const int iNumBytesIn, @@ -304,6 +307,7 @@ class CProtocol : public QObject bool EvaluateCLReqConnClientsListMes ( const CHostAddress& InetAddr ); bool EvaluateCLChannelLevelListMes ( const CHostAddress& InetAddr, const CVector& vecData ); bool EvaluateCLRegisterServerResp ( const CHostAddress& InetAddr, const CVector& vecData ); + bool EvaluateCLReqServerInfoMes ( const CHostAddress& InetAddr ); int iOldRecID; int iOldRecCnt; @@ -371,4 +375,5 @@ public slots: void CLReqConnClientsList ( CHostAddress InetAddr ); void CLChannelLevelListReceived ( CHostAddress InetAddr, CVector vecLevelList ); void CLRegisterServerResp ( CHostAddress InetAddr, ESvrRegResult eStatus ); + void CLReqServerInfo ( CHostAddress InetAddr ); }; diff --git a/src/server.cpp b/src/server.cpp index 67274965bc..9643021481 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -45,6 +45,7 @@ \******************************************************************************/ #include "server.h" +#include "util.h" // CServer implementation ****************************************************** CServer::CServer ( const int iNewMaxNumChan, @@ -291,6 +292,8 @@ CServer::CServer ( const int iNewMaxNumChan, QObject::connect ( &ConnLessProtocol, &CProtocol::CLReqConnClientsList, this, &CServer::OnCLReqConnClientsList ); + QObject::connect ( &ConnLessProtocol, &CProtocol::CLReqServerInfo, this, &CServer::OnCLReqServerInfo ); + QObject::connect ( &ServerListManager, &CServerListManager::SvrRegStatusChanged, this, &CServer::SvrRegStatusChanged ); QObject::connect ( &JamController, &recorder::CJamController::RestartRecorder, this, &CServer::RestartRecorder ); @@ -472,6 +475,53 @@ void CServer::OnNewConnection ( int iChID, int iTotChans, CHostAddress RecHostAd Logging.AddNewConnection ( RecHostAddr.InetAddr, iTotChans ); } +void CServer::OnCLReqServerInfo ( CHostAddress RecHostAddr ) +{ + // This is a bitmask of features enabled at the server. + // EFeatureSet from util.h is used to shift each bool into position + uint32_t iFeatures = 0; + + // Use 64 samples frame size mode? (argument -F) + iFeatures |= ( !bUseDoubleSystemFrameSize << FS_FAST_UPDATE ); + + // Multithreading enabled? (argument -T) + iFeatures |= ( bUseMultithreading << FS_MULTITHREADING ); + + // Recording directory set? (argument -R) + // If a recording directory is set a server could potentially record all client audio + iFeatures |= ( GetRecorderInitialised() << FS_RECORDER_ENABLED ); + + // Will an idle server start recording when a client joins? (argument --norecord) + // Also reflects if the active server is recording or not. + iFeatures |= ( ( JamController.GetRecorderState() == RS_RECORDING ) << FS_IS_RECORDING ); + + // Delay pan enabled? (argument -P) + iFeatures |= ( bDelayPan << FS_DELAY_PAN ); + + // IPv6 available? (argument --noipv6 disables this feature) + iFeatures |= ( IsIPv6Available() << FS_IPV6_AVAILABLE ); + + // "Max" audio quality setting enabled? (argument --noraw disables this feature) + iFeatures |= ( !bDisableRaw << FS_RAW_AUDIO ); + + // Disconnect all clients on quit? (argument -d) + iFeatures |= ( bDisconnectAllClientsOnQuit << FS_DISCONONQUIT ); + + // Has welcome message? (argument -w) + iFeatures |= ( !strWelcomeMessage.isEmpty() << FS_HAS_WELCOME_MESSAGE ); + + // Logging enabled? (argument -l) + iFeatures |= ( Logging.bIsLogging() << FS_IS_LOGGING ); + + // Licence agreement required? (argument -L) + iFeatures |= ( ( eLicenceType != LT_NO_LICENCE ) << FS_HAS_LICENCE ); + + // qDebug() << QString::number(iFeatures, 2).rightJustified(32, '0'); + + // Create and send the message + ConnLessProtocol.CreateCLServerInfoMes ( RecHostAddr, iFeatures ); +} + void CServer::OnServerFull ( CHostAddress RecHostAddr ) { // note: no mutex required here diff --git a/src/server.h b/src/server.h index 2e6b13e835..8617c94f77 100644 --- a/src/server.h +++ b/src/server.h @@ -396,6 +396,8 @@ public slots: void OnCLUnregisterServerReceived ( CHostAddress InetAddr ) { ServerListManager.Remove ( InetAddr ); } + void OnCLReqServerInfo ( CHostAddress InetAddr ); + void OnCLDisconnection ( CHostAddress InetAddr ); void OnAboutToQuit(); diff --git a/src/serverlogging.h b/src/serverlogging.h index 1ce0a7fba6..7a6c7ac5cf 100644 --- a/src/serverlogging.h +++ b/src/serverlogging.h @@ -66,6 +66,7 @@ class CServerLogging void AddServerStopped(); void AddNewConnection ( const QHostAddress& ClientInetAddr, const int iNumberOfConnectedClients ); + bool bIsLogging() { return bDoLogging; } protected: void operator<< ( const QString& sNewStr ); diff --git a/src/util.h b/src/util.h index 84ce8e3261..4c97d9a4fa 100644 --- a/src/util.h +++ b/src/util.h @@ -617,6 +617,23 @@ enum EDirectoryType AT_CUSTOM = 7 // Must be the last entry! }; +// Server feature set ---------------------------------------------------------- +enum EFeatureSet +{ + // used for protocol -> enum values must be fixed + FS_FAST_UPDATE = 0, + FS_MULTITHREADING = 1, + FS_RECORDER_ENABLED = 2, + FS_IS_RECORDING = 3, + FS_DELAY_PAN = 4, + FS_IPV6_AVAILABLE = 5, + FS_RAW_AUDIO = 6, + FS_DISCONONQUIT = 7, + FS_HAS_WELCOME_MESSAGE = 8, + FS_IS_LOGGING = 9, + FS_HAS_LICENCE = 10 +}; + inline QString DirectoryTypeToString ( EDirectoryType eAddrType ) { switch ( eAddrType )