From cd2cbbb34bfcfe8dacc75052bdaa35908b5358a3 Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Mon, 5 Aug 2024 21:59:57 +0200 Subject: [PATCH] adding logging functionality --- Makefile | 2 +- client.cc | 57 ++++++++++++------------------------- client.h | 14 +++++++-- log.cc | 68 ++++++++++++++++++++++++++++++++++++++++++++ nwthread.cc | 24 ++++++++++++++++ nwthread.h | 3 ++ testmodbus-client.ui | 4 +-- 7 files changed, 128 insertions(+), 44 deletions(-) create mode 100644 log.cc diff --git a/Makefile b/Makefile index 6ecad18..9f22315 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ VERSION = 0.1.9 -include Makefile.rules -OBJECTSCLI = client.oo tcp.oo nwthread.oo modbus.oo +OBJECTSCLI = client.oo tcp.oo nwthread.oo modbus.oo log.oo DISTNAME=testmodbus-client-$(VERSION) diff --git a/client.cc b/client.cc index 3320947..6a3d0ff 100644 --- a/client.cc +++ b/client.cc @@ -27,6 +27,19 @@ int num_requests = 0; // request counter NetworkThread netthread; +std::string to_hex8 (char v) { + char HEX[] = "0123456789ABCDEF"; + int i = v; + int n; + std::string txt = ""; + + for (n = 0; n < 2; n++) { + txt = HEX[i%16]+ txt; + i = i / 16; + } + + return txt; +} std::string to_hex16 (int v) { char HEX[] = "0123456789ABCDEF"; @@ -181,8 +194,9 @@ gboolean mbcli_thread_cb_net(gpointer data) { } - mbcli_statusline ((char*)"got data"); + log_addtext(LOG_RX, (std::string)(char*)"Got Data", (NWTReqResult *)data); + if (res->rawdata != NULL) free (res->rawdata); free (res); return FALSE; }; @@ -218,49 +232,14 @@ void displayerror (std::string error) { gtk_widget_destroy(dialog); } -/* - * display last four lines of error message - */ -#define STATUS_LEN 1024 -#define STATUS_LINES 2 -void mbcli_statusline(char *txt) { - char *oldoldtext, *oldtext; - char *p[STATUS_LINES], *l; - char newtext[STATUS_LEN]; - int i; - - for (i = 0; i < STATUS_LINES; i++) p[i] = NULL; - - GtkWidget *statusbarold = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_statusbarold")); - GtkWidget *statusbar = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_statusbar")); - oldoldtext = (char*) gtk_label_get_text(GTK_LABEL(statusbarold)); - oldtext = (char*) gtk_label_get_text(GTK_LABEL(statusbar)); - - for (l = oldoldtext; l != NULL; l = strchr(l+1, '\n')) { - for (i = 1; i < STATUS_LINES; i++) p[i-1] = p[i]; - p[STATUS_LINES-1] = l; - } - - if (p[0] != NULL) { - snprintf (newtext, STATUS_LEN, "%s\n%s", p[0]+1, oldtext); - } - else - snprintf (newtext, STATUS_LEN, "%s\n%s", oldoldtext, oldtext); - - gtk_label_set_label(GTK_LABEL(statusbarold), (char*)newtext); - gtk_label_set_label(GTK_LABEL(statusbar), (char*)txt); -} - - /* * network thread callback */ gboolean mbcli_thread_cb_status(gpointer data) { - mbcli_connect_btn_sensitive (netthread.GetState() == NWT_nothing); if (data) { - mbcli_statusline ((char*)data); + log_addtext(LOG_CONNECT, (std::string)(char*)data, NULL); free (data); } @@ -427,11 +406,11 @@ gboolean mbcli_refreshtimeout(gpointer data) { num_requests++; if (netthread.SendRequestRead(unitid, fc, reg, num) == 0) { num_errors++; - mbcli_statusline ((char*)"Busy, another request in progress. Close connection."); + log_addtext(LOG_ERROR, (std::string)(char*)"Busy, another request in progress. Close connection.", NULL); netthread.Disconnect(); } else { - mbcli_statusline ((char*)"request send"); + log_addtext(LOG_TX, (std::string)(char*)"Request Send", NULL); } } else diff --git a/client.h b/client.h index eb7efe9..c1a2255 100644 --- a/client.h +++ b/client.h @@ -15,6 +15,8 @@ #include #include +#include "nwthread.h" + #ifdef __cplusplus extern "C" { #endif @@ -22,9 +24,16 @@ extern "C" { #include "modbus.h" #define LEN_STATUSTEXT 255 +enum { + LOG_CONNECT, + LOG_TX, + LOG_RX, + LOG_CLOSE, + LOG_ERROR +}; void displayerror (std::string error); - +void log_addtext (int logtype, std::string text, NWTReqResult *data); // *********************************************************************** // @@ -34,6 +43,7 @@ gboolean mbcli_thread_cb_error(gpointer data); gboolean mbcli_thread_cb_status(gpointer data); gboolean mbcli_thread_cb_net(gpointer data); + int mbcli_get_FC (); int mbcli_get_register (); int mbcli_get_unitid (); @@ -43,8 +53,8 @@ void mbcli_set_update (int active); int mbcli_get_FC1516 (); void mbcli_readdata(); gboolean mbcli_refreshtimeout(gpointer data); -void mbcli_statusline(char *); std::string to_hex16 (int v); +std::string to_hex8 (char v); G_MODULE_EXPORT void mbcli_cb_show(GtkWidget *widget, gpointer data); G_MODULE_EXPORT void mbcli_cb_updateread (GtkToggleButton *togglebutton, gpointer user_data); diff --git a/log.cc b/log.cc new file mode 100644 index 0000000..e4566bc --- /dev/null +++ b/log.cc @@ -0,0 +1,68 @@ + +#include "config.h" +#include "client.h" +#include "nwthread.h" +#include "modbus.h" + +extern GtkBuilder *_builder_; + +void log_addtext (int logtype, std::string text, NWTReqResult *data) { + char timetext[255]; + std::string str; + GtkWidget *textview = GTK_WIDGET(gtk_builder_get_object (_builder_, "cli_LogText")); + GtkTextBuffer *textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); + GtkTextIter start, end; + GtkTextTag *tag_datetime; + GtkTextTag *tag_data; + GtkTextTag *tag_info; + GtkTextTag *tag_error; + GtkTextTag *tag_status; + time_t _tm =time(NULL); + struct tm * curtime = localtime (&_tm); + static int _once = 0; + + if (_once == 0) { + _once = 1; + tag_datetime = gtk_text_buffer_create_tag (textbuffer, "LogDateTime", + "foreground", "blue", "style", PANGO_WEIGHT_BOLD, "family", "Monospace", NULL); + tag_data = gtk_text_buffer_create_tag (textbuffer, "LogData", + "foreground", "black", "style", PANGO_WEIGHT_NORMAL, "family", "Monospace", NULL); + tag_info = gtk_text_buffer_create_tag (textbuffer, "LogInfo", + "foreground", "black", "style", PANGO_WEIGHT_NORMAL, "family", "Sans", NULL); + tag_status = gtk_text_buffer_create_tag (textbuffer, "LogStatus", + "foreground", "black", "style", PANGO_WEIGHT_BOLD, "family", "Sans", NULL); + tag_error = gtk_text_buffer_create_tag (textbuffer, "LogError", + "foreground", "red", "style", PANGO_WEIGHT_BOLD, "family", "Sans", NULL); + } + strftime (timetext, 255, "%H:%M:%S", curtime); + + // + // display data if there are any + // + if (data != NULL && data->rawdatalen > 0 && data->rawdata != NULL) { + str = ""; + for (int i = 0; i < data->rawdatalen; i++) { + if (i & 16) str += "\n "; + else if (i & 4 && i > 0) str += " "; + str += to_hex8(data->rawdata[i]); + } + gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, str.c_str(), -1, "LogData", NULL); + } + + // + // display text + // + gtk_text_buffer_get_start_iter(textbuffer, &start); + if (logtype == LOG_CONNECT) gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "LogStatus", NULL); + else if (logtype == LOG_CLOSE) gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "LogStatus", NULL); + else if (logtype == LOG_ERROR) gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "LogError", NULL); + else gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, text.c_str(), -1, "LogInfo", NULL); + + // + // add date + // + str = (std::string)"\n" + (std::string)timetext + (std::string)" "; + gtk_text_buffer_get_start_iter(textbuffer, &start); + gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, str.c_str(), -1, "LogDateTime", NULL); +}; + diff --git a/nwthread.cc b/nwthread.cc index f8c53ea..7e3c628 100644 --- a/nwthread.cc +++ b/nwthread.cc @@ -157,9 +157,16 @@ void NetworkThread::GuiSendResult(char *buffer, int len, modbustcp_rq_header *mb int i, cnt; uint16_t tmp; + res->isrequest = 0; res->fc = mbh_rq->fc; res->cnt = mbh_rq->number; res->reg = mbh_rq->offset; + if ((res->rawdata = (char*) malloc(len)) == NULL) { + fprintf (stderr, "%s:%d could not allocate memory. Error:%s\n", __FILE__, __LINE__, strerror(errno)); + exit (-1); + } + res->rawdatalen = len; + memcpy (res->rawdata, buffer, len); if (res->fc == 1 || res->fc == 2) { for (cnt = 0, i = 9; i < len && cnt < 0x100 && cnt < mbh_rq->number; cnt++) { @@ -184,11 +191,28 @@ void NetworkThread::GuiSendResult(char *buffer, int len, modbustcp_rq_header *mb */ void NetworkThread::BuildAndSendReadReq(char *buffer, int size) { char *pos; + NWTReqResult *res = (NWTReqResult*) malloc(sizeof (NWTReqResult)); + // req_mbh.transid++; // with modbus tcp/ip it should always be set to 0 req_mbh.transid = 0; pos = modbustcp_pkt_headerrq(buffer, size, &req_mbh); tcp.Write(buffer, (pos-buffer)); + + // + // logging information + // + res->rawdatalen = pos-buffer; + if ((res->rawdata = (char *) malloc(res->rawdatalen)) == NULL) { + fprintf (stderr, "%s:%d could not allocate memory. Error:%s\n", __FILE__, __LINE__, strerror(errno)); + exit (-1); + } + memcpy (res->rawdata, buffer, res->rawdatalen); + res->isrequest = 1; + res->fc = req_mbh.fc; + res->reg = req_mbh.offset; + res->cnt = req_mbh.number; + gdk_threads_add_idle(mbcli_thread_cb_net, (void *) res); }; diff --git a/nwthread.h b/nwthread.h index 782eb9d..6af58d0 100644 --- a/nwthread.h +++ b/nwthread.h @@ -26,10 +26,13 @@ enum { struct { + int isrequest; // isrequest = 0 ... Response, 1 ... Request int fc; int reg; int cnt; uint16_t data[0x100]; + int rawdatalen; + char *rawdata; } typedef NWTReqResult; class NetworkThread { diff --git a/testmodbus-client.ui b/testmodbus-client.ui index b8e29b7..b9f06ee 100644 --- a/testmodbus-client.ui +++ b/testmodbus-client.ui @@ -611,7 +611,7 @@ - + True True 4 @@ -620,7 +620,7 @@ 4 in - + True True