From 47073dedc3d82ac1e624927282d70becc0df0709 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Thu, 10 Jan 2019 12:35:14 -0200 Subject: [PATCH] Implementing D-Bus basic request object. --- src/include/lib3270++.h | 16 ++++++++++++++++ src/lib3270++/ipc/session.cc | 20 ++++++++++++++++++-- src/lib3270++/linux/request.cc | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- src/lib3270++/local/session.cc | 9 +++++++++ src/lib3270++/private.h | 32 +++++++++++++++++++++++++++----- src/lib3270++/testprogram/testprogram.cc | 9 +++++++-- 6 files changed, 135 insertions(+), 14 deletions(-) diff --git a/src/include/lib3270++.h b/src/include/lib3270++.h index dbcc695..14e8f27 100644 --- a/src/include/lib3270++.h +++ b/src/include/lib3270++.h @@ -212,6 +212,10 @@ return toString(); } + // Get properties. + virtual std::string getVersion() const = 0; + virtual std::string getRevision() const = 0; + virtual ProgramMessage getProgramMessage() const = 0; inline operator ProgramMessage() const { return getProgramMessage(); @@ -326,6 +330,18 @@ session->setCursorPosition(row,col); } + // Get properties + + /// @brief Get lib3270 version. + inline std::string getVersion() const { + return session->getVersion(); + } + + /// @brief Get lib3270 revision. + std::string getRevision() const { + return session->getRevision(); + } + // Set contents. /// @brief Set field at current posicion, jumps to next writable field. diff --git a/src/lib3270++/ipc/session.cc b/src/lib3270++/ipc/session.cc index 030be5d..6ae6b6e 100644 --- a/src/lib3270++/ipc/session.cc +++ b/src/lib3270++/ipc/session.cc @@ -120,8 +120,7 @@ } void IPC::Session::disconnect() { - Request request(*this,"disconnect"); - request.call(); + Request(*this,"disconnect").call(); } // Wait for session state. @@ -212,6 +211,23 @@ } + /// @brief Get lib3270 version. + std::string IPC::Session::getVersion() const { + + string rc; + + Request request{*this,false,"version"}; + request.call().pop(rc); + + return rc; + } + + /// @brief Get lib3270 revision. + std::string IPC::Session::getRevision() const { + throw std::system_error(ENOTSUP, std::system_category()); + return ""; + } + } diff --git a/src/lib3270++/linux/request.cc b/src/lib3270++/linux/request.cc index 22c30a1..e836fea 100644 --- a/src/lib3270++/linux/request.cc +++ b/src/lib3270++/linux/request.cc @@ -44,13 +44,13 @@ namespace TN3270 { - IPC::Request::Request(Session &session) { + IPC::Request::Request(const Session &session) { this->conn = session.conn; this->msg.in = nullptr; this->msg.out = nullptr; } - IPC::Request::Request(Session &session, const char *method) : Request(session) { + IPC::Request::Request(const Session &session, const char *method) : Request(session) { this->msg.out = dbus_message_new_method_call( session.name.c_str(), // Destination @@ -65,13 +65,23 @@ } - IPC::Request::Request(Session &session, const char *method, const char *property) : Request(session) { + IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) { +/* + dbus-send \ + --session \ + --dest=br.com.bb.pw3270.a\ + --print-reply \ + "/br/com/bb/tn3270/session" \ + "org.freedesktop.DBus.Properties.Get" \ + string:br.com.bb.tn3270.session \ + string:${1} +*/ this->msg.out = dbus_message_new_method_call( session.name.c_str(), // Destination session.path.c_str(), // Path "org.freedesktop.DBus.Properties", // Interface - method // Method + (isSet ? "Set" : "Get") ); if(!msg.out) { @@ -91,7 +101,7 @@ dbus_message_append_args( this->msg.out, DBUS_TYPE_STRING,&interface_name, - DBUS_TYPE_STRING,&method, + DBUS_TYPE_STRING,&property, DBUS_TYPE_INVALID ); @@ -123,6 +133,10 @@ throw std::runtime_error(message.c_str()); } + dbus_message_iter_init(msg.in, &msg.iter); + + debug(__FUNCTION__," got a valid response"); + return *this; } @@ -132,6 +146,45 @@ return *this; } + IPC::Request & IPC::Request::pop(std::string &value) { + + const char * str = ""; + + if(dbus_message_iter_get_arg_type(&msg.iter) == DBUS_TYPE_STRING) { + + dbus_message_iter_get_basic(&msg.iter, &str); + + } else if(dbus_message_iter_get_arg_type(&msg.iter) == DBUS_TYPE_VARIANT) { + + DBusMessageIter sub; + int current_type; + + dbus_message_iter_recurse(&msg.iter, &sub); + + while ((current_type = dbus_message_iter_get_arg_type(&sub)) != DBUS_TYPE_INVALID) { + + if (current_type == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&sub, &str); + break; + } + dbus_message_iter_next(&sub); + } + + } else { + + debug("Argument type is ", ((char) dbus_message_iter_get_arg_type(&msg.iter)) ); + throw std::runtime_error("Expected an string data type"); + + } + + value.assign(str); + + debug(__FUNCTION__,"= \"",str,"\""); + + return *this; + } + + } diff --git a/src/lib3270++/local/session.cc b/src/lib3270++/local/session.cc index 6ba8350..20edec5 100644 --- a/src/lib3270++/local/session.cc +++ b/src/lib3270++/local/session.cc @@ -298,6 +298,15 @@ } + // Get properties. + std::string Local::Session::getVersion() const { + return lib3270_get_version(); + } + + std::string Local::Session::getRevision() const { + return lib3270_get_revision(); + } + } diff --git a/src/lib3270++/private.h b/src/lib3270++/private.h index 7757d48..eb13e06 100644 --- a/src/lib3270++/private.h +++ b/src/lib3270++/private.h @@ -176,6 +176,10 @@ // Wait for session state. void waitForReady(time_t timeout = 5) throw() override; + // Get properties. + std::string getVersion() const override; + std::string getRevision() const override; + // Gets std::string toString(int baddr, size_t len, char lf) const override; std::string toString(int row, int col, size_t sz, char lf) const override; @@ -233,28 +237,42 @@ static DWORD pack(std::vector &args, uint8_t * outBuffer, size_t szBuffer); #else struct { - DBusMessage * in; - DBusMessage * out; + DBusMessage * in; + DBusMessage * out; + DBusMessageIter iter; + } msg; DBusConnection * conn; #endif // _WIN32 - Request(Session &session); + Request(const Session &session); public: /// @brief Create a method call. - Request(Session &session, const char *method); + Request(const Session &session, const char *method); /// @brief Create a get/set property call. - Request(Session &session, const char *method, const char *property); + /// + /// @param session Session object. + /// @param isSet true if this is a setProperty call. + /// @param property Property name. + // + Request(const Session &session, bool isSet, const char *property); ~Request(); Request & call(); + + // Push values + Request & push(const char *arg); + // Pop values + + Request & pop(std::string &value); + }; class TN3270_PRIVATE Session : public TN3270::Abstract::Session { @@ -288,6 +306,10 @@ // Wait for session state. void waitForReady(time_t timeout = 5) throw() override; + // Get properties. + std::string getVersion() const override; + std::string getRevision() const override; + // Gets std::string toString(int baddr, size_t len, char lf) const override; std::string toString(int row, int col, size_t sz, char lf) const override; diff --git a/src/lib3270++/testprogram/testprogram.cc b/src/lib3270++/testprogram/testprogram.cc index 4137d10..61da88f 100644 --- a/src/lib3270++/testprogram/testprogram.cc +++ b/src/lib3270++/testprogram/testprogram.cc @@ -45,9 +45,14 @@ int main(int argc, const char *argv[]) { - TN3270::Host host("pw3270:a"); + TN3270::Host host{"pw3270:a"}; - host.connect(getenv("LIB3270_DEFAULT_HOST")); + cout + << "Version: " << host.getVersion() +// << " Revision: " << host.getRevision() + << std::endl; + + // host.connect(getenv("LIB3270_DEFAULT_HOST")); /* cout << host << endl; -- libgit2 0.21.2