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