ccRTP 2.1.2
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rtpduphello.cpp
Go to the documentation of this file.
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 ...
33 #include <ccrtp/ext.h>
34 
35 #ifdef CCXX_NAMESPACES
36 using namespace ost;
37 using namespace std;
38 #endif
39 
44 class ccRTP_dupHello: public Thread
45 {
46 private:
47  // There will be two duplex connections. They both will send
48  // and receive packets.
49  RTPDuplex *duplexA, *duplexB;
50 
51 public:
52  // Destructor.
54  {
55  terminate();
56  delete duplexA;
57  delete duplexB;
58  }
59 
60  // Constructor.
61  ccRTP_dupHello() : duplexA(NULL), duplexB(NULL)
62  {}
63 
64  // This method does almost everything.
65  void run(void)
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);
159  const AppDataUnit* aduA =
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 << "]: " <<
165  aduA->getData() << endl;
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);
181  const AppDataUnit* aduB =
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 << "]: " <<
187  aduB->getData() << endl;
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.
199  ccRTP_dupHello *hello = new ccRTP_dupHello;
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 
void run(void)
Definition: rtpduphello.cpp:65
ccRTP Stack extensions.
int main(int argc, char *argv[])
Interface (envelope) to data received over RTP packets.
Definition: queuebase.h:68
RTPDuplex * duplexB
Definition: rtpduphello.cpp:49
A peer associated RTP socket pair for physically connected peer hosts.
Definition: ext.h:72
Static payload format objects.
Definition: formats.h:200
const uint8 *const getData() const
Get data as it is received in RTP packets (i.e.
Definition: queuebase.h:105
MPEG 2 Transport stream (RFCs 1890, 2250)
Definition: formats.h:108
This is the class that will do almost everything.
Definition: rtpduphello.cpp:44