|
@@ -268,19 +268,34 @@ static void _modbus_rtu_ioctl_rts(modbus_t *ctx, int on)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
static ssize_t _modbus_rtu_write_n_read(modbus_t *ctx, const uint8_t *req, int req_length) {
|
|
static ssize_t _modbus_rtu_write_n_read(modbus_t *ctx, const uint8_t *req, int req_length) {
|
|
|
|
+ int rc;
|
|
ssize_t w, r, i;
|
|
ssize_t w, r, i;
|
|
uint8_t rb[512];
|
|
uint8_t rb[512];
|
|
-
|
|
|
|
|
|
+ fd_set rset;
|
|
|
|
+ struct timeval tv;
|
|
|
|
+
|
|
// Transmit
|
|
// Transmit
|
|
w = write(ctx->s, req, req_length);
|
|
w = write(ctx->s, req, req_length);
|
|
|
|
|
|
// Read back written bytes if hw has echo
|
|
// Read back written bytes if hw has echo
|
|
- r = 0;
|
|
|
|
- while (r < w)
|
|
|
|
- r += read(ctx->s, rb + r, w - r);
|
|
|
|
|
|
+ FD_ZERO(&rset);
|
|
|
|
+ FD_SET(ctx->s, &rset);
|
|
|
|
+
|
|
|
|
+ r = w;
|
|
|
|
+ do {
|
|
|
|
+ tv.tv_sec = ctx->response_timeout.tv_sec;
|
|
|
|
+ tv.tv_usec = ctx->response_timeout.tv_usec;
|
|
|
|
+ rc = ctx->backend->select(ctx, &rset, &tv, r);
|
|
|
|
+ if(rc > 0){
|
|
|
|
+ ctx->backend->recv(ctx, rb + (w-r) , rc > r?r:rc);
|
|
|
|
+ r -= rc;
|
|
|
|
+ }
|
|
|
|
+ }while( (rc > 0) && (r > 0));
|
|
|
|
+
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|
|
- for (i = 0; i < r; ++i)
|
|
|
|
- fprintf(stderr, "|%02X|", rb[i]);
|
|
|
|
|
|
+ fprintf(stderr, "====> w: %d r: %d req_len %d |", w, r, req_length);
|
|
|
|
+ for (i = 0; i < (w - r); ++i)
|
|
|
|
+ fprintf(stderr, "%02X%c", rb[i], i == (w -r) -1 ?'|':'-');
|
|
fprintf(stderr, "\n");
|
|
fprintf(stderr, "\n");
|
|
fflush(stderr);
|
|
fflush(stderr);
|
|
}
|
|
}
|
|
@@ -416,6 +431,7 @@ static int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg,
|
|
|
|
|
|
if(ctx_rtu->echohw) {/* on active echomode empty receiver on crc error */
|
|
if(ctx_rtu->echohw) {/* on active echomode empty receiver on crc error */
|
|
int rc;
|
|
int rc;
|
|
|
|
+ int inputchars = 0;
|
|
fd_set rfds;
|
|
fd_set rfds;
|
|
struct timeval tv;
|
|
struct timeval tv;
|
|
|
|
|
|
@@ -430,15 +446,17 @@ static int _modbus_rtu_check_integrity(modbus_t *ctx, uint8_t *msg,
|
|
fflush(stderr);
|
|
fflush(stderr);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#define MAX_INPUT_BUF_SIZE 64
|
|
do {
|
|
do {
|
|
- unsigned char cc[256]; /* dummy buffer für cleaning input */
|
|
|
|
|
|
+ unsigned char cc[MAX_INPUT_BUF_SIZE]; /* dummy buffer für cleaning input */
|
|
|
|
|
|
tv.tv_sec = ctx->response_timeout.tv_sec;
|
|
tv.tv_sec = ctx->response_timeout.tv_sec;
|
|
tv.tv_usec = ctx->response_timeout.tv_usec;
|
|
tv.tv_usec = ctx->response_timeout.tv_usec;
|
|
|
|
|
|
rc = ctx->backend->select(ctx, &rfds, &tv, sizeof(cc));
|
|
rc = ctx->backend->select(ctx, &rfds, &tv, sizeof(cc));
|
|
- if(rc > 0) ctx->backend->recv(ctx, msg + msg_length, rc);
|
|
|
|
- } while(rc > 0); /* read until transfer empty */
|
|
|
|
|
|
+ if(rc > 0) ctx->backend->recv(ctx, cc, rc);
|
|
|
|
+ inputchars += rc;
|
|
|
|
+ } while((rc > 0) && (inputchars < MAX_INPUT_BUF_SIZE)); /* read until transfer empty */
|
|
}
|
|
}
|
|
|
|
|
|
if (ctx->debug) {
|
|
if (ctx->debug) {
|