adding logging window, also some better error handling

main
Steffen Pohle 1 year ago
parent aca24dc4f4
commit dce22d2542

@ -1,3 +1,6 @@
2024-08-07:
- changed: logging screen is now working.
2024-02-22: 2024-02-22:
- fixed: length was not set on request. - fixed: length was not set on request.
- showing last three status lines. - showing last three status lines.

@ -108,10 +108,35 @@ void mbcli_cb_show(GtkWidget *widget, gpointer data) {
} }
/* /*
* got some data * got some data
*/ */
gboolean mbcli_thread_cb_net(gpointer 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; NWTReqResult *res = (NWTReqResult*) data;
GtkWidget *textview = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_RawResult")); GtkWidget *textview = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_RawResult"));
GtkTextBuffer *textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); 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; float f1, f2;
char tmp[255]; char tmp[255];
printf ("%s:%d %s got some data\n", __FILE__, __LINE__, __FUNCTION__);
if (data == NULL) { 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; 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); free (res);
return FALSE; return FALSE;
}; };
@ -243,10 +263,12 @@ void displayerror (std::string error) {
* network thread callback * network thread callback
*/ */
gboolean mbcli_thread_cb_status(gpointer data) { gboolean mbcli_thread_cb_status(gpointer data) {
NWTMessage *msg = (NWTMessage *) data;
mbcli_connect_btn_sensitive (netthread.GetState() == NWT_nothing); mbcli_connect_btn_sensitive (netthread.GetState() == NWT_nothing);
if (data) { if (msg) {
log_addtext(LOG_CONNECT, (std::string)(char*)data, NULL); log_addtext(msg->type, (std::string)(char*)msg->txt, NULL);
free (data); free (msg);
} }
return FALSE; return FALSE;

@ -33,7 +33,7 @@ enum {
}; };
void displayerror (std::string error); 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_error(gpointer data);
gboolean mbcli_thread_cb_status(gpointer data); gboolean mbcli_thread_cb_status(gpointer data);
gboolean mbcli_thread_cb_net(gpointer data); gboolean mbcli_thread_cb_net(gpointer data);
gboolean mbcli_thread_cb_modbusdata(gpointer data);
int mbcli_get_FC (); int mbcli_get_FC ();

@ -6,7 +6,7 @@
extern GtkBuilder *_builder_; 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]; char timetext[255];
std::string str; std::string str;
GtkWidget *textview = GTK_WIDGET(gtk_builder_get_object (_builder_, "cli_LogText")); 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", tag_datetime = gtk_text_buffer_create_tag (textbuffer, "LogDateTime",
"foreground", "blue", "style", PANGO_WEIGHT_BOLD, "family", "Monospace", NULL); "foreground", "blue", "style", PANGO_WEIGHT_BOLD, "family", "Monospace", NULL);
tag_data = gtk_text_buffer_create_tag (textbuffer, "LogData", 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", tag_info = gtk_text_buffer_create_tag (textbuffer, "LogInfo",
"foreground", "black", "style", PANGO_WEIGHT_NORMAL, "family", "Sans", NULL); "foreground", "black", "style", PANGO_WEIGHT_NORMAL, "family", "Sans", NULL);
tag_status = gtk_text_buffer_create_tag (textbuffer, "LogStatus", 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++) { for (int i = 0; i < data->rawdatalen; i++) {
if ((i % 16) == 0) str += "\n "; if ((i % 16) == 0) str += "\n ";
else if ((i % 4) == 0 && i > 0) str += " "; else if ((i % 4) == 0 && i > 0) str += " ";
else if ((i % 2) == 0 && i > 0) str += ":";
str += to_hex8(data->rawdata[i]); 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); gtk_text_buffer_insert_with_tags_by_name(textbuffer, &start, str.c_str(), -1, "LogData", NULL);
} }

