void RTCPCompoundPacketBuilder::ClearBuildBuffers()
{
	report.Clear();
	sdes.Clear();

	std::list<Buffer>::const_iterator it;
	for (it = byepackets.begin() ; it != byepackets.end() ; it++)
	{
		if ((*it).packetdata)
			RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
	}
	for (it = apppackets.begin() ; it != apppackets.end() ; it++)
	{
		if ((*it).packetdata)
			RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
	}
#ifdef RTP_SUPPORT_RTCPUNKNOWN
	for (it = unknownpackets.begin() ; it != unknownpackets.end() ; it++)
	{
		if ((*it).packetdata)
			RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
	}
#endif // RTP_SUPPORT_RTCPUNKNOWN 

	byepackets.clear();
	apppackets.clear();
#ifdef RTP_SUPPORT_RTCPUNKNOWN
	unknownpackets.clear();
#endif // RTP_SUPPORT_RTCPUNKNOWN 
	byesize = 0;
	appsize = 0;
#ifdef RTP_SUPPORT_RTCPUNKNOWN
	unknownsize = 0;
#endif // RTP_SUPPORT_RTCPUNKNOWN 
}
示例#2
0
void RTPSession::Destroy()
{
	if (!created)
		return;

#ifdef RTP_SUPPORT_THREAD
	if (pollthread)
		RTPDelete(pollthread,GetMemoryManager());
#endif // RTP_SUPPORT_THREAD
	
	if (deletetransmitter)
		RTPDelete(rtptrans,GetMemoryManager());
	packetbuilder.Destroy();
	rtcpbuilder.Destroy();
	rtcpsched.Reset();
	collisionlist.Clear();
	sources.Clear();

	std::list<RTCPCompoundPacket *>::const_iterator it;

	for (it = byepackets.begin() ; it != byepackets.end() ; it++)
		RTPDelete(*it,GetMemoryManager());
	byepackets.clear();
	
	created = false;
}
示例#3
0
int RTPSession::Create(const RTPSessionParams &sessparams,const RTPTransmissionParams *transparams /* = 0 */,
		       RTPTransmitter::TransmissionProtocol protocol)
{
	int status;
	
	if (created)
		return ERR_RTP_SESSION_ALREADYCREATED;

	usingpollthread = sessparams.IsUsingPollThread();
	useSR_BYEifpossible = sessparams.GetSenderReportForBYE();
	sentpackets = false;
	
	// Check max packet size
	
	if ((maxpacksize = sessparams.GetMaximumPacketSize()) < RTP_MINPACKETSIZE)
		return ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL;
		
	// Initialize the transmission component
	
	rtptrans = 0;
	switch(protocol)
	{
	case RTPTransmitter::IPv4UDPProto:
		rtptrans = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMITTER) RTPUDPv4Transmitter(GetMemoryManager());
		break;
#ifdef RTP_SUPPORT_IPV6
	case RTPTransmitter::IPv6UDPProto:
		rtptrans = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPTRANSMITTER) RTPUDPv6Transmitter(GetMemoryManager());
		break;
