Review URL: http://webrtc-codereview.appspot.com/315003
git-svn-id: http://libjingle.googlecode.com/svn/trunk@100 dd674b97-3498-5ee5-1854-bdd07cd0ff33
diff --git a/CHANGELOG b/CHANGELOG
index 16d7ed6..cacbc90 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,10 @@
Libjingle
+0.6.5 - Dec 12, 2011
+ - Add IPv6 support in SocketAddress.
+ - Change PeerConnectionFactory inteface.
+ - Bug fixes.
+
0.6.4 - Nov 30, 2011
- Branch app/webrtc to app/webrtcv1.
- Add more base unit tests.
diff --git a/talk/app/webrtc/peerconnectionfactory.cc b/talk/app/webrtc/peerconnectionfactory.cc
index 1b40c14..a3dac39 100644
--- a/talk/app/webrtc/peerconnectionfactory.cc
+++ b/talk/app/webrtc/peerconnectionfactory.cc
@@ -35,22 +35,18 @@
namespace webrtc {
PeerConnectionFactory::PeerConnectionFactory(
- cricket::PortAllocator* port_allocator,
cricket::MediaEngineInterface* media_engine,
cricket::DeviceManagerInterface* device_manager,
talk_base::Thread* worker_thread)
: initialized_(false),
- port_allocator_(port_allocator),
channel_manager_(new cricket::ChannelManager(media_engine,
device_manager,
worker_thread)) {
}
PeerConnectionFactory::PeerConnectionFactory(
- cricket::PortAllocator* port_allocator,
talk_base::Thread* worker_thread)
: initialized_(false),
- port_allocator_(port_allocator),
channel_manager_(new cricket::ChannelManager(worker_thread)) {
}
@@ -64,11 +60,12 @@
}
PeerConnection* PeerConnectionFactory::CreatePeerConnection(
+ cricket::PortAllocator* port_allocator,
talk_base::Thread* signaling_thread) {
PeerConnectionProxy* pc = NULL;
if (initialized_) {
pc = new PeerConnectionProxy(
- port_allocator_.get(), channel_manager_.get(), signaling_thread);
+ port_allocator, channel_manager_.get(), signaling_thread);
if (!pc->Init()) {
LOG(LERROR) << "Error in initializing PeerConnection";
delete pc;
diff --git a/talk/app/webrtc/peerconnectionfactory.h b/talk/app/webrtc/peerconnectionfactory.h
index 7c65e05..ea509d6 100644
--- a/talk/app/webrtc/peerconnectionfactory.h
+++ b/talk/app/webrtc/peerconnectionfactory.h
@@ -51,21 +51,20 @@
class PeerConnectionFactory {
public:
- PeerConnectionFactory(cricket::PortAllocator* port_allocator,
- cricket::MediaEngineInterface* media_engine,
+ PeerConnectionFactory(cricket::MediaEngineInterface* media_engine,
cricket::DeviceManagerInterface* device_manager,
talk_base::Thread* worker_thread);
- PeerConnectionFactory(cricket::PortAllocator* port_allocator,
- talk_base::Thread* worker_thread);
+ PeerConnectionFactory(talk_base::Thread* worker_thread);
virtual ~PeerConnectionFactory();
bool Initialize();
- PeerConnection* CreatePeerConnection(talk_base::Thread* signaling_thread);
+ PeerConnection* CreatePeerConnection(
+ cricket::PortAllocator* port_allocator,
+ talk_base::Thread* signaling_thread);
private:
bool initialized_;
- talk_base::scoped_ptr<cricket::PortAllocator> port_allocator_;
talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
};
diff --git a/talk/app/webrtc/webrtcsession_unittest.cc b/talk/app/webrtc/webrtcsession_unittest.cc
index 7a07614..85339c0 100644
--- a/talk/app/webrtc/webrtcsession_unittest.cc
+++ b/talk/app/webrtc/webrtcsession_unittest.cc
@@ -36,10 +36,10 @@
#include "talk/base/fakenetwork.h"
#include "talk/base/scoped_ptr.h"
#include "talk/base/thread.h"
+#include "talk/p2p/base/fakesession.h"
#include "talk/p2p/base/portallocator.h"
#include "talk/p2p/base/sessiondescription.h"
#include "talk/p2p/client/fakeportallocator.h"
-#include "talk/session/phone/fakesession.h"
#include "talk/session/phone/mediasessionclient.h"
class WebRtcSessionTest
diff --git a/talk/app/webrtcv1/peerconnectionfactory.cc b/talk/app/webrtcv1/peerconnectionfactory.cc
index ab2e0d5..7bf2f89 100644
--- a/talk/app/webrtcv1/peerconnectionfactory.cc
+++ b/talk/app/webrtcv1/peerconnectionfactory.cc
@@ -35,22 +35,18 @@
namespace webrtc {
PeerConnectionFactory::PeerConnectionFactory(
- cricket::PortAllocator* port_allocator,
cricket::MediaEngineInterface* media_engine,
cricket::DeviceManagerInterface* device_manager,
talk_base::Thread* worker_thread)
: initialized_(false),
- port_allocator_(port_allocator),
channel_manager_(new cricket::ChannelManager(media_engine,
device_manager,
worker_thread)) {
}
PeerConnectionFactory::PeerConnectionFactory(
- cricket::PortAllocator* port_allocator,
talk_base::Thread* worker_thread)
: initialized_(false),
- port_allocator_(port_allocator),
channel_manager_(new cricket::ChannelManager(worker_thread)) {
}
@@ -64,11 +60,12 @@
}
PeerConnection* PeerConnectionFactory::CreatePeerConnection(
+ cricket::PortAllocator* port_allocator,
talk_base::Thread* signaling_thread) {
PeerConnectionProxy* pc = NULL;
if (initialized_) {
pc = new PeerConnectionProxy(
- port_allocator_.get(), channel_manager_.get(), signaling_thread);
+ port_allocator, channel_manager_.get(), signaling_thread);
if (!pc->Init()) {
LOG(LERROR) << "Error in initializing PeerConnection";
delete pc;
diff --git a/talk/app/webrtcv1/peerconnectionfactory.h b/talk/app/webrtcv1/peerconnectionfactory.h
index 7c65e05..ea509d6 100644
--- a/talk/app/webrtcv1/peerconnectionfactory.h
+++ b/talk/app/webrtcv1/peerconnectionfactory.h
@@ -51,21 +51,20 @@
class PeerConnectionFactory {
public:
- PeerConnectionFactory(cricket::PortAllocator* port_allocator,
- cricket::MediaEngineInterface* media_engine,
+ PeerConnectionFactory(cricket::MediaEngineInterface* media_engine,
cricket::DeviceManagerInterface* device_manager,
talk_base::Thread* worker_thread);
- PeerConnectionFactory(cricket::PortAllocator* port_allocator,
- talk_base::Thread* worker_thread);
+ PeerConnectionFactory(talk_base::Thread* worker_thread);
virtual ~PeerConnectionFactory();
bool Initialize();
- PeerConnection* CreatePeerConnection(talk_base::Thread* signaling_thread);
+ PeerConnection* CreatePeerConnection(
+ cricket::PortAllocator* port_allocator,
+ talk_base::Thread* signaling_thread);
private:
bool initialized_;
- talk_base::scoped_ptr<cricket::PortAllocator> port_allocator_;
talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
};
diff --git a/talk/app/webrtcv1/webrtcsession_unittest.cc b/talk/app/webrtcv1/webrtcsession_unittest.cc
index c8940d6..2c23d6a 100644
--- a/talk/app/webrtcv1/webrtcsession_unittest.cc
+++ b/talk/app/webrtcv1/webrtcsession_unittest.cc
@@ -36,10 +36,10 @@
#include "talk/base/fakenetwork.h"
#include "talk/base/scoped_ptr.h"
#include "talk/base/thread.h"
+#include "talk/p2p/base/fakesession.h"
#include "talk/p2p/base/portallocator.h"
#include "talk/p2p/base/sessiondescription.h"
#include "talk/p2p/client/fakeportallocator.h"
-#include "talk/session/phone/fakesession.h"
#include "talk/session/phone/mediasessionclient.h"
class WebRtcSessionTest
diff --git a/talk/base/autodetectproxy.cc b/talk/base/autodetectproxy.cc
index f79926d..37faa4d 100644
--- a/talk/base/autodetectproxy.cc
+++ b/talk/base/autodetectproxy.cc
@@ -107,7 +107,7 @@
proxy().address.hostname(),
sizeof address_hostname);
- uint32 address_ip = proxy().address.ip();
+ IPAddress address_ip = proxy().address.ipaddr();
uint16 address_port = proxy().address.port();
diff --git a/talk/base/basicpacketsocketfactory.cc b/talk/base/basicpacketsocketfactory.cc
index 42721ba..d1da08e 100644
--- a/talk/base/basicpacketsocketfactory.cc
+++ b/talk/base/basicpacketsocketfactory.cc
@@ -157,7 +157,8 @@
} else {
// Otherwise, try to find a port in the provided range.
for (int port = min_port; ret < 0 && port <= max_port; ++port) {
- ret = socket->Bind(talk_base::SocketAddress(local_address.ip(), port));
+ ret = socket->Bind(talk_base::SocketAddress(local_address.ipaddr(),
+ port));
}
}
return ret;
diff --git a/talk/base/fakenetwork.h b/talk/base/fakenetwork.h
index 67df88a..c5ae4b6 100644
--- a/talk/base/fakenetwork.h
+++ b/talk/base/fakenetwork.h
@@ -52,7 +52,7 @@
void AddInterface(const SocketAddress& iface) {
// ensure a unique name for the interface
SocketAddress address("test" + talk_base::ToString(next_index_++), 0);
- address.SetResolvedIP(iface.ip());
+ address.SetResolvedIP(iface.ipaddr());
ifaces_.push_back(address);
DoUpdateNetworks();
}
@@ -89,7 +89,8 @@
std::vector<Network*> networks;
for (std::vector<SocketAddress>::iterator it = ifaces_.begin();
it != ifaces_.end(); ++it) {
- networks.push_back(new Network(it->hostname(), it->hostname(), it->ip()));
+ networks.push_back(new Network(it->hostname(), it->hostname(),
+ it->ipaddr()));
}
MergeNetworkList(networks, true);
}
diff --git a/talk/base/fileutils.cc b/talk/base/fileutils.cc
index 4504d29..7b0d348 100644
--- a/talk/base/fileutils.cc
+++ b/talk/base/fileutils.cc
@@ -154,15 +154,17 @@
#endif
}
-scoped_ptr<FilesystemInterface> Filesystem::default_filesystem_;
+FilesystemInterface* Filesystem::default_filesystem_ = NULL;
+
FilesystemInterface *Filesystem::EnsureDefaultFilesystem() {
- if (!default_filesystem_.get())
+ if (!default_filesystem_) {
#ifdef WIN32
- default_filesystem_.reset(new Win32Filesystem());
+ default_filesystem_ = new Win32Filesystem();
#else
- default_filesystem_.reset(new UnixFilesystem());
+ default_filesystem_ = new UnixFilesystem();
#endif
- return default_filesystem_.get();
+ }
+ return default_filesystem_;
}
bool FilesystemInterface::CopyFolder(const Pathname &old_path,
diff --git a/talk/base/fileutils.h b/talk/base/fileutils.h
index 644516d..186c963 100644
--- a/talk/base/fileutils.h
+++ b/talk/base/fileutils.h
@@ -285,18 +285,18 @@
class Filesystem {
public:
static FilesystemInterface *default_filesystem() {
- ASSERT(default_filesystem_.get() != NULL);
- return default_filesystem_.get();
+ ASSERT(default_filesystem_ != NULL);
+ return default_filesystem_;
}
static void set_default_filesystem(FilesystemInterface *filesystem) {
- default_filesystem_.reset(filesystem);
+ default_filesystem_ = filesystem;
}
static FilesystemInterface *swap_default_filesystem(
FilesystemInterface *filesystem) {
- FilesystemInterface *cur = default_filesystem_.release();
- default_filesystem_.reset(filesystem);
+ FilesystemInterface *cur = default_filesystem_;
+ default_filesystem_ = filesystem;
return cur;
}
@@ -425,7 +425,7 @@
}
private:
- static scoped_ptr<FilesystemInterface> default_filesystem_;
+ static FilesystemInterface* default_filesystem_;
static FilesystemInterface *EnsureDefaultFilesystem();
DISALLOW_IMPLICIT_CONSTRUCTORS(Filesystem);
@@ -455,4 +455,3 @@
} // namespace talk_base
#endif // TALK_BASE_FILEUTILS_H_
-
diff --git a/talk/base/firewallsocketserver.cc b/talk/base/firewallsocketserver.cc
index a99c72e..71385f8 100644
--- a/talk/base/firewallsocketserver.cc
+++ b/talk/base/firewallsocketserver.cc
@@ -177,11 +177,11 @@
const Rule& r = rules_[i];
if ((r.p != p) && (r.p != FP_ANY))
continue;
- if ((r.src.ip() != src.ip()) && !r.src.IsAny())
+ if ((r.src.ipaddr() != src.ipaddr()) && !r.src.IsAny())
continue;
if ((r.src.port() != src.port()) && (r.src.port() != 0))
continue;
- if ((r.dst.ip() != dst.ip()) && !r.dst.IsAny())
+ if ((r.dst.ipaddr() != dst.ipaddr()) && !r.dst.IsAny())
continue;
if ((r.dst.port() != dst.port()) && (r.dst.port() != 0))
continue;
diff --git a/talk/base/helpers.cc b/talk/base/helpers.cc
index 1abaa2d..855305e 100644
--- a/talk/base/helpers.cc
+++ b/talk/base/helpers.cc
@@ -205,8 +205,8 @@
// This round about way of creating a global RNG is to safe-guard against
// indeterminant static initialization order.
-scoped_ptr<RandomGenerator>& GetGlobalRng() {
- static scoped_ptr<RandomGenerator> g_rng(new SecureRandomGenerator());
+RandomGenerator*& GetGlobalRng() {
+ static RandomGenerator* g_rng = new SecureRandomGenerator();
return g_rng;
}
@@ -218,9 +218,9 @@
void SetRandomTestMode(bool test) {
if (!test) {
- GetGlobalRng().reset(new SecureRandomGenerator());
+ GetGlobalRng() = new SecureRandomGenerator();
} else {
- GetGlobalRng().reset(new TestRandomGenerator());
+ GetGlobalRng() = new TestRandomGenerator();
}
}
diff --git a/talk/base/macasyncsocket.cc b/talk/base/macasyncsocket.cc
index e31be57..4924333 100644
--- a/talk/base/macasyncsocket.cc
+++ b/talk/base/macasyncsocket.cc
@@ -328,9 +328,11 @@
}
if (res) {
- // Add this socket to the run loop
- source_ = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket_, 0);
+ // Add this socket to the run loop, at priority 1 so that it will be
+ // queued behind any pending signals.
+ source_ = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket_, 1);
res = (source_ != NULL);
+ if (!res) errno = EINVAL;
}
if (res) {
diff --git a/talk/base/macsocketserver.cc b/talk/base/macsocketserver.cc
index 154b83d..5b2ec03 100644
--- a/talk/base/macsocketserver.cc
+++ b/talk/base/macsocketserver.cc
@@ -41,6 +41,47 @@
ASSERT(found == 1);
}
+bool MacBaseSocketServer::SetPosixSignalHandler(int signum,
+ void (*handler)(int)) {
+ Dispatcher* dispatcher = signal_dispatcher();
+ if (!PhysicalSocketServer::SetPosixSignalHandler(signum, handler)) {
+ return false;
+ }
+
+ // Only register the FD once, when the first custom handler is installed.
+ if (!dispatcher && (dispatcher = signal_dispatcher())) {
+ CFFileDescriptorContext ctx = { 0 };
+ ctx.info = this;
+
+ CFFileDescriptorRef desc = CFFileDescriptorCreate(
+ kCFAllocatorDefault,
+ dispatcher->GetDescriptor(),
+ false,
+ &MacBaseSocketServer::FileDescriptorCallback,
+ &ctx);
+ if (!desc) {
+ return false;
+ }
+
+ CFFileDescriptorEnableCallBacks(desc, kCFFileDescriptorReadCallBack);
+ CFRunLoopSourceRef ref =
+ CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, desc, 0);
+
+ if (!ref) {
+ CFRelease(desc);
+ return false;
+ }
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), ref, kCFRunLoopCommonModes);
+ CFRelease(desc);
+ CFRelease(ref);
+ }
+
+ return true;
+}
+
+// Used to disable socket events from waking our message queue when
+// process_io is false. Does not disable signal event handling though.
void MacBaseSocketServer::EnableSocketCallbacks(bool enable) {
for (std::set<MacAsyncSocket*>::iterator it = sockets().begin();
it != sockets().end(); ++it) {
@@ -52,6 +93,21 @@
}
}
+void MacBaseSocketServer::FileDescriptorCallback(CFFileDescriptorRef fd,
+ CFOptionFlags flags,
+ void* context) {
+ MacBaseSocketServer* this_ss =
+ reinterpret_cast<MacBaseSocketServer*>(context);
+ ASSERT(this_ss);
+ Dispatcher* signal_dispatcher = this_ss->signal_dispatcher();
+ ASSERT(signal_dispatcher);
+
+ signal_dispatcher->OnPreEvent(DE_READ);
+ signal_dispatcher->OnEvent(DE_READ, 0);
+ CFFileDescriptorEnableCallBacks(fd, kCFFileDescriptorReadCallBack);
+}
+
+
///////////////////////////////////////////////////////////////////////////////
// MacCFSocketServer
///////////////////////////////////////////////////////////////////////////////
@@ -225,6 +281,9 @@
// MacCarbonAppSocketServer
///////////////////////////////////////////////////////////////////////////////
+// Carbon is deprecated for x64. Switch to Cocoa
+#if !defined(__x86_64__)
+
MacCarbonAppSocketServer::MacCarbonAppSocketServer()
: event_queue_(GetCurrentEventQueue()) {
// Install event handler
@@ -296,6 +355,7 @@
}
ReleaseEvent(wake_up);
}
+#endif
///////////////////////////////////////////////////////////////////////////////
// MacNotificationsSocketServer
diff --git a/talk/base/macsocketserver.h b/talk/base/macsocketserver.h
index 6a4a729..53118b8 100644
--- a/talk/base/macsocketserver.h
+++ b/talk/base/macsocketserver.h
@@ -31,6 +31,9 @@
void RegisterSocket(MacAsyncSocket* socket);
void UnregisterSocket(MacAsyncSocket* socket);
+ // PhysicalSocketServer Overrides
+ virtual bool SetPosixSignalHandler(int signum, void (*handler)(int));
+
protected:
void EnableSocketCallbacks(bool enable);
const std::set<MacAsyncSocket*>& sockets() {
@@ -38,6 +41,10 @@
}
private:
+ static void FileDescriptorCallback(CFFileDescriptorRef ref,
+ CFOptionFlags flags,
+ void* context);
+
std::set<MacAsyncSocket*> sockets_;
};
diff --git a/talk/base/nat_unittest.cc b/talk/base/nat_unittest.cc
index 3a2c778..a7fc3b1 100644
--- a/talk/base/nat_unittest.cc
+++ b/talk/base/nat_unittest.cc
@@ -195,7 +195,9 @@
SocketAddress int_addr("127.0.0.1", 0);
std::string ext_ip1 = "127.0.0.1";
- std::string ext_ip2 = SocketAddress::IPToString(networks[0]->ip());
+ std::string ext_ip2 = networks[0]->ip().ToString();
+
+ LOG(LS_INFO) << "selected ip " << ext_ip2;
SocketAddress ext_addrs[4] = {
SocketAddress(ext_ip1, 0),
@@ -226,11 +228,11 @@
new PhysicalSocketServer());
SocketAddress int_addr, ext_addrs[4];
- int_addr.SetIP(int_vss->GetNextIP());
- ext_addrs[0].SetIP(ext_vss->GetNextIP());
- ext_addrs[1].SetIP(ext_vss->GetNextIP());
- ext_addrs[2].SetIP(ext_addrs[0].ip());
- ext_addrs[3].SetIP(ext_addrs[1].ip());
+ int_addr.SetIP(IPAddress(int_vss->GetNextIP()));
+ ext_addrs[0].SetIP(IPAddress(ext_vss->GetNextIP()));
+ ext_addrs[1].SetIP(IPAddress(ext_vss->GetNextIP()));
+ ext_addrs[2].SetIP(ext_addrs[0].ipaddr());
+ ext_addrs[3].SetIP(ext_addrs[1].ipaddr());
TestBindings(int_vss, int_addr, ext_vss, ext_addrs);
TestFilters(int_vss, int_addr, ext_vss, ext_addrs);
diff --git a/talk/base/network.cc b/talk/base/network.cc
index d6ecbbf..9d1a83d 100644
--- a/talk/base/network.cc
+++ b/talk/base/network.cc
@@ -166,7 +166,7 @@
struct sockaddr_in* inaddr =
reinterpret_cast<struct sockaddr_in*>(&ptr->ifr_ifru.ifru_addr);
if (inaddr->sin_family == AF_INET) {
- uint32 ip = ntohl(inaddr->sin_addr.s_addr);
+ IPAddress ip(inaddr->sin_addr);
scoped_ptr<Network> network(
new Network(ptr->ifr_name, ptr->ifr_name, ip));
network->set_ignored(IsIgnoredNetwork(*network));
@@ -201,6 +201,8 @@
scoped_array<char> buf(new char[len]);
IP_ADAPTER_INFO *infos = reinterpret_cast<IP_ADAPTER_INFO *>(buf.get());
+ // TODO: GetAdaptersInfo is IPv4 only. Replace with GetAddressesInfo when
+ // IPv6 support is needed in Network.
DWORD ret = GetAdaptersInfo(infos, &len);
if (ret != NO_ERROR) {
LOG_ERR_EX(LS_ERROR, ret) << "GetAdaptersInfo failed";
@@ -225,12 +227,13 @@
name = ost.str();
count++;
#endif // !_DEBUG
-
- scoped_ptr<Network> network(new Network(name, info->Description,
- SocketAddress::StringToIP(info->IpAddressList.IpAddress.String)));
- network->set_ignored(IsIgnoredNetwork(*network));
- if (include_ignored || !network->ignored()) {
- networks->push_back(network.release());
+ IPAddress ip;
+ if (IPFromString(info->IpAddressList.IpAddress.String, &ip)) {
+ scoped_ptr<Network> network(new Network(name, info->Description, ip));
+ network->set_ignored(IsIgnoredNetwork(*network));
+ if (include_ignored || !network->ignored()) {
+ networks->push_back(network.release());
+ }
}
}
@@ -257,7 +260,10 @@
#endif
// Ignore any networks with a 0.x.y.z IP
- return (network.ip() < 0x01000000);
+ if (network.ip().family() == AF_INET) {
+ return (network.ip().v4AddressAsHostOrderInteger() < 0x01000000);
+ }
+ return false;
}
void BasicNetworkManager::StartUpdating() {
@@ -312,7 +318,8 @@
}
}
-Network::Network(const std::string& name, const std::string& desc, uint32 ip)
+Network::Network(const std::string& name, const std::string& desc,
+ const IPAddress& ip)
: name_(name), description_(desc), ip_(ip), ignored_(false),
uniform_numerator_(0), uniform_denominator_(0),
exponential_numerator_(0), exponential_denominator_(0) {
@@ -323,7 +330,7 @@
// Print out the first space-terminated token of the network desc, plus
// the IP address.
ss << "Net[" << description_.substr(0, description_.find(' '))
- << ":" << SocketAddress::IPToString(ip_) << "]";
+ << ":" << ip_ << "]";
return ss.str();
}
diff --git a/talk/base/network.h b/talk/base/network.h
index 10b4bec..bb5f15d 100644
--- a/talk/base/network.h
+++ b/talk/base/network.h
@@ -34,6 +34,7 @@
#include <vector>
#include "talk/base/basictypes.h"
+#include "talk/base/ipaddress.h"
#include "talk/base/messagehandler.h"
#include "talk/base/sigslot.h"
@@ -135,7 +136,10 @@
// Represents a Unix-type network interface, with a name and single address.
class Network {
public:
- Network(const std::string& name, const std::string& description, uint32 ip);
+ Network() : ip_(INADDR_ANY) {}
+
+ Network(const std::string& name, const std::string& description,
+ const IPAddress& ip);
// Returns the index of this network. This is considered the primary key
// that identifies each network.
@@ -146,8 +150,8 @@
const std::string& description() const { return description_; }
// Identifies the current IP address used by this network.
- uint32 ip() const { return ip_; }
- void set_ip(uint32 ip) { ip_ = ip; }
+ const IPAddress& ip() const { return ip_; }
+ void set_ip(const IPAddress& ip) { ip_ = ip; }
// Indicates whether this network should be ignored, perhaps because
// the IP is 0, or the interface is one we know is invalid.
@@ -162,7 +166,7 @@
std::string name_;
std::string description_;
- uint32 ip_;
+ IPAddress ip_;
bool ignored_;
SessionList sessions_;
double uniform_numerator_;
diff --git a/talk/base/network_unittest.cc b/talk/base/network_unittest.cc
index 4bec4a3..d48abbb 100644
--- a/talk/base/network_unittest.cc
+++ b/talk/base/network_unittest.cc
@@ -32,9 +32,11 @@
namespace talk_base {
// A network that should not be ignored.
-static const Network kNetwork1("test1", "Test Network Adapter 1", 0x12345678);
+static const Network kNetwork1("test1", "Test Network Adapter 1",
+ IPAddress(0x12345678));
// A network that should be ignored (IP is 0.1.0.4).
-static const Network kNetwork2("test2", "Test Network Adapter 2", 0x00010004);
+static const Network kNetwork2("test2", "Test Network Adapter 2",
+ IPAddress(0x00010004));
class NetworkTest : public testing::Test, public sigslot::has_slots<> {
public:
@@ -56,6 +58,13 @@
return BasicNetworkManager::IsIgnoredNetwork(network);
}
+ NetworkManager::NetworkList GetNetworks(
+ const BasicNetworkManager& network_manager, bool include_ignored) {
+ NetworkManager::NetworkList list;
+ network_manager.CreateNetworks(include_ignored, &list);
+ return list;
+ }
+
protected:
bool callback_called_;
};
@@ -64,7 +73,7 @@
TEST_F(NetworkTest, TestNetworkConstruct) {
EXPECT_EQ("test1", kNetwork1.name());
EXPECT_EQ("Test Network Adapter 1", kNetwork1.description());
- EXPECT_EQ(0x12345678U, kNetwork1.ip());
+ EXPECT_EQ(IPAddress(0x12345678U), kNetwork1.ip());
EXPECT_FALSE(kNetwork1.ignored());
}
@@ -74,6 +83,41 @@
EXPECT_TRUE(IsIgnoredNetwork(kNetwork2));
}
+TEST_F(NetworkTest, TestCreateNetworks) {
+ BasicNetworkManager manager;
+ NetworkManager::NetworkList result = GetNetworks(manager, true);
+ // We should be able to bind to any addresses we find.
+ // (Excluding IPv6 link-local for now, as we don't (yet) record scope ids.)
+ NetworkManager::NetworkList::iterator it;
+ for (it = result.begin();
+ it != result.end();
+ ++it) {
+ sockaddr_storage storage;
+ memset(&storage, 0, sizeof(storage));
+ IPAddress ip = (*it)->ip();
+ // This condition excludes FE80::/16, i.e. IPv6 link-local addresses. These
+ // require their scope id to be known. Remove when scope ids are supported.
+ if (!(ip.family() == AF_INET6 && IPIsPrivate(ip) && !IPIsLoopback(ip))) {
+ SocketAddress bindaddress(ip, 0);
+ // TODO: Make this use talk_base::AsyncSocket once it supports IPv6.
+ int fd = socket(ip.family(), SOCK_STREAM, IPPROTO_TCP);
+ if (fd > 0) {
+ size_t ipsize = bindaddress.ToSockAddrStorage(&storage);
+ EXPECT_GE(ipsize, 0U);
+ int success = ::bind(fd,
+ reinterpret_cast<sockaddr*>(&storage),
+ ipsize);
+ EXPECT_EQ(0, success);
+#ifdef WIN32
+ closesocket(fd);
+#else
+ close(fd);
+#endif
+ }
+ }
+ }
+}
+
// Test that UpdateNetworks succeeds.
TEST_F(NetworkTest, TestUpdateNetworks) {
BasicNetworkManager manager;
diff --git a/talk/base/physicalsocketserver.cc b/talk/base/physicalsocketserver.cc
index f18e4ae..10d534f 100644
--- a/talk/base/physicalsocketserver.cc
+++ b/talk/base/physicalsocketserver.cc
@@ -1409,6 +1409,10 @@
return true;
}
+Dispatcher* PhysicalSocketServer::signal_dispatcher() {
+ return signal_dispatcher_.get();
+}
+
bool PhysicalSocketServer::InstallSignal(int signum, void (*handler)(int)) {
struct sigaction act;
// It doesn't really matter what we set this mask to.
diff --git a/talk/base/physicalsocketserver.h b/talk/base/physicalsocketserver.h
index aeb8348..1b7a298 100644
--- a/talk/base/physicalsocketserver.h
+++ b/talk/base/physicalsocketserver.h
@@ -2,26 +2,26 @@
* libjingle
* Copyright 2004--2005, Google Inc.
*
- * Redistribution and use in source and binary forms, with or without
+ * 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,
+ * 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
+ * 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
+ * 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,
+ * 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
+ * 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.
*/
@@ -73,7 +73,7 @@
// A socket server that provides the real sockets of the underlying OS.
class PhysicalSocketServer : public SocketServer {
-public:
+ public:
PhysicalSocketServer();
virtual ~PhysicalSocketServer();
@@ -104,10 +104,13 @@
// Dispatching signals on multiple PhysicalSocketServers is not reliable.
// The signal mask is not modified. It is the caller's responsibily to
// maintain it as desired.
- bool SetPosixSignalHandler(int signum, void (*handler)(int));
+ virtual bool SetPosixSignalHandler(int signum, void (*handler)(int));
+
+ protected:
+ Dispatcher* signal_dispatcher();
#endif
-private:
+ private:
typedef std::vector<Dispatcher*> DispatcherList;
typedef std::vector<size_t*> IteratorList;
diff --git a/talk/base/proxydetect.cc b/talk/base/proxydetect.cc
index 66213ee..4bfae29 100644
--- a/talk/base/proxydetect.cc
+++ b/talk/base/proxydetect.cc
@@ -233,7 +233,9 @@
m = 0;
uint32 mask = (m == 0) ? 0 : (~0UL) << (32 - m);
SocketAddress addr(url.host(), 0);
- return !addr.IsUnresolved() && ((addr.ip() & mask) == (ip & mask));
+ // TODO: Support IPv6 proxyitems. This code block is IPv4 only anyway.
+ return !addr.IsUnresolved() &&
+ ((addr.ipaddr().v4AddressAsHostOrderInteger() & mask) == (ip & mask));
}
// .foo.com
diff --git a/talk/base/proxyserver.cc b/talk/base/proxyserver.cc
index 3cdf598..d764fd7 100644
--- a/talk/base/proxyserver.cc
+++ b/talk/base/proxyserver.cc
@@ -36,7 +36,7 @@
ProxyServer::ProxyServer(
SocketFactory* int_factory, const SocketAddress& int_addr,
SocketFactory* ext_factory, const SocketAddress& ext_ip)
- : ext_factory_(ext_factory), ext_ip_(ext_ip.ip(), 0), // strip off any port
+ : ext_factory_(ext_factory), ext_ip_(ext_ip.ipaddr(), 0), // strip off port
server_socket_(int_factory->CreateAsyncSocket(SOCK_STREAM)) {
server_socket_->Bind(int_addr);
server_socket_->Listen(5);
diff --git a/talk/base/socket_unittest.cc b/talk/base/socket_unittest.cc
index d5c4a3b..8d5b3c5 100644
--- a/talk/base/socket_unittest.cc
+++ b/talk/base/socket_unittest.cc
@@ -37,7 +37,7 @@
namespace talk_base {
static const SocketAddress kEmptyAddr;
-static const SocketAddress kLoopbackAddr(INADDR_LOOPBACK, 0);
+static const SocketAddress kLoopbackAddr(IPAddress(INADDR_LOOPBACK), 0);
void SocketTest::TestConnect() {
testing::StreamSink sink;
@@ -153,7 +153,7 @@
// Attempt connect to a non-existent socket.
// We don't connect to the server socket created above, since on
// MacOS it takes about 75 seconds to get back an error!
- SocketAddress bogus_addr(INADDR_LOOPBACK, 65535);
+ SocketAddress bogus_addr(IPAddress(INADDR_LOOPBACK), 65535);
EXPECT_EQ(0, client->Connect(bogus_addr));
// Wait for connection to fail (ECONNREFUSED).
@@ -664,7 +664,7 @@
SocketAddress addr4;
EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
- EXPECT_EQ(addr4.ip(), addr2.ip());
+ EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
SocketAddress addr5;
EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
diff --git a/talk/base/socketaddress.cc b/talk/base/socketaddress.cc
index 71ed674..42143f5 100644
--- a/talk/base/socketaddress.cc
+++ b/talk/base/socketaddress.cc
@@ -362,7 +362,7 @@
return true;
}
-static void ToSockAddrStorageHelper(sockaddr_storage* addr,
+static size_t ToSockAddrStorageHelper(sockaddr_storage* addr,
IPAddress ip, int port) {
memset(addr, 0, sizeof(sockaddr_storage));
addr->ss_family = ip.family();
@@ -370,19 +370,22 @@
sockaddr_in6* saddr = reinterpret_cast<sockaddr_in6*>(addr);
saddr->sin6_addr = ip.ipv6_address();
saddr->sin6_port = HostToNetwork16(port);
- } else {
+ return sizeof(sockaddr_in6);
+ } else if (addr->ss_family == AF_INET) {
sockaddr_in* saddr = reinterpret_cast<sockaddr_in*>(addr);
saddr->sin_addr = ip.ipv4_address();
saddr->sin_port = HostToNetwork16(port);
+ return sizeof(sockaddr_in);
}
+ return 0;
}
-void SocketAddress::ToDualStackSockAddrStorage(sockaddr_storage *addr) const {
- ToSockAddrStorageHelper(addr, ip_.AsIPv6Address(), port_);
+size_t SocketAddress::ToDualStackSockAddrStorage(sockaddr_storage *addr) const {
+ return ToSockAddrStorageHelper(addr, ip_.AsIPv6Address(), port_);
}
-void SocketAddress::ToSockAddrStorage(sockaddr_storage* addr) const {
- ToSockAddrStorageHelper(addr, ip_, port_);
+size_t SocketAddress::ToSockAddrStorage(sockaddr_storage* addr) const {
+ return ToSockAddrStorageHelper(addr, ip_, port_);
}
std::string SocketAddress::IPToString(uint32 ip_as_host_order_integer) {
@@ -437,27 +440,6 @@
return "";
}
-bool SocketAddress::GetLocalIPs(std::vector<uint32>& ips) {
- ips.clear();
-
- const std::string hostname = GetHostname();
- if (hostname.empty())
- return false;
-
- int errcode;
- if (hostent* pHost = SafeGetHostByName(hostname.c_str(), &errcode)) {
- for (size_t i = 0; pHost->h_addr_list[i]; ++i) {
- uint32 ip =
- NetworkToHost32(*reinterpret_cast<uint32 *>(pHost->h_addr_list[i]));
- ips.push_back(ip);
- }
- FreeHostEnt(pHost);
- return !ips.empty();
- }
- LOG(LS_ERROR) << "gethostbyname err: " << errcode;
- return false;
-}
-
bool SocketAddress::GetLocalIPs(std::vector<IPAddress>* ips) {
if (!ips) {
return false;
diff --git a/talk/base/socketaddress.h b/talk/base/socketaddress.h
index 2272b53..3ebf556 100644
--- a/talk/base/socketaddress.h
+++ b/talk/base/socketaddress.h
@@ -191,8 +191,10 @@
// Dual stack version always sets family to AF_INET6, and maps v4 addresses.
// The other version doesn't map, and outputs an AF_INET address for
// v4 or mapped addresses, and AF_INET6 addresses for others.
- void ToDualStackSockAddrStorage(sockaddr_storage* saddr) const;
- void ToSockAddrStorage(sockaddr_storage* saddr) const;
+ // Returns the size of the sockaddr_in or sockaddr_in6 structure that is
+ // written to the sockaddr_storage, or zero on failure.
+ size_t ToDualStackSockAddrStorage(sockaddr_storage* saddr) const;
+ size_t ToSockAddrStorage(sockaddr_storage* saddr) const;
// Converts the IP address given in 'compact form' into dotted form.
// IP is given as an integer in host byte order. V4 only, to be deprecated.
@@ -210,16 +212,12 @@
static bool StringToIP(const std::string& str, IPAddress* ip);
// Get a list of the local machine's ip addresses.
- // TODO: Deprecate this function.
- static bool GetLocalIPs(std::vector<uint32>& ips);
+ // TODO: Move to nethelpers or similar (doesn't belong in socketaddress).
+ static bool GetLocalIPs(std::vector<IPAddress>* ips);
private:
// Get local machine's hostname.
static std::string GetHostname();
- // Get a list of the local machine's ip addresses.
- // TODO: Remove this (and the other GetLocalIPs method).
- static bool GetLocalIPs(std::vector<IPAddress>* ips);
-
std::string hostname_;
IPAddress ip_;
uint16 port_;
diff --git a/talk/base/socketaddress_unittest.cc b/talk/base/socketaddress_unittest.cc
index d19c723..fcfd89c 100644
--- a/talk/base/socketaddress_unittest.cc
+++ b/talk/base/socketaddress_unittest.cc
@@ -50,16 +50,16 @@
TEST(SocketAddressTest, TestDefaultCtor) {
SocketAddress addr;
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0U, addr.ip());
+ EXPECT_EQ(IPAddress(INADDR_ANY), addr.ipaddr());
EXPECT_EQ(0, addr.port());
EXPECT_EQ("", addr.hostname());
EXPECT_EQ("0.0.0.0:0", addr.ToString());
}
TEST(SocketAddressTest, TestIPPortCtor) {
- SocketAddress addr(0x01020304, 5678);
+ SocketAddress addr(IPAddress(0x01020304), 5678);
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
@@ -68,7 +68,7 @@
TEST(SocketAddressTest, TestIPv4StringPortCtor) {
SocketAddress addr("1.2.3.4", 5678);
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("1.2.3.4", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
@@ -89,7 +89,7 @@
// inet_addr doesn't handle this address properly.
SocketAddress addr("255.255.255.255", 5678);
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0xFFFFFFFFU, addr.ip());
+ EXPECT_EQ(IPAddress(0xFFFFFFFFU), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("255.255.255.255", addr.hostname());
EXPECT_EQ("255.255.255.255:5678", addr.ToString());
@@ -98,7 +98,7 @@
TEST(SocketAddressTest, TestHostnamePortCtor) {
SocketAddress addr("a.b.com", 5678);
EXPECT_TRUE(addr.IsUnresolvedIP());
- EXPECT_EQ(0U, addr.ip());
+ EXPECT_EQ(IPAddress(INADDR_ANY), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("a.b.com", addr.hostname());
EXPECT_EQ("a.b.com:5678", addr.ToString());
@@ -108,7 +108,7 @@
SocketAddress from("1.2.3.4", 5678);
SocketAddress addr(from);
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("1.2.3.4", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
@@ -116,49 +116,49 @@
TEST(SocketAddressTest, TestAssign) {
SocketAddress from("1.2.3.4", 5678);
- SocketAddress addr(0x88888888, 9999);
+ SocketAddress addr(IPAddress(0x88888888), 9999);
addr = from;
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("1.2.3.4", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
}
TEST(SocketAddressTest, TestSetIPPort) {
- SocketAddress addr(0x88888888, 9999);
- addr.SetIP(0x01020304);
+ SocketAddress addr(IPAddress(0x88888888), 9999);
+ addr.SetIP(IPAddress(0x01020304));
addr.SetPort(5678);
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
}
TEST(SocketAddressTest, TestSetIPFromString) {
- SocketAddress addr(0x88888888, 9999);
+ SocketAddress addr(IPAddress(0x88888888), 9999);
addr.SetIP("1.2.3.4");
addr.SetPort(5678);
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("1.2.3.4", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
}
TEST(SocketAddressTest, TestSetIPFromHostname) {
- SocketAddress addr(0x88888888, 9999);
+ SocketAddress addr(IPAddress(0x88888888), 9999);
addr.SetIP("a.b.com");
addr.SetPort(5678);
EXPECT_TRUE(addr.IsUnresolvedIP());
- EXPECT_EQ(0U, addr.ip());
+ EXPECT_EQ(IPAddress(INADDR_ANY), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("a.b.com", addr.hostname());
EXPECT_EQ("a.b.com:5678", addr.ToString());
- addr.SetResolvedIP(0x01020304);
+ addr.SetResolvedIP(IPAddress(0x01020304));
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ("a.b.com", addr.hostname());
EXPECT_EQ("a.b.com:5678", addr.ToString());
}
@@ -167,7 +167,7 @@
SocketAddress addr;
EXPECT_TRUE(addr.FromString("1.2.3.4:5678"));
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("1.2.3.4", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
@@ -186,7 +186,7 @@
SocketAddress addr;
EXPECT_TRUE(addr.FromString("a.b.com:5678"));
EXPECT_TRUE(addr.IsUnresolvedIP());
- EXPECT_EQ(0U, addr.ip());
+ EXPECT_EQ(IPAddress(INADDR_ANY), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("a.b.com", addr.hostname());
EXPECT_EQ("a.b.com:5678", addr.ToString());
@@ -198,7 +198,7 @@
from.ToSockAddr(&addr_in);
EXPECT_TRUE(addr.FromSockAddr(addr_in));
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
@@ -210,7 +210,7 @@
from.ToSockAddrStorage(&addr_storage);
EXPECT_TRUE(SocketAddressFromSockAddrStorage(addr_storage, &addr));
EXPECT_FALSE(addr.IsUnresolvedIP());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
@@ -239,7 +239,7 @@
EXPECT_TRUE(addr.Read_(buf, sizeof(buf)));
EXPECT_FALSE(addr.IsUnresolvedIP());
EXPECT_EQ(AF_INET, addr.ipaddr().family());
- EXPECT_EQ(0x01020304U, addr.ip());
+ EXPECT_EQ(IPAddress(0x01020304U), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("", addr.hostname());
EXPECT_EQ("1.2.3.4:5678", addr.ToString());
@@ -266,7 +266,7 @@
EXPECT_EQ(0, error);
EXPECT_FALSE(addr.IsUnresolvedIP());
EXPECT_TRUE(addr.IsLoopbackIP());
- EXPECT_EQ(0x7F000001U, addr.ip());
+ EXPECT_EQ(IPAddress(INADDR_LOOPBACK), addr.ipaddr());
EXPECT_EQ(5678, addr.port());
EXPECT_EQ("localhost", addr.hostname());
EXPECT_EQ("localhost:5678", addr.ToString());
diff --git a/talk/base/task.cc b/talk/base/task.cc
index ad17438..c37797c 100644
--- a/talk/base/task.cc
+++ b/talk/base/task.cc
@@ -197,22 +197,15 @@
}
std::string Task::GetStateName(int state) const {
- static const std::string STR_BLOCKED("BLOCKED");
- static const std::string STR_INIT("INIT");
- static const std::string STR_START("START");
- static const std::string STR_DONE("DONE");
- static const std::string STR_ERROR("ERROR");
- static const std::string STR_RESPONSE("RESPONSE");
- static const std::string STR_HUH("??");
switch (state) {
- case STATE_BLOCKED: return STR_BLOCKED;
- case STATE_INIT: return STR_INIT;
- case STATE_START: return STR_START;
- case STATE_DONE: return STR_DONE;
- case STATE_ERROR: return STR_ERROR;
- case STATE_RESPONSE: return STR_RESPONSE;
+ case STATE_BLOCKED: return "BLOCKED";
+ case STATE_INIT: return "INIT";
+ case STATE_START: return "START";
+ case STATE_DONE: return "DONE";
+ case STATE_ERROR: return "ERROR";
+ case STATE_RESPONSE: return "RESPONSE";
}
- return STR_HUH;
+ return "??";
}
int Task::Process(int state) {
diff --git a/talk/base/virtualsocket_unittest.cc b/talk/base/virtualsocket_unittest.cc
index 6b2ae99..1c44fe7 100644
--- a/talk/base/virtualsocket_unittest.cc
+++ b/talk/base/virtualsocket_unittest.cc
@@ -56,7 +56,7 @@
};
TEST_F(VirtualSocketServerTest, basic) {
- SocketAddress addr1(0, 5000);
+ SocketAddress addr1(IPAddress(INADDR_ANY), 5000);
AsyncSocket* socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
socket->Bind(addr1);
addr1 = socket->GetLocalAddress();
@@ -80,7 +80,8 @@
SocketAddress addr4;
EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
- EXPECT_EQ(addr4.ip(), addr2.ip() + 1);
+ EXPECT_EQ(addr4.ipaddr().v4AddressAsHostOrderInteger(),
+ addr2.ipaddr().v4AddressAsHostOrderInteger() + 1);
EXPECT_EQ(addr4.port(), addr2.port() + 1);
SocketAddress addr5;
@@ -618,8 +619,8 @@
TEST_F(VirtualSocketServerTest, bandwidth) {
AsyncSocket* send_socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
AsyncSocket* recv_socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
- ASSERT_EQ(0, send_socket->Bind(SocketAddress(0, 1000)));
- ASSERT_EQ(0, recv_socket->Bind(SocketAddress(0, 1000)));
+ ASSERT_EQ(0, send_socket->Bind(SocketAddress(IPAddress(INADDR_ANY), 1000)));
+ ASSERT_EQ(0, recv_socket->Bind(SocketAddress(IPAddress(INADDR_ANY), 1000)));
ASSERT_EQ(0, send_socket->Connect(recv_socket->GetLocalAddress()));
uint32 bandwidth = 64 * 1024;
@@ -653,8 +654,8 @@
AsyncSocket* send_socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
AsyncSocket* recv_socket = ss_->CreateAsyncSocket(SOCK_DGRAM);
- ASSERT_EQ(0, send_socket->Bind(SocketAddress(0, 1000)));
- ASSERT_EQ(0, recv_socket->Bind(SocketAddress(0, 1000)));
+ ASSERT_EQ(0, send_socket->Bind(SocketAddress(IPAddress(INADDR_ANY), 1000)));
+ ASSERT_EQ(0, recv_socket->Bind(SocketAddress(IPAddress(INADDR_ANY), 1000)));
ASSERT_EQ(0, send_socket->Connect(recv_socket->GetLocalAddress()));
Thread* pthMain = Thread::Current();
diff --git a/talk/base/virtualsocketserver.cc b/talk/base/virtualsocketserver.cc
index 77614b2..c9c9f0b 100644
--- a/talk/base/virtualsocketserver.cc
+++ b/talk/base/virtualsocketserver.cc
@@ -608,7 +608,7 @@
const SocketAddress& addr) {
ASSERT(NULL != socket);
// Address must be completely specified at this point
- ASSERT(addr.ip() != 0);
+ ASSERT(!IPIsAny(addr.ipaddr()));
ASSERT(addr.port() != 0);
AddressMap::value_type entry(addr, socket);
@@ -618,8 +618,9 @@
int VirtualSocketServer::Bind(VirtualSocket* socket, SocketAddress* addr) {
ASSERT(NULL != socket);
- if (addr->ip() == 0) {
- addr->SetIP(GetNextIP());
+ if (IPIsAny(addr->ipaddr())) {
+ // TODO: An IPv6-ish version of this?
+ addr->SetIP(IPAddress(GetNextIP()));
}
if (addr->port() == 0) {
diff --git a/talk/examples/call/call_main.cc b/talk/examples/call/call_main.cc
index 748936b..077869c 100644
--- a/talk/examples/call/call_main.cc
+++ b/talk/examples/call/call_main.cc
@@ -216,6 +216,7 @@
"Disable or enable encryption: disable, enable, require.");
DEFINE_string(tls, "enable",
"Disable or enable tls: disable, enable, require.");
+ DEFINE_bool(allowplain, false, "Allow plain authentication");
DEFINE_bool(testserver, false, "Use test server");
DEFINE_int(portallocator, 0, "Filter out unwanted connection types.");
DEFINE_string(filterhost, NULL, "Filter out the host from all candidates.");
@@ -240,6 +241,7 @@
bool debug = FLAG_d;
std::string protocol = FLAG_protocol;
bool test_server = FLAG_testserver;
+ bool allow_plain = FLAG_allowplain;
std::string tls = FLAG_tls;
int32 portallocator_flags = FLAG_portallocator;
std::string pmuc_domain = FLAG_pmuc;
@@ -314,11 +316,9 @@
xcs.set_user(jid.node());
xcs.set_resource("call");
xcs.set_host(jid.domain());
-
- bool allow_plain = (test_server) ? true : false;
xcs.set_allow_plain(allow_plain);
- if(test_server || tls == "disable") {
+ if(tls == "disable") {
xcs.set_use_tls(buzz::TLS_DISABLED);
} else if (tls == "enable") {
xcs.set_use_tls(buzz::TLS_ENABLED);
@@ -332,6 +332,7 @@
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(talk_base::CryptString(pass));
diff --git a/talk/libjingle.scons b/talk/libjingle.scons
index 3d0463a..0ec1f59 100644
--- a/talk/libjingle.scons
+++ b/talk/libjingle.scons
@@ -233,6 +233,7 @@
"session/phone/mediaengine.cc",
"session/phone/mediamessages.cc",
"session/phone/mediamonitor.cc",
+ "session/phone/mediarecorder.cc",
"session/phone/mediasession.cc",
"session/phone/mediasessionclient.cc",
"session/phone/rtpdump.cc",
@@ -534,15 +535,23 @@
"srtp",
],
srcs = [
+ "session/phone/channel_unittest.cc",
+ "session/phone/channelmanager_unittest.cc",
"session/phone/codec_unittest.cc",
"session/phone/currentspeakermonitor_unittest.cc",
+ "session/phone/devicemanager_unittest.cc",
+ "session/phone/dummydevicemanager_unittest.cc",
"session/phone/filemediaengine_unittest.cc",
"session/phone/filevideocapturer_unittest.cc",
+ "session/phone/mediarecorder_unittest.cc",
"session/phone/mediamessages_unittest.cc",
"session/phone/mediasession_unittest.cc",
+ "session/phone/mediasessionclient_unittest.cc",
+ "session/phone/rtcpmuxfilter_unittest.cc",
"session/phone/rtpdump_unittest.cc",
"session/phone/rtputils_unittest.cc",
"session/phone/srtpfilter_unittest.cc",
+ "session/phone/ssrcmuxfilter_unittest.cc",
"session/phone/testutils.cc",
"session/phone/videocapturer_unittest.cc",
"session/phone/videocommon_unittest.cc",
diff --git a/talk/p2p/base/constants.cc b/talk/p2p/base/constants.cc
index 6123fc1..4d65f5b 100644
--- a/talk/p2p/base/constants.cc
+++ b/talk/p2p/base/constants.cc
@@ -104,7 +104,7 @@
const char NS_JINGLE_RTP[] = "urn:xmpp:jingle:apps:rtp:1";
const buzz::StaticQName QN_JINGLE_RTP_CONTENT =
{ NS_JINGLE_RTP, LN_DESCRIPTION };
-const buzz::StaticQName QN_JINGLE_SSRC = { NS_EMPTY, "ssrc" };
+const buzz::StaticQName QN_SSRC = { NS_EMPTY, "ssrc" };
const buzz::StaticQName QN_JINGLE_RTP_PAYLOADTYPE =
{ NS_JINGLE_RTP, LN_PAYLOADTYPE };
const buzz::StaticQName QN_JINGLE_RTP_BANDWIDTH =
@@ -202,40 +202,24 @@
const char STR_TERMINATE_UNKNOWN_ERROR[] = "unknown-error";
// Draft view and notify messages.
-const buzz::StaticQName QN_JINGLE_DRAFT_CONTENT_NAME =
- { cricket::NS_EMPTY, "name" };
const char STR_JINGLE_DRAFT_CONTENT_NAME_VIDEO[] = "video";
const char STR_JINGLE_DRAFT_CONTENT_NAME_AUDIO[] = "audio";
-const buzz::StaticQName QN_JINGLE_DRAFT_NOTIFY = { NS_JINGLE_DRAFT, "notify" };
-const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE = { NS_JINGLE_DRAFT, "source" };
-const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_NICK =
- { cricket::NS_EMPTY, "nick" };
-const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_NAME =
- { cricket::NS_EMPTY, "name" };
-const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_USAGE =
- { cricket::NS_EMPTY, "usage" };
-const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_STATE =
- { cricket::NS_EMPTY, "state" };
-const char STR_JINGLE_DRAFT_SOURCE_STATE_REMOVED[] = "removed";
-const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_SSRC =
- { NS_JINGLE_DRAFT, "ssrc" };
+const buzz::StaticQName QN_NICK = { cricket::NS_EMPTY, "nick" };
+const buzz::StaticQName QN_TYPE = { cricket::NS_EMPTY, "type" };
const buzz::StaticQName QN_JINGLE_DRAFT_VIEW = { NS_JINGLE_DRAFT, "view" };
-const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_TYPE =
- { cricket::NS_EMPTY, "type" };
const char STR_JINGLE_DRAFT_VIEW_TYPE_NONE[] = "none";
const char STR_JINGLE_DRAFT_VIEW_TYPE_STATIC[] = "static";
-const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_SSRC =
- { cricket::NS_EMPTY, "ssrc" };
-const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS =
- { NS_JINGLE_DRAFT, "params" };
-const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS_WIDTH =
- { cricket::NS_EMPTY, "width" };
-const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS_HEIGHT =
- { cricket::NS_EMPTY, "height" };
-const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS_FRAMERATE =
- { cricket::NS_EMPTY, "framerate" };
-const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS_PREFERENCE =
- { cricket::NS_EMPTY, "preference" };
+const buzz::StaticQName QN_JINGLE_DRAFT_PARAMS = { NS_JINGLE_DRAFT, "params" };
+const buzz::StaticQName QN_JINGLE_DRAFT_STREAMS = { NS_JINGLE_DRAFT, "streams" };
+const buzz::StaticQName QN_JINGLE_DRAFT_STREAM = { NS_JINGLE_DRAFT, "stream" };
+const buzz::StaticQName QN_DISPLAY = { cricket::NS_EMPTY, "display" };
+const buzz::StaticQName QN_CNAME = { cricket::NS_EMPTY, "cname" };
+const buzz::StaticQName QN_JINGLE_DRAFT_SSRC = { NS_JINGLE_DRAFT, "ssrc" };
+const buzz::StaticQName QN_JINGLE_DRAFT_SSRC_GROUP =
+ { NS_JINGLE_DRAFT, "ssrc-group" };
+const buzz::StaticQName QN_SEMANTICS = { cricket::NS_EMPTY, "semantics" };
+const buzz::StaticQName QN_JINGLE_LEGACY_NOTIFY = { NS_JINGLE_DRAFT, "notify" };
+const buzz::StaticQName QN_JINGLE_LEGACY_SOURCE = { NS_JINGLE_DRAFT, "source" };
// old stuff
#ifdef FEATURE_ENABLE_VOICEMAIL
diff --git a/talk/p2p/base/constants.h b/talk/p2p/base/constants.h
index 0a53345..0c84dd6 100644
--- a/talk/p2p/base/constants.h
+++ b/talk/p2p/base/constants.h
@@ -97,9 +97,6 @@
extern const buzz::StaticQName QN_CLOCKRATE;
extern const buzz::StaticQName QN_BITRATE;
extern const buzz::StaticQName QN_CHANNELS;
-extern const buzz::StaticQName QN_WIDTH;
-extern const buzz::StaticQName QN_HEIGHT;
-extern const buzz::StaticQName QN_FRAMERATE;
extern const buzz::StaticQName QN_PARAMETER;
extern const char LN_NAME[];
extern const char LN_VALUE[];
@@ -125,7 +122,7 @@
extern const char NS_JINGLE_RTP[];
extern const buzz::StaticQName QN_JINGLE_RTP_CONTENT;
-extern const buzz::StaticQName QN_JINGLE_SSRC;
+extern const buzz::StaticQName QN_SSRC;
extern const buzz::StaticQName QN_JINGLE_RTP_PAYLOADTYPE;
extern const buzz::StaticQName QN_JINGLE_RTP_BANDWIDTH;
extern const buzz::StaticQName QN_JINGLE_RTCP_MUX;
@@ -213,28 +210,26 @@
extern const char STR_TERMINATE_UNKNOWN_ERROR[];
// Draft view and notify messages.
-extern const buzz::StaticQName QN_JINGLE_DRAFT_CONTENT_NAME;
extern const char STR_JINGLE_DRAFT_CONTENT_NAME_VIDEO[];
extern const char STR_JINGLE_DRAFT_CONTENT_NAME_AUDIO[];
-extern const buzz::StaticQName QN_JINGLE_DRAFT_NOTIFY;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_NICK;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_NAME;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_USAGE;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_STATE;
-extern const char STR_JINGLE_DRAFT_SOURCE_STATE_REMOVED[];
-extern const buzz::StaticQName QN_JINGLE_DRAFT_SOURCE_SSRC;
+extern const buzz::StaticQName QN_NICK;
+extern const buzz::StaticQName QN_TYPE;
extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_NAME;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_TYPE;
extern const char STR_JINGLE_DRAFT_VIEW_TYPE_NONE[];
extern const char STR_JINGLE_DRAFT_VIEW_TYPE_STATIC[];
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_SSRC;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS_WIDTH;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS_HEIGHT;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS_FRAMERATE;
-extern const buzz::StaticQName QN_JINGLE_DRAFT_VIEW_PARAMS_PREFERENCE;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_PARAMS;
+extern const buzz::StaticQName QN_WIDTH;
+extern const buzz::StaticQName QN_HEIGHT;
+extern const buzz::StaticQName QN_FRAMERATE;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_STREAM;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_STREAMS;
+extern const buzz::StaticQName QN_DISPLAY;
+extern const buzz::StaticQName QN_CNAME;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_SSRC;
+extern const buzz::StaticQName QN_JINGLE_DRAFT_SSRC_GROUP;
+extern const buzz::StaticQName QN_SEMANTICS;
+extern const buzz::StaticQName QN_JINGLE_LEGACY_NOTIFY;
+extern const buzz::StaticQName QN_JINGLE_LEGACY_SOURCE;
// old stuff
#ifdef FEATURE_ENABLE_VOICEMAIL
diff --git a/talk/p2p/base/p2ptransportchannel_unittest.cc b/talk/p2p/base/p2ptransportchannel_unittest.cc
index 109b04f..ae5ab62 100644
--- a/talk/p2p/base/p2ptransportchannel_unittest.cc
+++ b/talk/p2p/base/p2ptransportchannel_unittest.cc
@@ -384,9 +384,9 @@
} else if (config == BLOCK_ALL_BUT_OUTGOING_HTTP) {
// Block all TCP to/from the endpoint except 80/443 out
fw()->AddRule(true, talk_base::FP_TCP, kPublicAddrs[endpoint],
- SocketAddress(0, 80));
+ SocketAddress(talk_base::IPAddress(INADDR_ANY), 80));
fw()->AddRule(true, talk_base::FP_TCP, kPublicAddrs[endpoint],
- SocketAddress(0, 443));
+ SocketAddress(talk_base::IPAddress(INADDR_ANY), 443));
fw()->AddRule(false, talk_base::FP_TCP, talk_base::FD_ANY,
kPublicAddrs[endpoint]);
} else if (config == PROXY_HTTPS) {
diff --git a/talk/p2p/base/parsing.cc b/talk/p2p/base/parsing.cc
index a54d379..f302956 100644
--- a/talk/p2p/base/parsing.cc
+++ b/talk/p2p/base/parsing.cc
@@ -91,6 +91,18 @@
return NULL;
}
+const buzz::XmlElement* GetXmlElement(const XmlElements& elems,
+ const buzz::QName& name) {
+ for (XmlElements::const_iterator iter = elems.begin();
+ iter != elems.end(); ++iter) {
+ const buzz::XmlElement* elem = *iter;
+ if (elem->Name() == name) {
+ return elem;
+ }
+ }
+ return NULL;
+}
+
bool RequireXmlChild(const buzz::XmlElement* parent,
const std::string& name,
const buzz::XmlElement** child,
@@ -120,6 +132,14 @@
}
}
+void AddXmlAttrIfNonEmpty(buzz::XmlElement* elem,
+ const buzz::QName name,
+ const std::string& value) {
+ if (!value.empty()) {
+ elem->AddAttr(name, value);
+ }
+}
+
void AddXmlChildren(buzz::XmlElement* parent,
const std::vector<buzz::XmlElement*>& children) {
for (std::vector<buzz::XmlElement*>::const_iterator iter = children.begin();
diff --git a/talk/p2p/base/parsing.h b/talk/p2p/base/parsing.h
index 7931431..589d9d7 100644
--- a/talk/p2p/base/parsing.h
+++ b/talk/p2p/base/parsing.h
@@ -112,6 +112,9 @@
const buzz::XmlElement* GetXmlChild(const buzz::XmlElement* parent,
const std::string& name);
+const buzz::XmlElement* GetXmlElement(const XmlElements& elems,
+ const buzz::QName& name);
+
bool RequireXmlChild(const buzz::XmlElement* parent,
const std::string& name,
const buzz::XmlElement** child,
@@ -120,6 +123,9 @@
const buzz::QName& name,
std::string* value,
ParseError* error);
+void AddXmlAttrIfNonEmpty(buzz::XmlElement* elem,
+ const buzz::QName name,
+ const std::string& value);
void AddXmlChildren(buzz::XmlElement* parent,
const std::vector<buzz::XmlElement*>& children);
void CopyXmlChildren(const buzz::XmlElement* source, buzz::XmlElement* dest);
diff --git a/talk/p2p/base/port.cc b/talk/p2p/base/port.cc
index bb4ab26..a016f63 100644
--- a/talk/p2p/base/port.cc
+++ b/talk/p2p/base/port.cc
@@ -126,7 +126,7 @@
Port::Port(talk_base::Thread* thread, const std::string& type,
talk_base::PacketSocketFactory* factory, talk_base::Network* network,
- uint32 ip, int min_port, int max_port)
+ const talk_base::IPAddress& ip, int min_port, int max_port)
: thread_(thread),
factory_(factory),
type_(type),
@@ -351,7 +351,7 @@
StunAddressAttribute* addr_attr =
StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
addr_attr->SetPort(addr.port());
- addr_attr->SetIP(addr.ip());
+ addr_attr->SetIP(addr.ipaddr());
response.AddAttribute(addr_attr);
// Send the response message.
@@ -528,11 +528,8 @@
}
const Candidate& Connection::local_candidate() const {
- if (local_candidate_index_ < port_->candidates().size())
- return port_->candidates()[local_candidate_index_];
- ASSERT(false);
- static Candidate foo;
- return foo;
+ ASSERT(local_candidate_index_ < port_->candidates().size());
+ return port_->candidates()[local_candidate_index_];
}
void Connection::set_read_state(ReadState value) {
diff --git a/talk/p2p/base/port.h b/talk/p2p/base/port.h
index 8304146..396fce0 100644
--- a/talk/p2p/base/port.h
+++ b/talk/p2p/base/port.h
@@ -77,7 +77,7 @@
public:
Port(talk_base::Thread* thread, const std::string& type,
talk_base::PacketSocketFactory* factory, talk_base::Network* network,
- uint32 ip, int min_port, int max_port);
+ const talk_base::IPAddress& ip, int min_port, int max_port);
virtual ~Port();
// The thread on which this port performs its I/O.
@@ -241,7 +241,7 @@
talk_base::PacketSocketFactory* factory_;
std::string type_;
talk_base::Network* network_;
- uint32 ip_;
+ talk_base::IPAddress ip_;
int min_port_;
int max_port_;
uint32 generation_;
diff --git a/talk/p2p/base/port_unittest.cc b/talk/p2p/base/port_unittest.cc
index 4bb7fd3..1bdac3d 100644
--- a/talk/p2p/base/port_unittest.cc
+++ b/talk/p2p/base/port_unittest.cc
@@ -157,7 +157,8 @@
: main_(talk_base::Thread::Current()),
pss_(new talk_base::PhysicalSocketServer),
ss_(new talk_base::VirtualSocketServer(pss_.get())),
- ss_scope_(ss_.get()), network_("unittest", "unittest", 0),
+ ss_scope_(ss_.get()),
+ network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY)),
socket_factory_(talk_base::Thread::Current()),
nat_factory1_(ss_.get(), kNatAddr1),
nat_factory2_(ss_.get(), kNatAddr2),
@@ -241,7 +242,8 @@
}
UDPPort* CreateUdpPort(const SocketAddress& addr,
PacketSocketFactory* socket_factory) {
- return UDPPort::Create(main_, socket_factory, &network_, addr.ip(), 0, 0);
+ return UDPPort::Create(main_, socket_factory, &network_,
+ addr.ipaddr(), 0, 0);
}
TCPPort* CreateTcpPort(const SocketAddress& addr) {
return CreateTcpPort(addr, &socket_factory_);
@@ -249,19 +251,19 @@
TCPPort* CreateTcpPort(const SocketAddress& addr,
PacketSocketFactory* socket_factory) {
return TCPPort::Create(main_, socket_factory, &network_,
- addr.ip(), 0, 0, true);
+ addr.ipaddr(), 0, 0, true);
}
StunPort* CreateStunPort(const SocketAddress& addr,
talk_base::PacketSocketFactory* factory) {
return StunPort::Create(main_, factory, &network_,
- addr.ip(), 0, 0, kStunAddr);
+ addr.ipaddr(), 0, 0, kStunAddr);
}
RelayPort* CreateRelayPort(const SocketAddress& addr,
ProtocolType int_proto, ProtocolType ext_proto) {
std::string user = talk_base::CreateRandomString(16);
std::string pass = talk_base::CreateRandomString(16);
RelayPort* port = RelayPort::Create(main_, &socket_factory_, &network_,
- addr.ip(), 0, 0, user, pass, "");
+ addr.ipaddr(), 0, 0, user, pass, "");
SocketAddress addrs[] =
{ kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
diff --git a/talk/p2p/base/relayport.cc b/talk/p2p/base/relayport.cc
index 76bd5ff..c6c066a 100644
--- a/talk/p2p/base/relayport.cc
+++ b/talk/p2p/base/relayport.cc
@@ -187,9 +187,9 @@
RelayPort::RelayPort(
talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
- talk_base::Network* network, uint32 ip, int min_port, int max_port,
- const std::string& username, const std::string& password,
- const std::string& magic_cookie)
+ talk_base::Network* network, const talk_base::IPAddress& ip,
+ int min_port, int max_port, const std::string& username,
+ const std::string& password, const std::string& magic_cookie)
: Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port),
ready_(false),
magic_cookie_(magic_cookie),
@@ -554,7 +554,7 @@
StunAddressAttribute* addr_attr =
StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
- addr_attr->SetIP(addr.ip());
+ addr_attr->SetIP(addr.ipaddr());
addr_attr->SetPort(addr.port());
request.AddAttribute(addr_attr);
@@ -702,7 +702,7 @@
return;
}
- talk_base::SocketAddress remote_addr2(addr_attr->ip(), addr_attr->port());
+ talk_base::SocketAddress remote_addr2(addr_attr->ipaddr(), addr_attr->port());
const StunByteStringAttribute* data_attr = msg.GetByteString(STUN_ATTR_DATA);
if (!data_attr) {
@@ -764,7 +764,7 @@
} else if (addr_attr->family() != 1) {
LOG(INFO) << "Mapped address has bad family";
} else {
- talk_base::SocketAddress addr(addr_attr->ip(), addr_attr->port());
+ talk_base::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
entry_->OnConnect(addr, connection_);
}
diff --git a/talk/p2p/base/relayport.h b/talk/p2p/base/relayport.h
index 62bb758..2137606 100644
--- a/talk/p2p/base/relayport.h
+++ b/talk/p2p/base/relayport.h
@@ -55,9 +55,9 @@
// RelayPort doesn't yet do anything fancy in the ctor.
static RelayPort* Create(
talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
- talk_base::Network* network, uint32 ip, int min_port, int max_port,
- const std::string& username, const std::string& password,
- const std::string& magic_cookie) {
+ talk_base::Network* network, const talk_base::IPAddress& ip,
+ int min_port, int max_port, const std::string& username,
+ const std::string& password, const std::string& magic_cookie) {
return new RelayPort(thread, factory, network, ip, min_port, max_port,
username, password, magic_cookie);
}
@@ -85,9 +85,9 @@
protected:
RelayPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
- talk_base::Network*, uint32 ip, int min_port, int max_port,
- const std::string& username, const std::string& password,
- const std::string& magic_cookie);
+ talk_base::Network*, const talk_base::IPAddress& ip,
+ int min_port, int max_port, const std::string& username,
+ const std::string& password, const std::string& magic_cookie);
bool Init();
void SetReady();
diff --git a/talk/p2p/base/relayport_unittest.cc b/talk/p2p/base/relayport_unittest.cc
index 67fb238..688e635 100644
--- a/talk/p2p/base/relayport_unittest.cc
+++ b/talk/p2p/base/relayport_unittest.cc
@@ -65,12 +65,13 @@
virtual_socket_server_(new talk_base::VirtualSocketServer(
physical_socket_server_.get())),
ss_scope_(virtual_socket_server_.get()),
- network_("unittest", "unittest", 0),
+ network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY)),
socket_factory_(talk_base::Thread::Current()),
username_(talk_base::CreateRandomString(16)),
password_(talk_base::CreateRandomString(16)),
relay_port_(cricket::RelayPort::Create(main_, &socket_factory_,
- &network_, kLocalAddress.ip(),
+ &network_,
+ kLocalAddress.ipaddr(),
0, 0, username_, password_, "")),
relay_server_(new cricket::RelayServer(main_)) {
}
diff --git a/talk/p2p/base/relayserver.cc b/talk/p2p/base/relayserver.cc
index 554337f..b17da5b 100644
--- a/talk/p2p/base/relayserver.cc
+++ b/talk/p2p/base/relayserver.cc
@@ -444,7 +444,7 @@
StunAddressAttribute* addr_attr =
StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
- addr_attr->SetIP(ext_addr.ip());
+ addr_attr->SetIP(ext_addr.ipaddr());
addr_attr->SetPort(ext_addr.port());
response.AddAttribute(addr_attr);
@@ -478,7 +478,7 @@
return;
}
- talk_base::SocketAddress ext_addr(addr_attr->ip(), addr_attr->port());
+ talk_base::SocketAddress ext_addr(addr_attr->ipaddr(), addr_attr->port());
RelayServerConnection* ext_conn =
int_conn->binding()->GetExternalConnection(ext_addr);
if (!ext_conn) {
@@ -620,7 +620,7 @@
StunAddressAttribute* addr_attr =
StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
- addr_attr->SetIP(from_addr.ip());
+ addr_attr->SetIP(from_addr.ipaddr());
addr_attr->SetPort(from_addr.port());
msg.AddAttribute(addr_attr);
diff --git a/talk/p2p/base/relayserver_unittest.cc b/talk/p2p/base/relayserver_unittest.cc
index 1528eb4..0f96e27 100644
--- a/talk/p2p/base/relayserver_unittest.cc
+++ b/talk/p2p/base/relayserver_unittest.cc
@@ -174,7 +174,7 @@
static void AddDestinationAttr(StunMessage* msg, const SocketAddress& addr) {
StunAddressAttribute* attr =
StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
- attr->SetIP(addr.ip());
+ attr->SetIP(addr.ipaddr());
attr->SetPort(addr.port());
msg->AddAttribute(attr);
}
@@ -263,7 +263,7 @@
ASSERT_TRUE(mapped_addr != NULL);
EXPECT_EQ(1, mapped_addr->family());
EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
- EXPECT_EQ(server_ext_addr.ip(), mapped_addr->ip());
+ EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
const StunUInt32Attribute* res_lifetime_attr =
res->GetUInt32(STUN_ATTR_LIFETIME);
@@ -293,7 +293,7 @@
ASSERT_TRUE(mapped_addr != NULL);
EXPECT_EQ(1, mapped_addr->family());
EXPECT_EQ(server_ext_addr.port(), mapped_addr->port());
- EXPECT_EQ(server_ext_addr.ip(), mapped_addr->ip());
+ EXPECT_EQ(server_ext_addr.ipaddr(), mapped_addr->ipaddr());
const StunUInt32Attribute* lifetime_attr =
res->GetUInt32(STUN_ATTR_LIFETIME);
@@ -330,7 +330,7 @@
res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
ASSERT_TRUE(src_addr != NULL);
EXPECT_EQ(1, src_addr->family());
- EXPECT_EQ(client2_addr.ip(), src_addr->ip());
+ EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
EXPECT_EQ(client2_addr.port(), src_addr->port());
EXPECT_TRUE(Receive2() == NULL);
@@ -498,7 +498,7 @@
res->GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
ASSERT_TRUE(src_addr != NULL);
EXPECT_EQ(1, src_addr->family());
- EXPECT_EQ(client2_addr.ip(), src_addr->ip());
+ EXPECT_EQ(client2_addr.ipaddr(), src_addr->ipaddr());
EXPECT_EQ(client2_addr.port(), src_addr->port());
const StunByteStringAttribute* recv_data =
diff --git a/talk/p2p/base/session.cc b/talk/p2p/base/session.cc
index ab4d83f..9891ee2 100644
--- a/talk/p2p/base/session.cc
+++ b/talk/p2p/base/session.cc
@@ -737,8 +737,8 @@
case ACTION_TRANSPORT_ACCEPT:
valid = OnTransportAcceptMessage(msg, &error);
break;
- case ACTION_UPDATE:
- valid = OnUpdateMessage(msg, &error);
+ case ACTION_DESCRIPTION_INFO:
+ valid = OnDescriptionInfoMessage(msg, &error);
break;
default:
valid = BadMessage(buzz::QN_STANZA_BAD_REQUEST,
@@ -946,7 +946,7 @@
return true;
}
-bool Session::OnUpdateMessage(const SessionMessage& msg,
+bool Session::OnDescriptionInfoMessage(const SessionMessage& msg,
MessageError* error) {
if (!CheckState(STATE_INPROGRESS, error))
return false;
@@ -972,12 +972,14 @@
}
// Merge the updates into the remote description.
+ // TODO: Merge streams instead of overwriting.
for (it = updated_contents.begin(); it != updated_contents.end(); ++it) {
LOG(LS_INFO) << "Updating content " << it->name;
remote_description()->RemoveContentByName(it->name);
remote_description()->AddContent(it->name, it->type, it->description);
}
+ // TODO: Add an argument that shows what streams were changed.
SignalRemoteDescriptionUpdate(this);
return true;
diff --git a/talk/p2p/base/session.h b/talk/p2p/base/session.h
index c968f5d..f3b6f25 100644
--- a/talk/p2p/base/session.h
+++ b/talk/p2p/base/session.h
@@ -562,7 +562,7 @@
bool OnTerminateMessage(const SessionMessage& msg, MessageError* error);
bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error);
bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error);
- bool OnUpdateMessage(const SessionMessage& msg, MessageError* error);
+ bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error);
bool OnRedirectError(const SessionRedirect& redirect, SessionError* error);
// Verifies that we are in the appropriate state to receive this message.
diff --git a/talk/p2p/base/session_unittest.cc b/talk/p2p/base/session_unittest.cc
index e6f0d43..e663113 100644
--- a/talk/p2p/base/session_unittest.cc
+++ b/talk/p2p/base/session_unittest.cc
@@ -567,7 +567,7 @@
port_offset_(port_offset),
ports_(kNumPorts),
address_("127.0.0.1", 0),
- network_("network", "unittest", address_.ip()),
+ network_("network", "unittest", address_.ipaddr()),
socket_factory_(talk_base::Thread::Current()),
running_(false),
port_(28653) {
@@ -583,7 +583,7 @@
int index = port_offset_ + i;
ports_[i] = cricket::UDPPort::Create(
talk_base::Thread::Current(), &socket_factory_,
- &network_, address_.ip(), GetPort(index), GetPort(index));
+ &network_, address_.ipaddr(), GetPort(index), GetPort(index));
ports_[i]->set_username_fragment(GetUsername(index));
ports_[i]->set_password(GetPassword(index));
AddPort(ports_[i]);
@@ -1027,7 +1027,7 @@
session->CreateChannel(content_name_a, channel_name_a));
chan_b = new ChannelHandler(
session->CreateChannel(content_name_b, channel_name_b));
- if (chan_aa == NULL && chan_bb == NULL) {
+ if (!channel_name_aa.empty() && !channel_name_bb.empty()) {
chan_aa = new ChannelHandler(
session->CreateChannel(content_name_a, channel_name_aa));
chan_bb = new ChannelHandler(
@@ -2065,14 +2065,12 @@
// initiates to a client with protocol Y, they end up speaking protocol Z.
// Gingle => Gingle = Gingle (with other content)
-// Disabled due to flakey pulse builds
-TEST_F(SessionTest, DISABLED_GingleToGingleOtherContent) {
+TEST_F(SessionTest, GingleToGingleOtherContent) {
TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
}
// Gingle => Gingle = Gingle (with audio content)
-// Disabled due to flakey pulse builds
-TEST_F(SessionTest, DISABLED_GingleToGingleAudioContent) {
+TEST_F(SessionTest, GingleToGingleAudioContent) {
TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
}
@@ -2199,8 +2197,7 @@
TestRejection(PROTOCOL_JINGLE);
}
-// Disabled due to flakey pulse builds
-TEST_F(SessionTest, DISABLED_GingleGoodRedirect) {
+TEST_F(SessionTest, GingleGoodRedirect) {
TestGoodRedirect(PROTOCOL_GINGLE);
}
diff --git a/talk/p2p/base/sessionmessages.cc b/talk/p2p/base/sessionmessages.cc
index 840d1a6..96f91d1 100644
--- a/talk/p2p/base/sessionmessages.cc
+++ b/talk/p2p/base/sessionmessages.cc
@@ -73,9 +73,9 @@
if (type == JINGLE_ACTION_TRANSPORT_ACCEPT)
return ACTION_TRANSPORT_ACCEPT;
if (type == JINGLE_ACTION_DESCRIPTION_INFO)
- return ACTION_UPDATE;
+ return ACTION_DESCRIPTION_INFO;
if (type == GINGLE_ACTION_UPDATE)
- return ACTION_UPDATE;
+ return ACTION_DESCRIPTION_INFO;
return ACTION_UNKNOWN;
}
diff --git a/talk/p2p/base/sessionmessages.h b/talk/p2p/base/sessionmessages.h
index 214fa8c..1486f0c 100644
--- a/talk/p2p/base/sessionmessages.h
+++ b/talk/p2p/base/sessionmessages.h
@@ -62,7 +62,7 @@
ACTION_TRANSPORT_INFO,
ACTION_TRANSPORT_ACCEPT,
- ACTION_UPDATE,
+ ACTION_DESCRIPTION_INFO,
};
// Abstraction of a <jingle> element within an <iq> stanza, per XMPP
diff --git a/talk/p2p/base/stun.cc b/talk/p2p/base/stun.cc
index fab14af..3b3fad4 100644
--- a/talk/p2p/base/stun.cc
+++ b/talk/p2p/base/stun.cc
@@ -347,6 +347,7 @@
uint8 family;
// We don't expect IPv6 address here because IPv6 addresses would
// not pass the attribute size check in StunAttribute::Create().
+ // TODO: Support IPv6 addresses.
if (!buf->ReadUInt8(&family) || family != STUN_ADDRESS_IPV4) {
return false;
}
@@ -354,9 +355,10 @@
if (!buf->ReadUInt16(&port_))
return false;
-
- if (!buf->ReadUInt32(&ip_))
+ uint32 ip;
+ if (!buf->ReadUInt32(&ip))
return false;
+ SetIP(talk_base::IPAddress(ip));
return true;
}
@@ -368,7 +370,7 @@
buf->WriteUInt8(0);
buf->WriteUInt8(family_);
buf->WriteUInt16(port_);
- buf->WriteUInt32(ip_);
+ buf->WriteUInt32(ip_.v4AddressAsHostOrderInteger());
}
StunXorAddressAttribute::StunXorAddressAttribute(uint16 type)
@@ -380,7 +382,8 @@
return false;
SetPort(port() ^ (kStunMagicCookie >> 16));
- SetIP(ip() ^ kStunMagicCookie);
+ uint32 ip = ipaddr().v4AddressAsHostOrderInteger();
+ SetIP(talk_base::IPAddress(ip ^ kStunMagicCookie));
return true;
}
@@ -392,7 +395,7 @@
buf->WriteUInt8(0);
buf->WriteUInt8(family());
buf->WriteUInt16(port() ^ (kStunMagicCookie >> 16));
- buf->WriteUInt32(ip() ^ kStunMagicCookie);
+ buf->WriteUInt32(ipaddr().v4AddressAsHostOrderInteger() ^ kStunMagicCookie);
}
StunUInt32Attribute::StunUInt32Attribute(uint16 type)
diff --git a/talk/p2p/base/stun.h b/talk/p2p/base/stun.h
index efc5f2c..87687b1 100644
--- a/talk/p2p/base/stun.h
+++ b/talk/p2p/base/stun.h
@@ -36,6 +36,7 @@
#include "talk/base/basictypes.h"
#include "talk/base/bytebuffer.h"
+#include "talk/base/ipaddress.h"
namespace cricket {
@@ -206,6 +207,7 @@
};
// Implements STUN/TURN attributes that record an Internet address.
+// TODO: IPv6 support, and use the SocketAddress class.
class StunAddressAttribute : public StunAttribute {
public:
explicit StunAddressAttribute(uint16 type);
@@ -214,10 +216,10 @@
StunAddressFamily family() const { return family_; }
uint16 port() const { return port_; }
- uint32 ip() const { return ip_; }
+ talk_base::IPAddress ipaddr() const { return ip_; }
void SetFamily(StunAddressFamily family);
- void SetIP(uint32 ip) { ip_ = ip; }
+ void SetIP(const talk_base::IPAddress& ip) { ip_ = ip; }
void SetPort(uint16 port) { port_ = port; }
virtual bool Read(talk_base::ByteBuffer* buf);
@@ -226,7 +228,7 @@
private:
StunAddressFamily family_;
uint16 port_;
- uint32 ip_;
+ talk_base::IPAddress ip_;
};
// Implements STUN/TURN attributes that record an Internet address.
diff --git a/talk/p2p/base/stun_unittest.cc b/talk/p2p/base/stun_unittest.cc
index 16dc26c..34b6059 100644
--- a/talk/p2p/base/stun_unittest.cc
+++ b/talk/p2p/base/stun_unittest.cc
@@ -158,12 +158,12 @@
EXPECT_TRUE(addr != NULL);
EXPECT_EQ(1, addr->family());
EXPECT_EQ(13, addr->port());
- EXPECT_EQ(17U, addr->ip());
+ EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
StunAddressAttribute* addr2 =
StunAttribute::CreateAddress(STUN_ATTR_MAPPED_ADDRESS);
addr2->SetPort(13);
- addr2->SetIP(17);
+ addr2->SetIP(talk_base::IPAddress(17U));
msg2.AddAttribute(addr2);
const StunByteStringAttribute* bytes = msg.GetByteString(STUN_ATTR_USERNAME);
@@ -239,22 +239,22 @@
EXPECT_TRUE(addr != NULL);
EXPECT_EQ(1, addr->family());
EXPECT_EQ(13, addr->port());
- EXPECT_EQ(17U, addr->ip());
+ EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
addr2 = StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS);
addr2->SetPort(13);
- addr2->SetIP(17);
+ addr2->SetIP(talk_base::IPAddress(17U));
msg2.AddAttribute(addr2);
addr = msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2);
EXPECT_TRUE(addr != NULL);
EXPECT_EQ(1, addr->family());
EXPECT_EQ(13, addr->port());
- EXPECT_EQ(17U, addr->ip());
+ EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
addr2 = StunAttribute::CreateAddress(STUN_ATTR_SOURCE_ADDRESS2);
addr2->SetPort(13);
- addr2->SetIP(17);
+ addr2->SetIP(talk_base::IPAddress(17U));
msg2.AddAttribute(addr2);
bytes = msg.GetByteString(STUN_ATTR_DATA);
@@ -306,7 +306,7 @@
EXPECT_TRUE(addr != NULL);
EXPECT_EQ(1, addr->family());
EXPECT_EQ(13, addr->port());
- EXPECT_EQ(17U, addr->ip());
+ EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
const StunUInt32Attribute* uval = msg.GetUInt32(STUN_ATTR_LIFETIME);
EXPECT_TRUE(uval != NULL);
@@ -324,11 +324,11 @@
EXPECT_TRUE(addr != NULL);
EXPECT_EQ(1, addr->family());
EXPECT_EQ(13, addr->port());
- EXPECT_EQ(17U, addr->ip());
+ EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
addr = msg.GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
EXPECT_TRUE(addr != NULL);
EXPECT_EQ(1, addr->family());
EXPECT_EQ(13, addr->port());
- EXPECT_EQ(17U, addr->ip());
+ EXPECT_EQ(talk_base::IPAddress(17U), addr->ipaddr());
}
diff --git a/talk/p2p/base/stunport.cc b/talk/p2p/base/stunport.cc
index ba797ff..7328b99 100644
--- a/talk/p2p/base/stunport.cc
+++ b/talk/p2p/base/stunport.cc
@@ -66,7 +66,7 @@
} else if (addr_attr->family() != 1) {
LOG(LS_ERROR) << "Binding address has bad family";
} else {
- talk_base::SocketAddress addr(addr_attr->ip(), addr_attr->port());
+ talk_base::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port());
port_->AddAddress(addr, "udp", true);
}
@@ -127,7 +127,7 @@
StunPort::StunPort(talk_base::Thread* thread,
talk_base::PacketSocketFactory* factory,
talk_base::Network* network,
- uint32 ip, int min_port, int max_port,
+ const talk_base::IPAddress& ip, int min_port, int max_port,
const talk_base::SocketAddress& server_addr)
: Port(thread, STUN_PORT_TYPE, factory, network, ip, min_port, max_port),
server_addr_(server_addr),
diff --git a/talk/p2p/base/stunport.h b/talk/p2p/base/stunport.h
index 26f46a5..c74ad4d 100644
--- a/talk/p2p/base/stunport.h
+++ b/talk/p2p/base/stunport.h
@@ -49,7 +49,8 @@
static StunPort* Create(talk_base::Thread* thread,
talk_base::PacketSocketFactory* factory,
talk_base::Network* network,
- uint32 ip, int min_port, int max_port,
+ const talk_base::IPAddress& ip,
+ int min_port, int max_port,
const talk_base::SocketAddress& server_addr) {
StunPort* port = new StunPort(thread, factory, network,
ip, min_port, max_port, server_addr);
@@ -88,7 +89,8 @@
protected:
StunPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
- talk_base::Network* network, uint32 ip, int min_port, int max_port,
+ talk_base::Network* network, const talk_base::IPAddress& ip,
+ int min_port, int max_port,
const talk_base::SocketAddress& server_addr);
bool Init();
diff --git a/talk/p2p/base/stunport_unittest.cc b/talk/p2p/base/stunport_unittest.cc
index 6dd1ee4..3d830ba 100644
--- a/talk/p2p/base/stunport_unittest.cc
+++ b/talk/p2p/base/stunport_unittest.cc
@@ -48,7 +48,7 @@
public sigslot::has_slots<> {
public:
StunPortTest()
- : network_("unittest", "unittest", 0),
+ : network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY)),
socket_factory_(talk_base::Thread::Current()),
stun_server_(new cricket::TestStunServer(
talk_base::Thread::Current(), kStunAddr)),
@@ -62,7 +62,7 @@
void CreateStunPort(const talk_base::SocketAddress& server_addr) {
stun_port_.reset(cricket::StunPort::Create(
talk_base::Thread::Current(), &socket_factory_, &network_,
- kLocalAddr.ip(), 0, 0, server_addr));
+ kLocalAddr.ipaddr(), 0, 0, server_addr));
stun_port_->SignalAddressReady.connect(this,
&StunPortTest::OnAddressReady);
stun_port_->SignalAddressError.connect(this,
diff --git a/talk/p2p/base/stunserver.cc b/talk/p2p/base/stunserver.cc
index f34fd2d..8a5d447 100644
--- a/talk/p2p/base/stunserver.cc
+++ b/talk/p2p/base/stunserver.cc
@@ -96,7 +96,7 @@
mapped_addr = StunAttribute::CreateAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
}
mapped_addr->SetPort(remote_addr.port());
- mapped_addr->SetIP(remote_addr.ip());
+ mapped_addr->SetIP(remote_addr.ipaddr());
response.AddAttribute(mapped_addr);
// TODO: Add username and message-integrity.
diff --git a/talk/p2p/base/stunserver_unittest.cc b/talk/p2p/base/stunserver_unittest.cc
index a475101..b7f2f00 100644
--- a/talk/p2p/base/stunserver_unittest.cc
+++ b/talk/p2p/base/stunserver_unittest.cc
@@ -99,11 +99,10 @@
EXPECT_TRUE(mapped_addr != NULL);
EXPECT_EQ(1, mapped_addr->family());
EXPECT_EQ(client_addr.port(), mapped_addr->port());
- if (mapped_addr->ip() != client_addr.ip()) {
+ if (mapped_addr->ipaddr() != client_addr.ipaddr()) {
LOG(LS_WARNING) << "Warning: mapped IP ("
- << talk_base::SocketAddress::IPToString(
- mapped_addr->ip()).c_str()
- << ") != local IP (" << client_addr.IPAsString().c_str()
+ << mapped_addr->ipaddr()
+ << ") != local IP (" << client_addr.ipaddr()
<< ")";
}
diff --git a/talk/p2p/base/tcpport.cc b/talk/p2p/base/tcpport.cc
index 555ba73..4db4761 100644
--- a/talk/p2p/base/tcpport.cc
+++ b/talk/p2p/base/tcpport.cc
@@ -35,7 +35,7 @@
TCPPort::TCPPort(talk_base::Thread* thread,
talk_base::PacketSocketFactory* factory,
- talk_base::Network* network, uint32 ip,
+ talk_base::Network* network, const talk_base::IPAddress& ip,
int min_port, int max_port, bool allow_listen)
: Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port),
incoming_only_(false),
@@ -218,7 +218,7 @@
}
} else {
// Incoming connections should match the network address.
- ASSERT(socket_->GetLocalAddress().ip() == port->ip_);
+ ASSERT(socket_->GetLocalAddress().ipaddr() == port->ip_);
}
if (socket_) {
diff --git a/talk/p2p/base/tcpport.h b/talk/p2p/base/tcpport.h
index 8345b12..5ce917d 100644
--- a/talk/p2p/base/tcpport.h
+++ b/talk/p2p/base/tcpport.h
@@ -50,7 +50,8 @@
static TCPPort* Create(talk_base::Thread* thread,
talk_base::PacketSocketFactory* factory,
talk_base::Network* network,
- uint32 ip, int min_port, int max_port,
+ const talk_base::IPAddress& ip,
+ int min_port, int max_port,
bool allow_listen) {
TCPPort* port = new TCPPort(thread, factory, network,
ip, min_port, max_port, allow_listen);
@@ -73,8 +74,8 @@
protected:
TCPPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
- talk_base::Network* network, uint32 ip, int min_port, int max_port,
- bool allow_listen);
+ talk_base::Network* network, const talk_base::IPAddress& ip,
+ int min_port, int max_port, bool allow_listen);
bool Init();
// Handles sending using the local TCP socket.
diff --git a/talk/p2p/base/udpport.cc b/talk/p2p/base/udpport.cc
index 8355b00..311fb45 100644
--- a/talk/p2p/base/udpport.cc
+++ b/talk/p2p/base/udpport.cc
@@ -38,7 +38,7 @@
UDPPort::UDPPort(talk_base::Thread* thread,
talk_base::PacketSocketFactory* factory,
talk_base::Network* network,
- uint32 ip, int min_port, int max_port)
+ const talk_base::IPAddress& ip, int min_port, int max_port)
: Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port),
socket_(NULL),
error_(0) {
diff --git a/talk/p2p/base/udpport.h b/talk/p2p/base/udpport.h
index d74d4a3..5d767bb 100644
--- a/talk/p2p/base/udpport.h
+++ b/talk/p2p/base/udpport.h
@@ -48,7 +48,8 @@
static UDPPort* Create(talk_base::Thread* thread,
talk_base::PacketSocketFactory* factory,
talk_base::Network* network,
- uint32 ip, int min_port, int max_port) {
+ const talk_base::IPAddress& ip,
+ int min_port, int max_port) {
UDPPort* port = new UDPPort(thread, factory, network,
ip, min_port, max_port);
if (!port->Init()) {
@@ -68,7 +69,8 @@
protected:
UDPPort(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
- talk_base::Network* network, uint32 ip, int min_port, int max_port);
+ talk_base::Network* network, const talk_base::IPAddress& ip,
+ int min_port, int max_port);
bool Init();
// Handles sending using the local UDP socket.
diff --git a/talk/p2p/client/basicportallocator.cc b/talk/p2p/client/basicportallocator.cc
index 51d069e..ec13b86 100644
--- a/talk/p2p/client/basicportallocator.cc
+++ b/talk/p2p/client/basicportallocator.cc
@@ -154,7 +154,7 @@
BasicPortAllocatorSession* session_;
talk_base::Network* network_;
- uint32 ip_;
+ talk_base::IPAddress ip_;
PortConfiguration* config_;
bool running_;
int step_;
diff --git a/talk/p2p/client/portallocator_unittest.cc b/talk/p2p/client/portallocator_unittest.cc
index 9c7db4d..be3a4e1 100644
--- a/talk/p2p/client/portallocator_unittest.cc
+++ b/talk/p2p/client/portallocator_unittest.cc
@@ -104,7 +104,7 @@
const std::string& proto,
const SocketAddress& addr) {
return (c.name() == name && c.type() == type &&
- c.protocol() == proto && c.address().ip() == addr.ip() &&
+ c.protocol() == proto && c.address().ipaddr() == addr.ipaddr() &&
(addr.port() == 0 || (c.address().port() == addr.port())));
}
static bool CheckPort(const talk_base::SocketAddress& addr,
diff --git a/talk/session/phone/call.cc b/talk/session/phone/call.cc
index e01e937..4b2e229 100644
--- a/talk/session/phone/call.cc
+++ b/talk/session/phone/call.cc
@@ -151,7 +151,7 @@
XmlElements elems;
WriteError error;
- if (!WriteViewRequest(CN_VIDEO, view_request, &elems, &error)) {
+ if (!WriteJingleViewRequest(CN_VIDEO, view_request, &elems, &error)) {
LOG(LS_ERROR) << "Couldn't write out view request: " << error.text;
return false;
}
diff --git a/talk/session/phone/channel.cc b/talk/session/phone/channel.cc
index 42506dd..90d917d 100644
--- a/talk/session/phone/channel.cc
+++ b/talk/session/phone/channel.cc
@@ -559,6 +559,8 @@
return ret;
}
+// TODO: Check all of the ssrcs in all of the streams in
+// the content, and not just the first one.
bool BaseChannel::SetSsrcMux_w(bool enable,
const MediaContentDescription* content,
ContentAction action,
@@ -567,12 +569,12 @@
if (action == CA_OFFER) {
ret = ssrc_filter_.SetOffer(enable, src);
if (ret && src == CS_REMOTE) { // if received offer with ssrc
- ret = ssrc_filter_.AddStream(content->ssrc());
+ ret = ssrc_filter_.AddStream(content->first_ssrc());
}
} else if (action == CA_ANSWER) {
ret = ssrc_filter_.SetAnswer(enable, src);
if (ret && src == CS_REMOTE && ssrc_filter_.IsActive()) {
- ret = ssrc_filter_.AddStream(content->ssrc());
+ ret = ssrc_filter_.AddStream(content->first_ssrc());
}
}
return ret;
@@ -838,9 +840,10 @@
ASSERT(audio != NULL);
bool ret;
- if (audio->ssrc_set()) {
- media_channel()->SetSendSsrc(audio->ssrc());
- LOG(LS_INFO) << "Set send ssrc for audio: " << audio->ssrc();
+ if (audio->has_ssrcs()) {
+ // TODO: Handle multiple streams and ssrcs here.
+ media_channel()->SetSendSsrc(audio->first_ssrc());
+ LOG(LS_INFO) << "Set send ssrc for audio: " << audio->first_ssrc();
}
// Set local SRTP parameters (what we will encrypt with).
ret = SetSrtp_w(audio->cryptos(), action, CS_LOCAL);
@@ -850,7 +853,7 @@
}
// Set SSRC mux filter
if (ret) {
- ret = SetSsrcMux_w(audio->ssrc_set(), content, action, CS_LOCAL);
+ ret = SetSsrcMux_w(audio->has_ssrcs(), content, action, CS_LOCAL);
}
// Set local audio codecs (what we want to receive).
if (ret) {
@@ -889,7 +892,7 @@
}
// Set SSRC mux filter
if (ret) {
- ret = SetSsrcMux_w(audio->ssrc_set(), content, action, CS_REMOTE);
+ ret = SetSsrcMux_w(audio->has_ssrcs(), content, action, CS_REMOTE);
}
// Set remote video codecs (what the other side wants to receive).
@@ -1201,9 +1204,10 @@
ASSERT(video != NULL);
bool ret;
- if (video->ssrc_set()) {
- media_channel()->SetSendSsrc(video->ssrc());
- LOG(LS_INFO) << "Set send ssrc for video: " << video->ssrc();
+ if (video->has_ssrcs()) {
+ // TODO: Handle multiple streams and ssrcs here.
+ media_channel()->SetSendSsrc(video->first_ssrc());
+ LOG(LS_INFO) << "Set send ssrc for video: " << video->first_ssrc();
}
// Set local SRTP parameters (what we will encrypt with).
ret = SetSrtp_w(video->cryptos(), action, CS_LOCAL);
@@ -1213,7 +1217,7 @@
}
// Set SSRC mux filter
if (ret) {
- ret = SetSsrcMux_w(video->ssrc_set(), content, action, CS_LOCAL);
+ ret = SetSsrcMux_w(video->has_ssrcs(), content, action, CS_LOCAL);
}
// Set local video codecs (what we want to receive).
@@ -1253,7 +1257,7 @@
}
// Set SSRC mux filter
if (ret) {
- ret = SetSsrcMux_w(video->ssrc_set(), content, action, CS_REMOTE);
+ ret = SetSsrcMux_w(video->has_ssrcs(), content, action, CS_REMOTE);
}
// Set remote video codecs (what the other side wants to receive).
if (ret) {
diff --git a/talk/session/phone/devicemanager_unittest.cc b/talk/session/phone/devicemanager_unittest.cc
index 91afdc8..a64eab9 100644
--- a/talk/session/phone/devicemanager_unittest.cc
+++ b/talk/session/phone/devicemanager_unittest.cc
@@ -29,11 +29,12 @@
#include "talk/base/win32.h"
#include <objbase.h>
#endif
+#include "talk/base/fileutils.h"
#include "talk/base/gunit.h"
#include "talk/base/logging.h"
-#include "talk/base/stream.h"
-#include "talk/base/fileutils.h"
#include "talk/base/pathutils.h"
+#include "talk/base/scoped_ptr.h"
+#include "talk/base/stream.h"
#include "talk/session/phone/devicemanager.h"
#include "talk/session/phone/v4llookup.h"
@@ -42,50 +43,47 @@
#include "talk/base/fileutils_mock.h"
#endif // LINUX
+#include "talk/session/phone/devicemanager.h"
+
using talk_base::Pathname;
using talk_base::FileTimeType;
+using talk_base::scoped_ptr;
using cricket::Device;
+using cricket::DeviceManager;
+using cricket::DeviceManagerFactory;
+using cricket::DeviceManagerInterface;
// Test that we startup/shutdown properly.
TEST(DeviceManagerTest, StartupShutdown) {
- cricket::DeviceManager dm;
- EXPECT_FALSE(dm.initialized());
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.initialized());
- dm.Terminate();
- EXPECT_FALSE(dm.initialized());
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
+ EXPECT_TRUE(dm->Init());
+ dm->Terminate();
}
// Test CoInitEx behavior
#ifdef WIN32
TEST(DeviceManagerTest, CoInitialize) {
- cricket::DeviceManager dm;
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> devices;
// Ensure that calls to video device work if COM is not yet initialized.
- EXPECT_FALSE(dm.initialized());
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.initialized());
- EXPECT_TRUE(dm.GetVideoCaptureDevices(&devices));
- dm.Terminate();
+ EXPECT_TRUE(dm->Init());
+ EXPECT_TRUE(dm->GetVideoCaptureDevices(&devices));
+ dm->Terminate();
// Ensure that the ref count is correct.
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
CoUninitialize();
// Ensure that Init works in COINIT_APARTMENTTHREADED setting.
- EXPECT_FALSE(dm.initialized());
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.initialized());
- dm.Terminate();
+ EXPECT_TRUE(dm->Init());
+ dm->Terminate();
CoUninitialize();
// Ensure that the ref count is correct.
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
CoUninitialize();
// Ensure that Init works in COINIT_MULTITHREADED setting.
- EXPECT_FALSE(dm.initialized());
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.initialized());
- dm.Terminate();
+ EXPECT_TRUE(dm->Init());
+ dm->Terminate();
CoUninitialize();
// Ensure that the ref count is correct.
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
@@ -95,52 +93,52 @@
// Test enumerating devices (although we may not find any).
TEST(DeviceManagerTest, GetDevices) {
- cricket::DeviceManager dm;
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> audio_ins, audio_outs, video_ins;
std::vector<cricket::Device> video_in_devs;
cricket::Device def_video;
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.GetAudioInputDevices(&audio_ins));
- EXPECT_TRUE(dm.GetAudioOutputDevices(&audio_outs));
- EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
- EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_in_devs));
+ EXPECT_TRUE(dm->Init());
+ EXPECT_TRUE(dm->GetAudioInputDevices(&audio_ins));
+ EXPECT_TRUE(dm->GetAudioOutputDevices(&audio_outs));
+ EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
+ EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_in_devs));
EXPECT_EQ(video_ins.size(), video_in_devs.size());
// If we have any video devices, we should be able to pick a default.
- EXPECT_TRUE(dm.GetVideoCaptureDevice(
+ EXPECT_TRUE(dm->GetVideoCaptureDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &def_video)
!= video_ins.empty());
}
// Test that we return correct ids for default and bogus devices.
TEST(DeviceManagerTest, GetAudioDeviceIds) {
- cricket::DeviceManager dm;
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
Device device;
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.GetAudioInputDevice(
+ EXPECT_TRUE(dm->Init());
+ EXPECT_TRUE(dm->GetAudioInputDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
EXPECT_EQ("-1", device.id);
- EXPECT_TRUE(dm.GetAudioOutputDevice(
+ EXPECT_TRUE(dm->GetAudioOutputDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
EXPECT_EQ("-1", device.id);
- EXPECT_FALSE(dm.GetAudioInputDevice("_NOT A REAL DEVICE_", &device));
- EXPECT_FALSE(dm.GetAudioOutputDevice("_NOT A REAL DEVICE_", &device));
+ EXPECT_FALSE(dm->GetAudioInputDevice("_NOT A REAL DEVICE_", &device));
+ EXPECT_FALSE(dm->GetAudioOutputDevice("_NOT A REAL DEVICE_", &device));
}
// Test that we get the video capture device by name properly.
TEST(DeviceManagerTest, GetVideoDeviceIds) {
- cricket::DeviceManager dm;
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
Device device;
- EXPECT_TRUE(dm.Init());
- EXPECT_FALSE(dm.GetVideoCaptureDevice("_NOT A REAL DEVICE_", &device));
+ EXPECT_TRUE(dm->Init());
+ EXPECT_FALSE(dm->GetVideoCaptureDevice("_NOT A REAL DEVICE_", &device));
std::vector<Device> video_ins;
- EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
+ EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
if (!video_ins.empty()) {
// Get the default device with the parameter kDefaultDeviceName.
- EXPECT_TRUE(dm.GetVideoCaptureDevice(
+ EXPECT_TRUE(dm->GetVideoCaptureDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
// Get the first device with the parameter video_ins[0].name.
- EXPECT_TRUE(dm.GetVideoCaptureDevice(video_ins[0].name, &device));
+ EXPECT_TRUE(dm->GetVideoCaptureDevice(video_ins[0].name, &device));
EXPECT_EQ(device.name, video_ins[0].name);
EXPECT_EQ(device.id, video_ins[0].id);
}
@@ -148,15 +146,15 @@
TEST(DeviceManagerTest, VerifyDevicesListsAreCleared) {
const std::string imaginary("_NOT A REAL DEVICE_");
- cricket::DeviceManager dm;
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> audio_ins, audio_outs, video_ins;
audio_ins.push_back(Device(imaginary, imaginary));
audio_outs.push_back(Device(imaginary, imaginary));
video_ins.push_back(Device(imaginary, imaginary));
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.GetAudioInputDevices(&audio_ins));
- EXPECT_TRUE(dm.GetAudioOutputDevices(&audio_outs));
- EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
+ EXPECT_TRUE(dm->Init());
+ EXPECT_TRUE(dm->GetAudioInputDevices(&audio_ins));
+ EXPECT_TRUE(dm->GetAudioOutputDevices(&audio_outs));
+ EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
for (size_t i = 0; i < audio_ins.size(); ++i) {
EXPECT_NE(imaginary, audio_ins[i].name);
}
@@ -168,6 +166,57 @@
}
}
+static bool CompareDeviceList(std::vector<Device>& devices,
+ const char* const device_list[], int list_size) {
+ if (list_size != static_cast<int>(devices.size())) {
+ return false;
+ }
+ for (int i = 0; i < list_size; ++i) {
+ if (devices[i].name.compare(device_list[i]) != 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+TEST(DeviceManagerTest, VerifyFilterDevices) {
+ static const char* const kTotalDevicesName[] = {
+ "Google Camera Adapters are tons of fun.",
+ "device1",
+ "device2",
+ "device3",
+ "device4",
+ "device5",
+ "Google Camera Adapter 0",
+ "Google Camera Adapter 1",
+ };
+ static const char* const kFilteredDevicesName[] = {
+ "device2",
+ "device4",
+ "Google Camera Adapter",
+ NULL,
+ };
+ static const char* const kDevicesName[] = {
+ "device1",
+ "device3",
+ "device5",
+ };
+ std::vector<Device> devices;
+ for (int i = 0; i < ARRAY_SIZE(kTotalDevicesName); ++i) {
+ devices.push_back(Device(kTotalDevicesName[i], i));
+ }
+ EXPECT_TRUE(CompareDeviceList(devices, kTotalDevicesName,
+ ARRAY_SIZE(kTotalDevicesName)));
+ // Return false if given NULL as the exclusion list.
+ EXPECT_TRUE(DeviceManager::FilterDevices(&devices, NULL));
+ // The devices should not change.
+ EXPECT_TRUE(CompareDeviceList(devices, kTotalDevicesName,
+ ARRAY_SIZE(kTotalDevicesName)));
+ EXPECT_TRUE(DeviceManager::FilterDevices(&devices, kFilteredDevicesName));
+ EXPECT_TRUE(CompareDeviceList(devices, kDevicesName,
+ ARRAY_SIZE(kDevicesName)));
+}
+
#ifdef LINUX
class FakeV4LLookup : public cricket::V4LLookup {
public:
@@ -202,10 +251,10 @@
"Video Device 2"));
talk_base::FilesystemScope fs(new talk_base::FakeFileSystem(files));
- cricket::DeviceManager dm;
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> video_ins;
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
+ EXPECT_TRUE(dm->Init());
+ EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
EXPECT_EQ(2u, video_ins.size());
EXPECT_EQ("Video Device 1", video_ins.at(0).name);
EXPECT_EQ("Video Device 2", video_ins.at(1).name);
@@ -231,10 +280,10 @@
"param1: value1\nname: Video Device 2\n param2: value2\n"));
talk_base::FilesystemScope fs(new talk_base::FakeFileSystem(files));
- cricket::DeviceManager dm;
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> video_ins;
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
+ EXPECT_TRUE(dm->Init());
+ EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
EXPECT_EQ(2u, video_ins.size());
EXPECT_EQ("Video Device 1", video_ins.at(0).name);
EXPECT_EQ("Video Device 2", video_ins.at(1).name);
@@ -252,10 +301,10 @@
files.push_back(talk_base::FakeFileSystem::File("/dev/video5", ""));
talk_base::FilesystemScope fs(new talk_base::FakeFileSystem(files));
- cricket::DeviceManager dm;
+ scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> video_ins;
- EXPECT_TRUE(dm.Init());
- EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
+ EXPECT_TRUE(dm->Init());
+ EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
EXPECT_EQ(2u, video_ins.size());
EXPECT_EQ("/dev/video0", video_ins.at(0).name);
EXPECT_EQ("/dev/video5", video_ins.at(1).name);
diff --git a/talk/session/phone/linuxdevicemanager.cc b/talk/session/phone/linuxdevicemanager.cc
index 5ebf9e3..6bad677 100644
--- a/talk/session/phone/linuxdevicemanager.cc
+++ b/talk/session/phone/linuxdevicemanager.cc
@@ -83,7 +83,7 @@
"surround50:",
"surround51:",
"surround71:",
- "iec958:" // S/PDIF
+ "iec958:", // S/PDIF
#endif
NULL,
};
diff --git a/talk/session/phone/mediamessages.cc b/talk/session/phone/mediamessages.cc
index 9031351..c40b03f 100644
--- a/talk/session/phone/mediamessages.cc
+++ b/talk/session/phone/mediamessages.cc
@@ -31,9 +31,12 @@
#include "talk/session/phone/mediamessages.h"
+#include "talk/base/logging.h"
#include "talk/base/stringencode.h"
#include "talk/p2p/base/constants.h"
+#include "talk/p2p/base/parsing.h"
#include "talk/session/phone/mediasessionclient.h"
+#include "talk/session/phone/streamparams.h"
#include "talk/xmllite/xmlelement.h"
namespace cricket {
@@ -96,19 +99,15 @@
bool ParseNamedSource(const buzz::XmlElement* source_elem,
NamedSource* named_source,
ParseError* error) {
- named_source->nick = source_elem->Attr(QN_JINGLE_DRAFT_SOURCE_NICK);
+ named_source->nick = source_elem->Attr(QN_NICK);
if (named_source->nick.empty()) {
return BadParse("Missing or invalid nick.", error);
}
- named_source->name = source_elem->Attr(QN_JINGLE_DRAFT_SOURCE_NAME);
- named_source->usage = source_elem->Attr(QN_JINGLE_DRAFT_SOURCE_USAGE);
- named_source->removed =
- STR_JINGLE_DRAFT_SOURCE_STATE_REMOVED ==
- source_elem->Attr(QN_JINGLE_DRAFT_SOURCE_STATE);
+ named_source->name = source_elem->Attr(QN_NAME);
const buzz::XmlElement* ssrc_elem =
- source_elem->FirstNamed(QN_JINGLE_DRAFT_SOURCE_SSRC);
+ source_elem->FirstNamed(QN_JINGLE_DRAFT_SSRC);
if (ssrc_elem != NULL && !ssrc_elem->BodyText().empty()) {
uint32 ssrc;
if (!ParseSsrc(ssrc_elem->BodyText(), &ssrc)) {
@@ -126,8 +125,8 @@
const std::string& type) {
buzz::XmlElement* view_elem =
new buzz::XmlElement(QN_JINGLE_DRAFT_VIEW, true);
- view_elem->AddAttr(QN_JINGLE_DRAFT_CONTENT_NAME, name);
- view_elem->SetAttr(QN_JINGLE_DRAFT_VIEW_TYPE, type);
+ view_elem->AddAttr(QN_NAME, name);
+ view_elem->SetAttr(QN_TYPE, type);
return view_elem;
}
@@ -144,16 +143,13 @@
const StaticVideoView& view) {
buzz::XmlElement* view_elem =
CreateVideoViewElem(content_name, STR_JINGLE_DRAFT_VIEW_TYPE_STATIC);
- AddXmlAttr(view_elem, QN_JINGLE_DRAFT_VIEW_SSRC, view.ssrc);
+ AddXmlAttr(view_elem, QN_SSRC, view.ssrc);
- buzz::XmlElement* params_elem = new buzz::XmlElement(
- QN_JINGLE_DRAFT_VIEW_PARAMS);
- AddXmlAttr(params_elem, QN_JINGLE_DRAFT_VIEW_PARAMS_WIDTH, view.width);
- AddXmlAttr(params_elem, QN_JINGLE_DRAFT_VIEW_PARAMS_HEIGHT, view.height);
- AddXmlAttr(params_elem, QN_JINGLE_DRAFT_VIEW_PARAMS_FRAMERATE,
- view.framerate);
- AddXmlAttr(params_elem, QN_JINGLE_DRAFT_VIEW_PARAMS_PREFERENCE,
- view.preference);
+ buzz::XmlElement* params_elem = new buzz::XmlElement(QN_JINGLE_DRAFT_PARAMS);
+ AddXmlAttr(params_elem, QN_WIDTH, view.width);
+ AddXmlAttr(params_elem, QN_HEIGHT, view.height);
+ AddXmlAttr(params_elem, QN_FRAMERATE, view.framerate);
+ AddXmlAttr(params_elem, QN_PREFERENCE, view.preference);
view_elem->AddElement(params_elem);
return view_elem;
@@ -200,10 +196,60 @@
RemoveSourceBySsrc(ssrc, &video_);
}
-bool WriteViewRequest(const std::string& content_name,
- const ViewRequest& request,
- XmlElements* elems,
- WriteError* error) {
+bool IsJingleViewRequest(const XmlElements& action_elems) {
+ return GetXmlElement(action_elems, QN_JINGLE_DRAFT_VIEW) != NULL;
+}
+
+bool ParseStaticVideoView(const buzz::XmlElement* view_elem,
+ StaticVideoView* view,
+ ParseError* error) {
+ if (!ParseSsrc(view_elem->Attr(QN_SSRC), &(view->ssrc))) {
+ return BadParse("Invalid or missing view ssrc.", error);
+ }
+
+ const buzz::XmlElement* params_elem =
+ view_elem->FirstNamed(QN_JINGLE_DRAFT_PARAMS);
+ if (params_elem) {
+ view->width = GetXmlAttr(params_elem, QN_WIDTH, 0);
+ view->height = GetXmlAttr(params_elem, QN_HEIGHT, 0);
+ view->framerate = GetXmlAttr(params_elem, QN_FRAMERATE, 0);
+ view->preference = GetXmlAttr(params_elem, QN_PREFERENCE, 0);
+ } else {
+ return BadParse("Missing view params.", error);
+ }
+
+ return true;
+}
+
+bool ParseJingleViewRequest(const XmlElements& action_elems,
+ ViewRequest* view_request,
+ ParseError* error) {
+ for (XmlElements::const_iterator iter = action_elems.begin();
+ iter != action_elems.end(); ++iter) {
+ const buzz::XmlElement* view_elem = *iter;
+ if (view_elem->Name() == QN_JINGLE_DRAFT_VIEW) {
+ std::string type = view_elem->Attr(QN_TYPE);
+ if (STR_JINGLE_DRAFT_VIEW_TYPE_NONE == type) {
+ view_request->static_video_views.clear();
+ return true;
+ } else if (STR_JINGLE_DRAFT_VIEW_TYPE_STATIC == type) {
+ StaticVideoView static_video_view(0, 0, 0, 0);
+ if (!ParseStaticVideoView(view_elem, &static_video_view, error)) {
+ return false;
+ }
+ view_request->static_video_views.push_back(static_video_view);
+ } else {
+ LOG(LS_INFO) << "Ingnoring unknown view type: " << type;
+ }
+ }
+ }
+ return true;
+}
+
+bool WriteJingleViewRequest(const std::string& content_name,
+ const ViewRequest& request,
+ XmlElements* elems,
+ WriteError* error) {
if (request.static_video_views.empty()) {
elems->push_back(CreateNoneVideoViewElem(content_name));
} else {
@@ -217,7 +263,7 @@
}
bool IsSourcesNotify(const buzz::XmlElement* action_elem) {
- return action_elem->FirstNamed(QN_JINGLE_DRAFT_NOTIFY) != NULL;
+ return action_elem->FirstNamed(QN_JINGLE_LEGACY_NOTIFY) != NULL;
}
bool ParseSourcesNotify(const buzz::XmlElement* action_elem,
@@ -225,14 +271,14 @@
MediaSources* sources,
ParseError* error) {
for (const buzz::XmlElement* notify_elem =
- action_elem->FirstNamed(QN_JINGLE_DRAFT_NOTIFY);
+ action_elem->FirstNamed(QN_JINGLE_LEGACY_NOTIFY);
notify_elem != NULL;
- notify_elem = notify_elem->NextNamed(QN_JINGLE_DRAFT_NOTIFY)) {
- std::string content_name = notify_elem->Attr(QN_JINGLE_DRAFT_CONTENT_NAME);
+ notify_elem = notify_elem->NextNamed(QN_JINGLE_LEGACY_NOTIFY)) {
+ std::string content_name = notify_elem->Attr(QN_NAME);
for (const buzz::XmlElement* source_elem =
- notify_elem->FirstNamed(QN_JINGLE_DRAFT_SOURCE);
+ notify_elem->FirstNamed(QN_JINGLE_LEGACY_SOURCE);
source_elem != NULL;
- source_elem = source_elem->NextNamed(QN_JINGLE_DRAFT_SOURCE)) {
+ source_elem = source_elem->NextNamed(QN_JINGLE_LEGACY_SOURCE)) {
NamedSource named_source;
if (!ParseNamedSource(source_elem, &named_source, error)) {
return false;
@@ -258,4 +304,150 @@
return true;
}
+bool ParseSsrcAsLegacyStream(const buzz::XmlElement* desc_elem,
+ std::vector<StreamParams>* streams,
+ ParseError* error) {
+ const std::string ssrc_str = desc_elem->Attr(QN_SSRC);
+ if (!ssrc_str.empty()) {
+ uint32 ssrc;
+ if (!ParseSsrc(ssrc_str, &ssrc)) {
+ return BadParse("Missing or invalid ssrc.", error);
+ }
+
+ streams->push_back(StreamParams::CreateLegacy(ssrc));
+ }
+ return true;
+}
+
+bool ParseSsrcs(const buzz::XmlElement* parent_elem,
+ std::vector<uint32>* ssrcs,
+ ParseError* error) {
+ for (const buzz::XmlElement* ssrc_elem =
+ parent_elem->FirstNamed(QN_JINGLE_DRAFT_SSRC);
+ ssrc_elem != NULL;
+ ssrc_elem = ssrc_elem->NextNamed(QN_JINGLE_DRAFT_SSRC)) {
+ uint32 ssrc;
+ if (!ParseSsrc(ssrc_elem->BodyText(), &ssrc)) {
+ return BadParse("Missing or invalid ssrc.", error);
+ }
+
+ ssrcs->push_back(ssrc);
+ }
+ return true;
+}
+
+bool ParseSsrcGroups(const buzz::XmlElement* parent_elem,
+ std::vector<SsrcGroup>* ssrc_groups,
+ ParseError* error) {
+ for (const buzz::XmlElement* group_elem =
+ parent_elem->FirstNamed(QN_JINGLE_DRAFT_SSRC_GROUP);
+ group_elem != NULL;
+ group_elem = group_elem->NextNamed(QN_JINGLE_DRAFT_SSRC_GROUP)) {
+ std::string semantics = group_elem->Attr(QN_SEMANTICS);
+ std::vector<uint32> ssrcs;
+ if (!ParseSsrcs(group_elem, &ssrcs, error)) {
+ return false;
+ }
+ ssrc_groups->push_back(SsrcGroup(semantics, ssrcs));
+ }
+ return true;
+}
+
+bool ParseJingleStream(const buzz::XmlElement* stream_elem,
+ std::vector<StreamParams>* streams,
+ ParseError* error) {
+ StreamParams stream;
+ stream.nick = stream_elem->Attr(QN_NICK);
+ stream.name = stream_elem->Attr(QN_NAME);
+ stream.type = stream_elem->Attr(QN_TYPE);
+ stream.display = stream_elem->Attr(QN_DISPLAY);
+ stream.cname = stream_elem->Attr(QN_CNAME);
+ if (!ParseSsrcs(stream_elem, &(stream.ssrcs), error)) {
+ return false;
+ }
+ std::vector<SsrcGroup> ssrc_groups;
+ if (!ParseSsrcGroups(stream_elem, &(stream.ssrc_groups), error)) {
+ return false;
+ }
+ streams->push_back(stream);
+ return true;
+}
+
+bool HasJingleStreams(const buzz::XmlElement* desc_elem) {
+ const buzz::XmlElement* streams_elem =
+ desc_elem->FirstNamed(QN_JINGLE_DRAFT_STREAMS);
+ return (streams_elem != NULL);
+}
+
+bool ParseJingleStreams(const buzz::XmlElement* desc_elem,
+ std::vector<StreamParams>* streams,
+ ParseError* error) {
+ const buzz::XmlElement* streams_elem =
+ desc_elem->FirstNamed(QN_JINGLE_DRAFT_STREAMS);
+ if (streams_elem == NULL) {
+ return BadParse("Missing streams element.", error);
+ }
+ for (const buzz::XmlElement* stream_elem =
+ streams_elem->FirstNamed(QN_JINGLE_DRAFT_STREAM);
+ stream_elem != NULL;
+ stream_elem = stream_elem->NextNamed(QN_JINGLE_DRAFT_STREAM)) {
+ if (!ParseJingleStream(stream_elem, streams, error)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void WriteSsrcs(const std::vector<uint32>& ssrcs,
+ buzz::XmlElement* parent_elem) {
+ for (std::vector<uint32>::const_iterator ssrc = ssrcs.begin();
+ ssrc != ssrcs.end(); ++ssrc) {
+ buzz::XmlElement* ssrc_elem =
+ new buzz::XmlElement(QN_JINGLE_DRAFT_SSRC, false);
+ SetXmlBody(ssrc_elem, *ssrc);
+
+ parent_elem->AddElement(ssrc_elem);
+ }
+}
+
+void WriteSsrcGroups(const std::vector<SsrcGroup>& groups,
+ buzz::XmlElement* parent_elem) {
+ for (std::vector<SsrcGroup>::const_iterator group = groups.begin();
+ group != groups.end(); ++group) {
+ buzz::XmlElement* group_elem =
+ new buzz::XmlElement(QN_JINGLE_DRAFT_SSRC_GROUP, false);
+ AddXmlAttrIfNonEmpty(group_elem, QN_SEMANTICS, group->semantics);
+ WriteSsrcs(group->ssrcs, group_elem);
+
+ parent_elem->AddElement(group_elem);
+ }
+}
+
+void WriteJingleStream(const StreamParams& stream,
+ buzz::XmlElement* parent_elem) {
+ buzz::XmlElement* stream_elem =
+ new buzz::XmlElement(QN_JINGLE_DRAFT_STREAM, false);
+ AddXmlAttrIfNonEmpty(stream_elem, QN_NICK, stream.nick);
+ AddXmlAttrIfNonEmpty(stream_elem, QN_NAME, stream.name);
+ AddXmlAttrIfNonEmpty(stream_elem, QN_TYPE, stream.type);
+ AddXmlAttrIfNonEmpty(stream_elem, QN_DISPLAY, stream.display);
+ AddXmlAttrIfNonEmpty(stream_elem, QN_CNAME, stream.cname);
+ WriteSsrcs(stream.ssrcs, stream_elem);
+ WriteSsrcGroups(stream.ssrc_groups, stream_elem);
+
+ parent_elem->AddElement(stream_elem);
+}
+
+void WriteJingleStreams(const std::vector<StreamParams>& streams,
+ buzz::XmlElement* parent_elem) {
+ buzz::XmlElement* streams_elem =
+ new buzz::XmlElement(QN_JINGLE_DRAFT_STREAMS, true);
+ for (std::vector<StreamParams>::const_iterator stream = streams.begin();
+ stream != streams.end(); ++stream) {
+ WriteJingleStream(*stream, streams_elem);
+ }
+
+ parent_elem->AddElement(streams_elem);
+}
+
} // namespace cricket
diff --git a/talk/session/phone/mediamessages.h b/talk/session/phone/mediamessages.h
index 541572f..11b9e89 100644
--- a/talk/session/phone/mediamessages.h
+++ b/talk/session/phone/mediamessages.h
@@ -45,6 +45,8 @@
namespace cricket {
+struct StreamParams;
+
// In a <notify> message, there are number of sources with names.
// This represents one such named source.
struct NamedSource {
@@ -57,7 +59,6 @@
std::string nick;
std::string name;
- std::string usage;
uint32 ssrc;
bool ssrc_set;
bool removed;
@@ -123,18 +124,29 @@
typedef std::vector<StaticVideoView> StaticVideoViews;
-// Represents a whole <view> message, which contains many views.
+// Represents a whole view request message, which contains many views.
struct ViewRequest {
StaticVideoViews static_video_views;
};
+// If the elems of a parent (usually <jingle>) constitute a view request.
+bool IsJingleViewRequest(const XmlElements& elems);
+
+// Parses a view request from jingle contents (<view>s). If it
+// fails, returns false and fills an error message.
+bool ParseJingleViewRequest(const XmlElements& elems,
+ ViewRequest* view_request,
+ ParseError* error);
+
// Serializes a view request to XML. If it fails, returns false and
// fills in an error message.
-bool WriteViewRequest(const std::string& content_name,
- const ViewRequest& view,
- XmlElements* elems,
- WriteError* error);
+bool WriteJingleViewRequest(const std::string& content_name,
+ const ViewRequest& view,
+ XmlElements* elems,
+ WriteError* error);
+// TODO: Get rid of legacy source notify and replace with
+// description-info as soon as reflector is capable of sending it.
bool IsSourcesNotify(const buzz::XmlElement* action_elem);
// Parses a notify message from XML. If it fails, returns false and
@@ -145,6 +157,19 @@
MediaSources* sources,
ParseError* error);
+// If the given elem has <streams>.
+bool HasJingleStreams(const buzz::XmlElement* desc_elem);
+
+// Parses streams from a jingle <description>. If it fails, returns
+// false and fills an error message.
+bool ParseJingleStreams(const buzz::XmlElement* desc_elem,
+ std::vector<StreamParams>* streams,
+ ParseError* error);
+
+// Write a <streams> element to the parent_elem.
+void WriteJingleStreams(const std::vector<StreamParams>& streams,
+ buzz::XmlElement* parent_elem);
+
} // namespace cricket
#endif // TALK_SESSION_PHONE_MEDIAMESSAGES_H_
diff --git a/talk/session/phone/mediamessages_unittest.cc b/talk/session/phone/mediamessages_unittest.cc
index e5ae12f..0290c02 100644
--- a/talk/session/phone/mediamessages_unittest.cc
+++ b/talk/session/phone/mediamessages_unittest.cc
@@ -81,7 +81,6 @@
static std::string NotifyAddXml(const std::string& content_name,
const std::string& nick,
const std::string& name,
- const std::string& usage,
const std::string& ssrc) {
return "<notify xmlns='google:jingle'"
" name='" + content_name + "'"
@@ -89,7 +88,6 @@
" <source"
" nick='" + nick + "'"
" name='" + name + "'"
- " usage='" + usage + "'"
" >"
" <ssrc>" + ssrc + "</ssrc>"
" </source>"
@@ -129,19 +127,56 @@
"</notify>";
}
- static std::string NotifyExplicitRemoveXml(const std::string& content_name,
- const std::string& nick,
- const std::string& ssrc) {
- return "<notify xmlns='google:jingle'"
- " name='" + content_name + "'"
+ static cricket::StreamParams CreateStream(const std::string& nick,
+ const std::string& name,
+ uint32 ssrc1,
+ uint32 ssrc2,
+ const std::string& semantics,
+ const std::string& type,
+ const std::string& display) {
+ StreamParams stream;
+ stream.nick = nick;
+ stream.name = name;
+ stream.ssrcs.push_back(ssrc1);
+ stream.ssrcs.push_back(ssrc2);
+ stream.ssrc_groups.push_back(
+ cricket::SsrcGroup(semantics, stream.ssrcs));
+ stream.type = type;
+ stream.display = display;
+ return stream;
+ }
+
+ static std::string StreamsXml(const std::string& stream1,
+ const std::string& stream2) {
+ return "<streams xmlns='google:jingle'>"
+ + stream1
+ + stream2 +
+ "</streams>";
+ }
+
+
+ static std::string StreamXml(const std::string& nick,
+ const std::string& name,
+ const std::string& ssrc1,
+ const std::string& ssrc2,
+ const std::string& semantics,
+ const std::string& type,
+ const std::string& display) {
+ return "<stream"
+ " nick='" + nick + "'"
+ " name='" + name + "'"
+ " type='" + type + "'"
+ " display='" + display + "'"
">"
- " <source"
- " nick='" + nick + "'"
- " state='removed'"
- " >"
- " <ssrc>" + ssrc + "</ssrc>"
- " </source>"
- "</notify>";
+ "<ssrc>" + ssrc1 + "</ssrc>"
+ "<ssrc>" + ssrc2 + "</ssrc>"
+ "<ssrc-group"
+ " semantics='" + semantics + "'"
+ ">"
+ "<ssrc>" + ssrc1 + "</ssrc>"
+ "<ssrc>" + ssrc2 + "</ssrc>"
+ "</ssrc-group>"
+ "</stream>";
}
static cricket::SessionDescription* CreateMediaSessionDescription(
@@ -161,7 +196,7 @@
} // anonymous namespace
// Test serializing/deserializing an empty <view> message.
-TEST_F(MediaMessagesTest, ViewNoneToXml) {
+TEST_F(MediaMessagesTest, ViewNoneToFromXml) {
talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem(
buzz::XmlElement::ForStr(kViewVideoNoneXml));
@@ -169,15 +204,22 @@
cricket::XmlElements actual_view_elems;
cricket::WriteError error;
- ASSERT_TRUE(cricket::WriteViewRequest(
+ EXPECT_FALSE(cricket::IsJingleViewRequest(actual_view_elems));
+ ASSERT_TRUE(cricket::WriteJingleViewRequest(
"video1", view_request, &actual_view_elems, &error));
ASSERT_EQ(1U, actual_view_elems.size());
EXPECT_EQ(expected_view_elem->Str(), actual_view_elems[0]->Str());
+
+ cricket::ParseError parse_error;
+ EXPECT_TRUE(cricket::IsJingleViewRequest(actual_view_elems));
+ ASSERT_TRUE(cricket::ParseJingleViewRequest(
+ actual_view_elems, &view_request, &parse_error));
+ EXPECT_EQ(0U, view_request.static_video_views.size());
}
// Test serializing/deserializing an a simple vga <view> message.
-TEST_F(MediaMessagesTest, ViewVgaToXml) {
+TEST_F(MediaMessagesTest, ViewVgaToFromXml) {
talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem1(
buzz::XmlElement::ForStr(ViewVideoStaticVgaXml("1234")));
talk_base::scoped_ptr<buzz::XmlElement> expected_view_elem2(
@@ -192,12 +234,37 @@
view_request.static_video_views.push_back(
cricket::StaticVideoView(2468, 640, 480, 30));
- ASSERT_TRUE(cricket::WriteViewRequest(
+ ASSERT_TRUE(cricket::WriteJingleViewRequest(
"video1", view_request, &actual_view_elems, &error));
ASSERT_EQ(2U, actual_view_elems.size());
EXPECT_EQ(expected_view_elem1->Str(), actual_view_elems[0]->Str());
EXPECT_EQ(expected_view_elem2->Str(), actual_view_elems[1]->Str());
+
+ view_request.static_video_views.clear();
+ cricket::ParseError parse_error;
+ EXPECT_TRUE(cricket::IsJingleViewRequest(actual_view_elems));
+ ASSERT_TRUE(cricket::ParseJingleViewRequest(
+ actual_view_elems, &view_request, &parse_error));
+ EXPECT_EQ(2U, view_request.static_video_views.size());
+ EXPECT_EQ(1234U, view_request.static_video_views[0].ssrc);
+ EXPECT_EQ(640, view_request.static_video_views[0].width);
+ EXPECT_EQ(480, view_request.static_video_views[0].height);
+ EXPECT_EQ(30, view_request.static_video_views[0].framerate);
+ EXPECT_EQ(2468U, view_request.static_video_views[1].ssrc);
+}
+
+// Test deserializing bad view XML.
+TEST_F(MediaMessagesTest, ParseBadViewXml) {
+ talk_base::scoped_ptr<buzz::XmlElement> view_elem(
+ buzz::XmlElement::ForStr(ViewVideoStaticVgaXml("not-an-ssrc")));
+ XmlElements view_elems;
+ view_elems.push_back(view_elem.get());
+
+ cricket::ViewRequest view_request;
+ cricket::ParseError parse_error;
+ ASSERT_FALSE(cricket::ParseJingleViewRequest(
+ view_elems, &view_request, &parse_error));
}
// Test serializing/deserializing an empty session-info message.
@@ -232,22 +299,19 @@
new buzz::XmlElement(cricket::QN_JINGLE));
action_elem->AddElement(
buzz::XmlElement::ForStr(NotifyAddXml(
- "video1", "Joe", "Facetime", "", "1234")));
+ "video1", "Joe", "Facetime", "1234")));
action_elem->AddElement(
buzz::XmlElement::ForStr(NotifyAddXml(
- "video1", "Bob", "Microsoft Word", "screencast", "2468")));
+ "video1", "Bob", "Microsoft Word", "2468")));
action_elem->AddElement(
buzz::XmlElement::ForStr(NotifyAddXml(
- "video1", "Bob", "", "", "3692")));
+ "video1", "Bob", "", "3692")));
action_elem->AddElement(
buzz::XmlElement::ForStr(NotifyImplicitRemoveXml(
"audio1", "Joe")));
action_elem->AddElement(
- buzz::XmlElement::ForStr(NotifyExplicitRemoveXml(
- "audio1", "Joe", "1234")));
- action_elem->AddElement(
buzz::XmlElement::ForStr(NotifyAddXml(
- "audio1", "Bob", "", "", "3692")));
+ "audio1", "Bob", "", "3692")));
action_elem->AddElement(
buzz::XmlElement::ForStr(NotifyTwoSourceXml(
"video1", "Joe", "1234", "Bob", "2468")));
@@ -261,18 +325,16 @@
&sources, &error));
ASSERT_EQ(5U, sources.video().size());
- ASSERT_EQ(3U, sources.audio().size());
+ ASSERT_EQ(2U, sources.audio().size());
EXPECT_EQ("Joe", sources.video()[0].nick);
EXPECT_EQ("Facetime", sources.video()[0].name);
- EXPECT_EQ("", sources.video()[0].usage);
EXPECT_EQ(1234U, sources.video()[0].ssrc);
EXPECT_TRUE(sources.video()[0].ssrc_set);
EXPECT_FALSE(sources.video()[0].removed);
EXPECT_EQ("Bob", sources.video()[1].nick);
EXPECT_EQ("Microsoft Word", sources.video()[1].name);
- EXPECT_EQ("screencast", sources.video()[1].usage);
EXPECT_EQ(2468U, sources.video()[1].ssrc);
EXPECT_TRUE(sources.video()[1].ssrc_set);
EXPECT_FALSE(sources.video()[0].removed);
@@ -281,7 +343,6 @@
EXPECT_EQ(3692U, sources.video()[2].ssrc);
EXPECT_TRUE(sources.video()[2].ssrc_set);
EXPECT_EQ("", sources.video()[2].name);
- EXPECT_EQ("", sources.video()[2].usage);
EXPECT_FALSE(sources.video()[0].removed);
EXPECT_EQ("Joe", sources.video()[3].nick);
@@ -293,16 +354,6 @@
EXPECT_EQ("Joe", sources.audio()[0].nick);
EXPECT_FALSE(sources.audio()[0].ssrc_set);
EXPECT_FALSE(sources.video()[0].removed);
-
- EXPECT_EQ("Joe", sources.audio()[1].nick);
- EXPECT_TRUE(sources.audio()[1].ssrc_set);
- EXPECT_EQ(1234U, sources.audio()[1].ssrc);
- EXPECT_TRUE(sources.audio()[1].removed);
-
- EXPECT_EQ("Bob", sources.audio()[2].nick);
- EXPECT_EQ(3692U, sources.audio()[2].ssrc);
- EXPECT_TRUE(sources.audio()[2].ssrc_set);
- EXPECT_FALSE(sources.audio()[2].removed);
}
// Test serializing/deserializing a malformed <notify> message.
@@ -314,7 +365,7 @@
talk_base::scoped_ptr<buzz::XmlElement> action_elem(
new buzz::XmlElement(cricket::QN_JINGLE));
action_elem->AddElement(
- buzz::XmlElement::ForStr(NotifyAddXml("video1", "Joe", "", "", "XYZ")));
+ buzz::XmlElement::ForStr(NotifyAddXml("video1", "Joe", "", "XYZ")));
EXPECT_TRUE(cricket::IsSourcesNotify(action_elem.get()));
EXPECT_FALSE(cricket::ParseSourcesNotify(
action_elem.get(), remote_description_.get(), &sources, &error));
@@ -322,10 +373,69 @@
// Bad nick
action_elem.reset(new buzz::XmlElement(cricket::QN_JINGLE));
action_elem->AddElement(
- buzz::XmlElement::ForStr(NotifyAddXml("video1", "", "", "", "1234")));
+ buzz::XmlElement::ForStr(NotifyAddXml("video1", "", "", "1234")));
EXPECT_TRUE(cricket::IsSourcesNotify(action_elem.get()));
EXPECT_FALSE(cricket::ParseSourcesNotify(
action_elem.get(), remote_description_.get(), &sources, &error));
}
+// Test serializing/deserializing typical streams xml.
+TEST_F(MediaMessagesTest, StreamsToFromXml) {
+ talk_base::scoped_ptr<buzz::XmlElement> expected_streams_elem(
+ buzz::XmlElement::ForStr(
+ StreamsXml(
+ StreamXml("nick1", "name1", "101", "102",
+ "semantics1", "type1", "display1"),
+ StreamXml("nick2", "name2", "201", "202",
+ "semantics2", "type2", "display2"))));
+
+ std::vector<cricket::StreamParams> expected_streams;
+ expected_streams.push_back(CreateStream("nick1", "name1", 101U, 102U,
+ "semantics1", "type1", "display1"));
+ expected_streams.push_back(CreateStream("nick2", "name2", 201U, 202U,
+ "semantics2", "type2", "display2"));
+
+ talk_base::scoped_ptr<buzz::XmlElement> actual_desc_elem(
+ new buzz::XmlElement(QN_JINGLE_RTP_CONTENT));
+ cricket::WriteJingleStreams(expected_streams, actual_desc_elem.get());
+
+ const buzz::XmlElement* actual_streams_elem =
+ actual_desc_elem->FirstNamed(QN_JINGLE_DRAFT_STREAMS);
+ ASSERT_TRUE(actual_streams_elem != NULL);
+ EXPECT_EQ(expected_streams_elem->Str(), actual_streams_elem->Str());
+
+ talk_base::scoped_ptr<buzz::XmlElement> expected_desc_elem(
+ new buzz::XmlElement(QN_JINGLE_RTP_CONTENT));
+ expected_desc_elem->AddElement(new buzz::XmlElement(
+ *expected_streams_elem));
+ std::vector<cricket::StreamParams> actual_streams;
+ cricket::ParseError parse_error;
+
+ EXPECT_TRUE(cricket::HasJingleStreams(expected_desc_elem.get()));
+ ASSERT_TRUE(cricket::ParseJingleStreams(
+ expected_desc_elem.get(), &actual_streams, &parse_error));
+ EXPECT_EQ(2U, actual_streams.size());
+ EXPECT_EQ(expected_streams[0], actual_streams[0]);
+ EXPECT_EQ(expected_streams[1], actual_streams[1]);
+}
+
+// Test deserializing bad streams xml.
+TEST_F(MediaMessagesTest, StreamsFromBadXml) {
+ talk_base::scoped_ptr<buzz::XmlElement> streams_elem(
+ buzz::XmlElement::ForStr(
+ StreamsXml(
+ StreamXml("nick1", "name1", "101", "not-an-ssrc",
+ "semantics1", "type1", "display1"),
+ StreamXml("nick2", "name2", "202", "not-an-ssrc",
+ "semantics2", "type2", "display2"))));
+ talk_base::scoped_ptr<buzz::XmlElement> desc_elem(
+ new buzz::XmlElement(QN_JINGLE_RTP_CONTENT));
+ desc_elem->AddElement(new buzz::XmlElement(*streams_elem));
+
+ std::vector<cricket::StreamParams> actual_streams;
+ cricket::ParseError parse_error;
+ ASSERT_FALSE(cricket::ParseJingleStreams(
+ desc_elem.get(), &actual_streams, &parse_error));
+}
+
} // namespace cricket
diff --git a/talk/session/phone/mediasession.cc b/talk/session/phone/mediasession.cc
index 9bb83e6..05875b5 100644
--- a/talk/session/phone/mediasession.cc
+++ b/talk/session/phone/mediasession.cc
@@ -233,8 +233,12 @@
}
uint32 ssrc = GenerateSsrc(*current_params);
// TODO: Generate the more complex types of stream_params.
- StreamParams stream_param(stream_it->name, ssrc, cname,
- stream_it->sync_label);
+
+ StreamParams stream_param;
+ stream_param.name = stream_it->name;
+ stream_param.ssrcs.push_back(ssrc);
+ stream_param.cname = cname;
+ stream_param.sync_label = stream_it->sync_label;
content_description->AddStream(stream_param);
// Store the new StreamParams in current_params.
@@ -303,8 +307,8 @@
}
if (options.streams.empty()) {
- // TODO: Remove this legacy ssrc when all apps use StreamParams.
- audio->set_ssrc(talk_base::CreateRandomNonZeroId());
+ // TODO: Remove this legacy stream when all apps use StreamParams.
+ audio->AddLegacyStream(talk_base::CreateRandomNonZeroId());
}
audio->set_rtcp_mux(true);
audio->set_lang(lang_);
@@ -355,8 +359,8 @@
}
if (options.streams.empty()) {
- // TODO: Remove this legacy ssrc when all apps use StreamParams.
- video->set_ssrc(talk_base::CreateRandomNonZeroId());
+ // TODO: Remove this legacy stream when all apps use StreamParams.
+ video->AddLegacyStream(talk_base::CreateRandomNonZeroId());
}
video->set_bandwidth(options.video_bandwidth);
video->set_rtcp_mux(true);
@@ -429,8 +433,8 @@
}
if (options.streams.empty()) {
- // TODO: Remove this legacy ssrc when all apps use StreamParams.
- audio_accept->set_ssrc(talk_base::CreateRandomNonZeroId());
+ // TODO: Remove this legacy stream when all apps use StreamParams.
+ audio_accept->AddLegacyStream(talk_base::CreateRandomNonZeroId());
}
audio_accept->set_rtcp_mux(audio_offer->rtcp_mux());
@@ -493,8 +497,8 @@
}
if (options.streams.empty()) {
- // TODO: Remove this legacy ssrc when all apps use StreamParams.
- video_accept->set_ssrc(talk_base::CreateRandomNonZeroId());
+ // TODO: Remove this legacy stream when all apps use StreamParams.
+ video_accept->AddLegacyStream(talk_base::CreateRandomNonZeroId());
}
video_accept->set_bandwidth(options.video_bandwidth);
video_accept->set_rtcp_mux(video_offer->rtcp_mux());
@@ -579,5 +583,3 @@
}
} // namespace cricket
-
-
diff --git a/talk/session/phone/mediasession.h b/talk/session/phone/mediasession.h
index ea4acd7..127a7ed 100644
--- a/talk/session/phone/mediasession.h
+++ b/talk/session/phone/mediasession.h
@@ -114,23 +114,15 @@
class MediaContentDescription : public ContentDescription {
public:
MediaContentDescription()
- : ssrc_(0),
- ssrc_set_(false),
- rtcp_mux_(false),
+ : rtcp_mux_(false),
bandwidth_(kAutoBandwidth),
crypto_required_(false),
- rtp_header_extensions_set_(false) {
+ rtp_header_extensions_set_(false),
+ multistream_(false) {
}
virtual MediaType type() const = 0;
- uint32 ssrc() const { return ssrc_; }
- bool ssrc_set() const { return ssrc_set_; }
- void set_ssrc(uint32 ssrc) {
- ssrc_ = ssrc;
- ssrc_set_ = true;
- }
-
bool rtcp_mux() const { return rtcp_mux_; }
void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; }
@@ -165,22 +157,46 @@
bool rtp_header_extensions_set() const {
return rtp_header_extensions_set_;
}
+ // True iff the client supports multiple streams.
+ void set_multistream(bool multistream) { multistream_ = multistream; }
+ bool multistream() const { return multistream_; }
const StreamParamsVec& streams() const {
return streams_;
}
+ // TODO: Remove this by giving mediamessage.cc access
+ // to MediaContentDescription
+ StreamParamsVec& mutable_streams() {
+ return streams_;
+ }
void AddStream(const StreamParams& stream) {
streams_.push_back(stream);
}
+ // Legacy streams have an ssrc, but nothing else.
+ void AddLegacyStream(uint32 ssrc) {
+ streams_.push_back(StreamParams::CreateLegacy(ssrc));
+ }
+
+ uint32 first_ssrc() const {
+ if (streams_.empty()) {
+ return 0;
+ }
+ return streams_[0].first_ssrc();
+ }
+ bool has_ssrcs() const {
+ if (streams_.empty()) {
+ return false;
+ }
+ return streams_[0].has_ssrcs();
+ }
protected:
- uint32 ssrc_;
- bool ssrc_set_;
bool rtcp_mux_;
int bandwidth_;
std::vector<CryptoParams> cryptos_;
bool crypto_required_;
std::vector<RtpHeaderExtension> rtp_header_extensions_;
bool rtp_header_extensions_set_;
+ bool multistream_;
StreamParamsVec streams_;
};
@@ -285,5 +301,3 @@
} // namespace cricket
#endif // TALK_SESSION_PHONE_MEDIASESSION_H_
-
-
diff --git a/talk/session/phone/mediasession_unittest.cc b/talk/session/phone/mediasession_unittest.cc
index 8b083a3..36fedc6 100644
--- a/talk/session/phone/mediasession_unittest.cc
+++ b/talk/session/phone/mediasession_unittest.cc
@@ -137,10 +137,13 @@
ssrc_groups.push_back(fec_group2);
ssrc_groups.push_back(fec_group3);
- StreamParams simulcast_params(kVideoTrack1,
- MAKE_VECTOR(kSimulcastParamsSsrc),
- ssrc_groups, "Video_SIM_FEC",
- kMediaStream1);
+ StreamParams simulcast_params;
+ simulcast_params.name = kVideoTrack1;
+ simulcast_params.ssrcs = MAKE_VECTOR(kSimulcastParamsSsrc);
+ simulcast_params.ssrc_groups = ssrc_groups;
+ simulcast_params.cname = "Video_SIM_FEC";
+ simulcast_params.sync_label = kMediaStream1;
+
StreamParamsVec video_streams;
video_streams.push_back(simulcast_params);
@@ -178,7 +181,7 @@
static_cast<const AudioContentDescription*>(ac->description);
EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
- EXPECT_NE(0U, acd->ssrc()); // a random nonzero ssrc
+ EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc
EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto)
EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on
ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
@@ -204,13 +207,13 @@
static_cast<const VideoContentDescription*>(vc->description);
EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
EXPECT_EQ(f1_.audio_codecs(), acd->codecs());
- EXPECT_NE(0U, acd->ssrc()); // a random nonzero ssrc
+ EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc
EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto)
EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on
ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
EXPECT_EQ(f1_.video_codecs(), vcd->codecs());
- EXPECT_NE(0U, vcd->ssrc()); // a random nonzero ssrc
+ EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc
EXPECT_EQ(kAutoBandwidth, vcd->bandwidth()); // default bandwidth (auto)
EXPECT_TRUE(vcd->rtcp_mux()); // rtcp-mux defaults on
ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
@@ -234,7 +237,7 @@
static_cast<const AudioContentDescription*>(ac->description);
EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
- EXPECT_NE(0U, acd->ssrc()); // a random nonzero ssrc
+ EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc
EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw
EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux
ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
@@ -263,12 +266,12 @@
EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type());
EXPECT_EQ(MAKE_VECTOR(kAudioCodecsAnswer), acd->codecs());
EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw
- EXPECT_NE(0U, acd->ssrc()); // a random nonzero ssrc
+ EXPECT_NE(0U, acd->first_ssrc()); // a random nonzero ssrc
EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux
ASSERT_CRYPTO(acd, false, 1U, CS_AES_CM_128_HMAC_SHA1_32);
EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type());
EXPECT_EQ(MAKE_VECTOR(kVideoCodecsAnswer), vcd->codecs());
- EXPECT_NE(0U, vcd->ssrc()); // a random nonzero ssrc
+ EXPECT_NE(0U, vcd->first_ssrc()); // a random nonzero ssrc
EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux
ASSERT_CRYPTO(vcd, false, 1U, CS_AES_CM_128_HMAC_SHA1_80);
}
@@ -324,7 +327,6 @@
ASSERT_EQ(1U, audio_streams[1].ssrcs.size());
EXPECT_NE(0U, audio_streams[1].ssrcs[0]);
- EXPECT_EQ(0U, acd->ssrc()); // 0- not used.
EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto)
EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on
ASSERT_CRYPTO(acd, false, 2U, CS_AES_CM_128_HMAC_SHA1_32);
@@ -337,7 +339,6 @@
ASSERT_EQ(1U, video_streams.size());
EXPECT_EQ(video_streams[0].cname, audio_streams[0].cname);
EXPECT_EQ(kVideoTrack1, video_streams[0].name);
- EXPECT_EQ(0U, vcd->ssrc()); // 0- not used.
EXPECT_EQ(kAutoBandwidth, vcd->bandwidth()); // default bandwidth (auto)
EXPECT_TRUE(vcd->rtcp_mux()); // rtcp-mux defaults on
@@ -429,7 +430,6 @@
ASSERT_EQ(1U, audio_streams[1].ssrcs.size());
EXPECT_NE(0U, audio_streams[1].ssrcs[0]);
- EXPECT_EQ(0U, acd->ssrc()); // 0- not used.
EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto)
EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on
@@ -440,7 +440,6 @@
ASSERT_EQ(1U, video_streams.size());
EXPECT_EQ(video_streams[0].cname, audio_streams[0].cname);
EXPECT_EQ(kVideoTrack1, video_streams[0].name);
- EXPECT_EQ(0U, vcd->ssrc()); // 0- not used.
EXPECT_EQ(kAutoBandwidth, vcd->bandwidth()); // default bandwidth (auto)
EXPECT_TRUE(vcd->rtcp_mux()); // rtcp-mux defaults on
diff --git a/talk/session/phone/mediasessionclient.cc b/talk/session/phone/mediasessionclient.cc
index f20b0f0..c7d8c88 100644
--- a/talk/session/phone/mediasessionclient.cc
+++ b/talk/session/phone/mediasessionclient.cc
@@ -36,6 +36,7 @@
#include "talk/p2p/base/constants.h"
#include "talk/p2p/base/parsing.h"
#include "talk/session/phone/cryptoparams.h"
+#include "talk/session/phone/mediamessages.h"
#include "talk/session/phone/srtpfilter.h"
#include "talk/xmpp/constants.h"
#include "talk/xmllite/qname.h"
@@ -198,6 +199,8 @@
return session;
}
+// TODO: Move all of the parsing and writing functions into
+// mediamessages.cc, with unit tests.
bool ParseGingleAudioCodec(const buzz::XmlElement* element, AudioCodec* out) {
int id = GetXmlAttr(element, QN_ID, -1);
if (id < 0)
@@ -225,26 +228,30 @@
return true;
}
-uint32 parse_ssrc(const std::string& ssrc) {
- // TODO: Return an error rather than defaulting to 0.
- uint32 default_ssrc = 0U;
- return talk_base::FromString(default_ssrc, ssrc);
+// Parses an ssrc string as a legacy stream. If it fails, returns
+// false and fills an error message.
+bool ParseSsrcAsLegacyStream(const std::string& ssrc_str,
+ std::vector<StreamParams>* streams,
+ ParseError* error) {
+ if (!ssrc_str.empty()) {
+ uint32 ssrc;
+ if (!talk_base::FromString(ssrc_str, &ssrc)) {
+ return BadParse("Missing or invalid ssrc.", error);
+ }
+
+ streams->push_back(StreamParams::CreateLegacy(ssrc));
+ }
+ return true;
}
void ParseGingleSsrc(const buzz::XmlElement* parent_elem,
const buzz::QName& name,
- MediaContentDescription* content) {
+ MediaContentDescription* media) {
const buzz::XmlElement* ssrc_elem = parent_elem->FirstNamed(name);
if (ssrc_elem) {
- content->set_ssrc(parse_ssrc(ssrc_elem->BodyText()));
- }
-}
-
-void ParseJingleSsrc(const buzz::XmlElement* desc_elem,
- MediaContentDescription* content) {
- const std::string ssrc = desc_elem->Attr(QN_JINGLE_SSRC);
- if (!ssrc.empty()) {
- content->set_ssrc(parse_ssrc(ssrc));
+ ParseError error;
+ ParseSsrcAsLegacyStream(
+ ssrc_elem->BodyText(), &(media->mutable_streams()), &error);
}
}
@@ -454,6 +461,23 @@
return true;
}
+bool ParseJingleStreamsOrLegacySsrc(const buzz::XmlElement* desc_elem,
+ MediaContentDescription* media,
+ ParseError* error) {
+ if (HasJingleStreams(desc_elem)) {
+ if (!ParseJingleStreams(desc_elem, &(media->mutable_streams()), error)) {
+ return false;
+ }
+ } else {
+ const std::string ssrc_str = desc_elem->Attr(QN_SSRC);
+ if (!ParseSsrcAsLegacyStream(
+ ssrc_str, &(media->mutable_streams()), error)) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool ParseJingleAudioContent(const buzz::XmlElement* content_elem,
const ContentDescription** content,
ParseError* error) {
@@ -469,12 +493,13 @@
}
}
- ParseJingleSsrc(content_elem, audio);
+ if (!ParseJingleStreamsOrLegacySsrc(content_elem, audio, error)) {
+ return false;
+ }
if (!ParseJingleEncryption(content_elem, audio, error)) {
return false;
}
- // TODO: Figure out how to integrate SSRC into Jingle.
*content = audio;
return true;
}
@@ -494,13 +519,14 @@
}
}
- ParseJingleSsrc(content_elem, video);
+ if (!ParseJingleStreamsOrLegacySsrc(content_elem, video, error)) {
+ return false;
+ }
ParseBandwidth(content_elem, video);
if (!ParseJingleEncryption(content_elem, video, error)) {
return false;
}
- // TODO: Figure out how to integrate SSRC into Jingle.
*content = video;
return true;
}
@@ -625,9 +651,9 @@
codec != audio->codecs().end(); ++codec) {
elem->AddElement(CreateGingleAudioCodecElem(*codec));
}
- if (audio->ssrc_set()) {
+ if (audio->has_ssrcs()) {
elem->AddElement(CreateGingleSsrcElem(
- QN_GINGLE_AUDIO_SRCID, audio->ssrc()));
+ QN_GINGLE_AUDIO_SRCID, audio->first_ssrc()));
}
const CryptoParamsVec& cryptos = audio->cryptos();
@@ -649,9 +675,9 @@
codec != video->codecs().end(); ++codec) {
elem->AddElement(CreateGingleVideoCodecElem(*codec));
}
- if (video->ssrc_set()) {
+ if (video->has_ssrcs()) {
elem->AddElement(CreateGingleSsrcElem(
- QN_GINGLE_VIDEO_SRCID, video->ssrc()));
+ QN_GINGLE_VIDEO_SRCID, video->first_ssrc()));
}
if (video->bandwidth() != kAutoBandwidth) {
elem->AddElement(CreateBandwidthElem(QN_GINGLE_VIDEO_BANDWIDTH,
@@ -712,15 +738,19 @@
return elem;
}
-void WriteJingleSsrc(const MediaContentDescription* media,
- buzz::XmlElement* elem) {
- // TODO: Right now, we have an ssrc=0 to mean "let the
- // server choose". In Jingle, it would make the most sense to just
- // leave off the attribute. But then we can't have an ssrc of 0.
- // Once we have initiator-choosen ssrcs, we can remove this check
- // and write out ssrc=0.
- if (media->ssrc_set() && (media->ssrc() != 0)) {
- AddXmlAttr(elem, QN_JINGLE_SSRC, media->ssrc());
+void WriteLegacyJingleSsrc(const MediaContentDescription* media,
+ buzz::XmlElement* elem) {
+ if (media->has_ssrcs()) {
+ AddXmlAttr(elem, QN_SSRC, media->first_ssrc());
+ }
+}
+
+void WriteJingleStreamsOrLegacySsrc(const MediaContentDescription* media,
+ buzz::XmlElement* desc_elem) {
+ if (!media->multistream()) {
+ WriteLegacyJingleSsrc(media, desc_elem);
+ } else {
+ WriteJingleStreams(media->streams(), desc_elem);
}
}
@@ -730,7 +760,7 @@
new buzz::XmlElement(QN_JINGLE_RTP_CONTENT, true);
elem->SetAttr(QN_JINGLE_CONTENT_MEDIA, JINGLE_CONTENT_MEDIA_AUDIO);
- WriteJingleSsrc(audio, elem);
+ WriteJingleStreamsOrLegacySsrc(audio, elem);
for (AudioCodecs::const_iterator codec = audio->codecs().begin();
codec != audio->codecs().end(); ++codec) {
@@ -755,7 +785,7 @@
new buzz::XmlElement(QN_JINGLE_RTP_CONTENT, true);
elem->SetAttr(QN_JINGLE_CONTENT_MEDIA, JINGLE_CONTENT_MEDIA_VIDEO);
- WriteJingleSsrc(video, elem);
+ WriteJingleStreamsOrLegacySsrc(video, elem);
for (VideoCodecs::const_iterator codec = video->codecs().begin();
codec != video->codecs().end(); ++codec) {
diff --git a/talk/session/phone/ssrcmuxfilter.cc b/talk/session/phone/ssrcmuxfilter.cc
index 76245f2..2f3e1f2 100644
--- a/talk/session/phone/ssrcmuxfilter.cc
+++ b/talk/session/phone/ssrcmuxfilter.cc
@@ -35,6 +35,8 @@
namespace cricket {
+static const uint32 kSsrc01 = 0x01;
+
SsrcMuxFilter::SsrcMuxFilter()
: state_(ST_INIT),
enabled_(false) {
@@ -88,10 +90,16 @@
if (!GetRtcpType(data, len, &pl_type)) return false;
if (pl_type == kRtcpTypeSR || pl_type == kRtcpTypeRR) {
// Getting SSRC from the report packets.
- GetRtcpSsrc(data, len, &ssrc);
+ if (!GetRtcpSsrc(data, len, &ssrc)) return false;
+ if (ssrc == kSsrc01) {
+ // SSRC 1 has a special meaning and indicates generic feedback on
+ // some systems and should never be dropped. If it is forwarded
+ // incorrectly it will be ignored by lower layers anyway.
+ return true;
+ }
} else {
// All other RTCP packets are handled by the all channels.
- // TODO - Add SSRC parsing to all RTCP messages.
+ // TODO: Add SSRC parsing to all RTCP messages.
LOG(LS_INFO) << "Non RTCP report packet received for demux.";
return true;
}
diff --git a/talk/session/phone/streamparams.h b/talk/session/phone/streamparams.h
index 527d9b7..ec4b380 100644
--- a/talk/session/phone/streamparams.h
+++ b/talk/session/phone/streamparams.h
@@ -52,6 +52,7 @@
SsrcGroup(const std::string& usage, const std::vector<uint32>& ssrcs)
: semantics(usage), ssrcs(ssrcs) {
}
+
bool operator==(const SsrcGroup& other) const {
return (semantics == other.semantics && ssrcs == other.ssrcs);
}
@@ -64,38 +65,48 @@
};
struct StreamParams {
- StreamParams(const std::string& name,
- const std::vector<uint32>& ssrcs,
- const std::vector<SsrcGroup>& ssrc_groups,
- const std::string& cname,
- const std::string& sync_label)
- : name(name),
- ssrcs(ssrcs),
- ssrc_groups(ssrc_groups),
- cname(cname),
- sync_label(sync_label) {
- }
- StreamParams(const std::string& name,
- uint32 ssrc,
- const std::string& cname,
- const std::string& sync_label)
- : name(name),
- cname(cname),
- sync_label(sync_label) {
- ssrcs.push_back(ssrc);
+ static StreamParams CreateLegacy(uint32 ssrc) {
+ StreamParams stream;
+ stream.ssrcs.push_back(ssrc);
+ return stream;
}
bool operator==(const StreamParams& other) const {
- return (name == other.name && ssrcs == other.ssrcs &&
- ssrc_groups == other.ssrc_groups && cname == other.cname &&
- sync_label == sync_label);
+ return (nick == other.nick &&
+ name == other.name &&
+ ssrcs == other.ssrcs &&
+ ssrc_groups == other.ssrc_groups &&
+ type == other.type &&
+ display == other.display &&
+ cname == other.cname &&
+ sync_label == sync_label);
}
bool operator!=(const StreamParams &other) const {
return !(*this == other);
}
- std::string name; // Unique name of this source.
+ uint32 first_ssrc() const {
+ if (ssrcs.empty()) {
+ return 0;
+ }
+
+ return ssrcs[0];
+ }
+ bool has_ssrcs() const {
+ return !ssrcs.empty();
+ }
+
+ // Resource of the MUC jid of the participant of with this stream.
+ // For 1:1 calls, should be left empty (which means remote streams
+ // and local streams should not be mixed together).
+ std::string nick;
+ // Unique name of this source (unique per-nick, not for all nicks)
+ std::string name;
std::vector<uint32> ssrcs; // All SSRCs for this source
std::vector<SsrcGroup> ssrc_groups; // e.g. FID, FEC, SIM
+ // Examples: "camera", "screencast"
+ std::string type;
+ // Friendly name describing stream
+ std::string display;
std::string cname; // RTCP CNAME
std::string sync_label; // Friendly name of cname.
};
diff --git a/talk/session/phone/webrtcvideoengine.cc b/talk/session/phone/webrtcvideoengine.cc
index 3460e49..046ae5f 100644
--- a/talk/session/phone/webrtcvideoengine.cc
+++ b/talk/session/phone/webrtcvideoengine.cc
@@ -33,6 +33,7 @@
#include "talk/session/phone/webrtcvideoengine.h"
+#include "talk/base/basictypes.h"
#include "talk/base/common.h"
#include "talk/base/buffer.h"
#include "talk/base/byteorder.h"
@@ -53,7 +54,8 @@
static const int kDefaultLogSeverity = talk_base::LS_WARNING;
-static const int kMinVideoBitrate = 300;
+static const int kMinVideoBitrate = 100;
+static const int kStartVideoBitrate = 300;
static const int kMaxVideoBitrate = 2000;
static const int kVideoMtu = 1200;
@@ -772,9 +774,9 @@
out_codec.maxFramerate = in_codec.framerate;
// Init the codec with the default bandwidth options.
- out_codec.maxBitrate = kMaxVideoBitrate;
- out_codec.startBitrate = kMinVideoBitrate;
out_codec.minBitrate = kMinVideoBitrate;
+ out_codec.startBitrate = kStartVideoBitrate;
+ out_codec.maxBitrate = kMaxVideoBitrate;
return true;
}
@@ -946,6 +948,7 @@
render_started_(false),
muted_(false),
send_min_bitrate_(kMinVideoBitrate),
+ send_start_bitrate_(kStartVideoBitrate),
send_max_bitrate_(kMaxVideoBitrate),
local_stream_info_(new LocalStreamInfo()) {
engine->RegisterChannel(this);
@@ -1171,7 +1174,8 @@
kDefaultNumberOfTemporalLayers;
}
- if (!SetSendCodec(codec, send_min_bitrate_, send_max_bitrate_)) {
+ if (!SetSendCodec(
+ codec, send_min_bitrate_, send_start_bitrate_, send_max_bitrate_)) {
return false;
}
@@ -1420,21 +1424,25 @@
return true;
}
- int min_bitrate = kMinVideoBitrate;
- int max_bitrate = kMaxVideoBitrate;
+ int min_bitrate;
+ int start_bitrate;
+ int max_bitrate;
if (autobw) {
- // Use the default values as min
+ // Use the default values for min bitrate.
min_bitrate = kMinVideoBitrate;
// Use the default value or the bps for the max
max_bitrate = (bps <= 0) ? kMaxVideoBitrate : (bps / 1000);
+ // Maximum start bitrate can be kStartVideoBitrate.
+ start_bitrate = talk_base::_min(kStartVideoBitrate, max_bitrate);
} else {
// Use the default start or the bps as the target bitrate.
- int target_bitrate = (bps <= 0) ? kMinVideoBitrate : (bps / 1000);
+ int target_bitrate = (bps <= 0) ? kStartVideoBitrate : (bps / 1000);
min_bitrate = target_bitrate;
+ start_bitrate = target_bitrate;
max_bitrate = target_bitrate;
}
- if (!SetSendCodec(*send_codec_, min_bitrate, max_bitrate)) {
+ if (!SetSendCodec(*send_codec_, min_bitrate, start_bitrate, max_bitrate)) {
return false;
}
@@ -1467,6 +1475,23 @@
// Update local stream statistics.
local_stream_info_->UpdateFrame(frame->GetWidth(), frame->GetHeight());
+ // If the captured video format is smaller than what we asked for, reset send
+ // codec on video engine.
+ if (send_codec_.get() != NULL &&
+ frame->GetWidth() < send_codec_->width &&
+ frame->GetHeight() < send_codec_->height) {
+ LOG(LS_INFO) << "Captured video frame size changed to: "
+ << frame->GetWidth() << "x" << frame->GetHeight();
+ webrtc::VideoCodec new_codec = *send_codec_;
+ new_codec.width = frame->GetWidth();
+ new_codec.height = frame->GetHeight();
+ if (!SetSendCodec(
+ new_codec, send_min_bitrate_, send_start_bitrate_, send_max_bitrate_)) {
+ LOG(LS_WARNING) << "Failed to switch to new frame size: "
+ << frame->GetWidth() << "x" << frame->GetHeight();
+ }
+ }
+
// Blacken the frame if video is muted.
const VideoFrame* frame_out = frame;
talk_base::scoped_ptr<VideoFrame> black_frame;
@@ -1543,10 +1568,12 @@
}
bool WebRtcVideoMediaChannel::SetSendCodec(const webrtc::VideoCodec& codec,
- int min_bitrate, int max_bitrate) {
+ int min_bitrate,
+ int start_bitrate,
+ int max_bitrate) {
// Make a copy of the codec
webrtc::VideoCodec target_codec = codec;
- target_codec.startBitrate = min_bitrate;
+ target_codec.startBitrate = start_bitrate;
target_codec.minBitrate = min_bitrate;
target_codec.maxBitrate = max_bitrate;
@@ -1558,6 +1585,7 @@
// Reset the send_codec_ only if SetSendCodec is success.
send_codec_.reset(new webrtc::VideoCodec(target_codec));
send_min_bitrate_ = min_bitrate;
+ send_start_bitrate_ = start_bitrate;
send_max_bitrate_ = max_bitrate;
return true;
diff --git a/talk/session/phone/webrtcvideoengine.h b/talk/session/phone/webrtcvideoengine.h
index eb2caa9..be8c5f0 100644
--- a/talk/session/phone/webrtcvideoengine.h
+++ b/talk/session/phone/webrtcvideoengine.h
@@ -267,7 +267,9 @@
bool EnableNack();
bool SetNackFec(int red_payload_type, int fec_payload_type);
bool SetSendCodec(const webrtc::VideoCodec& codec,
- int min_bitrate, int max_bitrate);
+ int min_bitrate,
+ int start_bitrate,
+ int max_bitrate);
bool ResetRecvCodecs(int channel);
WebRtcVideoEngine* engine_;
@@ -279,6 +281,7 @@
bool render_started_;
bool muted_; // Flag to tell if we need to mute video.
int send_min_bitrate_;
+ int send_start_bitrate_;
int send_max_bitrate_;
talk_base::scoped_ptr<webrtc::VideoCodec> send_codec_;
talk_base::scoped_ptr<WebRtcRenderAdapter> remote_renderer_;
diff --git a/talk/session/phone/webrtcvideoengine_unittest.cc b/talk/session/phone/webrtcvideoengine_unittest.cc
index 0c1fa4b..ad11f20 100644
--- a/talk/session/phone/webrtcvideoengine_unittest.cc
+++ b/talk/session/phone/webrtcvideoengine_unittest.cc
@@ -34,6 +34,7 @@
#include "talk/session/phone/videoengine_unittest.h"
#include "talk/session/phone/webrtcvideocapturer.h"
#include "talk/session/phone/webrtcvideoengine.h"
+#include "talk/session/phone/webrtcvideoframe.h"
#include "talk/session/phone/webrtcvoiceengine.h"
// Tests for the WebRtcVideoEngine/VideoChannel code.
@@ -47,7 +48,8 @@
&kUlpFecCodec
};
-static const unsigned int kMinBandwidthKbps = 300;
+static const unsigned int kMinBandwidthKbps = 100;
+static const unsigned int kStartBandwidthKbps = 300;
static const unsigned int kMaxBandwidthKbps = 2000;
class FakeViEWrapper : public cricket::ViEWrapper {
@@ -171,7 +173,7 @@
EXPECT_EQ(kVP8Codec.height, gcodec.height);
EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
EXPECT_EQ(kMinBandwidthKbps, gcodec.minBitrate);
- EXPECT_EQ(kMinBandwidthKbps, gcodec.startBitrate);
+ EXPECT_EQ(kStartBandwidthKbps, gcodec.startBitrate);
EXPECT_EQ(kMaxBandwidthKbps, gcodec.maxBitrate);
// TODO: Check HybridNackFecStatus.
// TODO: Check RTCP, PLI, TMMBR.
@@ -250,6 +252,40 @@
EXPECT_EQ(0, gcodec.plType);
}
+// Test that send codec is reset if the captured frame is smaller.
+TEST_F(WebRtcVideoEngineTestFake, ResetSendCodecOnSmallerFrame) {
+ EXPECT_TRUE(SetupEngine());
+ int channel_num = vie_.GetLastChannel();
+
+ const int old_w = 640;
+ const int old_h = 400;
+ const int new_w = 160;
+ const int new_h = 100;
+
+ // Set send codec and start sending.
+ cricket::VideoCodec codec(kVP8Codec);
+ codec.width = old_w;
+ codec.height = old_h;
+ std::vector<cricket::VideoCodec> codec_list;
+ codec_list.push_back(codec);
+ EXPECT_TRUE(channel_->SetSendCodecs(codec_list));
+ EXPECT_TRUE(channel_->SetSend(true));
+
+ // Capture a smaller frame.
+ cricket::WebRtcVideoFrame frame;
+ uint8 pixel[new_w * new_h * 3 / 2] = { 0 }; // I420
+ EXPECT_TRUE(frame.Init(cricket::FOURCC_I420, new_w, new_h, new_w, new_h,
+ pixel, sizeof(pixel), 1, 1, 0, 0, 0));
+ EXPECT_TRUE(channel_->SendFrame(0, &frame));
+
+ // Verify the send codec has been reset to the new format.
+ webrtc::VideoCodec gcodec;
+ EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
+ EXPECT_EQ(kVP8Codec.id, gcodec.plType);
+ EXPECT_EQ(new_w, gcodec.width);
+ EXPECT_EQ(new_h, gcodec.height);
+}
+
// Test that we set our inbound codecs properly.
TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecs) {
EXPECT_TRUE(SetupEngine());
@@ -367,7 +403,7 @@
EXPECT_EQ(kVP8Codec.id, gcodec.plType);
EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
EXPECT_EQ(kMinBandwidthKbps, gcodec.minBitrate);
- EXPECT_EQ(kMinBandwidthKbps, gcodec.startBitrate);
+ EXPECT_EQ(kStartBandwidthKbps, gcodec.startBitrate);
EXPECT_EQ(kMaxBandwidthKbps, gcodec.maxBitrate);
}
@@ -382,7 +418,7 @@
EXPECT_EQ(kVP8Codec.id, gcodec.plType);
EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
EXPECT_EQ(kMinBandwidthKbps, gcodec.minBitrate);
- EXPECT_EQ(kMinBandwidthKbps, gcodec.startBitrate);
+ EXPECT_EQ(kStartBandwidthKbps, gcodec.startBitrate);
EXPECT_EQ(768U, gcodec.maxBitrate);
}
diff --git a/talk/session/phone/webrtcvideoframe.cc b/talk/session/phone/webrtcvideoframe.cc
index e12771d..2562ed5 100644
--- a/talk/session/phone/webrtcvideoframe.cc
+++ b/talk/session/phone/webrtcvideoframe.cc
@@ -27,14 +27,10 @@
#include "talk/session/phone/webrtcvideoframe.h"
+#include "libyuv/planar_functions.h"
#include "talk/base/logging.h"
#include "talk/session/phone/videocapturer.h"
#include "talk/session/phone/videocommon.h"
-#ifdef WEBRTC_RELATIVE_PATH
-#include "common_video/vplib/main/interface/vplib.h"
-#else
-#include "third_party/webrtc/files/include/vplib.h"
-#endif
namespace cricket {
@@ -217,10 +213,11 @@
return needed;
}
+// TODO: Refactor into base class and share with lmi
size_t WebRtcVideoFrame::ConvertToRgbBuffer(uint32 to_fourcc,
uint8* buffer,
size_t size,
- size_t pitch_rgb) const {
+ size_t stride_rgb) const {
if (!video_frame_.Buffer()) {
return 0;
}
@@ -231,29 +228,44 @@
// explanation of pitch and why this is the amount of space we need.
// TODO: increase to stride * height to allow padding to be used
// to overwrite for efficiency.
- size_t needed = pitch_rgb * (height - 1) + 4 * width;
+ size_t needed = stride_rgb * (height - 1) + 4 * width;
if (needed > size) {
LOG(LS_WARNING) << "RGB buffer is not large enough";
- return 0;
+ return needed;
}
- webrtc::VideoType to_type = webrtc::kUnknown;
+ // TODO: Use libyuv::ConvertFromI420
switch (to_fourcc) {
case FOURCC_ARGB:
- to_type = webrtc::kARGB;
+ libyuv::I420ToARGB(
+ GetYPlane(), GetYPitch(),
+ GetUPlane(), GetUPitch(),
+ GetVPlane(), GetVPitch(),
+ buffer, stride_rgb, width, height);
break;
+
+ case FOURCC_BGRA:
+ libyuv::I420ToBGRA(
+ GetYPlane(), GetYPitch(),
+ GetUPlane(), GetUPitch(),
+ GetVPlane(), GetVPitch(),
+ buffer, stride_rgb, width, height);
+ break;
+
+ case FOURCC_ABGR:
+ libyuv::I420ToABGR(
+ GetYPlane(), GetYPitch(),
+ GetUPlane(), GetUPitch(),
+ GetVPlane(), GetVPitch(),
+ buffer, stride_rgb, width, height);
+ break;
+
default:
+ needed = 0;
LOG(LS_WARNING) << "RGB type not supported: " << to_fourcc;
- return 0;
+ break;
}
-
- if (to_type != webrtc::kUnknown) {
- // TODO: Use libyuv::ConvertFromI420
- webrtc::ConvertFromI420(to_type, video_frame_.Buffer(),
- width, height, buffer);
- }
-
return needed;
}
diff --git a/talk/session/phone/webrtcvideoframe_unittest.cc b/talk/session/phone/webrtcvideoframe_unittest.cc
index 7b057e5..c4526c0 100644
--- a/talk/session/phone/webrtcvideoframe_unittest.cc
+++ b/talk/session/phone/webrtcvideoframe_unittest.cc
@@ -57,8 +57,10 @@
// Re-evaluate once WebRTC switches to libyuv
// TEST_LMIVIDEOFRAME(ConstructYuy2AllSizes)
// TODO: WebRtcVideoFrame currently only supports ARGB output.
-// TEST_WEBRTCVIDEOFRAME(ConvertToBGRABuffer)
-// TEST_WEBRTCVIDEOFRAME(ConvertToABGRBuffer)
+#ifdef HAVE_YUV
+TEST_WEBRTCVIDEOFRAME(ConvertToBGRABuffer)
+TEST_WEBRTCVIDEOFRAME(ConvertToABGRBuffer)
+#endif
TEST_WEBRTCVIDEOFRAME(ConvertToARGBBuffer)
//TEST_WEBRTCVIDEOFRAME(ConvertToYUY2Buffer)
//TEST_WEBRTCVIDEOFRAME(ConvertToI422Buffer)
diff --git a/talk/session/phone/webrtcvoiceengine.cc b/talk/session/phone/webrtcvoiceengine.cc
index cfe7345..561c13c 100644
--- a/talk/session/phone/webrtcvoiceengine.cc
+++ b/talk/session/phone/webrtcvoiceengine.cc
@@ -1410,9 +1410,8 @@
}
}
-// This api is currently present but nonfunctional in WebRTC VoiceEngine.
// This api call is not available in iOS version of VoiceEngine currently.
-#if 0 // !defined(IOS) && !defined(ANDROID)
+#if !defined(IOS) && !defined(ANDROID)
if (engine()->voe()->rtp()->SetRTPAudioLevelIndicationStatus(
voe_channel(), enable, id) == -1) {
LOG_RTCERR3(SetRTPAudioLevelIndicationStatus, voe_channel(), enable, id);
diff --git a/talk/session/phone/webrtcvoiceengine_unittest.cc b/talk/session/phone/webrtcvoiceengine_unittest.cc
index b1b1783..6bcc04e 100644
--- a/talk/session/phone/webrtcvoiceengine_unittest.cc
+++ b/talk/session/phone/webrtcvoiceengine_unittest.cc
@@ -4,11 +4,11 @@
#include "talk/base/byteorder.h"
#include "talk/base/gunit.h"
+#include "talk/p2p/base/fakesession.h"
#include "talk/session/phone/channel.h"
#include "talk/session/phone/fakemediaengine.h"
#include "talk/session/phone/fakemediaprocessor.h"
#include "talk/session/phone/fakertp.h"
-#include "talk/session/phone/fakesession.h"
#include "talk/session/phone/fakewebrtcvoiceengine.h"
#include "talk/session/phone/webrtcvoiceengine.h"
@@ -558,9 +558,8 @@
EXPECT_FALSE(enable);
}
-// TODO: Re-enable this test once audio level status is restored.
// Test that we support setting certain send header extensions.
-TEST_F(WebRtcVoiceEngineTestFake, DISABLED_SetSendRtpHeaderExtensions) {
+TEST_F(WebRtcVoiceEngineTestFake, SetSendRtpHeaderExtensions) {
EXPECT_TRUE(SetupEngine());
std::vector<cricket::RtpHeaderExtension> extensions;
int channel_num = voe_.GetLastChannel();
diff --git a/talk/xmllite/xmlelement.cc b/talk/xmllite/xmlelement.cc
index 6a0e8e8..7b208e6 100644
--- a/talk/xmllite/xmlelement.cc
+++ b/talk/xmllite/xmlelement.cc
@@ -521,7 +521,7 @@
std::string
XmlElement::Str() const {
std::stringstream ss;
- Print(&ss, NULL, 0);
+ XmlPrinter::PrintXml(&ss, this);
return ss.str();
}
@@ -532,12 +532,6 @@
return builder.CreateElement();
}
-void
-XmlElement::Print(
- std::ostream * pout, std::string xmlns[], int xmlnsCount) const {
- XmlPrinter::PrintXml(pout, this, xmlns, xmlnsCount);
-}
-
XmlElement::~XmlElement() {
XmlAttr * pattr;
for (pattr = pFirstAttr_; pattr; ) {
diff --git a/talk/xmllite/xmlelement.h b/talk/xmllite/xmlelement.h
index f50985a..7cb30f3 100644
--- a/talk/xmllite/xmlelement.h
+++ b/talk/xmllite/xmlelement.h
@@ -223,8 +223,6 @@
static XmlElement * ForStr(const std::string & str);
std::string Str() const;
- void Print(std::ostream * pout, std::string xmlns[], int xmlnsCount) const;
-
bool IsCDATA() const { return cdata_; }
protected:
diff --git a/talk/xmllite/xmlprinter.cc b/talk/xmllite/xmlprinter.cc
index 691419c..1350454 100644
--- a/talk/xmllite/xmlprinter.cc
+++ b/talk/xmllite/xmlprinter.cc
@@ -39,117 +39,111 @@
class XmlPrinterImpl {
public:
- XmlPrinterImpl(std::ostream * pout,
- const std::string * const xmlns, int xmlnsCount);
- void PrintElement(const XmlElement * element);
- void PrintQuotedValue(const std::string & text);
- void PrintBodyText(const std::string & text);
- void PrintCDATAText(const std::string & text);
+ XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack);
+ void PrintElement(const XmlElement* element);
+ void PrintQuotedValue(const std::string& text);
+ void PrintBodyText(const std::string& text);
+ void PrintCDATAText(const std::string& text);
private:
std::ostream *pout_;
- XmlnsStack xmlnsStack_;
+ XmlnsStack* ns_stack_;
};
-void
-XmlPrinter::PrintXml(std::ostream * pout, const XmlElement * element) {
- PrintXml(pout, element, NULL, 0);
+void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element) {
+ XmlnsStack ns_stack;
+ PrintXml(pout, element, &ns_stack);
}
-void
-XmlPrinter::PrintXml(std::ostream * pout, const XmlElement * element,
- const std::string * const xmlns, int xmlnsCount) {
- XmlPrinterImpl printer(pout, xmlns, xmlnsCount);
+void XmlPrinter::PrintXml(std::ostream* pout, const XmlElement* element,
+ XmlnsStack* ns_stack) {
+ XmlPrinterImpl printer(pout, ns_stack);
printer.PrintElement(element);
}
-XmlPrinterImpl::XmlPrinterImpl(std::ostream * pout,
- const std::string * const xmlns, int xmlnsCount) :
- pout_(pout),
- xmlnsStack_() {
- int i;
- for (i = 0; i < xmlnsCount; i += 2) {
- xmlnsStack_.AddXmlns(xmlns[i], xmlns[i + 1]);
- }
+XmlPrinterImpl::XmlPrinterImpl(std::ostream* pout, XmlnsStack* ns_stack)
+ : pout_(pout),
+ ns_stack_(ns_stack) {
}
-void
-XmlPrinterImpl::PrintElement(const XmlElement * element) {
- xmlnsStack_.PushFrame();
+void XmlPrinterImpl::PrintElement(const XmlElement* element) {
+ ns_stack_->PushFrame();
// first go through attrs of pel to add xmlns definitions
- const XmlAttr * pattr;
- for (pattr = element->FirstAttr(); pattr; pattr = pattr->NextAttr()) {
- if (pattr->Name() == QN_XMLNS)
- xmlnsStack_.AddXmlns(STR_EMPTY, pattr->Value());
- else if (pattr->Name().Namespace() == NS_XMLNS)
- xmlnsStack_.AddXmlns(pattr->Name().LocalPart(),
- pattr->Value());
+ const XmlAttr* attr;
+ for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
+ if (attr->Name() == QN_XMLNS) {
+ ns_stack_->AddXmlns(STR_EMPTY, attr->Value());
+ } else if (attr->Name().Namespace() == NS_XMLNS) {
+ ns_stack_->AddXmlns(attr->Name().LocalPart(),
+ attr->Value());
+ }
}
// then go through qnames to make sure needed xmlns definitons are added
- std::vector<std::string> newXmlns;
+ std::vector<std::string> new_ns;
std::pair<std::string, bool> prefix;
- prefix = xmlnsStack_.AddNewPrefix(element->Name().Namespace(), false);
+ prefix = ns_stack_->AddNewPrefix(element->Name().Namespace(), false);
if (prefix.second) {
- newXmlns.push_back(prefix.first);
- newXmlns.push_back(element->Name().Namespace());
+ new_ns.push_back(prefix.first);
+ new_ns.push_back(element->Name().Namespace());
}
- for (pattr = element->FirstAttr(); pattr; pattr = pattr->NextAttr()) {
- prefix = xmlnsStack_.AddNewPrefix(pattr->Name().Namespace(), true);
+ for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
+ prefix = ns_stack_->AddNewPrefix(attr->Name().Namespace(), true);
if (prefix.second) {
- newXmlns.push_back(prefix.first);
- newXmlns.push_back(pattr->Name().Namespace());
+ new_ns.push_back(prefix.first);
+ new_ns.push_back(attr->Name().Namespace());
}
}
// print the element name
- *pout_ << '<' << xmlnsStack_.FormatQName(element->Name(), false);
+ *pout_ << '<' << ns_stack_->FormatQName(element->Name(), false);
// and the attributes
- for (pattr = element->FirstAttr(); pattr; pattr = pattr->NextAttr()) {
- *pout_ << ' ' << xmlnsStack_.FormatQName(pattr->Name(), true) << "=\"";
- PrintQuotedValue(pattr->Value());
+ for (attr = element->FirstAttr(); attr; attr = attr->NextAttr()) {
+ *pout_ << ' ' << ns_stack_->FormatQName(attr->Name(), true) << "=\"";
+ PrintQuotedValue(attr->Value());
*pout_ << '"';
}
// and the extra xmlns declarations
- std::vector<std::string>::iterator i(newXmlns.begin());
- while (i < newXmlns.end()) {
- if (*i == STR_EMPTY)
+ std::vector<std::string>::iterator i(new_ns.begin());
+ while (i < new_ns.end()) {
+ if (*i == STR_EMPTY) {
*pout_ << " xmlns=\"" << *(i + 1) << '"';
- else
+ } else {
*pout_ << " xmlns:" << *i << "=\"" << *(i + 1) << '"';
+ }
i += 2;
}
// now the children
- const XmlChild * pchild = element->FirstChild();
+ const XmlChild* child = element->FirstChild();
- if (pchild == NULL)
+ if (child == NULL)
*pout_ << "/>";
else {
*pout_ << '>';
- while (pchild) {
- if (pchild->IsText()) {
+ while (child) {
+ if (child->IsText()) {
if (element->IsCDATA()) {
- PrintCDATAText(pchild->AsText()->Text());
+ PrintCDATAText(child->AsText()->Text());
} else {
- PrintBodyText(pchild->AsText()->Text());
+ PrintBodyText(child->AsText()->Text());
}
- } else
- PrintElement(pchild->AsElement());
- pchild = pchild->NextChild();
+ } else {
+ PrintElement(child->AsElement());
+ }
+ child = child->NextChild();
}
- *pout_ << "</" << xmlnsStack_.FormatQName(element->Name(), false) << '>';
+ *pout_ << "</" << ns_stack_->FormatQName(element->Name(), false) << '>';
}
- xmlnsStack_.PopFrame();
+ ns_stack_->PopFrame();
}
-void
-XmlPrinterImpl::PrintQuotedValue(const std::string & text) {
+void XmlPrinterImpl::PrintQuotedValue(const std::string& text) {
size_t safe = 0;
for (;;) {
size_t unsafe = text.find_first_of("<>&\"", safe);
@@ -170,8 +164,7 @@
}
}
-void
-XmlPrinterImpl::PrintBodyText(const std::string & text) {
+void XmlPrinterImpl::PrintBodyText(const std::string& text) {
size_t safe = 0;
for (;;) {
size_t unsafe = text.find_first_of("<>&", safe);
@@ -191,9 +184,8 @@
}
}
-void
-XmlPrinterImpl::PrintCDATAText(const std::string & text) {
+void XmlPrinterImpl::PrintCDATAText(const std::string& text) {
*pout_ << "<![CDATA[" << text << "]]>";
}
-}
+} // namespace buzz
diff --git a/talk/xmllite/xmlprinter.h b/talk/xmllite/xmlprinter.h
index 96900d0..90cc255 100644
--- a/talk/xmllite/xmlprinter.h
+++ b/talk/xmllite/xmlprinter.h
@@ -2,48 +2,48 @@
* libjingle
* Copyright 2004--2005, Google Inc.
*
- * Redistribution and use in source and binary forms, with or without
+ * 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,
+ * 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
+ * 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
+ * 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,
+ * 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
+ * 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 _xmlprinter_h_
-#define _xmlprinter_h_
+#ifndef TALK_XMLLITE_XMLPRINTER_H_
+#define TALK_XMLLITE_XMLPRINTER_H_
#include <iosfwd>
#include <string>
-#include "talk/base/scoped_ptr.h"
namespace buzz {
class XmlElement;
+class XmlnsStack;
class XmlPrinter {
-public:
- static void PrintXml(std::ostream * pout, const XmlElement * pelt);
+ public:
+ static void PrintXml(std::ostream* pout, const XmlElement* pelt);
- static void PrintXml(std::ostream * pout, const XmlElement * pelt,
- const std::string * const xmlns, int xmlnsCount);
+ static void PrintXml(std::ostream* pout, const XmlElement* pelt,
+ XmlnsStack* ns_stack);
};
-}
+} // namespace buzz
-#endif
+#endif // TALK_XMLLITE_XMLPRINTER_H_
diff --git a/talk/xmllite/xmlprinter_unittest.cc b/talk/xmllite/xmlprinter_unittest.cc
index 8ac7e04..60b0e42 100644
--- a/talk/xmllite/xmlprinter_unittest.cc
+++ b/talk/xmllite/xmlprinter_unittest.cc
@@ -25,24 +25,22 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <string>
+#include "talk/xmllite/xmlprinter.h"
+
#include <sstream>
-#include <iostream>
+#include <string>
+
#include "talk/base/common.h"
#include "talk/base/gunit.h"
#include "talk/xmllite/qname.h"
#include "talk/xmllite/xmlelement.h"
-#include "talk/xmllite/xmlprinter.h"
+#include "talk/xmllite/xmlnsstack.h"
using buzz::QName;
using buzz::XmlElement;
+using buzz::XmlnsStack;
using buzz::XmlPrinter;
-static std::string XmlPrinterTest_Ns[] = {
- "gg", "google:test",
- "", "nested:test",
-};
-
TEST(XmlPrinterTest, TestBasicPrinting) {
XmlElement elt(QName("google:test", "first"));
std::stringstream ss;
@@ -55,7 +53,10 @@
elt.AddElement(new XmlElement(QName("nested:test", "second")));
std::stringstream ss;
- XmlPrinter::PrintXml(&ss, &elt, XmlPrinterTest_Ns, 4);
+ XmlnsStack ns_stack;
+ ns_stack.AddXmlns("gg", "google:test");
+ ns_stack.AddXmlns("", "nested:test");
+
+ XmlPrinter::PrintXml(&ss, &elt, &ns_stack);
EXPECT_EQ("<gg:first><second/></gg:first>", ss.str());
}
-
diff --git a/talk/xmpp/xmppengineimpl.cc b/talk/xmpp/xmppengineimpl.cc
index 3edddf2..eb539d1 100644
--- a/talk/xmpp/xmppengineimpl.cc
+++ b/talk/xmpp/xmppengineimpl.cc
@@ -2,87 +2,83 @@
* libjingle
* Copyright 2004--2005, Google Inc.
*
- * Redistribution and use in source and binary forms, with or without
+ * 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,
+ * 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
+ * 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
+ * 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,
+ * 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
+ * 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 TRACK_ARRAY_ALLOC_PROBLEM
-
-#include <vector>
-#include <sstream>
-#include <algorithm>
-#include "talk/xmllite/xmlelement.h"
-#include "talk/base/common.h"
#include "talk/xmpp/xmppengineimpl.h"
-#include "talk/xmpp/xmpplogintask.h"
-#include "talk/xmpp/constants.h"
+
+#include <algorithm>
+#include <sstream>
+#include <vector>
+
+#include "talk/base/common.h"
+#include "talk/xmllite/xmlelement.h"
#include "talk/xmllite/xmlprinter.h"
+#include "talk/xmpp/constants.h"
#include "talk/xmpp/saslhandler.h"
+#include "talk/xmpp/xmpplogintask.h"
namespace buzz {
-static const std::string XMPP_CLIENT_NAMESPACES[] = {
- "stream", "http://etherx.jabber.org/streams",
- "", "jabber:client",
-};
-
-static const size_t XMPP_CLIENT_NAMESPACES_LEN = 4;
-
-XmppEngine * XmppEngine::Create() {
+XmppEngine* XmppEngine::Create() {
return new XmppEngineImpl();
}
-XmppEngineImpl::XmppEngineImpl() :
- stanzaParseHandler_(this),
- stanzaParser_(&stanzaParseHandler_),
- engine_entered_(0),
- password_(),
- requested_resource_(STR_EMPTY),
- tls_option_(buzz::TLS_REQUIRED),
- login_task_(new XmppLoginTask(this)),
- next_id_(0),
- state_(STATE_START),
- encrypted_(false),
- error_code_(ERROR_NONE),
- subcode_(0),
- stream_error_(NULL),
- raised_reset_(false),
- output_handler_(NULL),
- session_handler_(NULL),
- iq_entries_(new IqEntryVector()),
- sasl_handler_(NULL),
- output_(new std::stringstream()) {
+XmppEngineImpl::XmppEngineImpl()
+ : stanza_parse_handler_(this),
+ stanza_parser_(&stanza_parse_handler_),
+ engine_entered_(0),
+ password_(),
+ requested_resource_(STR_EMPTY),
+ tls_option_(buzz::TLS_REQUIRED),
+ login_task_(new XmppLoginTask(this)),
+ next_id_(0),
+ state_(STATE_START),
+ encrypted_(false),
+ error_code_(ERROR_NONE),
+ subcode_(0),
+ stream_error_(NULL),
+ raised_reset_(false),
+ output_handler_(NULL),
+ session_handler_(NULL),
+ iq_entries_(new IqEntryVector()),
+ sasl_handler_(NULL),
+ output_(new std::stringstream()) {
for (int i = 0; i < HL_COUNT; i+= 1) {
stanza_handlers_[i].reset(new StanzaHandlerVector());
}
+
+ xmlns_stack_.AddXmlns("stream", "http://etherx.jabber.org/streams");
+ xmlns_stack_.AddXmlns("", "jabber:client");
}
XmppEngineImpl::~XmppEngineImpl() {
DeleteIqCookies();
}
-XmppReturnStatus
-XmppEngineImpl::SetOutputHandler(XmppOutputHandler* output_handler) {
+XmppReturnStatus XmppEngineImpl::SetOutputHandler(
+ XmppOutputHandler* output_handler) {
if (state_ != STATE_START)
return XMPP_RETURN_BADSTATE;
@@ -91,8 +87,8 @@
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::SetSessionHandler(XmppSessionHandler* session_handler) {
+XmppReturnStatus XmppEngineImpl::SetSessionHandler(
+ XmppSessionHandler* session_handler) {
if (state_ != STATE_START)
return XMPP_RETURN_BADSTATE;
@@ -101,21 +97,20 @@
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::HandleInput(const char * bytes, size_t len) {
+XmppReturnStatus XmppEngineImpl::HandleInput(
+ const char* bytes, size_t len) {
if (state_ < STATE_OPENING || state_ > STATE_OPEN)
return XMPP_RETURN_BADSTATE;
EnterExit ee(this);
// TODO: The return value of the xml parser is not checked.
- stanzaParser_.Parse(bytes, len, false);
+ stanza_parser_.Parse(bytes, len, false);
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::ConnectionClosed(int subcode) {
+XmppReturnStatus XmppEngineImpl::ConnectionClosed(int subcode) {
if (state_ != STATE_CLOSED) {
EnterExit ee(this);
// If told that connection closed and not already closed,
@@ -129,17 +124,16 @@
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::SetTls(TlsOptions useTls) {
+XmppReturnStatus XmppEngineImpl::SetTls(TlsOptions useTls) {
if (state_ != STATE_START)
return XMPP_RETURN_BADSTATE;
tls_option_ = useTls;
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::SetTlsServer(const std::string & tls_server_hostname,
- const std::string & tls_server_domain) {
+XmppReturnStatus XmppEngineImpl::SetTlsServer(
+ const std::string& tls_server_hostname,
+ const std::string& tls_server_domain) {
if (state_ != STATE_START)
return XMPP_RETURN_BADSTATE;
@@ -149,13 +143,11 @@
return XMPP_RETURN_OK;
}
-TlsOptions
-XmppEngineImpl::GetTls() {
+TlsOptions XmppEngineImpl::GetTls() {
return tls_option_;
}
-XmppReturnStatus
-XmppEngineImpl::SetUser(const Jid & jid) {
+XmppReturnStatus XmppEngineImpl::SetUser(const Jid& jid) {
if (state_ != STATE_START)
return XMPP_RETURN_BADSTATE;
@@ -164,13 +156,11 @@
return XMPP_RETURN_OK;
}
-const Jid &
-XmppEngineImpl::GetUser() {
+const Jid& XmppEngineImpl::GetUser() {
return user_jid_;
}
-XmppReturnStatus
-XmppEngineImpl::SetSaslHandler(SaslHandler * sasl_handler) {
+XmppReturnStatus XmppEngineImpl::SetSaslHandler(SaslHandler* sasl_handler) {
if (state_ != STATE_START)
return XMPP_RETURN_BADSTATE;
@@ -178,8 +168,8 @@
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::SetRequestedResource(const std::string & resource) {
+XmppReturnStatus XmppEngineImpl::SetRequestedResource(
+ const std::string& resource) {
if (state_ != STATE_START)
return XMPP_RETURN_BADSTATE;
@@ -188,14 +178,13 @@
return XMPP_RETURN_OK;
}
-const std::string &
-XmppEngineImpl::GetRequestedResource() {
+const std::string& XmppEngineImpl::GetRequestedResource() {
return requested_resource_;
}
-XmppReturnStatus
-XmppEngineImpl::AddStanzaHandler(XmppStanzaHandler * stanza_handler,
- XmppEngine::HandlerLevel level) {
+XmppReturnStatus XmppEngineImpl::AddStanzaHandler(
+ XmppStanzaHandler* stanza_handler,
+ XmppEngine::HandlerLevel level) {
if (state_ == STATE_CLOSED)
return XMPP_RETURN_BADSTATE;
@@ -204,9 +193,8 @@
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::RemoveStanzaHandler(XmppStanzaHandler * stanza_handler) {
-
+XmppReturnStatus XmppEngineImpl::RemoveStanzaHandler(
+ XmppStanzaHandler* stanza_handler) {
bool found = false;
for (int level = 0; level < HL_COUNT; level += 1) {
@@ -221,15 +209,13 @@
}
}
- if (!found) {
+ if (!found)
return XMPP_RETURN_BADARGUMENT;
- }
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::Connect() {
+XmppReturnStatus XmppEngineImpl::Connect() {
if (state_ != STATE_START)
return XMPP_RETURN_BADSTATE;
@@ -246,8 +232,7 @@
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::SendStanza(const XmlElement * element) {
+XmppReturnStatus XmppEngineImpl::SendStanza(const XmlElement* element) {
if (state_ == STATE_CLOSED)
return XMPP_RETURN_BADSTATE;
@@ -264,8 +249,7 @@
return XMPP_RETURN_OK;
}
-XmppReturnStatus
-XmppEngineImpl::SendRaw(const std::string & text) {
+XmppReturnStatus XmppEngineImpl::SendRaw(const std::string& text) {
if (state_ == STATE_CLOSED || login_task_.get())
return XMPP_RETURN_BADSTATE;
@@ -276,16 +260,13 @@
return XMPP_RETURN_OK;
}
-std::string
-XmppEngineImpl::NextId() {
+std::string XmppEngineImpl::NextId() {
std::stringstream ss;
ss << next_id_++;
return ss.str();
}
-XmppReturnStatus
-XmppEngineImpl::Disconnect() {
-
+XmppReturnStatus XmppEngineImpl::Disconnect() {
if (state_ != STATE_CLOSED) {
EnterExit ee(this);
if (state_ == STATE_OPEN)
@@ -296,14 +277,13 @@
return XMPP_RETURN_OK;
}
-void
-XmppEngineImpl::IncomingStart(const XmlElement * pelStart) {
+void XmppEngineImpl::IncomingStart(const XmlElement* start) {
if (HasError() || raised_reset_)
return;
if (login_task_.get()) {
// start-stream should go to login task
- login_task_->IncomingStanza(pelStart, true);
+ login_task_->IncomingStanza(start, true);
if (login_task_->IsDone())
login_task_.reset();
}
@@ -313,8 +293,7 @@
}
}
-void
-XmppEngineImpl::IncomingStanza(const XmlElement * stanza) {
+void XmppEngineImpl::IncomingStanza(const XmlElement* stanza) {
if (HasError() || raised_reset_)
return;
@@ -338,7 +317,7 @@
for (int level = HL_SINGLE; level <= HL_ALL; level += 1) {
for (size_t i = 0; i < stanza_handlers_[level]->size(); i += 1) {
if ((*stanza_handlers_[level])[i]->HandleStanza(stanza))
- goto Handled;
+ return;
}
}
@@ -346,29 +325,24 @@
// Only do this for IQ stanzas as messages should probably just be dropped
// and presence stanzas should certainly be dropped.
std::string type = stanza->Attr(QN_TYPE);
- if (stanza->Name() == QN_IQ &&
+ if (stanza->Name() == QN_IQ &&
!(type == "error" || type == "result")) {
SendStanzaError(stanza, XSE_FEATURE_NOT_IMPLEMENTED, STR_EMPTY);
}
}
- Handled:
- ; // handled - we're done
}
-void
-XmppEngineImpl::IncomingEnd(bool isError) {
+void XmppEngineImpl::IncomingEnd(bool isError) {
if (HasError() || raised_reset_)
return;
SignalError(isError ? ERROR_XML : ERROR_DOCUMENT_CLOSED, 0);
}
-void
-XmppEngineImpl::InternalSendStart(const std::string & to) {
+void XmppEngineImpl::InternalSendStart(const std::string& to) {
std::string hostname = tls_server_hostname_;
- if (hostname.empty()) {
+ if (hostname.empty())
hostname = to;
- }
// If not language is specified, the spec says use *
std::string lang = lang_;
@@ -385,60 +359,51 @@
<< "xmlns=\"jabber:client\">\r\n";
}
-void
-XmppEngineImpl::InternalSendStanza(const XmlElement * element) {
+void XmppEngineImpl::InternalSendStanza(const XmlElement* element) {
// It should really never be necessary to set a FROM attribute on a stanza.
// It is implied by the bind on the stream and if you get it wrong
// (by flipping from/to on a message?) the server will close the stream.
ASSERT(!element->HasAttr(QN_FROM));
- // TODO: consider caching the XmlPrinter
- XmlPrinter::PrintXml(output_.get(), element,
- XMPP_CLIENT_NAMESPACES, XMPP_CLIENT_NAMESPACES_LEN);
+ XmlPrinter::PrintXml(output_.get(), element, &xmlns_stack_);
}
-std::string
-XmppEngineImpl::ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted) {
+std::string XmppEngineImpl::ChooseBestSaslMechanism(
+ const std::vector<std::string>& mechanisms, bool encrypted) {
return sasl_handler_->ChooseBestSaslMechanism(mechanisms, encrypted);
}
-SaslMechanism *
-XmppEngineImpl::GetSaslMechanism(const std::string & name) {
+SaslMechanism* XmppEngineImpl::GetSaslMechanism(const std::string& name) {
return sasl_handler_->CreateSaslMechanism(name);
}
-void
-XmppEngineImpl::SignalBound(const Jid & fullJid) {
+void XmppEngineImpl::SignalBound(const Jid& fullJid) {
if (state_ == STATE_OPENING) {
bound_jid_ = fullJid;
state_ = STATE_OPEN;
}
}
-void
-XmppEngineImpl::SignalStreamError(const XmlElement * pelStreamError) {
+void XmppEngineImpl::SignalStreamError(const XmlElement* stream_error) {
if (state_ != STATE_CLOSED) {
- stream_error_.reset(new XmlElement(*pelStreamError));
+ stream_error_.reset(new XmlElement(*stream_error));
SignalError(ERROR_STREAM, 0);
}
}
-void
-XmppEngineImpl::SignalError(Error errorCode, int subCode) {
+void XmppEngineImpl::SignalError(Error error_code, int sub_code) {
if (state_ != STATE_CLOSED) {
- error_code_ = errorCode;
- subcode_ = subCode;
+ error_code_ = error_code;
+ subcode_ = sub_code;
state_ = STATE_CLOSED;
}
}
-bool
-XmppEngineImpl::HasError() {
+bool XmppEngineImpl::HasError() {
return error_code_ != ERROR_NONE;
}
-void
-XmppEngineImpl::StartTls(const std::string & domain) {
+void XmppEngineImpl::StartTls(const std::string& domain) {
if (output_handler_) {
// As substitute for the real (login jid's) domain, we permit
// verifying a tls_server_domain_ instead, if one was passed.
@@ -451,7 +416,7 @@
}
XmppEngineImpl::EnterExit::EnterExit(XmppEngineImpl* engine)
- : engine_(engine),
+ : engine_(engine),
state_(engine->state_),
error_(engine->error_code_) {
engine->engine_entered_ += 1;
@@ -482,17 +447,17 @@
return;
if (engine->raised_reset_) {
- engine->stanzaParser_.Reset();
+ engine->stanza_parser_.Reset();
engine->raised_reset_ = false;
}
if (engine->session_handler_) {
if (engine->state_ != state_)
engine->session_handler_->OnStateChange(engine->state_);
- // Note: Handling of OnStateChange(CLOSED) should allow for the
- // deletion of the engine, so no members should be accessed
- // after this line.
+ // Note: Handling of OnStateChange(CLOSED) should allow for the
+ // deletion of the engine, so no members should be accessed
+ // after this line.
}
}
-}
+} // namespace buzz
diff --git a/talk/xmpp/xmppengineimpl.h b/talk/xmpp/xmppengineimpl.h
index 931955d..1fdb2a0 100644
--- a/talk/xmpp/xmppengineimpl.h
+++ b/talk/xmpp/xmppengineimpl.h
@@ -25,8 +25,8 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _xmppengineimpl_h_
-#define _xmppengineimpl_h_
+#ifndef TALK_XMPP_XMPPENGINEIMPL_H_
+#define TALK_XMPP_XMPPENGINEIMPL_H_
#include <sstream>
#include <vector>
@@ -50,7 +50,7 @@
//! An application can listen for events and receive stanzas by
//! registering an XmppStanzaHandler via AddStanzaHandler().
class XmppEngineImpl : public XmppEngine {
-public:
+ public:
XmppEngineImpl();
virtual ~XmppEngineImpl();
@@ -60,7 +60,7 @@
virtual XmppReturnStatus SetOutputHandler(XmppOutputHandler *pxoh);
//! Provides socket input to the engine
- virtual XmppReturnStatus HandleInput(const char * bytes, size_t len);
+ virtual XmppReturnStatus HandleInput(const char* bytes, size_t len);
//! Advises the engine that the socket has closed
virtual XmppReturnStatus ConnectionClosed(int subcode);
@@ -68,13 +68,13 @@
// SESSION SETUP ---------------------------------------------------------
//! Indicates the (bare) JID for the user to use.
- virtual XmppReturnStatus SetUser(const Jid & jid);
+ virtual XmppReturnStatus SetUser(const Jid& jid);
//! Get the login (bare) JID.
- virtual const Jid & GetUser();
+ virtual const Jid& GetUser();
//! Indicates the autentication to use. Takes ownership of the object.
- virtual XmppReturnStatus SetSaslHandler(SaslHandler * sasl_handler);
+ virtual XmppReturnStatus SetSaslHandler(SaslHandler* sasl_handler);
//! Sets whether TLS will be used within the connection (default true).
virtual XmppReturnStatus SetTls(TlsOptions useTls);
@@ -83,8 +83,8 @@
//! This is for use in the case where a we want to allow a proxy to
//! serve up its own certificate rather than one owned by the underlying
//! domain.
- virtual XmppReturnStatus SetTlsServer(const std::string & proxy_hostname,
- const std::string & proxy_domain);
+ virtual XmppReturnStatus SetTlsServer(const std::string& proxy_hostname,
+ const std::string& proxy_domain);
//! Gets whether TLS will be used within the connection.
virtual TlsOptions GetTls();
@@ -95,10 +95,10 @@
virtual XmppReturnStatus SetRequestedResource(const std::string& resource);
//! Gets the request resource name.
- virtual const std::string & GetRequestedResource();
+ virtual const std::string& GetRequestedResource();
//! Sets language
- virtual void SetLanguage(const std::string & lang) {
+ virtual void SetLanguage(const std::string& lang) {
lang_ = lang;
}
@@ -130,7 +130,7 @@
//! The stream:error stanza, when the error is XmppEngine::ERROR_STREAM.
//! Notice the stanza returned is owned by the XmppEngine and
//! is deleted when the engine is destroyed.
- virtual const XmlElement * GetStreamError() { return stream_error_.get(); }
+ virtual const XmlElement* GetStreamError() { return stream_error_.get(); }
//! Closes down the connection.
//! Sends CloseConnection to output, and disconnects and registered
@@ -150,14 +150,14 @@
virtual XmppReturnStatus RemoveStanzaHandler(XmppStanzaHandler* handler);
//! Sends a stanza to the server.
- virtual XmppReturnStatus SendStanza(const XmlElement * pelStanza);
+ virtual XmppReturnStatus SendStanza(const XmlElement* stanza);
//! Sends raw text to the server
- virtual XmppReturnStatus SendRaw(const std::string & text);
+ virtual XmppReturnStatus SendRaw(const std::string& text);
//! Sends an iq to the server, and registers a callback for the result.
//! Returns the cookie passed to the result handler.
- virtual XmppReturnStatus SendIq(const XmlElement* pelStanza,
+ virtual XmppReturnStatus SendIq(const XmlElement* stanza,
XmppIqHandler* iq_handler,
XmppIqCookie* cookie);
@@ -169,55 +169,62 @@
//! Forms and sends an error in response to the given stanza.
//! Swaps to and from, sets type to "error", and adds error information
//! based on the passed code. Text is optional and may be STR_EMPTY.
- virtual XmppReturnStatus SendStanzaError(const XmlElement * pelOriginal,
+ virtual XmppReturnStatus SendStanzaError(const XmlElement* pelOriginal,
XmppStanzaError code,
- const std::string & text);
+ const std::string& text);
//! The fullly bound JID.
//! This JID is only valid after binding has succeeded. If the value
//! is JID_NULL, the binding has not succeeded.
- virtual const Jid & FullJid() { return bound_jid_; }
+ virtual const Jid& FullJid() { return bound_jid_; }
//! The next unused iq id for this connection.
//! Call this when building iq stanzas, to ensure that each iq
//! gets its own unique id.
virtual std::string NextId();
-private:
+ private:
friend class XmppLoginTask;
friend class XmppIqEntry;
- void IncomingStanza(const XmlElement *pelStanza);
- void IncomingStart(const XmlElement *pelStanza);
+ void IncomingStanza(const XmlElement *stanza);
+ void IncomingStart(const XmlElement *stanza);
void IncomingEnd(bool isError);
- void InternalSendStart(const std::string & domainName);
- void InternalSendStanza(const XmlElement * pelStanza);
- std::string ChooseBestSaslMechanism(const std::vector<std::string> & mechanisms, bool encrypted);
- SaslMechanism * GetSaslMechanism(const std::string & name);
- void SignalBound(const Jid & fullJid);
- void SignalStreamError(const XmlElement * pelStreamError);
+ void InternalSendStart(const std::string& domainName);
+ void InternalSendStanza(const XmlElement* stanza);
+ std::string ChooseBestSaslMechanism(
+ const std::vector<std::string>& mechanisms, bool encrypted);
+ SaslMechanism* GetSaslMechanism(const std::string& name);
+ void SignalBound(const Jid& fullJid);
+ void SignalStreamError(const XmlElement* streamError);
void SignalError(Error errorCode, int subCode);
bool HasError();
void DeleteIqCookies();
- bool HandleIqResponse(const XmlElement * element);
- void StartTls(const std::string & domain);
+ bool HandleIqResponse(const XmlElement* element);
+ void StartTls(const std::string& domain);
void RaiseReset() { raised_reset_ = true; }
class StanzaParseHandler : public XmppStanzaParseHandler {
- public:
- StanzaParseHandler(XmppEngineImpl * outer) : outer_(outer) {}
+ public:
+ StanzaParseHandler(XmppEngineImpl* outer) : outer_(outer) {}
virtual ~StanzaParseHandler() {}
- virtual void StartStream(const XmlElement * pelStream)
- { outer_->IncomingStart(pelStream); }
- virtual void Stanza(const XmlElement * pelStanza)
- { outer_->IncomingStanza(pelStanza); }
- virtual void EndStream()
- { outer_->IncomingEnd(false); }
- virtual void XmlError()
- { outer_->IncomingEnd(true); }
- private:
- XmppEngineImpl * const outer_;
+
+ virtual void StartStream(const XmlElement* stream) {
+ outer_->IncomingStart(stream);
+ }
+ virtual void Stanza(const XmlElement* stanza) {
+ outer_->IncomingStanza(stanza);
+ }
+ virtual void EndStream() {
+ outer_->IncomingEnd(false);
+ }
+ virtual void XmlError() {
+ outer_->IncomingEnd(true);
+ }
+
+ private:
+ XmppEngineImpl* const outer_;
};
class EnterExit {
@@ -234,9 +241,8 @@
friend class StanzaParseHandler;
friend class EnterExit;
- StanzaParseHandler stanzaParseHandler_;
- XmppStanzaParser stanzaParser_;
-
+ StanzaParseHandler stanza_parse_handler_;
+ XmppStanzaParser stanza_parser_;
// state
int engine_entered_;
@@ -260,6 +266,8 @@
XmppOutputHandler* output_handler_;
XmppSessionHandler* session_handler_;
+ XmlnsStack xmlns_stack_;
+
typedef std::vector<XmppStanzaHandler*> StanzaHandlerVector;
talk_base::scoped_ptr<StanzaHandlerVector> stanza_handlers_[HL_COUNT];
@@ -271,7 +279,6 @@
talk_base::scoped_ptr<std::stringstream> output_;
};
-}
+} // namespace buzz
-
-#endif
+#endif // TALK_XMPP_XMPPENGINEIMPL_H_