1 #include "rtpconfig.h"
2
3 // Let's assume that non-winsock platforms have SIGALRM and EINTR
4 #if !defined(RTP_SOCKETTYPE_WINSOCK) && defined(RTP_SUPPORT_THREAD)
5
6 #include "rtpsession.h"
7 #include "rtpudpv4transmitter.h"
8 #include "rtpipv4address.h"
9 #include "rtpsessionparams.h"
10 #include "rtperrors.h"
11 #include "rtplibraryversion.h"
12 #include "rtpsourcedata.h"
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <iostream>
16 #include <string>
17 #include <jthread/jthread.h>
18
19 #include <signal.h>
20 #include <unistd.h>
21
22 using namespace jrtplib;
23 using namespace jthread;
24 using namespace std;
25
checkerror(int rtperr)26 void checkerror(int rtperr)
27 {
28 if (rtperr < 0)
29 {
30 cout << "ERROR: " << RTPGetErrorString(rtperr) << endl;
31 exit(-1);
32 }
33 }
34
35 class MyRTPSession : public RTPSession
36 {
37 protected:
OnValidatedRTPPacket(RTPSourceData * srcdat,RTPPacket * rtppack,bool isonprobation,bool * ispackethandled)38 void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled)
39 {
40 printf("Got packet in OnValidatedRTPPacket from source 0x%04x!\n", srcdat->GetSSRC());
41 DeletePacket(rtppack);
42 *ispackethandled = true;
43 }
44
OnRTCPSDESItem(RTPSourceData * srcdat,RTCPSDESPacket::ItemType t,const void * itemdata,size_t itemlength)45 void OnRTCPSDESItem(RTPSourceData *srcdat, RTCPSDESPacket::ItemType t, const void *itemdata, size_t itemlength)
46 {
47 char msg[1024];
48
49 memset(msg, 0, sizeof(msg));
50 if (itemlength >= sizeof(msg))
51 itemlength = sizeof(msg)-1;
52
53 memcpy(msg, itemdata, itemlength);
54 printf("SSRC %x: Received SDES item (%d): %s", (unsigned int)srcdat->GetSSRC(), (int)t, msg);
55 }
56 };
57
58 class MyThread : public JThread
59 {
60 public:
MyThread()61 MyThread()
62 {
63 if (m_mutex.Init() < 0)
64 {
65 cerr << "Can't init mutex" << endl;
66 exit(-1);
67 }
68 m_stop = false;
69 }
70
~MyThread()71 ~MyThread()
72 {
73 m_mutex.Lock();
74 m_stop = true;
75 m_mutex.Unlock();
76
77 while (IsRunning())
78 RTPTime::Wait(RTPTime(0, 10000));
79 }
80
Thread()81 void *Thread()
82 {
83 ThreadStarted();
84
85 bool done = false;
86 pid_t pid = getpid();
87
88 while (!done)
89 {
90 kill(pid, SIGALRM);
91
92 RTPTime::Wait(RTPTime(0, 500000));
93
94 m_mutex.Lock();
95 done = m_stop;
96 m_mutex.Unlock();
97 }
98
99 return 0;
100 }
101
102 private:
103 JMutex m_mutex;
104 bool m_stop;
105 };
106
handler(int sig)107 void handler(int sig)
108 {
109 cerr << "Signal " << sig << endl;
110 }
111
main(void)112 int main(void)
113 {
114 if (signal(SIGALRM, handler) == SIG_ERR)
115 {
116 cerr << "Unable to install signal handler" << endl;
117 return -1;
118 }
119
120 MyThread t;
121
122 if (t.Start() < 0)
123 {
124 cerr << "Unable to start thread that sends signals" << endl;
125 return -1;
126 }
127
128 cerr << "Waiting one second to verify that handler is called and program doesn't exit yet" << endl;
129 RTPTime::Wait(RTPTime(1,0));
130
131 MyRTPSession sess;
132 uint16_t portbase = 5000, destport = 5000;
133 uint32_t destip;
134 string ipstr = "127.0.0.1";
135 int status,i,num;
136
137 destip = inet_addr(ipstr.c_str());
138 if (destip == INADDR_NONE)
139 {
140 cerr << "Bad IP address specified" << endl;
141 return -1;
142 }
143 destip = ntohl(destip);
144
145 num = 20;
146
147 // Now, we'll create a RTP session, set the destination, send some
148 // packets and poll for incoming data.
149
150 RTPUDPv4TransmissionParams transparams;
151 RTPSessionParams sessparams;
152
153 sessparams.SetOwnTimestampUnit(1.0/10.0);
154 sessparams.SetAcceptOwnPackets(true);
155 sessparams.SetUsePollThread(false);
156 transparams.SetPortbase(portbase);
157
158 status = sess.Create(sessparams,&transparams);
159 checkerror(status);
160
161 RTPIPv4Address addr(destip,destport);
162
163 status = sess.AddDestination(addr);
164 checkerror(status);
165
166 for (i = 1 ; i <= num ; i++)
167 {
168 printf("\nSending packet %d/%d\n",i,num);
169
170 // send the packet
171 status = sess.SendPacket((void *)"1234567890",10,0,false,10);
172 checkerror(status);
173
174 // Either the background thread or the poll function itself will
175 // cause the OnValidatedRTPPacket and OnRTCPSDESItem functions to
176 // be called, so in this loop there's not much left to do.
177
178 status = sess.Poll();
179 checkerror(status);
180
181 RTPTime startTime = RTPTime::CurrentTime();
182 RTPTime diff(0,0);
183 do
184 {
185 status = sess.WaitForIncomingData(RTPTime(0,100));
186 checkerror(status);
187
188 diff = RTPTime::CurrentTime();
189 diff -= startTime;
190 } while (diff.GetDouble() < 1.0); // Make sure we wait a second
191 }
192
193 return 0;
194 }
195
196 #else
197 #include <iostream>
198
199 using namespace std;
200
main(void)201 int main(void)
202 {
203 cerr << "Need JThread support and a unix-like platform for this test" << endl;
204 return 0;
205 }
206
207 #endif
208
209