2014-11-14 21:28:27 +01:00
|
|
|
/*
|
|
|
|
* rtcp.c: SAT>IP plugin for the Video Disk Recorder
|
|
|
|
*
|
|
|
|
* See the README file for copyright information and how to reach the author.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "rtcp.h"
|
|
|
|
|
|
|
|
cSatipRtcp::cSatipRtcp(cSatipTunerIf &tunerP, unsigned int bufferLenP)
|
2014-11-16 16:02:30 +01:00
|
|
|
: tunerM(tunerP),
|
2014-11-14 21:28:27 +01:00
|
|
|
bufferLenM(bufferLenP),
|
|
|
|
bufferM(MALLOC(unsigned char, bufferLenM))
|
|
|
|
{
|
2014-11-21 22:56:03 +01:00
|
|
|
debug("cSatipRtcp::%s(%u) [device %d]", __FUNCTION__, bufferLenP, tunerM.GetId());
|
2014-11-14 21:28:27 +01:00
|
|
|
if (bufferM)
|
|
|
|
memset(bufferM, 0, bufferLenM);
|
|
|
|
else
|
|
|
|
error("Cannot create RTCP buffer!");
|
|
|
|
}
|
|
|
|
|
|
|
|
cSatipRtcp::~cSatipRtcp()
|
|
|
|
{
|
2014-11-21 22:56:03 +01:00
|
|
|
debug("cSatipRtcp::%s() [device %d]", __FUNCTION__, tunerM.GetId());
|
2014-11-14 21:28:27 +01:00
|
|
|
DELETE_POINTER(bufferM);
|
|
|
|
}
|
|
|
|
|
|
|
|
int cSatipRtcp::GetFd(void)
|
|
|
|
{
|
2014-11-21 22:56:03 +01:00
|
|
|
//debug("cSatipRtcp::%s() [device %d]", __FUNCTION__, tunerM.GetId());
|
2014-11-14 21:28:27 +01:00
|
|
|
return Fd();
|
|
|
|
}
|
|
|
|
|
2014-11-16 09:31:34 +01:00
|
|
|
int cSatipRtcp::GetApplicationOffset(int *lengthP)
|
|
|
|
{
|
2014-11-23 18:08:15 +01:00
|
|
|
//debug("cSatipRtcp::%s(%d) [device %d]", __FUNCTION__, *lengthP, tunerM.GetId());
|
2014-11-16 09:31:34 +01:00
|
|
|
if (!lengthP)
|
|
|
|
return -1;
|
|
|
|
int offset = 0;
|
|
|
|
int total = *lengthP;
|
|
|
|
while (total > 0) {
|
|
|
|
// Version
|
|
|
|
unsigned int v = (bufferM[offset] >> 6) & 0x03;
|
|
|
|
// Padding
|
|
|
|
//unsigned int p = (bufferM[offset] >> 5) & 0x01;
|
|
|
|
// Subtype
|
|
|
|
//unsigned int st = bufferM[offset] & 0x1F;
|
|
|
|
// Payload type
|
|
|
|
unsigned int pt = bufferM[offset + 1] & 0xFF;
|
|
|
|
// Lenght
|
|
|
|
unsigned int length = ((bufferM[offset + 2] & 0xFF) << 8) | (bufferM[offset + 3] & 0xFF);
|
|
|
|
// Convert it to bytes
|
|
|
|
length = (length + 1) * 4;
|
|
|
|
// V=2, APP = 204
|
|
|
|
if ((v == 2) && (pt == 204)) {
|
|
|
|
// SSCR/CSCR
|
|
|
|
//unsigned int ssrc = ((bufferM[offset + 4] & 0xFF) << 24) | ((bufferM[offset + 5] & 0xFF) << 16) |
|
|
|
|
// ((bufferM[offset + 6] & 0xFF) << 8) | (bufferM[offset + 7] & 0xFF);
|
|
|
|
// Name
|
|
|
|
if ((bufferM[offset + 8] == 'S') && (bufferM[offset + 9] == 'E') &&
|
|
|
|
(bufferM[offset + 10] == 'S') && (bufferM[offset + 11] == '1')) {
|
|
|
|
// Identifier
|
|
|
|
//unsigned int id = ((bufferM[offset + 12] & 0xFF) << 8) | (bufferM[offset + 13] & 0xFF);
|
|
|
|
// String length
|
|
|
|
int string_length = ((bufferM[offset + 14] & 0xFF) << 8) | (bufferM[offset + 15] & 0xFF);
|
|
|
|
if (string_length > 0) {
|
|
|
|
*lengthP = string_length;
|
|
|
|
return (offset + 16);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
offset += length;
|
|
|
|
total -= length;
|
|
|
|
}
|
|
|
|
*lengthP = 0;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-11-25 21:04:34 +01:00
|
|
|
void cSatipRtcp::Process(void)
|
2014-11-14 21:28:27 +01:00
|
|
|
{
|
2014-11-25 21:04:34 +01:00
|
|
|
//debug("cSatipRtcp::%s() [device %d]", __FUNCTION__, tunerM.GetId());
|
2014-11-14 21:28:27 +01:00
|
|
|
if (bufferM) {
|
2014-11-27 21:03:56 +01:00
|
|
|
int length;
|
|
|
|
while ((length = Read(bufferM, bufferLenM)) > 0) {
|
|
|
|
int offset = GetApplicationOffset(&length);
|
|
|
|
if (offset >= 0)
|
|
|
|
tunerM.ProcessApplicationData(bufferM + offset, length);
|
|
|
|
}
|
|
|
|
if (errno != EAGAIN && errno != EWOULDBLOCK)
|
|
|
|
error("Error %d reading from RTCP socket [device %d]", errno, tunerM.GetId());
|
2014-11-14 21:28:27 +01:00
|
|
|
}
|
|
|
|
}
|