compare the backend's version with the plugin's version
This commit is contained in:
		| @@ -7,6 +7,8 @@ | ||||
| # Brief: | ||||
| #   Creates the plug-in which is used by Euroscope | ||||
|  | ||||
| ADD_DEFINITIONS(-DCURL_STATICLIB) | ||||
|  | ||||
| # define the Google Protobuf-files | ||||
| SET(PROTO_FILES | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/com/protobuf/Aircraft.proto | ||||
| @@ -86,8 +88,8 @@ ADD_LIBRARY( | ||||
|  | ||||
| # define the dependencies | ||||
| TARGET_INCLUDE_DIRECTORIES(ArrivalMANager INTERFACE EuroScope) | ||||
| TARGET_LINK_LIBRARIES(ArrivalMANager EuroScope GSL Shlwapi) | ||||
| TARGET_LINK_LIBRARIES(ArrivalMANager cppzmq protobuf) | ||||
| TARGET_LINK_LIBRARIES(ArrivalMANager EuroScope libcurl GSL Shlwapi) | ||||
| TARGET_LINK_LIBRARIES(ArrivalMANager cppzmq protobuf jsoncpp) | ||||
|  | ||||
| # configure the debugger and update the linker flags | ||||
| IF(MSVC) | ||||
|   | ||||
| @@ -17,6 +17,9 @@ | ||||
|  | ||||
| #include <aman/com/BackendReceiver.h> | ||||
| #include <aman/com/BackendNotification.h> | ||||
| #include <curl/curl.h> | ||||
| #include <json/json.h> | ||||
|  | ||||
| #include <aman/config/CommunicationFileFormat.h> | ||||
| #include <aman/config/IdentifierFileFormat.h> | ||||
| #include <aman/helper/String.h> | ||||
| @@ -28,6 +31,16 @@ EXTERN_C IMAGE_DOS_HEADER __ImageBase; | ||||
|  | ||||
| using namespace aman; | ||||
|  | ||||
| static std::string __receivedAmanData; | ||||
|  | ||||
| static std::size_t receiveCurl(void* ptr, std::size_t size, std::size_t nmemb, void* stream) { | ||||
|     (void)stream; | ||||
|  | ||||
|     std::string serverResult = static_cast<char*>(ptr); | ||||
|     __receivedAmanData += serverResult; | ||||
|     return size * nmemb; | ||||
| } | ||||
|  | ||||
| PlugIn::PlugIn() : | ||||
|         EuroScopePlugIn::CPlugIn(EuroScopePlugIn::COMPATIBILITY_CODE, | ||||
|                                  PLUGIN_NAME, | ||||
| @@ -37,7 +50,10 @@ PlugIn::PlugIn() : | ||||
|         m_configuration(), | ||||
|         m_screen(), | ||||
|         m_updateQueueLock(), | ||||
|         m_updateQueue() { | ||||
|         m_updateQueue(), | ||||
|         m_compatible(false), | ||||
|         m_airportsLock(), | ||||
|         m_airports() { | ||||
|     GOOGLE_PROTOBUF_VERIFY_VERSION; | ||||
|  | ||||
|     this->DisplayUserMessage(PLUGIN_NAME, "INFO", (std::string("Loaded ") + PLUGIN_NAME + " " + PLUGIN_VERSION).c_str(), true, true, false, false, false); | ||||
| @@ -75,6 +91,7 @@ PlugIn::PlugIn() : | ||||
|         BackendNotification::instance().deinitialize(); | ||||
|         return; | ||||
|     } | ||||
|     this->validateBackendData(); | ||||
| } | ||||
|  | ||||
| PlugIn::~PlugIn() noexcept { | ||||
| @@ -84,6 +101,78 @@ PlugIn::~PlugIn() noexcept { | ||||
|     google::protobuf::ShutdownProtobufLibrary(); | ||||
| } | ||||
|  | ||||
| void PlugIn::validateBackendData() { | ||||
|     std::string url = "http://" + this->m_configuration.address + ":5000/aman/airports"; | ||||
|     CURL* curl = curl_easy_init(); | ||||
|     CURLcode result; | ||||
|  | ||||
|     curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | ||||
|     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); | ||||
|     curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); | ||||
|     curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, static_cast<long>(CURL_HTTP_VERSION_1_1)); | ||||
|     curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); | ||||
|     curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0L); | ||||
|     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveCurl); | ||||
|     curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L); | ||||
|  | ||||
|     struct curl_slist* headers = nullptr; | ||||
|     headers = curl_slist_append(headers, "Accept: */*"); | ||||
|     headers = curl_slist_append(headers, "Content-Type: application/json"); | ||||
|     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); | ||||
|  | ||||
|     __receivedAmanData.clear(); | ||||
|  | ||||
|     result = curl_easy_perform(curl); | ||||
|     std::lock_guard guard(this->m_airportsLock); | ||||
|     this->m_airports.clear(); | ||||
|     this->m_compatible = false; | ||||
|  | ||||
|     if (CURLE_OK != result) { | ||||
|         MessageBoxA(nullptr, "Unable to receive backend information", "AMAN-Error", MB_OK); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /* validate the json data */ | ||||
|     Json::Value root; | ||||
|     Json::CharReaderBuilder builder; | ||||
|     std::unique_ptr<Json::CharReader> reader(builder.newCharReader()); | ||||
|     if (false == reader->parse(__receivedAmanData.c_str(), __receivedAmanData.c_str() + __receivedAmanData.length(), &root, nullptr)) { | ||||
|         MessageBoxA(nullptr, "Received invalid backend data", "AMAN-Error", MB_OK); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     std::vector<std::string> airports; | ||||
|     std::string version; | ||||
|     for (auto it = root.begin(); root.end() != it; ++it) { | ||||
|         if ("version" == it.key().asString()) { | ||||
|             version = it->asString(); | ||||
|         } | ||||
|         else if ("airports" == it.key().asString() && true == it->isArray()) { | ||||
|             auto airportArray = *it; | ||||
|  | ||||
|             airports.reserve(airportArray.size()); | ||||
|             for (auto i = 0; i < airportArray.size(); ++i) | ||||
|                 airports.push_back(airportArray[i].asString()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* invalid version or airports info */ | ||||
|     auto entries = String::splitString(version, "."); | ||||
|     if (3 != entries.size() || 0 == airports.size()) { | ||||
|         MessageBoxA(nullptr, "Unable to receive backend information", "AMAN-Error", MB_OK); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     /* incompatible communication version */ | ||||
|     if (PLUGIN_MAJOR_VERSION != std::atoi(entries[0].c_str()) || PLUGIN_MINOR_VERSION != std::atoi(entries[1].c_str())) { | ||||
|         MessageBoxA(nullptr, "Plugin version is outdated. An update is required", "AMAN-Error", MB_OK); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     this->m_airports = airports; | ||||
|     this->m_compatible = true; | ||||
| } | ||||
|  | ||||
| EuroScopePlugIn::CRadarScreen* PlugIn::OnRadarScreenCreated(const char* displayName, bool needsRadarContent, bool geoReferenced, | ||||
|     bool canBeSaved, bool canBeCreated) { | ||||
|     std::ignore = needsRadarContent; | ||||
|   | ||||
| @@ -41,6 +41,7 @@ namespace aman { | ||||
|         enum class TagItemElement { | ||||
|         }; | ||||
|  | ||||
|         void validateBackendData(); | ||||
|         aman::Aircraft* generateAircraftMessage(const EuroScopePlugIn::CRadarTarget& target); | ||||
|         void generateAircraftReportMessage(const EuroScopePlugIn::CRadarTarget& radarTarget, aman::AircraftReport* report); | ||||
|  | ||||
| @@ -48,6 +49,9 @@ namespace aman { | ||||
|         std::shared_ptr<RadarScreen> m_screen; | ||||
|         std::mutex                   m_updateQueueLock; | ||||
|         std::list<std::string>       m_updateQueue; | ||||
|         bool                         m_compatible; | ||||
|         std::mutex                   m_airportsLock; | ||||
|         std::vector<std::string>     m_airports; | ||||
|  | ||||
|     public: | ||||
|         /** | ||||
|   | ||||
		Reference in New Issue
	
	Block a user