removed channel set class and moved resulting code in server class -> not yet compilable

This commit is contained in:
Volker Fischer 2009-07-26 20:12:22 +00:00
parent 1c4f06ff5e
commit 31efe7e92d
9 changed files with 660 additions and 738 deletions

View file

@ -25,532 +25,6 @@
#include "channel.h"
/******************************************************************************\
* CChannelSet *
\******************************************************************************/
CChannelSet::CChannelSet() :
bWriteStatusHTMLFile ( false )
{
// enable all channels (for the server all channel must be enabled the
// entire life time of the software
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
vecChannels[i].SetEnable ( true );
}
// define colors for chat window identifiers
vstrChatColors.Init ( 6 );
vstrChatColors[0] = "mediumblue";
vstrChatColors[1] = "red";
vstrChatColors[2] = "darkorchid";
vstrChatColors[3] = "green";
vstrChatColors[4] = "maroon";
vstrChatColors[5] = "coral";
// CODE TAG: MAX_NUM_CHANNELS_TAG
// make sure we have MAX_NUM_CHANNELS connections!!!
// send message
QObject::connect ( &vecChannels[0], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh0 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[1], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh1 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[2], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh2 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[3], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh3 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[4], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh4 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[5], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh5 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[6], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh6 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[7], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh7 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[8], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh8 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[9], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh9 ( CVector<uint8_t> ) ) );
// request jitter buffer size
QObject::connect ( &vecChannels[0], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh0() ) );
QObject::connect ( &vecChannels[1], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh1() ) );
QObject::connect ( &vecChannels[2], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh2() ) );
QObject::connect ( &vecChannels[3], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh3() ) );
QObject::connect ( &vecChannels[4], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh4() ) );
QObject::connect ( &vecChannels[5], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh5() ) );
QObject::connect ( &vecChannels[6], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh6() ) );
QObject::connect ( &vecChannels[7], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh7() ) );
QObject::connect ( &vecChannels[8], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh8() ) );
QObject::connect ( &vecChannels[9], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh9() ) );
// request connected clients list
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() ) );
// channel name has changed
QObject::connect ( &vecChannels[0], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh0() ) );
QObject::connect ( &vecChannels[1], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh1() ) );
QObject::connect ( &vecChannels[2], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh2() ) );
QObject::connect ( &vecChannels[3], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh3() ) );
QObject::connect ( &vecChannels[4], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh4() ) );
QObject::connect ( &vecChannels[5], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh5() ) );
QObject::connect ( &vecChannels[6], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh6() ) );
QObject::connect ( &vecChannels[7], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh7() ) );
QObject::connect ( &vecChannels[8], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh8() ) );
QObject::connect ( &vecChannels[9], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh9() ) );
// chat text received
QObject::connect ( &vecChannels[0], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh0 ( QString ) ) );
QObject::connect ( &vecChannels[1], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh1 ( QString ) ) );
QObject::connect ( &vecChannels[2], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh2 ( QString ) ) );
QObject::connect ( &vecChannels[3], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh3 ( QString ) ) );
QObject::connect ( &vecChannels[4], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh4 ( QString ) ) );
QObject::connect ( &vecChannels[5], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh5 ( QString ) ) );
QObject::connect ( &vecChannels[6], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh6 ( QString ) ) );
QObject::connect ( &vecChannels[7], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh7 ( QString ) ) );
QObject::connect ( &vecChannels[8], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh8 ( QString ) ) );
QObject::connect ( &vecChannels[9], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh9 ( QString ) ) );
// ping message received
QObject::connect ( &vecChannels[0], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh0 ( int ) ) );
QObject::connect ( &vecChannels[1], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh1 ( int ) ) );
QObject::connect ( &vecChannels[2], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh2 ( int ) ) );
QObject::connect ( &vecChannels[3], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh3 ( int ) ) );
QObject::connect ( &vecChannels[4], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh4 ( int ) ) );
QObject::connect ( &vecChannels[5], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh5 ( int ) ) );
QObject::connect ( &vecChannels[6], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh6 ( int ) ) );
QObject::connect ( &vecChannels[7], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh7 ( int ) ) );
QObject::connect ( &vecChannels[8], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh8 ( int ) ) );
QObject::connect ( &vecChannels[9], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh9 ( int ) ) );
}
CVector<CChannelShortInfo> CChannelSet::CreateChannelList()
{
CVector<CChannelShortInfo> vecChanInfo ( 0 );
// look for free channels
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
// append channel ID, IP address and channel name to storing vectors
vecChanInfo.Add ( CChannelShortInfo (
i, // ID
vecChannels[i].GetAddress().InetAddr.toIPv4Address(), // IP address
vecChannels[i].GetName() /* name */ ) );
}
}
return vecChanInfo;
}
void CChannelSet::CreateAndSendChanListForAllConChannels()
{
// create channel list
CVector<CChannelShortInfo> vecChanInfo ( CChannelSet::CreateChannelList() );
// now send connected channels list to all connected clients
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
// send message
vecChannels[i].CreateConClientListMes ( vecChanInfo );
}
}
// create status HTML file if enabled
if ( bWriteStatusHTMLFile )
{
WriteHTMLChannelList();
}
}
void CChannelSet::CreateAndSendChanListForAllExceptThisChan ( const int iCurChanID )
{
// create channel list
CVector<CChannelShortInfo> 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 < USED_NUM_CHANNELS; i++ )
{
if ( ( vecChannels[i].IsConnected() ) && ( i != iCurChanID ) )
{
// send message
vecChannels[i].CreateConClientListMes ( vecChanInfo );
}
}
// create status HTML file if enabled
if ( bWriteStatusHTMLFile )
{
WriteHTMLChannelList();
}
}
void CChannelSet::CreateAndSendChanListForThisChan ( const int iCurChanID )
{
// create channel list
CVector<CChannelShortInfo> vecChanInfo ( CChannelSet::CreateChannelList() );
// now send connected channels list to the channel with the ID "iCurChanID"
vecChannels[iCurChanID].CreateConClientListMes ( vecChanInfo );
}
void CChannelSet::CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
const QString& strChatText )
{
// create message which is sent to all connected clients -------------------
// get client name, if name is empty, use IP address instead
QString ChanName = vecChannels[iCurChanID].GetName();
if ( ChanName.isEmpty() )
{
// convert IP address to text and show it
ChanName =
vecChannels[iCurChanID].GetAddress().GetIpAddressStringNoLastByte();
}
// add name of the client at the beginning of the message text and use
// different colors, to get correct HTML, the "<" and ">" signs must be
// replaced by "&#60;" and "&#62;"
QString sCurColor = vstrChatColors[iCurChanID % vstrChatColors.Size()];
const QString strActualMessageText =
"<font color=""" + sCurColor + """><b>&#60;" + ChanName +
"&#62;</b></font> " + strChatText;
// send chat text to all connected clients ---------------------------------
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
// send message
vecChannels[i].CreateChatTextMes ( strActualMessageText );
}
}
}
int CChannelSet::GetFreeChan()
{
// look for a free channel
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( !vecChannels[i].IsConnected() )
{
return i;
}
}
// no free channel found, return invalid ID
return INVALID_CHANNEL_ID;
}
int CChannelSet::CheckAddr ( const CHostAddress& Addr )
{
CHostAddress InetAddr;
// check for all possible channels if IP is already in use
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
if ( vecChannels[i].GetAddress ( InetAddr ) )
{
// IP found, return channel number
if ( InetAddr == Addr )
{
return i;
}
}
}
}
// IP not found, return invalid ID
return INVALID_CHANNEL_ID;
}
bool CChannelSet::PutData ( const CVector<uint8_t>& vecbyRecBuf,
const int iNumBytesRead,
const CHostAddress& HostAdr )
{
bool bAudioOK = false;
bool bNewChannelReserved = false;
Mutex.lock();
{
bool bChanOK = true;
// Get channel ID ------------------------------------------------------
// check address
int iCurChanID = CheckAddr ( HostAdr );
if ( iCurChanID == INVALID_CHANNEL_ID )
{
// a new client is calling, look for free channel
iCurChanID = GetFreeChan();
if ( iCurChanID != INVALID_CHANNEL_ID )
{
// initialize current channel by storing the calling host
// address
vecChannels[iCurChanID].SetAddress ( HostAdr );
// reset the channel gains of current channel, at the same
// time reset gains of this channel ID for all other channels
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
vecChannels[iCurChanID].SetGain ( i, (double) 1.0 );
// other channels (we do not distinguish the case if
// i == iCurChanID for simplicity)
vecChannels[i].SetGain ( iCurChanID, (double) 1.0 );
}
// set flag for new reserved channel
bNewChannelReserved = true;
}
else
{
// no free channel available
bChanOK = false;
// create and send "server full" message
// TODO problem: if channel is not officially connected, we cannot send messages
}
}
// Put received data in jitter buffer ----------------------------------
if ( bChanOK )
{
// put packet in socket buffer
switch ( vecChannels[iCurChanID].PutData ( vecbyRecBuf, iNumBytesRead ) )
{
case PS_AUDIO_OK:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN, iCurChanID );
bAudioOK = true; // in case we have an audio packet, return true
break;
case PS_AUDIO_ERR:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED, iCurChanID );
bAudioOK = true; // in case we have an audio packet, return true
break;
case PS_PROT_ERR:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW, iCurChanID );
// TEST
bAudioOK = true;
break;
}
}
// after data is put in channel buffer, create channel list message if
// requested
if ( bNewChannelReserved && bAudioOK )
{
// send message about new channel
emit ChannelConnected ( HostAdr );
// A new client connected to the server, create and
// send all clients the updated channel list (the list has to
// be created after the received data has to be put to the
// channel first so that this channel is marked as connected)
//
// 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();
return bAudioOK;
}
void CChannelSet::GetBlockAllConC ( CVector<int>& vecChanID,
CVector<CVector<double> >& vecvecdData,
CVector<CVector<double> >& vecvecdGains )
{
int i, j;
bool bChannelIsNowDisconnected = false;
// init temporal data vector and clear input buffers
CVector<double> vecdData ( SYSTEM_BLOCK_SIZE_SAMPLES );
vecChanID.Init ( 0 );
vecvecdData.Init ( 0 );
vecvecdGains.Init ( 0 );
// make put and get calls thread safe. Do not forget to unlock mutex
// afterwards!
Mutex.lock();
{
// check all possible channels
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
{
// read out all input buffers to decrease timeout counter on
// disconnected channels
// const EGetDataStat eGetStat = vecChannels[i].GetData ( vecdData );
const EGetDataStat eGetStat=GS_BUFFER_OK;//TEST
// if channel was just disconnected, set flag that connected
// client list is sent to all other clients
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
{
bChannelIsNowDisconnected = true;
}
if ( vecChannels[i].IsConnected() )
{
// add ID and data
vecChanID.Add ( i );
const int iOldSize = vecvecdData.Size();
vecvecdData.Enlarge ( 1 );
vecvecdData[iOldSize].Init ( vecdData.Size() );
vecvecdData[iOldSize] = vecdData;
// send message for get status (for GUI)
if ( eGetStat == GS_BUFFER_OK )
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN, i );
}
else
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED, i );
}
}
}
// now that we know the IDs of the connected clients, get gains
const int iNumCurConnChan = vecChanID.Size();
vecvecdGains.Init ( iNumCurConnChan );
for ( i = 0; i < iNumCurConnChan; i++ )
{
vecvecdGains[i].Init ( iNumCurConnChan );
for ( j = 0; j < iNumCurConnChan; j++ )
{
// The second index of "vecvecdGains" does not represent
// the channel ID! Therefore we have to use "vecChanID" to
// query the IDs of the currently connected channels
vecvecdGains[i][j] =
vecChannels[vecChanID[i]].GetGain( vecChanID[j] );
}
}
// a channel is now disconnected, take action on it
if ( bChannelIsNowDisconnected )
{
// update channel list for all currently connected clients
CreateAndSendChanListForAllConChannels();
}
}
Mutex.unlock(); // release mutex
}
void CChannelSet::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
CVector<QString>& vecsName,
CVector<int>& veciJitBufSize,
CVector<int>& veciNetwOutBlSiFact )
{
CHostAddress InetAddr;
// init return values
vecHostAddresses.Init ( USED_NUM_CHANNELS );
vecsName.Init ( USED_NUM_CHANNELS );
veciJitBufSize.Init ( USED_NUM_CHANNELS );
veciNetwOutBlSiFact.Init ( USED_NUM_CHANNELS );
// check all possible channels
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].GetAddress ( InetAddr ) )
{
// get requested data
vecHostAddresses[i] = InetAddr;
vecsName[i] = vecChannels[i].GetName();
veciJitBufSize[i] = vecChannels[i].GetSockBufSize();
veciNetwOutBlSiFact[i] = vecChannels[i].GetNetwBufSizeFactOut();
}
}
}
void CChannelSet::StartStatusHTMLFileWriting ( const QString& strNewFileName,
const QString& strNewServerNameWithPort )
{
// set important parameters
strServerHTMLFileListName = strNewFileName;
strServerNameWithPort = strNewServerNameWithPort;
// set flag
bWriteStatusHTMLFile = true;
// write initial file
WriteHTMLChannelList();
}
void CChannelSet::WriteHTMLChannelList()
{
// create channel list
CVector<CChannelShortInfo> vecChanInfo ( CChannelSet::CreateChannelList() );
// prepare file and stream
QFile serverFileListFile ( strServerHTMLFileListName );
if ( !serverFileListFile.open ( QIODevice::WriteOnly | QIODevice::Text ) )
{
return;
}
QTextStream streamFileOut ( &serverFileListFile );
streamFileOut << strServerNameWithPort << endl << "<ul>" << endl;
// get the number of connected clients
int iNumConnClients = 0;
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
iNumConnClients++;
}
}
// depending on number of connected clients write list
if ( iNumConnClients == 0 )
{
// no clients are connected -> empty server
streamFileOut << " No client connected" << endl;
}
else
{
// write entry for each connected client
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
QString strCurChanName = vecChannels[i].GetName();
// if text is empty, show IP address instead
if ( strCurChanName.isEmpty() )
{
// convert IP address to text and show it, remove last
// digits
strCurChanName =
vecChannels[i].GetAddress().GetIpAddressStringNoLastByte();
}
streamFileOut << " <li>" << strCurChanName << "</li>" << endl;
}
}
}
// finish list
streamFileOut << "</ul>" << endl;
}

View file

@ -41,9 +41,6 @@
// correction is implemented)
#define CON_TIME_OUT_SEC_MAX 60 // seconds
// no valid channel number
#define INVALID_CHANNEL_ID ( MAX_NUM_CHANNELS + 1 )
enum EPutDataStat
{
PS_GEN_ERROR,
@ -53,17 +50,8 @@ enum EPutDataStat
PS_PROT_ERR
};
enum EGetDataStat
{
GS_BUFFER_OK,
GS_BUFFER_UNDERRUN,
GS_CHAN_NOW_DISCONNECTED,
GS_CHAN_NOT_CONNECTED
};
/* Classes ********************************************************************/
// CChannel --------------------------------------------------------------------
class CChannel : public QObject
{
Q_OBJECT
@ -205,139 +193,4 @@ signals:
void ReqNetTranspProps();
};
// CChannelSet (for server) ----------------------------------------------------
class CChannelSet : public QObject
{
Q_OBJECT
public:
CChannelSet();
virtual ~CChannelSet() {}
bool PutData ( const CVector<uint8_t>& vecbyRecBuf,
const int iNumBytesRead, const CHostAddress& HostAdr );
int GetFreeChan();
int CheckAddr ( const CHostAddress& Addr );
void GetBlockAllConC ( CVector<int>& vecChanID,
CVector<CVector<double> >& vecvecdData,
CVector<CVector<double> >& vecvecdGains );
void GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
CVector<QString>& vecsName,
CVector<int>& veciJitBufSize,
CVector<int>& veciNetwOutBlSiFact );
// access functions for actual channels
bool IsConnected ( const int iChanNum )
{ return vecChannels[iChanNum].IsConnected(); }
CVector<uint8_t> PrepSendPacket ( const int iChanNum,
const CVector<short>& vecsNPacket )
{ return vecChannels[iChanNum].PrepSendPacket ( vecsNPacket ); }
CHostAddress GetAddress ( const int iChanNum )
{ return vecChannels[iChanNum].GetAddress(); }
void StartStatusHTMLFileWriting ( const QString& strNewFileName,
const QString& strNewServerNameWithPort );
protected:
CVector<CChannelShortInfo> CreateChannelList();
void CreateAndSendChanListForAllConChannels();
void CreateAndSendChanListForAllExceptThisChan ( const int iCurChanID );
void CreateAndSendChanListForThisChan ( const int iCurChanID );
void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText );
void WriteHTMLChannelList();
/* do not use the vector class since CChannel does not have appropriate
copy constructor/operator */
CChannel vecChannels[MAX_NUM_CHANNELS];
QMutex Mutex;
CVector<QString> vstrChatColors;
// HTML file server status
bool bWriteStatusHTMLFile;
QString strServerHTMLFileListName;
QString strServerNameWithPort;
public slots:
// CODE TAG: MAX_NUM_CHANNELS_TAG
// make sure we have MAX_NUM_CHANNELS connections!!!
// send message
void OnSendProtMessCh0 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 0, mess ); }
void OnSendProtMessCh1 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 1, mess ); }
void OnSendProtMessCh2 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 2, mess ); }
void OnSendProtMessCh3 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 3, mess ); }
void OnSendProtMessCh4 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 4, mess ); }
void OnSendProtMessCh5 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 5, mess ); }
void OnSendProtMessCh6 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 6, mess ); }
void OnSendProtMessCh7 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 7, mess ); }
void OnSendProtMessCh8 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 8, mess ); }
void OnSendProtMessCh9 ( CVector<uint8_t> mess ) { emit MessReadyForSending ( 9, mess ); }
void OnNewConnectionCh0() { vecChannels[0].CreateReqJitBufMes(); }
void OnNewConnectionCh1() { vecChannels[1].CreateReqJitBufMes(); }
void OnNewConnectionCh2() { vecChannels[2].CreateReqJitBufMes(); }
void OnNewConnectionCh3() { vecChannels[3].CreateReqJitBufMes(); }
void OnNewConnectionCh4() { vecChannels[4].CreateReqJitBufMes(); }
void OnNewConnectionCh5() { vecChannels[5].CreateReqJitBufMes(); }
void OnNewConnectionCh6() { vecChannels[6].CreateReqJitBufMes(); }
void OnNewConnectionCh7() { vecChannels[7].CreateReqJitBufMes(); }
void OnNewConnectionCh8() { vecChannels[8].CreateReqJitBufMes(); }
void OnNewConnectionCh9() { vecChannels[9].CreateReqJitBufMes(); }
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 ); }
void OnNameHasChangedCh0() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh1() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh2() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh3() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh4() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh5() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh6() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh7() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh8() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh9() { CreateAndSendChanListForAllConChannels(); }
void OnChatTextReceivedCh0 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 0, strChatText ); }
void OnChatTextReceivedCh1 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 1, strChatText ); }
void OnChatTextReceivedCh2 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 2, strChatText ); }
void OnChatTextReceivedCh3 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 3, strChatText ); }
void OnChatTextReceivedCh4 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 4, strChatText ); }
void OnChatTextReceivedCh5 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 5, strChatText ); }
void OnChatTextReceivedCh6 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 6, strChatText ); }
void OnChatTextReceivedCh7 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 7, strChatText ); }
void OnChatTextReceivedCh8 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 8, strChatText ); }
void OnChatTextReceivedCh9 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 9, strChatText ); }
void OnPingReceivedCh0 ( int iMs ) { vecChannels[0].CreatePingMes ( iMs ); }
void OnPingReceivedCh1 ( int iMs ) { vecChannels[1].CreatePingMes ( iMs ); }
void OnPingReceivedCh2 ( int iMs ) { vecChannels[2].CreatePingMes ( iMs ); }
void OnPingReceivedCh3 ( int iMs ) { vecChannels[3].CreatePingMes ( iMs ); }
void OnPingReceivedCh4 ( int iMs ) { vecChannels[4].CreatePingMes ( iMs ); }
void OnPingReceivedCh5 ( int iMs ) { vecChannels[5].CreatePingMes ( iMs ); }
void OnPingReceivedCh6 ( int iMs ) { vecChannels[6].CreatePingMes ( iMs ); }
void OnPingReceivedCh7 ( int iMs ) { vecChannels[7].CreatePingMes ( iMs ); }
void OnPingReceivedCh8 ( int iMs ) { vecChannels[8].CreatePingMes ( iMs ); }
void OnPingReceivedCh9 ( int iMs ) { vecChannels[9].CreatePingMes ( iMs ); }
signals:
void MessReadyForSending ( int iChID, CVector<uint8_t> vecMessage );
void ChannelConnected ( CHostAddress ChanAddr );
};
#endif /* !defined ( CHANNEL_HOIH9345KJH98_3_4344_BB23945IUHF1912__INCLUDED_ ) */

View file

@ -79,13 +79,12 @@ void CLlconServerDlg::OnTimer()
CVector<QString> vecsName;
CVector<int> veciJitBufSize;
CVector<int> veciNetwOutBlSiFact;
CVector<EAudComprType> veceAudComprType;
double dCurTiStdDev;
ListViewMutex.lock();
pServer->GetConCliParam ( vecHostAddresses, vecsName, veciJitBufSize,
veciNetwOutBlSiFact, veceAudComprType );
veciNetwOutBlSiFact );
// fill list with connected clients
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
@ -109,22 +108,6 @@ void CLlconServerDlg::OnTimer()
QString().setNum (
static_cast<double> ( veciNetwOutBlSiFact[i] * SYSTEM_BLOCK_DURATION_MS_FLOAT ), 'f', 2 ) );
// output audio compression
switch ( veceAudComprType[i] )
{
case CT_NONE:
vecpListViewItems[i]->setText ( 6, "None" );
break;
case CT_CELT:
vecpListViewItems[i]->setText ( 6, "CELT" );
break;
default:
vecpListViewItems[i]->setText ( 6, "Unknown" );
break;
}
vecpListViewItems[i]->setHidden ( false );
}
else

View file

@ -69,11 +69,6 @@
<string>Block Size Out</string>
</property>
</column>
<column>
<property name="text" >
<string>Audio Compr. Out</string>
</property>
</column>
</widget>
</item>
<item>

View file

@ -31,8 +31,25 @@ CServer::CServer ( const QString& strLoggingFileName,
const QString& strHTMLStatusFileName,
const QString& strHistoryFileName,
const QString& strServerNameForHTMLStatusFile ) :
Socket ( &ChannelSet, this, iPortNumber )
Socket ( this, iPortNumber ),
bWriteStatusHTMLFile ( false )
{
// enable all channels (for the server all channel must be enabled the
// entire life time of the software
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
vecChannels[i].SetEnable ( true );
}
// define colors for chat window identifiers
vstrChatColors.Init ( 6 );
vstrChatColors[0] = "mediumblue";
vstrChatColors[1] = "red";
vstrChatColors[2] = "darkorchid";
vstrChatColors[3] = "green";
vstrChatColors[4] = "maroon";
vstrChatColors[5] = "coral";
vecsSendData.Init ( SYSTEM_BLOCK_SIZE_SAMPLES );
// init moving average buffer for response time evaluation
@ -43,16 +60,6 @@ CServer::CServer ( const QString& strLoggingFileName,
QObject::connect ( &Timer, SIGNAL ( timeout() ),
this, SLOT ( OnTimer() ) );
// connection for protocol
QObject::connect ( &ChannelSet,
SIGNAL ( MessReadyForSending ( int, CVector<uint8_t> ) ),
this, SLOT ( OnSendProtMessage ( int, CVector<uint8_t> ) ) );
// connection for logging
QObject::connect ( &ChannelSet,
SIGNAL ( ChannelConnected ( CHostAddress ) ),
this, SLOT ( OnNewChannel ( CHostAddress ) ) );
// enable logging (if requested)
if ( !strLoggingFileName.isEmpty() )
{
@ -78,17 +85,91 @@ CServer::CServer ( const QString& strLoggingFileName,
// (the static cast to integer of the port number is required so that it
// works correctly under Linux)
ChannelSet.StartStatusHTMLFileWriting ( strHTMLStatusFileName,
StartStatusHTMLFileWriting ( strHTMLStatusFileName,
strCurServerNameForHTMLStatusFile + ":" +
QString().number( static_cast<int> ( iPortNumber ) ) );
}
// CODE TAG: MAX_NUM_CHANNELS_TAG
// make sure we have MAX_NUM_CHANNELS connections!!!
// send message
QObject::connect ( &vecChannels[0], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh0 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[1], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh1 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[2], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh2 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[3], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh3 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[4], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh4 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[5], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh5 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[6], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh6 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[7], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh7 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[8], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh8 ( CVector<uint8_t> ) ) );
QObject::connect ( &vecChannels[9], SIGNAL ( MessReadyForSending ( CVector<uint8_t> ) ), this, SLOT ( OnSendProtMessCh9 ( CVector<uint8_t> ) ) );
// request jitter buffer size
QObject::connect ( &vecChannels[0], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh0() ) );
QObject::connect ( &vecChannels[1], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh1() ) );
QObject::connect ( &vecChannels[2], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh2() ) );
QObject::connect ( &vecChannels[3], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh3() ) );
QObject::connect ( &vecChannels[4], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh4() ) );
QObject::connect ( &vecChannels[5], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh5() ) );
QObject::connect ( &vecChannels[6], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh6() ) );
QObject::connect ( &vecChannels[7], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh7() ) );
QObject::connect ( &vecChannels[8], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh8() ) );
QObject::connect ( &vecChannels[9], SIGNAL ( NewConnection() ), this, SLOT ( OnNewConnectionCh9() ) );
// request connected clients list
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() ) );
// channel name has changed
QObject::connect ( &vecChannels[0], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh0() ) );
QObject::connect ( &vecChannels[1], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh1() ) );
QObject::connect ( &vecChannels[2], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh2() ) );
QObject::connect ( &vecChannels[3], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh3() ) );
QObject::connect ( &vecChannels[4], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh4() ) );
QObject::connect ( &vecChannels[5], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh5() ) );
QObject::connect ( &vecChannels[6], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh6() ) );
QObject::connect ( &vecChannels[7], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh7() ) );
QObject::connect ( &vecChannels[8], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh8() ) );
QObject::connect ( &vecChannels[9], SIGNAL ( NameHasChanged() ), this, SLOT ( OnNameHasChangedCh9() ) );
// chat text received
QObject::connect ( &vecChannels[0], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh0 ( QString ) ) );
QObject::connect ( &vecChannels[1], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh1 ( QString ) ) );
QObject::connect ( &vecChannels[2], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh2 ( QString ) ) );
QObject::connect ( &vecChannels[3], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh3 ( QString ) ) );
QObject::connect ( &vecChannels[4], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh4 ( QString ) ) );
QObject::connect ( &vecChannels[5], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh5 ( QString ) ) );
QObject::connect ( &vecChannels[6], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh6 ( QString ) ) );
QObject::connect ( &vecChannels[7], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh7 ( QString ) ) );
QObject::connect ( &vecChannels[8], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh8 ( QString ) ) );
QObject::connect ( &vecChannels[9], SIGNAL ( ChatTextReceived ( QString ) ), this, SLOT ( OnChatTextReceivedCh9 ( QString ) ) );
// ping message received
QObject::connect ( &vecChannels[0], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh0 ( int ) ) );
QObject::connect ( &vecChannels[1], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh1 ( int ) ) );
QObject::connect ( &vecChannels[2], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh2 ( int ) ) );
QObject::connect ( &vecChannels[3], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh3 ( int ) ) );
QObject::connect ( &vecChannels[4], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh4 ( int ) ) );
QObject::connect ( &vecChannels[5], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh5 ( int ) ) );
QObject::connect ( &vecChannels[6], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh6 ( int ) ) );
QObject::connect ( &vecChannels[7], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh7 ( int ) ) );
QObject::connect ( &vecChannels[8], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh8 ( int ) ) );
QObject::connect ( &vecChannels[9], SIGNAL ( PingReceived ( int ) ), this, SLOT ( OnPingReceivedCh9 ( int ) ) );
}
void CServer::OnSendProtMessage ( int iChID, CVector<uint8_t> vecMessage )
{
// the protocol queries me to call the function to send the message
// send it through the network
Socket.SendPacket ( vecMessage, ChannelSet.GetAddress ( iChID ) );
Socket.SendPacket ( vecMessage, GetAddress ( iChID ) );
}
void CServer::Start()
@ -114,12 +195,6 @@ void CServer::Stop()
Logging.AddServerStopped();
}
void CServer::OnNewChannel ( CHostAddress ChanAddr )
{
// logging of new connected channel
Logging.AddNewConnection ( ChanAddr.InetAddr );
}
void CServer::OnTimer()
{
CVector<int> vecChanID;
@ -127,7 +202,7 @@ void CServer::OnTimer()
CVector<CVector<double> > vecvecdGains;
// get data from all connected clients
ChannelSet.GetBlockAllConC ( vecChanID, vecvecdData, vecvecdGains );
GetBlockAllConC ( vecChanID, vecvecdData, vecvecdGains );
const int iNumClients = vecChanID.Size();
// Check if at least one client is connected. If not, stop server until
@ -142,8 +217,8 @@ void CServer::OnTimer()
// send separate mix to current clients
Socket.SendPacket (
ChannelSet.PrepSendPacket ( vecChanID[i], vecsSendData ),
ChannelSet.GetAddress ( vecChanID[i] ) );
PrepSendPacket ( vecChanID[i], vecsSendData ),
GetAddress ( vecChanID[i] ) );
}
}
else
@ -157,6 +232,436 @@ void CServer::OnTimer()
CycleTimeVariance.Update();
}
void CServer::GetBlockAllConC ( CVector<int>& vecChanID,
CVector<CVector<double> >& vecvecdData,
CVector<CVector<double> >& vecvecdGains )
{
int i, j;
bool bChannelIsNowDisconnected = false;
// init temporal data vector and clear input buffers
CVector<double> vecdData ( SYSTEM_BLOCK_SIZE_SAMPLES );
vecChanID.Init ( 0 );
vecvecdData.Init ( 0 );
vecvecdGains.Init ( 0 );
// make put and get calls thread safe. Do not forget to unlock mutex
// afterwards!
Mutex.lock();
{
// check all possible channels
for ( i = 0; i < USED_NUM_CHANNELS; i++ )
{
// read out all input buffers to decrease timeout counter on
// disconnected channels
// const EGetDataStat eGetStat = vecChannels[i].GetData ( vecdData );
const EGetDataStat eGetStat=GS_BUFFER_OK;//TEST
// if channel was just disconnected, set flag that connected
// client list is sent to all other clients
if ( eGetStat == GS_CHAN_NOW_DISCONNECTED )
{
bChannelIsNowDisconnected = true;
}
if ( vecChannels[i].IsConnected() )
{
// add ID and data
vecChanID.Add ( i );
const int iOldSize = vecvecdData.Size();
vecvecdData.Enlarge ( 1 );
vecvecdData[iOldSize].Init ( vecdData.Size() );
vecvecdData[iOldSize] = vecdData;
// send message for get status (for GUI)
if ( eGetStat == GS_BUFFER_OK )
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN, i );
}
else
{
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED, i );
}
}
}
// now that we know the IDs of the connected clients, get gains
const int iNumCurConnChan = vecChanID.Size();
vecvecdGains.Init ( iNumCurConnChan );
for ( i = 0; i < iNumCurConnChan; i++ )
{
vecvecdGains[i].Init ( iNumCurConnChan );
for ( j = 0; j < iNumCurConnChan; j++ )
{
// The second index of "vecvecdGains" does not represent
// the channel ID! Therefore we have to use "vecChanID" to
// query the IDs of the currently connected channels
vecvecdGains[i][j] =
vecChannels[vecChanID[i]].GetGain( vecChanID[j] );
}
}
// a channel is now disconnected, take action on it
if ( bChannelIsNowDisconnected )
{
// update channel list for all currently connected clients
CreateAndSendChanListForAllConChannels();
}
}
Mutex.unlock(); // release mutex
}
CVector<CChannelShortInfo> CServer::CreateChannelList()
{
CVector<CChannelShortInfo> vecChanInfo ( 0 );
// look for free channels
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
// append channel ID, IP address and channel name to storing vectors
vecChanInfo.Add ( CChannelShortInfo (
i, // ID
vecChannels[i].GetAddress().InetAddr.toIPv4Address(), // IP address
vecChannels[i].GetName() /* name */ ) );
}
}
return vecChanInfo;
}
void CServer::CreateAndSendChanListForAllConChannels()
{
// create channel list
CVector<CChannelShortInfo> vecChanInfo ( CreateChannelList() );
// now send connected channels list to all connected clients
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
// send message
vecChannels[i].CreateConClientListMes ( vecChanInfo );
}
}
// create status HTML file if enabled
if ( bWriteStatusHTMLFile )
{
WriteHTMLChannelList();
}
}
void CServer::CreateAndSendChanListForAllExceptThisChan ( const int iCurChanID )
{
// create channel list
CVector<CChannelShortInfo> vecChanInfo ( CreateChannelList() );
// now send connected channels list to all connected clients except for
// the channel with the ID "iCurChanID"
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( ( vecChannels[i].IsConnected() ) && ( i != iCurChanID ) )
{
// send message
vecChannels[i].CreateConClientListMes ( vecChanInfo );
}
}
// create status HTML file if enabled
if ( bWriteStatusHTMLFile )
{
WriteHTMLChannelList();
}
}
void CServer::CreateAndSendChanListForThisChan ( const int iCurChanID )
{
// create channel list
CVector<CChannelShortInfo> vecChanInfo ( CreateChannelList() );
// now send connected channels list to the channel with the ID "iCurChanID"
vecChannels[iCurChanID].CreateConClientListMes ( vecChanInfo );
}
void CServer::CreateAndSendChatTextForAllConChannels ( const int iCurChanID,
const QString& strChatText )
{
// create message which is sent to all connected clients -------------------
// get client name, if name is empty, use IP address instead
QString ChanName = vecChannels[iCurChanID].GetName();
if ( ChanName.isEmpty() )
{
// convert IP address to text and show it
ChanName =
vecChannels[iCurChanID].GetAddress().GetIpAddressStringNoLastByte();
}
// add name of the client at the beginning of the message text and use
// different colors, to get correct HTML, the "<" and ">" signs must be
// replaced by "&#60;" and "&#62;"
QString sCurColor = vstrChatColors[iCurChanID % vstrChatColors.Size()];
const QString strActualMessageText =
"<font color=""" + sCurColor + """><b>&#60;" + ChanName +
"&#62;</b></font> " + strChatText;
// send chat text to all connected clients ---------------------------------
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
// send message
vecChannels[i].CreateChatTextMes ( strActualMessageText );
}
}
}
int CServer::GetFreeChan()
{
// look for a free channel
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( !vecChannels[i].IsConnected() )
{
return i;
}
}
// no free channel found, return invalid ID
return INVALID_CHANNEL_ID;
}
int CServer::CheckAddr ( const CHostAddress& Addr )
{
CHostAddress InetAddr;
// check for all possible channels if IP is already in use
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
if ( vecChannels[i].GetAddress ( InetAddr ) )
{
// IP found, return channel number
if ( InetAddr == Addr )
{
return i;
}
}
}
}
// IP not found, return invalid ID
return INVALID_CHANNEL_ID;
}
bool CServer::PutData ( const CVector<uint8_t>& vecbyRecBuf,
const int iNumBytesRead,
const CHostAddress& HostAdr )
{
bool bAudioOK = false;
bool bNewChannelReserved = false;
Mutex.lock();
{
bool bChanOK = true;
// Get channel ID ------------------------------------------------------
// check address
int iCurChanID = CheckAddr ( HostAdr );
if ( iCurChanID == INVALID_CHANNEL_ID )
{
// a new client is calling, look for free channel
iCurChanID = GetFreeChan();
if ( iCurChanID != INVALID_CHANNEL_ID )
{
// initialize current channel by storing the calling host
// address
vecChannels[iCurChanID].SetAddress ( HostAdr );
// reset the channel gains of current channel, at the same
// time reset gains of this channel ID for all other channels
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
vecChannels[iCurChanID].SetGain ( i, (double) 1.0 );
// other channels (we do not distinguish the case if
// i == iCurChanID for simplicity)
vecChannels[i].SetGain ( iCurChanID, (double) 1.0 );
}
// set flag for new reserved channel
bNewChannelReserved = true;
}
else
{
// no free channel available
bChanOK = false;
// create and send "server full" message
// TODO problem: if channel is not officially connected, we cannot send messages
}
}
// Put received data in jitter buffer ----------------------------------
if ( bChanOK )
{
// put packet in socket buffer
switch ( vecChannels[iCurChanID].PutData ( vecbyRecBuf, iNumBytesRead ) )
{
case PS_AUDIO_OK:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN, iCurChanID );
bAudioOK = true; // in case we have an audio packet, return true
break;
case PS_AUDIO_ERR:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED, iCurChanID );
bAudioOK = true; // in case we have an audio packet, return true
break;
case PS_PROT_ERR:
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW, iCurChanID );
// TEST
bAudioOK = true;
break;
}
}
// after data is put in channel buffer, create channel list message if
// requested
if ( bNewChannelReserved && bAudioOK )
{
// logging of new connected channel
Logging.AddNewConnection ( HostAdr.InetAddr );
// A new client connected to the server, create and
// send all clients the updated channel list (the list has to
// be created after the received data has to be put to the
// channel first so that this channel is marked as connected)
//
// 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();
return bAudioOK;
}
void CServer::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
CVector<QString>& vecsName,
CVector<int>& veciJitBufSize,
CVector<int>& veciNetwOutBlSiFact )
{
CHostAddress InetAddr;
// init return values
vecHostAddresses.Init ( USED_NUM_CHANNELS );
vecsName.Init ( USED_NUM_CHANNELS );
veciJitBufSize.Init ( USED_NUM_CHANNELS );
veciNetwOutBlSiFact.Init ( USED_NUM_CHANNELS );
// check all possible channels
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].GetAddress ( InetAddr ) )
{
// get requested data
vecHostAddresses[i] = InetAddr;
vecsName[i] = vecChannels[i].GetName();
veciJitBufSize[i] = vecChannels[i].GetSockBufSize();
veciNetwOutBlSiFact[i] = vecChannels[i].GetNetwBufSizeFactOut();
}
}
}
void CServer::StartStatusHTMLFileWriting ( const QString& strNewFileName,
const QString& strNewServerNameWithPort )
{
// set important parameters
strServerHTMLFileListName = strNewFileName;
strServerNameWithPort = strNewServerNameWithPort;
// set flag
bWriteStatusHTMLFile = true;
// write initial file
WriteHTMLChannelList();
}
void CServer::WriteHTMLChannelList()
{
// create channel list
CVector<CChannelShortInfo> vecChanInfo ( CreateChannelList() );
// prepare file and stream
QFile serverFileListFile ( strServerHTMLFileListName );
if ( !serverFileListFile.open ( QIODevice::WriteOnly | QIODevice::Text ) )
{
return;
}
QTextStream streamFileOut ( &serverFileListFile );
streamFileOut << strServerNameWithPort << endl << "<ul>" << endl;
// get the number of connected clients
int iNumConnClients = 0;
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
iNumConnClients++;
}
}
// depending on number of connected clients write list
if ( iNumConnClients == 0 )
{
// no clients are connected -> empty server
streamFileOut << " No client connected" << endl;
}
else
{
// write entry for each connected client
for ( int i = 0; i < USED_NUM_CHANNELS; i++ )
{
if ( vecChannels[i].IsConnected() )
{
QString strCurChanName = vecChannels[i].GetName();
// if text is empty, show IP address instead
if ( strCurChanName.isEmpty() )
{
// convert IP address to text and show it, remove last
// digits
strCurChanName =
vecChannels[i].GetAddress().GetIpAddressStringNoLastByte();
}
streamFileOut << " <li>" << strCurChanName << "</li>" << endl;
}
}
}
// finish list
streamFileOut << "</ul>" << endl;
}
CVector<short> CServer::ProcessData ( CVector<CVector<double> >& vecvecdData,
CVector<double>& vecdGains )
{

View file

@ -36,6 +36,11 @@
#include "serverlogging.h"
/* Definitions ****************************************************************/
// no valid channel number
#define INVALID_CHANNEL_ID ( MAX_NUM_CHANNELS + 1 )
/* Classes ********************************************************************/
class CServer : public QObject
{
@ -53,33 +58,65 @@ public:
void Stop();
bool IsRunning() { return Timer.isActive(); }
void GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
CVector<QString>& vecsName,
CVector<int>& veciJitBufSize,
CVector<int>& veciNetwOutBlSiFact,
CVector<EAudComprType>& veceAudComprType )
{
ChannelSet.GetConCliParam ( vecHostAddresses,
vecsName,
veciJitBufSize,
veciNetwOutBlSiFact );
}
bool GetTimingStdDev ( double& dCurTiStdDev );
CChannelSet* GetChannelSet() { return &ChannelSet; }
bool PutData ( const CVector<uint8_t>& vecbyRecBuf,
const int iNumBytesRead, const CHostAddress& HostAdr );
void GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
CVector<QString>& vecsName,
CVector<int>& veciJitBufSize,
CVector<int>& veciNetwOutBlSiFact );
protected:
// access functions for actual channels
bool IsConnected ( const int iChanNum )
{ return vecChannels[iChanNum].IsConnected(); }
CVector<uint8_t> PrepSendPacket ( const int iChanNum,
const CVector<short>& vecsNPacket )
{ return vecChannels[iChanNum].PrepSendPacket ( vecsNPacket ); }
CHostAddress GetAddress ( const int iChanNum )
{ return vecChannels[iChanNum].GetAddress(); }
void StartStatusHTMLFileWriting ( const QString& strNewFileName,
const QString& strNewServerNameWithPort );
void GetBlockAllConC ( CVector<int>& vecChanID,
CVector<CVector<double> >& vecvecdData,
CVector<CVector<double> >& vecvecdGains );
int CheckAddr ( const CHostAddress& Addr );
int GetFreeChan();
CVector<CChannelShortInfo> CreateChannelList();
void CreateAndSendChanListForAllConChannels();
void CreateAndSendChanListForAllExceptThisChan ( const int iCurChanID );
void CreateAndSendChanListForThisChan ( const int iCurChanID );
void CreateAndSendChatTextForAllConChannels ( const int iCurChanID, const QString& strChatText );
void WriteHTMLChannelList();
CVector<short> ProcessData ( CVector<CVector<double> >& vecvecdData,
CVector<double>& vecdGains );
virtual void customEvent ( QEvent* Event );
/* do not use the vector class since CChannel does not have appropriate
copy constructor/operator */
CChannel vecChannels[MAX_NUM_CHANNELS];
QMutex Mutex;
CVector<QString> vstrChatColors;
// HTML file server status
bool bWriteStatusHTMLFile;
QString strServerHTMLFileListName;
QString strServerNameWithPort;
QTimer Timer;
CVector<short> vecsSendData;
// actual working objects
CChannelSet ChannelSet;
CSocket Socket;
CCycleTimeVariance CycleTimeVariance;
@ -90,7 +127,75 @@ protected:
public slots:
void OnTimer();
void OnSendProtMessage ( int iChID, CVector<uint8_t> vecMessage );
void OnNewChannel ( CHostAddress ChanAddr );
// CODE TAG: MAX_NUM_CHANNELS_TAG
// make sure we have MAX_NUM_CHANNELS connections!!!
// send message
void OnSendProtMessCh0 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 0, mess ); }
void OnSendProtMessCh1 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 1, mess ); }
void OnSendProtMessCh2 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 2, mess ); }
void OnSendProtMessCh3 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 3, mess ); }
void OnSendProtMessCh4 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 4, mess ); }
void OnSendProtMessCh5 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 5, mess ); }
void OnSendProtMessCh6 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 6, mess ); }
void OnSendProtMessCh7 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 7, mess ); }
void OnSendProtMessCh8 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 8, mess ); }
void OnSendProtMessCh9 ( CVector<uint8_t> mess ) { OnSendProtMessage ( 9, mess ); }
void OnNewConnectionCh0() { vecChannels[0].CreateReqJitBufMes(); }
void OnNewConnectionCh1() { vecChannels[1].CreateReqJitBufMes(); }
void OnNewConnectionCh2() { vecChannels[2].CreateReqJitBufMes(); }
void OnNewConnectionCh3() { vecChannels[3].CreateReqJitBufMes(); }
void OnNewConnectionCh4() { vecChannels[4].CreateReqJitBufMes(); }
void OnNewConnectionCh5() { vecChannels[5].CreateReqJitBufMes(); }
void OnNewConnectionCh6() { vecChannels[6].CreateReqJitBufMes(); }
void OnNewConnectionCh7() { vecChannels[7].CreateReqJitBufMes(); }
void OnNewConnectionCh8() { vecChannels[8].CreateReqJitBufMes(); }
void OnNewConnectionCh9() { vecChannels[9].CreateReqJitBufMes(); }
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 ); }
void OnNameHasChangedCh0() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh1() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh2() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh3() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh4() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh5() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh6() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh7() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh8() { CreateAndSendChanListForAllConChannels(); }
void OnNameHasChangedCh9() { CreateAndSendChanListForAllConChannels(); }
void OnChatTextReceivedCh0 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 0, strChatText ); }
void OnChatTextReceivedCh1 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 1, strChatText ); }
void OnChatTextReceivedCh2 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 2, strChatText ); }
void OnChatTextReceivedCh3 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 3, strChatText ); }
void OnChatTextReceivedCh4 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 4, strChatText ); }
void OnChatTextReceivedCh5 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 5, strChatText ); }
void OnChatTextReceivedCh6 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 6, strChatText ); }
void OnChatTextReceivedCh7 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 7, strChatText ); }
void OnChatTextReceivedCh8 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 8, strChatText ); }
void OnChatTextReceivedCh9 ( QString strChatText ) { CreateAndSendChatTextForAllConChannels ( 9, strChatText ); }
void OnPingReceivedCh0 ( int iMs ) { vecChannels[0].CreatePingMes ( iMs ); }
void OnPingReceivedCh1 ( int iMs ) { vecChannels[1].CreatePingMes ( iMs ); }
void OnPingReceivedCh2 ( int iMs ) { vecChannels[2].CreatePingMes ( iMs ); }
void OnPingReceivedCh3 ( int iMs ) { vecChannels[3].CreatePingMes ( iMs ); }
void OnPingReceivedCh4 ( int iMs ) { vecChannels[4].CreatePingMes ( iMs ); }
void OnPingReceivedCh5 ( int iMs ) { vecChannels[5].CreatePingMes ( iMs ); }
void OnPingReceivedCh6 ( int iMs ) { vecChannels[6].CreatePingMes ( iMs ); }
void OnPingReceivedCh7 ( int iMs ) { vecChannels[7].CreatePingMes ( iMs ); }
void OnPingReceivedCh8 ( int iMs ) { vecChannels[8].CreatePingMes ( iMs ); }
void OnPingReceivedCh9 ( int iMs ) { vecChannels[9].CreatePingMes ( iMs ); }
};
#endif /* !defined ( SERVER_HOIHGE7LOKIH83JH8_3_43445KJIUHF1912__INCLUDED_ ) */

View file

@ -122,7 +122,7 @@ void CSocket::OnDataReceived()
else
{
// server
if ( pChannelSet->PutData ( vecbyRecBuf, iNumBytesRead, RecHostAddr ) )
if ( pServer->PutData ( vecbyRecBuf, iNumBytesRead, RecHostAddr ) )
{
// this was an audio packet, start server
// tell the server object to wake up if it

View file

@ -49,8 +49,8 @@ class CSocket : public QObject
public:
CSocket ( CChannel* pNewChannel, const quint16 iPortNumber ) :
pChannel( pNewChannel ), bIsClient ( true ) { Init ( iPortNumber ); }
CSocket ( CChannelSet* pNewChannelSet, QObject* pNServP, const quint16 iPortNumber ) :
pChannelSet ( pNewChannelSet ), pServer ( pNServP ), bIsClient ( false )
CSocket ( QObject* pNServP, const quint16 iPortNumber ) :
pServer ( pNServP ), bIsClient ( false )
{ Init ( iPortNumber ); }
virtual ~CSocket() {}
@ -65,8 +65,7 @@ protected:
CVector<uint8_t> vecbyRecBuf;
CHostAddress RecHostAddr;
CChannel* pChannel; // for client
CChannelSet* pChannelSet; // for server
CChannel* pChannel; // for client
QObject* pServer;
bool bIsClient;

View file

@ -419,6 +419,14 @@ enum EAudComprType
CT_CELT = 1
};
enum EGetDataStat
{
GS_BUFFER_OK,
GS_BUFFER_UNDERRUN,
GS_CHAN_NOW_DISCONNECTED,
GS_CHAN_NOT_CONNECTED
};
class CNetworkTransportProps
{
public: