Commit 0753e7a88061c4573c187b5b251e8d6c6cb9df95

Authored by Perry Werneck
2 parents 59680e11 b6bfda0d
Exists in master and in 1 other branch develop

Merge branch 'develop' of https://github.com/PerryWerneck/libipc3270 into develop

client/src/core/windows/request.cc
... ... @@ -147,7 +147,16 @@
147 147 uint16_t rc = *((uint16_t *) (in.block + in.current));
148 148 in.current += sizeof(uint16_t);
149 149  
150   - // Extract argc
  150 + if(rc) {
  151 +
  152 + // It´s an error, extract message
  153 + in.block[in.used] = 0;
  154 + debug("Error was ",rc," (\"",(const char *) (in.block + in.current),"\")");
  155 + throw std::system_error(std::error_code(rc,std::system_category()),(const char *) (in.block + in.current));
  156 +
  157 + }
  158 +
  159 + // It´s not an error, extract argument count
151 160 uint16_t argc = *((uint16_t *) (in.block + in.current));
152 161 in.current += sizeof(uint16_t);
153 162  
... ...
client/src/host/pop.cc
... ... @@ -41,41 +41,17 @@
41 41 /*---[ Implement ]----------------------------------------------------------------------------------*/
42 42  
43 43 TN3270::Host & TN3270::Host::pop(int baddr, std::string &text) {
44   -
45   - this->session->waitForReady(this->timeout);
46   -
47   - if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
48   - chkResponse(ENOTCONN);
49   - }
50   -
51 44 session->pop(baddr, text);
52   -
53 45 return *this;
54 46 }
55 47  
56 48 TN3270::Host & TN3270::Host::pop(unsigned short row, unsigned short col, std::string &text) {
57   -
58   - this->session->waitForReady(this->timeout);
59   -
60   - if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
61   - chkResponse(ENOTCONN);
62   - }
63   -
64 49 session->pop(row,col,text);
65   -
66 50 return *this;
67 51 }
68 52  
69 53 TN3270::Host & TN3270::Host::pop(std::string &text) {
70   -
71   - this->session->waitForReady(this->timeout);
72   -
73   - if(this->session->getConnectionState() == TN3270::DISCONNECTED) {
74   - chkResponse(ENOTCONN);
75   - }
76   -
77 54 session->pop(text);
78   -
79 55 return *this;
80 56 }
81 57  
... ...
client/src/host/stream.cc
... ... @@ -42,7 +42,6 @@
42 42  
43 43 /// @brief Writes characters to the associated file from the put area
44 44 int TN3270::Host::sync() {
45   - this->session->waitForReady(this->timeout);
46 45 return 0;
47 46 }
48 47  
... ...
client/src/host/string.cc
... ... @@ -41,52 +41,32 @@
41 41 /*---[ Implement ]----------------------------------------------------------------------------------*/
42 42  
43 43 std::string TN3270::Host::toString() const {
44   -
45   - this->session->waitForReady(this->timeout);
46 44 return this->session->toString();
47 45 }
48 46  
49 47 std::string TN3270::Host::toString(int baddr, int len, char lf) const {
50   -
51   - this->session->waitForReady(this->timeout);
52 48 return this->session->toString(baddr,len,lf);
53   -
54 49 }
55 50  
56 51 std::string TN3270::Host::toString(unsigned short row, unsigned short col, int len, char lf) const {
57   -
58   - this->session->waitForReady(this->timeout);
59 52 return this->session->toString(row,col,len,lf);
60   -
61 53 }
62 54  
63 55 /// @brief Checks if the terminal contains the string.
64 56 size_t TN3270::Host::find(const char * str, size_t pos) const {
65   -
66   - this->session->waitForReady(this->timeout);
67 57 return this->session->find(str,pos);
68   -
69 58 }
70 59  
71 60 /// @brief Get the number of occurrences of a string in the terminal.
72 61 size_t TN3270::Host::count(const char * str, size_t pos) const {
73   -
74   - this->session->waitForReady(this->timeout);
75 62 return this->session->count(str,pos);
76   -
77 63 }
78 64  
79 65 /// @brief Compare contents.
80 66 int TN3270::Host::compare(int baddr, const char* s, int len) const {
81   -
82   - this->session->waitForReady(this->timeout);
83 67 return this->session->compare(baddr, s, len);
84   -
85 68 }
86 69  
87 70 int TN3270::Host::compare(unsigned short row, unsigned short col, const char* s, int len) const {
88   -
89   - this->session->waitForReady(this->timeout);
90 71 return this->session->compare(row,col,s,len);
91   -
92 72 }
... ...
client/src/include/lib3270/ipc.h
... ... @@ -600,6 +600,9 @@
600 600 /// @brief Wait until session state changes to "ready".
601 601 virtual void waitForReady(time_t timeout = DEFAULT_TIMEOUT) const = 0;
602 602  
  603 + /// @brief Wait for connection state.
  604 + virtual void waitForConnectionState(ConnectionState state, time_t timeout = DEFAULT_TIMEOUT) const = 0;
  605 +
