Browse Source

use only one backend and adapt to the new communication structure
avoid empty messages

Sven Czarnian 3 years ago
parent
commit
689c2326c2

+ 14 - 12
include/aman/com/BackendNotification.h

@@ -1,6 +1,6 @@
 /*
- * @brief Defines the backend notification module to communicate with the backend
- * @file aman/com/BackendNotification.h
+ * @brief Defines the backend module to communicate with the backend
+ * @file aman/com/Backend.h
  * @author Sven Czarnian <devel@svcz.de>
  * @copyright Copyright 2021 Sven Czarnian
  * @license This project is published under the GNU General Public License v3 (GPLv3)
@@ -18,14 +18,14 @@
 
 namespace aman {
     /**
-     * @brief Defines the bakcend notification class which sends aircraft information to the backend
+     * @brief Defines the bakcend class which sends and receives aircraft information to and from the backend
      * @ingroup com
      */
-    class BackendNotification {
+    class Backend {
     private:
         std::unique_ptr<zmq::socket_t> m_socket;
 
-        BackendNotification() noexcept;
+        Backend() noexcept;
 
         template <typename T>
         bool setSocketKey(const std::string& key, T entry) {
@@ -38,11 +38,13 @@ namespace aman {
             }
         }
 
+        std::shared_ptr<aman::AircraftSequence> receiveSequence();
+
     public:
-        BackendNotification(const BackendNotification&) = delete;
-        BackendNotification(BackendNotification&&) = delete;
-        BackendNotification& operator=(const BackendNotification&) = delete;
-        BackendNotification& operator=(BackendNotification&&) = delete;
+        Backend(const Backend&) = delete;
+        Backend(Backend&&) = delete;
+        Backend& operator=(const Backend&) = delete;
+        Backend& operator=(Backend&&) = delete;
 
         /**
          * @brief Initializes the aircraft reporter
@@ -62,13 +64,13 @@ namespace aman {
         /**
          * @brief Sends a new message to the backend
          * @param[in] report The new aircraft update
-         * @return True if the report is sent, else false
+         * @return Receives the current sequence of the airport
          */
-        bool send(aman::AircraftUpdate& report);
+        std::shared_ptr<aman::AircraftSequence> update(aman::AircraftUpdate& report);
         /**
          * @brief Returns the reporter instance
          * @return The system-wide instance
          */
-        static BackendNotification& instance() noexcept;
+        static Backend& instance() noexcept;
     };
 }

+ 0 - 81
include/aman/com/BackendReceiver.h

@@ -1,81 +0,0 @@
-/*
- * @brief Defines the aircraft scheduling notifier module to receive plans from the backend
- * @file aman/com/BackendReceiver.h
- * @author Sven Czarnian <devel@svcz.de>
- * @copyright Copyright 2021 Sven Czarnian
- * @license This project is published under the GNU General Public License v3 (GPLv3)
- */
-
-#pragma once
-
-#include <thread>
-#include <memory>
-#include <zmq.hpp>
-
-#include <aman/types/Communication.h>
-
-#pragma warning(push, 0)
-#include "protobuf/Communication.pb.h"
-#pragma warning(pop)
-
-namespace aman {
-    /**
-     * @brief Defines the aircraft scheduling notification class to receive scheduling sequences
-     * @ingroup com
-     */
-    class BackendReceiver {
-    private:
-        std::unique_ptr<zmq::socket_t>                     m_socket;
-        std::thread                                        m_receiverThread;
-        std::atomic_bool                                   m_stopReceiver;
-        std::list<std::shared_ptr<aman::AircraftSequence>> m_sequences;
-        std::mutex                                         m_sequencesLock;
-
-        BackendReceiver() noexcept;
-
-        template <typename T>
-        bool setSocketKey(const std::string& key, T entry) {
-            try {
-                this->m_socket->set(entry, key);
-                return true;
-            }
-            catch (std::exception&) {
-                return false;
-            }
-        }
-        void receiveSequence();
-        void run();
-
-    public:
-        BackendReceiver(const BackendReceiver&) = delete;
-        BackendReceiver(BackendReceiver&&) = delete;
-        BackendReceiver& operator=(const BackendReceiver&) = delete;
-        BackendReceiver& operator=(BackendReceiver&&) = delete;
-
-        /**
-         * @brief Initializes the aircraft scheduler
-         * @param[in] configuration The current AMAM communication configuration
-         * @return True if the initialization is done, else false
-         */
-        bool initialize(const Communication& configuration);
-        /**
-         * @brief Terminates the scheduler connection
-         */
-        bool deinitialize();
-        /**
-         * @brief Checks if the scheduler is initialized
-         * @return True if it is initialized, else false
-         */
-        bool initialized() const noexcept;
-        /**
-         * @brief Returns the current sequence of the receiver queue
-         * @return The sequence queue
-         */
-        std::shared_ptr<aman::AircraftSequence> receive();
-        /**
-         * @brief Returns the scheduling instance
-         * @return The system-wide instance
-         */
-        static BackendReceiver& instance() noexcept;
-    };
-}

