1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/*
2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle
3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc.
4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without
6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met:
7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  1. Redistributions of source code must retain the above copyright notice,
9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer.
10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  2. Redistributions in binary form must reproduce the above copyright notice,
11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer in the documentation
12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     and/or other materials provided with the distribution.
13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  3. The name of the author may not be used to endorse or promote products
14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     derived from this software without specific prior written permission.
15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */
27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <time.h>
29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <iomanip>
30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <cstdio>
31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <cstring>
32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <vector>
33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/logging.h"
34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/flags.h"
35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/base/pathutils.h"
36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/base/stream.h"
37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/ssladapter.h"
38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/win32socketserver.h"
394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "talk/p2p/base/constants.h"
40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmpp/xmppclientsettings.h"
41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/examples/login/xmppthread.h"
42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/examples/login/xmppauth.h"
43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/examples/login/xmpppump.h"
44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/examples/call/callclient.h"
45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/examples/call/console.h"
46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/session/phone/filemediaengine.h"
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "talk/session/phone/mediasessionclient.h"
48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochclass DebugLog : public sigslot::has_slots<> {
50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch public:
51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DebugLog() :
52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    debug_input_buf_(NULL), debug_input_len_(0), debug_input_alloc_(0),
53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    debug_output_buf_(NULL), debug_output_len_(0), debug_output_alloc_(0),
54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    censor_password_(false)
55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      {}
56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  char * debug_input_buf_;
57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int debug_input_len_;
58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int debug_input_alloc_;
59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  char * debug_output_buf_;
60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int debug_output_len_;
61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int debug_output_alloc_;
62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool censor_password_;
63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void Input(const char * data, int len) {
65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (debug_input_len_ + len > debug_input_alloc_) {
66f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      char * old_buf = debug_input_buf_;
67f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      debug_input_alloc_ = 4096;
68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      while (debug_input_alloc_ < debug_input_len_ + len) {
69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        debug_input_alloc_ *= 2;
70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      debug_input_buf_ = new char[debug_input_alloc_];
72f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      memcpy(debug_input_buf_, old_buf, debug_input_len_);
73f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      delete[] old_buf;
74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    memcpy(debug_input_buf_ + debug_input_len_, data, len);
76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    debug_input_len_ += len;
77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    DebugPrint(debug_input_buf_, &debug_input_len_, false);
78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void Output(const char * data, int len) {
81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (debug_output_len_ + len > debug_output_alloc_) {
82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      char * old_buf = debug_output_buf_;
83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      debug_output_alloc_ = 4096;
84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      while (debug_output_alloc_ < debug_output_len_ + len) {
85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        debug_output_alloc_ *= 2;
86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      debug_output_buf_ = new char[debug_output_alloc_];
88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      memcpy(debug_output_buf_, old_buf, debug_output_len_);
89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      delete[] old_buf;
90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    memcpy(debug_output_buf_ + debug_output_len_, data, len);
92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    debug_output_len_ += len;
93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    DebugPrint(debug_output_buf_, &debug_output_len_, true);
94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  static bool IsAuthTag(const char * str, size_t len) {
97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (str[0] == '<' && str[1] == 'a' &&
98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                         str[2] == 'u' &&
99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                         str[3] == 't' &&
100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                         str[4] == 'h' &&
101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                         str[5] <= ' ') {
102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      std::string tag(str, len);
103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      if (tag.find("mechanism") != std::string::npos)
105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        return true;
106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return false;
108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  void DebugPrint(char * buf, int * plen, bool output) {
111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    int len = *plen;
112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (len > 0) {
113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      time_t tim = time(NULL);
114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      struct tm * now = localtime(&tim);
115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      char *time_string = asctime(now);
116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      if (time_string) {
117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        size_t time_len = strlen(time_string);
118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        if (time_len > 0) {
119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          time_string[time_len-1] = 0;    // trim off terminating \n
120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        }
121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      LOG(INFO) << (output ? "SEND >>>>>>>>>>>>>>>>" : "RECV <<<<<<<<<<<<<<<<")
123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                << " : " << time_string;
124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      bool indent;
126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      int start = 0, nest = 3;
127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      for (int i = 0; i < len; i += 1) {
128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        if (buf[i] == '>') {
129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          if ((i > 0) && (buf[i-1] == '/')) {
130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch            indent = false;
131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          } else if ((start + 1 < len) && (buf[start + 1] == '/')) {
132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch            indent = false;
133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch            nest -= 2;
134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          } else {
135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch            indent = true;
136f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          }
137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          // Output a tag
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          LOG(INFO) << std::setw(nest) << " "
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                    << std::string(buf + start, i + 1 - start);
141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          if (indent)
143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch            nest += 2;
144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          // Note if it's a PLAIN auth tag
146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          if (IsAuthTag(buf + start, i + 1 - start)) {
147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch            censor_password_ = true;
148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          }
149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          // incr
151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          start = i + 1;
152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        }
153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        if (buf[i] == '<' && start < i) {
155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          if (censor_password_) {
156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch            LOG(INFO) << std::setw(nest) << " " << "## TEXT REMOVED ##";
157f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch            censor_password_ = false;
158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          } else {
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            LOG(INFO) << std::setw(nest) << " "
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                      << std::string(buf + start, i - start);
161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          }
162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          start = i;
163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        }
164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      len = len - start;
166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      memcpy(buf, buf + start, len);
167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      *plen = len;
168f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic DebugLog debug_log_;
173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic const int DEFAULT_PORT = 5222;
174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickcricket::MediaEngine* CreateFileMediaEngine(const char* voice_in,
177731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                            const char* voice_out,
178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                            const char* video_in,
179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                            const char* video_out) {
180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  cricket::FileMediaEngine* file_media_engine = new cricket::FileMediaEngine;
181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Set the RTP dump file names.
182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (voice_in) {
183731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    file_media_engine->set_voice_input_filename(voice_in);
184731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
185731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (voice_out) {
186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    file_media_engine->set_voice_output_filename(voice_out);
187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
188731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (video_in) {
189731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    file_media_engine->set_video_input_filename(video_in);
190731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (video_out) {
192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    file_media_engine->set_video_output_filename(video_out);
193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Set voice and video codecs. TODO: The codecs actually depend on
196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // the the input voice and video streams.
197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::vector<cricket::AudioCodec> voice_codecs;
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  voice_codecs.push_back(
1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      cricket::AudioCodec(9, "G722", 16000, 0, 1, 0));
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  file_media_engine->set_voice_codecs(voice_codecs);
201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::vector<cricket::VideoCodec> video_codecs;
202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  video_codecs.push_back(
203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      cricket::VideoCodec(97, "H264", 320, 240, 30, 0));
204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  file_media_engine->set_video_codecs(video_codecs);
205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return file_media_engine;
207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint main(int argc, char **argv) {
210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // This app has three threads. The main thread will run the XMPP client,
211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // which will print to the screen in its own thread. A second thread
212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // will get input from the console, parse it, and pass the appropriate
213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // message back to the XMPP client's thread. A third thread is used
214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // by MediaSessionClient as its worker thread.
215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // define options
217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_bool(a, false, "Turn on auto accept.");
218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_bool(d, false, "Turn on debugging.");
2194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DEFINE_string(
2204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      protocol, "hybrid",
2214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      "Initial signaling protocol to use: jingle, gingle, or hybrid.");
222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DEFINE_string(
223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      secure, "disable",
224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      "Disable or enable encryption: disable, enable, require.");
225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_bool(testserver, false, "Use test server");
2264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DEFINE_bool(plainserver, false, "Turn off tls and allow plain password.");
227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_int(portallocator, 0, "Filter out unwanted connection types.");
228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_string(filterhost, NULL, "Filter out the host from all candidates.");
229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_string(pmuc, "groupchat.google.com", "The persistant muc domain.");
230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  DEFINE_string(s, "talk.google.com", "The connection server to use.");
231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DEFINE_string(voiceinput, NULL, "RTP dump file for voice input.");
232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DEFINE_string(voiceoutput, NULL, "RTP dump file for voice output.");
233731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DEFINE_string(videoinput, NULL, "RTP dump file for video input.");
234731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DEFINE_string(videooutput, NULL, "RTP dump file for video output.");
235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DEFINE_bool(help, false, "Prints this message");
236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // parse options
238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  FlagList::SetFlagsFromCommandLine(&argc, argv, true);
239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (FLAG_help) {
240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    FlagList::Print(NULL, false);
241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return 0;
242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool auto_accept = FLAG_a;
245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool debug = FLAG_d;
2464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  std::string protocol = FLAG_protocol;
247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool test_server = FLAG_testserver;
2484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  bool plain_server = FLAG_plainserver;
249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int32 portallocator_flags = FLAG_portallocator;
250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string pmuc_domain = FLAG_pmuc;
251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string server = FLAG_s;
252dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  std::string secure = FLAG_secure;
253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
2544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  cricket::SignalingProtocol initial_protocol = cricket::PROTOCOL_HYBRID;
2554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (protocol == "jingle") {
2564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    initial_protocol = cricket::PROTOCOL_JINGLE;
2574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  } else if (protocol == "gingle") {
2584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    initial_protocol = cricket::PROTOCOL_GINGLE;
2594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  } else if (protocol == "hybrid") {
2604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    initial_protocol = cricket::PROTOCOL_HYBRID;
2614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  } else {
262dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    printf("Invalid protocol.  Must be jingle, gingle, or hybrid.\n");
263dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return 1;
264dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
265dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
266dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  cricket::SecureMediaPolicy secure_policy = cricket::SEC_DISABLED;
267dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (secure == "disable") {
268dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    secure_policy = cricket::SEC_DISABLED;
269dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else if (secure == "enable") {
270dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    secure_policy = cricket::SEC_ENABLED;
271dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else if (secure == "require") {
272dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    secure_policy = cricket::SEC_REQUIRED;
273dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
274dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    printf("Invalid encryption.  Must be enable, disable, or require.\n");
2754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return 1;
2764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
2774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // parse username and password, if present
279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  buzz::Jid jid;
280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string username;
281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::InsecureCryptStringImpl pass;
282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (argc > 1) {
283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    username = argv[1];
284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (argc > 2) {
285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      pass.password() = argv[2];
286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (debug)
290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    talk_base::LogMessage::LogToDebug(talk_base::LS_VERBOSE);
291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (username.empty()) {
293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    std::cout << "JID: ";
294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    std::cin >> username;
295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (username.find('@') == std::string::npos) {
297f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    username.append("@localhost");
298f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
299f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  jid = buzz::Jid(username);
300f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!jid.IsValid() || jid.node() == "") {
301f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    printf("Invalid JID. JIDs should be in the form user@domain\n");
302f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return 1;
303f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
304f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (pass.password().empty() && !test_server) {
305f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Console::SetEcho(false);
306f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    std::cout << "Password: ";
307f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    std::cin >> pass.password();
308f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Console::SetEcho(true);
309f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    std::cout << std::endl;
310f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
311f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  buzz::XmppClientSettings xcs;
313f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  xcs.set_user(jid.node());
314f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  xcs.set_resource("call");
315f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  xcs.set_host(jid.domain());
316f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  xcs.set_use_tls(!test_server);
317f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
3184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (plain_server) {
3194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    xcs.set_use_tls(false);
3204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    xcs.set_allow_plain(true);
3214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
322f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (test_server) {
323f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pass.password() = jid.node();
324f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    xcs.set_allow_plain(true);
325f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
326f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  xcs.set_pass(talk_base::CryptString(pass));
327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
328f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string host;
329f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int port;
330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
331f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int colon = server.find(':');
332f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (colon == -1) {
333f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    host = server;
334f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    port = DEFAULT_PORT;
335f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  } else {
336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    host = server.substr(0, colon);
337f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    port = atoi(server.substr(colon + 1).c_str());
338f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
339f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
340f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  xcs.set_server(talk_base::SocketAddress(host, port));
341f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  printf("Logging in to %s as %s\n", server.c_str(), jid.Str().c_str());
342f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::InitializeSSL();
344f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
345f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
346f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#if WIN32
347f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Need to pump messages on our main thread on Windows.
348f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::Win32Thread w32_thread;
349f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::ThreadManager::SetCurrent(&w32_thread);
350f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
351f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::Thread* main_thread = talk_base::Thread::Current();
352f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
353f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  XmppPump pump;
354f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  CallClient *client = new CallClient(pump.client());
355f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
356731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (FLAG_voiceinput || FLAG_voiceoutput ||
357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      FLAG_videoinput || FLAG_videooutput) {
358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // If any dump file is specified, we use FileMediaEngine.
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    cricket::MediaEngine* engine = CreateFileMediaEngine(FLAG_voiceinput,
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                         FLAG_voiceoutput,
361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                         FLAG_videoinput,
362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                                         FLAG_videooutput);
363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // The engine will be released by the client later.
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    client->SetMediaEngine(engine);
365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
367f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Console *console = new Console(main_thread, client);
368f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  client->SetConsole(console);
369f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  client->SetAutoAccept(auto_accept);
370f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  client->SetPmucDomain(pmuc_domain);
371f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  client->SetPortAllocatorFlags(portallocator_flags);
3724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  client->SetAllowLocalIps(true);
3734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  client->SetInitialProtocol(initial_protocol);
374dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  client->SetSecurePolicy(secure_policy);
375f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  console->Start();
376f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
377f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (debug) {
378f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pump.client()->SignalLogInput.connect(&debug_log_, &DebugLog::Input);
379f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    pump.client()->SignalLogOutput.connect(&debug_log_, &DebugLog::Output);
380f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
381f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
382f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pump.DoLogin(xcs, new XmppSocket(true), NULL);
383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  main_thread->Run();
384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  pump.DoDisconnect();
385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  console->Stop();
387f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  delete console;
388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  delete client;
389f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
390f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return 0;
391f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
392