1 // rtpduphello.
2 // A very simple program for testing and illustrating basic features of ccRTP.
3 // Copyright (C) 2001-2015 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 CommonC++ threads.
22
23 // It is a typical hello world program. It consists of tow duplex
24 // connections that talk each other through RTP packets. They do not
25 // say more than a typical salutation message. They both send and
26 // receive messages, and print the messages they receive.
27
28
29 #include <cstdio>
30 #include <cstdlib>
31 // In order to use ccRTP, the RTP stack of CommonC++, you only need to
32 // include ...
34
35 #ifdef CCXX_NAMESPACES
36 using namespace ost;
37 using namespace std;
38 #endif
39
45 {
46 private:
47 // There will be two duplex connections. They both will send
48 // and receive packets.
50
51 public:
52 // Destructor.
54 {
55 terminate();
56 delete duplexA;
57 delete duplexB;
58 }
59
60 // Constructor.
62 {}
63
64 // This method does almost everything.
66 {
67 // redefined from Thread.
68
69 // Before using ccRTP you should learn something about other
70 // CommonC++ classes. We need InetHostAddress...
71
72 // Construct loopback address
73 InetHostAddress local_ip;
74 local_ip = "127.0.0.1";
75
76 // Is that correct?
77 if( ! local_ip ) {
78 // this is equivalent to `! local_ip.isInetAddress()'
79 cerr << ": IP address is not correct!" << endl;
80 exit();
81 }
82
83 cout << local_ip.getHostname() <<
84 " is going to talk to perself through " <<
85 local_ip << "..." << endl;
86
87 // ____Here comes the real RTP stuff____
88
89 // Construct two RTPSocket. 22222 will be the base
90 // port of A. 33334 will be the base port of B.
91 const int A_BASE = 22222;
92 const int B_BASE = 33334;
93
94 duplexA =
new RTPDuplex(local_ip,A_BASE,B_BASE);
95
96 duplexB =
new RTPDuplex(local_ip,B_BASE,A_BASE);
97
98 // Set up A's connection
99 duplexA->setSchedulingTimeout(90000);
100 duplexA->setExpireTimeout(2500000);
101 if( duplexA->connect(local_ip,B_BASE) < 0 )
102 cerr << "Duplex A could not connect.";
103
104 // Set up B's connection
105 duplexB->setSchedulingTimeout(160000);
106 duplexB->setExpireTimeout(3500000);
107 if( duplexB->connect(local_ip,A_BASE) < 0 )
108 cerr << "Duplex B could not connect.";
109
110 // Let's check the queues (you should read the documentation
111 // so that you know what the queues are for).
112
113 if( duplexA->RTPDataQueue::isActive() )
114 cout << "The queue A is active." << endl;
115 else
116 cerr << "The queue A is not active." << endl;
117
118 if( duplexB->RTPDataQueue::isActive() )
119 cout << "The queue B is active." << endl;
120 else
121 cerr << "The queue B is not active." << endl;
122
123
124 cout << "Transmitting..." << endl;
125
126 // This message will be sent on RTP packets, from A to
127 // B and from B to A.
128 unsigned char helloA[] = "Hello, brave gnu world from A!";
129 unsigned char helloB[] = "Hello, brave gnu world from B!";
130
131 // This is not important
132 time_t sending_time;
133 time_t receiving_time;
134 char tmstring[30];
135
137 duplexA->setPayloadFormat(pf);
138 duplexB->setPayloadFormat(pf);
139
140 // This is the main loop, where packets are sent and receipt.
141 // A and B both will send and receive packets.
142 for( int i = 0 ; true ; i++ ) {
143
144 // A and B do almost exactly the same things,
145 // I have kept this here -out of a send/receive
146 // method- in the interest of clarity.
147
148 // A: Send an RTP packet
149 sending_time = time(NULL);
150 duplexA->putData(2*(i)*90000,helloA,
151 strlen((char *)helloA));
152 // Tell it
153 strftime(tmstring,30,"%X",localtime(&sending_time));
154 cout << "A: sending message at " << tmstring << "..."
155 << endl;
156
157 // A: Receive an RTP packet
158 receiving_time = time(NULL);
160 duplexA->
getData(duplexA->getFirstTimestamp());
161 if ( aduA ) {
162 // Tell it
163 strftime(tmstring,30,"%X",localtime(&receiving_time));
164 cout << "A:[receiving at " << tmstring << "]: " <<
166 }
167 // Wait for 0.1 seconds
168 Thread::sleep(100);
169
170 // B: Send an RTP packet
171 sending_time = time(NULL);
172 duplexB->putData(2*(i)*90000,helloB,
173 strlen((char *)helloB));
174 // Tell it
175 strftime(tmstring,30,"%X",localtime(&sending_time));
176 cout << "B: sending message at " << tmstring << "..."
177 << endl;
178
179 // B: Receive an RTP packet
180 receiving_time = time(NULL);
182 duplexB->
getData(duplexB->getFirstTimestamp());
183 if ( aduB ) {
184 // Tell it
185 strftime(tmstring,30,"%X",localtime(&receiving_time));
186 cout << "B:[receiving at " << tmstring << "]: " <<
188 }
189
190 Thread::sleep(1900);
191 }
192
193 }
194 };
195
196 int main(
int argc,
char *argv[])
197 {
198 // Construct the main thread. It will not run yet.
200
201 cout << "This is rtpduphello, a very simple test program for ccRTP."
202 << endl << "Strike [Enter] when you are fed up." << endl;
203
204 // Start execution of hello.
205 hello->start();
206
207 cin.get();
208
209 cout << endl << "That's all" << endl;
210
211 delete hello;
212
213 exit(0);
214 }
215
int main(int argc, char *argv[])
Interface (envelope) to data received over RTP packets.
A peer associated RTP socket pair for physically connected peer hosts.
const uint8 *const getData() const
Get data as it is received in RTP packets (i.e.
MPEG 2 Transport stream (RFCs 1890, 2250)
This is the class that will do almost everything.