Commit cdc536c9ad4e6c053fcf34b45ac226d015e65973

Authored by Stéphane Raimbault
1 parent f5e2f2c9

The slave only listen when concerned (slave ID or broadcast)

- MAJOR changes to the API (see MIGRATION)
- New unit tests
- Removed TODO list
- Updated NEWS & MIGRATION files
MIGRATION
1   -=============================
2   -Migration from the 2.0 series
3   -=============================
  1 +=============================================
  2 +Migration notes from the 2.0 series (for 2.2)
  3 +=============================================
4 4  
5   -modbus_init_listen_tcp() has been renamed to modbus_slave_listen_tcp() and
6   -requires a new argument, the maximal number of connections:
  5 +1 - modbus_init_rtu/tcp takes a new argument: the slave and it is only required
  6 + in that function (eg. read_coil_status doesn't receive the slave ID in
  7 + argument anymore). If you need to use different slaves with the same
  8 + connection (eg. RS485), you can copy modbus_param_t or set
  9 + modbus_param_t.slave to a different value when required.
  10 +
  11 +2 - modbus_init_listen_tcp() has been renamed to modbus_slave_listen_tcp() and
  12 + requires a new argument, the maximal number of connections:
7 13  
8 14 int modbus_slave_init_tcp(modbus_param_t *mb_param, int nb_connection);
9 15  
10 16  
11   -New function modbus_slave_accept_tcp() to etablish a new connection (previously
12   -in modbus_init_listen_tcp()):
  17 +3 - New function modbus_slave_accept_tcp() to etablish a new connection
  18 + (previously in modbus_init_listen_tcp()):
13 19  
14 20 int modbus_slave_accept_tcp(modbus_param_t *mb_param, int *socket);
15 21  
16 22  
17   -modbus_listen() has been renamed to modbus_slave_receive() and requires a new
18   -argument, the socket file descriptor to listen on. If the sockfd is -1, the
19   -internal fd of modbus_param_t is used:
  23 +4 - modbus_listen() has been renamed to modbus_slave_receive() and requires a
  24 + new argument, the socket file descriptor to listen on. If the sockfd is -1,
  25 + the internal fd of modbus_param_t is used:
20 26  
21 27 int modbus_slave_receive(modbus_param_t *mb_param, int sockfd,
22 28 uint8_t *query, int *query_length);
23 29  
24 30  
25   -If you use the HEADER_LENGTH_ defines, their values have been incremented by 1
26   -to reflect the PDU and ADU of the Modbus protocol and to reduce the CPU
27   -consumption:
28   - - HEADER_LENGTH_RTU 0 -> 1
29   - - HEADER_LENGTH_TCP 6 -> 7
  31 +5 - If you use the HEADER_LENGTH_ defines, their values have been incremented by
  32 + 1 to reflect the PDU and ADU of the Modbus protocol and to reduce the CPU
  33 + consumption:
  34 + - HEADER_LENGTH_RTU 0 -> 1
  35 + - HEADER_LENGTH_TCP 6 -> 7
  36 +
30 37  
31   -===================================
32   -Migration notes from the 1.2 series
33   -===================================
  38 +=============================================
  39 +Migration notes from the 1.2 series (for 2.0)
  40 +=============================================
34 41  
35 42 Init
36 43 ====
... ...
1 1 libmodbus 2.2.0 (2009-05-01)
2 2 ============================
3 3 - New API for slave server (see MIGRATION)
  4 +- New slave server able to handle multiple connections
  5 +- Slave only replies to broadcast queries or queries with its slave ID
  6 +- Improved Modbus protocol conformance
4 7 - modbus_param_t is smaller (2 int removed)
  8 +- Faster
