123
This commit is contained in:
628
CryNetwork/CTPEndpointGNB.cpp
Normal file
628
CryNetwork/CTPEndpointGNB.cpp
Normal file
@@ -0,0 +1,628 @@
|
||||
#include "stdafx.h"
|
||||
#include "ctpendpointgnb.h"
|
||||
#include <IDataProbe.h>
|
||||
|
||||
#define PACKET_SIZE_COMPRESSION_LIMIT 100
|
||||
|
||||
|
||||
CCTPEndpointGNB::CCTPEndpointGNB( CNetwork *pNetwork )
|
||||
{
|
||||
m_pNetwork = pNetwork;
|
||||
Reset();
|
||||
|
||||
m_bCompress = true;
|
||||
m_nEncryptKey[0] = 1282732178u;
|
||||
m_nEncryptKey[1] = 1718763272u;
|
||||
m_nEncryptKey[2] = 297614432u;
|
||||
m_nEncryptKey[3] = 3389628651u;
|
||||
}
|
||||
|
||||
CCTPEndpointGNB::~CCTPEndpointGNB(void)
|
||||
{
|
||||
}
|
||||
|
||||
void CCTPEndpointGNB::SetPublicCryptKey( unsigned int key )
|
||||
{
|
||||
m_nEncryptKey[2] = key;
|
||||
}
|
||||
|
||||
static bool Between(LONG a, LONG b, LONG c)
|
||||
{
|
||||
return ((a <= b) &&(b < c)) ||((c < a) &&(a <= b)) ||((b < c) &&(c < a));
|
||||
}
|
||||
|
||||
void CCTPEndpointGNB::Reset()
|
||||
{
|
||||
m_nFrameExpected=0;
|
||||
m_nNextFrameToSend=0;
|
||||
m_nAckExpected=0;
|
||||
m_nBuffered=0; //number of output buffers currently used
|
||||
m_nCurrentTime=0;
|
||||
m_dwOutAckTimer=0;
|
||||
m_dwPingTime=0;
|
||||
m_nLostPackets=0;
|
||||
m_nUnreliableLostPackets=0;
|
||||
m_nBuffered=0;
|
||||
for (long n = 0; n < NUM_OF_BUFS; n++)
|
||||
{
|
||||
m_OutBuffers[n].dwTimeout = 0;
|
||||
m_OutBuffers[n].nSeq = 0;
|
||||
// m_nArrived[n]=false;
|
||||
}
|
||||
|
||||
while (!m_qOutgoingReliableData.empty())
|
||||
{
|
||||
m_qOutgoingReliableData.pop();
|
||||
}
|
||||
while (!m_qOutgoingUnreliableData.empty())
|
||||
{
|
||||
m_qOutgoingUnreliableData.pop();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCTPEndpointGNB::CryptPacket( CTPData &data )
|
||||
{
|
||||
// Write 1 bit of compressed packed info.
|
||||
data.m_bCompressed = false;
|
||||
CStream &stm = data.m_stmData;
|
||||
unsigned int* pBuffer = (unsigned int*)stm.GetPtr();
|
||||
unsigned int srclen = (stm.GetSize()+7)/8; // Always cover last byte.
|
||||
unsigned int destlen = srclen;
|
||||
// Try to compress big packets.
|
||||
if (srclen > PACKET_SIZE_COMPRESSION_LIMIT && m_pNetwork->IsPacketCompressionEnabled())
|
||||
{
|
||||
BYTE temp[DEFAULT_STREAM_BYTESIZE*2];
|
||||
destlen = sizeof(temp);
|
||||
IDataProbe *pProbe = GetISystem()->GetIDataProbe();
|
||||
pProbe->Compress( temp,destlen,pBuffer,srclen,1 );
|
||||
if (destlen < srclen)
|
||||
{
|
||||
data.m_bCompressed = true;
|
||||
data.m_nUncompressedSize = stm.GetSize(); // In bits.
|
||||
TEA_ENCODE( (unsigned int*)temp,(unsigned int*)temp,TEA_GETSIZE(destlen),m_nEncryptKey );
|
||||
stm.Reset();
|
||||
stm.WriteBits(temp,destlen*8);
|
||||
}
|
||||
}
|
||||
if (data.m_bCompressed)
|
||||
{
|
||||
//@TOOD: remove log.
|
||||
float f1 = 100.0f/srclen;
|
||||
float f2 = f1 * destlen;
|
||||
int prc = (int)(100 - f2);
|
||||
//if (m_pNetwork->GetLogLevel() > 1)
|
||||
//CryLog( "<NET> PckSize Compressed: Was:%.3d Now:%.3d, Win: %.2d%%",srclen,destlen,prc );
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = stm.GetSize()/8;
|
||||
if (len >= 8)
|
||||
{
|
||||
TEA_ENCODE( pBuffer,pBuffer,TEA_GETSIZE(len),m_nEncryptKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CCTPEndpointGNB::UncryptPacket( CTPData &data )
|
||||
{
|
||||
CStream &stm = data.m_stmData;
|
||||
if (data.m_bCompressed)
|
||||
{
|
||||
// Compressed data packet.
|
||||
BYTE temp[DEFAULT_STREAM_BYTESIZE*2];
|
||||
unsigned int* pBuffer = (unsigned int*)stm.GetPtr();
|
||||
int srclen = (stm.GetSize()+7)/8; // Always cover last byte.
|
||||
TEA_DECODE( pBuffer,pBuffer,TEA_GETSIZE(srclen),m_nEncryptKey );
|
||||
unsigned int destLen = sizeof(temp);
|
||||
IDataProbe *pProbe = GetISystem()->GetIDataProbe();
|
||||
pProbe->Uncompress( temp,destLen,pBuffer,srclen );
|
||||
|
||||
stm.Reset();
|
||||
stm.WriteBits( temp,data.m_nUncompressedSize );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Uncompressed data packet.
|
||||
unsigned int* pBuffer = (unsigned int*)stm.GetPtr();
|
||||
int len = stm.GetSize()/8;
|
||||
if (len >= 8)
|
||||
{
|
||||
TEA_DECODE( pBuffer,pBuffer,TEA_GETSIZE(len),m_nEncryptKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CCTPEndpointGNB::SendUnreliable(CStream &stmData)
|
||||
{
|
||||
m_qOutgoingUnreliableData.push(stmData);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCTPEndpointGNB::SendReliable(CStream &stmData)
|
||||
{
|
||||
m_qOutgoingReliableData.push(stmData);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCTPEndpointGNB::Update(unsigned int nTime,unsigned char cFrameType,CStream *pStm)
|
||||
{
|
||||
m_nCurrentTime = nTime;
|
||||
CTP *pFrame = NULL;
|
||||
CTPAck ack;
|
||||
CTPData data;
|
||||
CTPPong pong;
|
||||
if (cFrameType)
|
||||
{
|
||||
switch (cFrameType)
|
||||
{
|
||||
case FT_CTP_DATA:
|
||||
{
|
||||
data.Load(*pStm);
|
||||
pFrame = &data;
|
||||
HandleDataFrame(data);
|
||||
}
|
||||
break;
|
||||
case FT_CTP_ACK:
|
||||
{
|
||||
pFrame = &ack;
|
||||
ack.Load(*pStm);
|
||||
}
|
||||
break;
|
||||
case FT_CTP_PONG:
|
||||
{
|
||||
pong.Load(*pStm);
|
||||
m_LatencyCalculator.AddSample((float)m_nCurrentTime - m_dwPingTime, m_nCurrentTime, pong.m_nTimestamp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NET_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
///////////////////////////////////////////////////////////
|
||||
if (pFrame)
|
||||
{
|
||||
if (pFrame->m_bPingRequest == true)
|
||||
{
|
||||
CStream stm;
|
||||
CTPPong pong;
|
||||
// pong.m_cClientID = m_pParent->GetID();
|
||||
pong.m_nTimestamp = m_nCurrentTime;
|
||||
pong.Save(stm);
|
||||
m_pParent->Send(stm);
|
||||
}
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// manage piggybacked ack (all frames hold a piggybacked ack)
|
||||
|
||||
NET_TRACE("--->>>[CTP] SEQ %02d ACK %02d\n", pFrame->m_cSequenceNumber, pFrame->m_cAck);
|
||||
|
||||
if(!pFrame->m_bUnreliable)
|
||||
while (Between(m_nAckExpected, pFrame->m_cAck, m_nNextFrameToSend))
|
||||
{
|
||||
m_nBuffered = m_nBuffered - 1;
|
||||
NET_TRACE("Ack [%02d] STOPPING TIMER m_nBuffered=%02d\n",pFrame->m_cAck,m_nBuffered);
|
||||
StopTimer(m_nAckExpected%NUM_OF_BUFS);
|
||||
INC(m_nAckExpected);
|
||||
}
|
||||
}
|
||||
}
|
||||
// handle outgoing buffer timers
|
||||
ProcessBufferTimers();
|
||||
|
||||
// if there is some out-buffer free, I retrive some new data to send
|
||||
// and if the network layer is ready(enough bandwith) ...send outgoing frames
|
||||
if (IsTimeToSend())
|
||||
{
|
||||
BuildOutgoingFrame();
|
||||
}
|
||||
// handle ack timer
|
||||
ProcessAckTimer();
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CCTPEndpointGNB::SetRate(unsigned int nBytePerSec)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CCTPEndpointGNB::Dump()
|
||||
{
|
||||
NET_TRACE("m_nFrameExpected=%d |||", m_nFrameExpected);
|
||||
NET_TRACE("m_nBuffered=%d |||", m_nBuffered);
|
||||
NET_TRACE("m_nAckExpected=%d |||", m_nAckExpected);
|
||||
NET_TRACE("m_nNextFrameToSend=%d\n", m_nNextFrameToSend);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
unsigned int CCTPEndpointGNB::GetPing()
|
||||
{
|
||||
return (unsigned int)m_LatencyCalculator.GetAverageLatency();
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CCTPEndpointGNB::HandleDataFrame(CTPData &f)
|
||||
{
|
||||
CStream stmUncompressed;
|
||||
if(f.m_bUnreliable)
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//UNRELIABLE PACKET
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//if the packet is out of sequence will be discarded
|
||||
if(f.m_cSequenceNumber==m_nFrameExpected)
|
||||
{
|
||||
// CStream stmUncompressed=UncompressStream(f.m_stmData);
|
||||
// m_pParent->OnData(stmUncompressed);
|
||||
UncryptPacket( f );
|
||||
m_pParent->OnData( f.m_stmData );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nUnreliableLostPackets++;
|
||||
NET_TRACE("[%02d]expected-[%02d]received Packet discarded\n",m_nFrameExpected,f.m_cSequenceNumber);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//RELIABLE PACKET
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(f.m_cSequenceNumber==m_nFrameExpected)
|
||||
{
|
||||
// CStream stmUncompressed=UncompressStream(f.m_stmData);
|
||||
// m_pParent->OnData(stmUncompressed);
|
||||
//UncryptStream( f.m_stmData );
|
||||
//m_pParent->OnData(f.m_stmData);
|
||||
UncryptPacket( f );
|
||||
m_pParent->OnData( f.m_stmData );
|
||||
|
||||
INC(m_nFrameExpected);
|
||||
SetAckTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetAckTimer();
|
||||
|
||||
NET_TRACE("[%02d]expected-[%02d]received Packet discarded\n",m_nFrameExpected,f.m_cSequenceNumber);
|
||||
}
|
||||
|
||||
while(Between(m_nAckExpected,f.m_cAck,m_nNextFrameToSend))
|
||||
{
|
||||
m_nBuffered=m_nBuffered-1;
|
||||
StopTimer(m_nAckExpected%NUM_OF_BUFS);
|
||||
INC(m_nAckExpected);
|
||||
}
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void CCTPEndpointGNB::ProcessBufferTimers()
|
||||
{
|
||||
unsigned int ulTick = m_nCurrentTime;
|
||||
DWORD nLowest = 0xFFFFFFFF;
|
||||
DWORD nLowestIdx;
|
||||
bool bFound = false;
|
||||
// search for the oldest timer
|
||||
for (long n = 0; n < NUM_OF_BUFS; n++)
|
||||
{
|
||||
if ((m_OutBuffers[n].dwTimeout != 0) &&(m_OutBuffers[n].dwTimeout < nLowest))
|
||||
{
|
||||
bFound = true;
|
||||
nLowest = m_OutBuffers[n].dwTimeout;
|
||||
nLowestIdx = n;
|
||||
}
|
||||
}
|
||||
// test the oldest timer
|
||||
if (bFound)
|
||||
{
|
||||
/* if ((ulTick - nLowest)>(TM_BUFFER + m_LatencyCalculator.GetAverageLatency()))
|
||||
{
|
||||
/////////////////////////////////
|
||||
m_OutBuffers[nLowestIdx].dwTimeout = 0;
|
||||
HandleTimeout(m_OutBuffers[nLowestIdx].nSeq);
|
||||
}
|
||||
}*/
|
||||
DWORD dwTO=TM_BUFFER + (DWORD)(m_LatencyCalculator.GetAverageLatency());
|
||||
for (int n = 0; n < NUM_OF_BUFS; n++)
|
||||
{
|
||||
if((m_OutBuffers[nLowestIdx].dwTimeout!=0) && ((ulTick-m_OutBuffers[nLowestIdx].dwTimeout)>dwTO))
|
||||
{
|
||||
m_OutBuffers[nLowestIdx].dwTimeout = 0;
|
||||
HandleTimeout(m_OutBuffers[nLowestIdx].nSeq);
|
||||
}
|
||||
nLowestIdx=(nLowestIdx+1)%NUM_OF_BUFS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCTPEndpointGNB::ProcessAckTimer()
|
||||
{
|
||||
// Process Ack timeout
|
||||
unsigned int ulTick = m_nCurrentTime;
|
||||
/////////////////////////////////
|
||||
if (m_dwOutAckTimer)
|
||||
{
|
||||
if ((ulTick - m_dwOutAckTimer)>(TM_ACK + m_LatencyCalculator.GetAverageLatency()))
|
||||
{
|
||||
HandleAckTimeout();
|
||||
m_dwOutAckTimer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CCTPEndpointGNB::IsTimeToSend()
|
||||
{
|
||||
if (m_nBuffered < NUM_OF_BUFS)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CCTPEndpointGNB::HandleAckTimeout()
|
||||
{
|
||||
NET_TRACE("HandleAckTimeout()\n");
|
||||
SendFrame(FT_CTP_ACK, 0, m_nFrameExpected);
|
||||
}
|
||||
|
||||
|
||||
void CCTPEndpointGNB::HandleTimeout(LONG nOldestFrame)
|
||||
{
|
||||
NET_TRACE("HandleTimeout()\n");
|
||||
m_nLostPackets++;
|
||||
if (m_nBuffered)
|
||||
SendFrame(FT_CTP_DATA, nOldestFrame, m_nFrameExpected);
|
||||
}
|
||||
|
||||
/*
|
||||
CStream CCTPEndpointGNB::CompressStream(CStream &stmUncompressed)
|
||||
{
|
||||
CStream stmCompressed;
|
||||
#ifdef USE_PACKET_COMPRESSION
|
||||
if(m_bCompress)
|
||||
{
|
||||
BYTE *pUncompressed=NULL;
|
||||
pUncompressed=stmUncompressed.GetPtr();
|
||||
unsigned short nUncompressedSizeInBits=(unsigned short)stmUncompressed.GetSize();
|
||||
unsigned short nUncompressedSize=BITS2BYTES(nUncompressedSizeInBits);
|
||||
unsigned short n=0;
|
||||
stmCompressed.Write(true);
|
||||
stmCompressed.Write(nUncompressedSizeInBits);
|
||||
while(n<nUncompressedSize)
|
||||
{
|
||||
BYTE b;
|
||||
|
||||
b=pUncompressed[n];
|
||||
if(b==0)
|
||||
{
|
||||
//write a 0
|
||||
stmCompressed.Write(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//write a 1
|
||||
stmCompressed.Write(true);
|
||||
//write a byte
|
||||
stmCompressed.Write(b);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stmCompressed.Write(false);
|
||||
stmCompressed.WriteBits(stmUncompressed.GetPtr(),stmUncompressed.GetSize());
|
||||
}
|
||||
|
||||
#else
|
||||
stmCompressed=stmUncompressed;
|
||||
#endif
|
||||
return stmCompressed;
|
||||
}
|
||||
|
||||
CStream CCTPEndpointGNB::UncompressStream(CStream &stmCompressed)
|
||||
{
|
||||
CStream stmUncompressed;
|
||||
#ifdef USE_PACKET_COMPRESSION
|
||||
unsigned short nUncompressedSize;
|
||||
stmUncompressed.Reset();
|
||||
bool bIsCompressed;
|
||||
stmCompressed.Read(bIsCompressed);
|
||||
if(bIsCompressed){
|
||||
stmCompressed.Read(nUncompressedSize);
|
||||
while(!stmCompressed.EOS())
|
||||
{
|
||||
bool bBit;
|
||||
BYTE bData;
|
||||
stmCompressed.Read(bBit);
|
||||
if(bBit)
|
||||
{
|
||||
stmCompressed.Read(bData);
|
||||
}
|
||||
else
|
||||
{
|
||||
bData=0;
|
||||
}
|
||||
stmUncompressed.Write(bData);
|
||||
if(stmUncompressed.GetSize()==nUncompressedSize)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stmCompressed.Read(stmUncompressed);
|
||||
}
|
||||
#else
|
||||
stmUncompressed=stmCompressed;
|
||||
#endif
|
||||
return stmUncompressed;
|
||||
}
|
||||
*/
|
||||
void CCTPEndpointGNB::SendFrame(LONG nType, LONG nFrameNum, LONG nFrameExpected, CStream *pUnreliable,bool bUnreliable)
|
||||
{
|
||||
static BYTE cUncompressed[1000];
|
||||
CTPData data;
|
||||
CTPAck ack;
|
||||
CTPNak nak;
|
||||
CTP *pFrame;
|
||||
switch (nType)
|
||||
{
|
||||
case FT_CTP_DATA:
|
||||
pFrame = &data;
|
||||
break;
|
||||
case FT_CTP_ACK:
|
||||
pFrame = &ack;
|
||||
break;
|
||||
default:
|
||||
NET_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
pFrame->m_cFrameType=(BYTE)nType;
|
||||
pFrame->m_bSecondaryTC=m_bSecondary;
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//DATA
|
||||
//////////////////////////////////////////////////////////////////
|
||||
if (nType == FT_CTP_DATA)
|
||||
{
|
||||
if(!bUnreliable)
|
||||
{
|
||||
data.m_stmData = m_OutBuffers[nFrameNum%NUM_OF_BUFS].stmData;
|
||||
m_OutBuffers[nFrameNum%NUM_OF_BUFS].nSeq = nFrameNum;
|
||||
if (pUnreliable)
|
||||
{
|
||||
if(pUnreliable->GetSize())
|
||||
data.m_stmData.Write(*pUnreliable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data.m_stmData = *pUnreliable;
|
||||
}
|
||||
CryptPacket( data );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//SEQ AND ACK
|
||||
pFrame->m_bUnreliable = bUnreliable;
|
||||
|
||||
pFrame->m_cSequenceNumber =(BYTE) nFrameNum;
|
||||
|
||||
pFrame->m_cAck =(BYTE) (nFrameExpected + MAX_SEQ_NUM)%(MAX_SEQ_NUM + 1);
|
||||
|
||||
if(nType == FT_CTP_DATA)
|
||||
{
|
||||
NET_TRACE("SEND [CTP] %s FRAME SEQ [%02d] ACK [%02d] \n",pFrame->m_bUnreliable?"unreliable":"reliable",pFrame->m_cSequenceNumber,pFrame->m_cAck);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//CHECK IF A PING REQUEST IS NEEDED
|
||||
if ((!m_bSecondary) && m_LatencyCalculator.IsTimeToPing(m_nCurrentTime))
|
||||
{
|
||||
m_dwPingTime = m_nCurrentTime;
|
||||
// set a piggybacked pong request
|
||||
pFrame->m_bPingRequest = true;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//SERIALIZE THE FRAME
|
||||
CStream stm;
|
||||
pFrame->Save(stm);
|
||||
m_pParent->Send(stm);
|
||||
|
||||
// Update the rate control
|
||||
m_nAllowedBytes -= BITS2BYTES(stm.GetSize());
|
||||
m_nLastPacketSent = m_nCurrentTime;
|
||||
// NET_TRACE(">>m_nAllowedBytes=%d\n",m_nAllowedBytes);
|
||||
|
||||
//////////////////////////////////////////
|
||||
if (nType == FT_CTP_DATA && (!bUnreliable))
|
||||
SetTimer(nFrameNum%NUM_OF_BUFS);
|
||||
|
||||
if(!bUnreliable)
|
||||
StopAckTimer();
|
||||
}
|
||||
|
||||
|
||||
void CCTPEndpointGNB::SetAckTimer()
|
||||
{
|
||||
if (m_dwOutAckTimer == 0)
|
||||
m_dwOutAckTimer = m_nCurrentTime;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//! stop the ack timer
|
||||
void CCTPEndpointGNB::StopAckTimer()
|
||||
{
|
||||
m_dwOutAckTimer = 0;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//! set packet retrasmisson timeout
|
||||
void CCTPEndpointGNB::SetTimer(LONG nIndex)
|
||||
{
|
||||
m_OutBuffers[nIndex].dwTimeout = m_nCurrentTime;
|
||||
NET_TRACE("SETTIMER %02d %d\n",nIndex,m_nCurrentTime);
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//! stop packet retrasmisson timeout
|
||||
void CCTPEndpointGNB::StopTimer(LONG nIndex)
|
||||
{
|
||||
DWORD nTimeout = m_OutBuffers[nIndex].dwTimeout;
|
||||
m_OutBuffers[nIndex].dwTimeout=0;
|
||||
NET_TRACE("STOPTIMER %02d %d\n",nIndex,nTimeout);
|
||||
}
|
||||
|
||||
|
||||
void CCTPEndpointGNB::BuildOutgoingFrame()
|
||||
{
|
||||
if (m_qOutgoingReliableData.empty() == false || m_qOutgoingUnreliableData.empty() == false)
|
||||
{
|
||||
CStream stmUnreliable;
|
||||
|
||||
CStream &stm=m_OutBuffers[m_nNextFrameToSend%NUM_OF_BUFS].stmData;
|
||||
stm.Reset();
|
||||
while ((!m_qOutgoingReliableData.empty())
|
||||
&& ((stm.GetSize() + m_qOutgoingReliableData.front().GetSize()) < MAX_PLAYLOAD_SIZE_IN_BITS))
|
||||
{
|
||||
stm.Write(m_qOutgoingReliableData.front());
|
||||
m_qOutgoingReliableData.pop();
|
||||
}
|
||||
while ((!m_qOutgoingUnreliableData.empty())
|
||||
&& ((stm.GetSize() + m_qOutgoingUnreliableData.front().GetSize()) < MAX_PLAYLOAD_SIZE_IN_BITS))
|
||||
{
|
||||
stmUnreliable.Write(m_qOutgoingUnreliableData.front());
|
||||
m_qOutgoingUnreliableData.pop();
|
||||
}
|
||||
//CHECK IF THERE IS RELIABLE DATA IN THE QUEUE
|
||||
if(stm.GetSize()>0)
|
||||
{
|
||||
SendFrame(FT_CTP_DATA, m_nNextFrameToSend, m_nFrameExpected, &stmUnreliable,false);
|
||||
INC(m_nNextFrameToSend);
|
||||
m_nBuffered += 1;
|
||||
NET_ASSERT(m_nBuffered<=NUM_OF_BUFS);
|
||||
NET_TRACE("SEND RELIABLE m_nBuffered=%02d\n",m_nBuffered);
|
||||
}
|
||||
else
|
||||
{
|
||||
//IF THERE ISN'T RELIABLE DATA SEND A UNRELIABLE ONLY PACKET
|
||||
//IF THERE IS UNRELIABLE DATA
|
||||
if(stmUnreliable.GetSize()>0)
|
||||
{
|
||||
SendFrame(FT_CTP_DATA, m_nNextFrameToSend, m_nFrameExpected, &stmUnreliable,true);
|
||||
NET_TRACE("SEND UNRELIABLE\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCTPEndpointGNB::GetMemoryStatistics(ICrySizer *pSizer)
|
||||
{
|
||||
pSizer->AddObject(&m_qOutgoingReliableData,m_qOutgoingReliableData.size()*sizeof(CStream));
|
||||
pSizer->AddObject(&m_qOutgoingUnreliableData,m_qOutgoingUnreliableData.size()*sizeof(CStream));
|
||||
}
|
||||
Reference in New Issue
Block a user