Commit 150e6b711f0b9ad9653771d4e57acef33a7f7966

Authored by Perry Werneck
1 parent 0cc65f1c
Exists in master and in 1 other branch develop

Refactoring IPC module.

client/Makefile.in
... ... @@ -35,7 +35,8 @@ MAIN_SOURCES= \
35 35 $(wildcard src/core/@OSNAME@/*.rc) \
36 36 $(wildcard src/session/*.cc) \
37 37 $(wildcard src/session/local/*.cc) \
38   - $(wildcard src/session/remote/*.cc)
  38 + $(wildcard src/session/remote/*.cc) \
  39 + $(wildcard src/session/remote/@OSNAME@/*.cc)
39 40  
40 41 TEST_SOURCES= \
41 42 $(wildcard src/testprogram/*.cc)
... ...
client/lib3270++.cbp
... ... @@ -51,7 +51,6 @@
51 51 <Unit filename="src/core/windows/request.cc" />
52 52 <Unit filename="src/core/windows/resources.rc" />
53 53 <Unit filename="src/core/windows/resources.rc.in" />
54   - <Unit filename="src/core/windows/session.cc" />
55 54 <Unit filename="src/include/ipc-client-internals.h" />
56 55 <Unit filename="src/session/get.cc" />
57 56 <Unit filename="src/session/local/actions.cc" />
... ... @@ -65,10 +64,14 @@
65 64 <Unit filename="src/session/remote/actions.cc" />
66 65 <Unit filename="src/session/remote/get.cc" />
67 66 <Unit filename="src/session/remote/init.cc" />
  67 + <Unit filename="src/session/remote/linux/request.cc" />
  68 + <Unit filename="src/session/remote/linux/session.cc" />
68 69 <Unit filename="src/session/remote/private.h" />
69 70 <Unit filename="src/session/remote/properties.cc" />
70 71 <Unit filename="src/session/remote/set.cc" />
71 72 <Unit filename="src/session/remote/tools.cc" />
  73 + <Unit filename="src/session/remote/windows/request.cc" />
  74 + <Unit filename="src/session/remote/windows/session.cc" />
72 75 <Unit filename="src/session/set.cc" />
73 76 <Unit filename="src/testprogram/testprogram.cc" />
74 77 <Extensions>
... ...
client/src/core/linux/request.cc
... ... @@ -44,60 +44,6 @@
44 44  
45 45 namespace TN3270 {
46 46  
47   - /*
48   - IPC::Request::Request(const Session &session) {
49   - this->conn = session.conn;
50   - this->msg.in = nullptr;
51   - this->msg.out = nullptr;
52   - }
53   -
54   - IPC::Request::Request(const Session &session, const char *method) : Request(session) {
55   -
56   - this->msg.out = dbus_message_new_method_call(
57   - session.name.c_str(), // Destination
58   - session.path.c_str(), // Path
59   - session.interface.c_str(), // Interface
60   - method // Method
61   - );
62   -
63   - if(!msg.out) {
64   - throw std::runtime_error("Can't create D-Bus Method Call");
65   - }
66   -
67   - }
68   -
69   - IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) {
70   -
71   - this->msg.out = dbus_message_new_method_call(
72   - session.name.c_str(), // Destination
73   - session.path.c_str(), // Path
74   - "org.freedesktop.DBus.Properties", // Interface
75   - (isSet ? "Set" : "Get")
76   - );
77   -
78   - if(!msg.out) {
79   - throw std::runtime_error("Can't create D-Bus Property Call");
80   - }
81   -
82   - //
83   - // https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
84   - // org.freedesktop.DBus.Properties.Get (in STRING interface_name,
85   - // in STRING property_name,
86   - // out VARIANT value);
87   - // org.freedesktop.DBus.Properties.Set (in STRING interface_name,
88   - // in STRING property_name,
89   - //
90   - const char *interface_name = session.interface.c_str();
91   -
92   - dbus_message_append_args(
93   - this->msg.out,
94   - DBUS_TYPE_STRING,&interface_name,
95   - DBUS_TYPE_STRING,&property,
96   - DBUS_TYPE_INVALID
97   - );
98   -
99   - }
100   -
101 47 IPC::Request::~Request() {
102 48 if(msg.out) {
103 49 dbus_message_unref(msg.out);
... ... @@ -253,8 +199,6 @@
253 199  
254 200 }
255 201  
256   - */
257   -
258 202 }
259 203  
260 204  
... ...
client/src/core/linux/session.cc
... ... @@ -1,100 +0,0 @@
1   -/*
2   - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
3   - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
4   - * aplicativos mainframe. Registro no INPI sob o nome G3270.
5   - *
6   - * Copyright (C) <2008> <Banco do Brasil S.A.>
7   - *
8   - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
9   - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
10   - * Free Software Foundation.
11   - *
12   - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
13   - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
14   - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
15   - * obter mais detalhes.
16   - *
17   - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
18   - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19   - * St, Fifth Floor, Boston, MA 02110-1301 USA
20   - *
21   - * Este programa está nomeado como - e possui - linhas de código.
22   - *
23   - * Contatos:
24   - *
25   - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
26   - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
27   - *
28   - */
29   -
30   -/**
31   - * @file src/os/linux/linux/session.cc
32   - *
33   - * @brief Implements Linux session methods.
34   - *
35   - * @author perry.werneck@gmail.com
36   - *
37   - */
38   -
39   - #include <ipc-client-internals.h>
40   - #include <cstring>
41   - #include <lib3270/trace.h>
42   -
43   - using std::string;
44   -
45   -/*---[ Implement ]----------------------------------------------------------------------------------*/
46   -
47   - static void throws_if_error(DBusError &err) {
48   -
49   - if(dbus_error_is_set(&err)) {
50   - string message = err.message;
51   - dbus_error_free(&err);
52   - throw std::runtime_error(message.c_str());
53   - }
54   -
55   - return;
56   -
57   - }
58   -
59   - namespace TN3270 {
60   -
61   - /*
62   - IPC::Session::Session(const char *id) : Abstract::Session() {
63   -
64   - // Create D-Bus session.
65   - DBusError err;
66   -
67   - dbus_error_init(&err);
68   - this->conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
69   -
70   - debug("dbus_bus_get conn=",conn);
71   -
72   - throws_if_error(err);
73   -
74   - if(!conn)
75   - throw std::runtime_error("DBUS Connection failed");
76   -
77   - auto sep = strchr(id,':');
78   - if(!sep) {
79   - throw std::system_error(EINVAL, std::system_category());
80   - }
81   -
82   - this->name = "br.com.bb.";
83   - this->name += string(id,(sep - id));
84   - this->name += ".";
85   - this->name += (sep+1);
86   - this->path = "/br/com/bb/tn3270/session";
87   - this->interface = "br.com.bb.tn3270.session";
88   -
89   - debug("D-Bus Object name=\"",this->name,"\" D-Bus Object path=\"",this->path,"\"");
90   -
91   - }
92   -
93   - IPC::Session::~Session() {
94   -
95   - }
96   - */
97   -
98   - }
99   -
100   -
client/src/core/session.cc
... ... @@ -49,12 +49,10 @@
49 49 return Local::getSessionInstance();
50 50 }
51 51  
52   - // return new IPC::Session(id);
  52 + return IPC::getSessionInstance(id);