603 606 /// @brief Wait for screen changes.
604 607 virtual void waitForChange(time_t seconds = DEFAULT_TIMEOUT) const = 0;
605 608  
... ... @@ -663,17 +666,6 @@
663 666 /// @brief Writes characters to the associated output sequence from the put area.
664 667 int overflow(int c) override;
665 668  
666   - /*
667   - /// @brief Write information to log file.
668   - void info(const char *fmt, ...) const;
669   -
670   - /// @brief Write warning to log file.
671   - void warning(const char *fmt, ...) const;
672   -
673   - /// @brief Write error to log file.
674   - void error(const char *fmt, ...) const;
675   - */
676   -
677 669 public:
678 670 Host(const char *id, const char *charset = nullptr);
679 671  
... ... @@ -733,6 +725,15 @@
733 725 return this->session->waitForKeyboardUnlock(timeout);
734 726 }
735 727  
  728 + /// @brief Wait for connection state.
  729 + inline void waitForConnectionState(ConnectionState state, time_t timeout = DEFAULT_TIMEOUT) {
  730 + return this->session->waitForConnectionState(state,timeout);
  731 + }
  732 +
  733 + inline void wait(ConnectionState state, time_t timeout = DEFAULT_TIMEOUT) {
  734 + return this->session->waitForConnectionState(state,timeout);
  735 + }
  736 +
736 737 /// @brief Execute action by name.
737 738 inline Host & action(const char *action_name) {
738 739 session->action(action_name);
... ...
client/src/session/local/private.h
... ... @@ -122,6 +122,7 @@
122 122  
123 123 void wait(time_t seconds) const override;
124 124 void waitForReady(time_t timeout) const override;
  125 + void waitForConnectionState(ConnectionState state, time_t timeout) const override;
125 126 void waitForChange(time_t timeout) const override;
126 127  
127 128 LIB3270_KEYBOARD_LOCK_STATE waitForKeyboardUnlock(time_t seconds) const override;
... ...
client/src/session/local/wait.cc
... ... @@ -56,6 +56,12 @@
56 56 chkResponse(lib3270_wait_for_ready(this->hSession, timeout));
57 57 }
58 58  
  59 + void Local::Session::waitForConnectionState(ConnectionState state, time_t timeout) const {
  60 +
  61 + std::lock_guard<std::mutex> lock(const_cast<Local::Session *>(this)->sync);
  62 + chkResponse(lib3270_wait_for_cstate(this->hSession, (LIB3270_CSTATE) state, timeout));
  63 + }
  64 +
59 65 LIB3270_KEYBOARD_LOCK_STATE Local::Session::waitForKeyboardUnlock(time_t timeout) const {
60 66  
61 67 std::lock_guard<std::mutex> lock(const_cast<Local::Session *>(this)->sync);
... ...
client/src/session/remote/actions.cc
... ... @@ -102,7 +102,7 @@
102 102 .call();
103 103  
104 104 if(seconds)
105   - this->waitForReady(seconds);
  105 + this->waitForConnectionState(CONNECTED_TN3270E,seconds);
106 106  
107 107 }
108 108  
... ...
client/src/session/remote/private.h
... ... @@ -121,6 +121,7 @@
121 121  
122 122 void wait(time_t seconds) const override;
123 123 void waitForReady(time_t timeout) const override;
  124 + void waitForConnectionState(ConnectionState state, time_t timeout) const override;