+ 2 - 4
src/CMakeLists.txt

@@ -34,8 +34,7 @@ SET(SOURCE_FILES
 )
 
 SET(SOURCE_COM_FILES
-    com/BackendReceiver.cpp
-    com/BackendNotification.cpp
+    com/Backend.cpp
     com/ZmqContext.cpp
     com/ZmqContext.h
 )
@@ -53,8 +52,7 @@ SET(SOURCE_FILES_RES
 )
 
 SET(INCLUDE_COM_FILES
-    ${CMAKE_SOURCE_DIR}/include/aman/com/BackendReceiver.h
-    ${CMAKE_SOURCE_DIR}/include/aman/com/BackendNotification.h
+    ${CMAKE_SOURCE_DIR}/include/aman/com/Backend.h
 )
 
 SET(INCLUDE_CONFIG_FILES

+ 10 - 15
src/PlugIn.cpp

@@ -15,11 +15,10 @@
 #include <Shlwapi.h>
 #include <Windows.h>
 
-#include <aman/com/BackendReceiver.h>
-#include <aman/com/BackendNotification.h>
 #include <curl/curl.h>
 #include <json/json.h>
 
+#include <aman/com/Backend.h>
 #include <aman/config/CommunicationFileFormat.h>
 #include <aman/config/IdentifierFileFormat.h>
 #include <aman/helper/String.h>
@@ -81,22 +80,14 @@ PlugIn::PlugIn() :
 
     ZmqContext::instance().initialize();
 
-    if (false == BackendNotification::instance().initialize(this->m_configuration)) {
+    if (false == Backend::instance().initialize(this->m_configuration))
         this->DisplayUserMessage(PLUGIN_NAME, "ERROR", "Unable to initialize the reporter-connection to the backend", true, true, true, true, true);
-        return;
-    }
 
-    if (false == BackendReceiver::instance().initialize(this->m_configuration)) {
-        this->DisplayUserMessage(PLUGIN_NAME, "ERROR", "Unable to initialize the scheduling-connection to the backend", true, true, true, true, true);
-        BackendNotification::instance().deinitialize();
-        return;
-    }
     this->validateBackendData();
 }
 
 PlugIn::~PlugIn() noexcept {
-    BackendReceiver::instance().deinitialize();
-    BackendNotification::instance().deinitialize();
+    Backend::instance().deinitialize();
     ZmqContext::instance().deinitialize();
     google::protobuf::ShutdownProtobufLibrary();
 }
