60 client_requests[request_id].count, |
60 client_requests[request_id].count, |
61 client_requests[request_id].coms_buffer, |
61 client_requests[request_id].coms_buffer, |
62 (int) client_requests[request_id].count, |
62 (int) client_requests[request_id].count, |
63 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
63 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
64 client_requests[request_id].retries, |
64 client_requests[request_id].retries, |
65 &(client_requests[request_id].error_code), |
65 &(client_requests[request_id].mb_error_code), |
66 &(client_requests[request_id].resp_timeout), |
66 &(client_requests[request_id].resp_timeout), |
67 &(client_requests[request_id].coms_buf_mutex)); |
67 &(client_requests[request_id].coms_buf_mutex)); |
68 |
68 |
69 case 2: /* read discrete inputs */ |
69 case 2: /* read discrete inputs */ |
70 return read_input_bits( client_requests[request_id].slave_id, |
70 return read_input_bits( client_requests[request_id].slave_id, |
72 client_requests[request_id].count, |
72 client_requests[request_id].count, |
73 client_requests[request_id].coms_buffer, |
73 client_requests[request_id].coms_buffer, |
74 (int) client_requests[request_id].count, |
74 (int) client_requests[request_id].count, |
75 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
75 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
76 client_requests[request_id].retries, |
76 client_requests[request_id].retries, |
77 &(client_requests[request_id].error_code), |
77 &(client_requests[request_id].mb_error_code), |
78 &(client_requests[request_id].resp_timeout), |
78 &(client_requests[request_id].resp_timeout), |
79 &(client_requests[request_id].coms_buf_mutex)); |
79 &(client_requests[request_id].coms_buf_mutex)); |
80 |
80 |
81 case 3: /* read holding registers */ |
81 case 3: /* read holding registers */ |
82 return read_output_words(client_requests[request_id].slave_id, |
82 return read_output_words(client_requests[request_id].slave_id, |
84 client_requests[request_id].count, |
84 client_requests[request_id].count, |
85 client_requests[request_id].coms_buffer, |
85 client_requests[request_id].coms_buffer, |
86 (int) client_requests[request_id].count, |
86 (int) client_requests[request_id].count, |
87 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
87 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
88 client_requests[request_id].retries, |
88 client_requests[request_id].retries, |
89 &(client_requests[request_id].error_code), |
89 &(client_requests[request_id].mb_error_code), |
90 &(client_requests[request_id].resp_timeout), |
90 &(client_requests[request_id].resp_timeout), |
91 &(client_requests[request_id].coms_buf_mutex)); |
91 &(client_requests[request_id].coms_buf_mutex)); |
92 |
92 |
93 case 4: /* read input registers */ |
93 case 4: /* read input registers */ |
94 return read_input_words(client_requests[request_id].slave_id, |
94 return read_input_words(client_requests[request_id].slave_id, |
96 client_requests[request_id].count, |
96 client_requests[request_id].count, |
97 client_requests[request_id].coms_buffer, |
97 client_requests[request_id].coms_buffer, |
98 (int) client_requests[request_id].count, |
98 (int) client_requests[request_id].count, |
99 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
99 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
100 client_requests[request_id].retries, |
100 client_requests[request_id].retries, |
101 &(client_requests[request_id].error_code), |
101 &(client_requests[request_id].mb_error_code), |
102 &(client_requests[request_id].resp_timeout), |
102 &(client_requests[request_id].resp_timeout), |
103 &(client_requests[request_id].coms_buf_mutex)); |
103 &(client_requests[request_id].coms_buf_mutex)); |
104 |
104 |
105 case 5: /* write single coil */ |
105 case 5: /* write single coil */ |
106 return write_output_bit(client_requests[request_id].slave_id, |
106 return write_output_bit(client_requests[request_id].slave_id, |
107 client_requests[request_id].address, |
107 client_requests[request_id].address, |
108 client_requests[request_id].coms_buffer[0], |
108 client_requests[request_id].coms_buffer[0], |
109 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
109 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
110 client_requests[request_id].retries, |
110 client_requests[request_id].retries, |
111 &(client_requests[request_id].error_code), |
111 &(client_requests[request_id].mb_error_code), |
112 &(client_requests[request_id].resp_timeout), |
112 &(client_requests[request_id].resp_timeout), |
113 &(client_requests[request_id].coms_buf_mutex)); |
113 &(client_requests[request_id].coms_buf_mutex)); |
114 |
114 |
115 case 6: /* write single register */ |
115 case 6: /* write single register */ |
116 return write_output_word(client_requests[request_id].slave_id, |
116 return write_output_word(client_requests[request_id].slave_id, |
117 client_requests[request_id].address, |
117 client_requests[request_id].address, |
118 client_requests[request_id].coms_buffer[0], |
118 client_requests[request_id].coms_buffer[0], |
119 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
119 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
120 client_requests[request_id].retries, |
120 client_requests[request_id].retries, |
121 &(client_requests[request_id].error_code), |
121 &(client_requests[request_id].mb_error_code), |
122 &(client_requests[request_id].resp_timeout), |
122 &(client_requests[request_id].resp_timeout), |
123 &(client_requests[request_id].coms_buf_mutex)); |
123 &(client_requests[request_id].coms_buf_mutex)); |
124 |
124 |
125 case 7: break; /* function not yet supported */ |
125 case 7: break; /* function not yet supported */ |
126 case 8: break; /* function not yet supported */ |
126 case 8: break; /* function not yet supported */ |
136 client_requests[request_id].address, |
136 client_requests[request_id].address, |
137 client_requests[request_id].count, |
137 client_requests[request_id].count, |
138 client_requests[request_id].coms_buffer, |
138 client_requests[request_id].coms_buffer, |
139 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
139 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
140 client_requests[request_id].retries, |
140 client_requests[request_id].retries, |
141 &(client_requests[request_id].error_code), |
141 &(client_requests[request_id].mb_error_code), |
142 &(client_requests[request_id].resp_timeout), |
142 &(client_requests[request_id].resp_timeout), |
143 &(client_requests[request_id].coms_buf_mutex)); |
143 &(client_requests[request_id].coms_buf_mutex)); |
144 |
144 |
145 case 16: /* write multiple registers */ |
145 case 16: /* write multiple registers */ |
146 return write_output_words(client_requests[request_id].slave_id, |
146 return write_output_words(client_requests[request_id].slave_id, |
147 client_requests[request_id].address, |
147 client_requests[request_id].address, |
148 client_requests[request_id].count, |
148 client_requests[request_id].count, |
149 client_requests[request_id].coms_buffer, |
149 client_requests[request_id].coms_buffer, |
150 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
150 client_nodes[client_requests[request_id].client_node_id].mb_nd, |
151 client_requests[request_id].retries, |
151 client_requests[request_id].retries, |
152 &(client_requests[request_id].error_code), |
152 &(client_requests[request_id].mb_error_code), |
153 &(client_requests[request_id].resp_timeout), |
153 &(client_requests[request_id].resp_timeout), |
154 &(client_requests[request_id].coms_buf_mutex)); |
154 &(client_requests[request_id].coms_buf_mutex)); |
155 |
155 |
156 default: break; /* should never occur, if file generation is correct */ |
156 default: break; /* should never occur, if file generation is correct */ |
157 } |
157 } |
350 fprintf(stderr, "Modbus client thread (%%d): RUNNING Modbus request %%d (periodic = %%d flag_exec_req = %%d)\n", |
350 fprintf(stderr, "Modbus client thread (%%d): RUNNING Modbus request %%d (periodic = %%d flag_exec_req = %%d)\n", |
351 client_node_id, req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req ); |
351 client_node_id, req, client_nodes[client_requests[req].client_node_id].periodic_act, client_requests[req].flag_exec_req ); |
352 */ |
352 */ |
353 |
353 |
354 int res_tmp = __execute_mb_request(req); |
354 int res_tmp = __execute_mb_request(req); |
|
355 client_requests[req].tn_error_code = 0; // assume success |
355 switch (res_tmp) { |
356 switch (res_tmp) { |
356 case PORT_FAILURE: { |
357 case PORT_FAILURE: { |
357 if (res_tmp != client_nodes[client_node_id].prev_error) |
358 if (res_tmp != client_nodes[client_node_id].prev_error) |
358 fprintf(stderr, "Modbus plugin: Error connecting Modbus client %%s to remote server.\n", client_nodes[client_node_id].location); |
359 fprintf(stderr, "Modbus plugin: Error connecting Modbus client %%s to remote server.\n", client_nodes[client_node_id].location); |
359 client_nodes[client_node_id].prev_error = res_tmp; |
360 client_nodes[client_node_id].prev_error = res_tmp; |
|
361 client_requests[req].tn_error_code = 1; // error accessing IP network, or serial interface |
360 break; |
362 break; |
361 } |
363 } |
362 case INVALID_FRAME: { |
364 case INVALID_FRAME: { |
363 if ((res_tmp != client_requests[req].prev_error) && (0 == client_nodes[client_node_id].prev_error)) |
365 if ((res_tmp != client_requests[req].prev_error) && (0 == client_nodes[client_node_id].prev_error)) |
364 fprintf(stderr, "Modbus plugin: Modbus client request configured at location %%s was unsuccesful. Server/slave returned an invalid/corrupted frame.\n", client_requests[req].location); |
366 fprintf(stderr, "Modbus plugin: Modbus client request configured at location %%s was unsuccesful. Server/slave returned an invalid/corrupted frame.\n", client_requests[req].location); |
365 client_requests[req].prev_error = res_tmp; |
367 client_requests[req].prev_error = res_tmp; |
|
368 client_requests[req].tn_error_code = 2; // reply received from server was an invalid frame |
366 break; |
369 break; |
367 } |
370 } |
368 case TIMEOUT: { |
371 case TIMEOUT: { |
369 if ((res_tmp != client_requests[req].prev_error) && (0 == client_nodes[client_node_id].prev_error)) |
372 if ((res_tmp != client_requests[req].prev_error) && (0 == client_nodes[client_node_id].prev_error)) |
370 fprintf(stderr, "Modbus plugin: Modbus client request configured at location %%s timed out waiting for reply from server.\n", client_requests[req].location); |
373 fprintf(stderr, "Modbus plugin: Modbus client request configured at location %%s timed out waiting for reply from server.\n", client_requests[req].location); |
371 client_requests[req].prev_error = res_tmp; |
374 client_requests[req].prev_error = res_tmp; |
|
375 client_requests[req].tn_error_code = 3; // server did not reply before timeout expired |
372 break; |
376 break; |
373 } |
377 } |
374 case MODBUS_ERROR: { |
378 case MODBUS_ERROR: { |
375 if (client_requests[req].prev_error != client_requests[req].error_code) { |
379 if (client_requests[req].prev_error != client_requests[req].mb_error_code) { |
376 fprintf(stderr, "Modbus plugin: Modbus client request configured at location %%s was unsuccesful. Server/slave returned error code 0x%%2x", client_requests[req].location, client_requests[req].error_code); |
380 fprintf(stderr, "Modbus plugin: Modbus client request configured at location %%s was unsuccesful. Server/slave returned error code 0x%%2x", client_requests[req].location, client_requests[req].mb_error_code); |
377 if (client_requests[req].error_code <= MAX_MODBUS_ERROR_CODE ) { |
381 if (client_requests[req].mb_error_code <= MAX_MODBUS_ERROR_CODE ) { |
378 fprintf(stderr, "(%%s)", modbus_error_messages[client_requests[req].error_code]); |
382 fprintf(stderr, "(%%s)", modbus_error_messages[client_requests[req].mb_error_code]); |
379 fprintf(stderr, ".\n"); |
383 fprintf(stderr, ".\n"); |
380 } |
384 } |
381 } |
385 } |
382 client_requests[req].prev_error = client_requests[req].error_code; |
386 client_requests[req].prev_error = client_requests[req].mb_error_code; |
|
387 client_requests[req].tn_error_code = 4; // server returned a valid Modbus error frame |
383 break; |
388 break; |
384 } |
389 } |
385 default: { |
390 default: { |
386 if ((res_tmp >= 0) && (client_nodes[client_node_id].prev_error != 0)) { |
391 if ((res_tmp >= 0) && (client_nodes[client_node_id].prev_error != 0)) { |
387 fprintf(stderr, "Modbus plugin: Modbus client %%s has reconnected to server/slave.\n", client_nodes[client_node_id].location); |
392 fprintf(stderr, "Modbus plugin: Modbus client %%s has reconnected to server/slave.\n", client_nodes[client_node_id].location); |
392 client_nodes[client_node_id].prev_error = 0; |
397 client_nodes[client_node_id].prev_error = 0; |
393 client_requests[req] .prev_error = 0; |
398 client_requests[req] .prev_error = 0; |
394 break; |
399 break; |
395 } |
400 } |
396 } |
401 } |
397 |
402 |
|
403 /* Set the flag_tn_error_code and flag_mb_error_code that are mapped onto |
|
404 * located BYTE variables, so the user program |
|
405 * knows how the communication is going. |
|
406 */ |
|
407 client_requests[req].flag_mb_error_code = client_requests[req].mb_error_code; |
|
408 client_requests[req].flag_tn_error_code = client_requests[req].tn_error_code; |
|
409 |
398 /* We have just finished excuting a client transcation request. |
410 /* We have just finished excuting a client transcation request. |
399 * If the current cycle was activated by user request we reset the flag used to ask to run it |
411 * If the current cycle was activated by user request we reset the flag used to ask to run it |
400 */ |
412 */ |
401 if (0 != client_requests[req].flag_exec_req) { |
413 if (0 != client_requests[req].flag_exec_req) { |
402 client_requests[req].flag_exec_req = 0; |
414 client_requests[req].flag_exec_req = 0; |