diff --git a/src/client.cpp b/src/client.cpp index 42b98f69..50e171c0 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -189,46 +189,19 @@ int CClient::EvaluatePingMessage ( const int iMs ) bool CClient::SetServerAddr ( QString strNAddr ) { - QHostAddress InetAddr; - quint16 iNetPort = LLCON_DEFAULT_PORT_NUMBER; - - // parse input address for the type [IP address]:[port number] - QString strPort = strNAddr.section ( ":", 1, 1 ); - if ( !strPort.isEmpty() ) + CHostAddress HostAddress; + if ( LlconNetwUtil().ParseNetworkAddress ( strNAddr, + HostAddress ) ) { - // a colon is present in the address string, try to extract port number - iNetPort = strPort.toInt(); + // apply address to the channel + Channel.SetAddress ( HostAddress ); - // extract address port before colon (should be actual internet address) - strNAddr = strNAddr.section ( ":", 0, 0 ); + return true; } - - // first try if this is an IP number an can directly applied to QHostAddress - if ( !InetAddr.setAddress ( strNAddr ) ) + else { - // it was no vaild IP address, try to get host by name, assuming - // that the string contains a valid host name string - QHostInfo HostInfo = QHostInfo::fromName ( strNAddr ); - - if ( HostInfo.error() == QHostInfo::NoError ) - { - // apply IP address to QT object - if ( !HostInfo.addresses().isEmpty() ) - { - // use the first IP address - InetAddr = HostInfo.addresses().first(); - } - } - else - { - return false; // invalid address - } + return false; // invalid address } - - // apply address (the server port is fixed and always the same) - Channel.SetAddress ( CHostAddress ( InetAddr, iNetPort ) ); - - return true; } void CClient::SetSndCrdPrefFrameSizeFactor ( const int iNewFactor ) diff --git a/src/main.cpp b/src/main.cpp index 68c506f5..7255bd91 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -57,8 +57,6 @@ int main ( int argc, char** argv ) bool bUseGUI = true; bool bConnectOnStartup = false; bool bDisalbeLEDs = false; - bool bIsCentralServer = false; - bool bServerListEnabled = false; quint16 iPortNumber = LLCON_DEFAULT_PORT_NUMBER; QString strIniFileName = ""; QString strHTMLStatusFileName = ""; @@ -250,12 +248,6 @@ int main ( int argc, char** argv ) // Dependencies ------------------------------------------------------------ - - -// TEST for implementation and debugging, always enable the server list -bServerListEnabled = true; - - // per definition: if we are in "GUI" server mode and no central server // address is given, we use the default central server address if ( !bIsClient && bUseGUI && strCentralServer.isEmpty() ) @@ -263,18 +255,6 @@ bServerListEnabled = true; strCentralServer = DEFAULT_SERVER_ADDRESS; } - // per definition: If we are in server mode and the central server address - // is the localhost address, we are in central server mode. For the central - // server, the server list is always enabled. - if ( !bIsClient && !strCentralServer.isEmpty() ) - { - bIsCentralServer = - ( !strCentralServer.toLower().compare ( "localhost" ) || - !strCentralServer.compare ( "127.0.0.1" ) ); - - bServerListEnabled = true; - } - // Application/GUI setup --------------------------------------------------- // Application object @@ -348,8 +328,6 @@ bServerListEnabled = true; strHTMLStatusFileName, strHistoryFileName, strServerName, - bServerListEnabled, - bIsCentralServer, strCentralServer ); if ( bUseGUI ) diff --git a/src/server.cpp b/src/server.cpp index f53823a4..12ce8e21 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -169,13 +169,10 @@ CServer::CServer ( const QString& strLoggingFileName, const QString& strHTMLStatusFileName, const QString& strHistoryFileName, const QString& strServerNameForHTMLStatusFile, - const bool bServerListEnabled, - const bool bIsCentralServer, const QString& strCentralServer ) : Socket ( this, iPortNumber ), bWriteStatusHTMLFile ( false ), - ServerListManager ( bServerListEnabled, - bIsCentralServer, + ServerListManager ( strCentralServer, &ConnLessProtocol ) { int i; diff --git a/src/server.h b/src/server.h index ad302a53..42a4a765 100755 --- a/src/server.h +++ b/src/server.h @@ -108,8 +108,6 @@ public: const QString& strHTMLStatusFileName, const QString& strHistoryFileName, const QString& strServerNameForHTMLStatusFile, - const bool bServerListEnabled, - const bool bIsCentralServer, const QString& strCentralServer ); void Start(); diff --git a/src/serverlist.cpp b/src/serverlist.cpp index bd127c66..d096ee58 100755 --- a/src/serverlist.cpp +++ b/src/serverlist.cpp @@ -26,12 +26,30 @@ /* Implementation *************************************************************/ -CServerListManager::CServerListManager ( const bool NbEbld, - const bool NbIsCentralServer, - CProtocol* pNConLProt ) - : bIsCentralServer ( NbIsCentralServer ), +CServerListManager::CServerListManager ( const QString& sNCentServAddr, + CProtocol* pNConLProt ) + : strCentralServerAddress ( sNCentServAddr ), pConnLessProtocol ( pNConLProt ) { + // per definition: If the central server address is empty, the server list + // is disabled. + // per definition: If we are in server mode and the central server address + // is the localhost address, we are in central server mode. For the central + // server, the server list is always enabled. + if ( !strCentralServerAddress.isEmpty() ) + { + bIsCentralServer = + ( !strCentralServerAddress.toLower().compare ( "localhost" ) || + !strCentralServerAddress.compare ( "127.0.0.1" ) ); + + bEnabled = true; + } + else + { + bIsCentralServer = false; + bEnabled = true; + } + // per definition, the very first entry is this server and this entry will // never be deleted ServerList.clear(); @@ -60,7 +78,7 @@ ServerList.append ( CServerListEntry ( // call set enable function after the connection of the timer since in this // function the timer gets started - SetEnabled ( NbEbld ); + SetEnabled ( bEnabled ); } void CServerListManager::SetEnabled ( const bool bState ) @@ -82,6 +100,14 @@ void CServerListManager::SetEnabled ( const bool bState ) // start timer for registering this server at the central server // 1 minute = 60 * 1000 ms TimerRegistering.start ( SERVLIST_REGIST_INTERV_MINUTES * 60000 ); + + +// TODO initiate a registration right away so we do not have to wait for the +// first time out of the timer +// TEST we cannot call RegisterServer directly since we would get a mutex dead lock +QTimer::singleShot(1, this, SLOT ( OnTimerRegistering() ) ); + + } } else @@ -215,12 +241,18 @@ void CServerListManager::OnTimerRegistering() if ( !bIsCentralServer && bEnabled ) { - // for the slave server, the slave server properties are store in the + // For the slave server, the slave server properties are store in the // very first item in the server list (which is actually no server list - // but just one item long for the slave server) - -// TODO - -// pConnLessProtocol->CreateCLRegisterServerMes (, ServerList[0] ); + // but just one item long for the slave server). + // Note that we always have to parse the server address again since if + // it is an URL of a dynamic IP address, the IP address might have + // changed in the meanwhile. + CHostAddress HostAddress; + if ( LlconNetwUtil().ParseNetworkAddress ( strCentralServerAddress, + HostAddress ) ) + { + pConnLessProtocol->CreateCLRegisterServerMes ( HostAddress, + ServerList[0] ); + } } } diff --git a/src/serverlist.h b/src/serverlist.h index ea5585c0..0e612874 100755 --- a/src/serverlist.h +++ b/src/serverlist.h @@ -125,9 +125,8 @@ class CServerListManager : public QObject Q_OBJECT public: - CServerListManager ( const bool NbEbld, - const bool NbIsCentralServer, - CProtocol* pNConLProt ); + CServerListManager ( const QString& sNCentServAddr, + CProtocol* pNConLProt ); void SetEnabled ( const bool bState ); bool GetEnabled() const { return bEnabled; } @@ -143,6 +142,7 @@ protected: QTimer TimerRegistering; QMutex Mutex; QList ServerList; + QString strCentralServerAddress; bool bEnabled; bool bIsCentralServer; diff --git a/src/util.cpp b/src/util.cpp index b90edd42..93d8c948 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -108,8 +108,8 @@ double CStereoSignalLevelMeter::CalcLogResult ( const double& dLinearLevel ) // CRC ------------------------------------------------------------------------- void CCRC::Reset() { - /* Init state shift-register with ones. Set all registers to "1" with - bit-wise not operation */ + // init state shift-register with ones. Set all registers to "1" with + // bit-wise not operation iStateShiftReg = ~uint32_t ( 0 ); } @@ -120,9 +120,9 @@ void CCRC::AddByte ( const uint8_t byNewInput ) // shift bits in shift-register for transistion iStateShiftReg <<= 1; - /* Take bit, which was shifted out of the register-size and place it - at the beginning (LSB) - (If condition is not satisfied, implicitely a "0" is added) */ + // take bit, which was shifted out of the register-size and place it + // at the beginning (LSB) + // (If condition is not satisfied, implicitely a "0" is added) if ( ( iStateShiftReg & iBitOutMask) > 0 ) { iStateShiftReg |= 1; @@ -300,7 +300,7 @@ double CAudioReverb::ProcessSample ( const double input ) /******************************************************************************\ -* GUI utilities * +* GUI Utilities * \******************************************************************************/ // About dialog ---------------------------------------------------------------- CAboutDlg::CAboutDlg ( QWidget* parent ) : QDialog ( parent ) @@ -417,7 +417,55 @@ CLlconHelpMenu::CLlconHelpMenu ( QWidget* parent ) : QMenu ( "&?", parent ) /******************************************************************************\ -* Global functions implementation * +* Other Classes * +\******************************************************************************/ +bool LlconNetwUtil::ParseNetworkAddress ( QString strAddress, + CHostAddress& HostAddress ) +{ + QHostAddress InetAddr; + quint16 iNetPort = LLCON_DEFAULT_PORT_NUMBER; + + // parse input address for the type [IP address]:[port number] + QString strPort = strAddress.section ( ":", 1, 1 ); + if ( !strPort.isEmpty() ) + { + // a colon is present in the address string, try to extract port number + iNetPort = strPort.toInt(); + + // extract address port before colon (should be actual internet address) + strAddress = strAddress.section ( ":", 0, 0 ); + } + + // first try if this is an IP number an can directly applied to QHostAddress + if ( !InetAddr.setAddress ( strAddress ) ) + { + // it was no vaild IP address, try to get host by name, assuming + // that the string contains a valid host name string + const QHostInfo HostInfo = QHostInfo::fromName ( strAddress ); + + if ( HostInfo.error() == QHostInfo::NoError ) + { + // apply IP address to QT object + if ( !HostInfo.addresses().isEmpty() ) + { + // use the first IP address + InetAddr = HostInfo.addresses().first(); + } + } + else + { + return false; // invalid address + } + } + + HostAddress = CHostAddress ( InetAddr, iNetPort ); + + return true; +} + + +/******************************************************************************\ +* Global Functions Implementation * \******************************************************************************/ void DebugError ( const QString& pchErDescr, const QString& pchPar1Descr, const double dPar1, const QString& pchPar2Descr, diff --git a/src/util.h b/src/util.h index dcc99390..05c12e60 100755 --- a/src/util.h +++ b/src/util.h @@ -26,6 +26,7 @@ #define UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_ #include +#include #include #include #include @@ -83,7 +84,7 @@ void DebugError ( const QString& pchErDescr, /******************************************************************************\ -* CVector base class * +* CVector Base Class * \******************************************************************************/ template class CVector : public std::vector { @@ -92,10 +93,10 @@ public: CVector ( const int iNeSi ) { Init(iNeSi); } CVector ( const int iNeSi, const TData tInVa ) { Init ( iNeSi, tInVa ); } - /* Copy constructor: The order of the initialization list must not be - changed. First, the base class must be initialized, then the pData - pointer must be set to the new data source. The bit access is, by - default, reset */ + // Copy constructor: The order of the initialization list must not be + // changed. First, the base class must be initialized, then the pData + // pointer must be set to the new data source. The bit access is, by + // default, reset. CVector ( const CVector& vecI ) : std::vector ( static_cast&> ( vecI ) ), iVectorSize ( vecI.Size() ) { pData = this->begin(); } @@ -111,8 +112,8 @@ public: inline int Size() const { return iVectorSize; } - /* This operator allows for a l-value assignment of this object: - CVector[x] = y is possible */ + // This operator allows for a l-value assignment of this object: + // CVector[x] = y is possible inline TData& operator[] ( const int iPos ) { #ifdef _DEBUG_ if ( ( iPos < 0 ) || ( iPos > iVectorSize - 1 ) ) @@ -135,9 +136,9 @@ public: inline CVector& operator= ( const CVector& vecI ) { #ifdef _DEBUG_ - /* Vectors which shall be copied MUST have same size! (If this is - satisfied, the parameter "iVectorSize" must not be adjusted as - a side effect) */ + // Vectors which shall be copied MUST have same size! (If this is + // satisfied, the parameter "iVectorSize" must not be adjusted as + // a side effect) if ( vecI.Size() != iVectorSize ) { DebugError ( "Vector operator=() different size", "Vector size", @@ -146,8 +147,8 @@ public: #endif vector::operator= ( vecI ); - /* Reset my data pointer in case, the operator=() of the base class - did change the actual memory */ + // reset my data pointer in case, the operator=() of the base class + // did change the actual memory pData = this->begin(); return *this; @@ -164,8 +165,8 @@ template void CVector::Init ( const int iNewSize ) { iVectorSize = iNewSize; - /* Clear old buffer and reserve memory for new buffer, get iterator - for pointer operations */ + // clear old buffer and reserve memory for new buffer, get iterator + // for pointer operations this->clear(); this->resize ( iNewSize ); pData = this->begin(); @@ -186,8 +187,8 @@ template void CVector::Enlarge ( const int iAddedSize ) iVectorSize += iAddedSize; this->resize ( iVectorSize ); - /* We have to reset the pointer since it could be that the vector size was - zero before enlarging the vector */ + // we have to reset the pointer since it could be that the vector size was + // zero before enlarging the vector pData = this->begin(); } @@ -202,7 +203,7 @@ template void CVector::Reset ( const TData tResetVal ) /******************************************************************************\ -* CFIFO class (first in, first out) * +* CFIFO Class (First In, First Out) * \******************************************************************************/ template class CFIFO : public CVector { @@ -249,7 +250,7 @@ template void CFIFO::Add ( const TData tNewD ) /******************************************************************************\ -* CMovingAv class (moving average) * +* CMovingAv Class (Moving Average) * \******************************************************************************/ template class CMovingAv : public CVector { @@ -307,7 +308,7 @@ template void CMovingAv::Add ( const TData tNewD ) /* Optimized calculation of the moving average. We only add a new value and subtract the old value from the result. We only need one addition and a - history buffer + history buffer. */ // subtract oldest value tCurAvResult -= this->pData[iCurIdx]; @@ -332,7 +333,7 @@ template void CMovingAv::Add ( const TData tNewD ) /******************************************************************************\ -* GUI utilities * +* GUI Utilities * \******************************************************************************/ // About dialog ---------------------------------------------------------------- class CAboutDlg : public QDialog, private Ui_CAboutDlgBase @@ -365,8 +366,10 @@ public slots: }; -/* Other Classes **************************************************************/ -// Stereo Signal Level Meter --------------------------------------------------- +/******************************************************************************\ +* Other Classes * +\******************************************************************************/ +// Stereo signal level meter --------------------------------------------------- class CStereoSignalLevelMeter { public: @@ -602,6 +605,15 @@ public: }; +// Network utility functions --------------------------------------------------- +class LlconNetwUtil +{ +public: + static bool ParseNetworkAddress ( QString strAddress, + CHostAddress& HostAddress ); +}; + + // Audio reverbration ---------------------------------------------------------- class CAudioReverb {