124 125 void waitForChange(time_t timeout) const override;
125 126  
126 127 LIB3270_KEYBOARD_LOCK_STATE waitForKeyboardUnlock(time_t seconds) const override;
... ...
client/src/session/remote/wait.cc
... ... @@ -113,6 +113,30 @@
113 113  
114 114 }
115 115  
  116 + void IPC::Session::waitForConnectionState(ConnectionState state, time_t timeout) const {
  117 +
  118 + debug(__FUNCTION__,"(",timeout,")");
  119 +
  120 + wait(timeout, [this,state]() {
  121 +
  122 + int rc;
  123 +
  124 + debug("Running waitForConnectionState request...");
  125 +
  126 + Request(*this,"waitForConnectionState")
  127 + .push((uint32_t) state)
  128 + .push((uint32_t) 1)
  129 + .call()
  130 + .pop(rc);
  131 +
  132 + debug("Wait for connection state returned ",rc);
  133 +
  134 + return rc;
  135 +
  136 + });
  137 +
  138 + }
  139 +
116 140 LIB3270_KEYBOARD_LOCK_STATE IPC::Session::waitForKeyboardUnlock(time_t timeout) const {
117 141  
118 142 int rc;
... ...
client/src/testprogram/testprogram.cc
... ... @@ -170,15 +170,13 @@
170 170  
171 171 TN3270::Host host{session};
172 172  
173   - host.connect();
  173 + // host.connect();
174 174  
175   - cout << "------------------------------" << endl;
176   - auto start = time(nullptr);
177   - host.waitForReady(5);
178   - cout << "Time: " << (time(nullptr) - start) << std::endl;
179   - cout << "------------------------------" << endl;
  175 + cout << endl << "------------------------" << endl;
  176 + host.toString(14,1,75,0);
  177 + cout << endl << "------------------------" << endl;
180 178  
181   - host.disconnect();
  179 + // host.disconnect();
182 180  
183 181 /*
184 182 cout
... ... @@ -265,8 +263,8 @@
265 263  
266 264 cout << "Session: " << session << endl;
267 265  
268   - // testHost(session);
269   - testPerformance(session);
  266 + testHost(session);
  267 + // testPerformance(session);
270 268  
271 269  
272 270 //testAttributes(session);
... ...
server/src/core/linux/gobject.c
... ... @@ -171,6 +171,11 @@ void ipc3270_add_terminal_introspection(GString *introspection) {
171 171 " <arg type='u' name='seconds' direction='in' />" \
172 172 " <arg type='i' name='result' direction='out' />" \
173 173 " </method>" \
  174 + " <method name= 'waitForConnectionState'>" \
  175 + " <arg type='u' name='cstate' direction='in' />" \
  176 + " <arg type='u' name='seconds' direction='in' />" \
  177 + " <arg type='i' name='result' direction='out' />" \
  178 + " </method>" \
174 179 " <method name= 'waitForKeyboardUnlock'>" \
175 180 " <arg type='u' name='seconds' direction='in' />" \
176 181 " <arg type='i' name='result' direction='out' />" \
... ... @@ -297,11 +302,6 @@ H3270 * ipc3270_get_session(GObject *object) {
297 302 return IPC3270(object)->hSession;
298 303 }
299 304  
300   -void ipc3270_set_error(GObject *object, int errcode, GError **error) {
301   - if(error && !*error)
302   - g_set_error(error,IPC3270(object)->error_domain,errcode,"%s",strerror(errcode));
303   -}
304   -
305 305 GQuark ipc3270_get_error_domain(GObject *object) {
306 306 return IPC3270(object)->error_domain;
307 307 }
... ...
server/src/core/methods/methods.c
... ... @@ -48,6 +48,7 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
48 48  
49 49 { "wait", ipc3270_method_wait },
50 50 { "waitforready", ipc3270_method_wait_for_ready },
  51 + { "waitForConnectionState", ipc3270_method_wait_for_cstate },
51 52 { "waitforupdate", ipc3270_method_wait_for_update },
52 53 { "waitforkeyboardunlock", ipc3270_method_wait_for_keyboard_unlock },
53 54  
... ... @@ -79,7 +80,7 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
79 80 size_t ix;
80 81 H3270 * hSession = ipc3270_get_session(object);
81 82  
82   - debug("%s(%s,request=%p,response=%p)",__FUNCTION__,method_name,request,response);
  83 + debug("%s(%s,request=%p,response=%p,error=%p)",__FUNCTION__,method_name,request,response,*error);
83 84  
84 85 lib3270_write_event_trace(hSession,"Method %s called on session %c\n",method_name,lib3270_get_session_id(hSession));
85 86  
... ... @@ -87,12 +88,21 @@ int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *req
87 88  
88 89 if(!g_ascii_strcasecmp(methods[ix].name,method_name)) {
89 90  
  91 +#ifdef _DEBUG_
  92 + g_message("Calling %s",methods[ix].name);
  93 +#endif // _DEBUG_
  94 +
90 95 int rc = methods[ix].call(object,request,response,error);
91 96  
92   - debug("rc=%d",rc);
  97 + debug("rc=%d error=%p",rc,*error);
93 98  
94 99 if(rc)
  100 + {
  101 + debug("%s exits with rc=%d (%s)",methods[ix].name,rc,ipc3270_get_error_message(rc));
  102 + g_message("%s exits with rc=%d (%s)",methods[ix].name,rc,ipc3270_get_error_message(rc));
95 103 ipc3270_set_error(object,rc,error);
  104 + debug("Error Message was set to %s",(*error)->message);
  105 + }
96 106  
97 107 return 0;
98 108 }
... ...
server/src/core/methods/private.h
... ... @@ -52,6 +52,7 @@
52 52  
53 53 G_GNUC_INTERNAL int ipc3270_method_wait(GObject *session, GVariant *request, GObject *response, GError **error);
54 54 G_GNUC_INTERNAL int ipc3270_method_wait_for_ready(GObject *session, GVariant *request, GObject *response, GError **error);
  55 + G_GNUC_INTERNAL int ipc3270_method_wait_for_cstate(GObject *session, GVariant *request, GObject *response, GError **error);
55 56 G_GNUC_INTERNAL int ipc3270_method_wait_for_update(GObject *session, GVariant *request, GObject *response, GError **error);
56 57 G_GNUC_INTERNAL int ipc3270_method_wait_for_keyboard_unlock(GObject *session, GVariant *request, GObject *response, GError **error);
57 58  
... ...
server/src/core/methods/wait.c
... ... @@ -116,6 +116,15 @@ int ipc3270_method_wait_for_ready(GObject *session, GVariant *request, GObject *
116 116 return 0;
117 117 }
118 118  
  119 +int ipc3270_method_wait_for_cstate(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) {
  120 + guint seconds = 1;
  121 + guint cstate = 0;
  122 + g_variant_get(request, "(uu)", &cstate, &seconds);
  123 + debug("cstate=%u seconds=%u",cstate,seconds);
  124 + ipc3270_response_append_int32(response,lib3270_wait_for_cstate(ipc3270_get_session(session),(LIB3270_CSTATE) cstate, seconds));
  125 + return 0;
  126 +}
  127 +
119 128 int ipc3270_method_wait_for_update(GObject *session, GVariant *request, GObject *response, GError G_GNUC_UNUSED(**error)) {
120 129 guint seconds = 1;
121 130 g_variant_get(request, "(u)", &seconds);
... ...
server/src/core/tools.c
... ... @@ -43,3 +43,30 @@
43 43  
44 44 #endif // ! GLIB(2,44,0)
45 45  
  46 + const char * ipc3270_get_error_message(int errcode) {
  47 +
  48 + static const struct Messages {
  49 + int errcode;
  50 + const char *msg;
  51 + } messages[] = {
  52 + { ENOTCONN, "Not connected to host" }
  53 + };
  54 +
  55 + size_t ix;
  56 +
  57 + for(ix = 0; ix < G_N_ELEMENTS(messages); ix++) {
  58 + if(messages[ix].errcode == errcode) {
  59 + return messages[ix].msg;
  60 + }
  61 + }
  62 +
  63 + return strerror(errcode);
  64 +}
  65 +
  66 +void ipc3270_set_error(GObject *object, int errcode, GError **error) {
  67 + if(error && !*error) {
  68 + g_set_error(error,ipc3270_get_error_domain(object),errcode,"%s",ipc3270_get_error_message(errcode));
  69 + }
  70 +}
  71 +
  72 +
... ...
server/src/core/windows/gobject.c
... ... @@ -112,10 +112,6 @@ H3270 * ipc3270_get_session(GObject *object) {
112 112 return IPC3270(object)->hSession;
113 113 }
114 114  
115   -void ipc3270_set_error(GObject *object, int errcode, GError **error) {
116   - g_set_error(error,IPC3270(object)->error_domain,errcode,"%s",strerror(errcode));
117   -}
118   -
119 115 GQuark ipc3270_get_error_domain(GObject *object) {
120 116 return IPC3270(object)->error_domain;
121 117 }
... ...
server/src/core/windows/inout.c
... ... @@ -46,7 +46,7 @@ unsigned char * ipc3270_pack_error(const GError *error, size_t * szPacket) {
46 46  
47 47 static const char * error_response = "error";
48 48  
49   - debug("%s(%d,%s)",__FUNCTION__,(int) error_response,error->message);
  49 + debug("%s(%d,%s)",__FUNCTION__,(int) error->code, (const char *) error->message);
50 50  
51 51 *szPacket = strlen(error_response) + 1 + (sizeof(guint16) * 2) + strlen(error->message);
52 52  
... ...
server/src/core/windows/pipesource.c
... ... @@ -110,6 +110,8 @@ static void process_input(IPC3270_PIPE_SOURCE *source, DWORD cbRead) {
110 110 g_autoptr (GVariant) response = NULL;
111 111 g_autoptr (GVariant) parameters = ipc3270_unpack(source->buffer, &request_type);
112 112  
  113 + debug("************ error=%p",error);
  114 +
113 115 if(parameters) {
114 116  
115 117 // Process query
... ... @@ -129,9 +131,12 @@ static void process_input(IPC3270_PIPE_SOURCE *source, DWORD cbRead) {
129 131  
130 132 debug("Parameters: %p", parameters);
131 133 debug("rsp: %p", rsp);
  134 + debug("Error=%p",error);
132 135  
133 136 ipc3270_method_call(source->object, request_name, parameters, rsp, &error);
134 137  
  138 + debug("Error=%p",error);
  139 +
135 140 if(ipc3270_response_has_values(rsp))
136 141 response = ipc3270_response_steal_value(rsp);
137 142  
... ...
server/src/core/windows/response.c
... ... @@ -93,6 +93,8 @@ GObject * ipc3270_response_new() {
93 93  
94 94 void ipc3270_response_append_int32(GObject *object, gint32 value) {
95 95  
  96 + debug("%s(%d)",__FUNCTION__,value);
  97 +
96 98 ipc3270Response * response = IPC3270_RESPONSE(object);
97 99  
98 100 if(response->value)
... ...
server/src/include/ipc-glib.h
... ... @@ -139,6 +139,7 @@
139 139 GQuark ipc3270_get_error_domain(GObject *object);
140 140  
141 141 void ipc3270_set_error(GObject *object, int errcode, GError **error);
  142 + const char * ipc3270_get_error_message(int errcode);
142 143  
143 144 int ipc3270_method_call(GObject *object, const gchar *method_name, GVariant *request, GObject *response, GError **error);
144 145 gboolean ipc3270_set_property(GObject *object, const gchar *property_name, GVariant *value, GError **error);
... ...
server/src/testprogram/testprogram.c
... ... @@ -213,7 +213,7 @@
213 213 if(url) {
214 214  
215 215 v3270_set_url(terminal,url);
216   - v3270_reconnect(terminal);
  216 + //v3270_reconnect(terminal);
217 217  
218 218 gchar * title = g_strdup_printf("%s - %s", v3270_get_session_name(terminal), url);
219 219 gtk_window_set_title(GTK_WINDOW(window), title);
... ...