53 53  
54   - return nullptr;
55 54 }
56 55  
57   -
58 56 Session::Session() {
59 57 }
60 58  
... ...
client/src/core/windows/request.cc
... ... @@ -44,46 +44,6 @@
44 44  
45 45 namespace TN3270 {
46 46  
47   - #define PIPE_BUFFER_LENGTH 8192
48   -
49   - IPC::Request::Request(const Session &session) {
50   -
51   - this->hPipe = session.hPipe;
52   -
53   - in.length = PIPE_BUFFER_LENGTH;
54   - in.used = 0;
55   - in.block = new uint8_t[in.length];
56   -
57   - out.length = PIPE_BUFFER_LENGTH;
58   - out.used = 0;
59   - out.block = new uint8_t[out.length];
60   -
61   - }
62   -
63   - IPC::Request::Request(const Session &session, const char *method) : Request(session) {
64   -
65   - // Add name
66   - strcpy((char *) out.block, method);
67   - out.used += strlen((char *) method) + 1;
68   -
69   - // Add ID
70   - *((uint16_t *) (out.block + out.used)) = (uint16_t) 3;
71   - out.used += sizeof(uint16_t);
72   -
73   - }
74   -
75   - IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) {
76   -
77   - // Add name
78   - strcpy((char *) out.block, property);
79   - out.used += strlen((char *) property) + 1;
80   -
81   - // Add ID (SetProperty = 2, getProperty = 1)
82   - *((uint16_t *) (out.block + out.used)) = (uint16_t) (isSet ? 2 : 1);
83   - out.used += sizeof(uint16_t);
84   -
85   - }
86   -
87 47 IPC::Request::~Request() {
88 48  
89 49 delete[] ((uint8_t *) in.block);
... ... @@ -186,6 +146,49 @@
186 146 return *this;
187 147 }
188 148  
  149 + IPC::Request & IPC::Request::call() {
  150 +
  151 +#ifdef DEBUG
  152 + // lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used);
  153 +#endif // DEBUG
  154 +
  155 + in.current = 0;
  156 +
  157 + if(!TransactNamedPipe(
  158 + this->hPipe,
  159 + this->out.block,
  160 + this->out.used,
  161 + this->in.block,
  162 + this->in.length,
  163 + &this->in.used,
  164 + NULL)
  165 + ) {
  166 +
  167 + throw std::runtime_error("Can't transact on IPC Channel");
  168 +
  169 + }
  170 +
  171 + debug("Received response \"", in.block, "\" with ", in.used, " bytes");
  172 +#ifdef DEBUG
  173 + // lib3270_trace_data(NULL,"Response block",(const char *) this->in.block, this->in.used);
  174 +#endif // DEBUG
  175 +
  176 + // Extract response name
  177 + in.current = strlen((const char *) in.block)+1;
  178 +
  179 + // Extract return code
  180 + uint16_t rc = *((uint16_t *) (in.block + in.current));
  181 + in.current += sizeof(uint16_t);
  182 +
  183 + // Extract argc
  184 + uint16_t argc = *((uint16_t *) (in.block + in.current));
  185 + in.current += sizeof(uint16_t);
  186 +
  187 + debug("Received response \"", ((const char *) in.block), "\" with rc=", rc, " and ", argc, " arguments");
  188 +
  189 + return *this;
  190 + }
  191 +
