Revert r7886:7887.

Broke build steps in other code that uses securetunnelsessionclient.cc
and others.

TBR=tommi@webrtc.org,pthatcher@webrtc.org
BUG=

Review URL: https://webrtc-codereview.appspot.com/36439004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7890 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org
2014-12-15 07:03:04 +00:00
parent 40e4767f2b
commit 18a3896bd2
65 changed files with 200 additions and 262 deletions

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>com.google.call</string>
<key>CFBundleName</key>
<string>call</string>
</dict>
</plist>

View File

@@ -0,0 +1,497 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <iomanip>
#include <iostream>
#include <vector>
#include "webrtc/base/flags.h"
#include "webrtc/base/logging.h"
#ifdef OSX
#include "webrtc/base/maccocoasocketserver.h"
#endif
#include "talk/examples/call/callclient.h"
#include "talk/examples/call/console.h"
#include "talk/examples/call/mediaenginefactory.h"
#include "webrtc/p2p/base/constants.h"
#include "talk/session/media/mediasessionclient.h"
#include "talk/session/media/srtpfilter.h"
#include "webrtc/libjingle/xmpp/xmppauth.h"
#include "webrtc/libjingle/xmpp/xmppclientsettings.h"
#include "webrtc/libjingle/xmpp/xmpppump.h"
#include "webrtc/libjingle/xmpp/xmppsocket.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/ssladapter.h"
#include "webrtc/base/stream.h"
#include "webrtc/base/win32socketserver.h"
class DebugLog : public sigslot::has_slots<> {
public:
DebugLog() :
debug_input_buf_(NULL), debug_input_len_(0), debug_input_alloc_(0),
debug_output_buf_(NULL), debug_output_len_(0), debug_output_alloc_(0),
censor_password_(false)
{}
char * debug_input_buf_;
int debug_input_len_;
int debug_input_alloc_;
char * debug_output_buf_;
int debug_output_len_;
int debug_output_alloc_;
bool censor_password_;
void Input(const char * data, int len) {
if (debug_input_len_ + len > debug_input_alloc_) {
char * old_buf = debug_input_buf_;
debug_input_alloc_ = 4096;
while (debug_input_alloc_ < debug_input_len_ + len) {
debug_input_alloc_ *= 2;
}
debug_input_buf_ = new char[debug_input_alloc_];
memcpy(debug_input_buf_, old_buf, debug_input_len_);
delete[] old_buf;
}
memcpy(debug_input_buf_ + debug_input_len_, data, len);
debug_input_len_ += len;
DebugPrint(debug_input_buf_, &debug_input_len_, false);
}
void Output(const char * data, int len) {
if (debug_output_len_ + len > debug_output_alloc_) {
char * old_buf = debug_output_buf_;
debug_output_alloc_ = 4096;
while (debug_output_alloc_ < debug_output_len_ + len) {
debug_output_alloc_ *= 2;
}
debug_output_buf_ = new char[debug_output_alloc_];
memcpy(debug_output_buf_, old_buf, debug_output_len_);
delete[] old_buf;
}
memcpy(debug_output_buf_ + debug_output_len_, data, len);
debug_output_len_ += len;
DebugPrint(debug_output_buf_, &debug_output_len_, true);
}
static bool IsAuthTag(const char * str, size_t len) {
if (str[0] == '<' && str[1] == 'a' &&
str[2] == 'u' &&
str[3] == 't' &&
str[4] == 'h' &&
str[5] <= ' ') {
std::string tag(str, len);
if (tag.find("mechanism") != std::string::npos)
return true;
}
return false;
}
void DebugPrint(char * buf, int * plen, bool output) {
int len = *plen;
if (len > 0) {
time_t tim = time(NULL);
struct tm * now = localtime(&tim);
char *time_string = asctime(now);
if (time_string) {
size_t time_len = strlen(time_string);
if (time_len > 0) {
time_string[time_len-1] = 0; // trim off terminating \n
}
}
LOG(INFO) << (output ? "SEND >>>>>>>>>>>>>>>>" : "RECV <<<<<<<<<<<<<<<<")
<< " : " << time_string;
bool indent;
int start = 0, nest = 3;
for (int i = 0; i < len; i += 1) {
if (buf[i] == '>') {
if ((i > 0) && (buf[i-1] == '/')) {
indent = false;
} else if ((start + 1 < len) && (buf[start + 1] == '/')) {
indent = false;
nest -= 2;
} else {
indent = true;
}
// Output a tag
LOG(INFO) << std::setw(nest) << " "
<< std::string(buf + start, i + 1 - start);
if (indent)
nest += 2;
// Note if it's a PLAIN auth tag
if (IsAuthTag(buf + start, i + 1 - start)) {
censor_password_ = true;
}
// incr
start = i + 1;
}
if (buf[i] == '<' && start < i) {
if (censor_password_) {
LOG(INFO) << std::setw(nest) << " " << "## TEXT REMOVED ##";
censor_password_ = false;
} else {
LOG(INFO) << std::setw(nest) << " "
<< std::string(buf + start, i - start);
}
start = i;
}
}
len = len - start;
memcpy(buf, buf + start, len);
*plen = len;
}
}
};
static DebugLog debug_log_;
static const int DEFAULT_PORT = 5222;
#ifdef ANDROID
static std::vector<cricket::AudioCodec> codecs;
static const cricket::AudioCodec ISAC(103, "ISAC", 40000, 16000, 1, 0);
cricket::MediaEngineInterface *CreateAndroidMediaEngine() {
cricket::FakeMediaEngine *engine = new cricket::FakeMediaEngine();
codecs.push_back(ISAC);
engine->SetAudioCodecs(codecs);
return engine;
}
#endif
// TODO: Move this into Console.
void Print(const char* chars) {
printf("%s", chars);
fflush(stdout);
}
bool GetSecurePolicy(const std::string& in, cricket::SecurePolicy* out) {
if (in == "disable") {
*out = cricket::SEC_DISABLED;
} else if (in == "enable") {
*out = cricket::SEC_ENABLED;
} else if (in == "require") {
*out = cricket::SEC_REQUIRED;
} else {
return false;
}
return true;
}
int main(int argc, char **argv) {
// This app has three threads. The main thread will run the XMPP client,
// which will print to the screen in its own thread. A second thread
// will get input from the console, parse it, and pass the appropriate
// message back to the XMPP client's thread. A third thread is used
// by MediaSessionClient as its worker thread.
// define options
DEFINE_string(s, "talk.google.com", "The connection server to use.");
DEFINE_string(tls, "require",
"Select connection encryption: disable, enable, require.");
DEFINE_bool(allowplain, false, "Allow plain authentication.");
DEFINE_bool(testserver, false, "Use test server.");
DEFINE_string(oauth, "", "OAuth2 access token.");
DEFINE_bool(a, false, "Turn on auto accept for incoming calls.");
DEFINE_string(signaling, "hybrid",
"Initial signaling protocol to use: jingle, gingle, or hybrid.");
DEFINE_string(transport, "hybrid",
"Initial transport protocol to use: ice, gice, or hybrid.");
DEFINE_string(sdes, "enable",
"Select SDES media encryption: disable, enable, require.");
DEFINE_string(dtls, "disable",
"Select DTLS transport encryption: disable, enable, require.");
DEFINE_int(portallocator, 0, "Filter out unwanted connection types.");
DEFINE_string(pmuc, "groupchat.google.com", "The persistant muc domain.");
DEFINE_string(capsnode, "http://code.google.com/p/libjingle/call",
"Caps node: A URI identifying the app.");
DEFINE_string(capsver, "0.6",
"Caps ver: A string identifying the version of the app.");
DEFINE_string(voiceinput, NULL, "RTP dump file for voice input.");
DEFINE_string(voiceoutput, NULL, "RTP dump file for voice output.");
DEFINE_string(videoinput, NULL, "RTP dump file for video input.");
DEFINE_string(videooutput, NULL, "RTP dump file for video output.");
DEFINE_bool(render, true, "Renders the video.");
DEFINE_string(datachannel, "",
"Enable a data channel, and choose the type: rtp or sctp.");
DEFINE_bool(d, false, "Turn on debugging.");
DEFINE_string(log, "", "Turn on debugging to a file.");
DEFINE_bool(debugsrtp, false, "Enable debugging for srtp.");
DEFINE_bool(help, false, "Prints this message");
DEFINE_bool(multisession, false,
"Enable support for multiple sessions in calls.");
DEFINE_bool(roster, false,
"Enable roster messages printed in console.");
// parse options
rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
if (FLAG_help) {
rtc::FlagList::Print(NULL, false);
return 0;
}
bool auto_accept = FLAG_a;
bool debug = FLAG_d;
std::string log = FLAG_log;
std::string signaling = FLAG_signaling;
std::string transport = FLAG_transport;
bool test_server = FLAG_testserver;
bool allow_plain = FLAG_allowplain;
std::string tls = FLAG_tls;
std::string oauth_token = FLAG_oauth;
int32 portallocator_flags = FLAG_portallocator;
std::string pmuc_domain = FLAG_pmuc;
std::string server = FLAG_s;
std::string sdes = FLAG_sdes;
std::string dtls = FLAG_dtls;
std::string caps_node = FLAG_capsnode;
std::string caps_ver = FLAG_capsver;
bool debugsrtp = FLAG_debugsrtp;
bool render = FLAG_render;
std::string data_channel = FLAG_datachannel;
bool multisession_enabled = FLAG_multisession;
rtc::SSLIdentity* ssl_identity = NULL;
bool show_roster_messages = FLAG_roster;
// Set up debugging.
if (debug) {
rtc::LogMessage::LogToDebug(rtc::LS_VERBOSE);
}
if (!log.empty()) {
rtc::StreamInterface* stream =
rtc::Filesystem::OpenFile(log, "a");
if (stream) {
rtc::LogMessage::LogToStream(stream, rtc::LS_VERBOSE);
} else {
Print(("Cannot open debug log " + log + "\n").c_str());
return 1;
}
}
if (debugsrtp) {
cricket::EnableSrtpDebugging();
}
// Set up the crypto subsystem.
rtc::InitializeSSL();
// Parse username and password, if present.
buzz::Jid jid;
std::string username;
rtc::InsecureCryptStringImpl pass;
if (argc > 1) {
username = argv[1];
if (argc > 2) {
pass.password() = argv[2];
}
}
if (username.empty()) {
Print("JID: ");
std::cin >> username;
}
if (username.find('@') == std::string::npos) {
username.append("@localhost");
}
jid = buzz::Jid(username);
if (!jid.IsValid() || jid.node() == "") {
Print("Invalid JID. JIDs should be in the form user@domain\n");
return 1;
}
if (pass.password().empty() && !test_server && oauth_token.empty()) {
Console::SetEcho(false);
Print("Password: ");
std::cin >> pass.password();
Console::SetEcho(true);
Print("\n");
}
// Decide on the connection settings.
buzz::XmppClientSettings xcs;
xcs.set_user(jid.node());
xcs.set_resource("call");
xcs.set_host(jid.domain());
xcs.set_allow_plain(allow_plain);
if (tls == "disable") {
xcs.set_use_tls(buzz::TLS_DISABLED);
} else if (tls == "enable") {
xcs.set_use_tls(buzz::TLS_ENABLED);
} else if (tls == "require") {
xcs.set_use_tls(buzz::TLS_REQUIRED);
} else {
Print("Invalid TLS option, must be enable, disable, or require.\n");
return 1;
}
if (test_server) {
pass.password() = jid.node();
xcs.set_allow_plain(true);
xcs.set_use_tls(buzz::TLS_DISABLED);
xcs.set_test_server_domain("google.com");
}
xcs.set_pass(rtc::CryptString(pass));
if (!oauth_token.empty()) {
xcs.set_auth_token(buzz::AUTH_MECHANISM_OAUTH2, oauth_token);
}
std::string host;
int port;
int colon = server.find(':');
if (colon == -1) {
host = server;
port = DEFAULT_PORT;
} else {
host = server.substr(0, colon);
port = atoi(server.substr(colon + 1).c_str());
}
xcs.set_server(rtc::SocketAddress(host, port));
// Decide on the signaling and crypto settings.
cricket::SignalingProtocol signaling_protocol = cricket::PROTOCOL_HYBRID;
if (signaling == "jingle") {
signaling_protocol = cricket::PROTOCOL_JINGLE;
} else if (signaling == "gingle") {
signaling_protocol = cricket::PROTOCOL_GINGLE;
} else if (signaling == "hybrid") {
signaling_protocol = cricket::PROTOCOL_HYBRID;
} else {
Print("Invalid signaling protocol. Must be jingle, gingle, or hybrid.\n");
return 1;
}
cricket::TransportProtocol transport_protocol = cricket::ICEPROTO_HYBRID;
if (transport == "ice") {
transport_protocol = cricket::ICEPROTO_RFC5245;
} else if (transport == "gice") {
transport_protocol = cricket::ICEPROTO_GOOGLE;
} else if (transport == "hybrid") {
transport_protocol = cricket::ICEPROTO_HYBRID;
} else {
Print("Invalid transport protocol. Must be ice, gice, or hybrid.\n");
return 1;
}
cricket::DataChannelType data_channel_type = cricket::DCT_NONE;
if (data_channel == "rtp") {
data_channel_type = cricket::DCT_RTP;
} else if (data_channel == "sctp") {
data_channel_type = cricket::DCT_SCTP;
} else if (!data_channel.empty()) {
Print("Invalid data channel type. Must be rtp or sctp.\n");
return 1;
}
cricket::SecurePolicy sdes_policy, dtls_policy;
if (!GetSecurePolicy(sdes, &sdes_policy)) {
Print("Invalid SDES policy. Must be enable, disable, or require.\n");
return 1;
}
if (!GetSecurePolicy(dtls, &dtls_policy)) {
Print("Invalid DTLS policy. Must be enable, disable, or require.\n");
return 1;
}
if (dtls_policy != cricket::SEC_DISABLED) {
ssl_identity = rtc::SSLIdentity::Generate(jid.Str());
if (!ssl_identity) {
Print("Failed to generate identity for DTLS.\n");
return 1;
}
}
#ifdef ANDROID
MediaEngineFactory::SetCreateFunction(&CreateAndroidMediaEngine);
#endif
#if WIN32
// Need to pump messages on our main thread on Windows.
rtc::Win32Thread w32_thread;
rtc::ThreadManager::Instance()->SetCurrentThread(&w32_thread);
#endif
rtc::Thread* main_thread = rtc::Thread::Current();
#ifdef OSX
rtc::MacCocoaSocketServer ss;
rtc::SocketServerScope ss_scope(&ss);
#endif
buzz::XmppPump pump;
CallClient *client = new CallClient(pump.client(), caps_node, caps_ver);
if (FLAG_voiceinput || FLAG_voiceoutput ||
FLAG_videoinput || FLAG_videooutput) {
// If any dump file is specified, we use a FileMediaEngine.
cricket::MediaEngineInterface* engine =
MediaEngineFactory::CreateFileMediaEngine(
FLAG_voiceinput, FLAG_voiceoutput,
FLAG_videoinput, FLAG_videooutput);
client->SetMediaEngine(engine);
}
Console *console = new Console(main_thread, client);
client->SetConsole(console);
client->SetAutoAccept(auto_accept);
client->SetPmucDomain(pmuc_domain);
client->SetPortAllocatorFlags(portallocator_flags);
client->SetAllowLocalIps(true);
client->SetSignalingProtocol(signaling_protocol);
client->SetTransportProtocol(transport_protocol);
client->SetSecurePolicy(sdes_policy, dtls_policy);
client->SetSslIdentity(ssl_identity);
client->SetRender(render);
client->SetDataChannelType(data_channel_type);
client->SetMultiSessionEnabled(multisession_enabled);
client->SetShowRosterMessages(show_roster_messages);
console->Start();
if (debug) {
pump.client()->SignalLogInput.connect(&debug_log_, &DebugLog::Input);
pump.client()->SignalLogOutput.connect(&debug_log_, &DebugLog::Output);
}
Print(("Logging in to " + server + " as " + jid.Str() + "\n").c_str());
pump.DoLogin(xcs, new buzz::XmppSocket(buzz::TLS_REQUIRED), new XmppAuth());
main_thread->Run();
pump.DoDisconnect();
console->Stop();
delete console;
delete client;
return 0;
}

