From 3593d5ad5408fb14607e9ad59f3f6f860c755f37 Mon Sep 17 00:00:00 2001 From: Stéphane Raimbault Date: Tue, 20 Jul 2010 19:42:18 +0200 Subject: [PATCH] Rename slave to server and master to client --- .gitignore | 14 +++++++------- tests/Makefile.am | 42 +++++++++++++++++++++--------------------- tests/README | 32 ++++++++++++++++---------------- tests/bandwidth-client.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/bandwidth-master.c | 155 ----------------------------------------------------------------------------------------------------------------------------------------------------------- tests/bandwidth-server-many-up.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/bandwidth-server-one.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/bandwidth-slave-many-up.c | 134 -------------------------------------------------------------------------------------------------------------------------------------- tests/bandwidth-slave-one.c | 66 ------------------------------------------------------------------ tests/random-test-client.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/random-test-master.c | 212 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- tests/random-test-server.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/random-test-slave.c | 66 ------------------------------------------------------------------ tests/unit-test-client.c | 526 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/unit-test-master.c | 526 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- tests/unit-test-server.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/unit-test-slave.c | 100 ---------------------------------------------------------------------------------------------------- 17 files changed, 1303 insertions(+), 1303 deletions(-) create mode 100644 tests/bandwidth-client.c delete mode 100644 tests/bandwidth-master.c create mode 100644 tests/bandwidth-server-many-up.c create mode 100644 tests/bandwidth-server-one.c delete mode 100644 tests/bandwidth-slave-many-up.c delete mode 100644 tests/bandwidth-slave-one.c create mode 100644 tests/random-test-client.c delete mode 100644 tests/random-test-master.c create mode 100644 tests/random-test-server.c delete mode 100644 tests/random-test-slave.c create mode 100644 tests/unit-test-client.c delete mode 100644 tests/unit-test-master.c create mode 100644 tests/unit-test-server.c delete mode 100644 tests/unit-test-slave.c diff --git a/.gitignore b/.gitignore index 59caf29..081bddb 100644 --- a/.gitignore +++ b/.gitignore @@ -27,11 +27,11 @@ modbus.h *.lo stamp-h1 *.o -tests/bandwidth-master -tests/bandwidth-slave-many-up -tests/bandwidth-slave-one -tests/random-test-master -tests/random-test-slave -tests/unit-test-master -tests/unit-test-slave +tests/bandwidth-client +tests/bandwidth-server-many-up +tests/bandwidth-server-one +tests/random-test-client +tests/random-test-server +tests/unit-test-client +tests/unit-test-server tests/version diff --git a/tests/Makefile.am b/tests/Makefile.am index 98e190e..77f46e7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,38 +1,38 @@ EXTRA_DIST = README noinst_PROGRAMS = \ - random-test-slave \ - random-test-master \ - unit-test-slave \ - unit-test-master \ - bandwidth-slave-one \ - bandwidth-slave-many-up \ - bandwidth-master \ + random-test-server \ + random-test-client \ + unit-test-server \ + unit-test-client \ + bandwidth-server-one \ + bandwidth-server-many-up \ + bandwidth-client \ version common_ldflags = \ $(top_builddir)/src/libmodbus.la -random_test_slave_SOURCES = random-test-slave.c -random_test_slave_LDADD = $(common_ldflags) +random_test_server_SOURCES = random-test-server.c +random_test_server_LDADD = $(common_ldflags) -random_test_master_SOURCES = random-test-master.c -random_test_master_LDADD = $(common_ldflags) +random_test_client_SOURCES = random-test-client.c +random_test_client_LDADD = $(common_ldflags) -unit_test_slave_SOURCES = unit-test-slave.c unit-test.h -unit_test_slave_LDADD = $(common_ldflags) +unit_test_server_SOURCES = unit-test-server.c unit-test.h +unit_test_server_LDADD = $(common_ldflags) -unit_test_master_SOURCES = unit-test-master.c unit-test.h -unit_test_master_LDADD = $(common_ldflags) +unit_test_client_SOURCES = unit-test-client.c unit-test.h +unit_test_client_LDADD = $(common_ldflags) -bandwidth_slave_one_SOURCES = bandwidth-slave-one.c -bandwidth_slave_one_LDADD = $(common_ldflags) +bandwidth_server_one_SOURCES = bandwidth-server-one.c +bandwidth_server_one_LDADD = $(common_ldflags) -bandwidth_slave_many_up_SOURCES = bandwidth-slave-many-up.c -bandwidth_slave_many_up_LDADD = $(common_ldflags) +bandwidth_server_many_up_SOURCES = bandwidth-server-many-up.c +bandwidth_server_many_up_LDADD = $(common_ldflags) -bandwidth_master_SOURCES = bandwidth-master.c -bandwidth_master_LDADD = $(common_ldflags) +bandwidth_client_SOURCES = bandwidth-client.c +bandwidth_client_LDADD = $(common_ldflags) version_SOURCES = version.c version_LDADD = $(common_ldflags) diff --git a/tests/README b/tests/README index 9a71bc4..f530c8a 100644 --- a/tests/README +++ b/tests/README @@ -2,37 +2,37 @@ Compilation ----------- After installation, you can use pkg-config to compile these tests. -For example, to compile random-test-slave run: +For example, to compile random-test-server run: -gcc random-test-slave.c -o random-test-slave `pkg-config --libs --cflags libmodbus` +gcc random-test-server.c -o random-test-server `pkg-config --libs --cflags libmodbus` -random-test-slave +random-test-server ----------------- -It's necessary to launch this server before run random-test-master. By +It's necessary to launch this server before run random-test-client. By default, it receives and responses to Modbus query on the localhost and port 1502. -random-test-master +random-test-client ------------------ This programm sends many different queries to a large range of -addresses and values to test the communication between the master and -the slave. +addresses and values to test the communication between the client and +the server. -unit-test-slave -unit-test-master +unit-test-server +unit-test-client ---------------- By default, this program sends some queries with the values defined in unit-test.h and checks the responses. These programs are useful to test the protocol implementation. -bandwidth-slave-one -bandwidth-slave-many-up -bandwidth-master +bandwidth-server-one +bandwidth-server-many-up +bandwidth-client ----------------------- It returns some very useful informations about the performance of -transfert rate between the slave and the master. +transfert rate between the server and the client. -- bandwidth-slave-one: it can handles only one connection with a master. -- bandwidth-slave-many-up: it opens a connection each time a new master asks - for, but the number of connection is limited. The same slave process handles +- bandwidth-server-one: it can handles only one connection with a client. +- bandwidth-server-many-up: it opens a connection each time a new client asks + for, but the number of connection is limited. The same server process handles all the connections. diff --git a/tests/bandwidth-client.c b/tests/bandwidth-client.c new file mode 100644 index 0000000..f1216e2 --- /dev/null +++ b/tests/bandwidth-client.c @@ -0,0 +1,155 @@ +/* + * Copyright © 2008-2010 Stéphane Raimbault + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Tests based on PI-MBUS-300 documentation */ +#define NB_LOOPS 100000 + +#define G_MSEC_PER_SEC 1000 + +uint32_t gettime_ms(void) +{ + struct timeval tv; + gettimeofday (&tv, NULL); + + return (uint32_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +int main(void) +{ + uint8_t *tab_bit; + uint16_t *tab_reg; + modbus_t *ctx; + int i; + int nb_points; + double elapsed; + uint32_t start; + uint32_t end; + uint32_t bytes; + uint32_t rate; + int rc; + + /* TCP */ + ctx = modbus_new_tcp("127.0.0.1", 1502); + if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connexion failed: %s\n", + modbus_strerror(errno)); + modbus_free(ctx); + return -1; + } + + /* Allocate and initialize the memory to store the status */ + tab_bit = (uint8_t *) malloc(MODBUS_MAX_BITS * sizeof(uint8_t)); + memset(tab_bit, 0, MODBUS_MAX_BITS * sizeof(uint8_t)); + + /* Allocate and initialize the memory to store the registers */ + tab_reg = (uint16_t *) malloc(MODBUS_MAX_REGISTERS * sizeof(uint16_t)); + memset(tab_reg, 0, MODBUS_MAX_REGISTERS * sizeof(uint16_t)); + + printf("READ BITS\n\n"); + + nb_points = MODBUS_MAX_BITS; + start = gettime_ms(); + for (i=0; i - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Tests based on PI-MBUS-300 documentation */ -#define NB_LOOPS 100000 - -#define G_MSEC_PER_SEC 1000 - -uint32_t gettime_ms(void) -{ - struct timeval tv; - gettimeofday (&tv, NULL); - - return (uint32_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; -} - -int main(void) -{ - uint8_t *tab_bit; - uint16_t *tab_reg; - modbus_t *ctx; - int i; - int nb_points; - double elapsed; - uint32_t start; - uint32_t end; - uint32_t bytes; - uint32_t rate; - int rc; - - /* TCP */ - ctx = modbus_new_tcp("127.0.0.1", 1502); - if (modbus_connect(ctx) == -1) { - fprintf(stderr, "Connexion failed: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; - } - - /* Allocate and initialize the memory to store the status */ - tab_bit = (uint8_t *) malloc(MODBUS_MAX_BITS * sizeof(uint8_t)); - memset(tab_bit, 0, MODBUS_MAX_BITS * sizeof(uint8_t)); - - /* Allocate and initialize the memory to store the registers */ - tab_reg = (uint16_t *) malloc(MODBUS_MAX_REGISTERS * sizeof(uint16_t)); - memset(tab_reg, 0, MODBUS_MAX_REGISTERS * sizeof(uint16_t)); - - printf("READ BITS\n\n"); - - nb_points = MODBUS_MAX_BITS; - start = gettime_ms(); - for (i=0; i + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define NB_CONNECTION 5 + +modbus_t *ctx = NULL; +int server_socket; +modbus_mapping_t *mb_mapping; + +static void close_sigint(int dummy) +{ + close(server_socket); + modbus_free(ctx); + modbus_mapping_free(mb_mapping); + + exit(dummy); +} + +int main(void) +{ + int master_socket; + int rc; + fd_set refset; + fd_set rdset; + + /* Maximum file descriptor number */ + int fdmax; + + ctx = modbus_new_tcp("127.0.0.1", 1502); + + mb_mapping = modbus_mapping_new(MODBUS_MAX_BITS, 0, + MODBUS_MAX_REGISTERS, 0); + if (mb_mapping == NULL) { + fprintf(stderr, "Failed to allocate the mapping: %s\n", + modbus_strerror(errno)); + modbus_free(ctx); + return -1; + } + + server_socket = modbus_listen(ctx, NB_CONNECTION); + + signal(SIGINT, close_sigint); + + /* Clear the reference set of socket */ + FD_ZERO(&refset); + /* Add the server socket */ + FD_SET(server_socket, &refset); + + /* Keep track of the max file descriptor */ + fdmax = server_socket; + + for (;;) { + rdset = refset; + if (select(fdmax+1, &rdset, NULL, NULL, NULL) == -1) { + perror("Server select() failure."); + close_sigint(1); + } + + /* Run through the existing connections looking for data to be + * read */ + for (master_socket = 0; master_socket <= fdmax; master_socket++) { + + if (FD_ISSET(master_socket, &rdset)) { + if (master_socket == server_socket) { + /* A client is asking a new connection */ + socklen_t addrlen; + struct sockaddr_in clientaddr; + int newfd; + + /* Handle new connections */ + addrlen = sizeof(clientaddr); + memset(&clientaddr, 0, sizeof(clientaddr)); + newfd = accept(server_socket, (struct sockaddr *)&clientaddr, &addrlen); + if (newfd == -1) { + perror("Server accept() error"); + } else { + FD_SET(newfd, &refset); + + if (newfd > fdmax) { + /* Keep track of the maximum */ + fdmax = newfd; + } + printf("New connection from %s:%d on socket %d\n", + inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, newfd); + } + } else { + /* An already connected master has sent a new query */ + uint8_t query[MODBUS_MAX_ADU_LENGTH_TCP]; + + rc = modbus_receive(ctx, master_socket, query); + if (rc != -1) { + modbus_reply(ctx, query, rc, mb_mapping); + } else { + /* Connection closed by the client, end of server */ + printf("Connection closed on socket %d\n", master_socket); + close(master_socket); + + /* Remove from reference set */ + FD_CLR(master_socket, &refset); + + if (master_socket == fdmax) { + fdmax--; + } + } + } + } + } + } + + return 0; +} diff --git a/tests/bandwidth-server-one.c b/tests/bandwidth-server-one.c new file mode 100644 index 0000000..7dad899 --- /dev/null +++ b/tests/bandwidth-server-one.c @@ -0,0 +1,66 @@ +/* + * Copyright © 2008-2010 Stéphane Raimbault + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include + +int main(void) +{ + int socket; + modbus_t *ctx; + modbus_mapping_t *mb_mapping; + int rc; + + ctx = modbus_new_tcp("127.0.0.1", 1502); + + mb_mapping = modbus_mapping_new(MODBUS_MAX_BITS, 0, + MODBUS_MAX_REGISTERS, 0); + if (mb_mapping == NULL) { + fprintf(stderr, "Failed to allocate the mapping: %s\n", + modbus_strerror(errno)); + modbus_free(ctx); + return -1; + } + + socket = modbus_listen(ctx, 1); + modbus_accept(ctx, &socket); + + for(;;) { + uint8_t query[MODBUS_MAX_ADU_LENGTH_TCP]; + + rc = modbus_receive(ctx, -1, query); + if (rc >= 0) { + modbus_reply(ctx, query, rc, mb_mapping); + } else { + /* Connection closed by the client or server */ + break; + } + } + + printf("Quit the loop: %s\n", modbus_strerror(errno)); + + modbus_mapping_free(mb_mapping); + close(socket); + modbus_free(ctx); + + return 0; +} diff --git a/tests/bandwidth-slave-many-up.c b/tests/bandwidth-slave-many-up.c deleted file mode 100644 index 4fb3860..0000000 --- a/tests/bandwidth-slave-many-up.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright © 2009-2010 Stéphane Raimbault - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include - -#define NB_CONNECTION 5 - -modbus_t *ctx = NULL; -int slave_socket; -modbus_mapping_t *mb_mapping; - -static void close_sigint(int dummy) -{ - close(slave_socket); - modbus_free(ctx); - modbus_mapping_free(mb_mapping); - - exit(dummy); -} - -int main(void) -{ - int master_socket; - int rc; - fd_set refset; - fd_set rdset; - - /* Maximum file descriptor number */ - int fdmax; - - ctx = modbus_new_tcp("127.0.0.1", 1502); - - mb_mapping = modbus_mapping_new(MODBUS_MAX_BITS, 0, - MODBUS_MAX_REGISTERS, 0); - if (mb_mapping == NULL) { - fprintf(stderr, "Failed to allocate the mapping: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; - } - - slave_socket = modbus_listen(ctx, NB_CONNECTION); - - signal(SIGINT, close_sigint); - - /* Clear the reference set of socket */ - FD_ZERO(&refset); - /* Add the slave socket */ - FD_SET(slave_socket, &refset); - - /* Keep track of the max file descriptor */ - fdmax = slave_socket; - - for (;;) { - rdset = refset; - if (select(fdmax+1, &rdset, NULL, NULL, NULL) == -1) { - perror("Slave select() failure."); - close_sigint(1); - } - - /* Run through the existing connections looking for data to be - * read */ - for (master_socket = 0; master_socket <= fdmax; master_socket++) { - - if (FD_ISSET(master_socket, &rdset)) { - if (master_socket == slave_socket) { - /* A client is asking a new connection */ - socklen_t addrlen; - struct sockaddr_in clientaddr; - int newfd; - - /* Handle new connections */ - addrlen = sizeof(clientaddr); - memset(&clientaddr, 0, sizeof(clientaddr)); - newfd = accept(slave_socket, (struct sockaddr *)&clientaddr, &addrlen); - if (newfd == -1) { - perror("Server accept() error"); - } else { - FD_SET(newfd, &refset); - - if (newfd > fdmax) { - /* Keep track of the maximum */ - fdmax = newfd; - } - printf("New connection from %s:%d on socket %d\n", - inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, newfd); - } - } else { - /* An already connected master has sent a new query */ - uint8_t query[MODBUS_MAX_ADU_LENGTH_TCP]; - - rc = modbus_receive(ctx, master_socket, query); - if (rc != -1) { - modbus_reply(ctx, query, rc, mb_mapping); - } else { - /* Connection closed by the client, end of server */ - printf("Connection closed on socket %d\n", master_socket); - close(master_socket); - - /* Remove from reference set */ - FD_CLR(master_socket, &refset); - - if (master_socket == fdmax) { - fdmax--; - } - } - } - } - } - } - - return 0; -} diff --git a/tests/bandwidth-slave-one.c b/tests/bandwidth-slave-one.c deleted file mode 100644 index 7dad899..0000000 --- a/tests/bandwidth-slave-one.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright © 2008-2010 Stéphane Raimbault - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include - -#include - -int main(void) -{ - int socket; - modbus_t *ctx; - modbus_mapping_t *mb_mapping; - int rc; - - ctx = modbus_new_tcp("127.0.0.1", 1502); - - mb_mapping = modbus_mapping_new(MODBUS_MAX_BITS, 0, - MODBUS_MAX_REGISTERS, 0); - if (mb_mapping == NULL) { - fprintf(stderr, "Failed to allocate the mapping: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; - } - - socket = modbus_listen(ctx, 1); - modbus_accept(ctx, &socket); - - for(;;) { - uint8_t query[MODBUS_MAX_ADU_LENGTH_TCP]; - - rc = modbus_receive(ctx, -1, query); - if (rc >= 0) { - modbus_reply(ctx, query, rc, mb_mapping); - } else { - /* Connection closed by the client or server */ - break; - } - } - - printf("Quit the loop: %s\n", modbus_strerror(errno)); - - modbus_mapping_free(mb_mapping); - close(socket); - modbus_free(ctx); - - return 0; -} diff --git a/tests/random-test-client.c b/tests/random-test-client.c new file mode 100644 index 0000000..3b2094e --- /dev/null +++ b/tests/random-test-client.c @@ -0,0 +1,212 @@ +/* + * Copyright © 2001-2010 Stéphane Raimbault + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include + +/* The goal of this program is to check all major functions of + libmodbus: + - write_coil + - read_bits + - write_coils + - write_register + - read_registers + - write_registers + - read_registers + + All these functions are called with random values on a address + range defined by the following defines. +*/ +#define LOOP 1 +#define MY_ID 1 +#define SERVER_ID 17 +#define ADDRESS_START 0 +#define ADDRESS_END 99 + +/* At each loop, the program works in the range ADDRESS_START to + * ADDRESS_END then ADDRESS_START + 1 to ADDRESS_END and so on. + */ +int main(void) +{ + modbus_t *ctx; + int rc; + int nb_fail; + int nb_loop; + int addr; + int nb; + uint8_t *tab_rq_bits; + uint8_t *tab_rp_bits; + uint16_t *tab_rq_registers; + uint16_t *tab_rp_registers; + + /* + ctx = modbus_new_rtu("/dev/ttyS0", 19200, 'N', 8, 1, MY_ID); + modbus_set_slave(ctx, SERVER_ID); + */ + + /* TCP */ + ctx = modbus_new_tcp("127.0.0.1", 1502); + modbus_set_debug(ctx, TRUE); + if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", + modbus_strerror(errno)); + modbus_free(ctx); + return -1; + } + + /* Allocate and initialize the different memory spaces */ + nb = ADDRESS_END - ADDRESS_START; + + tab_rq_bits = (uint8_t *) malloc(nb * sizeof(uint8_t)); + memset(tab_rq_bits, 0, nb * sizeof(uint8_t)); + + tab_rp_bits = (uint8_t *) malloc(nb * sizeof(uint8_t)); + memset(tab_rp_bits, 0, nb * sizeof(uint8_t)); + + tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t)); + memset(tab_rq_registers, 0, nb * sizeof(uint16_t)); + + tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t)); + memset(tab_rp_registers, 0, nb * sizeof(uint16_t)); + + nb_loop = nb_fail = 0; + while (nb_loop++ < LOOP) { + for (addr = ADDRESS_START; addr <= ADDRESS_END; addr++) { + int i; + + /* Random numbers (short) */ + for (i=0; i - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include - -#include - -/* The goal of this program is to check all major functions of - libmodbus: - - write_coil - - read_bits - - write_coils - - write_register - - read_registers - - write_registers - - read_registers - - All these functions are called with random values on a address - range defined by the following defines. -*/ -#define LOOP 1 -#define MY_ID 1 -#define SERVER_ID 17 -#define ADDRESS_START 0 -#define ADDRESS_END 99 - -/* At each loop, the program works in the range ADDRESS_START to - * ADDRESS_END then ADDRESS_START + 1 to ADDRESS_END and so on. - */ -int main(void) -{ - modbus_t *ctx; - int rc; - int nb_fail; - int nb_loop; - int addr; - int nb; - uint8_t *tab_rq_bits; - uint8_t *tab_rp_bits; - uint16_t *tab_rq_registers; - uint16_t *tab_rp_registers; - - /* - ctx = modbus_new_rtu("/dev/ttyS0", 19200, 'N', 8, 1, MY_ID); - modbus_set_slave(ctx, SERVER_ID); - */ - - /* TCP */ - ctx = modbus_new_tcp("127.0.0.1", 1502); - modbus_set_debug(ctx, TRUE); - if (modbus_connect(ctx) == -1) { - fprintf(stderr, "Connection failed: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; - } - - /* Allocate and initialize the different memory spaces */ - nb = ADDRESS_END - ADDRESS_START; - - tab_rq_bits = (uint8_t *) malloc(nb * sizeof(uint8_t)); - memset(tab_rq_bits, 0, nb * sizeof(uint8_t)); - - tab_rp_bits = (uint8_t *) malloc(nb * sizeof(uint8_t)); - memset(tab_rp_bits, 0, nb * sizeof(uint8_t)); - - tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t)); - memset(tab_rq_registers, 0, nb * sizeof(uint16_t)); - - tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t)); - memset(tab_rp_registers, 0, nb * sizeof(uint16_t)); - - nb_loop = nb_fail = 0; - while (nb_loop++ < LOOP) { - for (addr = ADDRESS_START; addr <= ADDRESS_END; addr++) { - int i; - - /* Random numbers (short) */ - for (i=0; i + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include + +int main(void) +{ + int socket; + modbus_t *ctx; + modbus_mapping_t *mb_mapping; + + ctx = modbus_new_tcp("127.0.0.1", 1502); + /* modbus_set_debug(ctx, TRUE); */ + + mb_mapping = modbus_mapping_new(500, 500, 500, 500); + if (mb_mapping == NULL) { + fprintf(stderr, "Failed to allocate the mapping: %s\n", + modbus_strerror(errno)); + modbus_free(ctx); + return -1; + } + + socket = modbus_listen(ctx, 1); + modbus_accept(ctx, &socket); + + for (;;) { + uint8_t query[MODBUS_MAX_ADU_LENGTH_TCP]; + int rc; + + rc = modbus_receive(ctx, -1, query); + if (rc != -1) { + /* rc is the query size */ + modbus_reply(ctx, query, rc, mb_mapping); + } else { + /* Connection closed by the client or error */ + break; + } + } + + printf("Quit the loop: %s\n", modbus_strerror(errno)); + + modbus_mapping_free(mb_mapping); + modbus_close(ctx); + modbus_free(ctx); + + return 0; +} diff --git a/tests/random-test-slave.c b/tests/random-test-slave.c deleted file mode 100644 index b4c6003..0000000 --- a/tests/random-test-slave.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright © 2008-2010 Stéphane Raimbault - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include - -int main(void) -{ - int socket; - modbus_t *ctx; - modbus_mapping_t *mb_mapping; - - ctx = modbus_new_tcp("127.0.0.1", 1502); - /* modbus_set_debug(ctx, TRUE); */ - - mb_mapping = modbus_mapping_new(500, 500, 500, 500); - if (mb_mapping == NULL) { - fprintf(stderr, "Failed to allocate the mapping: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; - } - - socket = modbus_listen(ctx, 1); - modbus_accept(ctx, &socket); - - for (;;) { - uint8_t query[MODBUS_MAX_ADU_LENGTH_TCP]; - int rc; - - rc = modbus_receive(ctx, -1, query); - if (rc != -1) { - /* rc is the query size */ - modbus_reply(ctx, query, rc, mb_mapping); - } else { - /* Connection closed by the client or error */ - break; - } - } - - printf("Quit the loop: %s\n", modbus_strerror(errno)); - - modbus_mapping_free(mb_mapping); - modbus_close(ctx); - modbus_free(ctx); - - return 0; -} diff --git a/tests/unit-test-client.c b/tests/unit-test-client.c new file mode 100644 index 0000000..c016ca7 --- /dev/null +++ b/tests/unit-test-client.c @@ -0,0 +1,526 @@ +/* + * Copyright © 2008-2010 Stéphane Raimbault + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "unit-test.h" + +int main(void) +{ + uint8_t *tab_rp_bits; + uint16_t *tab_rp_registers; + uint16_t *tab_rp_registers_bad; + modbus_t *ctx; + int is_mode_rtu = FALSE; + int i; + uint8_t value; + int address; + int nb_points; + int rc; + float real; + struct timeval timeout_begin_old; + struct timeval timeout_begin_new; + + /* + ctx = modbus_new_rtu("/dev/ttyS0", 19200, 'N', 8, 1, CLIENT_ID); + modbus_set_slave(ctx, SERVER_ID); + is_mode_rtu = TRUE; + */ + + /* TCP */ + ctx = modbus_new_tcp("127.0.0.1", 1502); + modbus_set_debug(ctx, TRUE); + + if (modbus_connect(ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", + modbus_strerror(errno)); + modbus_free(ctx); + return -1; + } + + /* Allocate and initialize the memory to store the bits */ + nb_points = (UT_BITS_NB_POINTS > UT_INPUT_BITS_NB_POINTS) ? + UT_BITS_NB_POINTS : UT_INPUT_BITS_NB_POINTS; + tab_rp_bits = (uint8_t *) malloc(nb_points * sizeof(uint8_t)); + memset(tab_rp_bits, 0, nb_points * sizeof(uint8_t)); + + /* Allocate and initialize the memory to store the registers */ + nb_points = (UT_REGISTERS_NB_POINTS > + UT_INPUT_REGISTERS_NB_POINTS) ? + UT_REGISTERS_NB_POINTS : UT_INPUT_REGISTERS_NB_POINTS; + tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t)); + memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t)); + + printf("** UNIT TESTING **\n"); + + printf("\nTEST WRITE/READ:\n"); + + /** COIL BITS **/ + + /* Single */ + rc = modbus_write_bit(ctx, UT_BITS_ADDRESS, ON); + printf("1/2 modbus_write_bit: "); + if (rc == 1) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, 1, tab_rp_bits); + printf("2/2 modbus_read_bits: "); + if (rc != 1) { + printf("FAILED (nb points %d)\n", rc); + goto close; + } + + if (tab_rp_bits[0] != ON) { + printf("FAILED (%0X = != %0X)\n", tab_rp_bits[0], ON); + goto close; + } + printf("OK\n"); + /* End single */ + + /* Multiple bits */ + { + uint8_t tab_value[UT_BITS_NB_POINTS]; + + modbus_set_bits_from_bytes(tab_value, 0, UT_BITS_NB_POINTS, + UT_BITS_TAB); + rc = modbus_write_bits(ctx, UT_BITS_ADDRESS, + UT_BITS_NB_POINTS, tab_value); + printf("1/2 modbus_write_bits: "); + if (rc == UT_BITS_NB_POINTS) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + } + + rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, + UT_BITS_NB_POINTS, tab_rp_bits); + printf("2/2 modbus_read_bits: "); + if (rc != UT_BITS_NB_POINTS) { + printf("FAILED (nb points %d)\n", rc); + goto close; + } + + i = 0; + address = UT_BITS_ADDRESS; + nb_points = UT_BITS_NB_POINTS; + while (nb_points > 0) { + int nb_bits = (nb_points > 8) ? 8 : nb_points; + + value = modbus_get_byte_from_bits(tab_rp_bits, i*8, nb_bits); + if (value != UT_BITS_TAB[i]) { + printf("FAILED (%0X != %0X)\n", + value, UT_BITS_TAB[i]); + goto close; + } + + nb_points -= nb_bits; + i++; + } + printf("OK\n"); + /* End of multiple bits */ + + /** DISCRETE INPUTS **/ + rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS, + UT_INPUT_BITS_NB_POINTS, tab_rp_bits); + printf("1/1 modbus_read_input_bits: "); + + if (rc != UT_INPUT_BITS_NB_POINTS) { + printf("FAILED (nb points %d)\n", rc); + goto close; + } + + i = 0; + address = UT_INPUT_BITS_ADDRESS; + nb_points = UT_INPUT_BITS_NB_POINTS; + while (nb_points > 0) { + int nb_bits = (nb_points > 8) ? 8 : nb_points; + + value = modbus_get_byte_from_bits(tab_rp_bits, i*8, nb_bits); + if (value != UT_INPUT_BITS_TAB[i]) { + printf("FAILED (%0X != %0X)\n", + value, UT_INPUT_BITS_TAB[i]); + goto close; + } + + nb_points -= nb_bits; + i++; + } + printf("OK\n"); + + /** HOLDING REGISTERS **/ + + /* Single register */ + rc = modbus_write_register(ctx, UT_REGISTERS_ADDRESS, 0x1234); + printf("1/2 modbus_write_register: "); + if (rc == 1) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, + 1, tab_rp_registers); + printf("2/2 modbus_read_registers: "); + if (rc != 1) { + printf("FAILED (nb points %d)\n", rc); + goto close; + } + + if (tab_rp_registers[0] != 0x1234) { + printf("FAILED (%0X != %0X)\n", + tab_rp_registers[0], 0x1234); + goto close; + } + printf("OK\n"); + /* End of single register */ + + /* Many registers */ + rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS, + UT_REGISTERS_NB_POINTS, + UT_REGISTERS_TAB); + printf("1/2 modbus_write_registers: "); + if (rc == UT_REGISTERS_NB_POINTS) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, + UT_REGISTERS_NB_POINTS, + tab_rp_registers); + printf("2/2 modbus_read_registers: "); + if (rc != UT_REGISTERS_NB_POINTS) { + printf("FAILED (nb points %d)\n", rc); + goto close; + } + + for (i=0; i < UT_REGISTERS_NB_POINTS; i++) { + if (tab_rp_registers[i] != UT_REGISTERS_TAB[i]) { + printf("FAILED (%0X != %0X)\n", + tab_rp_registers[i], + UT_REGISTERS_TAB[i]); + goto close; + } + } + printf("OK\n"); + /* End of many registers */ + + + /** INPUT REGISTERS **/ + rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS, + UT_INPUT_REGISTERS_NB_POINTS, + tab_rp_registers); + printf("1/1 modbus_read_input_registers: "); + if (rc != UT_INPUT_REGISTERS_NB_POINTS) { + printf("FAILED (nb points %d)\n", rc); + goto close; + } + + for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) { + if (tab_rp_registers[i] != UT_INPUT_REGISTERS_TAB[i]) { + printf("FAILED (%0X != %0X)\n", + tab_rp_registers[i], UT_INPUT_REGISTERS_TAB[i]); + goto close; + } + } + printf("OK\n"); + + printf("\nTEST FLOATS\n"); + /** FLOAT **/ + printf("1/2 Set float: "); + modbus_set_float(UT_REAL, tab_rp_registers); + if (tab_rp_registers[1] == (UT_IREAL >> 16) && + tab_rp_registers[0] == (UT_IREAL & 0xFFFF)) { + printf("OK\n"); + } else { + printf("FAILED (%x != %x)\n", + *((uint32_t *)tab_rp_registers), UT_IREAL); + goto close; + } + + printf("2/2 Get float: "); + real = modbus_get_float(tab_rp_registers); + if (real == UT_REAL) { + printf("OK\n"); + } else { + printf("FAILED (%f != %f)\n", real, UT_REAL); + goto close; + } + + printf("\nAt this point, error messages doesn't mean the test has failed\n"); + + /** ILLEGAL DATA ADDRESS **/ + printf("\nTEST ILLEGAL DATA ADDRESS:\n"); + + /* The mapping begins at 0 and ending at address + nb_points so + * the addresses below are not valid. */ + + rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, + UT_BITS_NB_POINTS + 1, + tab_rp_bits); + printf("* modbus_read_bits: "); + if (rc == -1 && errno == EMBXILADD) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS, + UT_INPUT_BITS_NB_POINTS + 1, + tab_rp_bits); + printf("* modbus_read_input_bits: "); + if (rc == -1 && errno == EMBXILADD) + printf("OK\n"); + else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, + UT_REGISTERS_NB_POINTS + 1, + tab_rp_registers); + printf("* modbus_read_registers: "); + if (rc == -1 && errno == EMBXILADD) + printf("OK\n"); + else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS, + UT_INPUT_REGISTERS_NB_POINTS + 1, + tab_rp_registers); + printf("* modbus_read_input_registers: "); + if (rc == -1 && errno == EMBXILADD) + printf("OK\n"); + else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_write_bit(ctx, UT_BITS_ADDRESS + UT_BITS_NB_POINTS, ON); + printf("* modbus_write_bit: "); + if (rc == -1 && errno == EMBXILADD) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_write_bits(ctx, UT_BITS_ADDRESS + UT_BITS_NB_POINTS, + UT_BITS_NB_POINTS, + tab_rp_bits); + printf("* modbus_write_coils: "); + if (rc == -1 && errno == EMBXILADD) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS + + UT_REGISTERS_NB_POINTS, + UT_REGISTERS_NB_POINTS, + tab_rp_registers); + printf("* modbus_write_registers: "); + if (rc == -1 && errno == EMBXILADD) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + + /** TOO MANY DATA **/ + printf("\nTEST TOO MANY DATA ERROR:\n"); + + rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, MODBUS_MAX_BITS + 1, + tab_rp_bits); + printf("* modbus_read_bits: "); + if (rc == -1 && errno == EMBMDATA) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS, + MODBUS_MAX_BITS + 1, + tab_rp_bits); + printf("* modbus_read_input_bits: "); + if (rc == -1 && errno == EMBMDATA) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, + MODBUS_MAX_REGISTERS + 1, + tab_rp_registers); + printf("* modbus_read_registers: "); + if (rc == -1 && errno == EMBMDATA) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS, + MODBUS_MAX_REGISTERS + 1, + tab_rp_registers); + printf("* modbus_read_input_registers: "); + if (rc == -1 && errno == EMBMDATA) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + rc = modbus_write_bits(ctx, UT_BITS_ADDRESS, + MODBUS_MAX_BITS + 1, + tab_rp_bits); + printf("* modbus_write_bits: "); + if (rc == -1 && errno == EMBMDATA) { + printf("OK\n"); + } else { + goto close; + printf("FAILED\n"); + } + + rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS, + MODBUS_MAX_REGISTERS + 1, + tab_rp_registers); + printf("* modbus_write_registers: "); + if (rc == -1 && errno == EMBMDATA) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + /** SLAVE REPLY **/ + printf("\nTEST SLAVE REPLY:\n"); + modbus_set_slave(ctx, 18); + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, + UT_REGISTERS_NB_POINTS, + tab_rp_registers); + printf("1/3 No or response from slave %d: ", 18); + if (is_mode_rtu) { + /* No response in RTU mode */ + if (rc == -1 && errno == ETIMEDOUT) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + } else { + /* Response in TCP mode */ + if (rc == UT_REGISTERS_NB_POINTS) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + } + + modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS); + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, + UT_REGISTERS_NB_POINTS, + tab_rp_registers); + printf("2/3 Reply after a broadcast query: "); + if (rc == UT_REGISTERS_NB_POINTS) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + /* Restore slave */ + if (is_mode_rtu) { + modbus_set_slave(ctx, SERVER_ID); + } else { + modbus_set_slave(ctx, MODBUS_TCP_SLAVE); + } + + /* Save original timeout */ + modbus_get_timeout_begin(ctx, &timeout_begin_old); + + /* Define a new and too short timeout */ + timeout_begin_new.tv_sec = 0; + timeout_begin_new.tv_usec = 0; + modbus_set_timeout_begin(ctx, &timeout_begin_new); + + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, + UT_REGISTERS_NB_POINTS, + tab_rp_registers); + printf("3/3 Too short timeout: "); + if (rc == -1 && errno == ETIMEDOUT) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + + /* Restore original timeout */ + modbus_set_timeout_begin(ctx, &timeout_begin_old); + + /** BAD RESPONSE **/ + printf("\nTEST BAD RESPONSE ERROR:\n"); + + /* Allocate only the required space */ + tab_rp_registers_bad = (uint16_t *) malloc( + UT_REGISTERS_NB_POINTS_SPECIAL * sizeof(uint16_t)); + rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, + UT_REGISTERS_NB_POINTS_SPECIAL, + tab_rp_registers_bad); + printf("* modbus_read_registers: "); + if (rc == -1 && errno == EMBBADDATA) { + printf("OK\n"); + } else { + printf("FAILED\n"); + goto close; + } + free(tab_rp_registers_bad); + + printf("\nALL TESTS PASS WITH SUCCESS.\n"); + +close: + /* Free the memory */ + free(tab_rp_bits); + free(tab_rp_registers); + + /* Close the connection */ + modbus_close(ctx); + modbus_free(ctx); + + return 0; +} diff --git a/tests/unit-test-master.c b/tests/unit-test-master.c deleted file mode 100644 index c016ca7..0000000 --- a/tests/unit-test-master.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Copyright © 2008-2010 Stéphane Raimbault - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "unit-test.h" - -int main(void) -{ - uint8_t *tab_rp_bits; - uint16_t *tab_rp_registers; - uint16_t *tab_rp_registers_bad; - modbus_t *ctx; - int is_mode_rtu = FALSE; - int i; - uint8_t value; - int address; - int nb_points; - int rc; - float real; - struct timeval timeout_begin_old; - struct timeval timeout_begin_new; - - /* - ctx = modbus_new_rtu("/dev/ttyS0", 19200, 'N', 8, 1, CLIENT_ID); - modbus_set_slave(ctx, SERVER_ID); - is_mode_rtu = TRUE; - */ - - /* TCP */ - ctx = modbus_new_tcp("127.0.0.1", 1502); - modbus_set_debug(ctx, TRUE); - - if (modbus_connect(ctx) == -1) { - fprintf(stderr, "Connection failed: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; - } - - /* Allocate and initialize the memory to store the bits */ - nb_points = (UT_BITS_NB_POINTS > UT_INPUT_BITS_NB_POINTS) ? - UT_BITS_NB_POINTS : UT_INPUT_BITS_NB_POINTS; - tab_rp_bits = (uint8_t *) malloc(nb_points * sizeof(uint8_t)); - memset(tab_rp_bits, 0, nb_points * sizeof(uint8_t)); - - /* Allocate and initialize the memory to store the registers */ - nb_points = (UT_REGISTERS_NB_POINTS > - UT_INPUT_REGISTERS_NB_POINTS) ? - UT_REGISTERS_NB_POINTS : UT_INPUT_REGISTERS_NB_POINTS; - tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t)); - memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t)); - - printf("** UNIT TESTING **\n"); - - printf("\nTEST WRITE/READ:\n"); - - /** COIL BITS **/ - - /* Single */ - rc = modbus_write_bit(ctx, UT_BITS_ADDRESS, ON); - printf("1/2 modbus_write_bit: "); - if (rc == 1) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, 1, tab_rp_bits); - printf("2/2 modbus_read_bits: "); - if (rc != 1) { - printf("FAILED (nb points %d)\n", rc); - goto close; - } - - if (tab_rp_bits[0] != ON) { - printf("FAILED (%0X = != %0X)\n", tab_rp_bits[0], ON); - goto close; - } - printf("OK\n"); - /* End single */ - - /* Multiple bits */ - { - uint8_t tab_value[UT_BITS_NB_POINTS]; - - modbus_set_bits_from_bytes(tab_value, 0, UT_BITS_NB_POINTS, - UT_BITS_TAB); - rc = modbus_write_bits(ctx, UT_BITS_ADDRESS, - UT_BITS_NB_POINTS, tab_value); - printf("1/2 modbus_write_bits: "); - if (rc == UT_BITS_NB_POINTS) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - } - - rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, - UT_BITS_NB_POINTS, tab_rp_bits); - printf("2/2 modbus_read_bits: "); - if (rc != UT_BITS_NB_POINTS) { - printf("FAILED (nb points %d)\n", rc); - goto close; - } - - i = 0; - address = UT_BITS_ADDRESS; - nb_points = UT_BITS_NB_POINTS; - while (nb_points > 0) { - int nb_bits = (nb_points > 8) ? 8 : nb_points; - - value = modbus_get_byte_from_bits(tab_rp_bits, i*8, nb_bits); - if (value != UT_BITS_TAB[i]) { - printf("FAILED (%0X != %0X)\n", - value, UT_BITS_TAB[i]); - goto close; - } - - nb_points -= nb_bits; - i++; - } - printf("OK\n"); - /* End of multiple bits */ - - /** DISCRETE INPUTS **/ - rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS, - UT_INPUT_BITS_NB_POINTS, tab_rp_bits); - printf("1/1 modbus_read_input_bits: "); - - if (rc != UT_INPUT_BITS_NB_POINTS) { - printf("FAILED (nb points %d)\n", rc); - goto close; - } - - i = 0; - address = UT_INPUT_BITS_ADDRESS; - nb_points = UT_INPUT_BITS_NB_POINTS; - while (nb_points > 0) { - int nb_bits = (nb_points > 8) ? 8 : nb_points; - - value = modbus_get_byte_from_bits(tab_rp_bits, i*8, nb_bits); - if (value != UT_INPUT_BITS_TAB[i]) { - printf("FAILED (%0X != %0X)\n", - value, UT_INPUT_BITS_TAB[i]); - goto close; - } - - nb_points -= nb_bits; - i++; - } - printf("OK\n"); - - /** HOLDING REGISTERS **/ - - /* Single register */ - rc = modbus_write_register(ctx, UT_REGISTERS_ADDRESS, 0x1234); - printf("1/2 modbus_write_register: "); - if (rc == 1) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, - 1, tab_rp_registers); - printf("2/2 modbus_read_registers: "); - if (rc != 1) { - printf("FAILED (nb points %d)\n", rc); - goto close; - } - - if (tab_rp_registers[0] != 0x1234) { - printf("FAILED (%0X != %0X)\n", - tab_rp_registers[0], 0x1234); - goto close; - } - printf("OK\n"); - /* End of single register */ - - /* Many registers */ - rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS, - UT_REGISTERS_NB_POINTS, - UT_REGISTERS_TAB); - printf("1/2 modbus_write_registers: "); - if (rc == UT_REGISTERS_NB_POINTS) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, - UT_REGISTERS_NB_POINTS, - tab_rp_registers); - printf("2/2 modbus_read_registers: "); - if (rc != UT_REGISTERS_NB_POINTS) { - printf("FAILED (nb points %d)\n", rc); - goto close; - } - - for (i=0; i < UT_REGISTERS_NB_POINTS; i++) { - if (tab_rp_registers[i] != UT_REGISTERS_TAB[i]) { - printf("FAILED (%0X != %0X)\n", - tab_rp_registers[i], - UT_REGISTERS_TAB[i]); - goto close; - } - } - printf("OK\n"); - /* End of many registers */ - - - /** INPUT REGISTERS **/ - rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS, - UT_INPUT_REGISTERS_NB_POINTS, - tab_rp_registers); - printf("1/1 modbus_read_input_registers: "); - if (rc != UT_INPUT_REGISTERS_NB_POINTS) { - printf("FAILED (nb points %d)\n", rc); - goto close; - } - - for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) { - if (tab_rp_registers[i] != UT_INPUT_REGISTERS_TAB[i]) { - printf("FAILED (%0X != %0X)\n", - tab_rp_registers[i], UT_INPUT_REGISTERS_TAB[i]); - goto close; - } - } - printf("OK\n"); - - printf("\nTEST FLOATS\n"); - /** FLOAT **/ - printf("1/2 Set float: "); - modbus_set_float(UT_REAL, tab_rp_registers); - if (tab_rp_registers[1] == (UT_IREAL >> 16) && - tab_rp_registers[0] == (UT_IREAL & 0xFFFF)) { - printf("OK\n"); - } else { - printf("FAILED (%x != %x)\n", - *((uint32_t *)tab_rp_registers), UT_IREAL); - goto close; - } - - printf("2/2 Get float: "); - real = modbus_get_float(tab_rp_registers); - if (real == UT_REAL) { - printf("OK\n"); - } else { - printf("FAILED (%f != %f)\n", real, UT_REAL); - goto close; - } - - printf("\nAt this point, error messages doesn't mean the test has failed\n"); - - /** ILLEGAL DATA ADDRESS **/ - printf("\nTEST ILLEGAL DATA ADDRESS:\n"); - - /* The mapping begins at 0 and ending at address + nb_points so - * the addresses below are not valid. */ - - rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, - UT_BITS_NB_POINTS + 1, - tab_rp_bits); - printf("* modbus_read_bits: "); - if (rc == -1 && errno == EMBXILADD) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS, - UT_INPUT_BITS_NB_POINTS + 1, - tab_rp_bits); - printf("* modbus_read_input_bits: "); - if (rc == -1 && errno == EMBXILADD) - printf("OK\n"); - else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, - UT_REGISTERS_NB_POINTS + 1, - tab_rp_registers); - printf("* modbus_read_registers: "); - if (rc == -1 && errno == EMBXILADD) - printf("OK\n"); - else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS, - UT_INPUT_REGISTERS_NB_POINTS + 1, - tab_rp_registers); - printf("* modbus_read_input_registers: "); - if (rc == -1 && errno == EMBXILADD) - printf("OK\n"); - else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_write_bit(ctx, UT_BITS_ADDRESS + UT_BITS_NB_POINTS, ON); - printf("* modbus_write_bit: "); - if (rc == -1 && errno == EMBXILADD) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_write_bits(ctx, UT_BITS_ADDRESS + UT_BITS_NB_POINTS, - UT_BITS_NB_POINTS, - tab_rp_bits); - printf("* modbus_write_coils: "); - if (rc == -1 && errno == EMBXILADD) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS + - UT_REGISTERS_NB_POINTS, - UT_REGISTERS_NB_POINTS, - tab_rp_registers); - printf("* modbus_write_registers: "); - if (rc == -1 && errno == EMBXILADD) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - - /** TOO MANY DATA **/ - printf("\nTEST TOO MANY DATA ERROR:\n"); - - rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, MODBUS_MAX_BITS + 1, - tab_rp_bits); - printf("* modbus_read_bits: "); - if (rc == -1 && errno == EMBMDATA) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS, - MODBUS_MAX_BITS + 1, - tab_rp_bits); - printf("* modbus_read_input_bits: "); - if (rc == -1 && errno == EMBMDATA) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, - MODBUS_MAX_REGISTERS + 1, - tab_rp_registers); - printf("* modbus_read_registers: "); - if (rc == -1 && errno == EMBMDATA) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS, - MODBUS_MAX_REGISTERS + 1, - tab_rp_registers); - printf("* modbus_read_input_registers: "); - if (rc == -1 && errno == EMBMDATA) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - rc = modbus_write_bits(ctx, UT_BITS_ADDRESS, - MODBUS_MAX_BITS + 1, - tab_rp_bits); - printf("* modbus_write_bits: "); - if (rc == -1 && errno == EMBMDATA) { - printf("OK\n"); - } else { - goto close; - printf("FAILED\n"); - } - - rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS, - MODBUS_MAX_REGISTERS + 1, - tab_rp_registers); - printf("* modbus_write_registers: "); - if (rc == -1 && errno == EMBMDATA) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - /** SLAVE REPLY **/ - printf("\nTEST SLAVE REPLY:\n"); - modbus_set_slave(ctx, 18); - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, - UT_REGISTERS_NB_POINTS, - tab_rp_registers); - printf("1/3 No or response from slave %d: ", 18); - if (is_mode_rtu) { - /* No response in RTU mode */ - if (rc == -1 && errno == ETIMEDOUT) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - } else { - /* Response in TCP mode */ - if (rc == UT_REGISTERS_NB_POINTS) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - } - - modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS); - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, - UT_REGISTERS_NB_POINTS, - tab_rp_registers); - printf("2/3 Reply after a broadcast query: "); - if (rc == UT_REGISTERS_NB_POINTS) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - /* Restore slave */ - if (is_mode_rtu) { - modbus_set_slave(ctx, SERVER_ID); - } else { - modbus_set_slave(ctx, MODBUS_TCP_SLAVE); - } - - /* Save original timeout */ - modbus_get_timeout_begin(ctx, &timeout_begin_old); - - /* Define a new and too short timeout */ - timeout_begin_new.tv_sec = 0; - timeout_begin_new.tv_usec = 0; - modbus_set_timeout_begin(ctx, &timeout_begin_new); - - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, - UT_REGISTERS_NB_POINTS, - tab_rp_registers); - printf("3/3 Too short timeout: "); - if (rc == -1 && errno == ETIMEDOUT) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - - /* Restore original timeout */ - modbus_set_timeout_begin(ctx, &timeout_begin_old); - - /** BAD RESPONSE **/ - printf("\nTEST BAD RESPONSE ERROR:\n"); - - /* Allocate only the required space */ - tab_rp_registers_bad = (uint16_t *) malloc( - UT_REGISTERS_NB_POINTS_SPECIAL * sizeof(uint16_t)); - rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS, - UT_REGISTERS_NB_POINTS_SPECIAL, - tab_rp_registers_bad); - printf("* modbus_read_registers: "); - if (rc == -1 && errno == EMBBADDATA) { - printf("OK\n"); - } else { - printf("FAILED\n"); - goto close; - } - free(tab_rp_registers_bad); - - printf("\nALL TESTS PASS WITH SUCCESS.\n"); - -close: - /* Free the memory */ - free(tab_rp_bits); - free(tab_rp_registers); - - /* Close the connection */ - modbus_close(ctx); - modbus_free(ctx); - - return 0; -} diff --git a/tests/unit-test-server.c b/tests/unit-test-server.c new file mode 100644 index 0000000..e46a45b --- /dev/null +++ b/tests/unit-test-server.c @@ -0,0 +1,100 @@ +/* + * Copyright © 2008-2010 Stéphane Raimbault + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "unit-test.h" + +/* Copied from modbus-private.h */ +#define HEADER_LENGTH_TCP 7 + +int main(void) +{ + int socket; + modbus_t *ctx; + modbus_mapping_t *mb_mapping; + int rc; + int i; + + ctx = modbus_new_tcp("127.0.0.1", 1502); + modbus_set_debug(ctx, TRUE); + modbus_set_error_recovery(ctx, TRUE); + + mb_mapping = modbus_mapping_new(UT_BITS_ADDRESS + UT_BITS_NB_POINTS, + UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB_POINTS, + UT_REGISTERS_ADDRESS + UT_REGISTERS_NB_POINTS, + UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB_POINTS); + if (mb_mapping == NULL) { + fprintf(stderr, "Failed to allocate the mapping: %s\n", + modbus_strerror(errno)); + modbus_free(ctx); + return -1; + } + + /* Examples from PI_MODBUS_300.pdf. + Only the read-only input values are assigned. */ + + /** INPUT STATUS **/ + modbus_set_bits_from_bytes(mb_mapping->tab_input_bits, + UT_INPUT_BITS_ADDRESS, UT_INPUT_BITS_NB_POINTS, + UT_INPUT_BITS_TAB); + + /** INPUT REGISTERS **/ + for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) { + mb_mapping->tab_input_registers[UT_INPUT_REGISTERS_ADDRESS+i] = + UT_INPUT_REGISTERS_TAB[i];; + } + + socket = modbus_listen(ctx, 1); + modbus_accept(ctx, &socket); + + for (;;) { + uint8_t query[MODBUS_MAX_ADU_LENGTH_TCP]; + + rc = modbus_receive(ctx, -1, query); + if (rc > 0) { + if (((query[HEADER_LENGTH_TCP + 3] << 8) + query[HEADER_LENGTH_TCP + 4]) + == UT_REGISTERS_NB_POINTS_SPECIAL) { + /* Change the number of values (offset + TCP = 6) */ + query[HEADER_LENGTH_TCP + 3] = 0; + query[HEADER_LENGTH_TCP + 4] = UT_REGISTERS_NB_POINTS; + } + + rc = modbus_reply(ctx, query, rc, mb_mapping); + if (rc == -1) { + return -1; + } + } else { + /* Connection closed by the client or error */ + break; + } + } + + printf("Quit the loop: %s\n", modbus_strerror(errno)); + + close(socket); + modbus_mapping_free(mb_mapping); + modbus_free(ctx); + + return 0; +} diff --git a/tests/unit-test-slave.c b/tests/unit-test-slave.c deleted file mode 100644 index e46a45b..0000000 --- a/tests/unit-test-slave.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright © 2008-2010 Stéphane Raimbault - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "unit-test.h" - -/* Copied from modbus-private.h */ -#define HEADER_LENGTH_TCP 7 - -int main(void) -{ - int socket; - modbus_t *ctx; - modbus_mapping_t *mb_mapping; - int rc; - int i; - - ctx = modbus_new_tcp("127.0.0.1", 1502); - modbus_set_debug(ctx, TRUE); - modbus_set_error_recovery(ctx, TRUE); - - mb_mapping = modbus_mapping_new(UT_BITS_ADDRESS + UT_BITS_NB_POINTS, - UT_INPUT_BITS_ADDRESS + UT_INPUT_BITS_NB_POINTS, - UT_REGISTERS_ADDRESS + UT_REGISTERS_NB_POINTS, - UT_INPUT_REGISTERS_ADDRESS + UT_INPUT_REGISTERS_NB_POINTS); - if (mb_mapping == NULL) { - fprintf(stderr, "Failed to allocate the mapping: %s\n", - modbus_strerror(errno)); - modbus_free(ctx); - return -1; - } - - /* Examples from PI_MODBUS_300.pdf. - Only the read-only input values are assigned. */ - - /** INPUT STATUS **/ - modbus_set_bits_from_bytes(mb_mapping->tab_input_bits, - UT_INPUT_BITS_ADDRESS, UT_INPUT_BITS_NB_POINTS, - UT_INPUT_BITS_TAB); - - /** INPUT REGISTERS **/ - for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) { - mb_mapping->tab_input_registers[UT_INPUT_REGISTERS_ADDRESS+i] = - UT_INPUT_REGISTERS_TAB[i];; - } - - socket = modbus_listen(ctx, 1); - modbus_accept(ctx, &socket); - - for (;;) { - uint8_t query[MODBUS_MAX_ADU_LENGTH_TCP]; - - rc = modbus_receive(ctx, -1, query); - if (rc > 0) { - if (((query[HEADER_LENGTH_TCP + 3] << 8) + query[HEADER_LENGTH_TCP + 4]) - == UT_REGISTERS_NB_POINTS_SPECIAL) { - /* Change the number of values (offset - TCP = 6) */ - query[HEADER_LENGTH_TCP + 3] = 0; - query[HEADER_LENGTH_TCP + 4] = UT_REGISTERS_NB_POINTS; - } - - rc = modbus_reply(ctx, query, rc, mb_mapping); - if (rc == -1) { - return -1; - } - } else { - /* Connection closed by the client or error */ - break; - } - } - - printf("Quit the loop: %s\n", modbus_strerror(errno)); - - close(socket); - modbus_mapping_free(mb_mapping); - modbus_free(ctx); - - return 0; -} -- libgit2 0.21.4