*** empty log message ***
git-svn-id: http://yate.null.ro/svn/yate/trunk@324 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
b720d0221b
commit
800cea176a
|
@ -23,10 +23,15 @@
|
|||
|
||||
#include <yatertp.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace TelEngine;
|
||||
|
||||
RTPSession::RTPSession()
|
||||
: m_transport(0), m_direction(FullStop)
|
||||
: m_transport(0), m_direction(FullStop), m_sync(true),
|
||||
m_rxSsrc(0), m_rxTs(0), m_rxSeq(0),
|
||||
m_txSsrc(0), m_txTs(0), m_txSeq(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -54,8 +59,57 @@ void RTPSession::rtpData(const void* data, int len)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
// trivial check for basic fields validity
|
||||
if ((len < 12) || !data)
|
||||
return;
|
||||
const unsigned char* pc = (const unsigned char*)data;
|
||||
// check protocol version number
|
||||
if ((pc[0] & 0xc0) != 0x80)
|
||||
return;
|
||||
// check if padding is present and remove it
|
||||
if (pc[0] & 0x20) {
|
||||
len -= pc[len-1];
|
||||
if (len < 12)
|
||||
return;
|
||||
}
|
||||
bool ext = (pc[0] & 0x10) != 0;
|
||||
int cc = pc[0] & 0x0f;
|
||||
bool marker = (pc[1] & 0x80) != 0;
|
||||
int typ = pc[1] & 0x7f;
|
||||
u_int16_t seq = ((u_int16_t)pc[2] << 8) | pc[3];
|
||||
u_int32_t ts = ((u_int32_t)pc[4] << 24) | ((u_int32_t)pc[5] << 16) |
|
||||
((u_int32_t)pc[6] << 8) | pc[7];
|
||||
u_int32_t ss = ((u_int32_t)pc[8] << 24) | ((u_int32_t)pc[9] << 16) |
|
||||
((u_int32_t)pc[10] << 8) | pc[11];
|
||||
|
||||
// grab some data at the first packet received or resync
|
||||
if (m_sync) {
|
||||
m_sync = false;
|
||||
m_rxSsrc = ss;
|
||||
m_rxTs = ts;
|
||||
m_rxSeq = seq;
|
||||
}
|
||||
|
||||
// check if the SSRC is unchanged
|
||||
if (ss != m_rxSsrc)
|
||||
return;
|
||||
|
||||
// skip over header and any CSRC
|
||||
pc += 12+(4*cc);
|
||||
len -= 12+(4*cc);
|
||||
// check if extension is present and skip it
|
||||
if (ext) {
|
||||
if (len < 4)
|
||||
return;
|
||||
int xl = ((int)pc[2] << 8) | pc[3];
|
||||
pc += xl+4;
|
||||
len -= xl+4;
|
||||
}
|
||||
if (len < 0)
|
||||
return;
|
||||
if (!len)
|
||||
pc = 0;
|
||||
rtpRecv(marker,typ,ts-m_rxTs,pc,len);
|
||||
}
|
||||
|
||||
void RTPSession::rtcpData(const void* data, int len)
|
||||
|
@ -92,4 +146,51 @@ bool RTPSession::direction(Direction dir)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool RTPSession::rtpRecv(bool marker, int payload, unsigned int timestamp, const void* data, int len)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RTPSession::rtpSend(bool marker, int payload, unsigned int timestamp, const void* data, int len)
|
||||
{
|
||||
switch (m_direction) {
|
||||
case FullStop:
|
||||
case RecvOnly:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!m_transport)
|
||||
return false;
|
||||
|
||||
if (!data)
|
||||
len = 0;
|
||||
payload &= 0x7f;
|
||||
if (marker)
|
||||
payload |= 0x80;
|
||||
timestamp += m_txTs;
|
||||
if (!m_txSsrc)
|
||||
m_txSsrc = ::random();
|
||||
m_txSeq++;
|
||||
|
||||
DataBlock buf(0,len+12);
|
||||
unsigned char* pc = (unsigned char*)buf.data();
|
||||
*pc++ = 0x80;
|
||||
*pc++ = payload;
|
||||
*pc++ = m_txSeq >> 8;
|
||||
*pc++ = m_txSeq & 0xff;
|
||||
*pc++ = timestamp >> 24;
|
||||
*pc++ = timestamp >> 16;
|
||||
*pc++ = timestamp >> 8;
|
||||
*pc++ = timestamp & 0xff;
|
||||
*pc++ = m_txSsrc >> 24;
|
||||
*pc++ = m_txSsrc >> 16;
|
||||
*pc++ = m_txSsrc >> 8;
|
||||
*pc++ = m_txSsrc & 0xff;
|
||||
if (data && len)
|
||||
::memcpy(pc,data,len);
|
||||
static_cast<RTPProcessor*>(m_transport)->rtpData(buf.data(),buf.length());
|
||||
return true;
|
||||
}
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
|
@ -281,10 +281,29 @@ public:
|
|||
* @param timestamp Sampling instant of the packet data
|
||||
* @param data Pointer to data block to process
|
||||
* @param len Length of the data block
|
||||
* @return True if data was handled
|
||||
*/
|
||||
virtual void rtpPayload(bool marker, int payload, unsigned timestamp,
|
||||
virtual bool rtpRecv(bool marker, int payload, unsigned int timestamp,
|
||||
const void* data, int len);
|
||||
|
||||
/**
|
||||
* Send one RTP payload packet
|
||||
* @param marker Set to true if the marker bit must be set
|
||||
* @param payload Payload number
|
||||
* @param timestamp Sampling instant of the packet data
|
||||
* @param data Pointer to data block to send
|
||||
* @param len Length of the data block
|
||||
* @return True if data sending was attempted
|
||||
*/
|
||||
bool rtpSend(bool marker, int payload, unsigned int timestamp,
|
||||
const void* data, int len);
|
||||
|
||||
/**
|
||||
* Request a resync on the first packet arrived
|
||||
*/
|
||||
inline void resync()
|
||||
{ m_sync = true; }
|
||||
|
||||
/**
|
||||
* Get the RTP/RTCP transport of data handled by this session
|
||||
* @return A pointer to the RTPTransport of this session
|
||||
|
@ -353,6 +372,13 @@ protected:
|
|||
private:
|
||||
RTPTransport* m_transport;
|
||||
Direction m_direction;
|
||||
bool m_sync;
|
||||
u_int32_t m_rxSsrc;
|
||||
u_int32_t m_rxTs;
|
||||
u_int16_t m_rxSeq;
|
||||
u_int32_t m_txSsrc;
|
||||
u_int32_t m_txTs;
|
||||
u_int16_t m_txSeq;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue