|
|
@ -10,6 +10,7 @@
|
|
|
|
#include "config.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "client.h"
|
|
|
|
#include "client.h"
|
|
|
|
#include "nwthread.h"
|
|
|
|
#include "nwthread.h"
|
|
|
|
|
|
|
|
#include "modbus.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define BUILDER_FILE "testmodbus-client.ui"
|
|
|
|
#define BUILDER_FILE "testmodbus-client.ui"
|
|
|
|
|
|
|
|
|
|
|
@ -20,10 +21,28 @@ GtkBuilder *_builder_ = NULL; // work around for the thread situation
|
|
|
|
gboolean mbcli_thread_cb_net(gpointer data); // callback thread network data
|
|
|
|
gboolean mbcli_thread_cb_net(gpointer data); // callback thread network data
|
|
|
|
gboolean mbcli_thread_cb_error(gpointer data); // callback thread error
|
|
|
|
gboolean mbcli_thread_cb_error(gpointer data); // callback thread error
|
|
|
|
void mbcli_connect_btn_sensitive (bool enable); // enable/disable connect buttons
|
|
|
|
void mbcli_connect_btn_sensitive (bool enable); // enable/disable connect buttons
|
|
|
|
|
|
|
|
int old_refreshtime = -1;
|
|
|
|
|
|
|
|
int num_errors = 0; // error counter
|
|
|
|
|
|
|
|
int num_requests = 0; // request counter
|
|
|
|
|
|
|
|
|
|
|
|
NetworkThread netthread;
|
|
|
|
NetworkThread netthread;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string to_hex16 (int v) {
|
|
|
|
|
|
|
|
char HEX[] = "0123456789ABCDEF";
|
|
|
|
|
|
|
|
int i = v;
|
|
|
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
std::string txt = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (n = 0; n < 4; n++) {
|
|
|
|
|
|
|
|
txt = HEX[i%16]+ txt;
|
|
|
|
|
|
|
|
i = i / 16;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return txt;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main (int argc, char **argv) {
|
|
|
|
int main (int argc, char **argv) {
|
|
|
|
GtkBuilder *builder;
|
|
|
|
GtkBuilder *builder;
|
|
|
|
GObject *window;
|
|
|
|
GObject *window;
|
|
|
@ -57,6 +76,89 @@ int main (int argc, char **argv) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void mbcli_cb_show(GtkWidget *widget, gpointer data) {
|
|
|
|
|
|
|
|
GtkTextTag *tag_addr;
|
|
|
|
|
|
|
|
GtkTextTag *tag_values;
|
|
|
|
|
|
|
|
GtkTextTag *tag_head;
|
|
|
|
|
|
|
|
GtkWidget *textview = GTK_WIDGET(gtk_builder_get_object (_builder_, "cli_RawResult"));
|
|
|
|
|
|
|
|
GtkTextBuffer *textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tag_head = gtk_text_buffer_create_tag (textbuffer, "Head",
|
|
|
|
|
|
|
|
"foreground", "green", "style", PANGO_WEIGHT_HEAVY, "family", "Monospace", NULL);
|
|
|
|
|
|
|
|
tag_addr = gtk_text_buffer_create_tag (textbuffer, "Addr",
|
|
|
|
|
|
|
|
"foreground", "blue", "style", PANGO_WEIGHT_BOLD, "family", "Monospace", NULL);
|
|
|
|
|
|
|
|
tag_values = gtk_text_buffer_create_tag (textbuffer, "Data",
|
|
|
|
|
|
|
|
"foreground", "black", "style", PANGO_WEIGHT_NORMAL, "family", "Monospace", NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* got some data
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
gboolean mbcli_thread_cb_net(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));
|
|
|
|
|
|
|
|
GtkTextIter start, end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string text;
|
|
|
|
|
|
|
|
float f1, f2;
|
|
|
|
|
|
|
|
char tmp[255];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d %s got some data\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
gtk_text_buffer_get_start_iter(textbuffer, &start);
|
|
|
|
|
|
|
|
gtk_text_buffer_get_end_iter(textbuffer, &end);
|
|
|
|
|
|
|
|
gtk_text_buffer_delete(textbuffer, &start, &end);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (res->fc == 1 | res->fc == 2) {
|
|
|
|
|
|
|
|
text = "binary data";
|
|
|
|
|
|
|
|
gtk_text_buffer_get_end_iter(textbuffer, &end);
|
|
|
|
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(textbuffer, &end, text.c_str(), -1, "Addr", NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
gtk_text_buffer_get_end_iter(textbuffer, &end);
|
|
|
|
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(textbuffer, &end, " Addr RawData Integer Float Float(SW)\n", -1, "Head", NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < res->cnt; i++) {
|
|
|
|
|
|
|
|
// add addr to textbuffer
|
|
|
|
|
|
|
|
snprintf (tmp, 255, "%5d ", res->reg + i);
|
|
|
|
|
|
|
|
gtk_text_buffer_get_end_iter(textbuffer, &end);
|
|
|
|
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(textbuffer, &end, tmp, -1, "Addr", NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// add data to textbuffer
|
|
|
|
|
|
|
|
text = to_hex16((int) res->data[i]);
|
|
|
|
|
|
|
|
if ((res->reg + i)%2 == 0 && i < res->cnt-1) {
|
|
|
|
|
|
|
|
memcpy (((char*)&f1) + 0, &res->data[i], 2);
|
|
|
|
|
|
|
|
memcpy (((char*)&f1) + 2, &res->data[i+1], 2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memcpy (((char*)&f2) + 2, &res->data[i], 2);
|
|
|
|
|
|
|
|
memcpy (((char*)&f2) + 0, &res->data[i+1], 2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
snprintf (tmp, 255, " | %6d | %9.3g | %9.5g", res->data[i], f1, f2);
|
|
|
|
|
|
|
|
text = text + tmp;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
snprintf (tmp, 255, " | %6d | | ", res->data[i]);
|
|
|
|
|
|
|
|
text = text + tmp;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gtk_text_buffer_get_end_iter(textbuffer, &end);
|
|
|
|
|
|
|
|
gtk_text_buffer_insert_with_tags_by_name(textbuffer, &end, text.c_str(), -1, "Data", NULL);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gtk_text_buffer_get_end_iter(textbuffer, &end);
|
|
|
|
|
|
|
|
gtk_text_buffer_insert(textbuffer, &end, (char *) "\n", -1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GtkWidget *statusbar = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_statusbar"));
|
|
|
|
|
|
|
|
gtk_label_set_label(GTK_LABEL(statusbar), (char*)"got data");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
free (res);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* display error if somethin happened within a thread
|
|
|
|
* display error if somethin happened within a thread
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -74,6 +176,7 @@ gboolean mbcli_thread_cb_error(gpointer data) {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void displayerror (std::string error) {
|
|
|
|
void displayerror (std::string error) {
|
|
|
|
GtkWidget *dialog;
|
|
|
|
GtkWidget *dialog;
|
|
|
|
GtkWidget *window = GTK_WIDGET (gtk_builder_get_object (_builder_, "testmodbus-client"));
|
|
|
|
GtkWidget *window = GTK_WIDGET (gtk_builder_get_object (_builder_, "testmodbus-client"));
|
|
|
@ -129,3 +232,154 @@ void mbcli_cb_disconnect (GtkWidget *widget, gpointer data) {
|
|
|
|
netthread.Disconnect();
|
|
|
|
netthread.Disconnect();
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* returns the currently selected FC
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mbcli_get_FC () {
|
|
|
|
|
|
|
|
GtkWidget *FC_n[4] = { NULL, NULL, NULL, NULL };
|
|
|
|
|
|
|
|
int fc = 0, i = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FC_n[fc++] = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_FC1"));
|
|
|
|
|
|
|
|
FC_n[fc++] = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_FC2"));
|
|
|
|
|
|
|
|
FC_n[fc++] = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_FC3"));
|
|
|
|
|
|
|
|
FC_n[fc++] = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_FC4"));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0, fc = -1; i < 4; i++)
|
|
|
|
|
|
|
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(FC_n[i]))) fc = i+1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return fc;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* returns the refresh time
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mbcli_get_refreshtime() {
|
|
|
|
|
|
|
|
GtkWidget *rd_refresh = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_refreshtime"));
|
|
|
|
|
|
|
|
return atoi(gtk_entry_get_text(GTK_ENTRY(rd_refresh)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* returns the register
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mbcli_get_register() {
|
|
|
|
|
|
|
|
GtkWidget *rd_refresh = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_register"));
|
|
|
|
|
|
|
|
return atoi(gtk_entry_get_text(GTK_ENTRY(rd_refresh)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* returns the number
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mbcli_get_number() {
|
|
|
|
|
|
|
|
GtkWidget *rd_refresh = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_number"));
|
|
|
|
|
|
|
|
return atoi(gtk_entry_get_text(GTK_ENTRY(rd_refresh)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* returns the unitid
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mbcli_get_unitid() {
|
|
|
|
|
|
|
|
GtkWidget *rd_refresh = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_unitid"));
|
|
|
|
|
|
|
|
return atoi(gtk_entry_get_text(GTK_ENTRY(rd_refresh)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* returns status of the update button
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mbcli_get_update () {
|
|
|
|
|
|
|
|
GtkWidget *tb_update = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_Update"));
|
|
|
|
|
|
|
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tb_update))) return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* sets the active button
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void mbcli_set_update (int active) {
|
|
|
|
|
|
|
|
GtkWidget *tb_update = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_Update"));
|
|
|
|
|
|
|
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb_update), active);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* returns status of the dont_use_FC1516 button
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
int mbcli_get_FC1516 () {
|
|
|
|
|
|
|
|
GtkWidget *tb_update = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_dontuse_FC1516"));
|
|
|
|
|
|
|
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tb_update))) return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* toglebutton to read some data is changed.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
void mbcli_cb_updateread (GtkToggleButton *togglebutton, gpointer user_data) {
|
|
|
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mbcli_get_update()) {
|
|
|
|
|
|
|
|
num_requests = 0;
|
|
|
|
|
|
|
|
num_errors = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_timeout_add(mbcli_get_refreshtime(), mbcli_refreshtimeout, NULL);
|
|
|
|
|
|
|
|
if (mbcli_get_FC1516()) mbcli_set_update(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gboolean mbcli_refreshtimeout(gpointer data) {
|
|
|
|
|
|
|
|
int timeout = mbcli_get_refreshtime();
|
|
|
|
|
|
|
|
int update = mbcli_get_update();
|
|
|
|
|
|
|
|
int fc1516 = mbcli_get_FC1516();
|
|
|
|
|
|
|
|
int fc = mbcli_get_FC();
|
|
|
|
|
|
|
|
int reg = mbcli_get_register();
|
|
|
|
|
|
|
|
int num = mbcli_get_number();
|
|
|
|
|
|
|
|
int unitid = mbcli_get_unitid();
|
|
|
|
|
|
|
|
int state = netthread.GetState();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GtkWidget *statusbar = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_statusbar"));
|
|
|
|
|
|
|
|
GtkWidget *rate = GTK_WIDGET (gtk_builder_get_object (_builder_, "cli_rate"));
|
|
|
|
|
|
|
|
char txt[255];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf ("%s:%d %s\n", __FILE__, __LINE__, __FUNCTION__);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (state == NWT_running) {
|
|
|
|
|
|
|
|
num_requests++;
|
|
|
|
|
|
|
|
if (netthread.SendRequestRead(unitid, fc, reg, num) == 0) {
|
|
|
|
|
|
|
|
num_errors++;
|
|
|
|
|
|
|
|
gtk_label_set_label(GTK_LABEL(statusbar), "busy, another request in progress");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
gtk_label_set_label(GTK_LABEL(statusbar), "request send");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf (txt, 255, "%d / %d", num_errors, num_requests);
|
|
|
|
|
|
|
|
gtk_label_set_label(GTK_LABEL(rate), txt);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
gtk_label_set_label(GTK_LABEL(rate), "- / -");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// need to continue
|
|
|
|
|
|
|
|
if (fc1516) {
|
|
|
|
|
|
|
|
mbcli_set_update(0);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!update) return FALSE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// refresh time changed?
|
|
|
|
|
|
|
|
if (timeout != old_refreshtime) {
|
|
|
|
|
|
|
|
old_refreshtime = timeout;
|
|
|
|
|
|
|
|
g_timeout_add(timeout, mbcli_refreshtimeout, NULL);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE; // continue with timer
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|