blob: 6f0beb1b3147a98258106ceb71bd2efe37d0f008 [file] [log] [blame]
Emeric Vigier2f625822012-08-06 11:09:52 -04001// rtphello
2// A very simple program for testing and illustrating basic features of ccRTP.
3// Copyright (C) 2001,2002 Federico Montesino <fedemp@altern.org>
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
20// This is an introductory example file that illustrates basic usage
21// of ccRTP. You will also see a bit on how to use other classes from
22// CommonC++.
23
24// I am a typical hello world program. I consist of a sender thread,
25// that sends the salutation message on RTP packets; and a receiver
26// thread, that prints the messages. This is a program with an unsual
27// structure, the receiver just tries to process the first available
28// packet periodically, and both are in the same program. Thus, it
29// should not be seen as an example for typical applications but as a
30// test of some functions of ccRTP.
31
32#include <cstdio>
33#include <ctime>
34// In order to use ccRTP, the RTP stack of CommonC++, just include...
35#include <ccrtp/rtp.h>
36
37#ifdef CCXX_NAMESPACES
38using namespace ost;
39using namespace std;
40#endif
41
42// base ports
43const int RECEIVER_BASE = 33634;
44const int TRANSMITTER_BASE = 32522;
45
46// For this example, this is irrelevant.
47//const int TIMESTAMP_RATE = 90000;
48
49/**
50 * @class ccRTP_Hello_Rx
51 * Receiver of salutes.
52 */
53class ccRTP_Hello_Rx: public Thread
54{
55
56private:
57 // socket to receive packets
58 RTPSession *socket;
59 // loopback network address
60 InetHostAddress local_ip;
61 // identifier of this sender
62 uint32 ssrc;
63
64public:
65 ccRTP_Hello_Rx(){
66 // Before using ccRTP you should learn something about other
67 // CommonC++ classes. We need InetHostAddress...
68
69 // Construct loopback address
70 local_ip = "127.0.0.1";
71
72 // Is that correct?
73 if( ! local_ip ){
74 // this is equivalent to `! local_ip.isInetAddress()'
75 cerr << "Rx: IP address is not correct!" << endl;
76 exit();
77 }
78
79 // create socket for RTP connection and get a random
80 // SSRC identifier
81 socket = new RTPSession(local_ip,RECEIVER_BASE);
82 ssrc = socket->getLocalSSRC();
83 }
84
85 ~ccRTP_Hello_Rx(){
86 cout << endl << "Destroying receiver -ID: " << hex
87 << (int)ssrc;
88 terminate();
89 delete socket;
90 cout << "... " << "destroyed.";
91 }
92
93 // This method does almost everything.
94 void run(void){
95
96 cout << "Hello, " << defaultApplication().
97 getSDESItem(SDESItemTypeCNAME)
98 << " ..." << endl;
99 // redefined from Thread.
100 // Set up connection
101 socket->setSchedulingTimeout(20000);
102 socket->setExpireTimeout(3000000);
103 //socket->UDPTransmit::setTypeOfService(SOCKET_IPTOS_LOWDELAY);
104 if( !socket->addDestination(local_ip,TRANSMITTER_BASE) )
105 cerr << "Rx (" << hex << (int)ssrc
106 << "): could not connect to port."
107 << TRANSMITTER_BASE;
108
109 cout << "Rx (" << hex << (int)ssrc
110 << "): " << local_ip.getHostname()
111 << " is waiting for salutes in port "
112 << RECEIVER_BASE << "..." << endl;
113
114 socket->setPayloadFormat(StaticPayloadFormat(sptMP2T));
115 socket->startRunning();
116 // Let's check the queues (you should read the documentation
117 // so that you know what the queues are for).
118 cout << "Rx (" << hex << (int)ssrc
119 << "): The queue is "
120 << ( socket->isActive() ? "" : "in")
121 << "active." << endl;
122
123 // This is the main loop, where packets are received.
124 for( int i = 0 ; true ; i++ ){
125
126 // Wait for an RTP packet.
127 const AppDataUnit *adu = NULL;
128 while ( NULL == adu ) {
129 Thread::sleep(10);
130 adu = socket->getData(socket->getFirstTimestamp());
131 }
132
133 // Print content (likely a salute :))
134 // Note we are sure the data is an asciiz string.
135 time_t receiving_time = time(NULL);
136 char tmstring[30];
137 strftime(tmstring,30,"%X",localtime(&receiving_time));
138 cout << "Rx (" << hex << (int)ssrc
139 << "): [receiving at " << tmstring << "]: "
140 << adu->getData() << endl;
141 delete adu;
142 }
143 }
144};
145
146/**
147 * @class ccRTP_Hello_Tx
148 * Transmitter of salutes.
149 */
150class ccRTP_Hello_Tx: public Thread, public TimerPort
151{
152
153private:
154 // socket to transmit
155 RTPSession *socket;
156 // loopback network address
157 InetHostAddress local_ip;
158 // identifier of this sender
159 uint32 ssrc;
160
161public:
162 ccRTP_Hello_Tx(){
163 // Before using ccRTP you should learn something about other
164 // CommonC++ classes. We need InetHostAddress...
165
166 // Construct loopback address
167 local_ip = "127.0.0.1";
168
169 // Is that correct?
170 if( ! local_ip ){
171 // this is equivalent to `! local_ip.isInetAddress()'
172 cerr << "Tx: IP address is not correct!" << endl;
173 exit();
174 }
175
176 socket = new RTPSession(local_ip,TRANSMITTER_BASE);
177 ssrc = socket->getLocalSSRC();
178 }
179
180 ~ccRTP_Hello_Tx(){
181 cout << endl << "Destroying transmitter -ID: " << hex
182 << (int)ssrc;
183 terminate();
184 delete socket;
185 cout << "... " << "destroyed.";
186 }
187
188 // This method does almost everything.
189 void run(void){
190 // redefined from Thread.
191 cout << "Tx (" << hex << (int)ssrc << "): " <<
192 local_ip.getHostname()
193 << " is going to salute perself through "
194 << local_ip << "..." << endl;
195
196 // Set up connection
197 socket->setSchedulingTimeout(20000);
198 socket->setExpireTimeout(3000000);
199 if( !socket->addDestination(local_ip,RECEIVER_BASE) )
200 cerr << "Tx (" << hex << (int)ssrc
201 << "): could not connect to port."
202 << RECEIVER_BASE;
203
204 cout << "Tx (" << hex << (int)ssrc <<
205 "): Transmitting salutes to port "
206 << RECEIVER_BASE << "..." << endl;
207
208 uint32 timestamp = 0;
209 // This will be useful for periodic execution
210 TimerPort::setTimer(1000);
211
212 // This is the main loop, where packets are sent.
213 socket->setPayloadFormat(StaticPayloadFormat(sptMP2T));
214 socket->startRunning();
215 // Let's check the queues (you should read the documentation
216 // so that you know what the queues are for).
217 cout << "Tx (" << hex << (int)ssrc << "): The queue is "
218 << ( socket->isActive()? "" : "in")
219 << "active." << endl;
220
221 for( int i = 0 ; true ;i++ ){
222
223 // send RTP packets, providing timestamp,
224 // payload type and payload.
225 // construct salute.
226 unsigned char salute[50];
227 snprintf((char *)salute,50,
228 "Hello, brave gnu world (#%u)!",i);
229 time_t sending_time = time(NULL);
230 // get timestamp to send salute
231 if ( 0 == i ){
232 timestamp = socket->getCurrentTimestamp();
233
234 } else {
235 // increment for 1 second
236 timestamp += socket->getCurrentRTPClockRate();
237 }
238
239 socket->putData(timestamp,salute,
240 strlen((char *)salute)+1);
241 // print info
242 char tmstring[30];
243 strftime(tmstring,30,"%X",
244 localtime(&sending_time));
245 cout << "Tx (" << hex << (int)ssrc
246 << "): sending salute " << "no " << dec << i
247 << ", at " << tmstring
248 << "..." << endl;
249
250 // Let's wait for the next cycle
251 Thread::sleep(TimerPort::getTimer());
252 TimerPort::incTimer(1000);
253 }
254 }
255};
256
257int main(int argc, char *argv[])
258{
259
260 // Construct the two main threads. they will not run yet.
261 ccRTP_Hello_Rx *receiver = new ccRTP_Hello_Rx;
262 ccRTP_Hello_Tx *transmitter = new ccRTP_Hello_Tx;
263
264 cout << "This is rtphello, a very simple test program for ccRTP." <<
265 endl << "Strike [Enter] when you are fed up with it." << endl;
266
267 // Start execution of hello now.
268 receiver->start();
269 transmitter->start();
270
271 cin.get();
272
273 delete transmitter;
274 delete receiver;
275
276 cout << endl << "That's all." << endl;
277
278 return 0;
279}
280
281/** EMACS **
282 * Local variables:
283 * mode: c++
284 * c-basic-offset: 8
285 * End:
286 */