Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: webrtc/libjingle/examples/call/call_main.cc

Issue 1175243003: Remove webrtc/libjingle/{examples,session}. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * libjingle
3 * Copyright 2004--2005, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <time.h>
31
32 #include <iomanip>
33 #include <iostream>
34 #include <vector>
35
36 #include "webrtc/base/flags.h"
37 #include "webrtc/base/logging.h"
38 #ifdef OSX
39 #include "webrtc/base/maccocoasocketserver.h"
40 #endif
41 #include "talk/examples/call/callclient.h"
42 #include "talk/examples/call/console.h"
43 #include "talk/examples/call/mediaenginefactory.h"
44 #include "talk/session/media/srtpfilter.h"
45 #include "webrtc/base/pathutils.h"
46 #include "webrtc/base/ssladapter.h"
47 #include "webrtc/base/stream.h"
48 #include "webrtc/base/win32socketserver.h"
49 #include "webrtc/libjingle/session/media/mediasessionclient.h"
50 #include "webrtc/libjingle/xmpp/xmppauth.h"
51 #include "webrtc/libjingle/xmpp/xmppclientsettings.h"
52 #include "webrtc/libjingle/xmpp/xmpppump.h"
53 #include "webrtc/libjingle/xmpp/xmppsocket.h"
54 #include "webrtc/p2p/base/constants.h"
55
56 class DebugLog : public sigslot::has_slots<> {
57 public:
58 DebugLog() :
59 debug_input_buf_(NULL), debug_input_len_(0), debug_input_alloc_(0),
60 debug_output_buf_(NULL), debug_output_len_(0), debug_output_alloc_(0),
61 censor_password_(false)
62 {}
63 char * debug_input_buf_;
64 int debug_input_len_;
65 int debug_input_alloc_;
66 char * debug_output_buf_;
67 int debug_output_len_;
68 int debug_output_alloc_;
69 bool censor_password_;
70
71 void Input(const char * data, int len) {
72 if (debug_input_len_ + len > debug_input_alloc_) {
73 char * old_buf = debug_input_buf_;
74 debug_input_alloc_ = 4096;
75 while (debug_input_alloc_ < debug_input_len_ + len) {
76 debug_input_alloc_ *= 2;
77 }
78 debug_input_buf_ = new char[debug_input_alloc_];
79 memcpy(debug_input_buf_, old_buf, debug_input_len_);
80 delete[] old_buf;
81 }
82 memcpy(debug_input_buf_ + debug_input_len_, data, len);
83 debug_input_len_ += len;
84 DebugPrint(debug_input_buf_, &debug_input_len_, false);
85 }
86
87 void Output(const char * data, int len) {
88 if (debug_output_len_ + len > debug_output_alloc_) {
89 char * old_buf = debug_output_buf_;
90 debug_output_alloc_ = 4096;
91 while (debug_output_alloc_ < debug_output_len_ + len) {
92 debug_output_alloc_ *= 2;
93 }
94 debug_output_buf_ = new char[debug_output_alloc_];
95 memcpy(debug_output_buf_, old_buf, debug_output_len_);
96 delete[] old_buf;
97 }
98 memcpy(debug_output_buf_ + debug_output_len_, data, len);
99 debug_output_len_ += len;
100 DebugPrint(debug_output_buf_, &debug_output_len_, true);
101 }
102
103 static bool IsAuthTag(const char * str, size_t len) {
104 if (str[0] == '<' && str[1] == 'a' &&
105 str[2] == 'u' &&
106 str[3] == 't' &&
107 str[4] == 'h' &&
108 str[5] <= ' ') {
109 std::string tag(str, len);
110
111 if (tag.find("mechanism") != std::string::npos)
112 return true;
113 }
114 return false;
115 }
116
117 void DebugPrint(char * buf, int * plen, bool output) {
118 int len = *plen;
119 if (len > 0) {
120 time_t tim = time(NULL);
121 struct tm * now = localtime(&tim);
122 char *time_string = asctime(now);
123 if (time_string) {
124 size_t time_len = strlen(time_string);
125 if (time_len > 0) {
126 time_string[time_len-1] = 0; // trim off terminating \n
127 }
128 }
129 LOG(INFO) << (output ? "SEND >>>>>>>>>>>>>>>>" : "RECV <<<<<<<<<<<<<<<<")
130 << " : " << time_string;
131
132 bool indent;
133 int start = 0, nest = 3;
134 for (int i = 0; i < len; i += 1) {
135 if (buf[i] == '>') {
136 if ((i > 0) && (buf[i-1] == '/')) {
137 indent = false;
138 } else if ((start + 1 < len) && (buf[start + 1] == '/')) {
139 indent = false;
140 nest -= 2;
141 } else {
142 indent = true;
143 }
144
145 // Output a tag
146 LOG(INFO) << std::setw(nest) << " "
147 << std::string(buf + start, i + 1 - start);
148
149 if (indent)
150 nest += 2;
151
152 // Note if it's a PLAIN auth tag
153 if (IsAuthTag(buf + start, i + 1 - start)) {
154 censor_password_ = true;
155 }
156
157 // incr
158 start = i + 1;
159 }
160
161 if (buf[i] == '<' && start < i) {
162 if (censor_password_) {
163 LOG(INFO) << std::setw(nest) << " " << "## TEXT REMOVED ##";
164 censor_password_ = false;
165 } else {
166 LOG(INFO) << std::setw(nest) << " "
167 << std::string(buf + start, i - start);
168 }
169 start = i;
170 }
171 }
172 len = len - start;
173 memcpy(buf, buf + start, len);
174 *plen = len;
175 }
176 }
177 };
178
179 static DebugLog debug_log_;
180 static const int DEFAULT_PORT = 5222;
181
182 #ifdef ANDROID
183 static std::vector<cricket::AudioCodec> codecs;
184 static const cricket::AudioCodec ISAC(103, "ISAC", 40000, 16000, 1, 0);
185
186 cricket::MediaEngineInterface *CreateAndroidMediaEngine() {
187 cricket::FakeMediaEngine *engine = new cricket::FakeMediaEngine();
188
189 codecs.push_back(ISAC);
190 engine->SetAudioCodecs(codecs);
191 return engine;
192 }
193 #endif
194
195 // TODO: Move this into Console.
196 void Print(const char* chars) {
197 printf("%s", chars);
198 fflush(stdout);
199 }
200
201 bool GetSecurePolicy(const std::string& in, cricket::SecurePolicy* out) {
202 if (in == "disable") {
203 *out = cricket::SEC_DISABLED;
204 } else if (in == "enable") {
205 *out = cricket::SEC_ENABLED;
206 } else if (in == "require") {
207 *out = cricket::SEC_REQUIRED;
208 } else {
209 return false;
210 }
211 return true;
212 }
213
214 int main(int argc, char **argv) {
215 // This app has three threads. The main thread will run the XMPP client,
216 // which will print to the screen in its own thread. A second thread
217 // will get input from the console, parse it, and pass the appropriate
218 // message back to the XMPP client's thread. A third thread is used
219 // by MediaSessionClient as its worker thread.
220
221 // define options
222 DEFINE_string(s, "talk.google.com", "The connection server to use.");
223 DEFINE_string(tls, "require",
224 "Select connection encryption: disable, enable, require.");
225 DEFINE_bool(allowplain, false, "Allow plain authentication.");
226 DEFINE_bool(testserver, false, "Use test server.");
227 DEFINE_string(oauth, "", "OAuth2 access token.");
228 DEFINE_bool(a, false, "Turn on auto accept for incoming calls.");
229 DEFINE_string(signaling, "hybrid",
230 "Initial signaling protocol to use: jingle, gingle, or hybrid.");
231 DEFINE_string(transport, "hybrid",
232 "Initial transport protocol to use: ice, gice, or hybrid.");
233 DEFINE_string(sdes, "enable",
234 "Select SDES media encryption: disable, enable, require.");
235 DEFINE_string(dtls, "disable",
236 "Select DTLS transport encryption: disable, enable, require.");
237 DEFINE_int(portallocator, 0, "Filter out unwanted connection types.");
238 DEFINE_string(pmuc, "groupchat.google.com", "The persistant muc domain.");
239 DEFINE_string(capsnode, "http://code.google.com/p/libjingle/call",
240 "Caps node: A URI identifying the app.");
241 DEFINE_string(capsver, "0.6",
242 "Caps ver: A string identifying the version of the app.");
243 DEFINE_string(voiceinput, NULL, "RTP dump file for voice input.");
244 DEFINE_string(voiceoutput, NULL, "RTP dump file for voice output.");
245 DEFINE_string(videoinput, NULL, "RTP dump file for video input.");
246 DEFINE_string(videooutput, NULL, "RTP dump file for video output.");
247 DEFINE_bool(render, true, "Renders the video.");
248 DEFINE_string(datachannel, "",
249 "Enable a data channel, and choose the type: rtp or sctp.");
250 DEFINE_bool(d, false, "Turn on debugging.");
251 DEFINE_bool(debugsrtp, false, "Enable debugging for srtp.");
252 DEFINE_bool(help, false, "Prints this message");
253 DEFINE_bool(multisession, false,
254 "Enable support for multiple sessions in calls.");
255 DEFINE_bool(roster, false,
256 "Enable roster messages printed in console.");
257
258 // parse options
259 rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
260 if (FLAG_help) {
261 rtc::FlagList::Print(NULL, false);
262 return 0;
263 }
264
265 bool auto_accept = FLAG_a;
266 bool debug = FLAG_d;
267 std::string signaling = FLAG_signaling;
268 std::string transport = FLAG_transport;
269 bool test_server = FLAG_testserver;
270 bool allow_plain = FLAG_allowplain;
271 std::string tls = FLAG_tls;
272 std::string oauth_token = FLAG_oauth;
273 int32 portallocator_flags = FLAG_portallocator;
274 std::string pmuc_domain = FLAG_pmuc;
275 std::string server = FLAG_s;
276 std::string sdes = FLAG_sdes;
277 std::string dtls = FLAG_dtls;
278 std::string caps_node = FLAG_capsnode;
279 std::string caps_ver = FLAG_capsver;
280 bool debugsrtp = FLAG_debugsrtp;
281 bool render = FLAG_render;
282 std::string data_channel = FLAG_datachannel;
283 bool multisession_enabled = FLAG_multisession;
284 rtc::SSLIdentity* ssl_identity = NULL;
285 bool show_roster_messages = FLAG_roster;
286
287 // Set up debugging.
288 if (debug) {
289 rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE);
290 }
291
292 if (debugsrtp) {
293 cricket::EnableSrtpDebugging();
294 }
295
296 // Set up the crypto subsystem.
297 rtc::InitializeSSL();
298
299 // Parse username and password, if present.
300 buzz::Jid jid;
301 std::string username;
302 rtc::InsecureCryptStringImpl pass;
303 if (argc > 1) {
304 username = argv[1];
305 if (argc > 2) {
306 pass.password() = argv[2];
307 }
308 }
309
310 if (username.empty()) {
311 Print("JID: ");
312 std::cin >> username;
313 }
314 if (username.find('@') == std::string::npos) {
315 username.append("@localhost");
316 }
317 jid = buzz::Jid(username);
318 if (!jid.IsValid() || jid.node() == "") {
319 Print("Invalid JID. JIDs should be in the form user@domain\n");
320 return 1;
321 }
322 if (pass.password().empty() && !test_server && oauth_token.empty()) {
323 Console::SetEcho(false);
324 Print("Password: ");
325 std::cin >> pass.password();
326 Console::SetEcho(true);
327 Print("\n");
328 }
329
330 // Decide on the connection settings.
331 buzz::XmppClientSettings xcs;
332 xcs.set_user(jid.node());
333 xcs.set_resource("call");
334 xcs.set_host(jid.domain());
335 xcs.set_allow_plain(allow_plain);
336
337 if (tls == "disable") {
338 xcs.set_use_tls(buzz::TLS_DISABLED);
339 } else if (tls == "enable") {
340 xcs.set_use_tls(buzz::TLS_ENABLED);
341 } else if (tls == "require") {
342 xcs.set_use_tls(buzz::TLS_REQUIRED);
343 } else {
344 Print("Invalid TLS option, must be enable, disable, or require.\n");
345 return 1;
346 }
347
348 if (test_server) {
349 pass.password() = jid.node();
350 xcs.set_allow_plain(true);
351 xcs.set_use_tls(buzz::TLS_DISABLED);
352 xcs.set_test_server_domain("google.com");
353 }
354 xcs.set_pass(rtc::CryptString(pass));
355 if (!oauth_token.empty()) {
356 xcs.set_auth_token(buzz::AUTH_MECHANISM_OAUTH2, oauth_token);
357 }
358
359 std::string host;
360 int port;
361
362 int colon = server.find(':');
363 if (colon == -1) {
364 host = server;
365 port = DEFAULT_PORT;
366 } else {
367 host = server.substr(0, colon);
368 port = atoi(server.substr(colon + 1).c_str());
369 }
370
371 xcs.set_server(rtc::SocketAddress(host, port));
372
373 // Decide on the signaling and crypto settings.
374 cricket::SignalingProtocol signaling_protocol = cricket::PROTOCOL_HYBRID;
375 if (signaling == "jingle") {
376 signaling_protocol = cricket::PROTOCOL_JINGLE;
377 } else if (signaling == "gingle") {
378 signaling_protocol = cricket::PROTOCOL_GINGLE;
379 } else if (signaling == "hybrid") {
380 signaling_protocol = cricket::PROTOCOL_HYBRID;
381 } else {
382 Print("Invalid signaling protocol. Must be jingle, gingle, or hybrid.\n");
383 return 1;
384 }
385
386 cricket::TransportProtocol transport_protocol = cricket::ICEPROTO_HYBRID;
387 if (transport == "ice") {
388 transport_protocol = cricket::ICEPROTO_RFC5245;
389 } else if (transport == "gice") {
390 transport_protocol = cricket::ICEPROTO_GOOGLE;
391 } else if (transport == "hybrid") {
392 transport_protocol = cricket::ICEPROTO_HYBRID;
393 } else {
394 Print("Invalid transport protocol. Must be ice, gice, or hybrid.\n");
395 return 1;
396 }
397
398 cricket::DataChannelType data_channel_type = cricket::DCT_NONE;
399 if (data_channel == "rtp") {
400 data_channel_type = cricket::DCT_RTP;
401 } else if (data_channel == "sctp") {
402 data_channel_type = cricket::DCT_SCTP;
403 } else if (!data_channel.empty()) {
404 Print("Invalid data channel type. Must be rtp or sctp.\n");
405 return 1;
406 }
407
408 cricket::SecurePolicy sdes_policy, dtls_policy;
409 if (!GetSecurePolicy(sdes, &sdes_policy)) {
410 Print("Invalid SDES policy. Must be enable, disable, or require.\n");
411 return 1;
412 }
413 if (!GetSecurePolicy(dtls, &dtls_policy)) {
414 Print("Invalid DTLS policy. Must be enable, disable, or require.\n");
415 return 1;
416 }
417 if (dtls_policy != cricket::SEC_DISABLED) {
418 ssl_identity = rtc::SSLIdentity::Generate(jid.Str());
419 if (!ssl_identity) {
420 Print("Failed to generate identity for DTLS.\n");
421 return 1;
422 }
423 }
424
425 #ifdef ANDROID
426 MediaEngineFactory::SetCreateFunction(&CreateAndroidMediaEngine);
427 #endif
428
429 #if WIN32
430 // Need to pump messages on our main thread on Windows.
431 rtc::Win32Thread w32_thread;
432 rtc::ThreadManager::Instance()->SetCurrentThread(&w32_thread);
433 #endif
434 rtc::Thread* main_thread = rtc::Thread::Current();
435 #ifdef OSX
436 rtc::MacCocoaSocketServer ss;
437 rtc::SocketServerScope ss_scope(&ss);
438 #endif
439
440 buzz::XmppPump pump;
441 CallClient *client = new CallClient(pump.client(), caps_node, caps_ver);
442
443 if (FLAG_voiceinput || FLAG_voiceoutput ||
444 FLAG_videoinput || FLAG_videooutput) {
445 // If any dump file is specified, we use a FileMediaEngine.
446 cricket::MediaEngineInterface* engine =
447 MediaEngineFactory::CreateFileMediaEngine(
448 FLAG_voiceinput, FLAG_voiceoutput,
449 FLAG_videoinput, FLAG_videooutput);
450 client->SetMediaEngine(engine);
451 }
452
453 Console *console = new Console(main_thread, client);
454 client->SetConsole(console);
455 client->SetAutoAccept(auto_accept);
456 client->SetPmucDomain(pmuc_domain);
457 client->SetPortAllocatorFlags(portallocator_flags);
458 client->SetAllowLocalIps(true);
459 client->SetSignalingProtocol(signaling_protocol);
460 client->SetTransportProtocol(transport_protocol);
461 client->SetSecurePolicy(sdes_policy, dtls_policy);
462 client->SetSslIdentity(ssl_identity);
463 client->SetRender(render);
464 client->SetDataChannelType(data_channel_type);
465 client->SetMultiSessionEnabled(multisession_enabled);
466 client->SetShowRosterMessages(show_roster_messages);
467 console->Start();
468
469 if (debug) {
470 pump.client()->SignalLogInput.connect(&debug_log_, &DebugLog::Input);
471 pump.client()->SignalLogOutput.connect(&debug_log_, &DebugLog::Output);
472 }
473
474 Print(("Logging in to " + server + " as " + jid.Str() + "\n").c_str());
475 pump.DoLogin(xcs, new buzz::XmppSocket(buzz::TLS_REQUIRED), new XmppAuth());
476 main_thread->Run();
477 pump.DoDisconnect();
478
479 console->Stop();
480 delete console;
481 delete client;
482
483 return 0;
484 }
OLDNEW
« no previous file with comments | « webrtc/libjingle/examples/call/Info.plist ('k') | webrtc/libjingle/examples/call/call_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698