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,7 +35,8 @@ MAIN_SOURCES= \
35 $(wildcard src/core/@OSNAME@/*.rc) \ 35 $(wildcard src/core/@OSNAME@/*.rc) \
36 $(wildcard src/session/*.cc) \ 36 $(wildcard src/session/*.cc) \
37 $(wildcard src/session/local/*.cc) \ 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 TEST_SOURCES= \ 41 TEST_SOURCES= \
41 $(wildcard src/testprogram/*.cc) 42 $(wildcard src/testprogram/*.cc)
client/lib3270++.cbp
@@ -51,7 +51,6 @@ @@ -51,7 +51,6 @@
51 <Unit filename="src/core/windows/request.cc" /> 51 <Unit filename="src/core/windows/request.cc" />
52 <Unit filename="src/core/windows/resources.rc" /> 52 <Unit filename="src/core/windows/resources.rc" />
53 <Unit filename="src/core/windows/resources.rc.in" /> 53 <Unit filename="src/core/windows/resources.rc.in" />
54 - <Unit filename="src/core/windows/session.cc" />  
55 <Unit filename="src/include/ipc-client-internals.h" /> 54 <Unit filename="src/include/ipc-client-internals.h" />
56 <Unit filename="src/session/get.cc" /> 55 <Unit filename="src/session/get.cc" />
57 <Unit filename="src/session/local/actions.cc" /> 56 <Unit filename="src/session/local/actions.cc" />
@@ -65,10 +64,14 @@ @@ -65,10 +64,14 @@
65 <Unit filename="src/session/remote/actions.cc" /> 64 <Unit filename="src/session/remote/actions.cc" />
66 <Unit filename="src/session/remote/get.cc" /> 65 <Unit filename="src/session/remote/get.cc" />
67 <Unit filename="src/session/remote/init.cc" /> 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 <Unit filename="src/session/remote/private.h" /> 69 <Unit filename="src/session/remote/private.h" />
69 <Unit filename="src/session/remote/properties.cc" /> 70 <Unit filename="src/session/remote/properties.cc" />
70 <Unit filename="src/session/remote/set.cc" /> 71 <Unit filename="src/session/remote/set.cc" />
71 <Unit filename="src/session/remote/tools.cc" /> 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 <Unit filename="src/session/set.cc" /> 75 <Unit filename="src/session/set.cc" />
73 <Unit filename="src/testprogram/testprogram.cc" /> 76 <Unit filename="src/testprogram/testprogram.cc" />
74 <Extensions> 77 <Extensions>
client/src/core/linux/request.cc
@@ -44,60 +44,6 @@ @@ -44,60 +44,6 @@
44 44
45 namespace TN3270 { 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 IPC::Request::~Request() { 47 IPC::Request::~Request() {
102 if(msg.out) { 48 if(msg.out) {
103 dbus_message_unref(msg.out); 49 dbus_message_unref(msg.out);
@@ -253,8 +199,6 @@ @@ -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,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,12 +49,10 @@
49 return Local::getSessionInstance(); 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 Session::Session() { 56 Session::Session() {
59 } 57 }
60 58
client/src/core/windows/request.cc
@@ -44,46 +44,6 @@ @@ -44,46 +44,6 @@
44 44
45 namespace TN3270 { 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 IPC::Request::~Request() { 47 IPC::Request::~Request() {
88 48
89 delete[] ((uint8_t *) in.block); 49 delete[] ((uint8_t *) in.block);
@@ -186,6 +146,49 @@ @@ -186,6 +146,49 @@
186 return *this; 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,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,19 +170,71 @@
170 /// @brief IPC Based acess (Access an active instance of pw3270 or pw3270d) 170 /// @brief IPC Based acess (Access an active instance of pw3270 or pw3270d)
171 namespace IPC { 171 namespace IPC {
172 172
173 - TN3270_PRIVATE Session * getSessionInstance(); 173 + TN3270_PRIVATE TN3270::Session * getSessionInstance(const char *id);
174 174
175 class Session; 175 class Session;
176 176
177 /// @brief PW3270 IPC Request/Response. 177 /// @brief PW3270 IPC Request/Response.
178 class Request { 178 class Request {
179 private: 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 public: 234 public:
183 235
184 /// @brief Create a method call. 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 /// @brief Create a get/set property call. 239 /// @brief Create a get/set property call.
188 /// 240 ///
@@ -190,7 +242,7 @@ @@ -190,7 +242,7 @@
190 /// @param isSet true if this is a setProperty call. 242 /// @param isSet true if this is a setProperty call.
191 /// @param property Property name. 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 ~Request(); 247 ~Request();
196 248
client/src/session/local/private.h
@@ -113,6 +113,9 @@ @@ -113,6 +113,9 @@
113 void getProperty(const char *name, int &value) const override; 113 void getProperty(const char *name, int &value) const override;
114 void getProperty(const char *name, std::string &value) const override; 114 void getProperty(const char *name, std::string &value) const override;
115 void getProperty(const char *name, bool &value) const override; 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 std::string getVersion() const override; 119 std::string getVersion() const override;
117 std::string getRevision() const override; 120 std::string getRevision() const override;
118 std::string getLUName() const override; 121 std::string getLUName() const override;
client/src/session/local/properties.cc
@@ -111,6 +111,14 @@ @@ -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 void Local::Session::setCharSet(const char *charset) { 122 void Local::Session::setCharSet(const char *charset) {
115 Abstract::Session::setCharSet(lib3270_get_display_charset(this->hSession),charset); 123 Abstract::Session::setCharSet(lib3270_get_display_charset(this->hSession),charset);
116 } 124 }
client/src/session/remote/actions.cc
@@ -39,35 +39,153 @@ @@ -39,35 +39,153 @@
39 #include "private.h" 39 #include "private.h"
40 #include <lib3270/actions.h> 40 #include <lib3270/actions.h>
41 41
  42 +#ifndef _WIN32
  43 + #include <unistd.h>
  44 +#endif // _WIN32
  45 +
42 /*---[ Implement ]----------------------------------------------------------------------------------*/ 46 /*---[ Implement ]----------------------------------------------------------------------------------*/
43 47
44 namespace TN3270 { 48 namespace TN3270 {
45 49
46 void IPC::Session::action(const char *action_name) { 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 void IPC::Session::connect(const char *url, int seconds) { 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 void IPC::Session::disconnect() { 79 void IPC::Session::disconnect() {
  80 +
  81 + Request(*this,"disconnect")
  82 + .call();
  83 +
53 } 84 }
54 85
55 void IPC::Session::wait(unsigned short seconds) const { 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 void IPC::Session::waitForReady(time_t timeout) const { 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 void IPC::Session::waitForChange(unsigned short seconds) const { 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 void IPC::Session::pfkey(unsigned short value) { 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 void IPC::Session::pakey(unsigned short value) { 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 void IPC::Session::push(const Action action) { 187 void IPC::Session::push(const Action action) {
  188 + this->action(toCharString(action));
71 } 189 }
72 190
73 void IPC::Session::print(LIB3270_CONTENT_OPTION option) { 191 void IPC::Session::print(LIB3270_CONTENT_OPTION option) {
client/src/session/remote/get.cc
@@ -43,21 +43,70 @@ @@ -43,21 +43,70 @@
43 namespace TN3270 { 43 namespace TN3270 {
44 44
45 std::string IPC::Session::get() const { 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 std::string IPC::Session::get(int baddr, size_t len, char lf) const { 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 std::string IPC::Session::get(int row, int col, size_t sz, char lf) const { 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 ProgramMessage IPC::Session::getProgramMessage() const { 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 ConnectionState IPC::Session::getConnectionState() const { 96 ConnectionState IPC::Session::getConnectionState() const {
  97 +
  98 + int cstate;
  99 + getProperty("cstate",cstate);
  100 + return (ConnectionState) cstate;
  101 +
58 } 102 }
59 103
60 SSLState IPC::Session::getSSLState() const { 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,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 @@ @@ -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 @@ @@ -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,52 +61,12 @@
61 #ifdef _WIN32 61 #ifdef _WIN32
62 /// @brief Pipe Handle. 62 /// @brief Pipe Handle.
63 HANDLE hPipe; 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 #else 64 #else
103 - struct {  
104 - DBusMessage * in;  
105 - DBusMessage * out;  
106 - DBusMessageIter iter;  
107 65
108 - } msg;  
109 DBusConnection * conn; 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 #endif // _WIN32 71 #endif // _WIN32
112 72
@@ -126,7 +86,7 @@ @@ -126,7 +86,7 @@
126 86
127 public: 87 public:
128 88
129 - Session(); 89 + Session(const char *id);
130 virtual ~Session(); 90 virtual ~Session();
131 91
132 // Actions 92 // Actions
@@ -151,6 +111,9 @@ @@ -151,6 +111,9 @@
151 void getProperty(const char *name, int &value) const override; 111 void getProperty(const char *name, int &value) const override;
152 void getProperty(const char *name, std::string &value) const override; 112 void getProperty(const char *name, std::string &value) const override;
153 void getProperty(const char *name, bool &value) const override; 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 std::string getVersion() const override; 117 std::string getVersion() const override;
155 std::string getRevision() const override; 118 std::string getRevision() const override;
156 std::string getLUName() const override; 119 std::string getLUName() const override;
client/src/session/remote/properties.cc
@@ -46,51 +46,154 @@ @@ -46,51 +46,154 @@
46 namespace TN3270 { 46 namespace TN3270 {
47 47
48 void IPC::Session::getProperty(const char *name, int &value) const { 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 void IPC::Session::getProperty(const char *name, std::string &value) const { 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 void IPC::Session::getProperty(const char *name, bool &value) const { 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 void IPC::Session::setCharSet(const char *charset) { 98 void IPC::Session::setCharSet(const char *charset) {
58 } 99 }
59 100
60 unsigned short IPC::Session::getScreenWidth() const { 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 unsigned short IPC::Session::getScreenHeight() const { 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 unsigned short IPC::Session::getScreenLength() const { 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 void IPC::Session::setUnlockDelay(unsigned short delay) { 125 void IPC::Session::setUnlockDelay(unsigned short delay) {
  126 +
  127 + setProperty("unlock_delay", (uint32_t) delay);
  128 +
70 } 129 }
71 130
72 void IPC::Session::setCursor(unsigned short addr) { 131 void IPC::Session::setCursor(unsigned short addr) {
  132 +
  133 + setProperty("setCursorAddress", (uint32_t) addr);
  134 +
73 } 135 }
74 136
75 void IPC::Session::setCursor(unsigned short row, unsigned short col) { 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 unsigned short IPC::Session::getCursorAddress() { 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 std::string IPC::Session::getVersion() const { 161 std::string IPC::Session::getVersion() const {
  162 +
  163 + string rc;
  164 + getProperty("version",rc);
  165 + return rc;
  166 +
82 } 167 }
83 168
84 std::string IPC::Session::getRevision() const { 169 std::string IPC::Session::getRevision() const {
  170 +
  171 + string rc;
  172 + getProperty("revision",rc);
  173 + return rc;
  174 +
85 } 175 }
86 176
87 std::string IPC::Session::getLUName() const { 177 std::string IPC::Session::getLUName() const {
  178 +
  179 + string rc;
  180 + getProperty("luname",rc);
  181 + return rc;
  182 +
88 } 183 }
89 184
90 std::string IPC::Session::getHostURL() const { 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 void IPC::Session::setHostURL(const char *url) { 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,12 +43,51 @@
43 namespace TN3270 { 43 namespace TN3270 {
44 44
45 void IPC::Session::set(const std::string &str) { 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 void IPC::Session::set(int baddr, const std::string &str) { 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 void IPC::Session::set(int row, int col, const std::string &str) { 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,6 +42,9 @@
42 42
43 namespace TN3270 { 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 @@ @@ -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 @@ @@ -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,7 +96,7 @@
96 << "\tRevision: " << host.getRevision() 96 << "\tRevision: " << host.getRevision()
97 << std::endl; 97 << std::endl;
98 98
99 - host.connect(nullptr); 99 +// host.connect(nullptr);
100 100
101 cout 101 cout
102 << "Connection state is " << toCharString(host.getConnectionState()) << std::endl 102 << "Connection state is " << toCharString(host.getConnectionState()) << std::endl
@@ -110,9 +110,6 @@ @@ -110,9 +110,6 @@
110 110
111 // host.input("test@0another line"); 111 // host.input("test@0another line");
112 112
113 - //host.connect();  
114 - //if(host) {  
115 - //}  
116 113
117 } catch(const std::exception &e) { 114 } catch(const std::exception &e) {
118 115
@@ -124,7 +121,7 @@ @@ -124,7 +121,7 @@
124 121
125 int main(int argc, char **argv) { 122 int main(int argc, char **argv) {
126 123
127 - const char * session = ""; // "pw3270:a"; 124 + const char * session = "pw3270:a";
128 125
129 #pragma GCC diagnostic push 126 #pragma GCC diagnostic push
130 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" 127 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
common/src/include/lib3270/ipc.h
@@ -290,6 +290,8 @@ @@ -290,6 +290,8 @@
290 virtual void getProperty(const char *name, int &value) const = 0; 290 virtual void getProperty(const char *name, int &value) const = 0;
291 virtual void getProperty(const char *name, std::string &value) const = 0; 291 virtual void getProperty(const char *name, std::string &value) const = 0;
292 virtual void getProperty(const char *name, bool &value) const = 0; 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 virtual std::string getVersion() const = 0; 296 virtual std::string getVersion() const = 0;
295 virtual std::string getRevision() const = 0; 297 virtual std::string getRevision() const = 0;
server/src/core/linux/start.c
@@ -72,6 +72,7 @@ static void @@ -72,6 +72,7 @@ static void
72 72
73 } else { 73 } else {
74 74
  75 + g_message("%s: Invalid or unexpected method call",method_name);
75 g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Invalid or unexpected method call"); 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,11 +68,10 @@ int ipc3270_method_get_string(GObject *session, GVariant *request, GObject *resp
68 break; 68 break;
69 69
70 default: 70 default:
  71 + g_message("getstring was called with %u arguments.",(unsigned int) g_variant_n_children(request));
71 return EINVAL; 72 return EINVAL;
72 } 73 }
73 74
74 - debug("text:\n%s\n",text);  
75 -  
76 if(!text) 75 if(!text)
77 return errno; 76 return errno;
78 77
server/src/core/methods/network.c
@@ -29,15 +29,15 @@ @@ -29,15 +29,15 @@
29 29
30 #include "private.h" 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 gchar *text = NULL; 34 gchar *text = NULL;
35 g_variant_get(request, "(&s)", &text); 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,26 +29,29 @@
29 29
30 #include "private.h" 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 guint seconds = 1; 34 guint seconds = 1;
35 g_variant_get(request, "(u)", &seconds); 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 guint seconds = 1; 43 guint seconds = 1;
43 g_variant_get(request, "(u)", &seconds); 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 guint seconds = 1; 52 guint seconds = 1;
51 g_variant_get(request, "(u)", &seconds); 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 }