/******************************************************************************\ * Copyright (c) 2004-2020 * * Author(s): * Volker Fischer * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * \******************************************************************************/ #pragma once #include #include #include #include #include #include "global.h" #include "socket.h" #include "protocol.h" #include "util.h" /* Classes ********************************************************************/ class CTestbench : public QObject { Q_OBJECT public: CTestbench ( QString sNewAddress, quint16 iNewPort ) : sAddress ( sNewAddress ), iPort ( iNewPort ) { sLAddress = GenRandomIPv4Address().toString(); iLPort = static_cast ( GenRandomIntInRange ( -2, 10000 ) ); // bind socket (try 100 port numbers) quint16 iPortIncrement = 0; // start value: port number plus ten bool bSuccess = false; // initialization for while loop while ( !bSuccess && ( iPortIncrement <= 100 ) ) { bSuccess = UdpSocket.bind ( QHostAddress( QHostAddress::Any ), 22222 + iPortIncrement ); iPortIncrement++; } // connect protocol signals QObject::connect ( &Protocol, &CProtocol::MessReadyForSending, this, &CTestbench::OnSendProtMessage ); QObject::connect ( &Protocol, &CProtocol::CLMessReadyForSending, this, &CTestbench::OnSendCLMessage ); // connect and start the timer (testbench heartbeat) QObject::connect ( &Timer, &QTimer::timeout, this, &CTestbench::OnTimer ); Timer.start ( 1 ); // 1 ms } protected: int GenRandomIntInRange ( const int iStart, const int iEnd ) const { return static_cast ( iStart + ( ( static_cast ( iEnd - iStart + 1 ) * rand() ) / RAND_MAX ) ); } QString GenRandomString() const { const int iLen = GenRandomIntInRange ( 0, 111 ); QString strReturn = ""; for ( int i = 0; i < iLen; i++ ) { strReturn += static_cast ( GenRandomIntInRange ( 0, 255 ) ); } return strReturn; } QHostAddress GenRandomIPv4Address() const { quint32 a = static_cast ( 192 ); quint32 b = static_cast ( 168 ); quint32 c = static_cast ( GenRandomIntInRange ( 1, 253 ) ); quint32 d = static_cast ( GenRandomIntInRange ( 1, 253 ) ); return QHostAddress( a << 24 | b << 16 | c << 8 | d ); } QString sAddress; quint16 iPort; QString sLAddress; quint16 iLPort; QTimer Timer; CProtocol Protocol; QUdpSocket UdpSocket; public slots: void OnTimer() { CVector vecChanInfo ( 1 ); CNetworkTransportProps NetTrProps; CServerCoreInfo ServerInfo; CVector vecServerInfo ( 1 ); CVector vecLevelList ( 1 ); CHostAddress CurHostAddress ( QHostAddress ( sAddress ), iPort ); CHostAddress CurLocalAddress ( QHostAddress ( sLAddress ), iLPort ); CChannelCoreInfo ChannelCoreInfo; ELicenceType eLicenceType; ESvrRegResult eSvrRegResult; // generate random protocol message switch ( GenRandomIntInRange ( 0, 34 ) ) { case 0: // PROTMESSID_JITT_BUF_SIZE Protocol.CreateJitBufMes ( GenRandomIntInRange ( 0, 10 ) ); break; case 1: // PROTMESSID_REQ_JITT_BUF_SIZE Protocol.CreateReqJitBufMes(); break; case 2: // PROTMESSID_CHANNEL_GAIN Protocol.CreateChanGainMes ( GenRandomIntInRange ( 0, 20 ), GenRandomIntInRange ( -100, 100 ) ); break; case 4: // PROTMESSID_CONN_CLIENTS_LIST vecChanInfo[0].iChanID = GenRandomIntInRange ( -2, 20 ); vecChanInfo[0].iIpAddr = GenRandomIPv4Address().toIPv4Address(); vecChanInfo[0].strName = GenRandomString(); Protocol.CreateConClientListMes ( vecChanInfo ); break; case 5: // PROTMESSID_REQ_CONN_CLIENTS_LIST Protocol.CreateReqConnClientsList(); break; case 7: // PROTMESSID_CHANNEL_INFOS ChannelCoreInfo.eCountry = static_cast ( GenRandomIntInRange ( 0, 100 ) ); ChannelCoreInfo.eSkillLevel = static_cast ( GenRandomIntInRange ( 0, 3 ) ); ChannelCoreInfo.iInstrument = GenRandomIntInRange ( 0, 100 ); ChannelCoreInfo.strCity = GenRandomString(); ChannelCoreInfo.strName = GenRandomString(); Protocol.CreateChanInfoMes ( ChannelCoreInfo ); break; case 8: // PROTMESSID_REQ_CHANNEL_INFOS Protocol.CreateReqChanInfoMes(); break; case 9: // PROTMESSID_CHAT_TEXT Protocol.CreateChatTextMes ( GenRandomString() ); break; case 10: // PROTMESSID_LICENCE_REQUIRED eLicenceType = static_cast ( GenRandomIntInRange ( 0, 1 ) ); Protocol.CreateLicenceRequiredMes ( eLicenceType ); break; case 11: // PROTMESSID_NETW_TRANSPORT_PROPS NetTrProps.eAudioCodingType = static_cast ( GenRandomIntInRange ( 0, 2 ) ); NetTrProps.iAudioCodingArg = GenRandomIntInRange ( -100, 100 ); NetTrProps.iBaseNetworkPacketSize = GenRandomIntInRange ( -2, 1000 ); NetTrProps.iBlockSizeFact = GenRandomIntInRange ( -2, 100 ); NetTrProps.iNumAudioChannels = GenRandomIntInRange ( -2, 10 ); NetTrProps.iSampleRate = GenRandomIntInRange ( -2, 10000 ); NetTrProps.iVersion = GenRandomIntInRange ( -2, 10000 ); Protocol.CreateNetwTranspPropsMes ( NetTrProps ); break; case 12: // PROTMESSID_REQ_NETW_TRANSPORT_PROPS Protocol.CreateReqNetwTranspPropsMes(); break; case 14: // PROTMESSID_CLM_PING_MS Protocol.CreateCLPingMes ( CurHostAddress, GenRandomIntInRange ( -2, 1000 ) ); break; case 15: // PROTMESSID_CLM_PING_MS_WITHNUMCLIENTS Protocol.CreateCLPingWithNumClientsMes ( CurHostAddress, GenRandomIntInRange ( -2, 1000 ), GenRandomIntInRange ( -2, 1000 ) ); break; case 16: // PROTMESSID_CLM_SERVER_FULL Protocol.CreateCLServerFullMes ( CurHostAddress ); break; case 17: // PROTMESSID_CLM_REGISTER_SERVER ServerInfo.bPermanentOnline = static_cast ( GenRandomIntInRange ( 0, 1 ) ); ServerInfo.eCountry = static_cast ( GenRandomIntInRange ( 0, 100 ) ); ServerInfo.iMaxNumClients = GenRandomIntInRange ( -2, 10000 ); ServerInfo.strCity = GenRandomString(); ServerInfo.strName = GenRandomString(); Protocol.CreateCLRegisterServerMes ( CurHostAddress, CurLocalAddress, ServerInfo ); break; case 18: // PROTMESSID_CLM_UNREGISTER_SERVER Protocol.CreateCLUnregisterServerMes ( CurHostAddress ); break; case 19: // PROTMESSID_CLM_SERVER_LIST vecServerInfo[0].bPermanentOnline = static_cast ( GenRandomIntInRange ( 0, 1 ) ); vecServerInfo[0].eCountry = static_cast ( GenRandomIntInRange ( 0, 100 ) ); vecServerInfo[0].HostAddr = CurHostAddress; vecServerInfo[0].LHostAddr = CurLocalAddress; vecServerInfo[0].iMaxNumClients = GenRandomIntInRange ( -2, 10000 ); vecServerInfo[0].strCity = GenRandomString(); vecServerInfo[0].strName = GenRandomString(); Protocol.CreateCLServerListMes ( CurHostAddress, vecServerInfo ); break; case 20: // PROTMESSID_CLM_REQ_SERVER_LIST Protocol.CreateCLReqServerListMes ( CurHostAddress ); break; case 21: // PROTMESSID_CLM_SEND_EMPTY_MESSAGE Protocol.CreateCLSendEmptyMesMes ( CurHostAddress, CurHostAddress ); break; case 22: // PROTMESSID_CLM_EMPTY_MESSAGE Protocol.CreateCLEmptyMes ( CurHostAddress ); break; case 23: // PROTMESSID_CLM_DISCONNECTION Protocol.CreateCLDisconnection ( CurHostAddress ); break; case 24: // PROTMESSID_CLM_VERSION_AND_OS Protocol.CreateCLVersionAndOSMes ( CurHostAddress ); break; case 25: // PROTMESSID_CLM_REQ_VERSION_AND_OS Protocol.CreateCLReqVersionAndOSMes ( CurHostAddress ); break; case 26: // PROTMESSID_ACKN Protocol.CreateAndImmSendAcknMess ( GenRandomIntInRange ( -10, 100 ), GenRandomIntInRange ( -100, 100 ) ); break; case 27: { // arbitrary "audio" packet (with random sizes) CVector vecMessage ( GenRandomIntInRange ( 1, 1000 ) ); OnSendProtMessage ( vecMessage ); break; } case 28: // PROTMESSID_CLM_CONN_CLIENTS_LIST vecChanInfo[0].iChanID = GenRandomIntInRange ( -2, 20 ); vecChanInfo[0].iIpAddr = GenRandomIPv4Address().toIPv4Address(); vecChanInfo[0].strName = GenRandomString(); Protocol.CreateCLConnClientsListMes ( CurHostAddress, vecChanInfo ); break; case 29: // PROTMESSID_CLM_REQ_CONN_CLIENTS_LIST Protocol.CreateCLReqConnClientsListMes ( CurHostAddress ); break; case 30: // PROTMESSID_CLM_CHANNEL_LEVEL_LIST vecLevelList[0] = GenRandomIntInRange ( 0, 0xF ); Protocol.CreateCLChannelLevelListMes ( CurHostAddress, vecLevelList, 1 ); break; case 31: // PROTMESSID_CLM_REGISTER_SERVER_RESP eSvrRegResult = static_cast ( GenRandomIntInRange ( 0, 1 ) ); Protocol.CreateCLRegisterServerResp ( CurHostAddress, eSvrRegResult ); break; case 32: // PROTMESSID_CHANNEL_PAN Protocol.CreateChanPanMes ( GenRandomIntInRange ( -2, 20 ), GenRandomIntInRange ( 0, 32767 ) ); break; case 33: // PROTMESSID_MUTE_STATE_CHANGED Protocol.CreateMuteStateHasChangedMes ( GenRandomIntInRange ( -2, 20 ), GenRandomIntInRange ( 0, 1 ) ); break; case 34: // PROTMESSID_CLIENT_ID Protocol.CreateClientIDMes ( GenRandomIntInRange ( -2, 20 ) ); break; } } void OnSendProtMessage ( CVector vecMessage ) { UdpSocket.writeDatagram ( (const char*) &( (CVector) vecMessage )[0], vecMessage.Size(), QHostAddress ( sAddress ), iPort ); // reset protocol so that we do not have to wait for an acknowledge to // send the next message Protocol.Reset(); } void OnSendCLMessage ( CHostAddress, CVector vecMessage ) { OnSendProtMessage ( vecMessage ); } };