Browse Source

Connect to an XMPP server

isand
Bohdan Horbeshko 5 months ago
parent
commit
6fa60bc63a
8 changed files with 156 additions and 1 deletions
  1. +2
    -0
      .gitignore
  2. +11
    -1
      Makefile
  3. +4
    -0
      README.md
  4. +2
    -0
      architecture.pu
  5. +2
    -0
      config.yaml.sample
  6. +90
    -0
      src/SignalManager.cpp
  7. +18
    -0
      src/SignalManager.h
  8. +27
    -0
      src/main.cpp

+ 2
- 0
.gitignore View File

@ -1 +1,3 @@
architecture.png
teleologicall
config.yaml

+ 11
- 1
Makefile View File

@ -1,5 +1,15 @@
.PHONY: all src diagram debdeps clean clean_diagram
all: src
src:
$(CXX) $(CFLAGS) $(LDFLAGS) -std=c++17 -fPIC src/*.cpp -o teleologicall \
`pkg-config --cflags --libs qxmpp` \
`pkg-config --cflags --libs Qt5Core` \
`pkg-config --cflags --libs Qt5Network` \
`pkg-config --cflags --libs yaml-cpp`
diagram:
plantuml architecture.pu
debdeps:
sudo apt install libqxmpp-dev libyaml-cpp-dev
clean: clean_diagram
clean_diagram:
rm architecture.png
rm architecture.png teleologicall

+ 4
- 0
README.md View File

@ -0,0 +1,4 @@
# Installation
* Install the dependencies (`make debdeps` on Debian-based systems, manage manually elsewhere).
* Build and install [TDlib](https://tdlib.github.io/td/build.html?language=C%2B%2B), [tgvoip](https://github.com/grishka/libtgvoip), and [tgcalls](https://github.com/TelegramMessenger/tgcalls). If you prefer to use your distribution packages, make sure that you use the same compiler of the same version that was used to build the distribution packages, when building other dependencies and this project itself.
* Run `make`.

+ 2
- 0
architecture.pu View File

@ -7,6 +7,7 @@
[tgcalls]
[tgvoip]
[teleologicall]
[yaml-cpp]
[QXmpp] ..> [GStreamer]
[QXmpp] ..> [Qt]
@ -14,6 +15,7 @@
[teleologicall] ..> [TDlib] : signaling
[teleologicall] ..> [tgvoip] : voice (legacy)
[teleologicall] ..> [tgcalls] : voice
[teleologicall] ..> [yaml-cpp] : config
[tgcalls] ..> [tgvoip]
@enduml

+ 2
- 0
config.yaml.sample View File

@ -0,0 +1,2 @@
jid: johndoe@fbi.gov
password: bushhidthefacts

+ 90
- 0
src/SignalManager.cpp View File

@ -0,0 +1,90 @@
#include "SignalManager.h"
#include <QXmppClient.h>
#include <QXmppStanza.h>
#include <QXmppRosterManager.h>
#include <QObject>
#include <signal.h>
#include <sys/socket.h>
#include <unistd.h>
SignalManager::SignalManager(QXmppClient &client) : client{client}
{
this->setupExtensions();
this->setupQXmppSignals();
this->setupUnixSignals();
}
void SignalManager::setupExtensions()
{
this->client.removeExtension(this->client.findExtension<QXmppRosterManager>());
}
void SignalManager::setupQXmppSignals()
{
QObject::connect(&this->client, &QXmppClient::connected, []() {
qInfo("Logged in");
});
QObject::connect(&this->client, &QXmppClient::disconnected, []() {
qInfo("Logged off");
});
QObject::connect(&this->client, &QXmppClient::error, [this](QXmppClient::Error e) {
switch (e) {
case QXmppClient::SocketError:
qCritical("%s", this->client.socketErrorString().toUtf8().data());
break;
case QXmppClient::XmppStreamError:
{
auto cond = this->client.xmppStreamError();
auto fakeError = QXmppStanza::Error(QXmppStanza::Error::Type::Cancel, cond, nullptr);
qCritical("%s", fakeError.text().toUtf8().data());
}
break;
case QXmppClient::KeepAliveError:
qCritical("Keep alive error");
break;
case QXmppClient::NoError:
break;
}
});
}
void SignalManager::setupUnixSignals()
{
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, SignalManager::unixSignalFd)) {
qFatal("Socketpair failure");
}
this->notifier = new QSocketNotifier(SignalManager::unixSignalFd[1], QSocketNotifier::Read);
QObject::connect(this->notifier, &QSocketNotifier::activated, [this]() {
this->notifier->setEnabled(false);
char tmp;
::read(SignalManager::unixSignalFd[1], &tmp, sizeof(tmp));
this->exit();
this->notifier->setEnabled(true);
});
signal(SIGINT, SignalManager::unixSignalHandler);
signal(SIGTERM, SignalManager::unixSignalHandler);
}
void SignalManager::unixSignalHandler(int num)
{
char a = 1;
::write(SignalManager::unixSignalFd[0], &a, sizeof(a));
}
void SignalManager::exit()
{
qInfo("Manual exit requested");
this->client.disconnect();
std::exit(0);
}

+ 18
- 0
src/SignalManager.h View File

@ -0,0 +1,18 @@
#include <QXmppClient.h>
#include <QSocketNotifier>
class SignalManager {
public:
SignalManager(QXmppClient&);
static void unixSignalHandler(int);
private:
QXmppClient &client;
inline static int unixSignalFd[2];
QSocketNotifier *notifier;
void setupExtensions();
void setupQXmppSignals();
void setupUnixSignals();
void exit();
};

+ 27
- 0
src/main.cpp View File

@ -0,0 +1,27 @@
#include "SignalManager.h"
#include <QXmppClient.h>
#include <QString>
#include <QCoreApplication>
#include <Qt>
#include <yaml-cpp/yaml.h>
#include <termios.h>
#include <unistd.h>
int main(int argc, char** argv)
{
QCoreApplication app(argc, argv);
QXmppClient client;
auto sm = SignalManager(client);
auto config = YAML::LoadFile("config.yaml");
auto jid = QString(config["jid"].as<std::string>().c_str());
auto password = QString(config["password"].as<std::string>().c_str());
client.connectToServer(jid, password);
app.exec();
}

Loading…
Cancel
Save