All checks were successful
PR Check / on-push-commit-check (push) Successful in 14m38s
106 lines
3.8 KiB
C++
106 lines
3.8 KiB
C++
#include <spdlog/common.h>
|
||
#include <spdlog/spdlog.h>
|
||
|
||
#include <boost/asio/co_spawn.hpp>
|
||
#include <boost/asio/detached.hpp>
|
||
#include <boost/program_options.hpp>
|
||
#include <larra/client/client.hpp>
|
||
#include <larra/presence.hpp>
|
||
#include <larra/printer_stream.hpp>
|
||
#include <print>
|
||
|
||
// clang-format off
|
||
constexpr auto ToString(spdlog::level::level_enum e) {
|
||
switch (e) {
|
||
case spdlog::level::trace: return "TRACE";
|
||
case spdlog::level::debug: return "DEBUG";
|
||
case spdlog::level::info: return "INFO";
|
||
case spdlog::level::warn: return "WARNING";
|
||
case spdlog::level::err: return "ERROR";
|
||
case spdlog::level::critical: return "CRITICAL";
|
||
case spdlog::level::off: return "OFF";
|
||
default:
|
||
return "INVALID";
|
||
}
|
||
}
|
||
// clang-format on
|
||
|
||
namespace iq = larra::xmpp::iq;
|
||
|
||
auto Coroutine() -> boost::asio::awaitable<void> {
|
||
SPDLOG_INFO("Connecting client...");
|
||
|
||
try {
|
||
auto client = co_await larra::xmpp::client::CreateClient<larra::xmpp::PrintStream<boost::asio::ip::tcp::socket>>(
|
||
larra::xmpp::PlainUserAccount{.jid = {.username = "test1", .server = "localhost"}, .password = "test1"},
|
||
{.useTls = larra::xmpp::client::Options::kNever});
|
||
|
||
// rfc6120 7.1
|
||
// After a client authenticates with a server,
|
||
// it MUST bind a specific resource to the stream so that the server can properly address the client.
|
||
co_await std::visit(
|
||
[](auto& client) -> boost::asio::awaitable<void> {
|
||
co_await client.CreateResourceBind();
|
||
},
|
||
client);
|
||
|
||
co_await std::visit(
|
||
[](auto& client) -> boost::asio::awaitable<void> {
|
||
co_await client.UpdateListOfContacts();
|
||
},
|
||
client);
|
||
|
||
// rfc6120 2.2
|
||
// Upon authenticating with a server and binding a resource (thus becoming a connected resource as defined in [XMPP‑CORE]),
|
||
// a client SHOULD request the roster before sending initial presence
|
||
co_await std::visit(
|
||
[](auto& client) -> boost::asio::awaitable<void> {
|
||
SPDLOG_INFO("Send presence: Available");
|
||
co_await client.Send(larra::xmpp::presence::c2s::Available{});
|
||
},
|
||
client);
|
||
|
||
} catch(const std::exception& err) {
|
||
SPDLOG_ERROR("{}", err.what());
|
||
co_return;
|
||
}
|
||
SPDLOG_INFO("Done connecting client!");
|
||
}
|
||
|
||
namespace po = boost::program_options;
|
||
|
||
auto main(int argc, char** argv) -> int {
|
||
// Define options
|
||
po::options_description desc("Allowed options");
|
||
desc.add_options()("help,h", "Print help message")("log_level,l",
|
||
po::value<int>()->default_value(SPDLOG_LEVEL_INFO),
|
||
"Set log level: 0=TRACE, 1=DEBUG, 2=INFO, 3=WARN, 4=ERROR, 5=CRITICAL, 6=OFF");
|
||
|
||
// Parse command-line arguments
|
||
po::variables_map vm;
|
||
try {
|
||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||
po::notify(vm);
|
||
|
||
if(vm["log_level"].as<int>() < spdlog::level::level_enum::trace || vm["log_level"].as<int>() > spdlog::level::level_enum::off) {
|
||
throw std::invalid_argument{
|
||
std::format("Invalid argument value for '--log_level' option. Check option description for more details")};
|
||
}
|
||
if(vm["log_level"].as<int>() < SPDLOG_ACTIVE_LEVEL) {
|
||
SPDLOG_WARN("Specified log_level '{}' is lower than max available one '{}'. Log level will be changed according to the maximum one",
|
||
vm["log_level"].as<int>(),
|
||
SPDLOG_ACTIVE_LEVEL);
|
||
}
|
||
} catch(const std::exception& e) {
|
||
SPDLOG_CRITICAL("Cmd parse error: {}", e.what());
|
||
return 1;
|
||
}
|
||
|
||
// Cmd options handling
|
||
spdlog::set_level(static_cast<spdlog::level::level_enum>(vm["log_level"].as<int>()));
|
||
std::println("\nEnvironment setup:\n\tCurrently set log level: {}\n", ToString(spdlog::get_level()));
|
||
|
||
boost::asio::io_context io_context;
|
||
boost::asio::co_spawn(io_context, Coroutine(), boost::asio::detached);
|
||
io_context.run();
|
||
}
|