SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
rtpsession.cpp
Go to the documentation of this file.
1 /*
2 
3  This file is a part of JRTPLIB
4  Copyright (c) 1999-2017 Jori Liesenborgs
5 
6  Contact: jori.liesenborgs@gmail.com
7 
8  This library was developed at the Expertise Centre for Digital Media
9  (http://www.edm.uhasselt.be), a research center of the Hasselt University
10  (http://www.uhasselt.be). The library is based upon work done for
11  my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
12 
13  Permission is hereby granted, free of charge, to any person obtaining a
14  copy of this software and associated documentation files (the "Software"),
15  to deal in the Software without restriction, including without limitation
16  the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  and/or sell copies of the Software, and to permit persons to whom the
18  Software is furnished to do so, subject to the following conditions:
19 
20  The above copyright notice and this permission notice shall be included
21  in all copies or substantial portions of the Software.
22 
23  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29  IN THE SOFTWARE.
30 
31  */
32 
33 #include "rtpsession.h"
34 #include "rtperrors.h"
35 // TODO: this is for Create with transmitter creation. See if we keep it.
36 //#include "rtpudpv4transmitter.h"
37 //#include "rtptcptransmitter.h"
38 //#include "rtpexternaltransmitter.h"
39 #include "rtpsessionparams.h"
40 #include "rtpdefines.h"
41 #include "rtprawpacket.h"
42 #include "rtppacket.h"
43 #include "rtptimeutilities.h"
44 #include "rtprandomrand48.h"
45 #include "rtprandomrands.h"
46 #include "rtprandomurandom.h"
47 #ifdef RTP_SUPPORT_SENDAPP
48 #include "rtcpcompoundpacket.h"
49 #endif // RTP_SUPPORT_SENDAPP
50 #include "rtpinternalutils.h"
51 
52 #include <stdlib.h>
53 
54 #include <QHostInfo>
55 
56 
57 namespace qrtplib
58 {
59 
61  rtprnd(GetRandomNumberGenerator(r)),
62  sources(*this),
63  packetbuilder(*rtprnd),
64  rtcpsched(sources, *rtprnd),
65  rtcpbuilder(sources, packetbuilder)
66 {
67  // We're not going to set these flags in Create, so that the constructor of a derived class
68  // can already change them
69  m_changeIncomingData = false;
70  m_changeOutgoingData = false;
71 
72  created = false;
73  timeinit.Dummy();
74 
75  //std::cout << (void *)(rtprnd) << std::endl;
76 }
77 
79 {
80  Destroy();
81 
82  if (deletertprnd)
83  delete rtprnd;
84 }
85 
86 //int RTPSession::Create(const RTPSessionParams &sessparams, const RTPTransmissionParams *transparams /* = 0 */, RTPTransmitter::TransmissionProtocol protocol)
87 //{
88 // int status;
89 //
90 // if (created)
91 // return ERR_RTP_SESSION_ALREADYCREATED;
92 //
93 // usingpollthread = sessparams.IsUsingPollThread();
94 //
95 // useSR_BYEifpossible = sessparams.GetSenderReportForBYE();
96 // sentpackets = false;
97 //
98 // // Check max packet size
99 //
100 // if ((maxpacksize = sessparams.GetMaximumPacketSize()) < RTP_MINPACKETSIZE)
101 // return ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL;
102 //
103 // // Initialize the transmission component
104 //
105 // rtptrans = 0;
106 // switch (protocol)
107 // {
108  // TODO: see if we keep this Create method or use the one with the transmitter specified
109 // case RTPTransmitter::IPv4UDPProto:
110 // rtptrans = new RTPUDPv4Transmitter();
111 // break;
112 // case RTPTransmitter::ExternalProto:
113 // rtptrans = new RTPExternalTransmitter();
114 // break;
115 // case RTPTransmitter::UserDefinedProto:
116 // rtptrans = NewUserDefinedTransmitter();
117 // if (rtptrans == 0)
118 // return ERR_RTP_SESSION_USERDEFINEDTRANSMITTERNULL;
119 // break;
120 // case RTPTransmitter::TCPProto:
121 // rtptrans = new RTPTCPTransmitter();
122 // break;
123 
124 // default:
125 // return ERR_RTP_SESSION_UNSUPPORTEDTRANSMISSIONPROTOCOL;
126 // }
127 //
128 // if (rtptrans == 0)
129 // return ERR_RTP_OUTOFMEM;
130 // if ((status = rtptrans->Init()) < 0)
131 // {
132 // delete rtptrans;
133 // return status;
134 // }
135 // if ((status = rtptrans->Create(maxpacksize, transparams)) < 0)
136 // {
137 // delete rtptrans;
138 // return status;
139 // }
140 //
141 // deletetransmitter = true;
142 // return InternalCreate(sessparams);
143 //}
144 
145 int RTPSession::Create(const RTPSessionParams &sessparams, RTPTransmitter *transmitter)
146 {
147  int status;
148 
149  if (created)
151 
152  usingpollthread = sessparams.IsUsingPollThread();
153 
155  sentpackets = false;
156 
157  // Check max packet size
158 
159  if ((maxpacksize = sessparams.GetMaximumPacketSize()) < RTP_MINPACKETSIZE)
161 
162  rtptrans = transmitter;
163 
164  if ((status = rtptrans->SetMaximumPacketSize(maxpacksize)) < 0)
165  return status;
166 
167  deletetransmitter = false;
168  return InternalCreate(sessparams);
169 }
170 
172 {
173  int status;
174 
175  // Initialize packet builder
176 
177  if ((status = packetbuilder.Init(maxpacksize)) < 0)
178  {
179  if (deletetransmitter)
180  delete rtptrans;
181  return status;
182  }
183 
184  if (sessparams.GetUsePredefinedSSRC())
186 
187  // Add our own ssrc to the source table
188 
189  if ((status = sources.CreateOwnSSRC(packetbuilder.GetSSRC())) < 0)
190  {
192  if (deletetransmitter)
193  delete rtptrans;
194  return status;
195  }
196 
197  // Set the initial receive mode
198 
199  if ((status = rtptrans->SetReceiveMode(sessparams.GetReceiveMode())) < 0)
200  {
202  sources.Clear();
203  if (deletetransmitter)
204  delete rtptrans;
205  return status;
206  }
207 
208  // Init the RTCP packet builder
209 
210  double timestampunit = sessparams.GetOwnTimestampUnit();
211  uint8_t buf[1024] = {0};
212  std::size_t buflen = 1024;
213  std::string forcedcname = sessparams.GetCNAME();
214 
215  if (forcedcname.length() == 0)
216  {
217  if ((status = CreateCNAME(buf, &buflen, sessparams.GetResolveLocalHostname())) < 0)
218  {
220  sources.Clear();
221  if (deletetransmitter)
222  delete rtptrans;
223  return status;
224  }
225  }
226  else
227  {
228  strncpy((char * )buf, forcedcname.c_str(), buflen);
229  buf[buflen - 1] = 0;
230  buflen = strlen((char *) buf);
231  }
232 
233  if ((status = rtcpbuilder.Init(maxpacksize, timestampunit, buf, buflen)) < 0)
234  {
236  sources.Clear();
237  if (deletetransmitter)
238  delete rtptrans;
239  return status;
240  }
241 
242  // Set scheduler parameters
243 
244  rtcpsched.Reset();
246 
247  RTCPSchedulerParams schedparams;
248 
249  sessionbandwidth = sessparams.GetSessionBandwidth();
251 
252  if ((status = schedparams.SetRTCPBandwidth(sessionbandwidth * controlfragment)) < 0)
253  {
254  if (deletetransmitter)
255  delete rtptrans;
257  sources.Clear();
259  return status;
260  }
261  if ((status = schedparams.SetSenderBandwidthFraction(sessparams.GetSenderControlBandwidthFraction())) < 0)
262  {
263  if (deletetransmitter)
264  delete rtptrans;
266  sources.Clear();
268  return status;
269  }
270  if ((status = schedparams.SetMinimumTransmissionInterval(sessparams.GetMinimumRTCPTransmissionInterval())) < 0)
271  {
272  if (deletetransmitter)
273  delete rtptrans;
275  sources.Clear();
277  return status;
278  }
279  schedparams.SetUseHalfAtStartup(sessparams.GetUseHalfRTCPIntervalAtStartup());
280  schedparams.SetRequestImmediateBYE(sessparams.GetRequestImmediateBYE());
281 
282  rtcpsched.SetParameters(schedparams);
283 
284  // copy other parameters
285 
286  acceptownpackets = sessparams.AcceptOwnPackets();
289  byemultiplier = sessparams.GetBYETimeoutMultiplier();
292 
293  // Do thread stuff if necessary
294 
295  created = true;
296  return 0;
297 }
298 
300 {
301  if (!created)
302  return;
303 
304  if (deletetransmitter)
305  delete rtptrans;
308  rtcpsched.Reset();
310  sources.Clear();
311 
312  std::list<RTCPCompoundPacket *>::const_iterator it;
313 
314  for (it = byepackets.begin(); it != byepackets.end(); it++)
315  delete *it;
316  byepackets.clear();
317 
318  created = false;
319 }
320 
321 void RTPSession::BYEDestroy(const RTPTime &maxwaittime, const void *reason, std::size_t reasonlength)
322 {
323  if (!created)
324  return;
325 
326  // first, stop the thread so we have full control over all components
327 
328  RTPTime stoptime = RTPTime::CurrentTime();
329  stoptime += maxwaittime;
330 
331  // add bye packet to the list if we've sent data
332 
333  RTCPCompoundPacket *pack;
334 
335  if (sentpackets)
336  {
337  int status;
338 
339  reasonlength = (reasonlength > RTCP_BYE_MAXREASONLENGTH) ? RTCP_BYE_MAXREASONLENGTH : reasonlength;
340  status = rtcpbuilder.BuildBYEPacket(&pack, reason, reasonlength, useSR_BYEifpossible);
341  if (status >= 0)
342  {
343  byepackets.push_back(pack);
344 
345  if (byepackets.size() == 1)
347  }
348  }
349 
350  if (!byepackets.empty())
351  {
352  bool done = false;
353 
354  while (!done)
355  {
356  RTPTime curtime = RTPTime::CurrentTime();
357 
358  if (curtime >= stoptime)
359  done = true;
360 
361  if (rtcpsched.IsTime())
362  {
363  pack = *(byepackets.begin());
364  byepackets.pop_front();
365 
367 
368  OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering
369 
370  delete pack;
371  if (!byepackets.empty()) // more bye packets to send, schedule them
372  rtcpsched.ScheduleBYEPacket((*(byepackets.begin()))->GetCompoundPacketLength());
373  else
374  done = true;
375  }
376  if (!done)
377  RTPTime::Wait(RTPTime(0, 100000));
378  }
379  }
380 
381  if (deletetransmitter)
382  delete rtptrans;
385  rtcpsched.Reset();
387  sources.Clear();
388 
389  // clear rest of bye packets
390  std::list<RTCPCompoundPacket *>::const_iterator it;
391 
392  for (it = byepackets.begin(); it != byepackets.end(); it++)
393  delete *it;
394  byepackets.clear();
395 
396  created = false;
397 }
398 
400 {
401  return created;
402 }
403 
405 {
406  if (!created)
407  return 0;
408 
409  uint32_t ssrc;
410 
411  ssrc = packetbuilder.GetSSRC();
412  return ssrc;
413 }
414 
416 {
417  if (!created)
419  return rtptrans->AddDestination(addr);
420 }
421 
423 {
424  if (!created)
426  return rtptrans->DeleteDestination(addr);
427 }
428 
430 {
431  if (!created)
432  return;
434 }
435 
437 {
438  if (!created)
439  return false;
440  return rtptrans->SupportsMulticasting();
441 }
442 
444 {
445  if (!created)
447  return rtptrans->JoinMulticastGroup(addr);
448 }
449 
451 {
452  if (!created)
454  return rtptrans->LeaveMulticastGroup(addr);
455 }
456 
457 int RTPSession::SendPacket(const void *data, std::size_t len)
458 {
459  int status;
460 
461  if (!created)
463 
464  if ((status = packetbuilder.BuildPacket(data, len)) < 0)
465  {
466  return status;
467  }
469  {
470  return status;
471  }
472 
474  sentpackets = true;
475  return 0;
476 }
477 
478 int RTPSession::SendPacket(const void *data, std::size_t len, uint8_t pt, bool mark, uint32_t timestampinc)
479 {
480  int status;
481 
482  if (!created)
484 
485  if ((status = packetbuilder.BuildPacket(data, len, pt, mark, timestampinc)) < 0)
486  {
487  return status;
488  }
490  {
491  return status;
492  }
493 
495  sentpackets = true;
496  return 0;
497 }
498 
499 int RTPSession::SendPacketEx(const void *data, std::size_t len, uint16_t hdrextID, const void *hdrextdata, std::size_t numhdrextwords)
500 {
501  int status;
502 
503  if (!created)
505 
506  if ((status = packetbuilder.BuildPacketEx(data, len, hdrextID, hdrextdata, numhdrextwords)) < 0)
507  {
508  return status;
509  }
511  {
512  return status;
513  }
514 
516  sentpackets = true;
517  return 0;
518 }
519 
520 int RTPSession::SendPacketEx(const void *data, std::size_t len, uint8_t pt, bool mark, uint32_t timestampinc, uint16_t hdrextID, const void *hdrextdata, std::size_t numhdrextwords)
521 {
522  int status;
523 
524  if (!created)
526 
527  if ((status = packetbuilder.BuildPacketEx(data, len, pt, mark, timestampinc, hdrextID, hdrextdata, numhdrextwords)) < 0)
528  {
529  return status;
530  }
532  {
533  return status;
534  }
535 
537  sentpackets = true;
538  return 0;
539 }
540 
541 #ifdef RTP_SUPPORT_SENDAPP
542 
543 int RTPSession::SendRTCPAPPPacket(uint8_t subtype, const uint8_t name[4], const void *appdata, std::size_t appdatalen)
544 {
545  int status;
546 
547  if (!created)
549 
550  uint32_t ssrc = packetbuilder.GetSSRC();
551 
553 
554  status = pb.InitBuild(maxpacksize);
555 
556  if (status < 0)
557  return status;
558 
559  //first packet in an rtcp compound packet should always be SR or RR
560  if ((status = pb.StartReceiverReport(ssrc)) < 0)
561  return status;
562 
563  //add SDES packet with CNAME item
564  if ((status = pb.AddSDESSource(ssrc)) < 0)
565  return status;
566 
567  std::size_t owncnamelen = 0;
568  uint8_t *owncname = rtcpbuilder.GetLocalCNAME(&owncnamelen);
569 
570  if ((status = pb.AddSDESNormalItem(RTCPSDESPacket::CNAME, owncname, owncnamelen)) < 0)
571  {
572  return status;
573  }
574 
575  //add our application specific packet
576  if ((status = pb.AddAPPPacket(subtype, ssrc, name, appdata, appdatalen)) < 0)
577  return status;
578 
579  if ((status = pb.EndBuild()) < 0)
580  return status;
581 
582  //send packet
584  if (status < 0)
585  return status;
586 
587  sentpackets = true;
588 
589  return pb.GetCompoundPacketLength();
590 }
591 
592 #endif // RTP_SUPPORT_SENDAPP
593 
594 int RTPSession::SendRawData(const void *data, std::size_t len, bool usertpchannel)
595 {
596  if (!created)
598 
599  int status;
600 
601  if (usertpchannel)
602  status = rtptrans->SendRTPData(data, len);
603  else
604  status = rtptrans->SendRTCPData(data, len);
605  return status;
606 }
607 
609 {
610  if (!created)
612 
613  int status;
614 
616  return status;
617 }
618 
620 {
621  if (!created)
623 
624  int status;
625 
626  status = packetbuilder.SetDefaultMark(m);
627  return status;
628 }
629 
631 {
632  if (!created)
634 
635  int status;
636 
637  status = packetbuilder.SetDefaultTimestampIncrement(timestampinc);
638  return status;
639 }
640 
642 {
643  if (!created)
645 
646  int status;
647 
648  status = packetbuilder.IncrementTimestamp(inc);
649  return status;
650 }
651 
653 {
654  if (!created)
656 
657  int status;
658 
660  return status;
661 }
662 
664 {
665  if (!created)
667 
668  int status;
669 
670  status = rtcpbuilder.SetPreTransmissionDelay(delay);
671  return status;
672 }
673 
675 {
676  if (!created)
677  return 0;
678  return rtptrans->GetTransmissionInfo();
679 }
680 
682 {
683  if (!created)
684  return;
686 }
687 
689 {
690  if (!created)
691  return RTPTime(0, 0);
692  if (usingpollthread)
693  return RTPTime(0, 0);
694 
696  return t;
697 }
698 
700 {
701  if (!created)
703  return 0;
704 }
705 
707 {
708  if (!created)
709  return false;
710  return sources.GotoFirstSource();
711 }
712 
714 {
715  if (!created)
716  return false;
717  return sources.GotoNextSource();
718 }
719 
721 {
722  if (!created)
723  return false;
724  return sources.GotoPreviousSource();
725 }
726 
728 {
729  if (!created)
730  return false;
732 }
733 
735 {
736  if (!created)
737  return false;
739 }
740 
742 {
743  if (!created)
744  return false;
746 }
747 
749 {
750  if (!created)
751  return 0;
752  return sources.GetCurrentSourceInfo();
753 }
754 
756 {
757  if (!created)
758  return 0;
759  return sources.GetSourceInfo(ssrc);
760 }
761 
763 {
764  if (!created)
765  return 0;
766  return sources.GetNextPacket();
767 }
768 
770 {
772 }
773 
775 {
776  delete p;
777 }
778 
780 {
781  if (!created)
783  return 0;
784 }
785 
787 {
788  if (!created)
790  return rtptrans->SetReceiveMode(m);
791 }
792 
794 {
795  if (!created)
797  return rtptrans->AddToIgnoreList(addr);
798 }
799 
801 {
802  if (!created)
804  return rtptrans->DeleteFromIgnoreList(addr);
805 }
806 
808 {
809  if (!created)
810  return;
812 }
813 
815 {
816  if (!created)
818  return rtptrans->AddToAcceptList(addr);
819 }
820 
822 {
823  if (!created)
825  return rtptrans->DeleteFromAcceptList(addr);
826 }
827 
829 {
830  if (!created)
831  return;
833 }
834 
836 {
837  if (!created)
839 
840  if (s < RTP_MINPACKETSIZE)
842 
843  int status;
844 
845  if ((status = rtptrans->SetMaximumPacketSize(s)) < 0)
846  return status;
847 
848  if ((status = packetbuilder.SetMaximumPacketSize(s)) < 0)
849  {
850  // restore previous max packet size
852  return status;
853  }
854  if ((status = rtcpbuilder.SetMaximumPacketSize(s)) < 0)
855  {
856  // restore previous max packet size
859  return status;
860  }
861  maxpacksize = s;
862  return 0;
863 }
864 
866 {
867  if (!created)
869 
870  int status;
872  status = p.SetRTCPBandwidth(bw * controlfragment);
873  if (status >= 0)
874  {
876  sessionbandwidth = bw;
877  }
878  return status;
879 }
880 
882 {
883  if (!created)
885 
886  int status;
887 
888  status = rtcpbuilder.SetTimestampUnit(u);
889  return status;
890 }
891 
893 {
894  if (!created)
895  return;
897 }
898 
900 {
901  if (!created)
902  return;
904 }
905 
907 {
908  if (!created)
909  return;
911 }
912 
914 {
915  if (!created)
916  return;
918 }
919 
921 {
922  if (!created)
923  return;
925 }
926 
928 {
929  if (!created)
930  return;
932 }
933 
934 int RTPSession::SetLocalName(const void *s, std::size_t len)
935 {
936  if (!created)
938 
939  int status;
940  status = rtcpbuilder.SetLocalName(s, len);
941  return status;
942 }
943 
944 int RTPSession::SetLocalEMail(const void *s, std::size_t len)
945 {
946  if (!created)
948 
949  int status;
950  status = rtcpbuilder.SetLocalEMail(s, len);
951  return status;
952 }
953 
954 int RTPSession::SetLocalLocation(const void *s, std::size_t len)
955 {
956  if (!created)
958 
959  int status;
960  status = rtcpbuilder.SetLocalLocation(s, len);
961  return status;
962 }
963 
964 int RTPSession::SetLocalPhone(const void *s, std::size_t len)
965 {
966  if (!created)
968 
969  int status;
970  status = rtcpbuilder.SetLocalPhone(s, len);
971  return status;
972 }
973 
974 int RTPSession::SetLocalTool(const void *s, std::size_t len)
975 {
976  if (!created)
978 
979  int status;
980  status = rtcpbuilder.SetLocalTool(s, len);
981  return status;
982 }
983 
984 int RTPSession::SetLocalNote(const void *s, std::size_t len)
985 {
986  if (!created)
988 
989  int status;
990  status = rtcpbuilder.SetLocalNote(s, len);
991  return status;
992 }
993 
995 {
996  RTPRawPacket *rawpack;
997  int status;
998 
999  while ((rawpack = rtptrans->GetNextPacket()) != 0)
1000  {
1002  {
1003  // Provide a way to change incoming data, for decryption for example
1004  if (!OnChangeIncomingData(rawpack))
1005  {
1006  delete rawpack;
1007  continue;
1008  }
1009  }
1010 
1012 
1013  // since our sources instance also uses the scheduler (analysis of incoming packets)
1014  // we'll lock it
1015  if ((status = sources.ProcessRawPacket(rawpack, rtptrans, acceptownpackets)) < 0)
1016  {
1017  delete rawpack;
1018  return status;
1019  }
1020 
1021  if (sources.DetectedOwnCollision()) // collision handling!
1022  {
1023  bool created;
1024 
1025  if ((status = collisionlist.UpdateAddress(&rawpack->GetSenderAddress(), rawpack->GetReceiveTime(), &created)) < 0)
1026  {
1027  delete rawpack;
1028  return status;
1029  }
1030 
1031  if (created) // first time we've encountered this address, send bye packet and
1032  { // change our own SSRC
1033  bool hassentpackets = sentpackets;
1034 
1035  if (hassentpackets)
1036  {
1037  // Only send BYE packet if we've actually sent data using this
1038  // SSRC
1039 
1040  RTCPCompoundPacket *rtcpcomppack;
1041 
1042  if ((status = rtcpbuilder.BuildBYEPacket(&rtcpcomppack, 0, 0, useSR_BYEifpossible)) < 0)
1043  {
1044  delete rawpack;
1045  return status;
1046  }
1047 
1048  byepackets.push_back(rtcpcomppack);
1049  if (byepackets.size() == 1) // was the first packet, schedule a BYE packet (otherwise there's already one scheduled)
1050  {
1052  }
1053  }
1054  // bye packet is built and scheduled, now change our SSRC
1055  // and reset the packet count in the transmitter
1056 
1058 
1059  sentpackets = false;
1060 
1061  // remove old entry in source table and add new one
1062 
1063  if ((status = sources.DeleteOwnSSRC()) < 0)
1064  {
1065  delete rawpack;
1066  return status;
1067  }
1068  if ((status = sources.CreateOwnSSRC(newssrc)) < 0)
1069  {
1070  delete rawpack;
1071  return status;
1072  }
1073  }
1074  }
1075  delete rawpack;
1076  }
1077 
1079 
1081  double Td = d.GetDouble();
1082  RTPTime sendertimeout = RTPTime(Td * sendermultiplier);
1083  RTPTime generaltimeout = RTPTime(Td * membermultiplier);
1084  RTPTime byetimeout = RTPTime(Td * byemultiplier);
1085  RTPTime colltimeout = RTPTime(Td * collisionmultiplier);
1086  RTPTime notetimeout = RTPTime(Td * notemultiplier);
1087 
1088  sources.MultipleTimeouts(t, sendertimeout, byetimeout, generaltimeout, notetimeout);
1089  collisionlist.Timeout(t, colltimeout);
1090 
1091  // We'll check if it's time for RTCP stuff
1092 
1093  bool istime = rtcpsched.IsTime();
1094 
1095  if (istime)
1096  {
1097  RTCPCompoundPacket *pack;
1098 
1099  // we'll check if there's a bye packet to send, or just a normal packet
1100 
1101  if (byepackets.empty())
1102  {
1103  if ((status = rtcpbuilder.BuildNextPacket(&pack)) < 0)
1104  {
1105  return status;
1106  }
1107  if ((status = SendRTCPData(pack->GetCompoundPacketData(), pack->GetCompoundPacketLength())) < 0)
1108  {
1109  delete pack;
1110  return status;
1111  }
1112 
1113  sentpackets = true;
1114 
1115  OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering
1116  }
1117  else
1118  {
1119  pack = *(byepackets.begin());
1120  byepackets.pop_front();
1121 
1122  if ((status = SendRTCPData(pack->GetCompoundPacketData(), pack->GetCompoundPacketLength())) < 0)
1123  {
1124  delete pack;
1125  return status;
1126  }
1127 
1128  sentpackets = true;
1129 
1130  OnSendRTCPCompoundPacket(pack); // we'll place this after the actual send to avoid tampering
1131 
1132  if (!byepackets.empty()) // more bye packets to send, schedule them
1133  {
1134  rtcpsched.ScheduleBYEPacket((*(byepackets.begin()))->GetCompoundPacketLength());
1135  }
1136  }
1137 
1138  rtcpsched.AnalyseOutgoing(*pack);
1139 
1140  delete pack;
1141  }
1142  return 0;
1143 }
1144 
1145 int RTPSession::CreateCNAME(uint8_t *buffer, std::size_t *bufferlength, bool resolve)
1146 {
1147  (void) resolve;
1148  buffer[*bufferlength - 1] = 0;
1149 
1150  std::size_t offset = strlen((const char *) buffer);
1151  if (offset < (*bufferlength - 1))
1152  buffer[offset] = (uint8_t) '@';
1153  offset++;
1154 
1155  std::size_t buflen2 = *bufferlength - offset;
1156 
1157  QString hostnameStr = QHostInfo::localHostName();
1158  int hostnameSize = hostnameStr.size();
1159 
1160  strncpy((char * )(buffer + offset), hostnameStr.toStdString().c_str(), buflen2);
1161  *bufferlength = offset + hostnameSize;
1162 
1163  if (*bufferlength > RTCP_SDES_MAXITEMLENGTH)
1164  *bufferlength = RTCP_SDES_MAXITEMLENGTH;
1165 
1166  return 0;
1167 }
1168 
1170 {
1171  RTPRandom *rnew = 0;
1172 
1173  if (r == 0)
1174  {
1176  deletertprnd = true;
1177  }
1178  else
1179  {
1180  rnew = r;
1181  deletertprnd = false;
1182  }
1183 
1184  return rnew;
1185 }
1186 
1187 int RTPSession::SendRTPData(const void *data, std::size_t len)
1188 {
1189  if (!m_changeOutgoingData)
1190  return rtptrans->SendRTPData(data, len);
1191 
1192  void *pSendData = 0;
1193  std::size_t sendLen = 0;
1194  int status = 0;
1195 
1196  status = OnChangeRTPOrRTCPData(data, len, true, &pSendData, &sendLen);
1197  if (status < 0)
1198  return status;
1199 
1200  if (pSendData)
1201  {
1202  status = rtptrans->SendRTPData(pSendData, sendLen);
1203  OnSentRTPOrRTCPData(pSendData, sendLen, true);
1204  }
1205 
1206  return status;
1207 }
1208 
1209 int RTPSession::SendRTCPData(const void *data, std::size_t len)
1210 {
1211  if (!m_changeOutgoingData)
1212  return rtptrans->SendRTCPData(data, len);
1213 
1214  void *pSendData = 0;
1215  std::size_t sendLen = 0;
1216  int status = 0;
1217 
1218  status = OnChangeRTPOrRTCPData(data, len, false, &pSendData, &sendLen);
1219  if (status < 0)
1220  return status;
1221 
1222  if (pSendData)
1223  {
1224  status = rtptrans->SendRTCPData(pSendData, sendLen);
1225  OnSentRTPOrRTCPData(pSendData, sendLen, false);
1226  }
1227 
1228  return status;
1229 }
1230 
1231 } // end namespace
1232 
int SetSenderBandwidthFraction(double fraction)
int IncrementTimestamp(uint32_t inc)
Definition: rtpsession.cpp:641
RTPTransmitter::ReceiveMode GetReceiveMode() const
int SetMaximumPacketSize(std::size_t s)
Definition: rtpsession.cpp:835
int SendRTPData(const void *data, std::size_t len)
RTPTime GetReceiveTime() const
Definition: rtprawpacket.h:76
void SetHeaderOverhead(std::size_t numbytes)
RTPTime GetRTCPDelay()
Definition: rtpsession.cpp:688
virtual int SendRTPData(const void *data, std::size_t len)=0
int Init(unsigned int maxpacksize)
uint16_t GetSequenceNumber() const
int Create(const RTPSessionParams &sessparams, RTPTransmitter *transmitter)
Definition: rtpsession.cpp:145
double GetDouble() const
RTCPSchedulerParams GetParameters() const
RTPTimeInitializerObject timeinit
std::size_t GetMaximumPacketSize() const
int SendPacketEx(const void *data, std::size_t len, uint16_t hdrextID, const void *hdrextdata, std::size_t numhdrextwords)
Definition: rtpsession.cpp:499
virtual RTPRawPacket * GetNextPacket()=0
void BYEDestroy(const RTPTime &maxwaittime, const void *reason, std::size_t reasonlength)
Definition: rtpsession.cpp:321
double GetOwnTimestampUnit() const
RTPSourceData * GetSourceInfo(uint32_t ssrc)
Definition: rtpsession.cpp:755
int BuildBYEPacket(RTCPCompoundPacket **pack, const void *reason, std::size_t reasonlength, bool useSRifpossible=true)
int SetLocalNote(const void *s, std::size_t len)
Definition: rtpsession.cpp:984
int SetLocalNote(const void *s, std::size_t len)
double GetControlTrafficFraction() const
int SetLocalPhone(const void *s, std::size_t len)
Definition: rtpsession.cpp:964
int CreateCNAME(uint8_t *buffer, std::size_t *bufferlength, bool resolve)
int DeleteFromAcceptList(const RTPAddress &addr)
Definition: rtpsession.cpp:821
int SetLocalPhone(const void *s, std::size_t len)
void SetUseHalfAtStartup(bool usehalf)
Definition: rtcpscheduler.h:90
int SetMinimumTransmissionInterval(const RTPTime &t)
int DeleteDestination(const RTPAddress &addr)
Definition: rtpsession.cpp:422
int SetReceiveMode(RTPTransmitter::ReceiveMode m)
Definition: rtpsession.cpp:786
double GetSenderTimeoutMultiplier() const
void DeletePacket(RTPPacket *p)
Definition: rtpsession.cpp:774
int IncrementTimestamp(uint32_t inc)
RTPPacketBuilder packetbuilder
Definition: rtpsession.h:572
#define RTCP_BYE_MAXREASONLENGTH
Definition: rtpdefines.h:67
void MultipleTimeouts(const RTPTime &curtime, const RTPTime &sendertimeout, const RTPTime &byetimeout, const RTPTime &generaltimeout, const RTPTime &notetimeout)
double GetCollisionTimeoutMultiplier() const
int AddToAcceptList(const RTPAddress &addr)
Definition: rtpsession.cpp:814
int SetLocalTool(const void *s, std::size_t len)
uint16_t GetNextSequenceNumber() const
Definition: rtpsession.cpp:769
int AddAPPPacket(uint8_t subtype, uint32_t ssrc, const uint8_t name[4], const void *appdata, std::size_t appdatalen)
double GetSessionBandwidth() const
int SendRTCPAPPPacket(uint8_t subtype, const uint8_t name[4], const void *appdata, std::size_t appdatalen)
Definition: rtpsession.cpp:543
int LeaveMulticastGroup(const RTPAddress &addr)
Definition: rtpsession.cpp:450
int InitBuild(std::size_t maxpacketsize)
virtual int SendRTCPData(const void *data, std::size_t len)=0
RTCPPacketBuilder rtcpbuilder
Definition: rtpsession.h:574
RTPSourceData * GetCurrentSourceInfo()
Definition: rtpsources.cpp:609
RTPRandom * rtprnd
Definition: rtpsession.h:550
bool GotoNextSourceWithData()
Definition: rtpsession.cpp:734
virtual void DeleteTransmissionInfo(RTPTransmissionInfo *inf)=0
RTPPacket * GetNextPacket()
Definition: rtpsession.cpp:762
virtual int DeleteDestination(const RTPAddress &addr)=0
int SetDefaultTimestampIncrement(uint32_t timestampinc)
int AddToIgnoreList(const RTPAddress &addr)
Definition: rtpsession.cpp:793
virtual int DeleteFromAcceptList(const RTPAddress &addr)=0
#define ERR_RTP_SESSION_MAXPACKETSIZETOOSMALL
Definition: rtperrors.h:113
int JoinMulticastGroup(const RTPAddress &addr)
Definition: rtpsession.cpp:443
#define ERR_RTP_SESSION_NOTCREATED
Definition: rtperrors.h:114
bool GetResolveLocalHostname() const
RTPTransmissionInfo * GetTransmissionInfo()
Definition: rtpsession.cpp:674
void ScheduleBYEPacket(std::size_t packetsize)
int DeleteFromIgnoreList(const RTPAddress &addr)
Definition: rtpsession.cpp:800
RTPSessionSources sources
Definition: rtpsession.h:571
void SetNameInterval(int count)
Definition: rtpsession.cpp:892
double GetBYETimeoutMultiplier() const
bool GotoPreviousSourceWithData()
Definition: rtpsession.cpp:741
unsigned int uint32_t
Definition: rtptypes_win.h:46
#define RTCP_SDES_MAXITEMLENGTH
Definition: rtpdefines.h:65
int ProcessRawPacket(RTPRawPacket *rawpack, RTPTransmitter *trans, bool acceptownpackets)
Definition: rtpsources.cpp:149
virtual int AddToIgnoreList(const RTPAddress &addr)=0
std::string GetCNAME() const
int BuildPacket(const void *data, unsigned int len)
int BuildNextPacket(RTCPCompoundPacket **pack)
int InternalCreate(const RTPSessionParams &sessparams)
Definition: rtpsession.cpp:171
int AddDestination(const RTPAddress &addr)
Definition: rtpsession.cpp:415
int SetLocalName(const void *s, std::size_t len)
Definition: rtpsession.cpp:934
void SetToolInterval(int count)
Definition: rtpsession.cpp:920
int SendRTCPData(const void *data, std::size_t len)
#define ERR_RTP_SESSION_ALREADYCREATED
Definition: rtperrors.h:110
virtual int DeleteFromIgnoreList(const RTPAddress &addr)=0
int SetMaximumPacketSize(std::size_t maxpacksize)
#define RTP_MINPACKETSIZE
Definition: rtpdefines.h:39
RTPCollisionList collisionlist
Definition: rtpsession.h:575
bool GotoFirstSourceWithData()
Definition: rtpsources.cpp:552
virtual void ClearAcceptList()=0
RTPSession(RTPRandom *rnd=0)
Definition: rtpsession.cpp:60
void SetEMailInterval(int count)
Definition: rtpsession.cpp:899
unsigned char uint8_t
Definition: rtptypes_win.h:42
int SetSessionBandwidth(double bw)
Definition: rtpsession.cpp:865
RTPSourceData * GetSourceInfo(uint32_t ssrc)
Definition: rtpsources.cpp:616
int SetLocalEMail(const void *s, std::size_t len)
virtual void OnSentRTPOrRTCPData(void *senddata, std::size_t sendlen, bool isrtp)
Definition: rtpsession.h:650
double GetSourceTimeoutMultiplier() const
void SetNoteInterval(int count)
Definition: rtpsession.cpp:927
unsigned short uint16_t
Definition: rtptypes_win.h:44
bool GetUseHalfRTCPIntervalAtStartup() const
int SetDefaultPayloadType(uint8_t pt)
int UpdateAddress(const RTPAddress *addr, const RTPTime &receivetime, bool *created)
int CreateOwnSSRC(uint32_t ssrc)
Definition: rtpsources.cpp:87
int SetTimestampUnit(double tsunit)
int SetDefaultPayloadType(uint8_t pt)
Definition: rtpsession.cpp:608
RTPTransmitter * rtptrans
Definition: rtpsession.h:553
bool GotoNextSourceWithData()
Definition: rtpsources.cpp:571
virtual int SetMaximumPacketSize(std::size_t s)=0
bool GotoPreviousSourceWithData()
Definition: rtpsources.cpp:590
std::size_t maxpacksize
Definition: rtpsession.h:559
int SetLocalTool(const void *s, std::size_t len)
Definition: rtpsession.cpp:974
virtual int JoinMulticastGroup(const RTPAddress &addr)=0
int SetLocalLocation(const void *s, std::size_t len)
Definition: rtpsession.cpp:954
RTPRandom * GetRandomNumberGenerator(RTPRandom *r)
virtual int LeaveMulticastGroup(const RTPAddress &addr)=0
void Timeout(const RTPTime &currenttime, const RTPTime &timeoutdelay)
RTCPScheduler rtcpsched
Definition: rtpsession.h:573
virtual int SetReceiveMode(RTPTransmitter::ReceiveMode m)=0
int SetLocalEMail(const void *s, std::size_t len)
Definition: rtpsession.cpp:944
virtual bool OnChangeIncomingData(RTPRawPacket *rawpack)
Definition: rtpsession.h:653
void SetLocationInterval(int count)
int SetDefaultTimestampIncrement(uint32_t timestampinc)
Definition: rtpsession.cpp:630
std::list< RTCPCompoundPacket * > byepackets
Definition: rtpsession.h:577
virtual int OnChangeRTPOrRTCPData(const void *origdata, std::size_t origlen, bool isrtp, void **senddata, std::size_t *sendlen)
Definition: rtpsession.h:646
int SetTimestampUnit(double u)
Definition: rtpsession.cpp:881
int SetLocalLocation(const void *s, std::size_t len)
void SetParameters(const RTCPSchedulerParams &params)
void SetPhoneInterval(int count)
Definition: rtpsession.cpp:913
int IncrementTimestampDefault()
Definition: rtpsession.cpp:652
static void Wait(const RTPTime &delay)
int SendRawData(const void *data, std::size_t len, bool usertpchannel)
Definition: rtpsession.cpp:594
double collisionmultiplier
Definition: rtpsession.h:565
const RTPAddress & GetSenderAddress() const
Definition: rtprawpacket.h:82
int SetPreTransmissionDelay(const RTPTime &delay)
Definition: rtpsession.cpp:663
uint32_t GetLocalSSRC()
Definition: rtpsession.cpp:404
static RTPRandom * CreateDefaultRandomNumberGenerator()
Definition: rtprandom.cpp:73
static RTPTime CurrentTime()
virtual bool SupportsMulticasting()=0
RTPTime GetMinimumRTCPTransmissionInterval() const
virtual void ClearIgnoreList()=0
virtual std::size_t GetHeaderOverhead()=0
void AnalyseOutgoing(RTCPCompoundPacket &rtcpcomppack)
virtual void OnSendRTCPCompoundPacket(RTCPCompoundPacket *pack)
Definition: rtpsession.h:642
double GetNoteTimeoutMultiplier() const
int Init(std::size_t maxpacksize, double timestampunit, const void *cname, std::size_t cnamelen)
virtual void ClearDestinations()=0
RTPSourceData * GetCurrentSourceInfo()
Definition: rtpsession.cpp:748
int SetPreTransmissionDelay(const RTPTime &delay)
virtual int AddToAcceptList(const RTPAddress &addr)=0
int BuildPacketEx(const void *data, unsigned int len, uint16_t hdrextID, const void *hdrextdata, unsigned int numhdrextwords)
double GetSenderControlBandwidthFraction() const
uint32_t GetPredefinedSSRC() const
virtual ~RTPSession()
Definition: rtpsession.cpp:78
uint8_t * GetLocalCNAME(std::size_t *len) const
RTPPacket * GetNextPacket()
Definition: rtpsources.cpp:630
bool GotoFirstSourceWithData()
Definition: rtpsession.cpp:727
int SetLocalName(const void *s, std::size_t len)
void DeleteTransmissionInfo(RTPTransmissionInfo *inf)
Definition: rtpsession.cpp:681
virtual int AddDestination(const RTPAddress &addr)=0
int SendPacket(const void *data, std::size_t len)
Definition: rtpsession.cpp:457
int SetDefaultMark(bool m)
Definition: rtpsession.cpp:619
int SetMaximumPacketSize(unsigned int maxpacksize)
void SetLocationInterval(int count)
Definition: rtpsession.cpp:906
virtual RTPTransmissionInfo * GetTransmissionInfo()=0
RTPTime CalculateDeterministicInterval(bool sender=false)
int AddSDESNormalItem(RTCPSDESPacket::ItemType t, const void *itemdata, uint8_t itemlength)