5 9  
6 10 libmodbus 2.0.3 (2009-03-22)
7 11 ============================
... ...
TODO deleted
1   -Features
2   -* broadcasting
3   -* slave must listen only request sent for him
4   -
src/modbus.c
... ... @@ -259,16 +259,16 @@ static int build_query_basis_tcp(int slave, int function,
259 259 return PRESET_QUERY_LENGTH_TCP;
260 260 }
261 261  
262   -static int build_query_basis(modbus_param_t *mb_param, int slave,
  262 +static int build_query_basis(modbus_param_t *mb_param,
263 263 int function, int start_addr,
264 264 int nb, uint8_t *query)
265 265 {
266 266 if (mb_param->type_com == RTU)
267   - return build_query_basis_rtu(slave, function, start_addr,
268   - nb, query);
  267 + return build_query_basis_rtu(mb_param->slave, function,
  268 + start_addr, nb, query);
269 269 else
270   - return build_query_basis_tcp(slave, function, start_addr,
271   - nb, query);
  270 + return build_query_basis_tcp(mb_param->slave, function,
  271 + start_addr, nb, query);
272 272 }
273 273  
274 274 /* Builds a RTU response header */
... ... @@ -798,7 +798,7 @@ static int response_exception(modbus_param_t *mb_param, sft_t *sft,
798 798 If an error occurs, this function construct the response
799 799 accordingly.
800 800 */
801   -void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
  801 +void modbus_slave_manage(modbus_param_t *mb_param, const uint8_t *query,
802 802 int query_length, modbus_mapping_t *mb_mapping)
803 803 {
804 804 int offset = TAB_HEADER_LENGTH[mb_param->type_com];
... ... @@ -808,6 +808,14 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
808 808 uint8_t response[MAX_MESSAGE_LENGTH];
809 809 int resp_length = 0;
810 810 sft_t sft;
  811 +
  812 + if (slave != mb_param->slave && slave != MODBUS_BROADCAST_ADDRESS) {
  813 + // Ignores the query (not for me)
  814 + if (mb_param->debug) {
  815 + printf("Dropped request from slave %d (!= %d)\n", slave, mb_param->slave);
  816 + }
  817 + return;
  818 + }
811 819  
812 820 sft.slave = slave;
813 821 sft.function = function;
... ... @@ -987,7 +995,7 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
987 995 }
988 996  
989 997 /* Reads IO status */
990   -static int read_io_status(modbus_param_t *mb_param, int slave, int function,
  998 +static int read_io_status(modbus_param_t *mb_param, int function,
991 999 int start_addr, int nb, uint8_t *data_dest)
992 1000 {
993 1001 int ret;
... ... @@ -996,7 +1004,7 @@ static int read_io_status(modbus_param_t *mb_param, int slave, int function,
996 1004 uint8_t query[MIN_QUERY_LENGTH];
997 1005 uint8_t response[MAX_MESSAGE_LENGTH];
998 1006  
999   - query_length = build_query_basis(mb_param, slave, function,
  1007 + query_length = build_query_basis(mb_param, function,
1000 1008 start_addr, nb, query);
1001 1009  
1002 1010 ret = modbus_send(mb_param, query, query_length);
... ... @@ -1029,7 +1037,7 @@ static int read_io_status(modbus_param_t *mb_param, int slave, int function,
1029 1037  
1030 1038 /* Reads the boolean status of coils and sets the array elements
1031 1039 in the destination to TRUE or FALSE. */
1032   -int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
  1040 +int read_coil_status(modbus_param_t *mb_param, int start_addr,
1033 1041 int nb, uint8_t *data_dest)
1034 1042 {
1035 1043 int status;
... ... @@ -1040,7 +1048,7 @@ int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
1040 1048 return TOO_MANY_DATA;
1041 1049 }
1042 1050  
1043   - status = read_io_status(mb_param, slave, FC_READ_COIL_STATUS,
  1051 + status = read_io_status(mb_param, FC_READ_COIL_STATUS,
1044 1052 start_addr, nb, data_dest);
1045 1053  
1046 1054 if (status > 0)
... ... @@ -1051,7 +1059,7 @@ int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
1051 1059  
1052 1060  
1053 1061 /* Same as read_coil_status but reads the slaves input table */
1054   -int read_input_status(modbus_param_t *mb_param, int slave, int start_addr,
  1062 +int read_input_status(modbus_param_t *mb_param, int start_addr,
1055 1063 int nb, uint8_t *data_dest)
1056 1064 {
1057 1065 int status;
... ... @@ -1062,7 +1070,7 @@ int read_input_status(modbus_param_t *mb_param, int slave, int start_addr,
1062 1070 return TOO_MANY_DATA;
1063 1071 }
1064 1072  
1065   - status = read_io_status(mb_param, slave, FC_READ_INPUT_STATUS,
  1073 + status = read_io_status(mb_param, FC_READ_INPUT_STATUS,
1066 1074 start_addr, nb, data_dest);
1067 1075  
1068 1076 if (status > 0)
... ... @@ -1072,7 +1080,7 @@ int read_input_status(modbus_param_t *mb_param, int slave, int start_addr,
1072 1080 }
1073 1081  
1074 1082 /* Reads the data from a modbus slave and put that data into an array */
1075   -static int read_registers(modbus_param_t *mb_param, int slave, int function,
  1083 +static int read_registers(modbus_param_t *mb_param, int function,
1076 1084 int start_addr, int nb, uint16_t *data_dest)
1077 1085 {
1078 1086 int ret;
... ... @@ -1086,7 +1094,7 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function,
1086 1094 return TOO_MANY_DATA;
1087 1095 }
1088 1096  
1089   - query_length = build_query_basis(mb_param, slave, function,
  1097 + query_length = build_query_basis(mb_param, function,
1090 1098 start_addr, nb, query);
1091 1099  
1092 1100 ret = modbus_send(mb_param, query, query_length);
... ... @@ -1111,7 +1119,7 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function,
1111 1119  
1112 1120 /* Reads the holding registers in a slave and put the data into an
1113 1121 array */
1114   -int read_holding_registers(modbus_param_t *mb_param, int slave,
  1122 +int read_holding_registers(modbus_param_t *mb_param,
1115 1123 int start_addr, int nb, uint16_t *data_dest)
1116 1124 {
1117 1125 int status;
... ... @@ -1122,15 +1130,15 @@ int read_holding_registers(modbus_param_t *mb_param, int slave,
1122 1130 return TOO_MANY_DATA;
1123 1131 }
1124 1132  
1125   - status = read_registers(mb_param, slave, FC_READ_HOLDING_REGISTERS,
  1133 + status = read_registers(mb_param, FC_READ_HOLDING_REGISTERS,
1126 1134 start_addr, nb, data_dest);
1127 1135 return status;
1128 1136 }
1129 1137  
1130 1138 /* Reads the input registers in a slave and put the data into
1131 1139 an array */
1132   -int read_input_registers(modbus_param_t *mb_param, int slave,
1133   - int start_addr, int nb, uint16_t *data_dest)
  1140 +int read_input_registers(modbus_param_t *mb_param, int start_addr, int nb,
  1141 + uint16_t *data_dest)
1134 1142 {
1135 1143 int status;
1136 1144  
... ... @@ -1140,7 +1148,7 @@ int read_input_registers(modbus_param_t *mb_param, int slave,
1140 1148 return TOO_MANY_DATA;
1141 1149 }
1142 1150  
1143   - status = read_registers(mb_param, slave, FC_READ_INPUT_REGISTERS,
  1151 + status = read_registers(mb_param, FC_READ_INPUT_REGISTERS,
1144 1152 start_addr, nb, data_dest);
1145 1153  
1146 1154 return status;
... ... @@ -1148,14 +1156,14 @@ int read_input_registers(modbus_param_t *mb_param, int slave,
1148 1156  
1149 1157 /* Sends a value to a register in a slave.
1150 1158 Used by force_single_coil and preset_single_register */
1151   -static int set_single(modbus_param_t *mb_param, int slave, int function,
  1159 +static int set_single(modbus_param_t *mb_param, int function,
1152 1160 int addr, int value)
1153 1161 {
1154 1162 int ret;
1155 1163 int query_length;
1156 1164 uint8_t query[MIN_QUERY_LENGTH];
1157 1165  
1158   - query_length = build_query_basis(mb_param, slave, function,
  1166 + query_length = build_query_basis(mb_param, function,
1159 1167 addr, value, query);
1160 1168  
1161 1169 ret = modbus_send(mb_param, query, query_length);
... ... @@ -1170,35 +1178,32 @@ static int set_single(modbus_param_t *mb_param, int slave, int function,
1170 1178 }
1171 1179  
1172 1180 /* Turns ON or OFF a single coil in the slave device */
1173   -int force_single_coil(modbus_param_t *mb_param, int slave,
1174   - int coil_addr, int state)
  1181 +int force_single_coil(modbus_param_t *mb_param, int coil_addr, int state)
1175 1182 {
1176 1183 int status;
1177 1184  
1178 1185 if (state)
1179 1186 state = 0xFF00;
1180 1187  
1181   - status = set_single(mb_param, slave, FC_FORCE_SINGLE_COIL,
  1188 + status = set_single(mb_param, FC_FORCE_SINGLE_COIL,
1182 1189 coil_addr, state);
1183 1190  
1184 1191 return status;
1185 1192 }
1186 1193  
1187 1194 /* Sets a value in one holding register in the slave device */
1188   -int preset_single_register(modbus_param_t *mb_param, int slave,
1189   - int reg_addr, int value)
  1195 +int preset_single_register(modbus_param_t *mb_param, int reg_addr, int value)
1190 1196 {
1191 1197 int status;
1192 1198  
1193   - status = set_single(mb_param, slave, FC_PRESET_SINGLE_REGISTER,
  1199 + status = set_single(mb_param, FC_PRESET_SINGLE_REGISTER,
1194 1200 reg_addr, value);
1195 1201  
1196 1202 return status;
1197 1203 }
1198 1204  
1199 1205 /* Sets/resets the coils in the slave from an array in argument */
1200   -int force_multiple_coils(modbus_param_t *mb_param, int slave,
1201   - int start_addr, int nb,
  1206 +int force_multiple_coils(modbus_param_t *mb_param, int start_addr, int nb,
1202 1207 const uint8_t *data_src)
1203 1208 {
1204 1209 int ret;
... ... @@ -1216,8 +1221,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int slave,
1216 1221 return TOO_MANY_DATA;
1217 1222 }
1218 1223  
1219   - query_length = build_query_basis(mb_param, slave,
1220   - FC_FORCE_MULTIPLE_COILS,
  1224 + query_length = build_query_basis(mb_param, FC_FORCE_MULTIPLE_COILS,
1221 1225 start_addr, nb, query);
1222 1226 byte_count = (nb / 8) + ((nb % 8) ? 1 : 0);
1223 1227 query[query_length++] = byte_count;
... ... @@ -1250,8 +1254,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int slave,
1250 1254 }
1251 1255  
1252 1256 /* Copies the values in the slave from the array given in argument */
1253   -int preset_multiple_registers(modbus_param_t *mb_param, int slave,
1254   - int start_addr, int nb,
  1257 +int preset_multiple_registers(modbus_param_t *mb_param, int start_addr, int nb,
1255 1258 const uint16_t *data_src)
1256 1259 {
1257 1260 int ret;
... ... @@ -1267,8 +1270,7 @@ int preset_multiple_registers(modbus_param_t *mb_param, int slave,
1267 1270 return TOO_MANY_DATA;
1268 1271 }
1269 1272  
1270   - query_length = build_query_basis(mb_param, slave,
1271   - FC_PRESET_MULTIPLE_REGISTERS,
  1273 + query_length = build_query_basis(mb_param, FC_PRESET_MULTIPLE_REGISTERS,
1272 1274 start_addr, nb, query);
1273 1275 byte_count = nb * 2;
1274 1276 query[query_length++] = byte_count;
... ... @@ -1288,15 +1290,13 @@ int preset_multiple_registers(modbus_param_t *mb_param, int slave,
1288 1290 }
1289 1291  
1290 1292 /* Returns the slave id! */
1291   -int report_slave_id(modbus_param_t *mb_param, int slave,
1292   - uint8_t *data_dest)
  1293 +int report_slave_id(modbus_param_t *mb_param, uint8_t *data_dest)
1293 1294 {
1294 1295 int ret;
1295 1296 int query_length;
1296 1297 uint8_t query[MIN_QUERY_LENGTH];
1297 1298  
1298   - query_length = build_query_basis(mb_param, slave, FC_REPORT_SLAVE_ID,
1299   - 0, 0, query);
  1299 + query_length = build_query_basis(mb_param, FC_REPORT_SLAVE_ID, 0, 0, query);
1300 1300  
1301 1301 /* HACKISH, start_addr and count are not used */
1302 1302 query_length -= 4;
... ... @@ -1333,7 +1333,7 @@ int report_slave_id(modbus_param_t *mb_param, int slave,
1333 1333 */
1334 1334 void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1335 1335 int baud, const char *parity, int data_bit,
1336   - int stop_bit)
  1336 + int stop_bit, int slave)
1337 1337 {
1338 1338 memset(mb_param, 0, sizeof(modbus_param_t));
1339 1339 strcpy(mb_param->device, device);
... ... @@ -1344,6 +1344,7 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1344 1344 mb_param->stop_bit = stop_bit;
1345 1345 mb_param->type_com = RTU;
1346 1346 mb_param->error_handling = FLUSH_OR_RECONNECT_ON_ERROR;
  1347 + mb_param->slave = slave;
1347 1348 }
1348 1349  
1349 1350 /* Initializes the modbus_param_t structure for TCP.
... ... @@ -1355,13 +1356,14 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1355 1356 to 1024 because it's not necessary to be root to use this port
1356 1357 number.
1357 1358 */
1358   -void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port)
  1359 +void modbus_init_tcp(modbus_param_t *mb_param, const char *ip, int port, int slave)
1359 1360 {
1360 1361 memset(mb_param, 0, sizeof(modbus_param_t));
1361 1362 strncpy(mb_param->ip, ip, sizeof(char)*16);
1362 1363 mb_param->port = port;
1363 1364 mb_param->type_com = TCP;
1364 1365 mb_param->error_handling = FLUSH_OR_RECONNECT_ON_ERROR;
  1366 + mb_param->slave = slave;
1365 1367 }
1366 1368  
1367 1369 /* By default, the error handling mode used is FLUSH_OR_RECONNECT_ON_ERROR.
... ...
src/modbus.h
... ... @@ -27,6 +27,7 @@ extern "C" {
27 27 #endif
28 28  
29 29 #define MODBUS_TCP_DEFAULT_PORT 502
  30 +#define MODBUS_BROADCAST_ADDRESS 255
30 31  
31 32 /* Slave index */
32 33 #define HEADER_LENGTH_RTU 1
... ... @@ -135,6 +136,8 @@ typedef enum { FLUSH_OR_RECONNECT_ON_ERROR, NOP_ON_ERROR } error_handling_t;
135 136  
136 137 /* This structure is byte-aligned */
137 138 typedef struct {
  139 + /* Slave address */
  140 + int slave;
138 141 /* Descriptor (tty or socket) */
139 142 int fd;
140 143 /* Communication mode: RTU or TCP */
... ... @@ -189,41 +192,39 @@ typedef struct {
189 192  
190 193 /* Reads the boolean status of coils and sets the array elements in
191 194 the destination to TRUE or FALSE */
192   -int read_coil_status(modbus_param_t *mb_param, int slave,
193   - int start_addr, int nb, uint8_t *dest);
  195 +int read_coil_status(modbus_param_t *mb_param, int start_addr, int nb,
  196 + uint8_t *dest);
194 197  
195 198 /* Same as read_coil_status but reads the slaves input table */
196   -int read_input_status(modbus_param_t *mb_param, int slave,
197   - int start_addr, int nb, uint8_t *dest);
  199 +int read_input_status(modbus_param_t *mb_param, int start_addr, int nb,
  200 + uint8_t *dest);
198 201  
199 202 /* Reads the holding registers in a slave and put the data into an
200 203 array */
201   -int read_holding_registers(modbus_param_t *mb_param, int slave,
202   - int start_addr, int nb, uint16_t *dest);
  204 +int read_holding_registers(modbus_param_t *mb_param, int start_addr, int nb,
  205 + uint16_t *dest);
203 206  
204 207 /* Reads the input registers in a slave and put the data into an
205 208 array */
206   -int read_input_registers(modbus_param_t *mb_param, int slave,
207   - int start_addr, int nb, uint16_t *dest);
  209 +int read_input_registers(modbus_param_t *mb_param, int start_addr, int nb,
  210 + uint16_t *dest);
208 211  
209 212 /* Turns ON or OFF a single coil in the slave device */
210   -int force_single_coil(modbus_param_t *mb_param, int slave,
211   - int coil_addr, int state);
  213 +int force_single_coil(modbus_param_t *mb_param, int coil_addr, int state);
212 214  
213 215 /* Sets a value in one holding register in the slave device */
214   -int preset_single_register(modbus_param_t *mb_param, int slave,
215   - int reg_addr, int value);
  216 +int preset_single_register(modbus_param_t *mb_param, int reg_addr, int value);
216 217  
217 218 /* Sets/resets the coils in the slave from an array in argument */
218   -int force_multiple_coils(modbus_param_t *mb_param, int slave,
219   - int start_addr, int nb, const uint8_t *data);
  219 +int force_multiple_coils(modbus_param_t *mb_param, int start_addr, int nb,
  220 + const uint8_t *data);
220 221  
221 222 /* Copies the values in the slave from the array given in argument */
222   -int preset_multiple_registers(modbus_param_t *mb_param, int slave,
223   - int start_addr, int nb, const uint16_t *data);
  223 +int preset_multiple_registers(modbus_param_t *mb_param, int start_addr, int nb,
  224 + const uint16_t *data);
224 225  
225 226 /* Returns the slave id! */
226   -int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *dest);
  227 +int report_slave_id(modbus_param_t *mb_param, uint8_t *dest);
227 228  
228 229 /* Initializes the modbus_param_t structure for RTU.
229 230 - device: "/dev/ttyS0"
... ... @@ -234,18 +235,20 @@ int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *dest);
234 235 */
235 236 void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
236 237 int baud, const char *parity, int data_bit,
237   - int stop_bit);
  238 + int stop_bit, int slave);
238 239  
239 240 /* Initializes the modbus_param_t structure for TCP.
240   - - ip : "192.168.0.5"
241   - - port : 1099
  241 + - ip: "192.168.0.5"
  242 + - port: 1099
  243 + - slave: 5
242 244  
243 245 Set the port to MODBUS_TCP_DEFAULT_PORT to use the default one
244 246 (502). It's convenient to use a port number greater than or equal
245 247 to 1024 because it's not necessary to be root to use this port
246 248 number.
247 249 */
248   -void modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port);
  250 +void modbus_init_tcp(modbus_param_t *mb_param, const char *ip_address, int port,
  251 + int slave);
249 252  
250 253 /* By default, the error handling mode used is RECONNECT_ON_ERROR.
251 254  
... ... @@ -312,7 +315,7 @@ int modbus_slave_receive(modbus_param_t *mb_param, int sockfd,
312 315 If an error occurs, this function construct the response
313 316 accordingly.
314 317 */
315   -void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
  318 +void modbus_slave_manage(modbus_param_t *mb_param, const uint8_t *query,
316 319 int query_length, modbus_mapping_t *mb_mapping);
317 320  
318 321  
... ...
tests/bandwidth-master.c
... ... @@ -53,7 +53,7 @@ int main(void)
53 53 uint32_t rate;
54 54  
55 55 /* TCP */
56   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  56 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE);
57 57 if (modbus_connect(&mb_param) == -1) {
58 58 printf("ERROR Connection failed\n");
59 59 exit(1);
... ... @@ -72,7 +72,7 @@ int main(void)
72 72 nb_points = MAX_STATUS;
73 73 start = gettime_ms();
74 74 for (i=0; i<NB_LOOPS; i++) {
75   - ret = read_coil_status(&mb_param, SLAVE, 0, nb_points, tab_rp_status);
  75 + ret = read_coil_status(&mb_param, 0, nb_points, tab_rp_status);
76 76 }
77 77 end = gettime_ms();
78 78 elapsed = end - start;
... ... @@ -105,7 +105,7 @@ int main(void)
105 105 nb_points = MAX_REGISTERS;
106 106 start = gettime_ms();
107 107 for (i=0; i<NB_LOOPS; i++) {
108   - ret = read_holding_registers(&mb_param, SLAVE, 0, nb_points, tab_rp_registers);
  108 + ret = read_holding_registers(&mb_param, 0, nb_points, tab_rp_registers);
109 109 }
110 110 end = gettime_ms();
111 111 elapsed = end - start;
... ...
tests/bandwidth-slave-many-up.c
... ... @@ -24,7 +24,9 @@
24 24  
25 25 #include "modbus.h"
26 26  
27   -#define NB_CONNECTION 5
  27 +#define SLAVE 0x11
  28 +#define NB_CONNECTION 5
  29 +
28 30 int slave_socket;
29 31 modbus_mapping_t mb_mapping;
30 32  
... ... @@ -48,7 +50,7 @@ int main(void)
48 50 /* Maximum file descriptor number */
49 51 int fdmax;
50 52  
51   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  53 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE);
52 54  
53 55 ret = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
54 56 if (ret == FALSE) {
... ... @@ -109,7 +111,7 @@ int main(void)
109 111  
110 112 ret = modbus_slave_receive(&mb_param, master_socket, query, &query_size);
111 113 if (ret == 0) {
112   - modbus_manage_query(&mb_param, query, query_size, &mb_mapping);
  114 + modbus_slave_manage(&mb_param, query, query_size, &mb_mapping);
113 115 } else {
114 116 /* Connection closed by the client, end of server */
115 117 printf("Connection closed on socket %d\n", master_socket);
... ...
tests/bandwidth-slave-one.c
... ... @@ -22,6 +22,8 @@
22 22  
23 23 #include "modbus.h"
24 24  
  25 +#define SLAVE 0x11
  26 +
25 27 int main(void)
26 28 {
27 29 int socket;
... ... @@ -29,7 +31,7 @@ int main(void)
29 31 modbus_mapping_t mb_mapping;
30 32 int ret;
31 33  
32   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  34 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE);
33 35  
34 36 ret = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
35 37 if (ret == FALSE) {
... ... @@ -46,7 +48,7 @@ int main(void)
46 48  
47 49 ret = modbus_slave_receive(&mb_param, -1, query, &query_size);
48 50 if (ret == 0) {
49   - modbus_manage_query(&mb_param, query, query_size, &mb_mapping);
  51 + modbus_slave_manage(&mb_param, query, query_size, &mb_mapping);
50 52 } else if (ret == CONNECTION_CLOSED) {
51 53 /* Connection closed by the client, end of server */
52 54 break;
... ...
tests/random-test-master.c
... ... @@ -60,7 +60,7 @@ int main(void)
60 60 /* modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, "none", 8, 1); */
61 61  
62 62 /* TCP */
63   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  63 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE);
64 64 modbus_set_debug(&mb_param, TRUE);
65 65 if (modbus_connect(&mb_param) == -1) {
66 66 printf("ERROR Connection failed\n");
... ... @@ -95,14 +95,14 @@ int main(void)
95 95 nb = ADDRESS_END - addr;
96 96  
97 97 /* SINGLE COIL */
98   - ret = force_single_coil(&mb_param, SLAVE, addr, tab_rq_status[0]);
  98 + ret = force_single_coil(&mb_param, addr, tab_rq_status[0]);
99 99 if (ret != 1) {
100 100 printf("ERROR force_single_coil (%d)\n", ret);
101 101 printf("Slave = %d, address = %d, value = %d\n",
102 102 SLAVE, addr, tab_rq_status[0]);
103 103 nb_fail++;
104 104 } else {
105   - ret = read_coil_status(&mb_param, SLAVE, addr, 1, tab_rp_status);
  105 + ret = read_coil_status(&mb_param, addr, 1, tab_rp_status);
106 106 if (ret != 1 || tab_rq_status[0] != tab_rp_status[0]) {
107 107 printf("ERROR read_coil_status single (%d)\n", ret);
108 108 printf("Slave = %d, address = %d\n",
... ... @@ -112,14 +112,14 @@ int main(void)
112 112 }
113 113  
114 114 /* MULTIPLE COILS */
115   - ret = force_multiple_coils(&mb_param, SLAVE, addr, nb, tab_rq_status);
  115 + ret = force_multiple_coils(&mb_param, addr, nb, tab_rq_status);
116 116 if (ret != nb) {
117 117 printf("ERROR force_multiple_coils (%d)\n", ret);
118 118 printf("Slave = %d, address = %d, nb = %d\n",
119 119 SLAVE, addr, nb);
120 120 nb_fail++;
121 121 } else {
122   - ret = read_coil_status(&mb_param, SLAVE, addr, nb, tab_rp_status);
  122 + ret = read_coil_status(&mb_param, addr, nb, tab_rp_status);
123 123 if (ret != nb) {
124 124 printf("ERROR read_coil_status\n");
125 125 printf("Slave = %d, address = %d, nb = %d\n",
... ... @@ -140,15 +140,14 @@ int main(void)
140 140 }
141 141  
142 142 /* SINGLE REGISTER */
143   - ret = preset_single_register(&mb_param, SLAVE, addr, tab_rq_registers[0]);
  143 + ret = preset_single_register(&mb_param, addr, tab_rq_registers[0]);
144 144 if (ret != 1) {
145 145 printf("ERROR preset_single_register (%d)\n", ret);
146 146 printf("Slave = %d, address = %d, value = %d (0x%X)\n",
147 147 SLAVE, addr, tab_rq_registers[0], tab_rq_registers[0]);
148 148 nb_fail++;
149 149 } else {
150   - ret = read_holding_registers(&mb_param, SLAVE,
151   - addr, 1, tab_rp_registers);
  150 + ret = read_holding_registers(&mb_param, addr, 1, tab_rp_registers);
152 151 if (ret != 1) {
153 152 printf("ERROR read_holding_registers single (%d)\n", ret);
154 153 printf("Slave = %d, address = %d\n",
... ... @@ -167,16 +166,16 @@ int main(void)
167 166 }
168 167  
169 168 /* MULTIPLE REGISTERS */
170   - ret = preset_multiple_registers(&mb_param, SLAVE,
171   - addr, nb, tab_rq_registers);
  169 + ret = preset_multiple_registers(&mb_param, addr, nb,
  170 + tab_rq_registers);
172 171 if (ret != nb) {
173 172 printf("ERROR preset_multiple_registers (%d)\n", ret);
174 173 printf("Slave = %d, address = %d, nb = %d\n",
175 174 SLAVE, addr, nb);
176 175 nb_fail++;
177 176 } else {
178   - ret = read_holding_registers(&mb_param, SLAVE,
179   - addr, nb, tab_rp_registers);
  177 + ret = read_holding_registers(&mb_param, addr, nb,
  178 + tab_rp_registers);
180 179 if (ret != nb) {
181 180 printf("ERROR read_holding_registers (%d)\n", ret);
182 181 printf("Slave = %d, address = %d, nb = %d\n",
... ...
tests/random-test-slave.c
... ... @@ -21,6 +21,8 @@
21 21  
22 22 #include "modbus.h"
23 23  
  24 +#define SLAVE 0x11
  25 +
24 26 int main(void)
25 27 {
26 28 int socket;
... ... @@ -28,7 +30,7 @@ int main(void)
28 30 modbus_mapping_t mb_mapping;
29 31 int ret;
30 32  
31   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  33 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE);
32 34 /* modbus_set_debug(&mb_param, TRUE); */
33 35  
34 36 ret = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500);
... ... @@ -46,7 +48,7 @@ int main(void)
46 48  
47 49 ret = modbus_slave_receive(&mb_param, -1, query, &query_size);
48 50 if (ret == 0) {
49   - modbus_manage_query(&mb_param, query, query_size, &mb_mapping);
  51 + modbus_slave_manage(&mb_param, query, query_size, &mb_mapping);
50 52 } else if (ret == CONNECTION_CLOSED) {
51 53 /* Connection closed by the client, end of server */
52 54 break;
... ...
tests/unit-test-master.c
... ... @@ -38,11 +38,12 @@ int main(void)
38 38 int ret;
39 39  
40 40 /* RTU parity : none, even, odd */
41   -/* modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, "none", 8, 1); */
  41 +/* modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, "none", 8, 1, SLAVE); */
42 42  
43 43 /* TCP */
44   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  44 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE);
45 45 /* modbus_set_debug(&mb_param, TRUE);*/
  46 + modbus_set_error_handling(&mb_param, NOP_ON_ERROR);
46 47  
47 48 if (modbus_connect(&mb_param) == -1) {
48 49 printf("ERROR Connection failed\n");
... ... @@ -69,7 +70,7 @@ int main(void)
69 70 /** COIL STATUS **/
70 71  
71 72 /* Single */
72   - ret = force_single_coil(&mb_param, SLAVE, UT_COIL_STATUS_ADDRESS, ON);
  73 + ret = force_single_coil(&mb_param, UT_COIL_STATUS_ADDRESS, ON);
73 74 printf("1/2 force_single_coil: ");
74 75 if (ret == 1) {
75 76 printf("OK\n");
... ... @@ -78,7 +79,7 @@ int main(void)
78 79 goto close;
79 80 }
80 81  
81   - ret = read_coil_status(&mb_param, SLAVE, UT_COIL_STATUS_ADDRESS, 1,
  82 + ret = read_coil_status(&mb_param, UT_COIL_STATUS_ADDRESS, 1,
82 83 tab_rp_status);
83 84 printf("2/2 read_coil_status: ");
84 85 if (ret != 1) {
... ... @@ -99,7 +100,7 @@ int main(void)
99 100  
100 101 set_bits_from_bytes(tab_value, 0, UT_COIL_STATUS_NB_POINTS,
101 102 UT_COIL_STATUS_TAB);
102   - ret = force_multiple_coils(&mb_param, SLAVE,
  103 + ret = force_multiple_coils(&mb_param,
103 104 UT_COIL_STATUS_ADDRESS,
104 105 UT_COIL_STATUS_NB_POINTS,
105 106 tab_value);
... ... @@ -112,7 +113,7 @@ int main(void)
112 113 }
113 114 }
114 115  
115   - ret = read_coil_status(&mb_param, SLAVE, UT_COIL_STATUS_ADDRESS,
  116 + ret = read_coil_status(&mb_param, UT_COIL_STATUS_ADDRESS,
116 117 UT_COIL_STATUS_NB_POINTS, tab_rp_status);
117 118 printf("2/2 read_coil_status: ");
118 119 if (ret != UT_COIL_STATUS_NB_POINTS) {
... ... @@ -140,7 +141,7 @@ int main(void)
140 141 /* End of multiple coils */
141 142  
142 143 /** INPUT STATUS **/
143   - ret = read_input_status(&mb_param, SLAVE, UT_INPUT_STATUS_ADDRESS,
  144 + ret = read_input_status(&mb_param, UT_INPUT_STATUS_ADDRESS,
144 145 UT_INPUT_STATUS_NB_POINTS, tab_rp_status);
145 146 printf("1/1 read_input_status: ");
146 147  
... ... @@ -170,7 +171,7 @@ int main(void)
170 171 /** HOLDING REGISTERS **/
171 172  
172 173 /* Single register */
173   - ret = preset_single_register(&mb_param, SLAVE,
  174 + ret = preset_single_register(&mb_param,
174 175 UT_HOLDING_REGISTERS_ADDRESS, 0x1234);
175 176 printf("1/2 preset_single_register: ");
176 177 if (ret == 1) {
... ... @@ -180,7 +181,7 @@ int main(void)
180 181 goto close;
181 182 }
182 183  
183   - ret = read_holding_registers(&mb_param, SLAVE,
  184 + ret = read_holding_registers(&mb_param,
184 185 UT_HOLDING_REGISTERS_ADDRESS,
185 186 1, tab_rp_registers);
186 187 printf("2/2 read_holding_registers: ");
... ... @@ -198,7 +199,7 @@ int main(void)
198 199 /* End of single register */
199 200  
200 201 /* Many registers */
201   - ret = preset_multiple_registers(&mb_param, SLAVE,
  202 + ret = preset_multiple_registers(&mb_param,
202 203 UT_HOLDING_REGISTERS_ADDRESS,
203 204 UT_HOLDING_REGISTERS_NB_POINTS,
204 205 UT_HOLDING_REGISTERS_TAB);
... ... @@ -211,7 +212,7 @@ int main(void)
211 212 }
212 213  
213 214 ret = read_holding_registers(&mb_param,
214   - SLAVE, UT_HOLDING_REGISTERS_ADDRESS,
  215 + UT_HOLDING_REGISTERS_ADDRESS,
215 216 UT_HOLDING_REGISTERS_NB_POINTS,
216 217 tab_rp_registers);
217 218 printf("2/2 read_holding_registers: ");
... ... @@ -234,7 +235,7 @@ int main(void)
234 235  
235 236 /** INPUT REGISTERS **/
236 237 ret = read_input_registers(&mb_param,
237   - SLAVE, UT_INPUT_REGISTERS_ADDRESS,
  238 + UT_INPUT_REGISTERS_ADDRESS,
238 239 UT_INPUT_REGISTERS_NB_POINTS,
239 240 tab_rp_registers);
240 241 printf("1/1 read_input_registers: ");
... ... @@ -259,7 +260,7 @@ int main(void)
259 260 /* The mapping begins at 0 and ending at address + nb_points so
260 261 * the addresses below are not valid. */
261 262  
262   - ret = read_coil_status(&mb_param, SLAVE,
  263 + ret = read_coil_status(&mb_param,
263 264 UT_COIL_STATUS_ADDRESS,
264 265 UT_COIL_STATUS_NB_POINTS + 1,
265 266 tab_rp_status);
... ... @@ -269,7 +270,7 @@ int main(void)
269 270 else
270 271 printf("FAILED\n");
271 272  
272   - ret = read_input_status(&mb_param, SLAVE,
  273 + ret = read_input_status(&mb_param,
273 274 UT_INPUT_STATUS_ADDRESS,
274 275 UT_INPUT_STATUS_NB_POINTS + 1,
275 276 tab_rp_status);
... ... @@ -279,7 +280,7 @@ int main(void)
279 280 else
280 281 printf("FAILED\n");
281 282  
282   - ret = read_holding_registers(&mb_param, SLAVE,
  283 + ret = read_holding_registers(&mb_param,
283 284 UT_HOLDING_REGISTERS_ADDRESS,
284 285 UT_HOLDING_REGISTERS_NB_POINTS + 1,
285 286 tab_rp_registers);
... ... @@ -289,7 +290,7 @@ int main(void)
289 290 else
290 291 printf("FAILED\n");
291 292  
292   - ret = read_input_registers(&mb_param, SLAVE,
  293 + ret = read_input_registers(&mb_param,
293 294 UT_INPUT_REGISTERS_ADDRESS,
294 295 UT_INPUT_REGISTERS_NB_POINTS + 1,
295 296 tab_rp_registers);
... ... @@ -299,7 +300,7 @@ int main(void)
299 300 else
300 301 printf("FAILED\n");
301 302  
302   - ret = force_single_coil(&mb_param, SLAVE,
  303 + ret = force_single_coil(&mb_param,
303 304 UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
304 305 ON);
305 306 printf("* force_single_coil: ");
... ... @@ -309,7 +310,7 @@ int main(void)
309 310 printf("FAILED\n");
310 311 }
311 312  
312   - ret = force_multiple_coils(&mb_param, SLAVE,
  313 + ret = force_multiple_coils(&mb_param,
313 314 UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
314 315 UT_COIL_STATUS_NB_POINTS,
315 316 tab_rp_status);
... ... @@ -320,7 +321,7 @@ int main(void)
320 321 printf("FAILED\n");
321 322 }
322 323  
323   - ret = preset_multiple_registers(&mb_param, SLAVE,
  324 + ret = preset_multiple_registers(&mb_param,
324 325 UT_HOLDING_REGISTERS_ADDRESS + UT_HOLDING_REGISTERS_NB_POINTS,
325 326 UT_HOLDING_REGISTERS_NB_POINTS,
326 327 tab_rp_registers);
... ... @@ -335,7 +336,7 @@ int main(void)
335 336 /** TOO MANY DATA **/
336 337 printf("\nTEST TOO MANY DATA ERROR:\n");
337 338  
338   - ret = read_coil_status(&mb_param, SLAVE,
  339 + ret = read_coil_status(&mb_param,
339 340 UT_COIL_STATUS_ADDRESS,
340 341 MAX_STATUS + 1,
341 342 tab_rp_status);
... ... @@ -345,7 +346,7 @@ int main(void)
345 346 else
346 347 printf("FAILED\n");
347 348  
348   - ret = read_input_status(&mb_param, SLAVE,
  349 + ret = read_input_status(&mb_param,
349 350 UT_INPUT_STATUS_ADDRESS,
350 351 MAX_STATUS + 1,
351 352 tab_rp_status);
... ... @@ -355,7 +356,7 @@ int main(void)
355 356 else
356 357 printf("FAILED\n");
357 358  
358   - ret = read_holding_registers(&mb_param, SLAVE,
  359 + ret = read_holding_registers(&mb_param,
359 360 UT_HOLDING_REGISTERS_ADDRESS,
360 361 MAX_REGISTERS + 1,
361 362 tab_rp_registers);
... ... @@ -365,7 +366,7 @@ int main(void)
365 366 else
366 367 printf("FAILED\n");
367 368  
368   - ret = read_input_registers(&mb_param, SLAVE,
  369 + ret = read_input_registers(&mb_param,
369 370 UT_INPUT_REGISTERS_ADDRESS,
370 371 MAX_REGISTERS + 1,
371 372 tab_rp_registers);
... ... @@ -375,7 +376,7 @@ int main(void)
375 376 else
376 377 printf("FAILED\n");
377 378  
378   - ret = force_multiple_coils(&mb_param, SLAVE,
  379 + ret = force_multiple_coils(&mb_param,
379 380 UT_COIL_STATUS_ADDRESS,
380 381 MAX_STATUS + 1,
381 382 tab_rp_status);
... ... @@ -386,7 +387,7 @@ int main(void)
386 387 printf("FAILED\n");
387 388 }
388 389  
389   - ret = preset_multiple_registers(&mb_param, SLAVE,
  390 + ret = preset_multiple_registers(&mb_param,
390 391 UT_HOLDING_REGISTERS_ADDRESS,
391 392 MAX_REGISTERS + 1,
392 393 tab_rp_registers);
... ... @@ -397,6 +398,33 @@ int main(void)
397 398 printf("FAILED\n");
398 399 }
399 400  
  401 + /** SLAVE REPLY **/
  402 + printf("\nTEST SLAVE REPLY:\n");
  403 +
  404 + mb_param.slave = 0x12;
  405 + ret = read_holding_registers(&mb_param,
  406 + UT_HOLDING_REGISTERS_ADDRESS+1,
  407 + UT_HOLDING_REGISTERS_NB_POINTS,
  408 + tab_rp_registers);
  409 + printf("1/2 No reply from slave %d: ", mb_param.slave);
  410 + if (ret != UT_HOLDING_REGISTERS_NB_POINTS) {
  411 + printf("OK\n", ret);
  412 + } else {
  413 + printf("FAILED\n");
  414 + }
  415 +
  416 + mb_param.slave = MODBUS_BROADCAST_ADDRESS;
  417 + ret = read_holding_registers(&mb_param,
  418 + UT_HOLDING_REGISTERS_ADDRESS,
  419 + UT_HOLDING_REGISTERS_NB_POINTS,
  420 + tab_rp_registers);
  421 + printf("2/2 Reply after a broadcast query: ");
  422 + if (ret == UT_HOLDING_REGISTERS_NB_POINTS) {
  423 + printf("OK\n", ret);
  424 + } else {
  425 + printf("FAILED\n");
  426 + }
  427 +
400 428 /** BAD RESPONSE **/
401 429 printf("\nTEST BAD RESPONSE ERROR:\n");
402 430  
... ... @@ -404,7 +432,7 @@ int main(void)
404 432 uint16_t *tab_rp_registers_bad = (uint16_t *) malloc(
405 433 UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL * sizeof(uint16_t));
406 434 ret = read_holding_registers(&mb_param,
407   - SLAVE, UT_HOLDING_REGISTERS_ADDRESS,
  435 + UT_HOLDING_REGISTERS_ADDRESS,
408 436 UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL,
409 437 tab_rp_registers_bad);
410 438 printf("* read_holding_registers: ");
... ...
tests/unit-test-slave.c
... ... @@ -31,7 +31,7 @@ int main(void)
31 31 int ret;
32 32 int i;
33 33  
34   - modbus_init_tcp(&mb_param, "127.0.0.1", 1502);
  34 + modbus_init_tcp(&mb_param, "127.0.0.1", 1502, SLAVE);
35 35 modbus_set_debug(&mb_param, TRUE);
36 36  
37 37 ret = modbus_mapping_new(&mb_mapping,
... ... @@ -75,7 +75,7 @@ int main(void)
75 75 query[HEADER_LENGTH_TCP + 4] = UT_HOLDING_REGISTERS_NB_POINTS;
76 76 }
77 77  
78   - modbus_manage_query(&mb_param, query, query_size, &mb_mapping);
  78 + modbus_slave_manage(&mb_param, query, query_size, &mb_mapping);
79 79 } else if (ret == CONNECTION_CLOSED) {
80 80 /* Connection closed by the client, end of server */
81 81 break;
... ...
tests/unit-test.h
... ... @@ -20,6 +20,8 @@
20 20  
21 21 #include <stdint.h>
22 22  
  23 +#define SLAVE 0x11
  24 +
23 25 const uint16_t UT_COIL_STATUS_ADDRESS = 0x13;
24 26 const uint16_t UT_COIL_STATUS_NB_POINTS = 0x25;
25 27 const uint8_t UT_COIL_STATUS_TAB[] = { 0xCD, 0x6B, 0xB2, 0x0E, 0x1B };
... ...