// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "build/build_config.h" #if !defined(OS_WIN) extern "C" { #include } #endif // !defined(OS_WIN) #include #include #include "base/at_exit.h" #include "media/base/data_buffer.h" #include "remoting/base/constants.h" #include "remoting/jingle_glue/jingle_channel.h" #include "remoting/jingle_glue/jingle_client.h" #include "remoting/jingle_glue/jingle_thread.h" using remoting::JingleClient; using remoting::JingleChannel; using remoting::kChromotingTokenServiceName; class JingleTestClient : public JingleChannel::Callback, public JingleClient::Callback { public: virtual ~JingleTestClient() {} void Run(const std::string& username, const std::string& auth_token, const std::string& host_jid) { // TODO(hclam): Fix the threading problem. remoting::JingleThread jingle_thread; jingle_thread.Start(); client_ = new JingleClient(&jingle_thread); client_->Init(username, auth_token, kChromotingTokenServiceName, this); if (host_jid != "") { scoped_refptr channel = client_->Connect(host_jid, this); channels_.push_back(channel); } while (true) { std::string line; std::getline(std::cin, line); { AutoLock auto_lock(channels_lock_); // Broadcast message to all clients. for (ChannelsList::iterator it = channels_.begin(); it != channels_.end(); ++it) { uint8* buf = new uint8[line.length()]; memcpy(buf, line.c_str(), line.length()); (*it)->Write(new media::DataBuffer(buf, line.length())); } } if (line == "exit") break; } while (!channels_.empty()) { channels_.front()->Close(); channels_.pop_front(); } client_->Close(); jingle_thread.Stop(); } // JingleChannel::Callback interface. void OnStateChange(JingleChannel* channel, JingleChannel::State state) { LOG(INFO) << "State of " << channel->jid() << " changed to " << state; } void OnPacketReceived(JingleChannel* channel, scoped_refptr buffer) { std::string str(reinterpret_cast(buffer->GetData()), buffer->GetDataSize()); std::cout << "(" << channel->jid() << "): " << str << std::endl; } // JingleClient::Callback interface. void OnStateChange(JingleClient* client, JingleClient::State state) { if (state == JingleClient::CONNECTED) { std::cerr << "Connected as " << client->GetFullJid() << std::endl; } else if (state == JingleClient::CLOSED) { std::cerr << "Connection closed" << std::endl; } } bool OnAcceptConnection(JingleClient* client, const std::string& jid, JingleChannel::Callback** callback) { std::cerr << "Accepting new connection from " << jid << std::endl; *callback = this; return true; } void OnNewConnection(JingleClient* client, scoped_refptr channel) { std::cerr << "Connected to " << channel->jid() << std::endl; AutoLock auto_lock(channels_lock_); channels_.push_back(channel); } private: typedef std::list > ChannelsList; scoped_refptr client_; ChannelsList channels_; Lock channels_lock_; }; int main(int argc, char** argv) { if (argc > 2) std::cerr << "Usage: " << argv[0] << " []" << std::endl; base::AtExitManager exit_manager; std::string host_jid = argc == 2 ? argv[1] : ""; std::string username; std::cout << "JID: "; std::cin >> username; std::string auth_token; std::cout << "Auth token: "; std::cin >> auth_token; JingleTestClient client; client.Run(username, auth_token, host_jid); return 0; }