From dce22d254224c76ba9ce1ce521552c67033030a8 Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Wed, 7 Aug 2024 23:13:05 +0200 Subject: [PATCH] adding logging window, also some better error handling --- Changelog | 3 ++ client.cc | 40 +++++++++++++++++----- client.h | 3 +- log.cc | 7 ++-- nwthread.cc | 95 +++++++++++++++++++++++++++++++---------------------- nwthread.h | 21 +++++++++--- 6 files changed, 112 insertions(+), 57 deletions(-) diff --git a/Changelog b/Changelog index 5235c70..baf60f5 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,6 @@ +2024-08-07: +- changed: logging screen is now working. + 2024-02-22: - fixed: length was not set on request. - showing last three status lines. diff --git a/client.cc b/client.cc index 57bd003..bcc6ef0 100644 --- a/client.cc +++ b/client.cc @@ -108,10 +108,35 @@ void mbcli_cb_show(GtkWidget *widget, gpointer data) { } + /* * got some data */ gboolean mbcli_thread_cb_net(gpointer data) { + NWTRawData *res = (NWTRawData*) data; + + if (data == NULL) { + fprintf (stderr, "%s:%d %s data not set\n", __FILE__, __LINE__, __FUNCTION__); + return FALSE; + } + + printf ("%s:%d %s issend:%d size:%d data:%p\n", __FILE__, __LINE__, __FUNCTION__, + res->issend, res->rawdatalen, res->rawdata); + + if (res->issend) log_addtext(LOG_TX, (std::string)(char*)"TCP Send:", (NWTRawData *)data); + else log_addtext(LOG_TX, (std::string)(char*)"TCP Read:", (NWTRawData *)data); + + if (res->rawdata != NULL) free (res->rawdata); + free (res); + return FALSE; +}; + + + +/* + * got some data + */ +gboolean mbcli_thread_cb_modbusdata(gpointer data) { NWTReqResult *res = (NWTReqResult*) data; GtkWidget *textview = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_RawResult")); GtkTextBuffer *textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); @@ -122,10 +147,8 @@ gboolean mbcli_thread_cb_net(gpointer data) { float f1, f2; char tmp[255]; - printf ("%s:%d %s got some data\n", __FILE__, __LINE__, __FUNCTION__); - if (data == NULL) { - fprintf (stderr, "%s:%d data not set\n", __FILE__, __LINE__); + fprintf (stderr, "%s:%d %s data not set\n", __FILE__, __LINE__, __FUNCTION__); return FALSE; } @@ -200,9 +223,6 @@ gboolean mbcli_thread_cb_net(gpointer data) { } - log_addtext(LOG_RX, (std::string)(char*)"Got Data", (NWTReqResult *)data); - - if (res->rawdata != NULL) free (res->rawdata); free (res); return FALSE; }; @@ -243,10 +263,12 @@ void displayerror (std::string error) { * network thread callback */ gboolean mbcli_thread_cb_status(gpointer data) { + NWTMessage *msg = (NWTMessage *) data; + mbcli_connect_btn_sensitive (netthread.GetState() == NWT_nothing); - if (data) { - log_addtext(LOG_CONNECT, (std::string)(char*)data, NULL); - free (data); + if (msg) { + log_addtext(msg->type, (std::string)(char*)msg->txt, NULL); + free (msg); } return FALSE; diff --git a/client.h b/client.h index d622b36..1da7d26 100644 --- a/client.h +++ b/client.h @@ -33,7 +33,7 @@ enum { }; void displayerror (std::string error); -void log_addtext (int logtype, std::string text, NWTReqResult *data); +void log_addtext (int logtype, std::string text, NWTRawData *data); // *********************************************************************** // @@ -42,6 +42,7 @@ void log_addtext (int logtype, std::string text, NWTReqResult *data); gboolean mbcli_thread_cb_error(gpointer data); gboolean mbcli_thread_cb_status(gpointer data); gboolean mbcli_thread_cb_net(gpointer data); +gboolean mbcli_thread_cb_modbusdata(gpointer data); int mbcli_get_FC (); diff --git a/log.cc b/log.cc index bb16e2c..6d73c88 100644 --- a/log.cc +++ b/log.cc @@ -6,7 +6,7 @@ extern GtkBuilder *_builder_; -void log_addtext (int logtype, std::string text, NWTReqResult *data) { +void log_addtext (int logtype, std::string text, NWTRawData *data) { char timetext[255]; std::string str; GtkWidget *textview = GTK_WIDGET(gtk_builder_get_object (_builder_, "cli_LogText")); @@ -31,7 +31,7 @@ void log_addtext (int logtype, std::string text, NWTReqResult *data) { 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); + "foreground", "grey", "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", @@ -50,9 +50,10 @@ void log_addtext (int logtype, std::string text, NWTReqResult *data) { for (int i = 0; i < data->rawdatalen; i++) { if ((i % 16) == 0) str += "\n "; else if ((i % 4) == 0 && i > 0) str += " "; + else if ((i % 2) == 0 && i > 0) str += ":"; str += to_hex8(data->rawdata[i]); } - printf ("\n%s:%d \n'%s'\n", __FILE__, __LINE__, str.c_str()); + gtk_text_buffer_get_start_iter(textbuffer, &start); gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, str.c_str(), -1, "LogData", NULL); } diff --git a/nwthread.cc b/nwthread.cc index 75e66db..a68886e 100644 --- a/nwthread.cc +++ b/nwthread.cc @@ -135,15 +135,20 @@ int NetworkThread::SendRequestRead(int unitid, int fc, int reg, int num) { } -void NetworkThread::GuiSendStatustext(char *txt) { - char *msg = NULL; +void NetworkThread::GuiSendStatustext(int type, char *txt) { + NWTMessage *msg = NULL; if (txt) { int l = strlen (txt)+1; - msg = (char*) malloc(l+1); - memset (msg, 0x0, l+1); - strncpy (msg, txt, strlen (txt)); + msg = (NWTMessage *) malloc (sizeof (NWTMessage) + l); + if (msg == NULL) { + fprintf (stderr, "%s:%d %s could not allocate memory : %s\n", + __FILE__, __LINE__, __FUNCTION__, strerror(errno)); + exit(-1); + } + msg->type = type; + memcpy (msg->txt, txt, l); + gdk_threads_add_idle(mbcli_thread_cb_status, msg); } - gdk_threads_add_idle(mbcli_thread_cb_status, msg); } @@ -157,16 +162,9 @@ 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++) { @@ -182,36 +180,41 @@ void NetworkThread::GuiSendResult(char *buffer, int len, modbustcp_rq_header *mb } } - gdk_threads_add_idle(mbcli_thread_cb_net, (void *) res); + gdk_threads_add_idle(mbcli_thread_cb_modbusdata, (void *) res); } /* * data must be Thread Locked already * request information must be set already + * send a copy of the data to the logging window. */ void NetworkThread::BuildAndSendReadReq(char *buffer, int size) { char *pos; - NWTReqResult *res = (NWTReqResult*) malloc(sizeof (NWTReqResult)); + NWTRawData *raw = (NWTRawData*) malloc(sizeof (NWTRawData)); + + if (raw == NULL) { + fprintf (stderr, "%s:%d %s could not allocate memory: %s\n", + __FILE__, __LINE__, __FUNCTION__, strerror(errno)); + exit (-1); + } // 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)); + raw->rawdatalen = pos-buffer; + tcp.Write(buffer, raw->rawdatalen); + + raw->issend = 1; + raw->rawdata = (char *) malloc (raw->rawdatalen); + if (raw->rawdata == NULL) { + fprintf (stderr, "%s:%d %s could not allocate memory: %s\n", + __FILE__, __LINE__, __FUNCTION__, 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); + memcpy (raw->rawdata, buffer, raw->rawdatalen); + printf ("%s:%d %s send to log issend:%d size:%d data:%p\n", __FILE__, __LINE__, __FUNCTION__, + raw->issend, raw->rawdatalen, raw->rawdata); + gdk_threads_add_idle(mbcli_thread_cb_net, (void *) raw); }; @@ -225,7 +228,7 @@ void NetworkThread::Thread() { printf ("%s:%d NetworkThread::Thread Started\n", __FILE__, __LINE__); - GuiSendStatustext((char*)"connecting"); + GuiSendStatustext(LOG_CONNECT, (char*)"Connecting"); Lock(); req_mbh.fc = 0; req_mbh.transid = 0; @@ -239,15 +242,14 @@ void NetworkThread::Thread() { if (i < 0) { // // error on connect, stop thread. - GuiSendStatustext(strerror(errno)); + GuiSendStatustext(LOG_ERROR, strerror(errno)); SetState(NWT_nothing); - GuiSendStatustext(NULL); printf ("%s:%d NetworkThread::Thread Finished on connect\n", __FILE__, __LINE__); return; } - if (i == 1) GuiSendStatustext((char*)"connected"); + if (i == 1) GuiSendStatustext(LOG_CONNECT, (char*)"Connected"); // FIXME: else: still connecting need some timeout and checks. SetState(NWT_running); @@ -276,12 +278,27 @@ void NetworkThread::Thread() { // // we got some data Lock(); - printf ("read data\n"); len = tcp.Read(buffer, BUFFER_SIZE); if (len < 0) { state = NWT_close; } else { + // send to logging window + NWTRawData *raw = (NWTRawData*)malloc (sizeof(NWTRawData)); + if (raw == NULL) { + fprintf (stderr, "%s:%d %s cloud not allocate memory for RAW info data\n", __FILE__, __LINE__, __FUNCTION__); + exit (-1); + } + raw->issend = 0; + raw->rawdatalen = len; + raw->rawdata = (char*) malloc (len); + if (raw->rawdata == NULL) { + fprintf (stderr, "%s:%d %s cloud not allocate memory for RAW data\n", __FILE__, __LINE__, __FUNCTION__); + exit (-1); + } + memcpy (raw->rawdata, buffer, len); + gdk_threads_add_idle(mbcli_thread_cb_net, (void *) raw); + // // we could get some data, if busy reset connection if (req_mbh.fc == 0) { @@ -297,7 +314,7 @@ void NetworkThread::Thread() { if ((pos = modbustcp_unpkt_headerres(&in_mbh, buffer, len)) == NULL) { printf ("%s:%d error on reading modbus header (%s)\n", __FILE__, __LINE__, strerror(errno)); errno = EPROTO; - GuiSendStatustext(strerror(errno)); + GuiSendStatustext(LOG_ERROR, strerror(errno)); } // // process data is valid @@ -319,7 +336,7 @@ void NetworkThread::Thread() { printf ("%s:%d incorrect data: fc: %d == %d number: %d == %d(%d) transid: %d == %d\n", __FILE__, __LINE__, in_mbh.fc, req_mbh.fc, in_mbh.number, (((req_mbh.number-1) / 8)+1), req_mbh.number, in_mbh.transid, req_mbh.transid); errno = EPROTO; - GuiSendStatustext(strerror(errno)); + GuiSendStatustext(LOG_ERROR, strerror(errno)); } req_mbh.fc = 0; } @@ -331,15 +348,15 @@ void NetworkThread::Thread() { i = GetState(); switch (i) { case NWT_error: - GuiSendStatustext(strerror(errno)); + GuiSendStatustext(LOG_ERROR, strerror(errno)); tcp.Close(); break; case NWT_close: - GuiSendStatustext("Connection Closed"); + GuiSendStatustext(LOG_CLOSE, (char*)"Connection Closed"); tcp.Close(); break; default: - GuiSendStatustext((char*)"Unknown Error"); + GuiSendStatustext(LOG_ERROR, (char*)"Unknown Error"); tcp.Close(); break; } diff --git a/nwthread.h b/nwthread.h index 6af58d0..2d09ae3 100644 --- a/nwthread.h +++ b/nwthread.h @@ -26,15 +26,26 @@ enum { struct { - int isrequest; // isrequest = 0 ... Response, 1 ... Request int fc; int reg; int cnt; - uint16_t data[0x100]; - int rawdatalen; - char *rawdata; + uint16_t data[0x100]; } typedef NWTReqResult; + +struct { + int issend; + int rawdatalen; + char *rawdata; +} typedef NWTRawData; + + +struct { + int type; + char txt[]; +} typedef NWTMessage; + + class NetworkThread { private: GMutex mutex; @@ -51,7 +62,7 @@ private: std::string host, port; void SetState(int s); - void GuiSendStatustext(char* txt); + void GuiSendStatustext(int type, char* txt); void GuiSendResult(char *buffer, int len, modbustcp_rq_header *mbh_in); void BuildAndSendReadReq(char *buffer, int size);