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