| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  This file is a part of JRTPLIB | 
					
						
							|  |  |  |  Copyright (c) 1999-2017 Jori Liesenborgs | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  Contact: jori.liesenborgs@gmail.com | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  This library was developed at the Expertise Centre for Digital Media | 
					
						
							|  |  |  |  (http://www.edm.uhasselt.be), a research center of the Hasselt University
 | 
					
						
							|  |  |  |  (http://www.uhasselt.be). The library is based upon work done for
 | 
					
						
							|  |  |  |  my thesis at the School for Knowledge Technology (Belgium/The Netherlands). | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  Permission is hereby granted, free of charge, to any person obtaining a | 
					
						
							|  |  |  |  copy of this software and associated documentation files (the "Software"), | 
					
						
							|  |  |  |  to deal in the Software without restriction, including without limitation | 
					
						
							|  |  |  |  the rights to use, copy, modify, merge, publish, distribute, sublicense, | 
					
						
							|  |  |  |  and/or sell copies of the Software, and to permit persons to whom the | 
					
						
							|  |  |  |  Software is furnished to do so, subject to the following conditions: | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  The above copyright notice and this permission notice shall be included | 
					
						
							|  |  |  |  in all copies or substantial portions of the Software. | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | 
					
						
							|  |  |  |  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
					
						
							|  |  |  |  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL | 
					
						
							|  |  |  |  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
					
						
							|  |  |  |  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | 
					
						
							|  |  |  |  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | 
					
						
							|  |  |  |  IN THE SOFTWARE. | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "rtcpcompoundpacketbuilder.h"
 | 
					
						
							|  |  |  | #include "rtcpsrpacket.h"
 | 
					
						
							|  |  |  | #include "rtcprrpacket.h"
 | 
					
						
							|  |  |  | #include "rtcpsdespacket.h"
 | 
					
						
							|  |  |  | #include "rtcpbyepacket.h"
 | 
					
						
							|  |  |  | #include "rtcpapppacket.h"
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace qrtplib | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | RTCPCompoundPacketBuilder::RTCPCompoundPacketBuilder() | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     byesize = 0; | 
					
						
							|  |  |  |     appsize = 0; | 
					
						
							|  |  |  |     maximumpacketsize = 0; | 
					
						
							|  |  |  |     buffer = 0; | 
					
						
							|  |  |  |     external = false; | 
					
						
							|  |  |  |     arebuilding = false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RTCPCompoundPacketBuilder::~RTCPCompoundPacketBuilder() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (external) | 
					
						
							|  |  |  |         compoundpacket = 0; // make sure RTCPCompoundPacket doesn't delete the external buffer
 | 
					
						
							|  |  |  |     ClearBuildBuffers(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RTCPCompoundPacketBuilder::ClearBuildBuffers() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     report.Clear(); | 
					
						
							|  |  |  |     sdes.Clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::list<Buffer>::const_iterator it; | 
					
						
							|  |  |  |     for (it = byepackets.begin(); it != byepackets.end(); it++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ((*it).packetdata) | 
					
						
							|  |  |  |             delete[] (*it).packetdata; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (it = apppackets.begin(); it != apppackets.end(); it++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ((*it).packetdata) | 
					
						
							|  |  |  |             delete[] (*it).packetdata; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     byepackets.clear(); | 
					
						
							|  |  |  |     apppackets.clear(); | 
					
						
							|  |  |  |     byesize = 0; | 
					
						
							|  |  |  |     appsize = 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  | int RTCPCompoundPacketBuilder::InitBuild(std::size_t maxpacketsize) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILDING; | 
					
						
							|  |  |  |     if (compoundpacket) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (maxpacketsize < RTP_MINPACKETSIZE) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_MAXPACKETSIZETOOSMALL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     maximumpacketsize = maxpacketsize; | 
					
						
							|  |  |  |     buffer = 0; | 
					
						
							|  |  |  |     external = false; | 
					
						
							|  |  |  |     byesize = 0; | 
					
						
							|  |  |  |     appsize = 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     arebuilding = true; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  | int RTCPCompoundPacketBuilder::InitBuild(void *externalbuffer, std::size_t buffersize) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILDING; | 
					
						
							|  |  |  |     if (compoundpacket) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYBUILT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (buffersize < RTP_MINPACKETSIZE) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_BUFFERSIZETOOSMALL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     maximumpacketsize = buffersize; | 
					
						
							|  |  |  |     buffer = (uint8_t *) externalbuffer; | 
					
						
							|  |  |  |     external = true; | 
					
						
							|  |  |  |     byesize = 0; | 
					
						
							|  |  |  |     appsize = 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     arebuilding = true; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTCPCompoundPacketBuilder::StartSenderReport(uint32_t senderssrc, const RTPNTPTime &ntptimestamp, uint32_t rtptimestamp, uint32_t packetcount, uint32_t octetcount) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (report.headerlength != 0) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYGOTREPORT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t totalsize = byesize + appsize + sdes.NeededBytes(); | 
					
						
							|  |  |  |     std::size_t sizeleft = maximumpacketsize - totalsize; | 
					
						
							|  |  |  |     std::size_t neededsize = sizeof(RTCPCommonHeader) + sizeof(uint32_t) + sizeof(RTCPSenderReport); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (neededsize > sizeleft) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     // fill in some things
 | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     report.headerlength = sizeof(uint32_t) + sizeof(RTCPSenderReport); | 
					
						
							|  |  |  |     report.isSR = true; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint32_t *ssrc = (uint32_t *) report.headerdata; | 
					
						
							|  |  |  |     *ssrc = qToBigEndian(senderssrc); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTCPSenderReport *sr = (RTCPSenderReport *) (report.headerdata + sizeof(uint32_t)); | 
					
						
							|  |  |  |     sr->ntptime_msw = qToBigEndian(ntptimestamp.GetMSW()); | 
					
						
							|  |  |  |     sr->ntptime_lsw = qToBigEndian(ntptimestamp.GetLSW()); | 
					
						
							|  |  |  |     sr->rtptimestamp = qToBigEndian(rtptimestamp); | 
					
						
							|  |  |  |     sr->packetcount = qToBigEndian(packetcount); | 
					
						
							|  |  |  |     sr->octetcount = qToBigEndian(octetcount); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int RTCPCompoundPacketBuilder::StartReceiverReport(uint32_t senderssrc) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; | 
					
						
							|  |  |  |     if (report.headerlength != 0) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_ALREADYGOTREPORT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t totalsize = byesize + appsize + sdes.NeededBytes(); | 
					
						
							|  |  |  |     std::size_t sizeleft = maximumpacketsize - totalsize; | 
					
						
							|  |  |  |     std::size_t neededsize = sizeof(RTCPCommonHeader) + sizeof(uint32_t); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (neededsize > sizeleft) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     // fill in some things
 | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     report.headerlength = sizeof(uint32_t); | 
					
						
							|  |  |  |     report.isSR = false; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint32_t *ssrc = (uint32_t *) report.headerdata; | 
					
						
							|  |  |  |     *ssrc = qToBigEndian(senderssrc); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTCPCompoundPacketBuilder::AddReportBlock(uint32_t ssrc, uint8_t fractionlost, int32_t packetslost, uint32_t exthighestseq, uint32_t jitter, uint32_t lsr, uint32_t dlsr) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; | 
					
						
							|  |  |  |     if (report.headerlength == 0) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_REPORTNOTSTARTED; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t totalothersize = byesize + appsize + sdes.NeededBytes(); | 
					
						
							|  |  |  |     std::size_t reportsizewithextrablock = report.NeededBytesWithExtraReportBlock(); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if ((totalothersize + reportsizewithextrablock) > maximumpacketsize) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint8_t *buf = new uint8_t[sizeof(RTCPReceiverReport)]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     RTCPReceiverReport *rr = (RTCPReceiverReport *) buf; | 
					
						
							|  |  |  |     uint32_t *packlost = (uint32_t *) &packetslost; | 
					
						
							|  |  |  |     uint32_t packlost2 = (*packlost); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rr->ssrc = qToBigEndian(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 = qToBigEndian(exthighestseq); | 
					
						
							|  |  |  |     rr->jitter = qToBigEndian(jitter); | 
					
						
							|  |  |  |     rr->lsr = qToBigEndian(lsr); | 
					
						
							|  |  |  |     rr->dlsr = qToBigEndian(dlsr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     report.reportblocks.push_back(Buffer(buf, sizeof(RTCPReceiverReport))); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int RTCPCompoundPacketBuilder::AddSDESSource(uint32_t ssrc) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t totalotherbytes = byesize + appsize + report.NeededBytes(); | 
					
						
							|  |  |  |     std::size_t sdessizewithextrasource = sdes.NeededBytesWithExtraSource(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if ((totalotherbytes + sdessizewithextrasource) > maximumpacketsize) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     int status; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if ((status = sdes.AddSSRC(ssrc)) < 0) | 
					
						
							|  |  |  |         return status; | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTCPCompoundPacketBuilder::AddSDESNormalItem(RTCPSDESPacket::ItemType t, const void *itemdata, uint8_t itemlength) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t totalotherbytes = byesize + appsize + report.NeededBytes(); | 
					
						
							|  |  |  |     std::size_t sdessizewithextraitem = sdes.NeededBytesWithExtraItem(itemlength); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if ((sdessizewithextraitem + totalotherbytes) > maximumpacketsize) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint8_t *buf; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t len; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     buf = new uint8_t[sizeof(RTCPSDESHeader) + (std::size_t) itemlength]; | 
					
						
							|  |  |  |     len = sizeof(RTCPSDESHeader) + (std::size_t) itemlength; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (buf); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sdeshdr->sdesid = itemid; | 
					
						
							|  |  |  |     sdeshdr->length = itemlength; | 
					
						
							|  |  |  |     if (itemlength != 0) | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         memcpy((buf + sizeof(RTCPSDESHeader)), itemdata, (std::size_t) itemlength); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sdes.AddItem(buf, len); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef RTP_SUPPORT_SDESPRIV
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTCPCompoundPacketBuilder::AddSDESPrivateItem(const void *prefixdata, uint8_t prefixlength, const void *valuedata, uint8_t valuelength) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; | 
					
						
							|  |  |  |     if (sdes.sdessources.empty()) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOCURRENTSOURCE; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t itemlength = ((std::size_t) prefixlength) + 1 + ((std::size_t) valuelength); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (itemlength > 255) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_TOTALITEMLENGTHTOOBIG; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t totalotherbytes = byesize + appsize + report.NeededBytes(); | 
					
						
							|  |  |  |     std::size_t sdessizewithextraitem = sdes.NeededBytesWithExtraItem(itemlength); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if ((sdessizewithextraitem + totalotherbytes) > maximumpacketsize) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint8_t *buf; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t len; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     buf = new uint8_t[sizeof(RTCPSDESHeader) + itemlength]; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     len = sizeof(RTCPSDESHeader) + (std::size_t) itemlength; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTCPSDESHeader *sdeshdr = (RTCPSDESHeader *) (buf); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sdeshdr->sdesid = RTCP_SDES_ID_PRIVATE; | 
					
						
							|  |  |  |     sdeshdr->length = itemlength; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     buf[sizeof(RTCPSDESHeader)] = prefixlength; | 
					
						
							|  |  |  |     if (prefixlength != 0) | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         memcpy((buf + sizeof(RTCPSDESHeader) + 1), prefixdata, (std::size_t) prefixlength); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (valuelength != 0) | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         memcpy((buf + sizeof(RTCPSDESHeader) + 1 + (std::size_t) prefixlength), valuedata, (std::size_t) valuelength); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     sdes.AddItem(buf, len); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif // RTP_SUPPORT_SDESPRIV
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | int RTCPCompoundPacketBuilder::AddBYEPacket(uint32_t *ssrcs, uint8_t numssrcs, const void *reasondata, uint8_t reasonlength) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (numssrcs > 31) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_TOOMANYSSRCS; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t packsize = sizeof(RTCPCommonHeader) + sizeof(uint32_t) * ((std::size_t) numssrcs); | 
					
						
							|  |  |  |     std::size_t zerobytes = 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (reasonlength > 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         packsize += 1; // 1 byte for the length;
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         packsize += (std::size_t) reasonlength; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         std::size_t r = (packsize & 0x03); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         if (r != 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             zerobytes = 4 - r; | 
					
						
							|  |  |  |             packsize += zerobytes; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t totalotherbytes = appsize + byesize + sdes.NeededBytes() + report.NeededBytes(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if ((totalotherbytes + packsize) > maximumpacketsize) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint8_t *buf; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t numwords; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     buf = new uint8_t[packsize]; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTCPCommonHeader *hdr = (RTCPCommonHeader *) buf; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     hdr->version = 2; | 
					
						
							|  |  |  |     hdr->padding = 0; | 
					
						
							|  |  |  |     hdr->count = numssrcs; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     numwords = packsize / sizeof(uint32_t); | 
					
						
							|  |  |  |     hdr->length = qToBigEndian((uint16_t) (numwords - 1)); | 
					
						
							|  |  |  |     hdr->packettype = RTP_RTCPTYPE_BYE; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint32_t *sources = (uint32_t *) (buf + sizeof(RTCPCommonHeader)); | 
					
						
							|  |  |  |     uint8_t srcindex; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     for (srcindex = 0; srcindex < numssrcs; srcindex++) | 
					
						
							|  |  |  |         sources[srcindex] = qToBigEndian(ssrcs[srcindex]); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (reasonlength != 0) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         std::size_t offset = sizeof(RTCPCommonHeader) + ((std::size_t) numssrcs) * sizeof(uint32_t); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |         buf[offset] = reasonlength; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |         memcpy((buf + offset + 1), reasondata, (std::size_t) reasonlength); | 
					
						
							|  |  |  |         for (std::size_t i = 0; i < zerobytes; i++) | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |             buf[packsize - 1 - i] = 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     byepackets.push_back(Buffer(buf, packsize)); | 
					
						
							|  |  |  |     byesize += packsize; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  | int RTCPCompoundPacketBuilder::AddAPPPacket(uint8_t subtype, uint32_t ssrc, const uint8_t name[4], const void *appdata, std::size_t appdatalen) | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; | 
					
						
							|  |  |  |     if (subtype > 31) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALSUBTYPE; | 
					
						
							|  |  |  |     if ((appdatalen % 4) != 0) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_ILLEGALAPPDATALENGTH; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t appdatawords = appdatalen / 4; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if ((appdatawords + 2) > 65535) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_APPDATALENTOOBIG; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t packsize = sizeof(RTCPCommonHeader) + sizeof(uint32_t) * 2 + appdatalen; | 
					
						
							|  |  |  |     std::size_t totalotherbytes = appsize + byesize + sdes.NeededBytes() + report.NeededBytes(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if ((totalotherbytes + packsize) > maximumpacketsize) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTENOUGHBYTESLEFT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint8_t *buf; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     buf = new uint8_t[packsize]; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     RTCPCommonHeader *hdr = (RTCPCommonHeader *) buf; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     hdr->version = 2; | 
					
						
							|  |  |  |     hdr->padding = 0; | 
					
						
							|  |  |  |     hdr->count = subtype; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     hdr->length = qToBigEndian((uint16_t) (appdatawords + 2)); | 
					
						
							|  |  |  |     hdr->packettype = RTP_RTCPTYPE_APP; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint32_t *source = (uint32_t *) (buf + sizeof(RTCPCommonHeader)); | 
					
						
							|  |  |  |     *source = qToBigEndian(ssrc); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     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]; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (appdatalen > 0) | 
					
						
							|  |  |  |         memcpy((buf + sizeof(RTCPCommonHeader) + sizeof(uint32_t) * 2), appdata, appdatalen); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     apppackets.push_back(Buffer(buf, packsize)); | 
					
						
							|  |  |  |     appsize += packsize; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int RTCPCompoundPacketBuilder::EndBuild() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!arebuilding) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOTBUILDING; | 
					
						
							|  |  |  |     if (report.headerlength == 0) | 
					
						
							|  |  |  |         return ERR_RTP_RTCPCOMPPACKBUILDER_NOREPORTPRESENT; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     uint8_t *buf; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |     std::size_t len; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     len = appsize + byesize + report.NeededBytes() + sdes.NeededBytes(); | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     if (!external) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         buf = new uint8_t[len]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |             std::size_t offset; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             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++; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |             std::size_t numwords = offset / sizeof(uint32_t); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             hdr->length = qToBigEndian((uint16_t) (numwords - 1)); | 
					
						
							|  |  |  |             hdr->count = count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // add entry in parent's list
 | 
					
						
							|  |  |  |             if (hdr->packettype == RTP_RTCPTYPE_SR) | 
					
						
							|  |  |  |                 p = new RTCPSRPacket(curbuf, offset); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 p = new RTCPRRPacket(curbuf, offset); | 
					
						
							|  |  |  |             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; | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |             std::size_t offset = sizeof(RTCPCommonHeader); | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             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 = qToBigEndian((*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++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |                 std::size_t r = offset & 0x03; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |                 if (r != 0) // align to 32 bit boundary
 | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |                     std::size_t num = 4 - r; | 
					
						
							|  |  |  |                     std::size_t i; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     for (i = 0; i < num; i++) | 
					
						
							|  |  |  |                         curbuf[offset + i] = 0; | 
					
						
							|  |  |  |                     offset += num; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 sourceit++; | 
					
						
							|  |  |  |                 sourcecount++; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-28 13:31:44 +01:00
										 |  |  |             std::size_t numwords = offset / 4; | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             hdr->count = sourcecount; | 
					
						
							|  |  |  |             hdr->length = qToBigEndian((uint16_t) (numwords - 1)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             p = new RTCPSDESPacket(curbuf, offset); | 
					
						
							|  |  |  |             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 = new RTCPAPPPacket(curbuf, (*it).packetlength); | 
					
						
							|  |  |  |             rtcppacklist.push_back(p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             curbuf += (*it).packetlength; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-27 23:05:46 +01:00
										 |  |  |     // adding bye packets
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::list<Buffer>::const_iterator it; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (it = byepackets.begin(); it != byepackets.end(); it++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             memcpy(curbuf, (*it).packetdata, (*it).packetlength); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             p = new RTCPBYEPacket(curbuf, (*it).packetlength); | 
					
						
							|  |  |  |             rtcppacklist.push_back(p); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             curbuf += (*it).packetlength; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     compoundpacket = buf; | 
					
						
							|  |  |  |     compoundpacketlength = len; | 
					
						
							|  |  |  |     arebuilding = false; | 
					
						
							|  |  |  |     ClearBuildBuffers(); | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2018-02-27 01:35:16 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // end namespace
 | 
					
						
							|  |  |  | 
 |