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:
- fixed: length was not set on request.
- showing last three status lines.

@ -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;

@ -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 ();

@ -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);
}

@ -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;
}

@ -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);

Loading…
Cancel
Save