@ -135,16 +135,21 @@ int NetworkThread::SendRequestRead(int unitid, int fc, int reg, int num) {
} }
void NetworkThread::GuiSendStatustext(char *txt) { void NetworkThread::GuiSendStatustext(int type, char *txt) {
char *msg = NULL; NWTMessage *msg = NULL;
if (txt) { if (txt) {
int l = strlen (txt)+1; int l = strlen (txt)+1;
msg = (char*) malloc(l+1); msg = (NWTMessage *) malloc (sizeof (NWTMessage) + l);
memset (msg, 0x0, l+1); if (msg == NULL) {
strncpy (msg, txt, strlen (txt)); 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; int i, cnt;
uint16_t tmp; uint16_t tmp;
res->isrequest = 0;
res->fc = mbh_rq->fc; res->fc = mbh_rq->fc;
res->cnt = mbh_rq->number; res->cnt = mbh_rq->number;
res->reg = mbh_rq->offset; 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) { if (res->fc == 1 || res->fc == 2) {
for (cnt = 0, i = 9; i < len && cnt < 0x100 && cnt < mbh_rq->number; cnt++) { 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 * data must be Thread Locked already
* request information must be set already * request information must be set already
* send a copy of the data to the logging window.
*/ */
void NetworkThread::BuildAndSendReadReq(char *buffer, int size) { void NetworkThread::BuildAndSendReadReq(char *buffer, int size) {
char *pos; 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++; // with modbus tcp/ip it should always be set to 0
req_mbh.transid = 0; req_mbh.transid = 0;
pos = modbustcp_pkt_headerrq(buffer, size, &req_mbh); pos = modbustcp_pkt_headerrq(buffer, size, &req_mbh);
tcp.Write(buffer, (pos-buffer)); raw->rawdatalen = pos-buffer;
tcp.Write(buffer, raw->rawdatalen);
//
// logging information raw->issend = 1;
// raw->rawdata = (char *) malloc (raw->rawdatalen);
res->rawdatalen = pos-buffer; if (raw->rawdata == NULL) {
if ((res->rawdata = (char *) malloc(res->rawdatalen)) == NULL) { fprintf (stderr, "%s:%d %s could not allocate memory: %s\n",
fprintf (stderr, "%s:%d could not allocate memory. Error:%s\n", __FILE__, __LINE__, strerror(errno)); __FILE__, __LINE__, __FUNCTION__, strerror(errno));
exit (-1); exit (-1);
} }
memcpy (res->rawdata, buffer, res->rawdatalen); memcpy (raw->rawdata, buffer, raw->rawdatalen);
res->isrequest = 1; printf ("%s:%d %s send to log issend:%d size:%d data:%p\n", __FILE__, __LINE__, __FUNCTION__,
res->fc = req_mbh.fc; raw->issend, raw->rawdatalen, raw->rawdata);
res->reg = req_mbh.offset; gdk_threads_add_idle(mbcli_thread_cb_net, (void *) raw);
res->cnt = req_mbh.number;
gdk_threads_add_idle(mbcli_thread_cb_net, (void *) res);
}; };
@ -225,7 +228,7 @@ void NetworkThread::Thread() {
printf ("%s:%d NetworkThread::Thread Started\n", __FILE__, __LINE__); printf ("%s:%d NetworkThread::Thread Started\n", __FILE__, __LINE__);
GuiSendStatustext((char*)"connecting"); GuiSendStatustext(LOG_CONNECT, (char*)"Connecting");
Lock(); Lock();
req_mbh.fc = 0; req_mbh.fc = 0;
req_mbh.transid = 0; req_mbh.transid = 0;
@ -239,15 +242,14 @@ void NetworkThread::Thread() {
if (i < 0) { if (i < 0) {
// //
// error on connect, stop thread. // error on connect, stop thread.
GuiSendStatustext(strerror(errno)); GuiSendStatustext(LOG_ERROR, strerror(errno));
SetState(NWT_nothing); SetState(NWT_nothing);
GuiSendStatustext(NULL);
printf ("%s:%d NetworkThread::Thread Finished on connect\n", __FILE__, __LINE__); printf ("%s:%d NetworkThread::Thread Finished on connect\n", __FILE__, __LINE__);
return; return;
} }
if (i == 1) GuiSendStatustext((char*)"connected"); if (i == 1) GuiSendStatustext(LOG_CONNECT, (char*)"Connected");
// FIXME: else: still connecting need some timeout and checks. // FIXME: else: still connecting need some timeout and checks.
SetState(NWT_running); SetState(NWT_running);
@ -276,12 +278,27 @@ void NetworkThread::Thread() {
// //
// we got some data // we got some data
Lock(); Lock();
printf ("read data\n");
len = tcp.Read(buffer, BUFFER_SIZE); len = tcp.Read(buffer, BUFFER_SIZE);
if (len < 0) { if (len < 0) {
state = NWT_close; state = NWT_close;
} }
else { 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 // we could get some data, if busy reset connection
if (req_mbh.fc == 0) { if (req_mbh.fc == 0) {
@ -297,7 +314,7 @@ void NetworkThread::Thread() {
if ((pos = modbustcp_unpkt_headerres(&in_mbh, buffer, len)) == NULL) { if ((pos = modbustcp_unpkt_headerres(&in_mbh, buffer, len)) == NULL) {
printf ("%s:%d error on reading modbus header (%s)\n", __FILE__, __LINE__, strerror(errno)); printf ("%s:%d error on reading modbus header (%s)\n", __FILE__, __LINE__, strerror(errno));
errno = EPROTO; errno = EPROTO;
GuiSendStatustext(strerror(errno)); GuiSendStatustext(LOG_ERROR, strerror(errno));
} }
// //
// process data is valid // 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__, 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); 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; errno = EPROTO;
GuiSendStatustext(strerror(errno)); GuiSendStatustext(LOG_ERROR, strerror(errno));
} }
req_mbh.fc = 0; req_mbh.fc = 0;
} }
@ -331,15 +348,15 @@ void NetworkThread::Thread() {
i = GetState(); i = GetState();
switch (i) { switch (i) {
case NWT_error: case NWT_error:
GuiSendStatustext(strerror(errno)); GuiSendStatustext(LOG_ERROR, strerror(errno));
tcp.Close(); tcp.Close();
break; break;
case NWT_close: case NWT_close:
GuiSendStatustext("Connection Closed"); GuiSendStatustext(LOG_CLOSE, (char*)"Connection Closed");
tcp.Close(); tcp.Close();
break; break;
default: default:
GuiSendStatustext((char*)"Unknown Error"); GuiSendStatustext(LOG_ERROR, (char*)"Unknown Error");
tcp.Close(); tcp.Close();
break; break;
} }

@ -26,14 +26,25 @@ enum {
struct { struct {
int isrequest; // isrequest = 0 ... Response, 1 ... Request
int fc; int fc;
int reg; int reg;
int cnt; int cnt;
uint16_t data[0x100]; uint16_t data[0x100];
} typedef NWTReqResult;
struct {
int issend;
int rawdatalen; int rawdatalen;
char *rawdata; char *rawdata;
} typedef NWTReqResult; } typedef NWTRawData;
struct {
int type;
char txt[];
} typedef NWTMessage;
class NetworkThread { class NetworkThread {
private: private:
@ -51,7 +62,7 @@ private:
std::string host, port; std::string host, port;
void SetState(int s); 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 GuiSendResult(char *buffer, int len, modbustcp_rq_header *mbh_in);
void BuildAndSendReadReq(char *buffer, int size); void BuildAndSendReadReq(char *buffer, int size);

Loading…
Cancel
Save