1 #include "rtpsession.h"
2 #include "rtpipv4address.h"
3 #include "rtpsessionparams.h"
4 #include "rtpudpv4transmitter.h"
5 #include "rtperrors.h"
6 #include "rtcpcompoundpacket.h"
7 #include "rtcpsrpacket.h"
8 #include "rtcprrpacket.h"
9 #include "rtcpbyepacket.h"
10 #include "rtprawpacket.h"
11 #include <stdio.h>
12 #include <iostream>
13 
14 using namespace jrtplib;
15 
checkError(int status)16 void checkError(int status)
17 {
18 	if (status >= 0)
19 		return;
20 
21 	std::cerr << "An error occured in the RTP component: " << std::endl;
22 	std::cerr << "Error description: " << RTPGetErrorString(status) << std::endl;
23 
24 	exit(-1);
25 }
26 
27 class MyRTPSession : public RTPSession
28 {
29 private:
30 	FILE *pLogFile;
31 public:
MyRTPSession()32 	MyRTPSession()
33 	{
34 		SetChangeIncomingData(true);
35 
36 		pLogFile = fopen("logfile.dat", "wb");
37 	}
38 
~MyRTPSession()39 	~MyRTPSession()
40 	{
41 		if (pLogFile)
42 			fclose(pLogFile);
43 	}
44 protected:
OnValidatedRTPPacket(RTPSourceData * srcdat,RTPPacket * rtppack,bool isonprobation,bool * ispackethandled)45 	void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled)
46 	{
47 		// Make sure no RTP packets are stored internally, we'd just be wasting memory
48 		DeletePacket(rtppack);
49 		*ispackethandled = true;
50 	}
51 
OnChangeIncomingData(RTPRawPacket * pPack)52 	bool OnChangeIncomingData(RTPRawPacket *pPack)
53 	{
54 		if (pLogFile)
55 		{
56 			double t = pPack->GetReceiveTime().GetDouble();
57 			bool isRTP = pPack->IsRTP();
58 			uint32_t dataLength = (uint32_t)pPack->GetDataLength();
59 
60 			if (isRTP)
61 				fwrite("RTP ", 1, 4, pLogFile);
62 			else
63 				fwrite("RTCP", 1, 4, pLogFile);
64 
65 			fwrite(&t, 1, sizeof(double), pLogFile);
66 			fwrite(&dataLength, 1, sizeof(uint32_t),pLogFile);
67 			fwrite(pPack->GetData(), 1, dataLength, pLogFile);
68 		}
69 		return true;
70 	}
71 
OnRTCPCompoundPacket(RTCPCompoundPacket * p,const RTPTime & receivetime,const RTPAddress * senderaddress)72 	void OnRTCPCompoundPacket(RTCPCompoundPacket *p, const RTPTime &receivetime, const RTPAddress *senderaddress)
73 	{
74 		printf("%u.%06u RECEIVED\n",receivetime.GetSeconds(),receivetime.GetMicroSeconds());
75 
76 		DumpCompoundPacket(stdout,p);
77 	}
78 
OnSendRTCPCompoundPacket(RTCPCompoundPacket * p)79 	void OnSendRTCPCompoundPacket(RTCPCompoundPacket *p)
80 	{
81 		RTPTime t = RTPTime::CurrentTime();
82 
83 		printf("%u.%06u SENDING\n",t.GetSeconds(),t.GetMicroSeconds());
84 
85 		DumpCompoundPacket(stdout,p);
86 	}
87 
DumpCompoundPacket(FILE * f,RTCPCompoundPacket * p)88 	void DumpCompoundPacket(FILE *f, RTCPCompoundPacket *p)
89 	{
90 		RTCPPacket *pack;
91 
92 		p->GotoFirstPacket();
93 		while ((pack = p->GetNextPacket()) != 0)
94 		{
95 			if (pack->GetPacketType() == RTCPPacket::SR)
96 			{
97 				RTCPSRPacket *p = (RTCPSRPacket *)pack;
98 
99 				RTPTime t(p->GetNTPTimestamp());
100 
101 				fprintf(f,"  SR packet\n    SSRC %27u\n",p->GetSenderSSRC());
102 				fprintf(f,"    NTP timestamp: %10u.%06u\n    RTP timestamp: %17u\n    Packets sent: %18u\n    Octets sent: %19u\n",t.GetSeconds(),t.GetMicroSeconds(),p->GetRTPTimestamp(),p->GetSenderPacketCount(),p->GetSenderOctetCount());
103 
104 				for (int i = 0 ; i < p->GetReceptionReportCount() ; i++)
105 					fprintf(f,"    RR block %d\n      SSRC %25u\n      Fraction lost: %15d\n      Packets lost: %16d\n      Ext. high. seq. nr: %10u\n      Jitter: %22u\n      LSR: %25u\n      DLSR: %24u\n",(i+1),
106 							p->GetSSRC(i),(int)p->GetFractionLost(i),p->GetLostPacketCount(i),p->GetExtendedHighestSequenceNumber(i),p->GetJitter(i),p->GetLSR(i),
107 							p->GetDLSR(i));
108 			}
109 			else if (pack->GetPacketType() == RTCPPacket::RR)
110 			{
111 				RTCPRRPacket *p = (RTCPRRPacket *)pack;
112 
113 				fprintf(f,"  RR packet\n    SSRC %27u\n",p->GetSenderSSRC());
114 
115 				for (int i = 0 ; i < p->GetReceptionReportCount() ; i++)
116 					fprintf(f,"    RR block %d\n      SSRC %25u\n      Fraction lost: %15d\n      Packets lost: %16d\n      Ext. high. seq. nr: %10u\n      Jitter: %22u\n      LSR: %25u\n      DLSR: %24u\n",(i+1),
117 							p->GetSSRC(i),(int)p->GetFractionLost(i),p->GetLostPacketCount(i),p->GetExtendedHighestSequenceNumber(i),p->GetJitter(i),p->GetLSR(i),
118 							p->GetDLSR(i));
119 			}
120 			else if (pack->GetPacketType() == RTCPPacket::SDES)
121 			{
122 				RTCPSDESPacket *p = (RTCPSDESPacket *)pack;
123 				char str[1024];
124 
125 				if (!p->GotoFirstChunk())
126 					return;
127 
128 				do
129 				{
130 					fprintf(f,"  SDES Chunk:\n");
131 					fprintf(f,"    SSRC: %26u\n",p->GetChunkSSRC());
132 					if (p->GotoFirstItem())
133 					{
134 						do
135 						{
136 							switch (p->GetItemType())
137 							{
138 							case RTCPSDESPacket::None:
139 								strcpy(str,"None    ");
140 								break;
141 							case RTCPSDESPacket::CNAME:
142 								strcpy(str,"CNAME:  ");
143 								break;
144 							case RTCPSDESPacket::NAME:
145 								strcpy(str,"NAME:   ");
146 								break;
147 							case RTCPSDESPacket::EMAIL:
148 								strcpy(str,"EMAIL:  ");
149 								break;
150 							case RTCPSDESPacket::PHONE:
151 								strcpy(str,"PHONE:  ");
152 								break;
153 							case RTCPSDESPacket::LOC:
154 								strcpy(str,"LOC:    ");
155 								break;
156 							case RTCPSDESPacket::TOOL:
157 								strcpy(str,"TOOL:   ");
158 								break;
159 							case RTCPSDESPacket::NOTE:
160 								strcpy(str,"NOTE:   ");
161 								break;
162 							case RTCPSDESPacket::PRIV:
163 								strcpy(str,"PRIV:   ");
164 								break;
165 							case RTCPSDESPacket::Unknown:
166 							default:
167 								strcpy(str,"Unknown ");
168 							}
169 							fprintf(f,"    %s",str);
170 
171 							if (p->GetItemType() != RTCPSDESPacket::PRIV)
172 							{
173 								char str[1024];
174 								memcpy(str,p->GetItemData(),p->GetItemLength());
175 								str[p->GetItemLength()] = 0;
176 								fprintf(f,"%24s\n",str);
177 							}
178 						} while (p->GotoNextItem());
179 					}
180 				} while (p->GotoNextChunk());
181 			}
182 			else if (pack->GetPacketType() == RTCPPacket::BYE)
183 			{
184 				fprintf(f,"  BYE packet:\n");
185 
186 				RTCPBYEPacket *p = (RTCPBYEPacket *)pack;
187 
188 				int num = p->GetSSRCCount();
189 				int i;
190 
191 				for (i = 0 ; i < num ; i++)
192 					fprintf(f,"    SSRC: %26u\n",p->GetSSRC(i));
193 				if (p->HasReasonForLeaving())
194 				{
195 					char str[1024];
196 					memcpy(str,p->GetReasonData(),p->GetReasonLength());
197 					str[p->GetReasonLength()] = 0;
198 					fprintf(f,"    Reason: %24s\n",str);
199 				}
200 			}
201 		}
202 		fprintf(f,"\n");
203 	}
204 };
205 
main(int argc,char * argv[])206 int main(int argc, char *argv[])
207 {
208 	if (argc != 4)
209 	{
210 		fprintf(stderr, "Usage: rtcpdump portbase destIP destport\n");
211 		return -1;
212 	}
213 
214 	int portBase = atoi(argv[1]);
215 	int destPort = atoi(argv[3]);
216 	std::string destIP(argv[2]);
217 
218 	RTPIPv4Address dest;
219 	RTPUDPv4TransmissionParams transParams;
220 	RTPSessionParams sessParams;
221 	MyRTPSession session;
222 
223 	dest.SetIP(ntohl(inet_addr(destIP.c_str())));
224 	dest.SetPort((uint16_t)destPort);
225 
226 	transParams.SetPortbase((uint16_t)portBase);
227 	transParams.SetRTPReceiveBuffer(1024*1024);
228 	transParams.SetRTCPReceiveBuffer(1024*1024);
229 	sessParams.SetOwnTimestampUnit(1.0/5.0);
230 	sessParams.SetProbationType(RTPSources::NoProbation);
231 
232 	int status;
233 
234 	status = session.Create(sessParams, &transParams);
235 	checkError(status);
236 
237 	status = session.AddDestination(dest);
238 	checkError(status);
239 
240 	int i = 0;
241 
242 	getchar();
243 
244 	return 0;
245 }
246