@@ -356,7 +347,9 @@ void PlugIn::generateAircraftReportMessage(const EuroScopePlugIn::CRadarTarget&
 
 void PlugIn::OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget radarTarget) {
     /* do nothing if the reporter is not initialized and ignore invalid targets */
-    if (false == BackendNotification::instance().initialized() || false == radarTarget.IsValid())
+    if (false == this->m_compatible || false == Backend::instance().initialized() || false == radarTarget.IsValid())
+        return;
+    if (false == radarTarget.GetCorrelatedFlightPlan().GetTrackingControllerIsMe())
         return;
 
     std::lock_guard guard(this->m_updateQueueLock);
@@ -364,17 +357,19 @@ void PlugIn::OnRadarTargetPositionUpdate(EuroScopePlugIn::CRadarTarget radarTarg
 }
 
 void PlugIn::OnTimer(int counter) {
-    if (false == BackendNotification::instance().initialized() || 0 != (counter % 10))
+    if (false == this->m_compatible || false == Backend::instance().initialized() || 0 != (counter % 10))
         return;
 
     this->m_updateQueueLock.lock();
     aman::AircraftUpdate update;
+    bool inserted = false;
 
     for (auto target = this->RadarTargetSelectFirst(); true == target.IsValid(); target = this->RadarTargetSelectNext(target)) {
         auto it = std::find(this->m_updateQueue.cbegin(), this->m_updateQueue.cend(), target.GetCallsign());
         if (this->m_updateQueue.cend() != it) {
             auto report = update.add_reports();
             this->generateAircraftReportMessage(target, report);
+            inserted = true;
         }
     }
 
@@ -382,6 +377,6 @@ void PlugIn::OnTimer(int counter) {
     this->m_updateQueueLock.unlock();
 
     /* send the report */
-    if (false == BackendNotification::instance().send(update))
+    if (true == inserted && nullptr != Backend::instance().update(update))
         this->DisplayUserMessage(PLUGIN_NAME, "ERROR", "Unable to send a new aircraft report update", true, true, true, true, true);
 }

+ 37 - 17
src/com/BackendNotification.cpp

@@ -2,31 +2,30 @@
  * Author:
  *   Sven Czarnian <devel@svcz.de>
  * Brief:
- *   Implements the backend notification
+ *   Implements the backend communication
  * Copyright:
  *   2021 Sven Czarnian
  * License:
  *   GNU General Public License v3 (GPLv3)
  */
 
-#include <aman/com/BackendNotification.h>
+#include <aman/com/Backend.h>
 #include <aman/helper/String.h>
 
 #include "ZmqContext.h"
 
 using namespace aman;
 
-BackendNotification::BackendNotification() noexcept :
+Backend::Backend() noexcept :
         m_socket() { }
 
-bool BackendNotification::initialize(const Communication& configuration) {
+bool Backend::initialize(const Communication& configuration) {
     if (nullptr != this->m_socket)
         return true;
     if (false == configuration.valid)
         return false;
 
-    this->m_socket = std::make_unique<zmq::socket_t>(ZmqContext::instance().context(), zmq::socket_type::pub);
-    this->m_socket->set(zmq::sockopt::immediate, true);
+    this->m_socket = std::make_unique<zmq::socket_t>(ZmqContext::instance().context(), zmq::socket_type::req);
 
     /* configure the encryption */
     if (false == this->setSocketKey(configuration.serverPublicIdentifier, zmq::sockopt::curve_serverkey))
@@ -48,7 +47,7 @@ bool BackendNotification::initialize(const Communication& configuration) {
     return true;
 }
 
-bool BackendNotification::deinitialize() {
+bool Backend::deinitialize() {
     if (nullptr == this->m_socket)
         return true;
 
@@ -58,13 +57,33 @@ bool BackendNotification::deinitialize() {
     return true;
 }
 
-bool BackendNotification::initialized() const noexcept {
+bool Backend::initialized() const noexcept {
     return nullptr != this->m_socket;
 }
 
-bool BackendNotification::send(aman::AircraftUpdate& report) {
-    bool retval = false;
+std::shared_ptr<aman::AircraftSequence> Backend::receiveSequence() {
+    zmq::message_t message;
 
+    if (nullptr == this->m_socket)
+        return nullptr;
+
+    try {
+        //auto result = this->m_socket->recv(message, zmq::recv_flags::dontwait);
+        auto result = this->m_socket->recv(message);
+        if (false == result.has_value() || 0 == result.value())
+            return nullptr;
+    }
+    catch (zmq::error_t&) {
+        return nullptr;
+    }
+
+    std::unique_ptr<aman::AircraftSequence> retval = std::make_unique<aman::AircraftSequence>();
+    retval->ParseFromString(reinterpret_cast<const char*>(message.data()));
+
+    return std::move(retval);
+}
+
+std::shared_ptr<aman::AircraftSequence> Backend::update(aman::AircraftUpdate& report) {
     if (nullptr != this->m_socket) {
         /* serialize the report */
         std::string serialized = report.SerializeAsString();
@@ -72,19 +91,20 @@ bool BackendNotification::send(aman::AircraftUpdate& report) {
         std::memcpy(message.data(), serialized.c_str(), serialized.size());
 
         try {
-            auto size = message.size();
-            auto result = this->m_socket->send(message, zmq::send_flags::none);
-            retval = result.value() == size;
+            const auto size = message.size();
+            const auto result = this->m_socket->send(message, zmq::send_flags::none);
+            if (result.value() == size)
+                return this->receiveSequence();
         }
         catch (zmq::error_t&) {
-            return false;
+            return nullptr;
         }
     }
 
-    return retval;
+    return nullptr;
 }
 
-BackendNotification& BackendNotification::instance() noexcept {
-    static BackendNotification __instance;
+Backend& Backend::instance() noexcept {
+    static Backend __instance;
     return __instance;
 }

+ 0 - 121
src/com/BackendReceiver.cpp

@@ -1,121 +0,0 @@
-/*
- * Author:
- *   Sven Czarnian <devel@svcz.de>
- * Brief:
- *   Implements the backend receiver
- * Copyright:
- *   2021 Sven Czarnian
- * License:
- *   GNU General Public License v3 (GPLv3)
- */
-
-#include <aman/com/BackendReceiver.h>
-
-#include "ZmqContext.h"
-
-using namespace aman;
-using namespace std::chrono;
-
-BackendReceiver::BackendReceiver() noexcept :
-        m_socket(),
-        m_receiverThread(),
-        m_stopReceiver(false),
-        m_sequences(),
-        m_sequencesLock() { }
-
-bool BackendReceiver::initialize(const Communication& configuration) {
-    if (nullptr != this->m_socket)
-        return true;
-    if (false == configuration.valid)
-        return false;
-
-    this->m_socket = std::make_unique<zmq::socket_t>(ZmqContext::instance().context(), zmq::socket_type::sub);
-
-    /* configure the encryption */
-    if (false == this->setSocketKey(configuration.serverPublicIdentifier, zmq::sockopt::curve_serverkey))
-        return false;
-    if (false == this->setSocketKey(configuration.clientPublicIdentifier, zmq::sockopt::curve_publickey))
-        return false;
-    if (false == this->setSocketKey(configuration.clientPrivateIdentifier, zmq::sockopt::curve_secretkey))
-        return false;
-
-    /* connect to the server */
-    try {
-        this->m_socket->connect("tcp://" + configuration.address + ":" + std::to_string(configuration.portNotification));
-    }
-    catch (zmq::error_t&) {
-        this->m_socket = std::unique_ptr<zmq::socket_t>();
-        return false;
-    }
-
-    this->m_stopReceiver = false;
-    this->m_receiverThread = std::thread(&BackendReceiver::run, this);
-
-    return true;
-}
-
-bool BackendReceiver::deinitialize() {
-    if (nullptr == this->m_socket)
-        return true;
-
-    this->m_stopReceiver = true;
-    this->m_receiverThread.join();
-    this->m_socket->close();
-    this->m_socket = std::make_unique<zmq::socket_t>();
-
-    return true;
-}
-
-bool BackendReceiver::initialized() const noexcept {
-    return nullptr != this->m_socket;
-}
-
-void BackendReceiver::receiveSequence() {
-    zmq::message_t message;
-
-    if (nullptr == this->m_socket)
-        return;
-
-    try {
-        auto result = this->m_socket->recv(message, zmq::recv_flags::dontwait);
-        if (false == result.has_value() || 0 == result.value())
-            return;
-    }
-    catch (zmq::error_t&) {
-        return;
-    }
-
-    std::unique_ptr<aman::AircraftSequence> retval = std::make_unique<aman::AircraftSequence>();
-    retval->ParseFromString(reinterpret_cast<const char*>(message.data()));
-
-    std::lock_guard guard(this->m_sequencesLock);
-    this->m_sequences.push_back(std::move(retval));
-}
-
-void BackendReceiver::run() {
-    while (false == this->m_stopReceiver) {
-        auto message = this->receive();
-        if (nullptr == message) {
-            std::this_thread::sleep_for(500ms);
-            continue;
-        }
-
-        this->receiveSequence();
-    }
-}
-
-std::shared_ptr<aman::AircraftSequence> BackendReceiver::receive() {
-    std::lock_guard guard(this->m_sequencesLock);
-    if (0 != this->m_sequences.size()) {
-        auto retval = this->m_sequences.front();
-        this->m_sequences.pop_front();
-        return retval;
-    }
-
-    return nullptr;
-}
-
-BackendReceiver& BackendReceiver::instance() noexcept {
-    static BackendReceiver __instance;
-    return __instance;
-}