added mutex for protocol
This commit is contained in:
parent
1595a7446b
commit
fc816a7f09
8 changed files with 318 additions and 379 deletions
194
src/channel.cpp
194
src/channel.cpp
|
@ -112,44 +112,50 @@ bool CChannelSet::PutData ( const CVector<unsigned char>& vecbyRecBuf,
|
|||
const int iNumBytesRead,
|
||||
const CHostAddress& HostAdr )
|
||||
{
|
||||
bool bChanOK = true;
|
||||
|
||||
Mutex.lock ();
|
||||
|
||||
/* get channel ID ------------------------------------------------------- */
|
||||
bool bChanOK = true;
|
||||
|
||||
/* check address */
|
||||
int iCurChanID = CheckAddr ( HostAdr );
|
||||
|
||||
if ( iCurChanID == INVALID_CHANNEL_ID )
|
||||
{
|
||||
/* a new client is calling, look for free channel */
|
||||
iCurChanID = GetFreeChan ();
|
||||
/* get channel ID --------------------------------------------------- */
|
||||
/* check address */
|
||||
int iCurChanID = CheckAddr ( HostAdr );
|
||||
|
||||
if ( iCurChanID != INVALID_CHANNEL_ID )
|
||||
if ( iCurChanID == INVALID_CHANNEL_ID )
|
||||
{
|
||||
vecChannels[iCurChanID].SetAddress ( HostAdr );
|
||||
/* a new client is calling, look for free channel */
|
||||
iCurChanID = GetFreeChan ();
|
||||
|
||||
if ( iCurChanID != INVALID_CHANNEL_ID )
|
||||
{
|
||||
vecChannels[iCurChanID].SetAddress ( HostAdr );
|
||||
}
|
||||
else
|
||||
{
|
||||
bChanOK = false; /* no free channel available */
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
/* put received data in jitter buffer ------------------------------- */
|
||||
if ( bChanOK )
|
||||
{
|
||||
bChanOK = false; /* no free channel available */
|
||||
/* 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 );
|
||||
break;
|
||||
|
||||
case PS_AUDIO_ERR:
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED, iCurChanID );
|
||||
break;
|
||||
|
||||
case PS_PROT_ERR:
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW, iCurChanID );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* put received data in jitter buffer ----------------------------------- */
|
||||
if ( bChanOK )
|
||||
{
|
||||
/* put packet in socket buffer */
|
||||
if ( vecChannels[iCurChanID].PutData ( vecbyRecBuf, iNumBytesRead ) )
|
||||
{
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN, iCurChanID );
|
||||
}
|
||||
else
|
||||
{
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED, iCurChanID );
|
||||
}
|
||||
}
|
||||
|
||||
Mutex.unlock ();
|
||||
|
||||
return !bChanOK; /* return 1 if error */
|
||||
|
@ -167,36 +173,36 @@ void CChannelSet::GetBlockAllConC ( CVector<int>& vecChanID,
|
|||
/* make put and get calls thread safe. Do not forget to unlock mutex
|
||||
afterwards! */
|
||||
Mutex.lock ();
|
||||
|
||||
/* Check all possible channels */
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
{
|
||||
/* read out all input buffers to decrease timeout counter on
|
||||
disconnected channels */
|
||||
const bool bGetOK = vecChannels[i].GetData ( vecdData );
|
||||
|
||||
if ( vecChannels[i].IsConnected () )
|
||||
/* Check all possible channels */
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
{
|
||||
/* add ID and data */
|
||||
vecChanID.Add ( i );
|
||||
/* read out all input buffers to decrease timeout counter on
|
||||
disconnected channels */
|
||||
const bool bGetOK = vecChannels[i].GetData ( vecdData );
|
||||
|
||||
const int iOldSize = vecvecdData.Size ();
|
||||
vecvecdData.Enlarge ( 1 );
|
||||
vecvecdData[iOldSize].Init ( vecdData.Size () );
|
||||
vecvecdData[iOldSize] = vecdData;
|
||||
if ( vecChannels[i].IsConnected () )
|
||||
{
|
||||
/* add ID and data */
|
||||
vecChanID.Add ( i );
|
||||
|
||||
/* send message for get status (for GUI) */
|
||||
if ( bGetOK )
|
||||
{
|
||||
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN, i );
|
||||
}
|
||||
else
|
||||
{
|
||||
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED, 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 ( bGetOK )
|
||||
{
|
||||
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_GREEN, i );
|
||||
}
|
||||
else
|
||||
{
|
||||
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED, i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mutex.unlock (); /* release mutex */
|
||||
}
|
||||
|
||||
|
@ -221,20 +227,6 @@ void CChannelSet::GetConCliParam ( CVector<CHostAddress>& vecHostAddresses,
|
|||
}
|
||||
}
|
||||
|
||||
void CChannelSet::SetSockBufSize ( const int iNewBlockSize, const int iNumBlocks )
|
||||
{
|
||||
/* this opperation must be done with mutex */
|
||||
Mutex.lock ();
|
||||
|
||||
/* as a test we adjust the buffers of all channels to the new value. Maybe later
|
||||
do change only for some channels -> take care to set value back to default if
|
||||
channel is disconnected, afterwards! */
|
||||
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
|
||||
vecChannels[i].SetSockBufSize ( iNewBlockSize, iNumBlocks );
|
||||
|
||||
Mutex.unlock ();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************\
|
||||
* CChannel *
|
||||
|
@ -286,9 +278,9 @@ void CChannel::SetSockBufSize ( const int iNewBlockSize, const int iNumBlocks )
|
|||
{
|
||||
/* this opperation must be done with mutex */
|
||||
Mutex.lock ();
|
||||
|
||||
SockBuf.Init ( iNewBlockSize, iNumBlocks );
|
||||
|
||||
{
|
||||
SockBuf.Init ( iNewBlockSize, iNumBlocks );
|
||||
}
|
||||
Mutex.unlock ();
|
||||
}
|
||||
|
||||
|
@ -314,10 +306,10 @@ bool CChannel::GetAddress(CHostAddress& RetAddr)
|
|||
}
|
||||
}
|
||||
|
||||
bool CChannel::PutData ( const CVector<unsigned char>& vecbyData,
|
||||
int iNumBytes )
|
||||
EPutDataStat CChannel::PutData ( const CVector<unsigned char>& vecbyData,
|
||||
int iNumBytes )
|
||||
{
|
||||
bool bRet = true;
|
||||
EPutDataStat eRet = PS_GEN_ERROR;
|
||||
|
||||
/* only process if packet has correct size */
|
||||
if ( iNumBytes == iAudComprSize )
|
||||
|
@ -342,41 +334,61 @@ for (int i = 0; i < BLOCK_SIZE_SAMPLES; i++)
|
|||
|
||||
|
||||
Mutex.lock (); /* put mutex lock */
|
||||
|
||||
bRet = SockBuf.Put ( vecdResOutData );
|
||||
|
||||
{
|
||||
if ( SockBuf.Put ( vecdResOutData ) )
|
||||
{
|
||||
eRet = PS_AUDIO_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
eRet = PS_AUDIO_ERR;
|
||||
}
|
||||
}
|
||||
Mutex.unlock (); /* put mutex unlock */
|
||||
|
||||
/* reset time-out counter */
|
||||
// if channel was not connected, emit signal to inform that new connection
|
||||
// was established
|
||||
if ( iConTimeOut == 0 )
|
||||
{
|
||||
emit NewConnection();
|
||||
}
|
||||
|
||||
// reset time-out counter
|
||||
iConTimeOut = CON_TIME_OUT_CNT_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this seems not to be an audio block, parse the message
|
||||
|
||||
// TODO: different return code for protocol
|
||||
|
||||
bRet = Protocol.ParseMessage ( vecbyData, iNumBytes );
|
||||
if ( Protocol.ParseMessage ( vecbyData, iNumBytes ) )
|
||||
{
|
||||
eRet = PS_PROT_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
eRet = PS_PROT_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
return bRet;
|
||||
return eRet;
|
||||
}
|
||||
|
||||
bool CChannel::GetData ( CVector<double>& vecdData )
|
||||
{
|
||||
Mutex.lock (); /* get mutex lock */
|
||||
{
|
||||
bool bGetOK = false;
|
||||
|
||||
const bool bGetOK = SockBuf.Get ( vecdData );
|
||||
|
||||
if ( !bGetOK )
|
||||
Mutex.lock (); /* get mutex lock */
|
||||
{
|
||||
/* decrease time-out counter */
|
||||
if ( iConTimeOut > 0 )
|
||||
bGetOK = SockBuf.Get ( vecdData );
|
||||
|
||||
if ( !bGetOK )
|
||||
{
|
||||
iConTimeOut--;
|
||||
/* decrease time-out counter */
|
||||
if ( iConTimeOut > 0 )
|
||||
{
|
||||
iConTimeOut--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mutex.unlock (); /* get mutex unlock */
|
||||
|
||||
return bGetOK;
|
||||
|
|
102
src/channel.h
102
src/channel.h
|
@ -46,55 +46,44 @@
|
|||
#define MAX_NUM_CHANNELS 10 /* max number channels for server */
|
||||
|
||||
/* no valid channel number */
|
||||
#define INVALID_CHANNEL_ID (MAX_NUM_CHANNELS + 1)
|
||||
|
||||
|
||||
/* Classes ********************************************************************/
|
||||
class CSampleOffsetEst
|
||||
{
|
||||
public:
|
||||
CSampleOffsetEst() {Init();}
|
||||
virtual ~CSampleOffsetEst() {}
|
||||
|
||||
void Init();
|
||||
void AddTimeStampIdx(const int iTimeStampIdx);
|
||||
double GetSamRate() {return dSamRateEst;}
|
||||
|
||||
protected:
|
||||
QTime RefTime;
|
||||
int iAccTiStVal;
|
||||
double dSamRateEst;
|
||||
CVector<long int> veciTimeElapsed;
|
||||
CVector<long int> veciTiStIdx;
|
||||
int iInitCnt;
|
||||
#define INVALID_CHANNEL_ID (MAX_NUM_CHANNELS + 1)
|
||||
|
||||
enum EPutDataStat
|
||||
{
|
||||
PS_GEN_ERROR,
|
||||
PS_AUDIO_OK,
|
||||
PS_AUDIO_ERR,
|
||||
PS_PROT_OK,
|
||||
PS_PROT_ERR
|
||||
};
|
||||
|
||||
|
||||
/* Classes ********************************************************************/
|
||||
/* CChannel ----------------------------------------------------------------- */
|
||||
class CChannel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CChannel ();
|
||||
virtual ~CChannel () {}
|
||||
CChannel();
|
||||
virtual ~CChannel() {}
|
||||
|
||||
bool PutData ( const CVector<unsigned char>& vecbyData,
|
||||
int iNumBytes );
|
||||
EPutDataStat PutData ( const CVector<unsigned char>& vecbyData,
|
||||
int iNumBytes );
|
||||
bool GetData ( CVector<double>& vecdData );
|
||||
|
||||
CVector<unsigned char> PrepSendPacket ( const CVector<short>& vecsNPacket );
|
||||
|
||||
bool IsConnected () const { return iConTimeOut > 0; }
|
||||
bool IsConnected() const { return iConTimeOut > 0; }
|
||||
|
||||
int GetComprAudSize () { return iAudComprSize; }
|
||||
int GetComprAudSize() { return iAudComprSize; }
|
||||
|
||||
void SetAddress ( const CHostAddress NAddr ) { InetAddr = NAddr; }
|
||||
bool GetAddress ( CHostAddress& RetAddr );
|
||||
CHostAddress GetAddress () { return InetAddr; }
|
||||
|
||||
void SetSockBufSize ( const int iNewBlockSize, const int iNumBlocks );
|
||||
int GetSockBufSize () { return SockBuf.GetSize(); }
|
||||
int GetSockBufSize() { return SockBuf.GetSize(); }
|
||||
|
||||
// network protocol interface
|
||||
void CreateJitBufMes ( const int iJitBufSize )
|
||||
|
@ -139,6 +128,7 @@ public slots:
|
|||
|
||||
signals:
|
||||
void MessReadyForSending ( CVector<uint8_t> vecMessage );
|
||||
void NewConnection();
|
||||
};
|
||||
|
||||
|
||||
|
@ -151,28 +141,29 @@ public:
|
|||
CChannelSet();
|
||||
virtual ~CChannelSet() {}
|
||||
|
||||
bool PutData(const CVector<unsigned char>& vecbyRecBuf,
|
||||
const int iNumBytesRead, const CHostAddress& HostAdr);
|
||||
bool PutData ( const CVector<unsigned char>& vecbyRecBuf,
|
||||
const int iNumBytesRead, const CHostAddress& HostAdr );
|
||||
|
||||
int GetFreeChan();
|
||||
int CheckAddr(const CHostAddress& Addr);
|
||||
int GetFreeChan();
|
||||
|
||||
void GetBlockAllConC(CVector<int>& vecChanID,
|
||||
CVector<CVector<double> >& vecvecdData);
|
||||
void GetConCliParam(CVector<CHostAddress>& vecHostAddresses,
|
||||
CVector<int>& veciJitBufSize);
|
||||
int CheckAddr ( const CHostAddress& Addr );
|
||||
|
||||
void GetBlockAllConC ( CVector<int>& vecChanID,
|
||||
CVector<CVector<double> >& vecvecdData );
|
||||
|
||||
void GetConCliParam( CVector<CHostAddress>& vecHostAddresses,
|
||||
CVector<int>& veciJitBufSize );
|
||||
|
||||
/* access functions for actual channels */
|
||||
bool IsConnected(const int iChanNum)
|
||||
{return vecChannels[iChanNum].IsConnected();}
|
||||
CVector<unsigned char> PrepSendPacket(const int iChanNum,
|
||||
const CVector<short>& vecsNPacket)
|
||||
{return vecChannels[iChanNum].PrepSendPacket(vecsNPacket);}
|
||||
CHostAddress GetAddress(const int iChanNum)
|
||||
{return vecChannels[iChanNum].GetAddress();}
|
||||
bool IsConnected ( const int iChanNum )
|
||||
{ return vecChannels[iChanNum].IsConnected(); }
|
||||
|
||||
void SetSockBufSize ( const int iNewBlockSize, const int iNumBlocks);
|
||||
int GetSockBufSize() {return vecChannels[0].GetSockBufSize();}
|
||||
CVector<unsigned char> PrepSendPacket ( const int iChanNum,
|
||||
const CVector<short>& vecsNPacket )
|
||||
{ return vecChannels[iChanNum].PrepSendPacket ( vecsNPacket ); }
|
||||
|
||||
CHostAddress GetAddress ( const int iChanNum )
|
||||
{ return vecChannels[iChanNum].GetAddress(); }
|
||||
|
||||
protected:
|
||||
/* do not use the vector class since CChannel does not have appropriate
|
||||
|
@ -200,6 +191,27 @@ void OnSendProtMessCh9(CVector<uint8_t> mess) {emit MessReadyForSending(9,mess);
|
|||
signals:
|
||||
void MessReadyForSending ( int iChID, CVector<uint8_t> vecMessage );
|
||||
};
|
||||
|
||||
|
||||
/* Sample rate offset estimation -------------------------------------------- */
|
||||
class CSampleOffsetEst
|
||||
{
|
||||
public:
|
||||
CSampleOffsetEst() { Init(); }
|
||||
virtual ~CSampleOffsetEst() {}
|
||||
|
||||
void Init();
|
||||
void AddTimeStampIdx ( const int iTimeStampIdx );
|
||||
double GetSamRate() { return dSamRateEst; }
|
||||
|
||||
protected:
|
||||
QTime RefTime;
|
||||
int iAccTiStVal;
|
||||
double dSamRateEst;
|
||||
CVector<long int> veciTimeElapsed;
|
||||
CVector<long int> veciTiStIdx;
|
||||
int iInitCnt;
|
||||
};
|
||||
|
||||
|
||||
#endif /* !defined(CHANNEL_HOIH9345KJH98_3_4344_BB23945IUHF1912__INCLUDED_) */
|
||||
|
|
|
@ -69,12 +69,6 @@ CLlconServerDlg::CLlconServerDlg ( CServer* pNServP, QWidget* parent,
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Init slider control */
|
||||
SliderNetBuf->setRange(1, MAX_NET_BUF_SIZE_NUM_BL);
|
||||
const int iCurNumNetBuf = pServer->GetChannelSet()->GetSockBufSize();
|
||||
SliderNetBuf->setValue(iCurNumNetBuf);
|
||||
TextNetBuf->setText("Size: " + QString().setNum(iCurNumNetBuf));
|
||||
|
||||
/* Init timing jitter text label */
|
||||
TextLabelResponseTime->setText("");
|
||||
|
||||
|
@ -93,11 +87,7 @@ CLlconServerDlg::CLlconServerDlg ( CServer* pNServP, QWidget* parent,
|
|||
/* timers */
|
||||
QObject::connect(&Timer, SIGNAL(timeout()), this, SLOT(OnTimer()));
|
||||
|
||||
/* sliders */
|
||||
QObject::connect(SliderNetBuf, SIGNAL(valueChanged(int)),
|
||||
this, SLOT(OnSliderNetBuf(int)));
|
||||
|
||||
|
||||
|
||||
/* timers --------------------------------------------------------------- */
|
||||
/* start timer for GUI controls */
|
||||
Timer.start(GUI_CONTRL_UPDATE_TIME);
|
||||
|
@ -158,12 +148,6 @@ void CLlconServerDlg::OnTimer()
|
|||
}
|
||||
}
|
||||
|
||||
void CLlconServerDlg::OnSliderNetBuf(int value)
|
||||
{
|
||||
pServer->GetChannelSet()->SetSockBufSize( MIN_BLOCK_SIZE_SAMPLES, value );
|
||||
TextNetBuf->setText("Size: " + QString().setNum(value));
|
||||
}
|
||||
|
||||
void CLlconServerDlg::customEvent(QCustomEvent* Event)
|
||||
{
|
||||
if (Event->type() == QEvent::User + 11)
|
||||
|
|
|
@ -74,5 +74,4 @@ protected:
|
|||
|
||||
public slots:
|
||||
void OnTimer();
|
||||
void OnSliderNetBuf(int value);
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>633</width>
|
||||
<width>629</width>
|
||||
<height>240</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -37,110 +37,35 @@
|
|||
<number>6</number>
|
||||
</property>
|
||||
<widget>
|
||||
<class>QLayoutWidget</class>
|
||||
<class>QListView</class>
|
||||
<column>
|
||||
<property>
|
||||
<name>text</name>
|
||||
<string>Column 1</string>
|
||||
</property>
|
||||
<property>
|
||||
<name>clickable</name>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property>
|
||||
<name>resizeable</name>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</column>
|
||||
<item>
|
||||
<property>
|
||||
<name>text</name>
|
||||
<string>New Item</string>
|
||||
</property>
|
||||
<property>
|
||||
<name>pixmap</name>
|
||||
<pixmap></pixmap>
|
||||
</property>
|
||||
</item>
|
||||
<property stdset="1">
|
||||
<name>name</name>
|
||||
<cstring>Layout4</cstring>
|
||||
<cstring>ListViewClients</cstring>
|
||||
</property>
|
||||
<hbox>
|
||||
<property stdset="1">
|
||||
<name>margin</name>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property stdset="1">
|
||||
<name>spacing</name>
|
||||
<number>6</number>
|
||||
</property>
|
||||
<widget>
|
||||
<class>QListView</class>
|
||||
<column>
|
||||
<property>
|
||||
<name>text</name>
|
||||
<string>Column 1</string>
|
||||
</property>
|
||||
<property>
|
||||
<name>clickable</name>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property>
|
||||
<name>resizeable</name>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</column>
|
||||
<item>
|
||||
<property>
|
||||
<name>text</name>
|
||||
<string>New Item</string>
|
||||
</property>
|
||||
<property>
|
||||
<name>pixmap</name>
|
||||
<pixmap></pixmap>
|
||||
</property>
|
||||
</item>
|
||||
<property stdset="1">
|
||||
<name>name</name>
|
||||
<cstring>ListViewClients</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
<widget>
|
||||
<class>QGroupBox</class>
|
||||
<property stdset="1">
|
||||
<name>name</name>
|
||||
<cstring>GroupBox3</cstring>
|
||||
</property>
|
||||
<property stdset="1">
|
||||
<name>title</name>
|
||||
<string>Jitter Buffer</string>
|
||||
</property>
|
||||
<vbox>
|
||||
<property stdset="1">
|
||||
<name>margin</name>
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property stdset="1">
|
||||
<name>spacing</name>
|
||||
<number>6</number>
|
||||
</property>
|
||||
<widget>
|
||||
<class>QLabel</class>
|
||||
<property stdset="1">
|
||||
<name>name</name>
|
||||
<cstring>TextNetBuf</cstring>
|
||||
</property>
|
||||
<property stdset="1">
|
||||
<name>text</name>
|
||||
<string>Size</string>
|
||||
</property>
|
||||
<property stdset="1">
|
||||
<name>alignment</name>
|
||||
<set>AlignCenter</set>
|
||||
</property>
|
||||
<property>
|
||||
<name>hAlign</name>
|
||||
</property>
|
||||
</widget>
|
||||
<widget>
|
||||
<class>QSlider</class>
|
||||
<property stdset="1">
|
||||
<name>name</name>
|
||||
<cstring>SliderNetBuf</cstring>
|
||||
</property>
|
||||
<property stdset="1">
|
||||
<name>pageStep</name>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property stdset="1">
|
||||
<name>orientation</name>
|
||||
<enum>Vertical</enum>
|
||||
</property>
|
||||
<property stdset="1">
|
||||
<name>tickmarks</name>
|
||||
<enum>Both</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</vbox>
|
||||
</widget>
|
||||
</hbox>
|
||||
</widget>
|
||||
<widget>
|
||||
<class>QLayoutWidget</class>
|
||||
|
|
231
src/protocol.cpp
231
src/protocol.cpp
|
@ -72,14 +72,6 @@ MESSAGES
|
|||
|
||||
|
||||
/* Implementation *************************************************************/
|
||||
|
||||
|
||||
|
||||
// TODO take care of mutexing ressources!!!!!!
|
||||
|
||||
|
||||
|
||||
|
||||
CProtocol::CProtocol() : iCounter ( 0 ), iOldRecID ( PROTMESSID_ILLEGAL ),
|
||||
iOldRecCnt ( 0 )
|
||||
{
|
||||
|
@ -132,98 +124,6 @@ void CProtocol::SendMessage()
|
|||
}
|
||||
}
|
||||
|
||||
void CProtocol::DeleteSendMessQueue()
|
||||
{
|
||||
// delete complete "send message queue"
|
||||
SendMessQueue.clear();
|
||||
}
|
||||
|
||||
bool CProtocol::ParseMessage ( const CVector<unsigned char>& vecbyData,
|
||||
const int iNumBytes )
|
||||
{
|
||||
/*
|
||||
return code: true -> ok; false -> error
|
||||
*/
|
||||
int iRecCounter, iRecID, iData;
|
||||
unsigned int iPos;
|
||||
CVector<uint8_t> vecData;
|
||||
|
||||
|
||||
// convert unsigned char in uint8_t, TODO convert all buffers in uint8_t
|
||||
CVector<uint8_t> vecbyDataConv ( iNumBytes );
|
||||
for ( int i = 0; i < iNumBytes; i++ ) {
|
||||
vecbyDataConv[i] = static_cast<uint8_t> ( vecbyData[i] );
|
||||
}
|
||||
|
||||
|
||||
// important: vecbyDataConv must have iNumBytes to get it work!!!
|
||||
if ( ParseMessageFrame ( vecbyDataConv, iRecCounter, iRecID, vecData ) )
|
||||
{
|
||||
// In case we received a message and returned an answer but our answer
|
||||
// did not make it to the receiver, he will resend his message. We check
|
||||
// here if the message is the same as the old one, and if this is the
|
||||
// case, just resend our old answer again
|
||||
if ( ( iOldRecID == iRecID ) && ( iOldRecCnt == iRecCounter ) )
|
||||
{
|
||||
// acknowledgments are not acknowledged
|
||||
if ( iRecID != PROTMESSID_ACKN )
|
||||
{
|
||||
// re-send acknowledgement
|
||||
CreateAndSendAcknMess ( iRecID, iRecCounter );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check which type of message we received and do action
|
||||
switch ( iRecID )
|
||||
{
|
||||
case PROTMESSID_ACKN:
|
||||
|
||||
// extract data from stream and emit signal for received value
|
||||
iPos = 0;
|
||||
iData = static_cast<int> ( GetValFromStream ( vecData, iPos, 2 ) );
|
||||
|
||||
// check if this is the correct acknowledgment
|
||||
if ( ( SendMessQueue.front().iCnt == iRecCounter ) &&
|
||||
( SendMessQueue.front().iID == iData ) )
|
||||
{
|
||||
// message acknowledged, remove from queue
|
||||
SendMessQueue.pop_front();
|
||||
|
||||
// send next message in queue
|
||||
SendMessage();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PROTMESSID_JITT_BUF_SIZE:
|
||||
|
||||
// extract data from stream and emit signal for received value
|
||||
iPos = 0;
|
||||
iData = static_cast<int> ( GetValFromStream ( vecData, iPos, 2 ) );
|
||||
|
||||
// invoke message action
|
||||
emit ChangeJittBufSize ( iData );
|
||||
|
||||
// send acknowledge message
|
||||
CreateAndSendAcknMess ( iRecID, iRecCounter );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// save current message ID and counter to find out if message was re-sent
|
||||
iOldRecID = iRecID;
|
||||
iOldRecCnt = iRecCounter;
|
||||
|
||||
return true; // everything was ok
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; // return error code
|
||||
}
|
||||
}
|
||||
|
||||
void CProtocol::CreateAndSendAcknMess ( const int& iID, const int& iCnt )
|
||||
{
|
||||
CVector<uint8_t> vecAcknMessage;
|
||||
|
@ -240,46 +140,145 @@ void CProtocol::CreateAndSendAcknMess ( const int& iID, const int& iCnt )
|
|||
emit MessReadyForSending ( vecAcknMessage );
|
||||
}
|
||||
|
||||
void CProtocol::CreateJitBufMes ( const int iJitBufSize )
|
||||
|
||||
/*
|
||||
The following functions are access functions from different threads. These
|
||||
functions have to be secured by a mutex to avoid data corruption
|
||||
*/
|
||||
void CProtocol::DeleteSendMessQueue()
|
||||
{
|
||||
CVector<uint8_t> vecNewMessage;
|
||||
CVector<uint8_t> vecData ( 2 ); // 2 bytes of data
|
||||
unsigned int iPos = 0; // init position pointer
|
||||
Mutex.lock();
|
||||
{
|
||||
// delete complete "send message queue"
|
||||
SendMessQueue.clear();
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
// store current counter value
|
||||
const int iCurCounter = iCounter;
|
||||
void CProtocol::OnTimerSendMess()
|
||||
{
|
||||
Mutex.lock();
|
||||
{
|
||||
SendMessage();
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
// increase counter (wraps around automatically)
|
||||
// TODO: make it thread safe!!!!!!!!!!!!
|
||||
iCounter++;
|
||||
bool CProtocol::ParseMessage ( const CVector<unsigned char>& vecbyData,
|
||||
const int iNumBytes )
|
||||
{
|
||||
/*
|
||||
return code: true -> ok; false -> error
|
||||
*/
|
||||
Mutex.lock();
|
||||
{
|
||||
int iRecCounter, iRecID, iData;
|
||||
unsigned int iPos;
|
||||
CVector<uint8_t> vecData;
|
||||
|
||||
// build data vector
|
||||
PutValOnStream ( vecData, iPos, static_cast<uint32_t> ( iJitBufSize ), 2 );
|
||||
|
||||
// build complete message
|
||||
GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_JITT_BUF_SIZE, vecData );
|
||||
|
||||
// enqueue message
|
||||
EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_JITT_BUF_SIZE );
|
||||
// convert unsigned char in uint8_t, TODO convert all buffers in uint8_t
|
||||
CVector<uint8_t> vecbyDataConv ( iNumBytes );
|
||||
for ( int i = 0; i < iNumBytes; i++ ) {
|
||||
vecbyDataConv[i] = static_cast<uint8_t> ( vecbyData[i] );
|
||||
}
|
||||
|
||||
|
||||
// important: vecbyDataConv must have iNumBytes to get it work!!!
|
||||
if ( ParseMessageFrame ( vecbyDataConv, iRecCounter, iRecID, vecData ) )
|
||||
{
|
||||
// In case we received a message and returned an answer but our answer
|
||||
// did not make it to the receiver, he will resend his message. We check
|
||||
// here if the message is the same as the old one, and if this is the
|
||||
// case, just resend our old answer again
|
||||
if ( ( iOldRecID == iRecID ) && ( iOldRecCnt == iRecCounter ) )
|
||||
{
|
||||
// acknowledgments are not acknowledged
|
||||
if ( iRecID != PROTMESSID_ACKN )
|
||||
{
|
||||
// re-send acknowledgement
|
||||
CreateAndSendAcknMess ( iRecID, iRecCounter );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check which type of message we received and do action
|
||||
switch ( iRecID )
|
||||
{
|
||||
case PROTMESSID_ACKN:
|
||||
|
||||
// extract data from stream and emit signal for received value
|
||||
iPos = 0;
|
||||
iData = static_cast<int> ( GetValFromStream ( vecData, iPos, 2 ) );
|
||||
|
||||
// check if this is the correct acknowledgment
|
||||
if ( ( SendMessQueue.front().iCnt == iRecCounter ) &&
|
||||
( SendMessQueue.front().iID == iData ) )
|
||||
{
|
||||
// message acknowledged, remove from queue
|
||||
SendMessQueue.pop_front();
|
||||
|
||||
// send next message in queue
|
||||
SendMessage();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PROTMESSID_JITT_BUF_SIZE:
|
||||
|
||||
// extract data from stream and emit signal for received value
|
||||
iPos = 0;
|
||||
iData = static_cast<int> ( GetValFromStream ( vecData, iPos, 2 ) );
|
||||
|
||||
// invoke message action
|
||||
emit ChangeJittBufSize ( iData );
|
||||
|
||||
// send acknowledge message
|
||||
CreateAndSendAcknMess ( iRecID, iRecCounter );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// save current message ID and counter to find out if message was re-sent
|
||||
iOldRecID = iRecID;
|
||||
iOldRecCnt = iRecCounter;
|
||||
|
||||
return true; // everything was ok
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; // return error code
|
||||
}
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void CProtocol::CreateJitBufMes ( const int iJitBufSize )
|
||||
{
|
||||
Mutex.lock();
|
||||
{
|
||||
CVector<uint8_t> vecNewMessage;
|
||||
CVector<uint8_t> vecData ( 2 ); // 2 bytes of data
|
||||
unsigned int iPos = 0; // init position pointer
|
||||
|
||||
// store current counter value
|
||||
const int iCurCounter = iCounter;
|
||||
|
||||
// increase counter (wraps around automatically)
|
||||
iCounter++;
|
||||
|
||||
// build data vector
|
||||
PutValOnStream ( vecData, iPos, static_cast<uint32_t> ( iJitBufSize ), 2 );
|
||||
|
||||
// build complete message
|
||||
GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_JITT_BUF_SIZE, vecData );
|
||||
|
||||
// enqueue message
|
||||
EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_JITT_BUF_SIZE );
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************\
|
||||
|
|
|
@ -118,11 +118,12 @@ protected:
|
|||
uint8_t iCounter;
|
||||
int iOldRecID, iOldRecCnt;
|
||||
std::list<CSendMessage> SendMessQueue;
|
||||
|
||||
QTimer TimerSendMess;
|
||||
QMutex Mutex;
|
||||
|
||||
public slots:
|
||||
void OnTimerSendMess() { SendMessage(); }
|
||||
void OnTimerSendMess();
|
||||
|
||||
signals:
|
||||
// transmitting
|
||||
|
|
|
@ -105,14 +105,21 @@ void CSocket::OnDataReceived ()
|
|||
return;
|
||||
}
|
||||
|
||||
if ( pChannel->PutData( vecbyRecBuf, iNumBytesRead ) )
|
||||
{
|
||||
switch ( pChannel->PutData( vecbyRecBuf, iNumBytesRead ) )
|
||||
{
|
||||
case PS_AUDIO_OK:
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_GREEN );
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
case PS_AUDIO_ERR:
|
||||
case PS_GEN_ERROR:
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_RED );
|
||||
}
|
||||
break;
|
||||
|
||||
case PS_PROT_ERR:
|
||||
PostWinMessage ( MS_JIT_BUF_PUT, MUL_COL_LED_YELLOW );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue