1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3 // Copyright (C) 2015 Cherokees of Idaho.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 // As a special exception, you may use this file as part of a free software
20 // library without restriction. Specifically, if other files instantiate
21 // templates or use macros or inline functions from this file, or you compile
22 // this file and link it with other files to produce an executable, this
23 // file does not by itself cause the resulting executable to be covered by
24 // the GNU General Public License. This exception does not however
25 // invalidate any other reasons why the executable file might be covered by
26 // the GNU General Public License.
27 //
28 // This exception applies only to the code released under the name GNU
29 // ccRTP. If you copy code from other releases into a copy of GNU
30 // ccRTP, as the General Public License permits, the exception does
31 // not apply to the code that you add in this way. To avoid misleading
32 // anyone as to the status of such modified files, you must delete
33 // this exception notice from them.
34 //
35 // If you write modifications of your own for GNU ccRTP, it is your choice
36 // whether to permit this exception to apply to your modifications.
37 // If you do not wish that, delete this exception notice.
38 //
39
47 #include <cstdlib>
49 #include <cstdlib>
50 #include <climits>
51
52 NAMESPACE_COMMONCPP
53
60
63 queueApplication(app), srtcpIndex(0)
64 {
70
72
74
75 // initialize RTCP timing
81
86 // force an initial check for incoming RTCP packets
88 // check for incoming RTCP packets every 1/4 seconds.
92
94
96
99
100 // Fill in fixed fields that will never change
103 // (SSRCCollision will have to take this into account)
105
106 // allow to start RTCP service once everything is set up
108 }
109
110 // TODO Streamline this code (same as above, put into a separate method)
114 queueApplication(app), srtcpIndex(0)
115 {
121
123
125
126 // initialize RTCP timing
129
132
134
138 // force an initial check for incoming RTCP packets
140 // check for incoming RTCP packets every 1/4 seconds.
144
146
148
151
152 // Fill in fixed fields that will never change
155 // (SSRCCollision will have to take this into account)
157
158 // allow to start RTCP service once everything is set up
160 }
161
163 {
165 }
166
168 {
173
174 }
175
177 bool is_new, InetAddress& network_address, tpport_t transport_port)
178 {
179 bool result = true;
180
181 // Test if the source is new and it is not the local one.
183 return result;
184
188 // SSRC collision or a loop has happened
190 // TODO: Optional error counter.
191
192 // Note this differs from the default in the RFC.
193 // Discard packet only when the collision is
194 // repeating (to avoid flip-flopping)
196 (
197 (network_address ==
199 &&
200 (transport_port ==
202 ) ) {
203 // discard packet and do not flip-flop
204 result = false;
205 } else {
206 // Record who has collided so that in
207 // the future we can how if the
208 // collision repeats.
210 0,transport_port);
211 // Change sync source transport address
214 }
215
216 } else {
217 // Collision or loop of own packets.
220 transport_port);
221 if ( conflicting ) {
222 // Optional error counter.
224 result = false;
225 } else {
226 // New collision
230 dispatchBYE(
"SSRC collision detected when receiving RTCP packet");
236 }
237 }
238 }
239 return result;
240 }
241
243 {
245 return;
246
247 // A) see if there are incoming RTCP packets
248 SysTime::gettimeofday(&(
reconsInfo.rtcpTc),NULL);
252 // If this do loops more than once, then we have not
253 // been in time. So it skips until the next future
254 // instant.
255 do {
261 }
262 }
263
265 {
267 return;
268
269 // B) send RTCP packets
270 SysTime::gettimeofday(&(
reconsInfo.rtcpTc),NULL);
273 // this would update to last received RTCP packets
274 //while ( isPendingControl(0) )
275 // takeInControlPacket();
282 // we have updated tp and sent a report, so we
283 // have to recalculate the sending interval
286
287 // record current number of members for the
288 // next check.
290 }
291 }
292 }
293
295 {
296 bool result = false;
297 // compute again the interval to confirm it under current
298 // circumstances
301 SysTime::gettimeofday(&(
reconsInfo.rtcpTc),NULL);
304 result = true;
305 }
306 return result;
307 }
308
309 void
311 {}
312
313 void
315 {
316 size_t len = 0;
317 InetHostAddress network_address;
318 tpport_t transport_port;
320
321 // get time of arrival
322 struct timeval recvtime;
323 SysTime::gettimeofday(&recvtime,NULL);
324
325 // process a 'len' octets long RTCP compound packet
326
328
330 if (pcc == NULL) {
332 if (pcc != NULL) {
334 if (pcc != NULL) {
337 }
338 }
339 }
340 // If no crypto context: then SRTP/SRTCP is off
341 // If crypto context is available then unprotect data here. If an error
342 // occurs report the error and discard the packet.
343 if (pcc != NULL) {
344 int32 ret;
346 // TODO: do more error handling?
347 return;
348 }
349 len = ret; // adjust length after unprotecting the packet
350 }
351 // Check validity of the header fields of the compound packet
353 return;
354
355
356 // TODO: for now, we do nothing with the padding bit
357 // in the header.
358
359 bool source_created;
362
363 if ( source_created ) {
364 // Set control transport address.
366 // Network address is assumed to be the same as the control one
372 } else if ( s->getControlTransportPort() == 0 ) {
373 // Test if RTP data packets had been received but this
374 // is the first control packet from this source.
376 }
377 // record reception time
380
381 size_t pointer = 0;
382 // Check the first packet is a report and do special
383 // processing for SR reports.
385 // no special initialization is required for
386 // RR reports, all reports will be processed
387 // in the do-while down here.
390 network_address,
391 transport_port) )
394 // Advance to the next packet in the compound.
398 // TODO: handle XR reports.
399 } else {
400 // Ignore RTCP types unknown.
401 }
402
403 // Process all RR reports.
406 source_created);
408 network_address,transport_port) )
410 // Advance to the next packet in the compound
413 }
414
415 // SDES, APP and BYE. process first everything but the
416 // BYE packets.
417 bool cname_found = false;
418 while ( (pointer < len ) &&
423 source_created);
425 network_address,
426 transport_port) ) {
429 cname_found = cname_found? cname_found : cname;
432 // pointer += pkt->getLength();
433 } else {
434 // error?
435 }
436 }
437 // Get the next packet in the compound.
440 }
441
442 // TODO: error? if !cname_found
443
444 // process BYE packets
445 while ( pointer < len ) {
448 source_created);
450 network_address,
451 transport_port) )
454 break; // TODO: check non-BYE out of place.
455 } else {
456 break;
457 }
458 }
459
460 // Call plug-in in case there are profile extensions
461 // at the end of the SR/RR.
462 if ( pointer != len ) {
464 len - pointer);
465 }
466
467 // Everything went right, update the RTCP average size
469 }
470
472 {
473 bool result = false;
474
478 if ( NULL != si ) {
482 // approx.
486
489 timeval packetTime;
490 timeradd(&tNTP,&timevalInc,&packetTime);
491 timeval now, diff;
492 SysTime::gettimeofday(&now,NULL);
493 timersub(&now,&packetTime,&diff);
494
496 result = true;
497 }
498 }
499 return result;
500 }
501
503 {
504 // We ignore the receiver blocks and just get the sender info
505 // at the beginning of the SR.
507 }
508
510 {
511 for ( uint8 i = 0; i < blocks; i++) {
512 // this generic RTCP manager ignores reports about
513 // other sources than the local one
516 setReceiverInfo
517 (reinterpret_cast<unsigned char*>(&(RR.
blocks[i].
rinfo)));
518 }
519 }
520 }
521
523 {
524 size_t newlen = len;
527 }
528
530 {
532 return false;
533
534 char *reason = NULL;
535
541 reason = new char[len + 1];
543 reason[len] = '0円';
544 } else { // avoid dangerous conversion of NULL to a C++ string.
545 reason = new char[1];
546 reason[0] = '0円';
547 }
548
549 int i = 0;
551 bool created;
554 i++;
559
561 }
562
563 delete [] reason;
565 return true;
566 }
567
569 {
571 timeval inc;
572
573 // reconsider reconsInfo.rtcpTn (time for next RTCP packet)
576 1000000 +
580 inc.tv_usec = t % 1000000;
581 inc.tv_sec = t / 1000000;
583
584 // reconsider tp (time for previous RTCP packet)
586 1000000 +
590 inc.tv_usec = t % 1000000;
591 inc.tv_sec = t / 1000000;
593 }
595 }
596
598 {
599 // Take into account that length fields in SDES items are
600 // 8-bit long, so no ntoh[s|l] is required
601 bool cname_found = false;
602
603 std::ptrdiff_t pointer =
reinterpret_cast<unsigned char*
>(&pkt) -
rtcpRecvBuffer;
604 uint16 i = 0;
605 do {
609
610 bool source_created = false;
611 // TODO: avoid searching again the source of the first chunk.
614 source_created);
615 // TODO: check that there are no two chunks with the
616 // same SSRC but different CNAME
618
620 cname_found = true;
621 pointer +=len;
624 i++;
626 return cname_found;
627 }
628
630 {
631 bool cname_found = false;
633
636
637 size_t pointer =
sizeof(chunk.
ssrc);
638
639 // process chunk items
640 while ( (pointer < len) && !
end ) {
642 reinterpret_cast<SDESItem*
>(size_t(&(chunk)) + pointer);
644 pointer +=
sizeof(item->
type) +
sizeof(item->
len) +
648 std::string cname = std::string(item->
data,item->
len);
650 if ( p ) {
653 } else {
656 }
658 }
659
660 // support for CNAME updates
661 if ( part )
663
665 cname_found = true;
666 // note that CNAME must be send in
667 // every RTCP compound, so we only
668 // trust sources that include it.
671 }
673 end = true;
674 pointer++;
675 pointer += (pointer & 0x03); // padding
677 std::ptrdiff_t prevpointer = pointer;
678 uint8 plength = *( &(item->
len) + 1 );
679 pointer +=
sizeof(item->
type) +
sizeof(item->
len) + 1;
680
681 if ( part )
683 reinterpret_cast<char*>(item + pointer),plength);
684 pointer += plength;
686 reinterpret_cast<char*>(item + pointer),
687 (item->
len - 1 - plength));
688 pointer = prevpointer + item->
len;
689 } else {
690 pointer++;
691 // TODO: error: SDES unknown
693 }
694 }
695 return cname_found;
696 }
697
699 {
704 // reserve "sendControlBwFract" fraction of the total
705 // RTCP bandwith for senders.
707 // we take the side of active senders
710 } else {
711 // we take the side of passive receivers
714 }
715 }
716
718 // be a bit quicker at first
720 min_interval /= 2;
721 // this is the real computation:
723 if ( bwfract != 0 ) {
725 ((participants *
rtcpAvgSize / bwfract) * 1000000);
726
729 } else {
730 // 100 seconds instead of infinite
731 interval = 100000000;
732 }
733
735 (rand() / (RAND_MAX + 1.0))));
736
737 timeval result;
738 result.tv_sec = interval / 1000000;
739 result.tv_usec = interval % 1000000;
740 return result;
741 }
742
743 #define BYE_BUFFER_LENGTH 500
744
746 {
747 // for this method, see section 6.3.7 in RFC 3550
748 // never send a BYE packet if never sent an RTP or RTCP packet
749 // before
751 return 0;
752
754 // Usurp the scheduler role and apply a back-off
755 // algorithm to avoid BYE floods.
756 SysTime::gettimeofday(&(
reconsInfo.rtcpTc),NULL);
763 strlen(reason.c_str()) +
764 (4 - (strlen(reason.c_str()) & 0x03)));
765 SysTime::gettimeofday(&(
reconsInfo.rtcpTc),NULL);
771 break;
772 SysTime::gettimeofday(&(
reconsInfo.rtcpTc),NULL);
773 }
774 }
775
776
778 // Build an empty RR as first packet in the compound.
779 // TODO: provide more information if available. Not really
780 // important, since this is the last packet being sent.
787 uint16 len1 =
sizeof(
RTCPFixedHeader) +
sizeof(uint32);
// 1st pkt len.
788 pkt->
fh.
length = htons((len1 >> 2) - 1);
789 uint16 len = len1; // whole compound len.
790 // build a BYE packet
791 uint16 padlen = 0;
792 pkt =
reinterpret_cast<RTCPPacket*
>(buffer + len1);
796 // add the SSRC identifier
799 // add the optional reason
800 if ( reason.c_str() != NULL ){
804 padlen = 4 - ((len - len1) & 0x03);
805 if ( padlen ) {
806 memset(buffer + len,0,padlen);
807 len += padlen;
809 }
810 }
811 pkt->
fh.
length = htons(((len - len1) >> 2) - 1);
812
814 }
815
817 {
818 // This method is kind of simplified recvControl
819 timeval wait;
822 // wait up to reconsInfo.rtcpTn
824 return;
825
826 size_t len = 0;
827 InetHostAddress network_address;
828 tpport_t transport_port;
830 network_address,transport_port)) ) {
831 // Process a <code>len<code> octets long RTCP compound packet
832 // Check validity of the header fields of the compound packet
834 return;
835
836 // TODO: For now, we do nothing with the padding bit
837 // in the header.
838 uint32 pointer = 0;
840 while ( pointer < len) {
843
845 bool created;
848 created);
852 }
854 }
855 }
856 }
857
859 {
861 // Keep in mind: always include a report (in SR or RR) and at
862 // least a SDES with the local CNAME. It is mandatory.
863
864 // (A) SR or RR, depending on whether we sent.
865 // pkt will point to the packets of the compound
866
868 // Fixed header of the first report
871 // length of the RTCP compound packet. It will increase till
872 // the end of this routine. Both sender and receiver report
873 // carry the general 32-bit long fixed header and a 32-bit
874 // long SSRC identifier.
876
877 // the fields block_count and length will be filled in later
878 // now decide whether to send a SR or a SR
880 // we have sent rtp packets since last RTCP -> send SR
884
885 // Fill in sender info block. It would be more
886 // accurate if this were done as late as possible.
887 timeval now;
888 SysTime::gettimeofday(&now,NULL);
889 // NTP MSB and MSB: dependent on current payload type.
891 pkt->
info.
SR.
sinfo.
NTPLSW = htonl((uint32)(((
double)(now.tv_usec)*(uint32)(~0))/1000000.0));
892 // RTP timestamp
895 tstamp /= 1000;
900 // sender's packet and octet count
904 } else {
905 // RR
908 }
909
910 // (B) put report blocks
911 // After adding report blocks, we have to leave room for at
912 // least a CNAME SDES item
915 - len
917 2*sizeof(uint8) +
919 - 100);
920
921 // if we have to go to a new RR packet
922 bool another = false;
923 uint16 prevlen = 0;
927 else // ( RTCPPacket::tSR == pkt->fh.type )
929 do {
930 uint8 blocks = 0;
932 // the length field specifies 32-bit words
933 pkt->
fh.
length = htons( ((len - prevlen) >> 2) - 1);
934 prevlen = len;
935 if ( 31 == blocks ) {
936 // we would need room for a new RR packet and
937 // a CNAME SDES
938 if ( len < (available -
941 another = true;
942 // Header for this new packet in the compound
949 // appended a new Header and a report block
950
953 } else {
954 another = false;
955 }
956 } else {
957 another = false;
958 }
959 } while ( (len < available) && another );
960
961 // (C) SDES (CNAME)
962 // each SDES chunk must be 32-bit multiple long
963 // fill the padding with 0s
965
966 // TODO: virtual for sending APP RTCP packets?
967
968 // actually send the packet.
971 // Everything went right, update the RTCP average size
973
974 return count;
975 }
976
978 {
979 uint16 prevlen = len;
981 // Fill RTCP fixed header. Note fh.length is not set till the
982 // end of this routine.
989 // put CNAME
990 size_t cnameLen =
992 const char* cname =
998
1000 len += (uint16)cnameLen;
1001 // pack items other than CNAME (following priorities
1002 // stablished inside scheduleSDESItem()).
1007 item->
type = nexttype;
1008 const char *content =
1010 item->
len = (uint8)strlen(content);
1011 len += 2;
1015 }
1016
1017 // pack END item (terminate list of items in this chunk)
1019 len++;
1020
1021 uint8 padding = len & 0x03;
1022 if ( padding ) {
1023 padding = 4 - padding;
1025 len += padding;
1026 }
1027 pkt->
fh.
length = htons((len - prevlen - 1) >>2);
1028 }
1029
1031 {
1032 uint8 j = 0;
1033 // pack as many report blocks as we can
1035 for ( ;
1036 ( ( i != NULL ) &&
1038 ( j < 31 ) );
1041 // update stats.
1052 htonl(static_cast<uint32>(srcLink.
getJitter()));
1055 if ( NULL == si ) {
1058 } else {
1060 htonl( ((ntohl(si->
NTPMSW) & 0x0FFFF) << 16 )+
1061 ((ntohl(si->
NTPLSW) & 0xFFFF0000) >> 16)
1062 );
1063 timeval now, diff;
1064 SysTime::gettimeofday(&now,NULL);
1066 timersub(&now,&last,&diff);
1069 }
1071 j++;
1072 }
1073 return j;
1074 }
1075
1077 const char* const value, size_t len)
1078 {
1079 char* buf = new char[len + 1];
1080 memcpy(buf,value,len);
1081 buf[len] = '0円';
1083 delete [] buf;
1084 }
1085
1087 {
1088 char *buf = new char[len + 1];
1089 memcpy(buf,value,len);
1090 buf[len] = '0円';
1092 delete [] buf;
1093 }
1094
1096 {
1097 uint8 i = 0;
1098 // TODO: follow, at least, standard priorities
1100
1103 i++;
1105 }
1106 bool empty = true;
1108 empty = false;
1110 if ( empty )
1112 else
1113 return type;
1114 }
1115
1117 {
1118 t =
static_cast<SDESItemType >(
static_cast<int>(t) + 1 );
1121 return t;
1122 }
1123
1125 {
1126 size_t count = 0;
1128
1129 // Cast to have easy access to ssrc et al
1131
1133 if (pcc == NULL) {
1135 if (pcc != NULL) {
1137 if (pcc != NULL) {
1140 }
1141 }
1142 }
1143 // If no crypto context: then SRTP/SRTCP is off
1144 // If crypto context is available then unprotect data here. If an error
1145 // occurs report the error and discard the packet.
1146 if (pcc != NULL) {
1147 len =
protect(buffer, len, pcc);
1148 }
1149
1152 } else {
1153 // when no destination has been added, NULL == dest.
1154 for (std::list<TransportAddress*>::iterator i =
1160 }
1161 }
1163
1164 return count;
1165 }
1166
1167 int32
1169 /* Encrypt the packet */
1170
1171 uint32 ssrc = *(reinterpret_cast<uint32*>(pkt + 4)); // always SSRC of sender
1172 ssrc =ntohl(ssrc);
1173
1175
1176 uint32 encIndex =
srtcpIndex | 0x80000000;
// set the E flag
1177
1178 uint32* ip = reinterpret_cast<uint32*>(pkt+len);
1179 *ip = htonl(encIndex);
1180
1181 // NO MKI support yet - here we assume MKI is zero. To build in MKI
1182 // take MKI length into account when storing the authentication tag.
1183
1184 // Compute MAC and store in packet after the SRTCP index field
1186
1188 srtcpIndex &= ~0x80000000;
// clear possible overflow
1189
1191 }
1192
1193 int32
1195 if (pcc == NULL) {
1196 return true;
1197 }
1198
1199 // Compute the total length of the payload
1201
1202 // point to the SRTCP index field just after the real payload
1203 const uint32* index = reinterpret_cast<uint32*>(pkt + payloadLen);
1204 uint32 ssrc = *(reinterpret_cast<uint32*>(pkt + 4)); // always SSRC of sender
1205 ssrc =ntohl(ssrc);
1206
1207 uint32 encIndex = ntohl(*index);
1208 uint32 remoteIndex = encIndex & ~0x80000000; // index without Encryption flag
1209
1211 return -2;
1212 }
1213
1214 uint8 mac[20];
1215
1216 // Now get a pointer to the authentication tag field
1218
1219 // Authenticate includes the index, but not MKI and not (obviously) the tag itself
1222 return -1;
1223 }
1224
1225 // Decrypt the content, exclude the very first SRTCP header (fixed, 8 bytes)
1226 if (encIndex & 0x80000000)
1227 pcc->
srtcpEncrypt(pkt + 8, payloadLen - 8, remoteIndex, ssrc);
1228
1229 // Update the Crypto-context
1230 pcc->
update(remoteIndex);
1231
1232 return payloadLen;
1233 }
1234
1235
1236 void
1238 {
1239 std::list<CryptoContextCtrl *>::iterator i;
1240
1242 // check if a CryptoContext for a SSRC already exists. If yes
1243 // remove it from list before inserting the new one.
1245 if( (*i)->getSsrc() == cc->
getSsrc() ) {
1248 delete tmp;
1249 break;
1250 }
1251 }
1253 }
1254
1255 void
1257 {
1258 std::list<CryptoContextCtrl *>::iterator i;
1259
1261 if (cc == NULL) { // Remove any incoming crypto contexts
1265 delete tmp;
1266 }
1267 }
1268 else {
1270 if( (*i)->getSsrc() == cc->
getSsrc() ) {
1273 delete tmp;
1274 return;
1275 }
1276 }
1277 }
1278 }
1279
1282 {
1283 std::list<CryptoContextCtrl *>::iterator i;
1284
1287 if( (*i)->getSsrc() == ssrc) {
1288 return (*i);
1289 }
1290 }
1291 return NULL;
1292 }
1293
1294 void
1296 {
1297 std::list<CryptoContextCtrl *>::iterator i;
1298
1300 // check if a CryptoContext for a SSRC already exists. If yes
1301 // remove it from list before inserting the new one.
1303 if( (*i)->getSsrc() == cc->
getSsrc() ) {
1306 delete tmp;
1307 break;
1308 }
1309 }
1311 }
1312
1313 void
1315 {
1316 std::list<CryptoContextCtrl *>::iterator i;
1317
1319 if (cc == NULL) { // Remove any incoming crypto contexts
1323 delete tmp;
1324 }
1325 }
1326 else {
1328 if( (*i)->getSsrc() == cc->
getSsrc() ) {
1331 delete tmp;
1332 return;
1333 }
1334 }
1335 }
1336 }
1337
1340 {
1341 std::list<CryptoContextCtrl *>::iterator i;
1342
1345 if( (*i)->getSsrc() == ssrc) {
1346 return (*i);
1347 }
1348 }
1349 return NULL;
1350 }
1351
1352 END_NAMESPACE
1353
uint32 getSendPacketCount() const
Get the total number of packets sent so far.
Struct for a receiver info block in a SR (sender report) or an RR (receiver report) RTCP packet...
uint32 lsr
last sender report timestamp.
uint32 getNTPTimestampFrac() const
Get fractional part of the NTP timestamp of this packet.
unsigned char block_count
< For little endian boxes
uint32 getSendOctetCount() const
Get the total number of octets (payload only) sent so far.
void deriveSrtcpKeys()
Perform key derivation according to SRTP specification.
void addParticipant(RTPApplication &app, Participant &part)
uint32 getNTPTimestampInt() const
Get integer part of the NTP timestamp of this packet.
microtimeout_t getDefaultEnd2EndDelay() const
int32 protect(uint8 *pkt, size_t len, CryptoContextCtrl *cc)
The implementation for a SRTCP cryptographic context.
int32 getTagLength() const
Get the length of the SRTP authentication tag in bytes.
SDESItemType nextSDESType(SDESItemType t)
microtimeout_t getEnd2EndDelay() const
tpport_t getDataTransportPort() const
virtual bool isPendingControl(microtimeout_t timeout)=0
unsigned char * rtcpSendBuffer
low level structs and RTCP packet parsing and building methods.
std::list< CryptoContextCtrl * > outCryptoContexts
An RTP application, holding identifying RTCP SDES item values.
NAMESPACE_COMMONCPP const uint32 NTP_EPOCH_OFFSET
ReceiverInfo rinfo
info about the source.
Synchronization source in an RTP session.
static const SDESItemType firstSchedulable
bool getBYE(RTCPPacket &pkt, size_t &pointer, size_t len)
Process a BYE packet just received and identified.
uint32 highestSeqNum
highest sequence number.
void setPRIVPrefix(Participant *part, const std::string val)
unsigned char * getSenderInfo()
IncomingRTPPkt * getPacket() const
volatile bool controlServiceActive
uint32 ssrc
ssrc identifier of source leaving.
ConflictingTransportAddress * getPrevConflict() const
const uint8 CCRTP_VERSION
RTP protocol version supported.
uint32 jitter
arrival jitter.
virtual size_t sendControl(const unsigned char *const buffer, size_t len)=0
void setPrevConflict(InetAddress &addr, tpport_t dataPort, tpport_t controlPort)
Get conflicting address.
virtual bool onGotSDESChunk(SyncSource &source, SDESChunk &chunk, size_t len)
Plug-in for handling of SDES chunks.
void setProbation(uint8 p)
void updateAvgRTCPSize(size_t len)
This must be called in order to update the average RTCP compound packet size estimation when: ...
uint32 octetCount
cumulative octet counter.
bool checkCompoundRTCPHeader(size_t len)
Perform RTCP compound packet header validity check as specified in draft-ietv-avt-rtp-new.
uint32 microtimeout_t
Time interval expressed in microseconds.
virtual ~QueueRTCPManager()
Sender block information of SR RTCP reports.
Canonical end-point identifier.
int32 unprotect(uint8 *pkt, size_t len, CryptoContextCtrl *cc)
uint32 getSessionBandwidth() const
void srtcpEncrypt(uint8 *rtp, size_t len, uint64 index, uint32 ssrc)
Perform SRTP encryption.
virtual SDESItemType scheduleSDESItem()
Choose which should be the type of the next SDES item sent.
void setState(SyncSource &source, SyncSource::State ns)
bool checkSSRCInRTCPPkt(SyncSourceLink &sourceLink, bool is_new, InetAddress &na, tpport_t tp)
Appy collision and loop detection and correction algorithm when receiving RTCP packets.
microtimeout_t end2EndDelay
unsigned char padding
Padding bit.
bool timerReconsideration()
SyncSourceLink * getNext()
Get the link object for the next RTP source.
void endQueueRTCPManager()
void reverseReconsideration()
Apply reverse reconsideration adjustment to timing parameters when receiving BYE packets and not wait...
uint32 getLength() const
Get the packet length specified in its header, in octets and in host order.
microtimeout_t timeval2microtimeout(const timeval &t)
Convert a time interval, expressed as a timeval value into a microseconds counter.
uint32 getExtendedMaxSeqNum() const
std::list< TransportAddress * > destList
timeval rtcpCheckInterval
CryptoContextCtrl * getInQueueCryptoContextCtrl(uint32 ssrc)
Get an input queue CryptoContext identified by SSRC.
bool getGoodbye()
Mark this source as having sent a BYE control packet.
virtual void onNewSyncSource(const SyncSource &)
Virtual called when a new synchronization source has joined the session.
void setSenderInfo(unsigned char *si)
uint8 getMinValidPacketSequence() const
Get the minimun number of consecutive packets that must be received from a source before accepting it...
static const microtimeout_t defaultEnd2EndDelay
maximum end to end delay: unlimited
uint32 dlsr
delay since last sender report.
Fixed RTCP packet header.
virtual void onGotSR(SyncSource &source, SendReport &SR, uint8 blocks)
Plug-in for processing (acquire information carried in) an incoming RTCP Sender Report.
void removeInQueueCryptoContextCtrl(CryptoContextCtrl *cc)
Remove input queue CryptoContext.
tpport_t controlTransportPort
timeval getInitialTime() const
void lockDestinationList() const
Declaration of ccRTP internal stuff.
virtual void onGotAPP(SyncSource &, RTCPCompoundHandler::APPPacket &, size_t)
Plug-in for handling of APP (application specific) RTCP packets.
virtual void onGotRR(SyncSource &source, RecvReport &RR, uint8 blocks)
Plug-in for processing (acquire information carried in) an incoming RTCP Receiver Report...
uint8 packReportBlocks(RRBlock *blocks, uint16 &len, uint16 &available)
uint16 lostLSW
cumulative lost two LSB.
void setInQueueCryptoContextCtrl(CryptoContextCtrl *cc)
Set input queue CryptoContext.
virtual void onGotGoodbye(const SyncSource &, const std::string &)
A plugin point for goodbye message.
Synchronization Source internal handler within the incoming packets queue.
size_t sendControlToDestinations(unsigned char *buffer, size_t len)
void getOnlyBye()
To be executed when whe are leaving the session.
uint32 getSendRTCPPacketCount() const
Get the total number of RTCP packets sent until now.
SyncSource * getSource()
Get the synchronization source object this link objet holds information for.
static const double RECONSIDERATION_COMPENSATION
void setSDESItem(Participant *part, SDESItemType type, const char *const value, size_t len)
Set item value from a string without null termination (as it is transported in RTCP packets)...
Struct for BYE (leaving session) RTCP packets.
uint8 lostMSB
cumulative lost MSB of 3 octets.
uint8 len
item len in octets.
uint8 type
type of RTCP packet.
uint32 getInitialTimestamp()
uint32 ssrc
SSRC identifer from sender.
uint32 NTPMSW
NTP timestamp higher octets.
A class of objects representing remote participants (RTP applications) in a multimedia session...
uint32 getTimestamp() const
Struct for the sender info block in a SR (sender report) RTCP packet.
Struct for SR (sender report) RTCP packets.
CryptoContextCtrl * getOutQueueCryptoContextCtrl(uint32 ssrc)
Get an output queue CryptoContext identified by SSRC.
uint8 length
[optional] length of reason.
QueueRTCPManager(uint32 size=RTPDataQueue::defaultMembersHashSize, RTPApplication &app=defaultApplication())
void setNetworkAddress(SyncSource &source, InetAddress addr)
timeval lastRTCPPacketTime
virtual uint16 transportHeaderSize()
For certain control calculations in RTCP, the size of the underlying network and transport protocols ...
microtimeout_t rtcpMinInterval
RRBlock blocks[1]
receiver report blocks.
uint8 type
item identifier.
SenderInfo sinfo
actual sender info.
void computeStats()
Compute cumulative packet lost and fraction of packets lost during the last reporting interval...
void expireSSRCs()
Purge sources that do not seem active any more.
void setSDESItem(Participant *part, SDESItemType item, const std::string &val)
SDESItem item
SDES item from sender.
Struct for a chunk of items in a SDES RTCP packet.
void removeOutQueueCryptoContextCtrl(CryptoContextCtrl *cc)
Remove output queue CryptoContext.
Participant * getParticipant() const
Get the participant this synchronization source is asociated to.
void setParticipant(SyncSource &source, Participant &p)
RRBlock blocks[1]
possibly several receiver info blocks.
Struct representing general RTCP packet headers as they are sent through the network.
bool BYESource(uint32 ssrc)
Mark the source identified by ssrc as having sent a BYE packet.
Generic RTCP control queues.
void controlReceptionService()
Process incoming RTCP packets pending in the control reception socket.
SDESItemType nextScheduledSDESItem
virtual void setControlPeer(const InetAddress &host, tpport_t port)
uint32 timevalIntervalTo65536(timeval &t)
Convert a time interval, expressed as a timeval, into a 32-bit time interval expressed in units of 1/...
#define BYE_BUFFER_LENGTH
const RTPApplication & getApplication()
timeval getLastRTCPSRTime() const
uint32 getSsrc() const
Get the SSRC of this SRTP Cryptograhic context.
const InetAddress & getNetworkAddress() const
void takeInControlPacket()
For picking up incoming RTCP packets if they are waiting.
SyncSourceLink * getSourceLink() const
tpport_t getControlTransportPort() const
received, but source validity not yet guaranteed.
struct QueueRTCPManager::@0 reconsInfo
bool checkReplay(uint32 newSeqNumber)
Check for packet replay.
void srtcpAuthenticate(uint8 *rtp, size_t len, uint32 roc, uint8 *tag)
Compute the authentication tag.
char data[1]
item content.
Personal NAME of the user.
SyncSourceLink * getSourceBySSRC(uint32 ssrc, bool &created)
Get the description of a source by its ssrc identifier.
uint32 getLocalSSRCNetwork() const
static const SDESItemType lastSchedulable
uint32 RTPTimestamp
RTP timestamp.
virtual uint16 networkHeaderSize()
For certain control calculations in RTCP, the size of the underlying network and transport protocols ...
InetAddress networkAddress
tpport_t getControlTransportPort() const
raw structure of the source and every receiver report in an SR or RR RTCP packet. ...
const InetAddress & getNetworkAddress() const
unsigned char * rtcpRecvBuffer
int32 getMkiLength() const
Get the length of the MKI in bytes.
size_t dispatchControlPacket()
Posting of RTCP messages.
uint32 ssrc
source identifier.
uint32 getSSRC() const
Get the SSRC identifier specified in the packet header, in host order.
static const uint16 TIMEOUT_MULTIPLIER
void setMembersCount(uint32 n)
uint32 getLocalSSRC() const
void setPRIVPrefix(Participant *part, const char *const value, size_t len)
Set PRIV item previx value from a string without null termination (as it is transported in RTCP packe...
uint16 length
number of 32-bit words in the packet (minus one).
Struct for an item description of a SDES packet.
CryptoContextCtrl * newCryptoContextForSSRC(uint32 ssrc)
Derive a new Crypto Context for use with a new SSRC.
uint32 getRTPTimestamp() const
uint8 getFractionLost() const
virtual bool end2EndDelayed(IncomingRTPPktLink &p)
Virtual reimplemented from RTPDataQueue.
uint8 fractionLost
packet fraction lost.
timeval NTP2Timeval(uint32 msw, uint32 lsw)
Convert a NTP timestamp, expressed as two 32-bit long words, into a timeval value.
microtimeout_t leavingDelay
SyncSourceLink * getFirst()
std::list< CryptoContextCtrl * > inCryptoContexts
void controlTransmissionService()
Build and send RTCP packets following timing rules (including the "timer reconsideration" algorithm)...
uint32 getCurrentRTPClockRate() const
Get the clock rate in RTP clock units (for instance, 8000 units per second for PCMU, or 90000 units per second for MP2T).
bool onGotSDES(SyncSource &source, RTCPPacket &pkt)
virtual void onGotRRSRExtension(unsigned char *, size_t)
Plug-in for processing of SR/RR RTCP packet profile-specific extensions (third part of SR reports or ...
uint32 ssrc
source identifier.
void addConflict(const InetAddress &na, tpport_t dtp, tpport_t ctp)
void packSDES(uint16 &len)
Builds an SDES RTCP packet.
const std::string & getSDESItem(SDESItemType item) const
SyncSourceLink * getLink(const SyncSource &source) const
Incoming RTP data packets control structure within the incoming packet queue class.
union RTCPCompoundHandler::RTCPPacket::@6 info
Union for SR, RR, SDES, BYE and APP.
unsigned char version
Version, currently 2.
RTCPFixedHeader fh
Fixed RTCP header.
bool isSingleDestination() const
Get whether there is only a destination in the list.
SyncSourcesIterator end()
uint32 packetCount
cumulative packet counter.
const Participant * getParticipant(const std::string &cname) const
void updateConflict(ConflictingTransportAddress &ca)
void setOutQueueCryptoContextCtrl(CryptoContextCtrl *cc)
Set ouput queue CryptoContext.
void setPrevMembersNum(uint32 n)
virtual size_t recvControl(unsigned char *buffer, size_t len, InetHostAddress &na, tpport_t &tp)=0
uint32 NTPLSW
NTP timestamp lower octets.
virtual timeval computeRTCPInterval()
Computes the interval for sending RTCP compound packets, based on the average size of RTCP packets se...
uint32 lastSendPacketCount
__EXPORT timeval microtimeout2Timeval(microtimeout_t to)
Convert a time interval, expressed as a microtimeout_t (number of microseconds), into a timeval value...
void update(uint32 newSeqNumber)
Update the SRTP packet index.
no packet from this source has been received lately.
A packet queue handler for building different kinds of RTP protocol systems.
ConflictingTransportAddress * searchControlConflict(InetAddress na, tpport_t ctp)
SDESItemType
SDES items that may be carried in a Source DEScription RTCP packet.
bool getHello()
Mark this source as having sent some packet.
uint32 getCumulativePacketLost() const
RTPApplication & queueApplication
size_t dispatchBYE(const std::string &reason)
This method is used to send an RTCP BYE packet.
void unlockDestinationList() const
uint32 ssrc
source identifier.
void setControlTransportPort(SyncSource &source, tpport_t p)