summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Cole <robert.cole@intel.com>2015-06-03 16:40:15 -0400
committerErich Keane <erich.keane@intel.com>2015-06-09 06:22:38 +0000
commitb0c2d424aa62c3ea66cfac4520c3f223c676df26 (patch)
treee7bbc30d7e5f5d3f54262c3ff0ff1d56d5400a38
parent0786c728f45262ae654d6c205eba99086b6cd768 (diff)
Implementation and tests for XMPP service discovery and XMPP ping.
These are basic implementations of the representative iq messages for each type of service and do not include any additional parsing or timer handling (for ping). Change-Id: I9d3eece8092a3ced347ab0ed04efa171109a9ba3 Signed-off-by: Robert Cole <robert.cole@intel.com> Reviewed-on: https://gerrit.iotivity.org/gerrit/1184 Reviewed-by: Charlie Lenahan <charlie.lenahan@intel.com> Reviewed-by: Erich Keane <erich.keane@intel.com> Tested-by: Erich Keane <erich.keane@intel.com>
-rw-r--r--WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj2
-rw-r--r--WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj.filters6
-rw-r--r--src/xmpp/xmppclient.cpp63
-rw-r--r--src/xmpp/xmppclient.h10
-rw-r--r--src/xmpp/xmppconfig.h2
-rw-r--r--src/xmpp/xmppinterfaces.h8
-rw-r--r--src/xmpp/xmppping.cpp59
-rw-r--r--src/xmpp/xmppping.h36
-rw-r--r--src/xmpp/xmppservicedisc.cpp86
-rw-r--r--src/xmpp/xmppservicedisc.h34
-rw-r--r--test/ping_tests.cpp43
-rw-r--r--test/servicedisc_tests.cpp108
-rw-r--r--test/xmpp_connect_establish.cpp190
-rw-r--r--test/xmpp_connect_establish.h41
14 files changed, 651 insertions, 37 deletions
diff --git a/WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj b/WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj
index 081af65..457306a 100644
--- a/WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj
+++ b/WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj
@@ -277,6 +277,7 @@ xcopy /y /d "$(SolutionDir)\packages\libssh2.redist.1.4.3.1\build\native\bin\v11
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\test\xmpp_connect_config.h" />
+ <ClInclude Include="..\..\test\xmpp_connect_establish.h" />
<ClInclude Include="..\..\test\xmpp_dummy_server.h" />
<ClInclude Include="..\..\test\xmpp_test_config.h" />
<ClInclude Include="stdafx.h" />
@@ -302,6 +303,7 @@ xcopy /y /d "$(SolutionDir)\packages\libssh2.redist.1.4.3.1\build\native\bin\v11
<ClCompile Include="..\..\test\unittest_base.cpp" />
<ClCompile Include="..\..\test\xmpp_compliance_tests.cpp" />
<ClCompile Include="..\..\test\xmpp_connect_config.cpp" />
+ <ClCompile Include="..\..\test\xmpp_connect_establish.cpp" />
<ClCompile Include="..\..\test\xmpp_dummy_server.cpp" />
<ClCompile Include="..\..\test\xmpp_tests.cpp" />
<ClCompile Include="stdafx.cpp">
diff --git a/WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj.filters b/WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj.filters
index d99bfa4..249bd66 100644
--- a/WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj.filters
+++ b/WinDT/CCFXmpp_Tests/CCFXmpp_Tests.vcxproj.filters
@@ -30,6 +30,9 @@
<ClInclude Include="..\..\test\xmpp_connect_config.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\test\xmpp_connect_establish.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@@ -77,6 +80,9 @@
<ClCompile Include="..\..\test\xmpp_connect_config.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\test\xmpp_connect_establish.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
diff --git a/src/xmpp/xmppclient.cpp b/src/xmpp/xmppclient.cpp
index 3503f15..3acbc79 100644
--- a/src/xmpp/xmppclient.cpp
+++ b/src/xmpp/xmppclient.cpp
@@ -39,6 +39,7 @@
#include "../xmpp/xmppconfig.h"
#include "../xmpp/jabberid.h"
+
// TOOD: Move interface when refactoring for BOSH 'streams'
#include "../connect/tcpclient.h"
@@ -46,7 +47,36 @@
+
+/// @mainpage Iotivity XMPP Client
+///
+/// @section intro Introduction
+///
+/// The Iotivity XMPP Client is a basic C++ XMPP client implementation written to provide
+/// cross-platform support for XMPP for Iotivity and the CCF project.
+///
+/// @section XMPP Support
+///
+/// <ul>
+/// <li>RFC 6120 (XMPP Core)</li>
+/// <li>SASL
+/// <ul>
+/// <li>RFC 4616 (PLAIN)</li>
+/// </ul>
+/// </li>
+/// <li>XMPP Extensions
+/// <ul>
+/// <li>XEP-0077 (In-Band Registration)</li>
+/// <li>XEP-0030 (Service-Discovery) [Basic queries only]</li>
+/// <li>XEP-0199 (XMPP Ping) [Timer-based ping/pong still a WIP]</li>
+/// </ul>
+/// </li>
+/// </ul>
+
+
+
/// @addtogroup XMPP
+/// @{
/// Create and start an XMPP client:
/// @code
///
@@ -101,30 +131,7 @@
/// {}
///
/// @endcode
-
-
-/// @mainpage Iotivity XMPP Client
-///
-/// @section intro Introduction
-///
-/// The Iotivity XMPP Client is a basic C++ XMPP client implementation written to provide
-/// cross-platform support for XMPP for Iotivity and the CCF project.
-///
-/// @section XMPP Support
-///
-/// <ul>
-/// <li>RFC 6120 (XMPP Core)</li>
-/// <li>SASL
-/// <ul>
-/// <li>RFC 4616 (PLAIN)</li>
-/// </ul>
-/// </li>
-/// <li>XMPP Extensions
-/// <ul>
-/// <li>XEP-0077 (In-Band Registration)</li>
-/// </ul>
-/// </li>
-/// </ul>
+/// @}
@@ -234,7 +241,7 @@ namespace Iotivity
}
}
- // const static size_t DEFAULT_BUFFER_SIZE = 4096;
+ // const static size_t DEFAULT_BUFFER_SIZE = 4096;
void XmppConnection::receive(XMLElement::Ptr &payload)
{
@@ -987,6 +994,7 @@ namespace Iotivity
onConnected().fire(XmppConnectedEvent(
connect_error::SUCCESS));
m_boundPromise.set_value(m_boundJabberId);
+ m_negotiatedPromise.set_value();
}
else
{
@@ -1486,7 +1494,7 @@ namespace Iotivity
// Action runner for the XMPP client.
struct XmppClientRunner: public ActionRunner<std::shared_ptr<IXmppConnection>, XmppContext>
{
- XmppClientRunner(XmppClient &owner) /*: m_owner(owner)*/ {}
+ XmppClientRunner(XmppClient &) {}
protected:
virtual std::thread createActionThread(std::shared_ptr<runner_queue> queue,
@@ -1527,9 +1535,6 @@ namespace Iotivity
}
});
}
-
- private:
- // XmppClient &m_owner;
};
/// @endcond
diff --git a/src/xmpp/xmppclient.h b/src/xmpp/xmppclient.h
index e1f5cb9..00fc43d 100644
--- a/src/xmpp/xmppclient.h
+++ b/src/xmpp/xmppclient.h
@@ -139,12 +139,10 @@ namespace Iotivity
virtual SyncEvent<XmppStreamCreatedEvent> &onStreamCreated();
- typedef std::shared_ptr<std::promise<std::shared_ptr<IXmppStream>>>
- XmppStreamPromise;
-
- void initiateXMPP(const XmppConfig &config,
- std::shared_ptr<IXmppConnection> remoteServer,
- XmppStreamPromise xmppConnection = XmppStreamPromise());
+ virtual void initiateXMPP(const XmppConfig &config,
+ std::shared_ptr<IXmppConnection> remoteServer,
+ XmppStreamPromise xmppConnection =
+ XmppStreamPromise()) override;
protected:
XmppClient();
diff --git a/src/xmpp/xmppconfig.h b/src/xmpp/xmppconfig.h
index cde0df5..eef784e 100644
--- a/src/xmpp/xmppconfig.h
+++ b/src/xmpp/xmppconfig.h
@@ -43,7 +43,7 @@ namespace Iotivity
{
void operator()(XmppConfigImpl *);
};
- /// @endcode
+ /// @endcond
}
}
diff --git a/src/xmpp/xmppinterfaces.h b/src/xmpp/xmppinterfaces.h
index 7790c26..af9da86 100644
--- a/src/xmpp/xmppinterfaces.h
+++ b/src/xmpp/xmppinterfaces.h
@@ -53,6 +53,7 @@ namespace Iotivity
{
struct SaslResult;
class connect_error;
+ class XmppConfig;
/// @brief XML Stream interface. Provides a stream from which XML payloads may be
@@ -226,8 +227,15 @@ namespace Iotivity
class XMPP_API IXmppClient
{
public:
+ typedef std::shared_ptr<std::promise<std::shared_ptr<IXmppStream>>>
+ XmppStreamPromise;
+
virtual ~IXmppClient() {}
+ virtual void initiateXMPP(const XmppConfig &config,
+ std::shared_ptr<IXmppConnection> remoteServer,
+ XmppStreamPromise xmppConnection =
+ XmppStreamPromise()) = 0;
virtual SyncEvent<XmppStreamCreatedEvent> &onStreamCreated() = 0;
};
diff --git a/src/xmpp/xmppping.cpp b/src/xmpp/xmppping.cpp
index ab5271e..37beb42 100644
--- a/src/xmpp/xmppping.cpp
+++ b/src/xmpp/xmppping.cpp
@@ -26,7 +26,7 @@
#include "stdafx.h"
#include "xmppping.h"
-
+#include "jabberid.h"
#include "../connect/connecterror.h"
#ifndef DISABLE_SUPPORT_XEP0199
@@ -38,6 +38,63 @@ namespace Iotivity
{
namespace Xmpp
{
+ static const string XMPP_PING_NS = "urn:xmpp:ping";
+
+ shared_ptr<XmppPing::Params> XmppPing::Params::create()
+ {
+ return shared_ptr<Params>(new Params);
+ }
+
+ bool XmppPing::Params::supportsExtension(const string &extensionName) const
+ {
+ return extensionName == XmppPing::extensionName();
+ }
+
+ XmppPing::XmppPing(shared_ptr<IXmppStream> overStream):
+ XmppExtension(overStream)
+ {}
+
+ XmppPing::~XmppPing()
+ {
+ // Called here so any captured this is not stale when the queries halt.
+ haltSafeQueries();
+ }
+
+ void XmppPing::assignConfiguration(std::shared_ptr<IExtensionParams> config)
+ {
+ if (config && config->supportsExtension(XmppPing::extensionName()))
+ {
+ m_config = static_pointer_cast<Params>(config);
+ }
+ }
+
+ void XmppPing::sendPing(const JabberID &target, PongCallback onPong)
+ {
+ XMLElement::Ptr request = constructIQ("get", target.full());
+ XMLElement::Ptr query = request->owner()->createElement("ping");
+ query->setAttribute("xmlns", XMPP_PING_NS);
+ request->appendChild(query);
+
+ sendSafeQuery(move(request),
+ [this, onPong]
+ (const connect_error & ce, XMLElement::Ptr response)
+ {
+ if (!ce.succeeded())
+ {
+ onPong(ce);
+ return;
+ }
+
+ connect_error result = testAndProcessErrorResponse(response);
+ if (result.succeeded())
+ {
+
+ }
+ onPong(result);
+ });
+ }
+
+
}
}
diff --git a/src/xmpp/xmppping.h b/src/xmpp/xmppping.h
index e7bc99a..de701bf 100644
--- a/src/xmpp/xmppping.h
+++ b/src/xmpp/xmppping.h
@@ -39,6 +39,42 @@ namespace Iotivity
{
namespace Xmpp
{
+ class connect_error;
+
+ // XEP-0199 XMPP Ping
+ class XmppPing: public XmppExtension
+ {
+ public:
+ class XMPP_API Params: public IExtensionParams
+ {
+ public:
+ Params() = default;
+ Params(const Params &) = default;
+ static std::shared_ptr<Params> create();
+
+ virtual bool supportsExtension(const std::string &extensionName) const override;
+
+ private:
+
+ };
+ public:
+ XmppPing(std::shared_ptr<IXmppStream> overStream);
+ virtual ~XmppPing() override;
+
+ static std::string extensionName() { return "XEP0199"; }
+ virtual std::string getExtensionName() const override
+ {
+ return XmppPing::extensionName();
+ }
+
+ virtual void assignConfiguration(std::shared_ptr<IExtensionParams> config) override;
+
+ typedef std::function<void(const connect_error &)> PongCallback;
+ void sendPing(const JabberID &target, PongCallback onPong = PongCallback());
+
+ private:
+ std::shared_ptr<Params> m_config;
+ };
}
}
diff --git a/src/xmpp/xmppservicedisc.cpp b/src/xmpp/xmppservicedisc.cpp
index a1ac629..680aa1c 100644
--- a/src/xmpp/xmppservicedisc.cpp
+++ b/src/xmpp/xmppservicedisc.cpp
@@ -26,6 +26,7 @@
#include "stdafx.h"
#include "xmppservicedisc.h"
+#include "jabberid.h"
#include "../connect/connecterror.h"
@@ -38,6 +39,91 @@ namespace Iotivity
{
namespace Xmpp
{
+ static const string XMPP_SERVICE_DISCOVERY_INFO_NS = "http://jabber.org/protocol/disco#info";
+ static const string XMPP_SERVICE_DISCOVERY_ITEMS_NS = "http://jabber.org/protocol/disco#items";
+
+
+ shared_ptr<XmppServiceDiscovery::Params> XmppServiceDiscovery::Params::create()
+ {
+ return shared_ptr<Params>(new Params);
+ }
+
+ bool XmppServiceDiscovery::Params::supportsExtension(const string &extensionName) const
+ {
+ return extensionName == XmppServiceDiscovery::extensionName();
+ }
+
+ XmppServiceDiscovery::XmppServiceDiscovery(shared_ptr<IXmppStream> overStream):
+ XmppExtension(overStream)
+ {
+ }
+
+ XmppServiceDiscovery::~XmppServiceDiscovery()
+ {
+ // Called here so any captured this is not stale when the queries halt.
+ haltSafeQueries();
+ }
+
+ void XmppServiceDiscovery::assignConfiguration(std::shared_ptr<IExtensionParams> config)
+ {
+ if (config && config->supportsExtension(XmppServiceDiscovery::extensionName()))
+ {
+ m_config = static_pointer_cast<Params>(config);
+ }
+ }
+
+ void XmppServiceDiscovery::queryInfo(const JabberID &target, DiscoveryCallback callback)
+ {
+ XMLElement::Ptr request = constructIQ("get", target.full());
+ XMLElement::Ptr query = request->owner()->createElement("query");
+ query->setAttribute("xmlns", XMPP_SERVICE_DISCOVERY_INFO_NS);
+ request->appendChild(query);
+
+ sendSafeQuery(move(request),
+ [this, callback]
+ (const connect_error & ce, XMLElement::Ptr response)
+ {
+ if (!ce.succeeded())
+ {
+ callback(ce, response);
+ return;
+ }
+
+ connect_error result = testAndProcessErrorResponse(response);
+ if (result.succeeded())
+ {
+ // TODO: Decode response.
+ }
+ callback(result, response);
+ });
+ }
+
+ void XmppServiceDiscovery::queryItems(const JabberID &target, DiscoveryCallback callback)
+ {
+ XMLElement::Ptr request = constructIQ("get", target.full());
+ XMLElement::Ptr query = request->owner()->createElement("query");
+ query->setAttribute("xmlns", XMPP_SERVICE_DISCOVERY_ITEMS_NS);
+ request->appendChild(query);
+
+ sendSafeQuery(move(request),
+ [this, callback]
+ (const connect_error & ce, XMLElement::Ptr response)
+ {
+ if (!ce.succeeded())
+ {
+ callback(ce, response);
+ return;
+ }
+
+ connect_error result = testAndProcessErrorResponse(response);
+ if (result.succeeded())
+ {
+ // TODO: Decode response.
+ }
+ callback(result, response);
+ });
+ }
+
}
}
diff --git a/src/xmpp/xmppservicedisc.h b/src/xmpp/xmppservicedisc.h
index fed5a86..6ab6493 100644
--- a/src/xmpp/xmppservicedisc.h
+++ b/src/xmpp/xmppservicedisc.h
@@ -39,6 +39,40 @@ namespace Iotivity
{
namespace Xmpp
{
+ // XEP-0030 Service Discovery
+ class XmppServiceDiscovery: public XmppExtension
+ {
+ public:
+ class XMPP_API Params: public IExtensionParams
+ {
+ public:
+ Params() = default;
+ Params(const Params &) = default;
+ static std::shared_ptr<Params> create();
+
+ virtual bool supportsExtension(const std::string &extensionName) const override;
+ };
+ public:
+ XmppServiceDiscovery(std::shared_ptr<IXmppStream> overStream);
+ virtual ~XmppServiceDiscovery() override;
+
+ static std::string extensionName() { return "XEP0030"; }
+ virtual std::string getExtensionName() const override
+ {
+ return XmppServiceDiscovery::extensionName();
+ }
+
+ virtual void assignConfiguration(std::shared_ptr<IExtensionParams> config) override;
+
+ typedef std::function<void(const connect_error &,
+ const XML::XMLElement::Ptr &)> DiscoveryCallback;
+ void queryInfo(const JabberID &target, DiscoveryCallback callback);
+ void queryItems(const JabberID &target, DiscoveryCallback callback);
+
+
+ private:
+ std::shared_ptr<Params> m_config;
+ };
}
}
diff --git a/test/ping_tests.cpp b/test/ping_tests.cpp
index f76d5ed..1dfe628 100644
--- a/test/ping_tests.cpp
+++ b/test/ping_tests.cpp
@@ -27,8 +27,12 @@
#include <gtest/gtest.h>
#include <xmpp/xmppping.h>
+#include <connect/connecterror.h>
#include "xmpp_test_config.h"
+#include "xmpp_connect_config.h"
+#include "xmpp_connect_establish.h"
+
extern "C"
{
@@ -45,5 +49,44 @@ using namespace Iotivity;
using namespace Iotivity::Xmpp;
+#ifndef DISABLE_SUPPORT_XEP0199
+
+TEST(Ping, XEP_0199_One_Shot_Ping)
+{
+ shared_ptr<IXmppClient> client;
+ shared_ptr<IXmppStream> stream;
+ xmpp_test_default_connect_client(stream, client);
+ EXPECT_NE(client, nullptr);
+ ASSERT_NE(stream, nullptr);
+
+ try
+ {
+ string xmppDomain;
+#ifdef ENABLE_LIBSTROPHE
+ xmppDomain = xmpp_connect_config::xmppDomain("NO_PROXY");
+#else
+ xmppDomain = xmpp_connect_config::xmppDomain();
+#endif
+
+ XmppPing ping(stream);
+ promise<void> pingPromise;
+ future<void> pinged = pingPromise.get_future();
+
+ ping.sendPing(xmppDomain, [&pingPromise](const connect_error & ce)
+ {
+ auto promise = move(pingPromise);
+ EXPECT_TRUE(ce.succeeded());
+
+ promise.set_value();
+ });
+
+ pinged.get();
+
+ stream->close();
+ }
+ catch (...)
+ {}
+}
+#endif // DISABLE_SUPPORT_XEP0199
diff --git a/test/servicedisc_tests.cpp b/test/servicedisc_tests.cpp
index 49dcc9e..921714b 100644
--- a/test/servicedisc_tests.cpp
+++ b/test/servicedisc_tests.cpp
@@ -27,8 +27,11 @@
#include <gtest/gtest.h>
#include <xmpp/xmppservicedisc.h>
+#include <connect/connecterror.h>
#include "xmpp_test_config.h"
+#include "xmpp_connect_config.h"
+#include "xmpp_connect_establish.h"
extern "C"
{
@@ -43,6 +46,111 @@ extern "C"
using namespace std;
using namespace Iotivity;
using namespace Iotivity::Xmpp;
+using namespace Iotivity::XML;
+#ifndef DISABLE_SUPPORT_XEP0030
+
+TEST(ServiceDiscovery, XEP_0030_Discovery_Info)
+{
+ shared_ptr<IXmppClient> client;
+ shared_ptr<IXmppStream> stream;
+ xmpp_test_default_connect_client(stream, client);
+ EXPECT_NE(client, nullptr);
+ ASSERT_NE(stream, nullptr);
+
+ try
+ {
+ XmppServiceDiscovery serviceDisc(stream);
+
+ string xmppDomain;
+#ifdef ENABLE_LIBSTROPHE
+ xmppDomain = xmpp_connect_config::xmppDomain("NO_PROXY");
+#else
+ xmppDomain = xmpp_connect_config::xmppDomain();
+#endif
+
+ promise<void> queriedPromise;
+ future<void> queried = queriedPromise.get_future();
+ serviceDisc.queryInfo(xmppDomain,
+ [&queriedPromise](const connect_error & ce,
+ const XMLElement::Ptr & e)
+ {
+ auto activeQuery = move(queriedPromise);
+
+ EXPECT_TRUE(ce.succeeded());
+ cout << "RESULT: " << ce.toString() << endl;
+ EXPECT_NE(e, nullptr);
+ if (e)
+ {
+
+ }
+
+ activeQuery.set_value();
+ });
+
+
+ queried.get();
+
+ stream->close();
+ }
+ catch (...)
+ {
+ EXPECT_NO_THROW(throw);
+ }
+}
+
+
+TEST(ServiceDiscovery, XEP_0030_Items_Info)
+{
+ shared_ptr<IXmppClient> client;
+ shared_ptr<IXmppStream> stream;
+ xmpp_test_default_connect_client(stream, client);
+ EXPECT_NE(client, nullptr);
+ ASSERT_NE(stream, nullptr);
+
+ try
+ {
+ XmppServiceDiscovery serviceDisc(stream);
+
+ string xmppDomain;
+#ifdef ENABLE_LIBSTROPHE
+ xmppDomain = xmpp_connect_config::xmppDomain("NO_PROXY");
+#else
+ xmppDomain = xmpp_connect_config::xmppDomain();
+#endif
+
+ promise<void> queriedPromise;
+ future<void> queried = queriedPromise.get_future();
+ serviceDisc.queryItems(xmppDomain,
+ [&queriedPromise](const connect_error & ce,
+ const XMLElement::Ptr & e)
+ {
+ auto activeQuery = move(queriedPromise);
+
+ EXPECT_TRUE(ce.succeeded());
+ cout << "RESULT: " << ce.toString() << endl;
+ EXPECT_NE(e, nullptr);
+ if (e)
+ {
+
+ }
+
+ activeQuery.set_value();
+ });
+
+
+ queried.get();
+
+ stream->close();
+ }
+ catch (...)
+ {
+ EXPECT_NO_THROW(throw);
+ }
+
+}
+
+
+#endif // DISABLE_SUPPORT_XEP0030
diff --git a/test/xmpp_connect_establish.cpp b/test/xmpp_connect_establish.cpp
new file mode 100644
index 0000000..fd6df2a
--- /dev/null
+++ b/test/xmpp_connect_establish.cpp
@@ -0,0 +1,190 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+//
+///////////////////////////////////////////////////////////////////////////////
+
+/// @file xmpp_connect_establish.cpp
+
+#include "stdafx.h"
+#include "xmpp_connect_establish.h"
+#ifdef ENABLE_LIBSTROPHE
+#include <xmpp/xmppstrophe.h>
+#else
+#include <xmpp/xmppclient.h>
+#endif
+#include <connect/tcpclient.h>
+#include <connect/proxy.h>
+#include <common/bufferencrypt.h>
+#include <xmpp/sasl.h>
+#include <xmpp/xmppconfig.h>
+#include <xmpp/xmppregister.h>
+#include "xmpp_connect_config.h"
+
+#include <openssl/sha.h>
+#include <openssl/hmac.h>
+
+#include <iostream>
+
+using namespace std;
+using namespace Iotivity;
+using namespace Iotivity::Xmpp;
+
+
+
+const char *TEST_SESSION_GUID = "F1AED571-A1E4-4DB7-BF1C-41865C44E691";
+const char *TEST_APP_GUID = "7e14b5f9-914c-4911-8fbf-af58de8825fb";
+const char TEST_APP_KEY[] = "RA XMPP CLIENT SECRET MAY BE REVOKED AT ANY TIME";
+
+
+string base64Encode(const void *buf, size_t size)
+{
+ if (!buf || size == 0)
+ {
+ return "";
+ }
+
+ ByteBuffer outBuffer;
+ ByteBuffer::base64Encode(ByteBuffer((void *)buf, size, false), outBuffer);
+
+ return string((const char *)outBuffer.get(), outBuffer.size());
+}
+
+void constructTestUserAuth(const string &userPart1, const string &userPart2,
+ string &userName, string &password)
+{
+ // Use a block of non-random random data so multiple users do not get registered for the
+ // connectional functional tests.
+ uint8_t randBuf[64] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40
+ };
+
+ uint8_t hmac[SHA256_DIGEST_LENGTH] = {0};
+ unsigned int digestLength = SHA256_DIGEST_LENGTH;
+
+ HMAC(EVP_sha256(), TEST_APP_KEY, sizeof(TEST_APP_KEY) / sizeof(TEST_APP_KEY[0]) - 1,
+ randBuf, sizeof(randBuf) / sizeof(randBuf[0]), &hmac[0], &digestLength);
+
+ userName = userPart1 + "_" + userPart2;
+ password = base64Encode(randBuf, sizeof(randBuf) / sizeof(randBuf[0])) + ":" +
+ base64Encode(hmac, sizeof(hmac) / sizeof(hmac[0]));
+}
+
+
+void xmpp_test_default_connect_client(shared_ptr<IXmppStream> &stream,
+ shared_ptr<IXmppClient> &client)
+{
+#ifdef ENABLE_LIBSTROPHE
+ if (!xmpp_connect_config::hasConfig("NO_PROXY"))
+#else
+ if (!xmpp_connect_config::hasConfig())
+#endif
+ {
+ return;
+ }
+
+#ifdef ENABLE_LIBSTROPHE
+ auto xmlConnection = make_shared<XmppStropheConnection>(xmpp_connect_config::host("NO_PROXY"),
+ xmpp_connect_config::port("NO_PROXY"));
+#else
+ const ProxyConfig proxy(xmpp_connect_config::proxyHost(),
+ xmpp_connect_config::proxyPort(),
+ Iotivity::Xmpp::ProxyConfig::ProxyType::ProxySOCKS5);
+ auto remoteTcp = make_shared<TcpConnection>(xmpp_connect_config::host(),
+ xmpp_connect_config::port(), proxy);
+
+ auto xmlConnection = make_shared<XmppConnection>(
+ static_pointer_cast<IStreamConnection>(remoteTcp));
+#endif
+
+ auto streamPromise = make_shared<promise<shared_ptr<IXmppStream>>>();
+ auto streamFuture = streamPromise->get_future();
+
+ string userName = xmpp_connect_config::userName();
+ string passwordStr = xmpp_connect_config::password();
+ string userJID = xmpp_connect_config::userJID();
+
+ // No user-name in config. Fall back on default registration (CCF)
+ if (userName.size() == 0)
+ {
+ constructTestUserAuth(TEST_SESSION_GUID, TEST_APP_GUID, userName, passwordStr);
+ userJID = userName + "@" + xmpp_connect_config::xmppDomain();
+ }
+
+ SecureBuffer password;
+ password.write(passwordStr);
+ auto scramConfig = SaslScramSha1::Params::create(userName, password);
+ auto plainConfig = SaslPlain::Params::create(userName, password);
+
+#ifdef ENABLE_LIBSTROPHE
+ XmppConfig config(JabberID(xmpp_connect_config::userJID("NO_PROXY")),
+ xmpp_connect_config::xmppDomain("NO_PROXY"));
+#else
+ XmppConfig config(JabberID(xmpp_connect_config::userJID()),
+ xmpp_connect_config::xmppDomain());
+#endif
+
+ config.requireTLSNegotiation();
+ config.setSaslConfig("SCRAM-SHA-1", scramConfig);
+ config.setSaslConfig("PLAIN", plainConfig);
+
+#ifndef DISABLE_SUPPORT_XEP0077
+ config.requestInBandRegistration();
+ auto registrationParams = InBandRegistration::Params::create();
+ registrationParams->setRegistrationParam("username", userName);
+ registrationParams->setRegistrationParam("password",
+ string((const char *)password.get(), password.size()));
+ config.setExtensionConfig(InBandRegistration::extensionName(), registrationParams);
+#endif
+
+ client = XmppClient::create();
+ client->initiateXMPP(config, xmlConnection, streamPromise);
+
+ shared_ptr<IXmppStream> xmppStream;
+ try
+ {
+ xmppStream = streamFuture.get();
+ if (xmppStream)
+ {
+ auto status = xmppStream->whenNegotiated().wait_for(chrono::seconds(10));
+ if (status == future_status::ready)
+ {
+ try
+ {
+ xmppStream->whenNegotiated().get();
+ stream = xmppStream;
+ }
+ catch (...)
+ {}
+ }
+ }
+ }
+ catch (...)
+ {}
+
+ return;
+}
+
diff --git a/test/xmpp_connect_establish.h b/test/xmpp_connect_establish.h
new file mode 100644
index 0000000..e238dcc
--- /dev/null
+++ b/test/xmpp_connect_establish.h
@@ -0,0 +1,41 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+//
+///////////////////////////////////////////////////////////////////////////////
+
+/// @file xmpp_connect_establish.h
+
+// XMPP Server Connection Helper (for functional tests requiring server connections but
+// that are not explicitly testing connection behavior).
+
+#include <memory>
+
+namespace Iotivity
+{
+ namespace Xmpp
+ {
+ class IXmppStream;
+ class IXmppClient;
+ }
+}
+
+void xmpp_test_default_connect_client(std::shared_ptr<Iotivity::Xmpp::IXmppStream> &stream,
+ std::shared_ptr<Iotivity::Xmpp::IXmppClient> &client);