#endif // RTP_SUPPORT_IPV6
	case RTPTransmitter::UserDefinedProto:
		rtptrans = NewUserDefinedTransmitter();
		if (rtptrans == 0)
			return ERR_RTP_SESSION_USERDEFINEDTRANSMITTERNULL;
		break;
	default:
		return ERR_RTP_SESSION_UNSUPPORTEDTRANSMISSIONPROTOCOL;
	}
	
	if (rtptrans == 0)
		return ERR_RTP_OUTOFMEM;
	if ((status = rtptrans->Init(usingpollthread)) < 0)
	{
		RTPDelete(rtptrans,GetMemoryManager());
		return status;
	}
	if ((status = rtptrans->Create(maxpacksize,transparams)) < 0)
	{
		RTPDelete(rtptrans,GetMemoryManager());
		return status;
	}

	deletetransmitter = true;
	return InternalCreate(sessparams);
}
示例#4
0
RTPUDPv6Transmitter::RTPUDPv6Transmitter(RTPMemoryManager *mgr) : RTPTransmitter(mgr),
								  destinations(GetMemoryManager(),RTPMEM_TYPE_CLASS_DESTINATIONLISTHASHELEMENT),
								  multicastgroups(GetMemoryManager(),RTPMEM_TYPE_CLASS_MULTICASTHASHELEMENT),
								  acceptignoreinfo(GetMemoryManager(),RTPMEM_TYPE_CLASS_ACCEPTIGNOREHASHELEMENT)
{
	created = false;
	init = false;
#if (defined(WIN32) || defined(_WIN32_WCE))
	timeinit.Dummy();
#endif // WIN32 || _WIN32_WCE
}
示例#5
0
int RTCPSDESInfo::SetPrivateValue(const uint8_t *prefix,size_t prefixlen,const uint8_t *value,size_t valuelen)
{
	std::list<SDESPrivateItem *>::const_iterator it;
	bool found;
	
	found = false;
	it = privitems.begin();
	while (!found && it != privitems.end())
	{
		uint8_t *p;
		size_t l;
		
		p = (*it)->GetPrefix(&l);
		if (l == prefixlen)
		{
			if (l <= 0)
				found = true;
			else if (memcmp(prefix,p,l) == 0)
				found = true;
			else
				++it;
		}
		else
			++it;
	}
	
	SDESPrivateItem *item;
	
	if (found) // replace the value for this entry
		item = *it;
	else // no entry for this prefix found... add it
	{
		if (privitems.size() >= RTP_MAXPRIVITEMS) // too many items present, just ignore it
			return ERR_RTP_SDES_MAXPRIVITEMS;
		
		int status;
		
		item = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_SDESPRIVATEITEM) SDESPrivateItem(GetMemoryManager());
		if (item == 0)
			return ERR_RTP_OUTOFMEM;
		if ((status = item->SetPrefix(prefix,prefixlen)) < 0)
		{
			RTPDelete(item,GetMemoryManager());
			return status;
		}
		privitems.push_front(item);
	}
	return item->SetInfo(value,valuelen);
}
示例#6
0
int RTPPacketBuilder::SetMaximumPacketSize(size_t max)
{
	uint8_t *newbuf;

	if (max <= 0)
		return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE;
	newbuf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER) uint8_t[max];
	if (newbuf == 0)
		return ERR_RTP_OUTOFMEM;
	
	RTPDeleteByteArray(buffer,GetMemoryManager());
	buffer = newbuf;
	maxpacksize = max;
	return 0;
}
示例#7
0
void RTPPacketBuilder::Destroy()
{
	if (!init)
		return;
	RTPDeleteByteArray(buffer,GetMemoryManager());
	init = false;
}
示例#8
0
int RTPPacketBuilder::PrivateBuildPacket(const void *data,size_t len,
	                  uint8_t pt,bool mark,uint32_t timestampinc,bool gotextension,
	                  uint16_t hdrextID,const void *hdrextdata,size_t numhdrextwords)
{
	RTPPacket p(pt,data,len,seqnr,timestamp,ssrc,mark,numcsrcs,csrcs,gotextension,hdrextID,
	            (uint16_t)numhdrextwords,hdrextdata,buffer,maxpacksize,GetMemoryManager());
	int status = p.GetCreationError();

	if (status < 0)
		return status;
	packetlength = p.GetPacketLength();

	if (numpackets == 0) // first packet
	{
		lastwallclocktime = RTPTime::CurrentTime();
		lastrtptimestamp = timestamp;
		prevrtptimestamp = timestamp;
	}
	else if (timestamp != prevrtptimestamp)
	{
		lastwallclocktime = RTPTime::CurrentTime();
		lastrtptimestamp = timestamp;
		prevrtptimestamp = timestamp;
	}
	
	numpayloadbytes += (uint32_t)p.GetPayloadLength();
	numpackets++;
	timestamp += timestampinc;
	seqnr++;

	return 0;
}
示例#9
0
int RTPCollisionList::UpdateAddress(const RTPAddress *addr,const RTPTime &receivetime,bool *created)
{
	if (addr == 0)
		return ERR_RTP_COLLISIONLIST_BADADDRESS;
	
	std::list<AddressAndTime>::iterator it;
	
	for (it = addresslist.begin() ; it != addresslist.end() ; it++)
	{
		if (((*it).addr)->IsSameAddress(addr))
		{
			(*it).recvtime = receivetime;
			*created = false;
			return 0;
		}
	}

	RTPAddress *newaddr = addr->CreateCopy(GetMemoryManager());
	if (newaddr == 0)
		return ERR_RTP_OUTOFMEM;
	
	addresslist.push_back(AddressAndTime(newaddr,receivetime));
	*created = true;
	return 0;
}
int RTCPCompoundPacketBuilder::AddReportBlock(uint32_t ssrc,uint8_t fractionlost,int32_t packetslost,uint32_t exthighestseq,
	                                      uint32_t jitter,uint32_t lsr,uint32_t dlsr)
{
	if (!arebuilding)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING;
	if (report.headerlength == 0)
		return ERR_RTP_RTCPCOMPPACKBUILDER_REPORTNOTSTARTED;

	size_t totalothersize = byesize+appsize+sdes.NeededBytes();
	size_t reportsizewithextrablock = report.NeededBytesWithExtraReportBlock();
	
	if ((totalothersize+reportsizewithextrablock) > maximumpacketsize)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT;

	uint8_t *buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRECEIVERREPORT) uint8_t[sizeof(RTCPReceiverReport)];
	if (buf == 0)
		return ERR_RTP_OUTOFMEM;
	
	RTCPReceiverReport *rr = (RTCPReceiverReport *)buf;
	uint32_t *packlost = (uint32_t *)&packetslost;
	uint32_t packlost2 = (*packlost);
		
	rr->ssrc = htonl(ssrc);
	rr->fractionlost = fractionlost;
	rr->packetslost[2] = (uint8_t)(packlost2&0xFF);
	rr->packetslost[1] = (uint8_t)((packlost2>>8)&0xFF);
	rr->packetslost[0] = (uint8_t)((packlost2>>16)&0xFF);
	rr->exthighseqnr = htonl(exthighestseq);
	rr->jitter = htonl(jitter);
	rr->lsr = htonl(lsr);
	rr->dlsr = htonl(dlsr);

	report.reportblocks.push_back(Buffer(buf,sizeof(RTCPReceiverReport)));
	return 0;
}
示例#11
0
int RTCPSDESInfo::DeletePrivatePrefix(const uint8_t *prefix,size_t prefixlen)
{
	std::list<SDESPrivateItem *>::iterator it;
	bool found;
	
	found = false;
	it = privitems.begin();
	while (!found && it != privitems.end())
	{
		uint8_t *p;
		size_t l;
		
		p = (*it)->GetPrefix(&l);
		if (l == prefixlen)
		{
			if (l <= 0)
				found = true;
			else if (memcmp(prefix,p,l) == 0)
				found = true;
			else
				++it;
		}
		else
			++it;
	}
	if (!found)
		return ERR_RTP_SDES_PREFIXNOTFOUND;
	
	RTPDelete(*it,GetMemoryManager());
	privitems.erase(it);
	return 0;
}
int RTCPCompoundPacketBuilder::AddSDESNormalItem(RTCPSDESPacket::ItemType t,const void *itemdata,uint8_t itemlength)
{
	if (!arebuilding)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING;
	if (sdes.sdessources.empty())
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE;

	uint8_t itemid;
	
	switch(t)
	{
	case RTCPSDESPacket::CNAME:
		itemid = RTCP_SDES_ID_CNAME;
		break;
	case RTCPSDESPacket::NAME:
		itemid = RTCP_SDES_ID_NAME;
		break;
	case RTCPSDESPacket::EMAIL:
		itemid = RTCP_SDES_ID_EMAIL;
		break;
	case RTCPSDESPacket::PHONE:
		itemid = RTCP_SDES_ID_PHONE;
		break;
	case RTCPSDESPacket::LOC:
		itemid = RTCP_SDES_ID_LOCATION;
		break;
	case RTCPSDESPacket::TOOL:
		itemid = RTCP_SDES_ID_TOOL;
		break;
	case RTCPSDESPacket::NOTE:
		itemid = RTCP_SDES_ID_NOTE;
		break;
	default:
		return ERR_RTP_RTCPCOMPPACKBUILDER_INVALIDITEMTYPE;
	}

	size_t totalotherbytes = byesize+appsize+report.NeededBytes();
	size_t sdessizewithextraitem = sdes.NeededBytesWithExtraItem(itemlength);

	if ((sdessizewithextraitem+totalotherbytes) > maximumpacketsize)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT;

	uint8_t *buf;
	size_t len;

	buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPSDESBLOCK) uint8_t[sizeof(RTCPSDESHeader)+(size_t)itemlength];
	if (buf == 0)
		return ERR_RTP_OUTOFMEM;
	len = sizeof(RTCPSDESHeader)+(size_t)itemlength;

	RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(buf);

	sdeshdr->sdesid = itemid;
	sdeshdr->length = itemlength;
	if (itemlength != 0)
		memcpy((buf + sizeof(RTCPSDESHeader)),itemdata,(size_t)itemlength);

	sdes.AddItem(buf,len);
	return 0;
}
示例#13
0
void RTPCollisionList::Clear()
{
	std::list<AddressAndTime>::iterator it;
	
	for (it = addresslist.begin() ; it != addresslist.end() ; it++)
		RTPDelete((*it).addr,GetMemoryManager());
	addresslist.clear();
}
示例#14
0
void RTCPCompoundPacket::ClearPacketList()
{
	std::list<RTCPPacket *>::const_iterator it;

	for (it = rtcppacklist.begin() ; it != rtcppacklist.end() ; it++)
		RTPDelete(*it,GetMemoryManager());
	rtcppacklist.clear();
	rtcppackit = rtcppacklist.begin();
}
示例#15
0
int RTPInternalSourceData::ProcessBYEPacket(const uint8_t *reason,size_t reasonlen,const RTPTime &receivetime)
{
	if (byereason)
	{
		RTPDeleteByteArray(byereason,GetMemoryManager());
		byereason = 0;
		byereasonlen = 0;
	}

	byetime = receivetime;
	byereason = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPBYEREASON) uint8_t[reasonlen];
	if (byereason == 0)
		return ERR_RTP_OUTOFMEM;
	memcpy(byereason,reason,reasonlen);
	byereasonlen = reasonlen;
	receivedbye = true;
	stats.SetLastMessageTime(receivetime);
	return 0;
}
示例#16
0
void RTCPSDESInfo::Clear()
{
#ifdef RTP_SUPPORT_SDESPRIV
	std::list<SDESPrivateItem *>::const_iterator it;

	for (it = privitems.begin() ; it != privitems.end() ; ++it)
		RTPDelete(*it,GetMemoryManager());
	privitems.clear();
#endif // RTP_SUPPORT_SDESPRIV
}
int RTCPCompoundPacketBuilder::AddAPPPacket(uint8_t subtype,uint32_t ssrc,const uint8_t name[4],const void *appdata,size_t appdatalen)
{
	if (!arebuilding)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING;
	if (subtype > 31)
		return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE;
	if ((appdatalen%4) != 0)
		return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH;

	size_t appdatawords = appdatalen/4;

	if ((appdatawords+2) > 65535)
		return ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG;
	
	size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2+appdatalen;
#ifndef RTP_SUPPORT_RTCPUNKNOWN
	size_t totalotherbytes = appsize+byesize+sdes.NeededBytes()+report.NeededBytes();
#else
	size_t totalotherbytes = appsize+unknownsize+byesize+sdes.NeededBytes()+report.NeededBytes();
#endif // RTP_SUPPORT_RTCPUNKNOWN 

	if ((totalotherbytes + packsize) > maximumpacketsize)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT;

	uint8_t *buf;
	
	buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPAPPPACKET) uint8_t[packsize];
	if (buf == 0)
		return ERR_RTP_OUTOFMEM;

	RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf;

	hdr->version = 2;
	hdr->padding = 0;
	hdr->count = subtype;
	
	hdr->length = htons((uint16_t)(appdatawords+2));
	hdr->packettype = RTP_RTCPTYPE_APP;
	
	uint32_t *source = (uint32_t *)(buf+sizeof(RTCPCommonHeader));
	*source = htonl(ssrc);

	buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+0] = name[0];
	buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+1] = name[1];
	buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+2] = name[2];
	buf[sizeof(RTCPCommonHeader)+sizeof(uint32_t)+3] = name[3];

	if (appdatalen > 0)
		memcpy((buf+sizeof(RTCPCommonHeader)+sizeof(uint32_t)*2),appdata,appdatalen);

	apppackets.push_back(Buffer(buf,packsize));
	appsize += packsize;
	
	return 0;
}
void RTCPCompoundPacketBuilder::ClearBuildBuffers()
{
	report.Clear();
	sdes.Clear();

	std::list<Buffer>::const_iterator it;
	for (it = byepackets.begin() ; it != byepackets.end() ; it++)
	{
		if ((*it).packetdata)
			RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
	}
	for (it = apppackets.begin() ; it != apppackets.end() ; it++)
	{
		if ((*it).packetdata)
			RTPDeleteByteArray((*it).packetdata,GetMemoryManager());
	}

	byepackets.clear();
	apppackets.clear();
	byesize = 0;
	appsize = 0;
}
示例#19
0
int RTPFakeTransmitter::Create(size_t maximumpacketsize,const RTPTransmissionParams *transparams)
{
//	struct sockaddr_in addr;
//	int status;

	if (!init)
		return ERR_RTP_FAKETRANS_NOTINIT;
	
	MAINMUTEX_LOCK

	if (created)
	{
		MAINMUTEX_UNLOCK
		return ERR_RTP_FAKETRANS_ALREADYCREATED;
	}
	
	// Obtain transmission parameters
	
	if (transparams == 0)
		params = RTPNew(GetMemoryManager(),RTPMEM_TYPE_OTHER) RTPFakeTransmissionParams;
	else
	{
		if (transparams->GetTransmissionProtocol() != RTPTransmitter::UserDefinedProto)
			return ERR_RTP_FAKETRANS_ILLEGALPARAMETERS;
		params = (RTPFakeTransmissionParams *)transparams;
	}

	// Check if portbase is even
	//if (params->GetPortbase()%2 != 0)
	//{
	//	MAINMUTEX_UNLOCK
	//	return ERR_RTP_FAKETRANS_PORTBASENOTEVEN;
	//}

	// Try to obtain local IP addresses

	localIPs = params->GetLocalIPList();
	if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them
	{
		int status;
		
		if ((status = CreateLocalIPList()) < 0)
		{
			MAINMUTEX_UNLOCK
			return status;
		}
示例#20
0
void RTPCollisionList::Timeout(const RTPTime &currenttime,const RTPTime &timeoutdelay)
{
	std::list<AddressAndTime>::iterator it;
	RTPTime checktime = currenttime;
	checktime -= timeoutdelay;
	
	it = addresslist.begin();
	while(it != addresslist.end())
	{
		if ((*it).recvtime < checktime) // timeout
		{
			RTPDelete((*it).addr,GetMemoryManager());
			it = addresslist.erase(it);	
		}
		else
			it++;
	}
}
int RTCPCompoundPacketBuilder::AddSDESPrivateItem(const void *prefixdata,uint8_t prefixlength,const void *valuedata,
                                                  uint8_t valuelength)
{
	if (!arebuilding)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING;
	if (sdes.sdessources.empty())
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE;

	size_t itemlength = ((size_t)prefixlength)+1+((size_t)valuelength);
	if (itemlength > 255)
		return ERR_RTP_RTCPCOMPPACKBUILDER_TOTALITEMLENGTHTOOBIG;
	
#ifndef RTP_SUPPORT_RTCPUNKNOWN
	size_t totalotherbytes = byesize+appsize+report.NeededBytes();
#else
	size_t totalotherbytes = byesize+appsize+unknownsize+report.NeededBytes();
#endif // RTP_SUPPORT_RTCPUNKNOWN 
	size_t sdessizewithextraitem = sdes.NeededBytesWithExtraItem(itemlength);

	if ((sdessizewithextraitem+totalotherbytes) > maximumpacketsize)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT;

	uint8_t *buf;
	size_t len;

	buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPSDESBLOCK) uint8_t[sizeof(RTCPSDESHeader)+itemlength];
	if (buf == 0)
		return ERR_RTP_OUTOFMEM;
	len = sizeof(RTCPSDESHeader)+(size_t)itemlength;

	RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *)(buf);

	sdeshdr->sdesid = RTCP_SDES_ID_PRIVATE;
	sdeshdr->length = itemlength;
	
	buf[sizeof(RTCPSDESHeader)] = prefixlength;
	if (prefixlength != 0)
		memcpy((buf+sizeof(RTCPSDESHeader)+1),prefixdata,(size_t)prefixlength);
	if (valuelength != 0)
		memcpy((buf+sizeof(RTCPSDESHeader)+1+(size_t)prefixlength),valuedata,(size_t)valuelength);

	sdes.AddItem(buf,len);
	return 0;
}
int RTCPCompoundPacketBuilder::AddUnknownPacket(uint8_t payload_type, uint8_t subtype, uint32_t ssrc, const void *data, size_t len)
{
	if (!arebuilding)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING;

	size_t datawords = len/4;

	if ((datawords+2) > 65535)
		return ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG;
	
	size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)+len;
	size_t totalotherbytes = appsize+unknownsize+byesize+sdes.NeededBytes()+report.NeededBytes();

	if ((totalotherbytes + packsize) > maximumpacketsize)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT;

	uint8_t *buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPUNKNOWNPACKET) uint8_t[packsize];
	if (buf == 0)
		return ERR_RTP_OUTOFMEM;

	RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf;

	hdr->version = 2;
	hdr->padding = 0;
	hdr->count = subtype;
	hdr->length = htons((uint16_t)(datawords+1));
	hdr->packettype = payload_type;
	
	uint32_t *source = (uint32_t *)(buf+sizeof(RTCPCommonHeader));
	*source = htonl(ssrc);

	if (len > 0)
		memcpy((buf+sizeof(RTCPCommonHeader)+sizeof(uint32_t)),data,len);

	unknownpackets.push_back(Buffer(buf,packsize));
	unknownsize += packsize;
	
	return 0;
}
示例#23
0
int RTPPacketBuilder::Init(size_t max)
{
	if (init)
		return ERR_RTP_PACKBUILD_ALREADYINIT;
	if (max <= 0)
		return ERR_RTP_PACKBUILD_INVALIDMAXPACKETSIZE;
	
	maxpacksize = max;
	buffer = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTPPACKETBUILDERBUFFER) uint8_t [max];
	if (buffer == 0)
		return ERR_RTP_OUTOFMEM;
	packetlength = 0;
	
	CreateNewSSRC();

	deftsset = false;
	defptset = false;
	defmarkset = false;
		
	numcsrcs = 0;
	
	init = true;
	return 0;
}
示例#24
0
void Application::AtExit()
{
	// Remove all references
	GetMemoryManager().Sweep();
}
示例#25
0
void RTDyldObjectLinkingLayer::emit(MaterializationResponsibility R,
                                    std::unique_ptr<MemoryBuffer> O) {
  assert(O && "Object must not be null");

  // This method launches an asynchronous link step that will fulfill our
  // materialization responsibility. We need to switch R to be heap
  // allocated before that happens so it can live as long as the asynchronous
  // link needs it to (i.e. it must be able to outlive this method).
  auto SharedR = std::make_shared<MaterializationResponsibility>(std::move(R));

  auto &ES = getExecutionSession();

  // Create a MemoryBufferRef backed MemoryBuffer (i.e. shallow) copy of the
  // the underlying buffer to pass into RuntimeDyld. This allows us to hold
  // ownership of the real underlying buffer and return it to the user once
  // the object has been emitted.
  auto ObjBuffer = MemoryBuffer::getMemBuffer(O->getMemBufferRef(), false);

  auto Obj = object::ObjectFile::createObjectFile(*ObjBuffer);

  if (!Obj) {
    getExecutionSession().reportError(Obj.takeError());
    SharedR->failMaterialization();
    return;
  }

  // Collect the internal symbols from the object file: We will need to
  // filter these later.
  auto InternalSymbols = std::make_shared<std::set<StringRef>>();
  {
    for (auto &Sym : (*Obj)->symbols()) {
      if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) {
        if (auto SymName = Sym.getName())
          InternalSymbols->insert(*SymName);
        else {
          ES.reportError(SymName.takeError());
          R.failMaterialization();
          return;
        }
      }
    }
  }

  auto K = R.getVModuleKey();
  RuntimeDyld::MemoryManager *MemMgr = nullptr;

  // Create a record a memory manager for this object.
  {
    auto Tmp = GetMemoryManager();
    std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
    MemMgrs.push_back(std::move(Tmp));
    MemMgr = MemMgrs.back().get();
  }

  JITDylibSearchOrderResolver Resolver(*SharedR);

  // FIXME: Switch to move-capture for the 'O' buffer once we have c++14.
  MemoryBuffer *UnownedObjBuffer = O.release();
  jitLinkForORC(
      **Obj, std::move(O), *MemMgr, Resolver, ProcessAllSections,
      [this, K, SharedR, &Obj, InternalSymbols](
          std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
          std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
        return onObjLoad(K, *SharedR, **Obj, std::move(LoadedObjInfo),
                         ResolvedSymbols, *InternalSymbols);
      },
      [this, K, SharedR, UnownedObjBuffer](Error Err) {
        std::unique_ptr<MemoryBuffer> ObjBuffer(UnownedObjBuffer);
        onObjEmit(K, std::move(ObjBuffer), *SharedR, std::move(Err));
      });
}
示例#26
0
int RTCPCompoundPacket::ParseData(uint8_t *data, size_t datalen)
{
	bool first;
	
	if (datalen < sizeof(RTCPCommonHeader))
		return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET;

	first = true;
	
	do
	{
		RTCPCommonHeader *rtcphdr;
		size_t length;
		
		rtcphdr = (RTCPCommonHeader *)data;
		if (rtcphdr->version != RTP_VERSION) // check version
		{
			ClearPacketList();
			return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET;
		}
		if (first)
		{
			// Check if first packet is SR or RR
			
			first = false;
			if ( ! (rtcphdr->packettype == RTP_RTCPTYPE_SR || rtcphdr->packettype == RTP_RTCPTYPE_RR))
			{
				ClearPacketList();
				return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET;
			}
		}
		
		length = (size_t)ntohs(rtcphdr->length);
		length++;
		length *= sizeof(uint32_t);

		if (length > datalen) // invalid length field
		{
			ClearPacketList();
			return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET;
		}
		
		if (rtcphdr->padding)
		{
			// check if it's the last packet
			if (length != datalen)
			{
				ClearPacketList();
				return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET;
			}
		}

		RTCPPacket *p;
		
		switch (rtcphdr->packettype)
		{
		case RTP_RTCPTYPE_SR:
			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSRPACKET) RTCPSRPacket(data,length);
			break;
		case RTP_RTCPTYPE_RR:
			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRRPACKET) RTCPRRPacket(data,length);
			break;
		case RTP_RTCPTYPE_SDES:
			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSDESPACKET) RTCPSDESPacket(data,length);
			break;
		case RTP_RTCPTYPE_BYE:
			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPBYEPACKET) RTCPBYEPacket(data,length);
			break;
		case RTP_RTCPTYPE_APP:
			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPAPPPACKET) RTCPAPPPacket(data,length);
			break;
		default:
			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPUNKNOWNPACKET) RTCPUnknownPacket(data,length);
		}

		if (p == 0)
		{
			ClearPacketList();
			return ERR_RTP_OUTOFMEM;
		}

		rtcppacklist.push_back(p);
		
		datalen -= length;
		data += length;
	} while (datalen >= (size_t)sizeof(RTCPCommonHeader));

	if (datalen != 0) // some remaining bytes
	{
		ClearPacketList();
		return ERR_RTP_RTCPCOMPOUND_INVALIDPACKET;
	}
	return 0;
}
示例#27
0
RTCPCompoundPacket::~RTCPCompoundPacket()
{
	ClearPacketList();
	if (compoundpacket && deletepacket)
		RTPDeleteByteArray(compoundpacket,GetMemoryManager());
}
int RTCPCompoundPacketBuilder::AddBYEPacket(uint32_t *ssrcs,uint8_t numssrcs,const void *reasondata,uint8_t reasonlength)
{
	if (!arebuilding)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING;

	if (numssrcs > 31)
		return ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS;
	
	size_t packsize = sizeof(RTCPCommonHeader)+sizeof(uint32_t)*((size_t)numssrcs);
	size_t zerobytes = 0;
	
	if (reasonlength > 0)
	{
		packsize += 1; // 1 byte for the length;
		packsize += (size_t)reasonlength;

		size_t r = (packsize&0x03);
		if (r != 0)
		{
			zerobytes = 4-r;
			packsize += zerobytes;
		}
	}

	size_t totalotherbytes = appsize+byesize+sdes.NeededBytes()+report.NeededBytes();

	if ((totalotherbytes + packsize) > maximumpacketsize)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT;

	uint8_t *buf;
	size_t numwords;
	
	buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPBYEPACKET) uint8_t[packsize];
	if (buf == 0)
		return ERR_RTP_OUTOFMEM;

	RTCPCommonHeader *hdr = (RTCPCommonHeader *)buf;

	hdr->version = 2;
	hdr->padding = 0;
	hdr->count = numssrcs;
	
	numwords = packsize/sizeof(uint32_t);
	hdr->length = htons((uint16_t)(numwords-1));
	hdr->packettype = RTP_RTCPTYPE_BYE;
	
	uint32_t *sources = (uint32_t *)(buf+sizeof(RTCPCommonHeader));
	uint8_t srcindex;
	
	for (srcindex = 0 ; srcindex < numssrcs ; srcindex++)
		sources[srcindex] = htonl(ssrcs[srcindex]);

	if (reasonlength != 0)
	{
		size_t offset = sizeof(RTCPCommonHeader)+((size_t)numssrcs)*sizeof(uint32_t);

		buf[offset] = reasonlength;
		memcpy((buf+offset+1),reasondata,(size_t)reasonlength);
		for (size_t i = 0 ; i < zerobytes ; i++)
			buf[packsize-1-i] = 0;
	}

	byepackets.push_back(Buffer(buf,packsize));
	byesize += packsize;
	
	return 0;
}
示例#29
0
// The following function should delete rtppack if necessary
int RTPInternalSourceData::ProcessRTPPacket(RTPPacket *rtppack,const RTPTime &receivetime,bool *stored)
{
	bool accept,onprobation,applyprobation;
	double tsunit;
	
	*stored = false;
	
	if (timestampunit < 0) 
		tsunit = INF_GetEstimatedTimestampUnit();
	else
		tsunit = timestampunit;

#ifdef RTP_SUPPORT_PROBATION
	if (validated) 				// If the source is our own process, we can already be validated. No 
		applyprobation = false;		// probation should be applied in that case.
	else
	{
		if (probationtype == RTPSources::NoProbation)
			applyprobation = false;
		else
			applyprobation = true;
	}
#else
	applyprobation = false;
#endif // RTP_SUPPORT_PROBATION

	stats.ProcessPacket(rtppack,receivetime,tsunit,ownssrc,&accept,applyprobation,&onprobation);

#ifdef RTP_SUPPORT_PROBATION
	switch (probationtype)
	{
		case RTPSources::ProbationStore:
			if (!(onprobation || accept))
				return 0;
			if (accept)
				validated = true;
			break;
		case RTPSources::ProbationDiscard:
		case RTPSources::NoProbation:
			if (!accept)
				return 0;
			validated = true;
			break;
		default:
			return ERR_RTP_INTERNALSOURCEDATA_INVALIDPROBATIONTYPE;
	}
#else
	if (!accept)
		return 0;
	validated = true;
#endif // RTP_SUPPORT_PROBATION;
	
	if (validated && !ownssrc) // for own ssrc these variables depend on the outgoing packets, not on the incoming
		issender = true;
	
	// Now, we can place the packet in the queue
	
	if (packetlist.empty())
	{
		*stored = true;
		packetlist.push_back(rtppack);
		return 0;
	}
	
	if (!validated) // still on probation
	{
		// Make sure that we don't buffer too much packets to avoid wasting memory
		// on a bad source. Delete the packet in the queue with the lowest sequence
		// number.
		if (packetlist.size() == RTPINTERNALSOURCEDATA_MAXPROBATIONPACKETS)
		{
			RTPPacket *p = *(packetlist.begin());
			packetlist.pop_front();
			RTPDelete(p,GetMemoryManager());
		}
	}

	// find the right position to insert the packet
	
	std::list<RTPPacket*>::iterator it,start;
	bool done = false;
	uint32_t newseqnr = rtppack->GetExtendedSequenceNumber();
	
	it = packetlist.end();
	--it;
	start = packetlist.begin();
	
	while (!done)
	{
		RTPPacket *p;
		uint32_t seqnr;
		
		p = *it;
		seqnr = p->GetExtendedSequenceNumber();
		if (seqnr > newseqnr)
		{
			if (it != start)
				--it;
			else // we're at the start of the list
			{
				*stored = true;
				done = true;
				packetlist.push_front(rtppack);
			}
		}
		else if (seqnr < newseqnr) // insert after this packet
		{
			++it;
			packetlist.insert(it,rtppack);
			done = true;
			*stored = true;
		}
		else // they're equal !! Drop packet
		{
			done = true;
		}
	}

	return 0;
}
int RTCPCompoundPacketBuilder::EndBuild()
{
	if (!arebuilding)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING;
	if (report.headerlength == 0)
		return ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT;
	
	uint8_t *buf;
	size_t len;
	
	len = appsize+byesize+report.NeededBytes()+sdes.NeededBytes();
	
	if (!external)
	{
		buf = RTPNew(GetMemoryManager(),RTPMEM_TYPE_BUFFER_RTCPCOMPOUNDPACKET) uint8_t[len];
		if (buf == 0)
			return ERR_RTP_OUTOFMEM;
	}
	else
		buf = buffer;
	
	uint8_t *curbuf = buf;
	RTCPPacket *p;

	// first, we'll add all report info
	
	{
		bool firstpacket = true;
		bool done = false;
		std::list<Buffer>::const_iterator it = report.reportblocks.begin();
		do
		{
			RTCPCommonHeader *hdr = (RTCPCommonHeader *)curbuf;
			size_t offset;
			
			hdr->version = 2;
			hdr->padding = 0;

			if (firstpacket && report.isSR)
			{
				hdr->packettype = RTP_RTCPTYPE_SR;
				memcpy((curbuf+sizeof(RTCPCommonHeader)),report.headerdata,report.headerlength);
				offset = sizeof(RTCPCommonHeader)+report.headerlength;
			}
			else
			{
				hdr->packettype = RTP_RTCPTYPE_RR;
				memcpy((curbuf+sizeof(RTCPCommonHeader)),report.headerdata,sizeof(uint32_t));
				offset = sizeof(RTCPCommonHeader)+sizeof(uint32_t);
			}
			firstpacket = false;
			
			uint8_t count = 0;

			while (it != report.reportblocks.end() && count < 31)
			{
				memcpy(curbuf+offset,(*it).packetdata,(*it).packetlength);
				offset += (*it).packetlength;
				count++;
				it++;
			}

			size_t numwords = offset/sizeof(uint32_t);

			hdr->length = htons((uint16_t)(numwords-1));
			hdr->count = count;

			// add entry in parent's list
			if (hdr->packettype == RTP_RTCPTYPE_SR)
				p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSRPACKET) RTCPSRPacket(curbuf,offset);
			else
				p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPRRPACKET) RTCPRRPacket(curbuf,offset);
			if (p == 0)
			{
				if (!external)
					RTPDeleteByteArray(buf,GetMemoryManager());
				ClearPacketList();
				return ERR_RTP_OUTOFMEM;
			}
			rtcppacklist.push_back(p);

			curbuf += offset;
			if (it == report.reportblocks.end())
				done = true;
		} while (!done);
	}
		
	// then, we'll add the sdes info

	if (!sdes.sdessources.empty())
	{
		bool done = false;
		std::list<SDESSource *>::const_iterator sourceit = sdes.sdessources.begin();
		
		do
		{
			RTCPCommonHeader *hdr = (RTCPCommonHeader *)curbuf;
			size_t offset = sizeof(RTCPCommonHeader);
			
			hdr->version = 2;
			hdr->padding = 0;
			hdr->packettype = RTP_RTCPTYPE_SDES;

			uint8_t sourcecount = 0;
			
			while (sourceit != sdes.sdessources.end() && sourcecount < 31)
			{
				uint32_t *ssrc = (uint32_t *)(curbuf+offset);
				*ssrc = htonl((*sourceit)->ssrc);
				offset += sizeof(uint32_t);
				
				std::list<Buffer>::const_iterator itemit,itemend;

				itemit = (*sourceit)->items.begin();
				itemend = (*sourceit)->items.end();
				while (itemit != itemend)
				{
					memcpy(curbuf+offset,(*itemit).packetdata,(*itemit).packetlength);
					offset += (*itemit).packetlength;
					itemit++;
				}

				curbuf[offset] = 0; // end of item list;
				offset++;

				size_t r = offset&0x03;
				if (r != 0) // align to 32 bit boundary
				{
					size_t num = 4-r;
					size_t i;

					for (i = 0 ; i < num ; i++)
						curbuf[offset+i] = 0;
					offset += num;
				}
				
				sourceit++;
				sourcecount++;
			}

			size_t numwords = offset/4;
			
			hdr->count = sourcecount;
			hdr->length = htons((uint16_t)(numwords-1));

			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPSDESPACKET) RTCPSDESPacket(curbuf,offset);
			if (p == 0)
			{
				if (!external)
					RTPDeleteByteArray(buf,GetMemoryManager());
				ClearPacketList();
				return ERR_RTP_OUTOFMEM;
			}
			rtcppacklist.push_back(p);
			
			curbuf += offset;
			if (sourceit == sdes.sdessources.end())
				done = true;
		} while (!done);
	}
	
	// adding the app data
	
	{
		std::list<Buffer>::const_iterator it;

		for (it = apppackets.begin() ; it != apppackets.end() ; it++)
		{
			memcpy(curbuf,(*it).packetdata,(*it).packetlength);
			
			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPAPPPACKET) RTCPAPPPacket(curbuf,(*it).packetlength);
			if (p == 0)
			{
				if (!external)
					RTPDeleteByteArray(buf,GetMemoryManager());
				ClearPacketList();
				return ERR_RTP_OUTOFMEM;
			}
			rtcppacklist.push_back(p);
	
			curbuf += (*it).packetlength;
		}
	}
	
	// adding bye packets
	
	{
		std::list<Buffer>::const_iterator it;

		for (it = byepackets.begin() ; it != byepackets.end() ; it++)
		{
			memcpy(curbuf,(*it).packetdata,(*it).packetlength);
			
			p = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTCPBYEPACKET) RTCPBYEPacket(curbuf,(*it).packetlength);
			if (p == 0)
			{
				if (!external)
					RTPDeleteByteArray(buf,GetMemoryManager());
				ClearPacketList();
				return ERR_RTP_OUTOFMEM;
			}
			rtcppacklist.push_back(p);
	
			curbuf += (*it).packetlength;
		}
	}
	
	compoundpacket = buf;
	compoundpacketlength = len;
	arebuilding = false;
	ClearBuildBuffers();
	return 0;
}