From f45fd7c2ff18bde8adc0070841b88b63355c2910 Mon Sep 17 00:00:00 2001 From: v-zhuravlev Date: Sun, 23 Sep 2018 22:09:01 +0300 Subject: [PATCH 1/4] switched to modbus_new_tcp_pi --- README.md | 4 +--- src/modbus.c | 10 +++++++--- tests/test_00modbus_connection_string.py | 12 ++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index adc3e77..8f57b36 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,7 @@ where: for Modbus Encapsulated (RTU over TCP): IPv4 of Modbus gate, for example: `enc://192.168.1.1` - TCP port may also be redefined (from Modbus default 502) if needed: `enc://192.168.1.1:5000` - - Note: DNS names are not supported for TCP and RTU over TCP + TCP port may also be redefined (from Modbus default 502) if needed: `enc://192.168.1.1:5000` for Modbus RTU over serial: Serial connection parameters in a form of: diff --git a/src/modbus.c b/src/modbus.c index ffb2ef6..994f9b3 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -449,30 +449,34 @@ void create_modbus_context(char *con_string, modbus_t **ctx_out, int *lock_requi char host[100]; int port = MODBUS_TCP_DEFAULT_PORT; + char port_str[10]; if (strncmp(con_string, "enc://", strlen("enc://")) == 0) { *lock_required_out = 1; con_string += strlen("enc://"); sscanf(con_string, "%99[^:]:%99d[^\n]", host, &port); + sprintf(port_str, "%d", port); *lock_key = hash(host) % NSEMS; - *ctx_out = modbus_new_rtutcp(host, port); + *ctx_out = modbus_new_rtutcp_pi(host, port_str); } else if (strncmp(con_string, "tcp://", strlen("tcp://")) == 0) { *lock_required_out = 0; con_string += strlen("tcp://"); sscanf(con_string, "%99[^:]:%99d[^\n]", host, &port); + sprintf(port_str, "%d", port); *lock_key = hash(host) % NSEMS; - *ctx_out = modbus_new_tcp(host, port); + *ctx_out = modbus_new_tcp_pi(host, port_str); } else { // try Modbus TCP *lock_required_out = 0; sscanf(con_string, "%99[^:]:%99d[^\n]", host, &port); + sprintf(port_str, "%d", port); *lock_key = hash(host) % NSEMS; - *ctx_out = modbus_new_tcp(host, port); + *ctx_out = modbus_new_tcp_pi(host, port_str); } } diff --git a/tests/test_00modbus_connection_string.py b/tests/test_00modbus_connection_string.py index b42110f..e9ca1c4 100644 --- a/tests/test_00modbus_connection_string.py +++ b/tests/test_00modbus_connection_string.py @@ -6,6 +6,8 @@ class TestModbusConnectionString(object): host = "172.16.238.2:5020" host_rtutcp = "172.16.238.2:5021" + host_dns = "modbus-server:5020" + host_rtutcp_dns = "modbus-server:5021" # test enc:// (rtu over tcp) @@ -18,6 +20,16 @@ def test_modbus_tcp(self): key = "modbus_read[tcp://"+self.host+",1,1,3,uint16]" assert zabbix_get(key) == '49677' + # test enc:// (rtu over tcp) using hostname + def test_modbus_test_rtutcp_dns(self): + key = "modbus_read[enc://"+self.host_rtutcp_dns+",1,0,3,uint16]" + assert zabbix_get(key) == '49807' + + # test tcp:// (plain tcp) using hostname + def test_modbus_tcp_dns(self): + key = "modbus_read[tcp://"+self.host_dns+",1,1,3,uint16]" + assert zabbix_get(key) == '49677' + # test serial /dev/ttyS0 @pytest.mark.skip("implement this first") def test_modbus_serial(self, host): From 8399f6a2a0ffc77c7fca00bb32be6a7c4129478a Mon Sep 17 00:00:00 2001 From: v-zhuravlev Date: Mon, 24 Sep 2018 18:04:37 +0300 Subject: [PATCH 2/4] switched to myssta-patch libmodbus --- .gitmodules | 2 +- libmodbus | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2c06365..6f15961 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "libmodbus"] path = libmodbus url=https://github.com/v-zhuravlev/libmodbus - branch = v3.1.4 \ No newline at end of file + branch = myssta-patch \ No newline at end of file diff --git a/libmodbus b/libmodbus index 014c1f3..bb49530 160000 --- a/libmodbus +++ b/libmodbus @@ -1 +1 @@ -Subproject commit 014c1f35eb1ff42144995f5f150f385064091f41 +Subproject commit bb49530c91a9f17317f840d6909afd3c5a741239 From 7dd939ae3c769060bee39620a69de9f2fbfa7574 Mon Sep 17 00:00:00 2001 From: v-zhuravlev Date: Mon, 24 Sep 2018 22:12:03 +0300 Subject: [PATCH 3/4] Connection refused --- tests/test_01modbus_errors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_01modbus_errors.py b/tests/test_01modbus_errors.py index b3ceaa7..4d1df75 100644 --- a/tests/test_01modbus_errors.py +++ b/tests/test_01modbus_errors.py @@ -21,7 +21,7 @@ def test_no_IP(self, host): def test_bad_IP(self, host): """Test bad IP""" key = "modbus_read_registers[badIP,3,14,3,uint32,BE,0]" - assert zabbix_get(key) == 'ZBX_NOTSUPPORTED: Network is unreachable' + assert zabbix_get(key) == 'ZBX_NOTSUPPORTED: Connection refused' def test_no_slaveID(self, host): key = "modbus_read_registers[{HOST.CONN},,14,3,uint32,BE,0]" From b7eda07b5c41de7a4ca2e27ab3b5d5562b3b2832 Mon Sep 17 00:00:00 2001 From: v-zhuravlev Date: Mon, 24 Sep 2018 23:24:32 +0300 Subject: [PATCH 4/4] added modbus_set_slave error handling --- src/modbus.c | 7 ++++++- tests/test_01modbus_errors.py | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modbus.c b/src/modbus.c index 994f9b3..74ce28c 100644 --- a/src/modbus.c +++ b/src/modbus.c @@ -212,7 +212,12 @@ int zbx_modbus_read_registers(AGENT_REQUEST *request, AGENT_RESULT *result) modbus_free(ctx); return SYSINFO_RET_FAIL; } - modbus_set_slave(ctx, slave_id); + if (modbus_set_slave(ctx, slave_id) == -1) + { + SET_MSG_RESULT(result, strdup("Check slaveid parameter")); + modbus_free(ctx); + return SYSINFO_RET_FAIL; + } // set register to start from errno = 0; diff --git a/tests/test_01modbus_errors.py b/tests/test_01modbus_errors.py index 4d1df75..a0508ec 100644 --- a/tests/test_01modbus_errors.py +++ b/tests/test_01modbus_errors.py @@ -63,7 +63,7 @@ def test_bad_register_string(self, host): def test_bad_slaveid_integer(self, host): key = "modbus_read_registers["+host+",5000,99,3,uint32,BE,0]" - assert zabbix_get(key) == 'ZBX_NOTSUPPORTED: Illegal data address' + assert zabbix_get(key) == 'ZBX_NOTSUPPORTED: Check slaveid parameter' def test_bad_slaveid_string(self, host): key = "modbus_read_registers["+host+",bad,1,3,uint32,BE,0]" - assert zabbix_get(key) == 'ZBX_NOTSUPPORTED: Check slaveid parameter' + assert zabbix_get(key) == 'ZBX_NOTSUPPORTED: Check slaveid parameter'