View File

@@ -0,0 +1,37 @@
/*
* libjingle
* Copyright 2008, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Main function for all unit tests in talk/examples/call
#include "testing/base/public/gunit.h"
#include "webrtc/base/logging.h"
int main(int argc, char **argv) {
rtc::LogMessage::LogToDebug(rtc::LogMessage::NO_LOGGING);
testing::ParseGUnitFlags(&argc, argv);
return RUN_ALL_TESTS();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,352 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TALK_EXAMPLES_CALL_CALLCLIENT_H_
#define TALK_EXAMPLES_CALL_CALLCLIENT_H_
#include <map>
#include <string>
#include <vector>
#include "talk/examples/call/console.h"
#include "talk/media/base/mediachannel.h"
#include "webrtc/p2p/base/session.h"
#include "talk/session/media/mediamessages.h"
#include "talk/session/media/mediasessionclient.h"
#include "webrtc/libjingle/xmpp/hangoutpubsubclient.h"
#include "webrtc/libjingle/xmpp/presencestatus.h"
#include "webrtc/libjingle/xmpp/xmppclient.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/sslidentity.h"
namespace buzz {
class PresencePushTask;
class PresenceOutTask;
class MucInviteRecvTask;
class MucInviteSendTask;
class FriendInviteSendTask;
class DiscoInfoQueryTask;
class Muc;
class PresenceStatus;
class IqTask;
class MucRoomConfigTask;
class MucRoomLookupTask;
class MucPresenceStatus;
class XmlElement;
class HangoutPubSubClient;
struct AvailableMediaEntry;
struct MucRoomInfo;
} // namespace buzz
namespace rtc {
class Thread;
class NetworkManager;
} // namespace rtc
namespace cricket {
class PortAllocator;
class MediaEngineInterface;
class MediaSessionClient;
class Call;
class SessionManagerTask;
struct CallOptions;
struct MediaStreams;
struct StreamParams;
} // namespace cricket
struct RosterItem {
buzz::Jid jid;
buzz::PresenceStatus::Show show;
std::string status;
};
struct StaticRenderedView {
StaticRenderedView(const cricket::StaticVideoView& view,
cricket::VideoRenderer* renderer) :
view(view),
renderer(renderer) {
}
cricket::StaticVideoView view;
cricket::VideoRenderer* renderer;
};
// Maintain a mapping of (session, ssrc) to rendered view.
typedef std::map<std::pair<cricket::Session*, uint32>,
StaticRenderedView> StaticRenderedViews;
class CallClient: public sigslot::has_slots<> {
public:
CallClient(buzz::XmppClient* xmpp_client,
const std::string& caps_node,
const std::string& version);
~CallClient();
cricket::MediaSessionClient* media_client() const { return media_client_; }
void SetMediaEngine(cricket::MediaEngineInterface* media_engine) {
media_engine_ = media_engine;
}
void SetAutoAccept(bool auto_accept) {
auto_accept_ = auto_accept;
}
void SetPmucDomain(const std::string &pmuc_domain) {
pmuc_domain_ = pmuc_domain;
}
void SetRender(bool render) {
render_ = render;
}
void SetDataChannelType(cricket::DataChannelType data_channel_type) {
data_channel_type_ = data_channel_type;
}
void SetMultiSessionEnabled(bool multisession_enabled) {
multisession_enabled_ = multisession_enabled;
}
void SetConsole(Console *console) {
console_ = console;
}
void SetPriority(int priority) {
my_status_.set_priority(priority);
}
void SendStatus() {
SendStatus(my_status_);
}
void SendStatus(const buzz::PresenceStatus& status);
void ParseLine(const std::string &str);
void SendChat(const std::string& to, const std::string msg);
void SendData(const std::string& stream_name,
const std::string& text);
void InviteFriend(const std::string& user);
void JoinMuc(const buzz::Jid& room_jid);
void JoinMuc(const std::string& room_jid_str);
void LookupAndJoinMuc(const std::string& room_name);
void InviteToMuc(const std::string& user, const std::string& room);
bool InMuc();
const buzz::Jid* FirstMucJid();
void LeaveMuc(const std::string& room);
void SetNick(const std::string& muc_nick);
void SetPortAllocatorFlags(uint32 flags) { portallocator_flags_ = flags; }
void SetAllowLocalIps(bool allow_local_ips) {
allow_local_ips_ = allow_local_ips;
}
void SetSignalingProtocol(cricket::SignalingProtocol protocol) {
signaling_protocol_ = protocol;
}
void SetTransportProtocol(cricket::TransportProtocol protocol) {
transport_protocol_ = protocol;
}
void SetSecurePolicy(cricket::SecurePolicy sdes_policy,
cricket::SecurePolicy dtls_policy) {
sdes_policy_ = sdes_policy;
dtls_policy_ = dtls_policy;
}
void SetSslIdentity(rtc::SSLIdentity* identity) {
ssl_identity_.reset(identity);
}
typedef std::map<buzz::Jid, buzz::Muc*> MucMap;
const MucMap& mucs() const {
return mucs_;
}
void SetShowRosterMessages(bool show_roster_messages) {
show_roster_messages_ = show_roster_messages;
}
private:
void AddStream(uint32 audio_src_id, uint32 video_src_id);
void RemoveStream(uint32 audio_src_id, uint32 video_src_id);
void OnStateChange(buzz::XmppEngine::State state);
void InitMedia();
void InitPresence();
void StartXmppPing();
void OnPingTimeout();
void OnRequestSignaling();
void OnSessionCreate(cricket::Session* session, bool initiate);
void OnCallCreate(cricket::Call* call);
void OnCallDestroy(cricket::Call* call);
void OnSessionState(cricket::Call* call,
cricket::Session* session,
cricket::Session::State state);
void OnStatusUpdate(const buzz::PresenceStatus& status);
void OnMucInviteReceived(const buzz::Jid& inviter, const buzz::Jid& room,
const std::vector<buzz::AvailableMediaEntry>& avail);
void OnMucJoined(const buzz::Jid& endpoint);
void OnMucStatusUpdate(const buzz::Jid& jid,
const buzz::MucPresenceStatus& status);
void OnMucLeft(const buzz::Jid& endpoint, int error);
void OnPresenterStateChange(const std::string& nick,
bool was_presenting, bool is_presenting);
void OnAudioMuteStateChange(const std::string& nick,
bool was_muted, bool is_muted);
void OnRecordingStateChange(const std::string& nick,
bool was_recording, bool is_recording);
void OnRemoteMuted(const std::string& mutee_nick,
const std::string& muter_nick,
bool should_mute_locally);
void OnMediaBlocked(const std::string& blockee_nick,
const std::string& blocker_nick);
void OnHangoutRequestError(const std::string& node,
const buzz::XmlElement* stanza);
void OnHangoutPublishAudioMuteError(const std::string& task_id,
const buzz::XmlElement* stanza);
void OnHangoutPublishPresenterError(const std::string& task_id,
const buzz::XmlElement* stanza);
void OnHangoutPublishRecordingError(const std::string& task_id,
const buzz::XmlElement* stanza);
void OnHangoutRemoteMuteError(const std::string& task_id,
const std::string& mutee_nick,
const buzz::XmlElement* stanza);
void OnDevicesChange();
void OnMediaStreamsUpdate(cricket::Call* call,
cricket::Session* session,
const cricket::MediaStreams& added,
const cricket::MediaStreams& removed);
void OnSpeakerChanged(cricket::Call* call,
cricket::Session* session,
const cricket::StreamParams& speaker_stream);
void OnRoomLookupResponse(buzz::MucRoomLookupTask* task,
const buzz::MucRoomInfo& room_info);
void OnRoomLookupError(buzz::IqTask* task,
const buzz::XmlElement* stanza);
void OnRoomConfigResult(buzz::MucRoomConfigTask* task);
void OnRoomConfigError(buzz::IqTask* task,
const buzz::XmlElement* stanza);
void OnDataReceived(cricket::Call*,
const cricket::ReceiveDataParams& params,
const rtc::Buffer& payload);
buzz::Jid GenerateRandomMucJid();
// Depending on |enable|, render (or don't) all the streams in |session|.
void RenderAllStreams(cricket::Call* call,
cricket::Session* session,
bool enable);
// Depending on |enable|, render (or don't) the streams in |video_streams|.
void RenderStreams(cricket::Call* call,
cricket::Session* session,
const std::vector<cricket::StreamParams>& video_streams,
bool enable);
// Depending on |enable|, render (or don't) the supplied |stream|.
void RenderStream(cricket::Call* call,
cricket::Session* session,
const cricket::StreamParams& stream,
bool enable);
void AddStaticRenderedView(
cricket::Session* session,
uint32 ssrc, int width, int height, int framerate,
int x_offset, int y_offset);
bool RemoveStaticRenderedView(uint32 ssrc);
void RemoveCallsStaticRenderedViews(cricket::Call* call);
void SendViewRequest(cricket::Call* call, cricket::Session* session);
bool SelectFirstDesktopScreencastId(cricket::ScreencastId* screencastid);
static const std::string strerror(buzz::XmppEngine::Error err);
void PrintRoster();
bool FindJid(const std::string& name,
buzz::Jid* found_jid,
cricket::CallOptions* options);
bool PlaceCall(const std::string& name, cricket::CallOptions options);
bool InitiateAdditionalSession(const std::string& name,
cricket::CallOptions options);
void TerminateAndRemoveSession(cricket::Call* call, const std::string& id);
void PrintCalls();
void SwitchToCall(uint32 call_id);
void Accept(const cricket::CallOptions& options);
void Reject();
void Quit();
void GetDevices();
void PrintDevices(const std::vector<std::string>& names);
void SetVolume(const std::string& level);
cricket::Session* GetFirstSession() { return sessions_[call_->id()][0]; }
void AddSession(cricket::Session* session) {
sessions_[call_->id()].push_back(session);
}
void PrintStats() const;
void SetupAcceptedCall();
typedef std::map<std::string, RosterItem> RosterMap;
Console *console_;
buzz::XmppClient* xmpp_client_;
rtc::Thread* worker_thread_;
rtc::NetworkManager* network_manager_;
cricket::PortAllocator* port_allocator_;
cricket::SessionManager* session_manager_;
cricket::SessionManagerTask* session_manager_task_;
cricket::MediaEngineInterface* media_engine_;
cricket::DataEngineInterface* data_engine_;
cricket::MediaSessionClient* media_client_;
MucMap mucs_;
cricket::Call* call_;
typedef std::map<uint32, std::vector<cricket::Session *> > SessionMap;
SessionMap sessions_;
buzz::HangoutPubSubClient* hangout_pubsub_client_;
bool incoming_call_;
bool auto_accept_;
std::string pmuc_domain_;
bool render_;
cricket::DataChannelType data_channel_type_;
bool multisession_enabled_;
cricket::VideoRenderer* local_renderer_;
StaticRenderedViews static_rendered_views_;
uint32 static_views_accumulated_count_;
uint32 screencast_ssrc_;
buzz::PresenceStatus my_status_;
buzz::PresencePushTask* presence_push_;
buzz::PresenceOutTask* presence_out_;
buzz::MucInviteRecvTask* muc_invite_recv_;
buzz::MucInviteSendTask* muc_invite_send_;
buzz::FriendInviteSendTask* friend_invite_send_;
RosterMap* roster_;
uint32 portallocator_flags_;
bool allow_local_ips_;
cricket::SignalingProtocol signaling_protocol_;
cricket::TransportProtocol transport_protocol_;
cricket::SecurePolicy sdes_policy_;
cricket::SecurePolicy dtls_policy_;
rtc::scoped_ptr<rtc::SSLIdentity> ssl_identity_;
std::string last_sent_to_;
bool show_roster_messages_;
};
#endif // TALK_EXAMPLES_CALL_CALLCLIENT_H_

View File

@@ -0,0 +1,47 @@
/*
* libjingle
* Copyright 2008, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Unit tests for CallClient
#include "talk/examples/call/callclient.h"
#include "talk/media/base/filemediaengine.h"
#include "talk/media/base/mediaengine.h"
#include "webrtc/libjingle/xmpp/xmppthread.h"
#include "webrtc/base/gunit.h"
TEST(CallClientTest, CreateCallClientWithDefaultMediaEngine) {
buzz::XmppPump pump;
CallClient *client = new CallClient(pump.client(), "app", "version");
delete client;
}
TEST(CallClientTest, CreateCallClientWithFileMediaEngine) {
buzz::XmppPump pump;
CallClient *client = new CallClient(pump.client(), "app", "version");
client->SetMediaEngine(new cricket::FileMediaEngine);
delete client;
}

View File

@@ -0,0 +1,169 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _CRT_SECURE_NO_DEPRECATE 1
#include <assert.h>
#ifdef POSIX
#include <signal.h>
#include <termios.h>
#include <unistd.h>
#endif // POSIX
#include "talk/examples/call/callclient.h"
#include "talk/examples/call/console.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/messagequeue.h"
#include "webrtc/base/stringutils.h"
#ifdef POSIX
static void DoNothing(int unused) {}
#endif
Console::Console(rtc::Thread *thread, CallClient *client) :
client_(client),
client_thread_(thread),
stopped_(false) {}
Console::~Console() {
Stop();
}
void Console::Start() {
if (stopped_) {
// stdin was closed in Stop(), so we can't restart.
LOG(LS_ERROR) << "Cannot re-start";
return;
}
if (console_thread_) {
LOG(LS_WARNING) << "Already started";
return;
}
console_thread_.reset(new rtc::Thread());
console_thread_->Start();
console_thread_->Post(this, MSG_START);
}
void Console::Stop() {
if (console_thread_) {
#ifdef WIN32
CloseHandle(GetStdHandle(STD_INPUT_HANDLE));
#else
close(fileno(stdin));
// This forces the read() in fgets() to return with errno = EINTR. fgets()
// will retry the read() and fail, thus returning.
pthread_kill(console_thread_->GetPThread(), SIGUSR1);
#endif
console_thread_->Stop();
console_thread_.reset();
stopped_ = true;
}
}
void Console::SetEcho(bool on) {
#ifdef WIN32
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
if ((hIn == INVALID_HANDLE_VALUE) || (hIn == NULL))
return;
DWORD mode;
if (!GetConsoleMode(hIn, &mode))
return;
if (on) {
mode = mode | ENABLE_ECHO_INPUT;
} else {
mode = mode & ~ENABLE_ECHO_INPUT;
}
SetConsoleMode(hIn, mode);
#else
const int fd = fileno(stdin);
if (fd == -1)
return;
struct termios tcflags;
if (tcgetattr(fd, &tcflags) == -1)
return;
if (on) {
tcflags.c_lflag |= ECHO;
} else {
tcflags.c_lflag &= ~ECHO;
}
tcsetattr(fd, TCSANOW, &tcflags);
#endif
}
void Console::PrintLine(const char* format, ...) {
va_list ap;
va_start(ap, format);
char buf[4096];
int size = vsnprintf(buf, sizeof(buf), format, ap);
assert(size >= 0);
assert(size < static_cast<int>(sizeof(buf)));
buf[size] = '\0';
printf("%s\n", buf);
fflush(stdout);
va_end(ap);
}
void Console::RunConsole() {
char input_buffer[128];
while (fgets(input_buffer, sizeof(input_buffer), stdin) != NULL) {
client_thread_->Post(this, MSG_INPUT,
new rtc::TypedMessageData<std::string>(input_buffer));
}
}
void Console::OnMessage(rtc::Message *msg) {
switch (msg->message_id) {
case MSG_START:
#ifdef POSIX
// Install a no-op signal so that we can abort RunConsole() by raising
// SIGUSR1.
struct sigaction act;
act.sa_handler = &DoNothing;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGUSR1, &act, NULL) < 0) {
LOG(LS_WARNING) << "Can't install signal";
}
#endif
RunConsole();
break;
case MSG_INPUT:
rtc::TypedMessageData<std::string> *data =
static_cast<rtc::TypedMessageData<std::string>*>(msg->pdata);
client_->ParseLine(data->data());
break;
}
}

View File

@@ -0,0 +1,70 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TALK_EXAMPLES_CALL_CONSOLE_H_
#define TALK_EXAMPLES_CALL_CONSOLE_H_
#include <stdio.h>
#include "webrtc/base/messagequeue.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread.h"
class CallClient;
class Console : public rtc::MessageHandler {
public:
Console(rtc::Thread *thread, CallClient *client);
~Console();
// Starts reading lines from the console and giving them to the CallClient.
void Start();
// Stops reading lines. Cannot be restarted.
void Stop();
virtual void OnMessage(rtc::Message *msg);
void PrintLine(const char* format, ...);
static void SetEcho(bool on);
private:
enum {
MSG_START,
MSG_INPUT,
};
void RunConsole();
void ParseLine(std::string &str);
CallClient *client_;
rtc::Thread *client_thread_;
rtc::scoped_ptr<rtc::Thread> console_thread_;
bool stopped_;
};
#endif // TALK_EXAMPLES_CALL_CONSOLE_H_

View File

@@ -0,0 +1,76 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "talk/examples/call/friendinvitesendtask.h"
#include "webrtc/libjingle/xmpp/constants.h"
namespace buzz {
XmppReturnStatus
FriendInviteSendTask::Send(const Jid& user) {
if (GetState() != STATE_INIT && GetState() != STATE_START)
return XMPP_RETURN_BADSTATE;
// Need to first add to roster, then subscribe to presence.
XmlElement* iq = new XmlElement(QN_IQ);
iq->AddAttr(QN_TYPE, STR_SET);
XmlElement* query = new XmlElement(QN_ROSTER_QUERY);
XmlElement* item = new XmlElement(QN_ROSTER_ITEM);
item->AddAttr(QN_JID, user.Str());
item->AddAttr(QN_NAME, user.node());
query->AddElement(item);
iq->AddElement(query);
QueueStanza(iq);
// Subscribe to presence
XmlElement* presence = new XmlElement(QN_PRESENCE);
presence->AddAttr(QN_TO, user.Str());
presence->AddAttr(QN_TYPE, STR_SUBSCRIBE);
XmlElement* invitation = new XmlElement(QN_INVITATION);
invitation->AddAttr(QN_INVITE_MESSAGE,
"I've been using Google Talk and thought you might like to try it out. "
"We can use it to call each other for free over the internet. Here's an "
"invitation to download Google Talk. Give it a try!");
presence->AddElement(invitation);
QueueStanza(presence);
return XMPP_RETURN_OK;
}
int
FriendInviteSendTask::ProcessStart() {
const XmlElement* stanza = NextStanza();
if (stanza == NULL)
return STATE_BLOCKED;
if (SendStanza(stanza) != XMPP_RETURN_OK)
return STATE_ERROR;
return STATE_START;
}
}

View File

@@ -0,0 +1,49 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FRIENDINVITESENDTASK_H_
#define _FRIENDINVITESENDTASK_H_
#include "webrtc/libjingle/xmpp/xmppengine.h"
#include "webrtc/libjingle/xmpp/xmpptask.h"
namespace buzz {
class FriendInviteSendTask : public XmppTask {
public:
explicit FriendInviteSendTask(XmppTaskParentInterface* parent)
: XmppTask(parent) {}
virtual ~FriendInviteSendTask() {}
XmppReturnStatus Send(const Jid& user);
virtual int ProcessStart();
};
}
#endif

View File

@@ -0,0 +1,81 @@
//
// libjingle
// Copyright 2004--2007, Google Inc.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#include "talk/examples/call/mediaenginefactory.h"
#include "talk/media/base/fakemediaengine.h"
#include "talk/media/base/filemediaengine.h"
#include "talk/media/base/mediaengine.h"
#include "webrtc/base/stringutils.h"
std::vector<cricket::AudioCodec> RequiredAudioCodecs() {
std::vector<cricket::AudioCodec> audio_codecs;
audio_codecs.push_back(
cricket::AudioCodec(9, "G722", 16000, 0, 1, 0));
audio_codecs.push_back(
cricket::AudioCodec(0, "PCMU", 8000, 0, 1, 0));
audio_codecs.push_back(
cricket::AudioCodec(13, "CN", 8000, 0, 1, 0));
audio_codecs.push_back(
cricket::AudioCodec(105, "CN", 16000, 0, 1, 0));
return audio_codecs;
}
std::vector<cricket::VideoCodec> RequiredVideoCodecs() {
std::vector<cricket::VideoCodec> video_codecs;
video_codecs.push_back(
cricket::VideoCodec(97, "H264", 320, 240, 30, 0));
video_codecs.push_back(
cricket::VideoCodec(99, "H264-SVC", 640, 360, 30, 0));
return video_codecs;
}
cricket::MediaEngineInterface* MediaEngineFactory::CreateFileMediaEngine(
const char* voice_in, const char* voice_out,
const char* video_in, const char* video_out) {
cricket::FileMediaEngine* file_media_engine = new cricket::FileMediaEngine;
// Set the RTP dump file names.
if (voice_in) {
file_media_engine->set_voice_input_filename(voice_in);
}
if (voice_out) {
file_media_engine->set_voice_output_filename(voice_out);
}
if (video_in) {
file_media_engine->set_video_input_filename(video_in);
}
if (video_out) {
file_media_engine->set_video_output_filename(video_out);
}
// Set voice and video codecs. TODO: The codecs actually depend on
// the the input voice and video streams.
file_media_engine->set_voice_codecs(RequiredAudioCodecs());
file_media_engine->set_video_codecs(RequiredVideoCodecs());
return file_media_engine;
}

View File

@@ -0,0 +1,40 @@
/*
* libjingle
* Copyright 2011, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TALK_EXAMPLES_CALL_MEDIAENGINEFACTORY_H_
#define TALK_EXAMPLES_CALL_MEDIAENGINEFACTORY_H_
#include "talk/media/base/mediaengine.h"
class MediaEngineFactory {
public:
static cricket::MediaEngineInterface* CreateFileMediaEngine(
const char* voice_in, const char* voice_out,
const char* video_in, const char* video_out);
};
#endif // TALK_EXAMPLES_CALL_MEDIAENGINEFACTORY_H_

66
talk/examples/call/muc.h Normal file
View File

@@ -0,0 +1,66 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MUC_H_
#define _MUC_H_
#include <map>
#include "webrtc/libjingle/xmpp/jid.h"
#include "webrtc/libjingle/xmpp/presencestatus.h"
namespace buzz {
class Muc {
public:
Muc(const Jid& jid, const std::string& nick) : state_(MUC_JOINING),
jid_(jid), local_jid_(Jid(jid.Str() + "/" + nick)) {}
~Muc() {};
enum State { MUC_JOINING, MUC_JOINED, MUC_LEAVING };
State state() const { return state_; }
void set_state(State state) { state_ = state; }
const Jid & jid() const { return jid_; }
const Jid & local_jid() const { return local_jid_; }
typedef std::map<std::string, MucPresenceStatus> MemberMap;
// All the intelligence about how to manage the members is in
// CallClient, so we completely expose the map.
MemberMap& members() {
return members_;
}
private:
State state_;
Jid jid_;
Jid local_jid_;
MemberMap members_;
};
}
#endif

View File

@@ -0,0 +1,124 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "talk/examples/call/mucinviterecvtask.h"
#include "webrtc/libjingle/xmpp/constants.h"
namespace buzz {
const char* types[] = {
"unknown",
"audio",
"video",
};
const char* statuses[] = {
"unknown",
"sendrecv",
"sendonly",
"recvonly",
"inactive",
};
const char*
AvailableMediaEntry::TypeAsString(type_t type) {
// The values of the constants have been chosen such that this is correct.
return types[type];
}
const char*
AvailableMediaEntry::StatusAsString(status_t status) {
// The values of the constants have been chosen such that this is correct.
return statuses[status];
}
int bodytext_to_array_pos(const XmlElement* elem, const char* array[],
int len, int defval = -1) {
if (elem) {
const std::string& body(elem->BodyText());
for (int i = 0; i < len; ++i) {
if (body == array[i]) {
// Found it.
return i;
}
}
}
// If we get here, it's not any value in the array.
return defval;
}
bool
MucInviteRecvTask::HandleStanza(const XmlElement* stanza) {
// Figuring out that we want to handle this is a lot of the work of
// actually handling it, so we handle it right here instead of queueing it.
const XmlElement* xstanza;
const XmlElement* invite;
if (stanza->Name() != QN_MESSAGE) return false;
xstanza = stanza->FirstNamed(QN_MUC_USER_X);
if (!xstanza) return false;
invite = xstanza->FirstNamed(QN_MUC_USER_INVITE);
if (!invite) return false;
// Else it's an invite and we definitely want to handle it. Parse the
// available-media, if any.
std::vector<AvailableMediaEntry> v;
const XmlElement* avail =
invite->FirstNamed(QN_GOOGLE_MUC_USER_AVAILABLE_MEDIA);
if (avail) {
for (const XmlElement* entry = avail->FirstNamed(QN_GOOGLE_MUC_USER_ENTRY);
entry;
entry = entry->NextNamed(QN_GOOGLE_MUC_USER_ENTRY)) {
AvailableMediaEntry tmp;
// In the interest of debugging, we accept as much valid-looking data
// as we can.
tmp.label = atoi(entry->Attr(QN_LABEL).c_str());
tmp.type = static_cast<AvailableMediaEntry::type_t>(
bodytext_to_array_pos(
entry->FirstNamed(QN_GOOGLE_MUC_USER_TYPE),
types,
sizeof(types)/sizeof(const char*),
AvailableMediaEntry::TYPE_UNKNOWN));
tmp.status = static_cast<AvailableMediaEntry::status_t>(
bodytext_to_array_pos(
entry->FirstNamed(QN_GOOGLE_MUC_USER_STATUS),
statuses,
sizeof(statuses)/sizeof(const char*),
AvailableMediaEntry::STATUS_UNKNOWN));
v.push_back(tmp);
}
}
SignalInviteReceived(Jid(invite->Attr(QN_FROM)), Jid(stanza->Attr(QN_FROM)),
v);
return true;
}
int
MucInviteRecvTask::ProcessStart() {
// We never queue anything so we are always blocked.
return STATE_BLOCKED;
}
}

View File

@@ -0,0 +1,82 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MUCINVITERECVTASK_H_
#define _MUCINVITERECVTASK_H_
#include <vector>
#include "webrtc/libjingle/xmpp/xmppengine.h"
#include "webrtc/libjingle/xmpp/xmpptask.h"
#include "webrtc/base/sigslot.h"
namespace buzz {
struct AvailableMediaEntry {
enum type_t {
// SIP defines other media types, but these are the only ones we use in
// multiway jingle.
// These numbers are important; see .cc file
TYPE_UNKNOWN = 0, // indicates invalid string
TYPE_AUDIO = 1,
TYPE_VIDEO = 2,
};
enum status_t {
// These numbers are important; see .cc file
STATUS_UNKNOWN = 0, // indicates invalid string
STATUS_SENDRECV = 1,
STATUS_SENDONLY = 2,
STATUS_RECVONLY = 3,
STATUS_INACTIVE = 4,
};
uint32 label;
type_t type;
status_t status;
static const char* TypeAsString(type_t type);
static const char* StatusAsString(status_t status);
};
class MucInviteRecvTask : public XmppTask {
public:
explicit MucInviteRecvTask(XmppTaskParentInterface* parent)
: XmppTask(parent, XmppEngine::HL_TYPE) {}
virtual int ProcessStart();
// First arg is inviter's JID; second is MUC's JID.
sigslot::signal3<const Jid&, const Jid&, const std::vector<AvailableMediaEntry>& > SignalInviteReceived;
protected:
virtual bool HandleStanza(const XmlElement* stanza);
};
}
#endif

View File

@@ -0,0 +1,63 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "talk/examples/call/mucinvitesendtask.h"
#include "webrtc/libjingle/xmpp/constants.h"
#include "webrtc/libjingle/xmpp/xmppclient.h"
namespace buzz {
XmppReturnStatus
MucInviteSendTask::Send(const Jid& to, const Jid& invitee) {
if (GetState() != STATE_INIT && GetState() != STATE_START)
return XMPP_RETURN_BADSTATE;
XmlElement* message = new XmlElement(QN_MESSAGE);
message->AddAttr(QN_TO, to.Str());
XmlElement* xstanza = new XmlElement(QN_MUC_USER_X);
XmlElement* invite = new XmlElement(QN_MUC_USER_INVITE);
invite->AddAttr(QN_TO, invitee.Str());
xstanza->AddElement(invite);
message->AddElement(xstanza);
QueueStanza(message);
return XMPP_RETURN_OK;
}
int
MucInviteSendTask::ProcessStart() {
const XmlElement* stanza = NextStanza();
if (stanza == NULL)
return STATE_BLOCKED;
if (SendStanza(stanza) != XMPP_RETURN_OK)
return STATE_ERROR;
return STATE_START;
}
}

View File

@@ -0,0 +1,50 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MUCINVITESENDTASK_H_
#define _MUCINVITESENDTASK_H_
#include "talk/examples/call/muc.h"
#include "webrtc/libjingle/xmpp/xmppengine.h"
#include "webrtc/libjingle/xmpp/xmpptask.h"
namespace buzz {
class MucInviteSendTask : public XmppTask {
public:
explicit MucInviteSendTask(XmppTaskParentInterface* parent)
: XmppTask(parent) {}
virtual ~MucInviteSendTask() {}
XmppReturnStatus Send(const Jid& to, const Jid& invitee);
virtual int ProcessStart();
};
}
#endif

View File

@@ -0,0 +1,222 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "talk/examples/call/presencepushtask.h"
#include "talk/examples/call/muc.h"
#include "webrtc/libjingle/xmpp/constants.h"
#include "webrtc/base/stringencode.h"
namespace buzz {
// string helper functions -----------------------------------------------------
static bool
IsXmlSpace(int ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
static bool ListContainsToken(const std::string & list,
const std::string & token) {
size_t i = list.find(token);
if (i == std::string::npos || token.empty())
return false;
bool boundary_before = (i == 0 || IsXmlSpace(list[i - 1]));
bool boundary_after = (i == list.length() - token.length() ||
IsXmlSpace(list[i + token.length()]));
return boundary_before && boundary_after;
}
bool PresencePushTask::HandleStanza(const XmlElement * stanza) {
if (stanza->Name() != QN_PRESENCE)
return false;
QueueStanza(stanza);
return true;
}
static bool IsUtf8FirstByte(int c) {
return (((c)&0x80)==0) || // is single byte
((unsigned char)((c)-0xc0)<0x3e); // or is lead byte
}
int PresencePushTask::ProcessStart() {
const XmlElement * stanza = NextStanza();
if (stanza == NULL)
return STATE_BLOCKED;
Jid from(stanza->Attr(QN_FROM));
std::map<Jid, buzz::Muc*>::const_iterator elem =
client_->mucs().find(from.BareJid());
if (elem == client_->mucs().end()) {
HandlePresence(from, stanza);
} else {
HandleMucPresence(elem->second, from, stanza);
}
return STATE_START;
}
void PresencePushTask::HandlePresence(const Jid& from,
const XmlElement* stanza) {
if (stanza->Attr(QN_TYPE) == STR_ERROR)
return;
PresenceStatus s;
FillStatus(from, stanza, &s);
SignalStatusUpdate(s);
}
void PresencePushTask::HandleMucPresence(buzz::Muc* muc,
const Jid& from,
const XmlElement* stanza) {
if (from == muc->local_jid()) {
if (!stanza->HasAttr(QN_TYPE)) {
// We joined the MUC.
const XmlElement* elem = stanza->FirstNamed(QN_MUC_USER_X);
// Status code=110 or 100 is not guaranteed to be present, so we
// only check the item element and Muc join status.
if (elem) {
if (elem->FirstNamed(QN_MUC_USER_ITEM) &&
muc->state() == buzz::Muc::MUC_JOINING) {
SignalMucJoined(muc->jid());
}
}
} else {
// We've been kicked. Bye.
int error = 0;
if (stanza->Attr(QN_TYPE) == STR_ERROR) {
const XmlElement* elem = stanza->FirstNamed(QN_ERROR);
if (elem && elem->HasAttr(QN_CODE)) {
error = atoi(elem->Attr(QN_CODE).c_str());
}
}
SignalMucLeft(muc->jid(), error);
}
} else {
MucPresenceStatus s;
FillMucStatus(from, stanza, &s);
SignalMucStatusUpdate(muc->jid(), s);
}
}
void PresencePushTask::FillStatus(const Jid& from, const XmlElement* stanza,
PresenceStatus* s) {
s->set_jid(from);
if (stanza->Attr(QN_TYPE) == STR_UNAVAILABLE) {
s->set_available(false);
} else {
s->set_available(true);
const XmlElement * status = stanza->FirstNamed(QN_STATUS);
if (status != NULL) {
s->set_status(status->BodyText());
// Truncate status messages longer than 300 bytes
if (s->status().length() > 300) {
size_t len = 300;
// Be careful not to split legal utf-8 chars in half
while (!IsUtf8FirstByte(s->status()[len]) && len > 0) {
len -= 1;
}
std::string truncated(s->status(), 0, len);
s->set_status(truncated);
}
}
const XmlElement * priority = stanza->FirstNamed(QN_PRIORITY);
if (priority != NULL) {
int pri;
if (rtc::FromString(priority->BodyText(), &pri)) {
s->set_priority(pri);
}
}
const XmlElement * show = stanza->FirstNamed(QN_SHOW);
if (show == NULL || show->FirstChild() == NULL) {
s->set_show(PresenceStatus::SHOW_ONLINE);
}
else {
if (show->BodyText() == "away") {
s->set_show(PresenceStatus::SHOW_AWAY);
}
else if (show->BodyText() == "xa") {
s->set_show(PresenceStatus::SHOW_XA);
}
else if (show->BodyText() == "dnd") {
s->set_show(PresenceStatus::SHOW_DND);
}
else if (show->BodyText() == "chat") {
s->set_show(PresenceStatus::SHOW_CHAT);
}
else {
s->set_show(PresenceStatus::SHOW_ONLINE);
}
}
const XmlElement * caps = stanza->FirstNamed(QN_CAPS_C);
if (caps != NULL) {
std::string node = caps->Attr(QN_NODE);
std::string ver = caps->Attr(QN_VER);
std::string exts = caps->Attr(QN_EXT);
s->set_know_capabilities(true);
s->set_caps_node(node);
s->set_version(ver);
if (ListContainsToken(exts, "voice-v1")) {
s->set_voice_capability(true);
}
if (ListContainsToken(exts, "video-v1")) {
s->set_video_capability(true);
}
}
const XmlElement* delay = stanza->FirstNamed(kQnDelayX);
if (delay != NULL) {
// Ideally we would parse this according to the Psuedo ISO-8601 rules
// that are laid out in JEP-0082:
// http://www.jabber.org/jeps/jep-0082.html
std::string stamp = delay->Attr(kQnStamp);
s->set_sent_time(stamp);
}
const XmlElement* nick = stanza->FirstNamed(QN_NICKNAME);
if (nick) {
s->set_nick(nick->BodyText());
}
}
}
void PresencePushTask::FillMucStatus(const Jid& from, const XmlElement* stanza,
MucPresenceStatus* s) {
FillStatus(from, stanza, s);
}
}

View File

@@ -0,0 +1,70 @@
/*
* libjingle
* Copyright 2004--2005, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _PRESENCEPUSHTASK_H_
#define _PRESENCEPUSHTASK_H_
#include <vector>
#include "talk/examples/call/callclient.h"
#include "webrtc/libjingle/xmpp/presencestatus.h"
#include "webrtc/libjingle/xmpp/xmppengine.h"
#include "webrtc/libjingle/xmpp/xmpptask.h"
#include "webrtc/base/sigslot.h"
namespace buzz {
class PresencePushTask : public XmppTask {
public:
PresencePushTask(XmppTaskParentInterface* parent, CallClient* client)
: XmppTask(parent, XmppEngine::HL_TYPE),
client_(client) {}
virtual int ProcessStart();
sigslot::signal1<const PresenceStatus&> SignalStatusUpdate;
sigslot::signal1<const Jid&> SignalMucJoined;
sigslot::signal2<const Jid&, int> SignalMucLeft;
sigslot::signal2<const Jid&, const MucPresenceStatus&> SignalMucStatusUpdate;
protected:
virtual bool HandleStanza(const XmlElement * stanza);
void HandlePresence(const Jid& from, const XmlElement * stanza);
void HandleMucPresence(buzz::Muc* muc,
const Jid& from, const XmlElement * stanza);
static void FillStatus(const Jid& from, const XmlElement * stanza,
PresenceStatus* status);
static void FillMucStatus(const Jid& from, const XmlElement * stanza,
MucPresenceStatus* status);
private:
CallClient* client_;
};
}
#endif