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 int modbus_slave_init_tcp(modbus_param_t *mb_param, int nb_connection); 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 int modbus_slave_accept_tcp(modbus_param_t *mb_param, int *socket); 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 int modbus_slave_receive(modbus_param_t *mb_param, int sockfd, 27 int modbus_slave_receive(modbus_param_t *mb_param, int sockfd,
22 uint8_t *query, int *query_length); 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 Init 42 Init
36 ==== 43 ====
1 libmodbus 2.2.0 (2009-05-01) 1 libmodbus 2.2.0 (2009-05-01)
2 ============================ 2 ============================
3 - New API for slave server (see MIGRATION) 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 - modbus_param_t is smaller (2 int removed) 7 - modbus_param_t is smaller (2 int removed)
  8 +- Faster
5 9
6 libmodbus 2.0.3 (2009-03-22) 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,16 +259,16 @@ static int build_query_basis_tcp(int slave, int function,
259 return PRESET_QUERY_LENGTH_TCP; 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 int function, int start_addr, 263 int function, int start_addr,
264 int nb, uint8_t *query) 264 int nb, uint8_t *query)
265 { 265 {
266 if (mb_param->type_com == RTU) 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 else 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 /* Builds a RTU response header */ 274 /* Builds a RTU response header */
@@ -798,7 +798,7 @@ static int response_exception(modbus_param_t *mb_param, sft_t *sft, @@ -798,7 +798,7 @@ static int response_exception(modbus_param_t *mb_param, sft_t *sft,
798 If an error occurs, this function construct the response 798 If an error occurs, this function construct the response
799 accordingly. 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 int query_length, modbus_mapping_t *mb_mapping) 802 int query_length, modbus_mapping_t *mb_mapping)
803 { 803 {
804 int offset = TAB_HEADER_LENGTH[mb_param->type_com]; 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,6 +808,14 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
808 uint8_t response[MAX_MESSAGE_LENGTH]; 808 uint8_t response[MAX_MESSAGE_LENGTH];
809 int resp_length = 0; 809 int resp_length = 0;
810 sft_t sft; 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 sft.slave = slave; 820 sft.slave = slave;
813 sft.function = function; 821 sft.function = function;
@@ -987,7 +995,7 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query, @@ -987,7 +995,7 @@ void modbus_manage_query(modbus_param_t *mb_param, const uint8_t *query,
987 } 995 }
988 996
989 /* Reads IO status */ 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 int start_addr, int nb, uint8_t *data_dest) 999 int start_addr, int nb, uint8_t *data_dest)
992 { 1000 {
993 int ret; 1001 int ret;
@@ -996,7 +1004,7 @@ static int read_io_status(modbus_param_t *mb_param, int slave, int function, @@ -996,7 +1004,7 @@ static int read_io_status(modbus_param_t *mb_param, int slave, int function,
996 uint8_t query[MIN_QUERY_LENGTH]; 1004 uint8_t query[MIN_QUERY_LENGTH];
997 uint8_t response[MAX_MESSAGE_LENGTH]; 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 start_addr, nb, query); 1008 start_addr, nb, query);
1001 1009
1002 ret = modbus_send(mb_param, query, query_length); 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,7 +1037,7 @@ static int read_io_status(modbus_param_t *mb_param, int slave, int function,
1029 1037
1030 /* Reads the boolean status of coils and sets the array elements 1038 /* Reads the boolean status of coils and sets the array elements
1031 in the destination to TRUE or FALSE. */ 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 int nb, uint8_t *data_dest) 1041 int nb, uint8_t *data_dest)
1034 { 1042 {
1035 int status; 1043 int status;
@@ -1040,7 +1048,7 @@ int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr, @@ -1040,7 +1048,7 @@ int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
1040 return TOO_MANY_DATA; 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 start_addr, nb, data_dest); 1052 start_addr, nb, data_dest);
1045 1053
1046 if (status > 0) 1054 if (status > 0)
@@ -1051,7 +1059,7 @@ int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr, @@ -1051,7 +1059,7 @@ int read_coil_status(modbus_param_t *mb_param, int slave, int start_addr,
1051 1059
1052 1060
1053 /* Same as read_coil_status but reads the slaves input table */ 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 int nb, uint8_t *data_dest) 1063 int nb, uint8_t *data_dest)
1056 { 1064 {
1057 int status; 1065 int status;
@@ -1062,7 +1070,7 @@ int read_input_status(modbus_param_t *mb_param, int slave, int start_addr, @@ -1062,7 +1070,7 @@ int read_input_status(modbus_param_t *mb_param, int slave, int start_addr,
1062 return TOO_MANY_DATA; 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 start_addr, nb, data_dest); 1074 start_addr, nb, data_dest);
1067 1075
1068 if (status > 0) 1076 if (status > 0)
@@ -1072,7 +1080,7 @@ int read_input_status(modbus_param_t *mb_param, int slave, int start_addr, @@ -1072,7 +1080,7 @@ int read_input_status(modbus_param_t *mb_param, int slave, int start_addr,
1072 } 1080 }
1073 1081
1074 /* Reads the data from a modbus slave and put that data into an array */ 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 int start_addr, int nb, uint16_t *data_dest) 1084 int start_addr, int nb, uint16_t *data_dest)
1077 { 1085 {
1078 int ret; 1086 int ret;
@@ -1086,7 +1094,7 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function, @@ -1086,7 +1094,7 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function,
1086 return TOO_MANY_DATA; 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 start_addr, nb, query); 1098 start_addr, nb, query);
1091 1099
1092 ret = modbus_send(mb_param, query, query_length); 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,7 +1119,7 @@ static int read_registers(modbus_param_t *mb_param, int slave, int function,
1111 1119
1112 /* Reads the holding registers in a slave and put the data into an 1120 /* Reads the holding registers in a slave and put the data into an
1113 array */ 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 int start_addr, int nb, uint16_t *data_dest) 1123 int start_addr, int nb, uint16_t *data_dest)
1116 { 1124 {
1117 int status; 1125 int status;
@@ -1122,15 +1130,15 @@ int read_holding_registers(modbus_param_t *mb_param, int slave, @@ -1122,15 +1130,15 @@ int read_holding_registers(modbus_param_t *mb_param, int slave,
1122 return TOO_MANY_DATA; 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 start_addr, nb, data_dest); 1134 start_addr, nb, data_dest);
1127 return status; 1135 return status;
1128 } 1136 }
1129 1137
1130 /* Reads the input registers in a slave and put the data into 1138 /* Reads the input registers in a slave and put the data into
1131 an array */ 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 int status; 1143 int status;
1136 1144
@@ -1140,7 +1148,7 @@ int read_input_registers(modbus_param_t *mb_param, int slave, @@ -1140,7 +1148,7 @@ int read_input_registers(modbus_param_t *mb_param, int slave,
1140 return TOO_MANY_DATA; 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 start_addr, nb, data_dest); 1152 start_addr, nb, data_dest);
1145 1153
1146 return status; 1154 return status;
@@ -1148,14 +1156,14 @@ int read_input_registers(modbus_param_t *mb_param, int slave, @@ -1148,14 +1156,14 @@ int read_input_registers(modbus_param_t *mb_param, int slave,
1148 1156
1149 /* Sends a value to a register in a slave. 1157 /* Sends a value to a register in a slave.
1150 Used by force_single_coil and preset_single_register */ 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 int addr, int value) 1160 int addr, int value)
1153 { 1161 {
1154 int ret; 1162 int ret;
1155 int query_length; 1163 int query_length;
1156 uint8_t query[MIN_QUERY_LENGTH]; 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 addr, value, query); 1167 addr, value, query);
1160 1168
1161 ret = modbus_send(mb_param, query, query_length); 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,35 +1178,32 @@ static int set_single(modbus_param_t *mb_param, int slave, int function,
1170 } 1178 }
1171 1179
1172 /* Turns ON or OFF a single coil in the slave device */ 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 int status; 1183 int status;
1177 1184
1178 if (state) 1185 if (state)
1179 state = 0xFF00; 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 coil_addr, state); 1189 coil_addr, state);
1183 1190
1184 return status; 1191 return status;
1185 } 1192 }
1186 1193
1187 /* Sets a value in one holding register in the slave device */ 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 int status; 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 reg_addr, value); 1200 reg_addr, value);
1195 1201
1196 return status; 1202 return status;
1197 } 1203 }
1198 1204
1199 /* Sets/resets the coils in the slave from an array in argument */ 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 const uint8_t *data_src) 1207 const uint8_t *data_src)
1203 { 1208 {
1204 int ret; 1209 int ret;
@@ -1216,8 +1221,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int slave, @@ -1216,8 +1221,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int slave,
1216 return TOO_MANY_DATA; 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 start_addr, nb, query); 1225 start_addr, nb, query);
1222 byte_count = (nb / 8) + ((nb % 8) ? 1 : 0); 1226 byte_count = (nb / 8) + ((nb % 8) ? 1 : 0);
1223 query[query_length++] = byte_count; 1227 query[query_length++] = byte_count;
@@ -1250,8 +1254,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int slave, @@ -1250,8 +1254,7 @@ int force_multiple_coils(modbus_param_t *mb_param, int slave,
1250 } 1254 }
1251 1255
1252 /* Copies the values in the slave from the array given in argument */ 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 const uint16_t *data_src) 1258 const uint16_t *data_src)
1256 { 1259 {
1257 int ret; 1260 int ret;
@@ -1267,8 +1270,7 @@ int preset_multiple_registers(modbus_param_t *mb_param, int slave, @@ -1267,8 +1270,7 @@ int preset_multiple_registers(modbus_param_t *mb_param, int slave,
1267 return TOO_MANY_DATA; 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 start_addr, nb, query); 1274 start_addr, nb, query);
1273 byte_count = nb * 2; 1275 byte_count = nb * 2;
1274 query[query_length++] = byte_count; 1276 query[query_length++] = byte_count;
@@ -1288,15 +1290,13 @@ int preset_multiple_registers(modbus_param_t *mb_param, int slave, @@ -1288,15 +1290,13 @@ int preset_multiple_registers(modbus_param_t *mb_param, int slave,
1288 } 1290 }
1289 1291
1290 /* Returns the slave id! */ 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 int ret; 1295 int ret;
1295 int query_length; 1296 int query_length;
1296 uint8_t query[MIN_QUERY_LENGTH]; 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 /* HACKISH, start_addr and count are not used */ 1301 /* HACKISH, start_addr and count are not used */
1302 query_length -= 4; 1302 query_length -= 4;
@@ -1333,7 +1333,7 @@ int report_slave_id(modbus_param_t *mb_param, int slave, @@ -1333,7 +1333,7 @@ int report_slave_id(modbus_param_t *mb_param, int slave,
1333 */ 1333 */
1334 void modbus_init_rtu(modbus_param_t *mb_param, const char *device, 1334 void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1335 int baud, const char *parity, int data_bit, 1335 int baud, const char *parity, int data_bit,
1336 - int stop_bit) 1336 + int stop_bit, int slave)
1337 { 1337 {
1338 memset(mb_param, 0, sizeof(modbus_param_t)); 1338 memset(mb_param, 0, sizeof(modbus_param_t));
1339 strcpy(mb_param->device, device); 1339 strcpy(mb_param->device, device);
@@ -1344,6 +1344,7 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device, @@ -1344,6 +1344,7 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1344 mb_param->stop_bit = stop_bit; 1344 mb_param->stop_bit = stop_bit;
1345 mb_param->type_com = RTU; 1345 mb_param->type_com = RTU;
1346 mb_param->error_handling = FLUSH_OR_RECONNECT_ON_ERROR; 1346 mb_param->error_handling = FLUSH_OR_RECONNECT_ON_ERROR;
  1347 + mb_param->slave = slave;
1347 } 1348 }
1348 1349
1349 /* Initializes the modbus_param_t structure for TCP. 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,13 +1356,14 @@ void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
1355 to 1024 because it's not necessary to be root to use this port 1356 to 1024 because it's not necessary to be root to use this port
1356 number. 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 memset(mb_param, 0, sizeof(modbus_param_t)); 1361 memset(mb_param, 0, sizeof(modbus_param_t));
1361 strncpy(mb_param->ip, ip, sizeof(char)*16); 1362 strncpy(mb_param->ip, ip, sizeof(char)*16);
1362 mb_param->port = port; 1363 mb_param->port = port;
1363 mb_param->type_com = TCP; 1364 mb_param->type_com = TCP;
1364 mb_param->error_handling = FLUSH_OR_RECONNECT_ON_ERROR; 1365 mb_param->error_handling = FLUSH_OR_RECONNECT_ON_ERROR;
  1366 + mb_param->slave = slave;
1365 } 1367 }
1366 1368
1367 /* By default, the error handling mode used is FLUSH_OR_RECONNECT_ON_ERROR. 1369 /* By default, the error handling mode used is FLUSH_OR_RECONNECT_ON_ERROR.
src/modbus.h
@@ -27,6 +27,7 @@ extern "C" { @@ -27,6 +27,7 @@ extern "C" {
27 #endif 27 #endif
28 28
29 #define MODBUS_TCP_DEFAULT_PORT 502 29 #define MODBUS_TCP_DEFAULT_PORT 502
  30 +#define MODBUS_BROADCAST_ADDRESS 255
30 31
31 /* Slave index */ 32 /* Slave index */
32 #define HEADER_LENGTH_RTU 1 33 #define HEADER_LENGTH_RTU 1
@@ -135,6 +136,8 @@ typedef enum { FLUSH_OR_RECONNECT_ON_ERROR, NOP_ON_ERROR } error_handling_t; @@ -135,6 +136,8 @@ typedef enum { FLUSH_OR_RECONNECT_ON_ERROR, NOP_ON_ERROR } error_handling_t;
135 136
136 /* This structure is byte-aligned */ 137 /* This structure is byte-aligned */
137 typedef struct { 138 typedef struct {
  139 + /* Slave address */
  140 + int slave;
138 /* Descriptor (tty or socket) */ 141 /* Descriptor (tty or socket) */
139 int fd; 142 int fd;
140 /* Communication mode: RTU or TCP */ 143 /* Communication mode: RTU or TCP */
@@ -189,41 +192,39 @@ typedef struct { @@ -189,41 +192,39 @@ typedef struct {
189 192
190 /* Reads the boolean status of coils and sets the array elements in 193 /* Reads the boolean status of coils and sets the array elements in
191 the destination to TRUE or FALSE */ 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 /* Same as read_coil_status but reads the slaves input table */ 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 /* Reads the holding registers in a slave and put the data into an 202 /* Reads the holding registers in a slave and put the data into an
200 array */ 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 /* Reads the input registers in a slave and put the data into an 207 /* Reads the input registers in a slave and put the data into an
205 array */ 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 /* Turns ON or OFF a single coil in the slave device */ 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 /* Sets a value in one holding register in the slave device */ 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 /* Sets/resets the coils in the slave from an array in argument */ 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 /* Copies the values in the slave from the array given in argument */ 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 /* Returns the slave id! */ 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 /* Initializes the modbus_param_t structure for RTU. 229 /* Initializes the modbus_param_t structure for RTU.
229 - device: "/dev/ttyS0" 230 - device: "/dev/ttyS0"
@@ -234,18 +235,20 @@ int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *dest); @@ -234,18 +235,20 @@ int report_slave_id(modbus_param_t *mb_param, int slave, uint8_t *dest);
234 */ 235 */
235 void modbus_init_rtu(modbus_param_t *mb_param, const char *device, 236 void modbus_init_rtu(modbus_param_t *mb_param, const char *device,
236 int baud, const char *parity, int data_bit, 237 int baud, const char *parity, int data_bit,
237 - int stop_bit); 238 + int stop_bit, int slave);
238 239
239 /* Initializes the modbus_param_t structure for TCP. 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 Set the port to MODBUS_TCP_DEFAULT_PORT to use the default one 245 Set the port to MODBUS_TCP_DEFAULT_PORT to use the default one
244 (502). It's convenient to use a port number greater than or equal 246 (502). It's convenient to use a port number greater than or equal
245 to 1024 because it's not necessary to be root to use this port 247 to 1024 because it's not necessary to be root to use this port
246 number. 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 /* By default, the error handling mode used is RECONNECT_ON_ERROR. 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,7 +315,7 @@ int modbus_slave_receive(modbus_param_t *mb_param, int sockfd,
312 If an error occurs, this function construct the response 315 If an error occurs, this function construct the response
313 accordingly. 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 int query_length, modbus_mapping_t *mb_mapping); 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,7 +53,7 @@ int main(void)
53 uint32_t rate; 53 uint32_t rate;
54 54
55 /* TCP */ 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 if (modbus_connect(&mb_param) == -1) { 57 if (modbus_connect(&mb_param) == -1) {
58 printf("ERROR Connection failed\n"); 58 printf("ERROR Connection failed\n");
59 exit(1); 59 exit(1);
@@ -72,7 +72,7 @@ int main(void) @@ -72,7 +72,7 @@ int main(void)
72 nb_points = MAX_STATUS; 72 nb_points = MAX_STATUS;
73 start = gettime_ms(); 73 start = gettime_ms();
74 for (i=0; i<NB_LOOPS; i++) { 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 end = gettime_ms(); 77 end = gettime_ms();
78 elapsed = end - start; 78 elapsed = end - start;
@@ -105,7 +105,7 @@ int main(void) @@ -105,7 +105,7 @@ int main(void)
105 nb_points = MAX_REGISTERS; 105 nb_points = MAX_REGISTERS;
106 start = gettime_ms(); 106 start = gettime_ms();
107 for (i=0; i<NB_LOOPS; i++) { 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 end = gettime_ms(); 110 end = gettime_ms();
111 elapsed = end - start; 111 elapsed = end - start;
tests/bandwidth-slave-many-up.c
@@ -24,7 +24,9 @@ @@ -24,7 +24,9 @@
24 24
25 #include "modbus.h" 25 #include "modbus.h"
26 26
27 -#define NB_CONNECTION 5 27 +#define SLAVE 0x11
  28 +#define NB_CONNECTION 5
  29 +
28 int slave_socket; 30 int slave_socket;
29 modbus_mapping_t mb_mapping; 31 modbus_mapping_t mb_mapping;
30 32
@@ -48,7 +50,7 @@ int main(void) @@ -48,7 +50,7 @@ int main(void)
48 /* Maximum file descriptor number */ 50 /* Maximum file descriptor number */
49 int fdmax; 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 ret = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0); 55 ret = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
54 if (ret == FALSE) { 56 if (ret == FALSE) {
@@ -109,7 +111,7 @@ int main(void) @@ -109,7 +111,7 @@ int main(void)
109 111
110 ret = modbus_slave_receive(&mb_param, master_socket, query, &query_size); 112 ret = modbus_slave_receive(&mb_param, master_socket, query, &query_size);
111 if (ret == 0) { 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 } else { 115 } else {
114 /* Connection closed by the client, end of server */ 116 /* Connection closed by the client, end of server */
115 printf("Connection closed on socket %d\n", master_socket); 117 printf("Connection closed on socket %d\n", master_socket);
tests/bandwidth-slave-one.c
@@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
22 22
23 #include "modbus.h" 23 #include "modbus.h"
24 24
  25 +#define SLAVE 0x11
  26 +
25 int main(void) 27 int main(void)
26 { 28 {
27 int socket; 29 int socket;
@@ -29,7 +31,7 @@ int main(void) @@ -29,7 +31,7 @@ int main(void)
29 modbus_mapping_t mb_mapping; 31 modbus_mapping_t mb_mapping;
30 int ret; 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 ret = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0); 36 ret = modbus_mapping_new(&mb_mapping, MAX_STATUS, 0, MAX_REGISTERS, 0);
35 if (ret == FALSE) { 37 if (ret == FALSE) {
@@ -46,7 +48,7 @@ int main(void) @@ -46,7 +48,7 @@ int main(void)
46 48
47 ret = modbus_slave_receive(&mb_param, -1, query, &query_size); 49 ret = modbus_slave_receive(&mb_param, -1, query, &query_size);
48 if (ret == 0) { 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 } else if (ret == CONNECTION_CLOSED) { 52 } else if (ret == CONNECTION_CLOSED) {
51 /* Connection closed by the client, end of server */ 53 /* Connection closed by the client, end of server */
52 break; 54 break;
tests/random-test-master.c
@@ -60,7 +60,7 @@ int main(void) @@ -60,7 +60,7 @@ int main(void)
60 /* modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, "none", 8, 1); */ 60 /* modbus_init_rtu(&mb_param, "/dev/ttyS0", 19200, "none", 8, 1); */
61 61
62 /* TCP */ 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 modbus_set_debug(&mb_param, TRUE); 64 modbus_set_debug(&mb_param, TRUE);
65 if (modbus_connect(&mb_param) == -1) { 65 if (modbus_connect(&mb_param) == -1) {
66 printf("ERROR Connection failed\n"); 66 printf("ERROR Connection failed\n");
@@ -95,14 +95,14 @@ int main(void) @@ -95,14 +95,14 @@ int main(void)
95 nb = ADDRESS_END - addr; 95 nb = ADDRESS_END - addr;
96 96
97 /* SINGLE COIL */ 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 if (ret != 1) { 99 if (ret != 1) {
100 printf("ERROR force_single_coil (%d)\n", ret); 100 printf("ERROR force_single_coil (%d)\n", ret);
101 printf("Slave = %d, address = %d, value = %d\n", 101 printf("Slave = %d, address = %d, value = %d\n",
102 SLAVE, addr, tab_rq_status[0]); 102 SLAVE, addr, tab_rq_status[0]);
103 nb_fail++; 103 nb_fail++;
104 } else { 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 if (ret != 1 || tab_rq_status[0] != tab_rp_status[0]) { 106 if (ret != 1 || tab_rq_status[0] != tab_rp_status[0]) {
107 printf("ERROR read_coil_status single (%d)\n", ret); 107 printf("ERROR read_coil_status single (%d)\n", ret);
108 printf("Slave = %d, address = %d\n", 108 printf("Slave = %d, address = %d\n",
@@ -112,14 +112,14 @@ int main(void) @@ -112,14 +112,14 @@ int main(void)
112 } 112 }
113 113
114 /* MULTIPLE COILS */ 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 if (ret != nb) { 116 if (ret != nb) {
117 printf("ERROR force_multiple_coils (%d)\n", ret); 117 printf("ERROR force_multiple_coils (%d)\n", ret);
118 printf("Slave = %d, address = %d, nb = %d\n", 118 printf("Slave = %d, address = %d, nb = %d\n",
119 SLAVE, addr, nb); 119 SLAVE, addr, nb);
120 nb_fail++; 120 nb_fail++;
121 } else { 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 if (ret != nb) { 123 if (ret != nb) {
124 printf("ERROR read_coil_status\n"); 124 printf("ERROR read_coil_status\n");
125 printf("Slave = %d, address = %d, nb = %d\n", 125 printf("Slave = %d, address = %d, nb = %d\n",
@@ -140,15 +140,14 @@ int main(void) @@ -140,15 +140,14 @@ int main(void)
140 } 140 }
141 141
142 /* SINGLE REGISTER */ 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 if (ret != 1) { 144 if (ret != 1) {
145 printf("ERROR preset_single_register (%d)\n", ret); 145 printf("ERROR preset_single_register (%d)\n", ret);
146 printf("Slave = %d, address = %d, value = %d (0x%X)\n", 146 printf("Slave = %d, address = %d, value = %d (0x%X)\n",
147 SLAVE, addr, tab_rq_registers[0], tab_rq_registers[0]); 147 SLAVE, addr, tab_rq_registers[0], tab_rq_registers[0]);
148 nb_fail++; 148 nb_fail++;
149 } else { 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 if (ret != 1) { 151 if (ret != 1) {
153 printf("ERROR read_holding_registers single (%d)\n", ret); 152 printf("ERROR read_holding_registers single (%d)\n", ret);
154 printf("Slave = %d, address = %d\n", 153 printf("Slave = %d, address = %d\n",
@@ -167,16 +166,16 @@ int main(void) @@ -167,16 +166,16 @@ int main(void)
167 } 166 }
168 167
169 /* MULTIPLE REGISTERS */ 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 if (ret != nb) { 171 if (ret != nb) {
173 printf("ERROR preset_multiple_registers (%d)\n", ret); 172 printf("ERROR preset_multiple_registers (%d)\n", ret);
174 printf("Slave = %d, address = %d, nb = %d\n", 173 printf("Slave = %d, address = %d, nb = %d\n",
175 SLAVE, addr, nb); 174 SLAVE, addr, nb);
176 nb_fail++; 175 nb_fail++;
177 } else { 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 if (ret != nb) { 179 if (ret != nb) {
181 printf("ERROR read_holding_registers (%d)\n", ret); 180 printf("ERROR read_holding_registers (%d)\n", ret);
182 printf("Slave = %d, address = %d, nb = %d\n", 181 printf("Slave = %d, address = %d, nb = %d\n",
tests/random-test-slave.c
@@ -21,6 +21,8 @@ @@ -21,6 +21,8 @@
21 21
22 #include "modbus.h" 22 #include "modbus.h"
23 23
  24 +#define SLAVE 0x11
  25 +
24 int main(void) 26 int main(void)
25 { 27 {
26 int socket; 28 int socket;
@@ -28,7 +30,7 @@ int main(void) @@ -28,7 +30,7 @@ int main(void)
28 modbus_mapping_t mb_mapping; 30 modbus_mapping_t mb_mapping;
29 int ret; 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 /* modbus_set_debug(&mb_param, TRUE); */ 34 /* modbus_set_debug(&mb_param, TRUE); */
33 35
34 ret = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500); 36 ret = modbus_mapping_new(&mb_mapping, 500, 500, 500, 500);
@@ -46,7 +48,7 @@ int main(void) @@ -46,7 +48,7 @@ int main(void)
46 48
47 ret = modbus_slave_receive(&mb_param, -1, query, &query_size); 49 ret = modbus_slave_receive(&mb_param, -1, query, &query_size);
48 if (ret == 0) { 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 } else if (ret == CONNECTION_CLOSED) { 52 } else if (ret == CONNECTION_CLOSED) {
51 /* Connection closed by the client, end of server */ 53 /* Connection closed by the client, end of server */
52 break; 54 break;
tests/unit-test-master.c
@@ -38,11 +38,12 @@ int main(void) @@ -38,11 +38,12 @@ int main(void)
38 int ret; 38 int ret;
39 39
40 /* RTU parity : none, even, odd */ 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 /* TCP */ 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 /* modbus_set_debug(&mb_param, TRUE);*/ 45 /* modbus_set_debug(&mb_param, TRUE);*/
  46 + modbus_set_error_handling(&mb_param, NOP_ON_ERROR);
46 47
47 if (modbus_connect(&mb_param) == -1) { 48 if (modbus_connect(&mb_param) == -1) {
48 printf("ERROR Connection failed\n"); 49 printf("ERROR Connection failed\n");
@@ -69,7 +70,7 @@ int main(void) @@ -69,7 +70,7 @@ int main(void)
69 /** COIL STATUS **/ 70 /** COIL STATUS **/
70 71
71 /* Single */ 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 printf("1/2 force_single_coil: "); 74 printf("1/2 force_single_coil: ");
74 if (ret == 1) { 75 if (ret == 1) {
75 printf("OK\n"); 76 printf("OK\n");
@@ -78,7 +79,7 @@ int main(void) @@ -78,7 +79,7 @@ int main(void)
78 goto close; 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 tab_rp_status); 83 tab_rp_status);
83 printf("2/2 read_coil_status: "); 84 printf("2/2 read_coil_status: ");
84 if (ret != 1) { 85 if (ret != 1) {
@@ -99,7 +100,7 @@ int main(void) @@ -99,7 +100,7 @@ int main(void)
99 100
100 set_bits_from_bytes(tab_value, 0, UT_COIL_STATUS_NB_POINTS, 101 set_bits_from_bytes(tab_value, 0, UT_COIL_STATUS_NB_POINTS,
101 UT_COIL_STATUS_TAB); 102 UT_COIL_STATUS_TAB);
102 - ret = force_multiple_coils(&mb_param, SLAVE, 103 + ret = force_multiple_coils(&mb_param,
103 UT_COIL_STATUS_ADDRESS, 104 UT_COIL_STATUS_ADDRESS,
104 UT_COIL_STATUS_NB_POINTS, 105 UT_COIL_STATUS_NB_POINTS,
105 tab_value); 106 tab_value);
@@ -112,7 +113,7 @@ int main(void) @@ -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 UT_COIL_STATUS_NB_POINTS, tab_rp_status); 117 UT_COIL_STATUS_NB_POINTS, tab_rp_status);
117 printf("2/2 read_coil_status: "); 118 printf("2/2 read_coil_status: ");
118 if (ret != UT_COIL_STATUS_NB_POINTS) { 119 if (ret != UT_COIL_STATUS_NB_POINTS) {
@@ -140,7 +141,7 @@ int main(void) @@ -140,7 +141,7 @@ int main(void)
140 /* End of multiple coils */ 141 /* End of multiple coils */
141 142
142 /** INPUT STATUS **/ 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 UT_INPUT_STATUS_NB_POINTS, tab_rp_status); 145 UT_INPUT_STATUS_NB_POINTS, tab_rp_status);
145 printf("1/1 read_input_status: "); 146 printf("1/1 read_input_status: ");
146 147
@@ -170,7 +171,7 @@ int main(void) @@ -170,7 +171,7 @@ int main(void)
170 /** HOLDING REGISTERS **/ 171 /** HOLDING REGISTERS **/
171 172
172 /* Single register */ 173 /* Single register */
173 - ret = preset_single_register(&mb_param, SLAVE, 174 + ret = preset_single_register(&mb_param,
174 UT_HOLDING_REGISTERS_ADDRESS, 0x1234); 175 UT_HOLDING_REGISTERS_ADDRESS, 0x1234);
175 printf("1/2 preset_single_register: "); 176 printf("1/2 preset_single_register: ");
176 if (ret == 1) { 177 if (ret == 1) {
@@ -180,7 +181,7 @@ int main(void) @@ -180,7 +181,7 @@ int main(void)
180 goto close; 181 goto close;
181 } 182 }
182 183
183 - ret = read_holding_registers(&mb_param, SLAVE, 184 + ret = read_holding_registers(&mb_param,
184 UT_HOLDING_REGISTERS_ADDRESS, 185 UT_HOLDING_REGISTERS_ADDRESS,
185 1, tab_rp_registers); 186 1, tab_rp_registers);
186 printf("2/2 read_holding_registers: "); 187 printf("2/2 read_holding_registers: ");
@@ -198,7 +199,7 @@ int main(void) @@ -198,7 +199,7 @@ int main(void)
198 /* End of single register */ 199 /* End of single register */
199 200
200 /* Many registers */ 201 /* Many registers */
201 - ret = preset_multiple_registers(&mb_param, SLAVE, 202 + ret = preset_multiple_registers(&mb_param,
202 UT_HOLDING_REGISTERS_ADDRESS, 203 UT_HOLDING_REGISTERS_ADDRESS,
203 UT_HOLDING_REGISTERS_NB_POINTS, 204 UT_HOLDING_REGISTERS_NB_POINTS,
204 UT_HOLDING_REGISTERS_TAB); 205 UT_HOLDING_REGISTERS_TAB);
@@ -211,7 +212,7 @@ int main(void) @@ -211,7 +212,7 @@ int main(void)
211 } 212 }
212 213
213 ret = read_holding_registers(&mb_param, 214 ret = read_holding_registers(&mb_param,
214 - SLAVE, UT_HOLDING_REGISTERS_ADDRESS, 215 + UT_HOLDING_REGISTERS_ADDRESS,
215 UT_HOLDING_REGISTERS_NB_POINTS, 216 UT_HOLDING_REGISTERS_NB_POINTS,
216 tab_rp_registers); 217 tab_rp_registers);
217 printf("2/2 read_holding_registers: "); 218 printf("2/2 read_holding_registers: ");
@@ -234,7 +235,7 @@ int main(void) @@ -234,7 +235,7 @@ int main(void)
234 235
235 /** INPUT REGISTERS **/ 236 /** INPUT REGISTERS **/
236 ret = read_input_registers(&mb_param, 237 ret = read_input_registers(&mb_param,
237 - SLAVE, UT_INPUT_REGISTERS_ADDRESS, 238 + UT_INPUT_REGISTERS_ADDRESS,
238 UT_INPUT_REGISTERS_NB_POINTS, 239 UT_INPUT_REGISTERS_NB_POINTS,
239 tab_rp_registers); 240 tab_rp_registers);
240 printf("1/1 read_input_registers: "); 241 printf("1/1 read_input_registers: ");
@@ -259,7 +260,7 @@ int main(void) @@ -259,7 +260,7 @@ int main(void)
259 /* The mapping begins at 0 and ending at address + nb_points so 260 /* The mapping begins at 0 and ending at address + nb_points so
260 * the addresses below are not valid. */ 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 UT_COIL_STATUS_ADDRESS, 264 UT_COIL_STATUS_ADDRESS,
264 UT_COIL_STATUS_NB_POINTS + 1, 265 UT_COIL_STATUS_NB_POINTS + 1,
265 tab_rp_status); 266 tab_rp_status);
@@ -269,7 +270,7 @@ int main(void) @@ -269,7 +270,7 @@ int main(void)
269 else 270 else
270 printf("FAILED\n"); 271 printf("FAILED\n");
271 272
272 - ret = read_input_status(&mb_param, SLAVE, 273 + ret = read_input_status(&mb_param,
273 UT_INPUT_STATUS_ADDRESS, 274 UT_INPUT_STATUS_ADDRESS,
274 UT_INPUT_STATUS_NB_POINTS + 1, 275 UT_INPUT_STATUS_NB_POINTS + 1,
275 tab_rp_status); 276 tab_rp_status);
@@ -279,7 +280,7 @@ int main(void) @@ -279,7 +280,7 @@ int main(void)
279 else 280 else
280 printf("FAILED\n"); 281 printf("FAILED\n");
281 282
282 - ret = read_holding_registers(&mb_param, SLAVE, 283 + ret = read_holding_registers(&mb_param,
283 UT_HOLDING_REGISTERS_ADDRESS, 284 UT_HOLDING_REGISTERS_ADDRESS,
284 UT_HOLDING_REGISTERS_NB_POINTS + 1, 285 UT_HOLDING_REGISTERS_NB_POINTS + 1,
285 tab_rp_registers); 286 tab_rp_registers);
@@ -289,7 +290,7 @@ int main(void) @@ -289,7 +290,7 @@ int main(void)
289 else 290 else
290 printf("FAILED\n"); 291 printf("FAILED\n");
291 292
292 - ret = read_input_registers(&mb_param, SLAVE, 293 + ret = read_input_registers(&mb_param,
293 UT_INPUT_REGISTERS_ADDRESS, 294 UT_INPUT_REGISTERS_ADDRESS,
294 UT_INPUT_REGISTERS_NB_POINTS + 1, 295 UT_INPUT_REGISTERS_NB_POINTS + 1,
295 tab_rp_registers); 296 tab_rp_registers);
@@ -299,7 +300,7 @@ int main(void) @@ -299,7 +300,7 @@ int main(void)
299 else 300 else
300 printf("FAILED\n"); 301 printf("FAILED\n");
301 302
302 - ret = force_single_coil(&mb_param, SLAVE, 303 + ret = force_single_coil(&mb_param,
303 UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS, 304 UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
304 ON); 305 ON);
305 printf("* force_single_coil: "); 306 printf("* force_single_coil: ");
@@ -309,7 +310,7 @@ int main(void) @@ -309,7 +310,7 @@ int main(void)
309 printf("FAILED\n"); 310 printf("FAILED\n");
310 } 311 }
311 312
312 - ret = force_multiple_coils(&mb_param, SLAVE, 313 + ret = force_multiple_coils(&mb_param,
313 UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS, 314 UT_COIL_STATUS_ADDRESS + UT_COIL_STATUS_NB_POINTS,
314 UT_COIL_STATUS_NB_POINTS, 315 UT_COIL_STATUS_NB_POINTS,
315 tab_rp_status); 316 tab_rp_status);
@@ -320,7 +321,7 @@ int main(void) @@ -320,7 +321,7 @@ int main(void)
320 printf("FAILED\n"); 321 printf("FAILED\n");
321 } 322 }
322 323
323 - ret = preset_multiple_registers(&mb_param, SLAVE, 324 + ret = preset_multiple_registers(&mb_param,
324 UT_HOLDING_REGISTERS_ADDRESS + UT_HOLDING_REGISTERS_NB_POINTS, 325 UT_HOLDING_REGISTERS_ADDRESS + UT_HOLDING_REGISTERS_NB_POINTS,
325 UT_HOLDING_REGISTERS_NB_POINTS, 326 UT_HOLDING_REGISTERS_NB_POINTS,
326 tab_rp_registers); 327 tab_rp_registers);
@@ -335,7 +336,7 @@ int main(void) @@ -335,7 +336,7 @@ int main(void)
335 /** TOO MANY DATA **/ 336 /** TOO MANY DATA **/
336 printf("\nTEST TOO MANY DATA ERROR:\n"); 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 UT_COIL_STATUS_ADDRESS, 340 UT_COIL_STATUS_ADDRESS,
340 MAX_STATUS + 1, 341 MAX_STATUS + 1,
341 tab_rp_status); 342 tab_rp_status);
@@ -345,7 +346,7 @@ int main(void) @@ -345,7 +346,7 @@ int main(void)
345 else 346 else
346 printf("FAILED\n"); 347 printf("FAILED\n");
347 348
348 - ret = read_input_status(&mb_param, SLAVE, 349 + ret = read_input_status(&mb_param,
349 UT_INPUT_STATUS_ADDRESS, 350 UT_INPUT_STATUS_ADDRESS,
350 MAX_STATUS + 1, 351 MAX_STATUS + 1,
351 tab_rp_status); 352 tab_rp_status);
@@ -355,7 +356,7 @@ int main(void) @@ -355,7 +356,7 @@ int main(void)
355 else 356 else
356 printf("FAILED\n"); 357 printf("FAILED\n");
357 358
358 - ret = read_holding_registers(&mb_param, SLAVE, 359 + ret = read_holding_registers(&mb_param,
359 UT_HOLDING_REGISTERS_ADDRESS, 360 UT_HOLDING_REGISTERS_ADDRESS,
360 MAX_REGISTERS + 1, 361 MAX_REGISTERS + 1,
361 tab_rp_registers); 362 tab_rp_registers);
@@ -365,7 +366,7 @@ int main(void) @@ -365,7 +366,7 @@ int main(void)
365 else 366 else
366 printf("FAILED\n"); 367 printf("FAILED\n");
367 368
368 - ret = read_input_registers(&mb_param, SLAVE, 369 + ret = read_input_registers(&mb_param,
369 UT_INPUT_REGISTERS_ADDRESS, 370 UT_INPUT_REGISTERS_ADDRESS,
370 MAX_REGISTERS + 1, 371 MAX_REGISTERS + 1,
371 tab_rp_registers); 372 tab_rp_registers);
@@ -375,7 +376,7 @@ int main(void) @@ -375,7 +376,7 @@ int main(void)
375 else 376 else
376 printf("FAILED\n"); 377 printf("FAILED\n");
377 378
378 - ret = force_multiple_coils(&mb_param, SLAVE, 379 + ret = force_multiple_coils(&mb_param,
379 UT_COIL_STATUS_ADDRESS, 380 UT_COIL_STATUS_ADDRESS,
380 MAX_STATUS + 1, 381 MAX_STATUS + 1,
381 tab_rp_status); 382 tab_rp_status);
@@ -386,7 +387,7 @@ int main(void) @@ -386,7 +387,7 @@ int main(void)
386 printf("FAILED\n"); 387 printf("FAILED\n");
387 } 388 }
388 389
389 - ret = preset_multiple_registers(&mb_param, SLAVE, 390 + ret = preset_multiple_registers(&mb_param,
390 UT_HOLDING_REGISTERS_ADDRESS, 391 UT_HOLDING_REGISTERS_ADDRESS,
391 MAX_REGISTERS + 1, 392 MAX_REGISTERS + 1,
392 tab_rp_registers); 393 tab_rp_registers);
@@ -397,6 +398,33 @@ int main(void) @@ -397,6 +398,33 @@ int main(void)
397 printf("FAILED\n"); 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 /** BAD RESPONSE **/ 428 /** BAD RESPONSE **/
401 printf("\nTEST BAD RESPONSE ERROR:\n"); 429 printf("\nTEST BAD RESPONSE ERROR:\n");
402 430
@@ -404,7 +432,7 @@ int main(void) @@ -404,7 +432,7 @@ int main(void)
404 uint16_t *tab_rp_registers_bad = (uint16_t *) malloc( 432 uint16_t *tab_rp_registers_bad = (uint16_t *) malloc(
405 UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL * sizeof(uint16_t)); 433 UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL * sizeof(uint16_t));
406 ret = read_holding_registers(&mb_param, 434 ret = read_holding_registers(&mb_param,
407 - SLAVE, UT_HOLDING_REGISTERS_ADDRESS, 435 + UT_HOLDING_REGISTERS_ADDRESS,
408 UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL, 436 UT_HOLDING_REGISTERS_NB_POINTS_SPECIAL,
409 tab_rp_registers_bad); 437 tab_rp_registers_bad);
410 printf("* read_holding_registers: "); 438 printf("* read_holding_registers: ");
tests/unit-test-slave.c
@@ -31,7 +31,7 @@ int main(void) @@ -31,7 +31,7 @@ int main(void)
31 int ret; 31 int ret;
32 int i; 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 modbus_set_debug(&mb_param, TRUE); 35 modbus_set_debug(&mb_param, TRUE);
36 36
37 ret = modbus_mapping_new(&mb_mapping, 37 ret = modbus_mapping_new(&mb_mapping,
@@ -75,7 +75,7 @@ int main(void) @@ -75,7 +75,7 @@ int main(void)
75 query[HEADER_LENGTH_TCP + 4] = UT_HOLDING_REGISTERS_NB_POINTS; 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 } else if (ret == CONNECTION_CLOSED) { 79 } else if (ret == CONNECTION_CLOSED) {
80 /* Connection closed by the client, end of server */ 80 /* Connection closed by the client, end of server */
81 break; 81 break;
tests/unit-test.h
@@ -20,6 +20,8 @@ @@ -20,6 +20,8 @@
20 20
21 #include <stdint.h> 21 #include <stdint.h>
22 22
  23 +#define SLAVE 0x11
  24 +
23 const uint16_t UT_COIL_STATUS_ADDRESS = 0x13; 25 const uint16_t UT_COIL_STATUS_ADDRESS = 0x13;
24 const uint16_t UT_COIL_STATUS_NB_POINTS = 0x25; 26 const uint16_t UT_COIL_STATUS_NB_POINTS = 0x25;
25 const uint8_t UT_COIL_STATUS_TAB[] = { 0xCD, 0x6B, 0xB2, 0x0E, 0x1B }; 27 const uint8_t UT_COIL_STATUS_TAB[] = { 0xCD, 0x6B, 0xB2, 0x0E, 0x1B };