From fc0f1d6aaedeb6b8cb1c3ad648c3b20855c9c099 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Sat, 9 Dec 2006 10:04:27 +0000 Subject: [PATCH] fixed problem with receiving connected clients list on new connection --- src/channel.cpp | 213 ++++++++++++++++++++--------------- src/channel.h | 54 +++++---- src/client.cpp | 13 ++- src/clientsettingsdlgbase.ui | 8 +- src/global.h | 2 +- src/llconclientdlg.cpp | 3 +- src/protocol.cpp | 5 + 7 files changed, 174 insertions(+), 124 deletions(-) diff --git a/src/channel.cpp b/src/channel.cpp index 9e3e8c1e..fc439dfb 100755 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -30,6 +30,12 @@ \******************************************************************************/ CChannelSet::CChannelSet() { + // enable all channels + for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) + { + vecChannels[i].SetEnable ( true ); + } + // make sure we have MAX_NUM_CHANNELS connections!!! // send message QObject::connect(&vecChannels[0],SIGNAL(MessReadyForSending(CVector)),this,SLOT(OnSendProtMessCh0(CVector))); @@ -56,25 +62,24 @@ CChannelSet::CChannelSet() QObject::connect(&vecChannels[9],SIGNAL(NewConnection()),this,SLOT(OnNewConnectionCh9())); // request connected clients list - QObject::connect(&vecChannels[0],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh0())); - QObject::connect(&vecChannels[1],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh1())); - QObject::connect(&vecChannels[2],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh2())); - QObject::connect(&vecChannels[3],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh3())); - QObject::connect(&vecChannels[4],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh4())); - QObject::connect(&vecChannels[5],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh5())); - QObject::connect(&vecChannels[6],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh6())); - QObject::connect(&vecChannels[7],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh7())); - QObject::connect(&vecChannels[8],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh8())); - QObject::connect(&vecChannels[9],SIGNAL(ReqConnClientsList()),this,SLOT(OnNewConnectionCh9())); + QObject::connect(&vecChannels[0],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh0())); + QObject::connect(&vecChannels[1],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh1())); + QObject::connect(&vecChannels[2],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh2())); + QObject::connect(&vecChannels[3],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh3())); + QObject::connect(&vecChannels[4],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh4())); + QObject::connect(&vecChannels[5],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh5())); + QObject::connect(&vecChannels[6],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh6())); + QObject::connect(&vecChannels[7],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh7())); + QObject::connect(&vecChannels[8],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh8())); + QObject::connect(&vecChannels[9],SIGNAL(ReqConnClientsList()),this,SLOT(OnReqConnClientsListCh9())); } -void CChannelSet::CreateAndSendChanListForAllConClients() +CVector CChannelSet::CreateChannelList() { - int i; CVector vecChanInfo ( 0 ); // look for free channels - for ( i = 0; i < MAX_NUM_CHANNELS; i++ ) + for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { if ( vecChannels[i].IsConnected() ) { @@ -86,17 +91,35 @@ void CChannelSet::CreateAndSendChanListForAllConClients() } } - // now send connected channels list to all connected clients - for ( i = 0; i < MAX_NUM_CHANNELS; i++ ) + return vecChanInfo; +} + +void CChannelSet::CreateAndSendChanListForAllExceptThisChan ( const int iCurChanID ) +{ + // create channel list + CVector vecChanInfo ( CChannelSet::CreateChannelList() ); + + // now send connected channels list to all connected clients except for + // the channel with the ID "iCurChanID" + for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { - if ( vecChannels[i].IsConnected() ) + if ( ( vecChannels[i].IsConnected() ) && ( i != iCurChanID ) ) { // send message vecChannels[i].CreateConClientListMes ( vecChanInfo ); } } } - + +void CChannelSet::CreateAndSendChanListForThisChan ( const int iCurChanID ) +{ + // create channel list + CVector vecChanInfo ( CChannelSet::CreateChannelList() ); + + // now send connected channels list to the channel with the ID "iCurChanID" + vecChannels[iCurChanID].CreateConClientListMes ( vecChanInfo ); +} + int CChannelSet::GetFreeChan() { // look for a free channel @@ -216,18 +239,10 @@ bool CChannelSet::PutData ( const CVector& vecbyRecBuf, // requested if ( bCreateChanList ) { - - - -// TODO list is only send for new connected clients after request, only -// the already connected clients get the list automatically, because they -// don't know when new clients connect! - -// TODO use "void OnReqConnClientsListChx() {}" for sending list to specific client - -CreateAndSendChanListForAllConClients(); // <- replace this - - + // connected clients list is only send for new connected clients after + // request, only the already connected clients get the list + // automatically, because they don't know when new clients connect + CreateAndSendChanListForAllExceptThisChan ( iCurChanID ); } } Mutex.unlock(); @@ -384,6 +399,18 @@ CChannel::CChannel() : sName ( "" ), this, SLOT ( OnNetwBlSiFactChange ( int ) ) ); } +void CChannel::SetEnable ( const bool bNEnStat ) +{ + // set internal parameter + bIsEnabled = bNEnStat; + + // if channel is not enabled, reset time out count + if ( !bNEnStat ) + { + iConTimeOut = 0; + } +} + void CChannel::SetNetwInBlSiFact ( const int iNewBlockSizeFactor ) { // store new value @@ -491,37 +518,40 @@ bool CChannel::GetAddress(CHostAddress& RetAddr) EPutDataStat CChannel::PutData ( const CVector& vecbyData, int iNumBytes ) { - EPutDataStat eRet = PS_GEN_ERROR; - bool bNewConnection = false; - bool bIsAudioPacket = false; + EPutDataStat eRet = PS_GEN_ERROR; - // check if this is an audio packet by checking all possible lengths - for ( int i = 0; i < MAX_NET_BLOCK_SIZE_FACTOR; i++ ) + if ( bIsEnabled ) { - if ( iNumBytes == vecNetwInBufSizes[i] ) - { - bIsAudioPacket = true; + bool bNewConnection = false; + bool bIsAudioPacket = false; - // check if we are correctly initialized - const int iNewNetwInBlSiFact = i + 1; - if ( iNewNetwInBlSiFact != iCurNetwInBlSiFact ) + // check if this is an audio packet by checking all possible lengths + for ( int i = 0; i < MAX_NET_BLOCK_SIZE_FACTOR; i++ ) + { + if ( iNumBytes == vecNetwInBufSizes[i] ) { - // re-initialize to new value - SetNetwInBlSiFact ( iNewNetwInBlSiFact ); + bIsAudioPacket = true; + + // check if we are correctly initialized + const int iNewNetwInBlSiFact = i + 1; + if ( iNewNetwInBlSiFact != iCurNetwInBlSiFact ) + { + // re-initialize to new value + SetNetwInBlSiFact ( iNewNetwInBlSiFact ); + } } } - } - // only process if packet has correct size - if ( bIsAudioPacket ) - { - Mutex.lock(); - { - // decompress audio - CVector vecsDecomprAudio ( AudioCompressionIn.Decode ( vecbyData ) ); + // only process if packet has correct size + if ( bIsAudioPacket ) + { + Mutex.lock(); + { + // decompress audio + CVector vecsDecomprAudio ( AudioCompressionIn.Decode ( vecbyData ) ); - // do resampling to compensate for sample rate offsets in the - // different sound cards of the clients + // do resampling to compensate for sample rate offsets in the + // different sound cards of the clients /* for (int i = 0; i < BLOCK_SIZE_SAMPLES; i++) vecdResInData[i] = (double) vecsData[i]; @@ -535,55 +565,56 @@ for ( int i = 0; i < iCurNetwInBlSiFact * MIN_BLOCK_SIZE_SAMPLES; i++ ) { vecdResOutData[i] = (double) vecsDecomprAudio[i]; } - if ( SockBuf.Put ( vecdResOutData ) ) - { - eRet = PS_AUDIO_OK; - } - else - { - eRet = PS_AUDIO_ERR; - } + if ( SockBuf.Put ( vecdResOutData ) ) + { + eRet = PS_AUDIO_OK; + } + else + { + eRet = PS_AUDIO_ERR; + } - // check if channel was not connected, this is a new connection - bNewConnection = !IsConnected(); + // check if channel was not connected, this is a new connection + bNewConnection = !IsConnected(); - // reset time-out counter - iConTimeOut = iConTimeOutStartVal; - } - Mutex.unlock(); - } - else - { - // only use protocol data if channel is connected - if ( IsConnected() ) + // reset time-out counter + iConTimeOut = iConTimeOutStartVal; + } + Mutex.unlock(); + } + else { - // this seems not to be an audio block, parse the message - if ( Protocol.ParseMessage ( vecbyData, iNumBytes ) ) + // only use protocol data if channel is connected + if ( IsConnected() ) { - eRet = PS_PROT_OK; + // this seems not to be an audio block, parse the message + if ( Protocol.ParseMessage ( vecbyData, iNumBytes ) ) + { + eRet = PS_PROT_OK; - // create message for protocol status - emit ProtocolStatus ( true ); - } - else - { - eRet = PS_PROT_ERR; + // create message for protocol status + emit ProtocolStatus ( true ); + } + else + { + eRet = PS_PROT_ERR; - // create message for protocol status - emit ProtocolStatus ( false ); + // create message for protocol status + emit ProtocolStatus ( false ); + } } } - } - // inform other objects that new connection was established - if ( bNewConnection ) - { - // log new connection - CHostAddress address ( GetAddress() ); - qDebug ( CLogTimeDate::toString() + "Connected with IP %s", - address.InetAddr.toString().latin1() ); + // inform other objects that new connection was established + if ( bNewConnection ) + { + // log new connection + CHostAddress address ( GetAddress() ); + qDebug ( CLogTimeDate::toString() + "Connected with IP %s", + address.InetAddr.toString().latin1() ); - emit NewConnection(); + emit NewConnection(); + } } return eRet; diff --git a/src/channel.h b/src/channel.h index 832e362c..908f481c 100755 --- a/src/channel.h +++ b/src/channel.h @@ -36,17 +36,17 @@ /* Definitions ****************************************************************/ -/* Set the time-out for the input buffer until the state changes from - connected to not-connected (the actual time depends on the way the error - correction is implemented) */ -#define CON_TIME_OUT_SEC_MAX 5 // seconds +// Set the time-out for the input buffer until the state changes from +// connected to not-connected (the actual time depends on the way the error +// correction is implemented) +#define CON_TIME_OUT_SEC_MAX 5 // seconds -/* maximum number of internet connections (channels) */ +// maximum number of internet connections (channels) // if you want to change this paramter, change the connections in this class, too! -#define MAX_NUM_CHANNELS 10 /* max number channels for server */ +#define MAX_NUM_CHANNELS 10 /* max number channels for server */ -/* no valid channel number */ -#define INVALID_CHANNEL_ID (MAX_NUM_CHANNELS + 1) +// no valid channel number +#define INVALID_CHANNEL_ID (MAX_NUM_CHANNELS + 1) enum EPutDataStat { @@ -59,7 +59,7 @@ enum EPutDataStat /* Classes ********************************************************************/ -/* CChannel ----------------------------------------------------------------- */ +// CChannel -------------------------------------------------------------------- class CChannel : public QObject { Q_OBJECT @@ -75,6 +75,9 @@ public: CVector PrepSendPacket ( const CVector& vecsNPacket ); bool IsConnected() const { return iConTimeOut > 0; } + + void SetEnable ( const bool bNEnStat ); + bool IsEnabled() { return bIsEnabled; } void SetAddress ( const CHostAddress NAddr ) { InetAddr = NAddr; } bool GetAddress ( CHostAddress& RetAddr ); @@ -102,7 +105,7 @@ public: Protocol.CreateJitBufMes ( iJitBufSize ); } } - void CreateReqJitBufMes() { Protocol.CreateReqJitBufMes(); } + void CreateReqJitBufMes() { Protocol.CreateReqJitBufMes(); } void CreateReqConnClientsList() { Protocol.CreateReqConnClientsList(); } void CreateNetwBlSiFactMes ( const int iNetwBlSiFact ) @@ -155,6 +158,8 @@ protected: int iConTimeOut; int iConTimeOutStartVal; + bool bIsEnabled; + int vecNetwInBufSizes[MAX_NET_BLOCK_SIZE_FACTOR]; int iCurNetwInBlSiFact; @@ -178,7 +183,7 @@ signals: }; -/* CChannelSet (for server) ------------------------------------------------- */ +// CChannelSet (for server) ---------------------------------------------------- class CChannelSet : public QObject { Q_OBJECT @@ -203,7 +208,7 @@ public: CVector& veciNetwOutBlSiFact, CVector& veciNetwInBlSiFact ); - /* access functions for actual channels */ + // access functions for actual channels bool IsConnected ( const int iChanNum ) { return vecChannels[iChanNum].IsConnected(); } @@ -215,7 +220,9 @@ public: { return vecChannels[iChanNum].GetAddress(); } protected: - void CreateAndSendChanListForAllConClients(); + CVector CreateChannelList(); + void CreateAndSendChanListForAllExceptThisChan ( const int iCurChanID ); + void CreateAndSendChanListForThisChan ( const int iCurChanID ); /* do not use the vector class since CChannel does not have appropriate copy constructor/operator */ @@ -247,17 +254,16 @@ public slots: void OnNewConnectionCh8() {vecChannels[8].CreateReqJitBufMes();} void OnNewConnectionCh9() {vecChannels[9].CreateReqJitBufMes();} -// TODO - void OnReqConnClientsListCh0() {} - void OnReqConnClientsListCh1() {} - void OnReqConnClientsListCh2() {} - void OnReqConnClientsListCh3() {} - void OnReqConnClientsListCh4() {} - void OnReqConnClientsListCh5() {} - void OnReqConnClientsListCh6() {} - void OnReqConnClientsListCh7() {} - void OnReqConnClientsListCh8() {} - void OnReqConnClientsListCh9() {} + void OnReqConnClientsListCh0() { CreateAndSendChanListForThisChan ( 0 ); } + void OnReqConnClientsListCh1() { CreateAndSendChanListForThisChan ( 1 ); } + void OnReqConnClientsListCh2() { CreateAndSendChanListForThisChan ( 2 ); } + void OnReqConnClientsListCh3() { CreateAndSendChanListForThisChan ( 3 ); } + void OnReqConnClientsListCh4() { CreateAndSendChanListForThisChan ( 4 ); } + void OnReqConnClientsListCh5() { CreateAndSendChanListForThisChan ( 5 ); } + void OnReqConnClientsListCh6() { CreateAndSendChanListForThisChan ( 6 ); } + void OnReqConnClientsListCh7() { CreateAndSendChanListForThisChan ( 7 ); } + void OnReqConnClientsListCh8() { CreateAndSendChanListForThisChan ( 8 ); } + void OnReqConnClientsListCh9() { CreateAndSendChanListForThisChan ( 9 ); } signals: void MessReadyForSending ( int iChID, CVector vecMessage ); diff --git a/src/client.cpp b/src/client.cpp index fb24801c..6d12e638 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -46,6 +46,9 @@ CClient::CClient() : bRun ( false ), Socket ( &Channel ), QObject::connect ( &Channel, SIGNAL ( ConClientListMesReceived ( CVector ) ), SIGNAL ( ConClientListMesReceived ( CVector ) ) ); + + QObject::connect ( &Channel, SIGNAL ( NewConnection() ), + this, SLOT ( OnNewConnection() ) ); } void CClient::OnSendProtMessage ( CVector vecMessage ) @@ -162,7 +165,10 @@ void CClient::run() Init(); - // runtime phase ------------------------------------------------------------ + // runtime phase ------------------------------------------------------------ + // enable channel + Channel.SetEnable ( true ); + bRun = true; // main loop of working thread @@ -380,6 +386,9 @@ fflush(pFileTest); // store old time value TimeLastBlock = CurTime; } + + // disable channel + Channel.SetEnable ( false ); // reset current signal level and LEDs SignalLevelMeterL.Reset(); @@ -390,7 +399,7 @@ fflush(pFileTest); bool CClient::Stop() { // set flag so that thread can leave the main loop - bRun = false; + bRun = false; // give thread some time to terminate, return status return wait ( 5000 ); diff --git a/src/clientsettingsdlgbase.ui b/src/clientsettingsdlgbase.ui index ff751afb..f1911625 100755 --- a/src/clientsettingsdlgbase.ui +++ b/src/clientsettingsdlgbase.ui @@ -11,8 +11,8 @@ 0 0 - 410 - 249 + 404 + 294 @@ -381,7 +381,7 @@ sizePolicy - 1 + 3 1 @@ -449,7 +449,7 @@ sizePolicy - 1 + 3 1 diff --git a/src/global.h b/src/global.h index a5e5232f..f4a3c45e 100755 --- a/src/global.h +++ b/src/global.h @@ -42,7 +42,7 @@ /* version and application name (always use this version) */ #undef VERSION -#define VERSION "0.9.8cvs" +#define VERSION "0.9.9cvs" #define APP_NAME "llcon" diff --git a/src/llconclientdlg.cpp b/src/llconclientdlg.cpp index ae736d0f..20cb660f 100755 --- a/src/llconclientdlg.cpp +++ b/src/llconclientdlg.cpp @@ -242,13 +242,12 @@ void CLlconClientDlg::OnConnectDisconBut () // TEST -/* // make old controls invisible for ( int i = 0; i < MAX_NUM_CHANNELS; i++ ) { vecpChanFader[i]->Hide(); } -*/ + } diff --git a/src/protocol.cpp b/src/protocol.cpp index b15e5ed2..2a192cb2 100755 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -338,6 +338,11 @@ for ( int i = 0; i < iNumBytes; i++ ) { EvaluateConClientListMes ( iPos, vecData ); break; + + case PROTMESSID_REQ_CONN_CLIENTS_LIST: + + EvaluateReqConnClientsList ( iPos, vecData ); + break; } // send acknowledge message