189 192 }
190 193  
191 194  
... ...
client/src/core/windows/session.cc
... ... @@ -1,142 +0,0 @@
1   -/*
2   - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
3   - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
4   - * aplicativos mainframe. Registro no INPI sob o nome G3270.
5   - *
6   - * Copyright (C) <2008> <Banco do Brasil S.A.>
7   - *
8   - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
9   - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
10   - * Free Software Foundation.
11   - *
12   - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
13   - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
14   - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
15   - * obter mais detalhes.
16   - *
17   - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
18   - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19   - * St, Fifth Floor, Boston, MA 02110-1301 USA
20   - *
21   - * Este programa está nomeado como - e possui - linhas de código.
22   - *
23   - * Contatos:
24   - *
25   - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
26   - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
27   - *
28   - */
29   -
30   -/**
31   - * @file src/os/windows/session.cc
32   - *
33   - * @brief Implements WIN32 remote session methods.
34   - *
35   - * @author perry.werneck@gmail.com
36   - *
37   - */
38   -
39   - #include <ipc-client-internals.h>
40   - #include <cstring>
41   - #include <lib3270/trace.h>
42   - #include <algorithm>
43   -
44   - using std::string;
45   -
46   -/*---[ Implement ]----------------------------------------------------------------------------------*/
47   -
48   - namespace TN3270 {
49   -
50   - IPC::Session::Session(const char *id) : Abstract::Session() {
51   -
52   - char *ptr = strchr(id,':');
53   -
54   - if(!ptr)
55   - throw std::system_error(EINVAL, std::system_category());
56   -
57   - string pipename{"\\\\.\\pipe\\"};
58   -
59   - pipename += string(id,ptr - id);
60   - pipename += "\\";
61   - pipename += (ptr+1);
62   -
63   - std::transform(pipename.begin(), pipename.end(), pipename.begin(), ::tolower);
64   -
65   - debug("id: \"", id, "\" pipename: \"", pipename , "\"");
66   -
67   - this->hPipe = CreateFile(
68   - TEXT(pipename.c_str()), // pipe name
69   - GENERIC_READ | // read and write access
70   - GENERIC_WRITE,
71   - 0, // no sharing
72   - NULL, // default security attributes
73   - OPEN_EXISTING, // opens existing pipe
74   - 0, // default attributes
75   - NULL // no template file
76   - );
77   -
78   - if (hPipe == INVALID_HANDLE_VALUE) {
79   - throw std::runtime_error("Can't open IPC Channel");
80   - }
81   -
82   - // The pipe connected; change to message-read mode.
83   - DWORD dwMode = PIPE_READMODE_MESSAGE;
84   - if(!SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL)) {
85   - throw std::runtime_error("Can't set IPC Channel mode");
86   - }
87   -
88   - }
89   -
90   - IPC::Session::~Session() {
91   - CloseHandle(this->hPipe);
92   - }
93   -
94   -
95   - IPC::Request & IPC::Request::call() {
96   -
97   -#ifdef DEBUG
98   - // lib3270_trace_data(NULL,"Request block",(const char *) this->out.block, this->out.used);
99   -#endif // DEBUG
100   -
101   - in.current = 0;
102   -
103   - if(!TransactNamedPipe(
104   - this->hPipe,
105   - this->out.block,
106   - this->out.used,
107   - this->in.block,
108   - this->in.length,
109   - &this->in.used,
110   - NULL)
111   - ) {
112   -
113   - throw std::runtime_error("Can't transact on IPC Channel");
114   -
115   - }
116   -
117   - debug("Received response \"", in.block, "\" with ", in.used, " bytes");
118   -#ifdef DEBUG
119   - // lib3270_trace_data(NULL,"Response block",(const char *) this->in.block, this->in.used);
120   -#endif // DEBUG
121   -
122   - // Extract response name
123   - in.current = strlen((const char *) in.block)+1;
124   -
125   - // Extract return code
126   - uint16_t rc = *((uint16_t *) (in.block + in.current));
127   - in.current += sizeof(uint16_t);
128   -
129   - // Extract argc
130   - uint16_t argc = *((uint16_t *) (in.block + in.current));
131   - in.current += sizeof(uint16_t);
132   -
133   - debug("Received response \"", ((const char *) in.block), "\" with rc=", rc, " and ", argc, " arguments");
134   -
135   - return *this;
136   - }
137   -
138   -
139   -
140   - }
141   -
142   -
client/src/include/ipc-client-internals.h
... ... @@ -170,19 +170,71 @@
170 170 /// @brief IPC Based acess (Access an active instance of pw3270 or pw3270d)
171 171 namespace IPC {
172 172  
173   - TN3270_PRIVATE Session * getSessionInstance();
  173 + TN3270_PRIVATE TN3270::Session * getSessionInstance(const char *id);
174 174  
175 175 class Session;
176 176  
177 177 /// @brief PW3270 IPC Request/Response.
178 178 class Request {
179 179 private:
  180 + Request(const IPC::Session &session);
  181 +
  182 +#ifdef _WIN32
  183 + /// @brief Pipe Handle.
  184 + HANDLE hPipe;
  185 +
  186 + /// @brief IPC Data type.
  187 + enum Type : uint8_t {
  188 + String = 's',
  189 + Boolean = 'b',
  190 + Uchar = 'y',
  191 + Int16 = 'n',
  192 + Uint16 = 'q',
  193 + Int32 = 'i',
  194 + Int32x = 'h',
  195 + Uint32 = 'u',
  196 + Int64 = 'x',
  197 + Uint64 = 't'
  198 + };
  199 +
  200 + struct {
  201 + DWORD length; ///< @brief Length of input buffer.
  202 + DWORD used; ///< @brief Length of used block.
  203 + DWORD current; ///< @brief Offset of the current argument.
  204 + uint8_t * block;
  205 + } in;
  206 +
  207 + struct {
  208 + DWORD length;
  209 + DWORD used;
  210 + uint8_t * block;
  211 + } out;
180 212  
  213 + struct DataBlock {
  214 + Type type;
  215 + };
  216 +
  217 + /// @brief Store value on data block.
  218 + DataBlock * pushBlock(const void *ptr, size_t len);
  219 +
  220 + /// @brief Get next argument.
  221 + DataBlock * getNextBlock() const;
  222 +
  223 +#else
  224 + struct {
  225 + DBusMessage * in;
  226 + DBusMessage * out;
  227 + DBusMessageIter iter;
  228 +
  229 + } msg;
  230 + DBusConnection * conn;
  231 +
  232 +#endif // _WIN32
181 233  
182 234 public:
183 235  
184 236 /// @brief Create a method call.
185   - Request(const Session &session, const char *method);
  237 + Request(const IPC::Session &session, const char *method);
186 238  
187 239 /// @brief Create a get/set property call.
188 240 ///
... ... @@ -190,7 +242,7 @@
190 242 /// @param isSet true if this is a setProperty call.
191 243 /// @param property Property name.
192 244 //
193   - Request(const Session &session, bool isSet, const char *property);
  245 + Request(const IPC::Session &session, bool isSet, const char *property);
194 246  
195 247 ~Request();
196 248  
... ...
client/src/session/local/private.h
... ... @@ -113,6 +113,9 @@
113 113 void getProperty(const char *name, int &value) const override;
114 114 void getProperty(const char *name, std::string &value) const override;
115 115 void getProperty(const char *name, bool &value) const override;
  116 + void setProperty(const char *name, const int value) override;
  117 + void setProperty(const char *name, const char *value) override;
  118 +
116 119 std::string getVersion() const override;
117 120 std::string getRevision() const override;
118 121 std::string getLUName() const override;
... ...
client/src/session/local/properties.cc
... ... @@ -111,6 +111,14 @@
111 111  
112 112 }
113 113  
  114 + void Local::Session::setProperty(const char *name, const int value) {
  115 + throw std::system_error(ENOTSUP, std::system_category());
  116 + }
  117 +
  118 + void Local::Session::setProperty(const char *name, const char *value) {
  119 + throw std::system_error(ENOTSUP, std::system_category());
  120 + }
  121 +
114 122 void Local::Session::setCharSet(const char *charset) {
115 123 Abstract::Session::setCharSet(lib3270_get_display_charset(this->hSession),charset);
116 124 }
... ...
client/src/session/remote/actions.cc
... ... @@ -39,35 +39,153 @@
39 39 #include "private.h"
40 40 #include <lib3270/actions.h>
41 41  
  42 +#ifndef _WIN32
  43 + #include <unistd.h>
  44 +#endif // _WIN32
  45 +
42 46 /*---[ Implement ]----------------------------------------------------------------------------------*/
43 47  
44 48 namespace TN3270 {
45 49  
46 50 void IPC::Session::action(const char *action_name) {
  51 +
  52 + int32_t rc;
  53 +
  54 + Request(*this,"action")
  55 + .push(action_name)
  56 + .call()
  57 + .pop(rc);
  58 +
  59 + if(rc) {
  60 + throw std::system_error((int) rc, std::system_category());
  61 + }
  62 +
47 63 }
48 64  
49 65 void IPC::Session::connect(const char *url, int seconds) {
  66 +
  67 + if(!url)
  68 + url = "";
  69 +
  70 + Request(*this,"connect")
  71 + .push(url)
  72 + .call();
  73 +
  74 + if(seconds)
  75 + this->waitForReady(seconds);
  76 +
50 77 }
51 78  
52 79 void IPC::Session::disconnect() {
  80 +
  81 + Request(*this,"disconnect")
  82 + .call();
  83 +
53 84 }
54 85  
55 86 void IPC::Session::wait(unsigned short seconds) const {
  87 +
  88 + time_t end = time(nullptr) + seconds;
  89 +
  90 + while(time(nullptr) < end) {
  91 +
  92 +#ifdef _WIN32
  93 + Sleep(1000);
  94 +#else
  95 + sleep(1);
  96 +#endif // _WIN32
  97 +
  98 + if(getConnectionState() == TN3270::DISCONNECTED)
  99 + throw std::runtime_error("Disconnected");
  100 +
  101 + }
  102 +
56 103 }
57 104  
58 105 void IPC::Session::waitForReady(time_t timeout) const {
  106 +
  107 + int rc;
  108 +
  109 + time_t end = time(nullptr) + timeout;
  110 +
  111 + while(time(nullptr) < end) {
  112 +
  113 + debug("Running waitForReady request...");
  114 +
  115 + Request(*this,"waitForReady")
  116 + .push((uint32_t) 1)
  117 + .call()
  118 + .pop(rc);
  119 +
  120 + debug("Wait for ready returned ",rc);
  121 +
  122 + if(rc == 0)
  123 + return;
  124 +
  125 + }
  126 +
  127 + throw std::system_error(ETIMEDOUT, std::system_category());
  128 +
59 129 }
60 130  
61 131 void IPC::Session::waitForChange(unsigned short seconds) const {
  132 +
  133 + int rc;
  134 +
  135 + time_t end = time(nullptr) + seconds;
  136 +
  137 + while(time(nullptr) < end) {
  138 +
  139 + debug("Running waitForUpdate request...");
  140 +
  141 + Request(*this,"waitForUpdate")
  142 + .push((uint32_t) 1)
  143 + .call()
  144 + .pop(rc);
  145 +
  146 + debug("Wait for update returned ",rc);
  147 +
  148 + if(rc == 0)
  149 + return;
  150 +
  151 + }
  152 +
  153 + throw std::system_error(ETIMEDOUT, std::system_category());
  154 +
62 155 }
63 156  
64 157 void IPC::Session::pfkey(unsigned short value) {
  158 +
  159 + int32_t rc;
  160 +
  161 + Request(*this,"pfkey")
  162 + .push((uint32_t) value)
  163 + .call()
  164 + .pop(rc);
  165 +
  166 + if(rc) {
  167 + throw std::system_error((int) rc, std::system_category());
  168 + }
  169 +
65 170 }
66 171  
67 172 void IPC::Session::pakey(unsigned short value) {
  173 +
  174 + int32_t rc;
  175 +
  176 + Request(*this,"pakey")
  177 + .push((uint32_t) value)
  178 + .call()
  179 + .pop(rc);
  180 +
  181 + if(rc) {
  182 + throw std::system_error((int) rc, std::system_category());
  183 + }
  184 +
68 185 }
69 186  
70 187 void IPC::Session::push(const Action action) {
  188 + this->action(toCharString(action));
71 189 }
72 190  
73 191 void IPC::Session::print(LIB3270_CONTENT_OPTION option) {
... ...
client/src/session/remote/get.cc
... ... @@ -43,21 +43,70 @@
43 43 namespace TN3270 {
44 44  
45 45 std::string IPC::Session::get() const {
  46 +
  47 + std::string rc;
  48 +
  49 + Request(*this,"getString")
  50 + .call()
  51 + .pop(rc);
  52 +
  53 + return rc;
  54 +
46 55 }
47 56  
48 57 std::string IPC::Session::get(int baddr, size_t len, char lf) const {
  58 +
  59 + std::string rc;
  60 +
  61 + Request(*this,"getStringAtAddress")
  62 + .push((int32_t) baddr)
  63 + .push((int32_t) len)
  64 + .push((uint8_t) lf)
  65 + .call()
  66 + .pop(rc);
  67 +
  68 + return rc;
  69 +
49 70 }
50 71  
51 72 std::string IPC::Session::get(int row, int col, size_t sz, char lf) const {
  73 +
  74 + std::string rc;
  75 +
  76 + Request(*this,"getStringAt")
  77 + .push((uint32_t) row)
  78 + .push((uint32_t) col)
  79 + .push((uint32_t) sz)
  80 + .push((uint8_t) lf)
  81 + .call()
  82 + .pop(rc);
  83 +
  84 + return rc;
  85 +
52 86 }
53 87  
54 88 ProgramMessage IPC::Session::getProgramMessage() const {
  89 +
  90 + int program_message;
  91 + getProperty("program_message",program_message);
  92 + return (ProgramMessage) program_message;
  93 +
55 94 }
56 95  
57 96 ConnectionState IPC::Session::getConnectionState() const {
  97 +
  98 + int cstate;
  99 + getProperty("cstate",cstate);
  100 + return (ConnectionState) cstate;
  101 +
58 102 }
59 103  
60 104 SSLState IPC::Session::getSSLState() const {
  105 +
  106 + int value;
  107 + getProperty("sslstate",value);
  108 + return (TN3270::SSLState) value;
  109 +
61 110 }
62 111  
63 112  
... ...
client/src/session/remote/init.cc
... ... @@ -1,62 +0,0 @@
1   -/*
2   - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
3   - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
4   - * aplicativos mainframe. Registro no INPI sob o nome G3270.
5   - *
6   - * Copyright (C) <2008> <Banco do Brasil S.A.>
7   - *
8   - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
9   - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
10   - * Free Software Foundation.
11   - *
12   - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
13   - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
14   - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
15   - * obter mais detalhes.
16   - *
17   - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
18   - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
19   - * St, Fifth Floor, Boston, MA 02110-1301 USA
20   - *
21   - * Este programa está nomeado como - e possui - linhas de código.
22   - *
23   - * Contatos:
24   - *
25   - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
26   - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
27   - *
28   - */
29   -
30   -/**
31   - * @file src/session/local/init.cc
32   - *
33   - * @brief Implement lib3270 direct access layout (NO IPC).
34   - *
35   - * @author perry.werneck@gmail.com
36   - *
37   - */
38   -
39   - #include "private.h"
40   -
41   - extern "C" {
42   - #include <lib3270/session.h>
43   - }
44   -
45   -
46   -/*---[ Implement ]----------------------------------------------------------------------------------*/
47   -
48   - namespace TN3270 {
49   -
50   - Session * IPC::getSessionInstance() {
51   - return new IPC::Session();
52   - }
53   -
54   - IPC::Session::Session() : Abstract::Session() {
55   - }
56   -
57   - IPC::Session::~Session() {
58   - }
59   -
60   - }
61   -
62   -
client/src/session/remote/linux/request.cc 0 → 100644
... ... @@ -0,0 +1,109 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * @file
  32 + *
  33 + * @brief Implements linux request constructors based on TN3270::IPC::Session.
  34 + *
  35 + * @author perry.werneck@gmail.com
  36 + *
  37 + */
  38 +
  39 + #include "../private.h"
  40 + #include <iostream>
  41 +
  42 + using std::clog;
  43 + using std::endl;
  44 + using std::string;
  45 +
  46 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  47 +
  48 + namespace TN3270 {
  49 +
  50 + IPC::Request::Request(const IPC::Session &session) {
  51 + this->conn = session.conn;
  52 + this->msg.in = nullptr;
  53 + this->msg.out = nullptr;
  54 + }
  55 +
  56 + IPC::Request::Request(const IPC::Session &session, const char *method) : Request(session) {
  57 +
  58 +#ifdef DEBUG
  59 + clog << "Creating request \"" << method << "\"" << endl;
  60 +#endif // DEBUG
  61 +
  62 + this->msg.out = dbus_message_new_method_call(
  63 + session.name.c_str(), // Destination
  64 + session.path.c_str(), // Path
  65 + session.interface.c_str(), // Interface
  66 + method // Method
  67 + );
  68 +
  69 + if(!msg.out) {
  70 + throw std::runtime_error("Can't create D-Bus Method Call");
  71 + }
  72 +
  73 + }
  74 +
  75 + IPC::Request::Request(const IPC::Session &session, bool isSet, const char *property) : Request(session) {
  76 +
  77 + this->msg.out = dbus_message_new_method_call(
  78 + session.name.c_str(), // Destination
  79 + session.path.c_str(), // Path
  80 + "org.freedesktop.DBus.Properties", // Interface
  81 + (isSet ? "Set" : "Get")
  82 + );
  83 +
  84 + if(!msg.out) {
  85 + throw std::runtime_error("Can't create D-Bus Property Call");
  86 + }
  87 +
  88 + //
  89 + // https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties
  90 + // org.freedesktop.DBus.Properties.Get (in STRING interface_name,
  91 + // in STRING property_name,
  92 + // out VARIANT value);
  93 + // org.freedesktop.DBus.Properties.Set (in STRING interface_name,
  94 + // in STRING property_name,
  95 + //
  96 + const char *interface_name = session.interface.c_str();
  97 +
  98 + dbus_message_append_args(
  99 + this->msg.out,
  100 + DBUS_TYPE_STRING,&interface_name,
  101 + DBUS_TYPE_STRING,&property,
  102 + DBUS_TYPE_INVALID
  103 + );
  104 +
  105 + }
  106 +
  107 + }
  108 +
  109 +
... ...
client/src/session/remote/linux/session.cc 0 → 100644
... ... @@ -0,0 +1,101 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * @file src/os/linux/linux/session.cc
  32 + *
  33 + * @brief Implements Linux session methods.
  34 + *
  35 + * @author perry.werneck@gmail.com
  36 + *
  37 + */
  38 +
  39 + #include "../private.h"
  40 + #include <ipc-client-internals.h>
  41 + #include <cstring>
  42 + #include <lib3270/trace.h>
  43 +
  44 + using std::string;
  45 +
  46 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  47 +
  48 + static void throws_if_error(DBusError &err) {
  49 +
  50 + if(dbus_error_is_set(&err)) {
  51 + string message = err.message;
  52 + dbus_error_free(&err);
  53 + throw std::runtime_error(message.c_str());
  54 + }
  55 +
  56 + return;
  57 +
  58 + }
  59 +
  60 + namespace TN3270 {
  61 +
  62 + IPC::Session::Session(const char *id) : Abstract::Session() {
  63 +
  64 + // Create D-Bus session.
  65 + DBusError err;
  66 +
  67 + dbus_error_init(&err);
  68 + this->conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
  69 +
  70 + debug("dbus_bus_get conn=",conn);
  71 +
  72 + throws_if_error(err);
  73 +
  74 + if(!conn)
  75 + throw std::runtime_error("DBUS Connection failed");
  76 +
  77 + auto sep = strchr(id,':');
  78 + if(!sep) {
  79 + throw std::system_error(EINVAL, std::system_category());
  80 + }
  81 +
  82 + this->name = "br.com.bb.";
  83 + this->name += string(id,(sep - id));
  84 + this->name += ".";
  85 + this->name += (sep+1);
  86 + this->path = "/br/com/bb/tn3270/session";
  87 + this->interface = "br.com.bb.tn3270.session";
  88 +
  89 + debug("D-Bus Object name=\"",this->name,"\" D-Bus Object path=\"",this->path,"\"");
  90 +
  91 + setCharSet();
  92 +
  93 + }
  94 +
  95 + IPC::Session::~Session() {
  96 +
  97 + }
  98 +
  99 + }
  100 +
  101 +
... ...
client/src/session/remote/private.h
... ... @@ -61,52 +61,12 @@
61 61 #ifdef _WIN32
62 62 /// @brief Pipe Handle.
63 63 HANDLE hPipe;
64   -
65   - /// @brief IPC Data type.
66   - enum Type : uint8_t {
67   - String = 's',
68   - Boolean = 'b',
69   - Uchar = 'y',
70   - Int16 = 'n',
71   - Uint16 = 'q',
72   - Int32 = 'i',
73   - Int32x = 'h',
74   - Uint32 = 'u',
75   - Int64 = 'x',
76   - Uint64 = 't'
77   - };
78   -
79   - struct {
80   - DWORD length; ///< @brief Length of input buffer.
81   - DWORD used; ///< @brief Length of used block.
82   - DWORD current; ///< @brief Offset of the current argument.
83   - uint8_t * block;
84   - } in;
85   -
86   - struct {
87   - DWORD length;
88   - DWORD used;
89   - uint8_t * block;
90   - } out;
91   -
92   - struct DataBlock {
93   - Type type;
94   - };
95   -
96   - /// @brief Store value on data block.
97   - DataBlock * pushBlock(const void *ptr, size_t len);
98   -
99   - /// @brief Get next argument.
100   - DataBlock * getNextBlock() const;
101   -
102 64 #else
103   - struct {
104   - DBusMessage * in;
105   - DBusMessage * out;
106   - DBusMessageIter iter;
107 65  
108   - } msg;
109 66 DBusConnection * conn;
  67 + std::string name; ///< @brief D-Bus Object name.
  68 + std::string path; ///< @brief D-Bus Object path.
  69 + std::string interface; ///< @brief D-Bus interface.
110 70  
111 71 #endif // _WIN32
112 72  
... ... @@ -126,7 +86,7 @@
126 86  
127 87 public:
128 88  
129   - Session();
  89 + Session(const char *id);
130 90 virtual ~Session();
131 91  
132 92 // Actions
... ... @@ -151,6 +111,9 @@
151 111 void getProperty(const char *name, int &value) const override;
152 112 void getProperty(const char *name, std::string &value) const override;
153 113 void getProperty(const char *name, bool &value) const override;
  114 + void setProperty(const char *name, const int value) override;
  115 + void setProperty(const char *name, const char *value) override;
  116 +
154 117 std::string getVersion() const override;
155 118 std::string getRevision() const override;
156 119 std::string getLUName() const override;
... ...
client/src/session/remote/properties.cc
... ... @@ -46,51 +46,154 @@
46 46 namespace TN3270 {
47 47  
48 48 void IPC::Session::getProperty(const char *name, int &value) const {
  49 +
  50 + Request(*this,false,name)
  51 + .call()
  52 + .pop(value);
  53 +
49 54 }
50 55  
51 56 void IPC::Session::getProperty(const char *name, std::string &value) const {
  57 +
  58 + Request(*this,false,name)
  59 + .call()
  60 + .pop(value);
  61 +
52 62 }
53 63  
54 64 void IPC::Session::getProperty(const char *name, bool &value) const {
  65 + throw std::system_error(ENOTSUP, std::system_category());
  66 + }
  67 +
  68 + void IPC::Session::setProperty(const char *name, const int value) {
  69 +
  70 + int32_t rc;
  71 +
  72 + Request(*this,true,name)
  73 + .push(value)
  74 + .call()
  75 + .pop(rc);
  76 +
  77 + if(rc) {
  78 + throw std::system_error((int) rc, std::system_category());
  79 + }
  80 +
  81 + }
  82 +
  83 + void IPC::Session::setProperty(const char *name, const char *value) {
  84 +
  85 + int32_t rc;
  86 +
  87 + Request(*this,true,name)
  88 + .push(value)
  89 + .call()
  90 + .pop(rc);
  91 +
  92 + if(rc) {
  93 + throw std::system_error((int) rc, std::system_category());
  94 + }
  95 +
55 96 }
56 97  
57 98 void IPC::Session::setCharSet(const char *charset) {
58 99 }
59 100  
60 101 unsigned short IPC::Session::getScreenWidth() const {
  102 +
  103 + int value;
  104 + getProperty("width",value);
  105 + return (unsigned short) value;
  106 +
61 107 }
62 108  
63 109 unsigned short IPC::Session::getScreenHeight() const {
  110 +
  111 + int value;
  112 + getProperty("height",value);
  113 + return (unsigned short) value;
  114 +
64 115 }
65 116  
66 117 unsigned short IPC::Session::getScreenLength() const {
  118 +
  119 + int value;
  120 + getProperty("length",value);
  121 + return (unsigned short) value;
  122 +
67 123 }
68 124  
69 125 void IPC::Session::setUnlockDelay(unsigned short delay) {
  126 +
  127 + setProperty("unlock_delay", (uint32_t) delay);
  128 +
70 129 }
71 130  
72 131 void IPC::Session::setCursor(unsigned short addr) {
  132 +
  133 + setProperty("setCursorAddress", (uint32_t) addr);
  134 +
73 135 }
74 136  
75 137 void IPC::Session::setCursor(unsigned short row, unsigned short col) {
  138 +
  139 + int32_t rc;
  140 +
  141 + Request(*this,"setCursorPosition")
  142 + .push((uint32_t) row)
  143 + .push((uint32_t) col)
  144 + .call()
  145 + .pop(rc);
  146 +
  147 + if(rc) {
  148 + throw std::system_error((int) rc, std::system_category());
  149 + }
  150 +
76 151 }
77 152  
78 153 unsigned short IPC::Session::getCursorAddress() {
  154 +
  155 + int32_t address;
  156 + getProperty("cursor_address",address);
  157 + return (unsigned short) address;
  158 +
79 159 }
80 160  
81 161 std::string IPC::Session::getVersion() const {
  162 +
  163 + string rc;
  164 + getProperty("version",rc);
  165 + return rc;
  166 +
82 167 }
83 168  
84 169 std::string IPC::Session::getRevision() const {
  170 +
  171 + string rc;
  172 + getProperty("revision",rc);
  173 + return rc;
  174 +
85 175 }
86 176  
87 177 std::string IPC::Session::getLUName() const {
  178 +
  179 + string rc;
  180 + getProperty("luname",rc);
  181 + return rc;
  182 +
88 183 }
89 184  
90 185 std::string IPC::Session::getHostURL() const {
  186 +
  187 + std::string value;
  188 + getProperty("url",value);
  189 + return value;
  190 +
91 191 }
92 192  
93 193 void IPC::Session::setHostURL(const char *url) {
  194 +
  195 + setProperty("url",url);
  196 +
94 197 }
95 198  
96 199 }
... ...
client/src/session/remote/set.cc
... ... @@ -43,12 +43,51 @@
43 43 namespace TN3270 {
44 44  
45 45 void IPC::Session::set(const std::string &str) {
  46 +
  47 + int rc;
  48 +
  49 + Request(*this,"setString")
  50 + .push(str.c_str())
  51 + .call()
  52 + .pop(rc);
  53 +
  54 + if(rc) {
  55 + throw std::system_error((int) rc, std::system_category());
  56 + }
  57 +
46 58 }
47 59  
48 60 void IPC::Session::set(int baddr, const std::string &str) {
  61 +
  62 + int rc;
  63 +
  64 + Request(*this,"setStringAtAddress")
  65 + .push((int32_t) baddr)
  66 + .push(str.c_str())
  67 + .call()
  68 + .pop(rc);
  69 +
  70 + if(rc) {
  71 + throw std::system_error((int) rc, std::system_category());
  72 + }
  73 +
49 74 }
50 75  
51 76 void IPC::Session::set(int row, int col, const std::string &str) {
  77 +
  78 + int32_t rc;
  79 +
  80 + Request(*this,"setStringAt")
  81 + .push((uint32_t) row)
  82 + .push((uint32_t) col)
  83 + .push(str.c_str())
  84 + .call()
  85 + .pop(rc);
  86 +
  87 + if(rc) {
  88 + throw std::system_error((int) rc, std::system_category());
  89 + }
  90 +
52 91 }
53 92  
54 93 }
... ...
client/src/session/remote/tools.cc
... ... @@ -42,6 +42,9 @@
42 42  
43 43 namespace TN3270 {
44 44  
  45 + Session * IPC::getSessionInstance(const char *id) {
  46 + return new IPC::Session(id);
  47 + }
45 48  
46 49  
47 50 }
... ...
client/src/session/remote/windows/request.cc 0 → 100644
... ... @@ -0,0 +1,89 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * @file
  32 + *
  33 + * @brief Implements WIN32 request constructors based on TN3270::IPC::Session.
  34 + *
  35 + * @author perry.werneck@gmail.com
  36 + *
  37 + */
  38 +
  39 + #include "../private.h"
  40 +
  41 + using std::string;
  42 +
  43 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  44 +
  45 + namespace TN3270 {
  46 +
  47 + #define PIPE_BUFFER_LENGTH 8192
  48 +
  49 + IPC::Request::Request(const Session &session) {
  50 +
  51 + this->hPipe = session.hPipe;
  52 +
  53 + in.length = PIPE_BUFFER_LENGTH;
  54 + in.used = 0;
  55 + in.block = new uint8_t[in.length];
  56 +
  57 + out.length = PIPE_BUFFER_LENGTH;
  58 + out.used = 0;
  59 + out.block = new uint8_t[out.length];
  60 +
  61 + }
  62 +
  63 + IPC::Request::Request(const Session &session, const char *method) : Request(session) {
  64 +
  65 + // Add name
  66 + strcpy((char *) out.block, method);
  67 + out.used += strlen((char *) method) + 1;
  68 +
  69 + // Add ID
  70 + *((uint16_t *) (out.block + out.used)) = (uint16_t) 3;
  71 + out.used += sizeof(uint16_t);
  72 +
  73 + }
  74 +
  75 + IPC::Request::Request(const Session &session, bool isSet, const char *property) : Request(session) {
  76 +
  77 + // Add name
  78 + strcpy((char *) out.block, property);
  79 + out.used += strlen((char *) property) + 1;
  80 +
  81 + // Add ID (SetProperty = 2, getProperty = 1)
  82 + *((uint16_t *) (out.block + out.used)) = (uint16_t) (isSet ? 2 : 1);
  83 + out.used += sizeof(uint16_t);
  84 +
  85 + }
  86 +
  87 + }
  88 +
  89 +
... ...
client/src/session/remote/windows/session.cc 0 → 100644
... ... @@ -0,0 +1,97 @@
  1 +/*
  2 + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270
  3 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a
  4 + * aplicativos mainframe. Registro no INPI sob o nome G3270.
  5 + *
  6 + * Copyright (C) <2008> <Banco do Brasil S.A.>
  7 + *
  8 + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob
  9 + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela
  10 + * Free Software Foundation.
  11 + *
  12 + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER
  13 + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO
  14 + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para
  15 + * obter mais detalhes.
  16 + *
  17 + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este
  18 + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin
  19 + * St, Fifth Floor, Boston, MA 02110-1301 USA
  20 + *
  21 + * Este programa está nomeado como - e possui - linhas de código.
  22 + *
  23 + * Contatos:
  24 + *
  25 + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
  26 + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça)
  27 + *
  28 + */
  29 +
  30 +/**
  31 + * @file src/os/windows/session.cc
  32 + *
  33 + * @brief Implements WIN32 remote session methods.
  34 + *
  35 + * @author perry.werneck@gmail.com
  36 + *
  37 + */
  38 +
  39 + #include <ipc-client-internals.h>
  40 + #include <cstring>
  41 + #include <lib3270/trace.h>
  42 + #include <algorithm>
  43 +
  44 + using std::string;
  45 +
  46 +/*---[ Implement ]----------------------------------------------------------------------------------*/
  47 +
  48 + namespace TN3270 {
  49 +
  50 + IPC::Session::Session(const char *id) : Abstract::Session() {
  51 +
  52 + char *ptr = strchr(id,':');
  53 +
  54 + if(!ptr)
  55 + throw std::system_error(EINVAL, std::system_category());
  56 +
  57 + string pipename{"\\\\.\\pipe\\"};
  58 +
  59 + pipename += string(id,ptr - id);
  60 + pipename += "\\";
  61 + pipename += (ptr+1);
  62 +
  63 + std::transform(pipename.begin(), pipename.end(), pipename.begin(), ::tolower);
  64 +
  65 + debug("id: \"", id, "\" pipename: \"", pipename , "\"");
  66 +
  67 + this->hPipe = CreateFile(
  68 + TEXT(pipename.c_str()), // pipe name
  69 + GENERIC_READ | // read and write access
  70 + GENERIC_WRITE,
  71 + 0, // no sharing
  72 + NULL, // default security attributes
  73 + OPEN_EXISTING, // opens existing pipe
  74 + 0, // default attributes
  75 + NULL // no template file
  76 + );
  77 +
  78 + if (hPipe == INVALID_HANDLE_VALUE) {
  79 + throw std::runtime_error("Can't open IPC Channel");
  80 + }
  81 +
  82 + // The pipe connected; change to message-read mode.
  83 + DWORD dwMode = PIPE_READMODE_MESSAGE;
  84 + if(!SetNamedPipeHandleState(hPipe,&dwMode,NULL,NULL)) {
  85 + throw std::runtime_error("Can't set IPC Channel mode");
  86 + }
  87 +
  88 + setCharSet();
  89 + }
  90 +
  91 + IPC::Session::~Session() {
  92 + CloseHandle(this->hPipe);
  93 + }
  94 +
  95 + }
  96 +
  97 +
... ...
client/src/testprogram/testprogram.cc
... ... @@ -96,7 +96,7 @@
96 96 << "\tRevision: " << host.getRevision()
97 97 << std::endl;
98 98  
99   - host.connect(nullptr);
  99 +// host.connect(nullptr);
100 100  
101 101 cout
102 102 << "Connection state is " << toCharString(host.getConnectionState()) << std::endl
... ... @@ -110,9 +110,6 @@
110 110  
111 111 // host.input("test@0another line");
112 112  
113   - //host.connect();
114   - //if(host) {
115   - //}
116 113  
117 114 } catch(const std::exception &e) {
118 115  
... ... @@ -124,7 +121,7 @@
124 121  
125 122 int main(int argc, char **argv) {
126 123  
127   - const char * session = ""; // "pw3270:a";
  124 + const char * session = "pw3270:a";
128 125  
129 126 #pragma GCC diagnostic push
130 127 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
... ...
common/src/include/lib3270/ipc.h
... ... @@ -290,6 +290,8 @@
290 290 virtual void getProperty(const char *name, int &value) const = 0;
291 291 virtual void getProperty(const char *name, std::string &value) const = 0;
292 292 virtual void getProperty(const char *name, bool &value) const = 0;
  293 + virtual void setProperty(const char *name, const int value) = 0;
  294 + virtual void setProperty(const char *name, const char *value) = 0;
293 295  
294 296 virtual std::string getVersion() const = 0;
295 297 virtual std::string getRevision() const = 0;
... ...
server/src/core/linux/start.c
... ... @@ -72,6 +72,7 @@ static void
72 72  
73 73 } else {
74 74  
  75 + g_message("%s: Invalid or unexpected method call",method_name);
75 76 g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Invalid or unexpected method call");
76 77  
77 78 }
... ...
server/src/core/methods/get.c
... ... @@ -68,11 +68,10 @@ int ipc3270_method_get_string(GObject *session, GVariant *request, GObject *resp
68 68 break;
69 69  
70 70 default:
  71 + g_message("getstring was called with %u arguments.",(unsigned int) g_variant_n_children(request));
71 72 return EINVAL;
72 73 }
73 74  
74   - debug("text:\n%s\n",text);
75   -
76 75 if(!text)
77 76 return errno;
78 77  
... ...
server/src/core/methods/network.c
... ... @@ -29,15 +29,15 @@
29 29  
30 30 #include "private.h"
31 31  
32   -int ipc3270_method_connect(GObject *session, GVariant *request, GObject G_GNUC_UNUSED(*response), GError G_GNUC_UNUSED(**error)) {
  32 +int ipc3270_method_connect(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) {
33 33  
34 34 gchar *text = NULL;
35 35 g_variant_get(request, "(&s)", &text);
36   -
37   - return lib3270_connect_url(ipc3270_get_session(session),text,0);
38   -
  36 + ipc3270_response_append_int32(response, lib3270_connect_url(ipc3270_get_session(session),text,0));
  37 + return 0;
39 38 }
40 39  
41   -int ipc3270_method_disconnect(GObject *session, GVariant G_GNUC_UNUSED(*request), GObject G_GNUC_UNUSED(*response), GError G_GNUC_UNUSED(**error)) {
42   - return lib3270_disconnect(ipc3270_get_session(session));
  40 +int ipc3270_method_disconnect(GObject *session, GVariant G_GNUC_UNUSED(*request), GObject *response, GError G_GNUC_UNUSED(**error)) {
  41 + ipc3270_response_append_int32(response, lib3270_disconnect(ipc3270_get_session(session)));
  42 + return 0;
43 43 }
... ...
server/src/core/methods/wait.c
... ... @@ -29,26 +29,29 @@
29 29  
30 30 #include "private.h"
31 31  
32   -int ipc3270_method_wait(GObject *session, GVariant *request, GObject G_GNUC_UNUSED(*response), GError G_GNUC_UNUSED(**error)) {
  32 +int ipc3270_method_wait(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) {
33 33  
34 34 guint seconds = 1;
35 35 g_variant_get(request, "(u)", &seconds);
36   - return lib3270_wait(ipc3270_get_session(session),seconds);
  36 + ipc3270_response_append_int32(response, lib3270_wait(ipc3270_get_session(session),seconds));
  37 + return 0;
37 38  
38 39 }
39 40  
40   -int ipc3270_method_wait_for_ready(GObject *session, GVariant *request, GObject G_GNUC_UNUSED(*response), GError G_GNUC_UNUSED(**error)) {
  41 +int ipc3270_method_wait_for_ready(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) {
41 42  
42 43 guint seconds = 1;
43 44 g_variant_get(request, "(u)", &seconds);
44   - return lib3270_wait_for_ready(ipc3270_get_session(session),seconds);
  45 + ipc3270_response_append_int32(response, lib3270_wait_for_ready(ipc3270_get_session(session),seconds));
  46 + return 0;
45 47  
46 48 }
47 49  
48   -int ipc3270_method_wait_for_update(GObject *session, GVariant *request, GObject G_GNUC_UNUSED(*response), GError G_GNUC_UNUSED(**error)) {
  50 +int ipc3270_method_wait_for_update(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) {
49 51  
50 52 guint seconds = 1;
51 53 g_variant_get(request, "(u)", &seconds);
52   - return lib3270_wait_for_update(ipc3270_get_session(session),seconds);
  54 + ipc3270_response_append_int32(response, lib3270_wait_for_update(ipc3270_get_session(session),seconds));
  55 + return 0;
53 56  
54 57 }
... ...