diff --git a/src/modbus-rtu.c b/src/modbus-rtu.c index faa5062..acbbaad 100644 --- a/src/modbus-rtu.c +++ b/src/modbus-rtu.c @@ -166,30 +166,38 @@ int _modbus_rtu_send_msg_pre(uint8_t *req, int req_length) static void win32_ser_init(struct win32_ser *ws) { /* Clear everything */ - memset(ws,0x00,sizeof(struct win32_ser)); + memset(ws, 0x00, sizeof(struct win32_ser)); + /* Set file handle to invalid */ ws->fd = INVALID_HANDLE_VALUE; } static int win32_ser_select(struct win32_ser *ws, int max_len, struct timeval *tv) { - COMMTIMEOUTS comm_to; unsigned int msec = 0; + COMMTIMEOUTS comm_to; + unsigned int msec = 0; + /* Check if some data still in the buffer to be consumed */ if (ws->n_bytes> 0) { return 1; } + /* Setup timeouts like select() would do */ msec = tv->tv_sec * 1000 + tv->tv_usec / 1000; - if (msec < 1) msec = 1; + if (msec < 1) + msec = 1; + comm_to.ReadIntervalTimeout = msec; comm_to.ReadTotalTimeoutMultiplier = 0; comm_to.ReadTotalTimeoutConstant = msec; comm_to.WriteTotalTimeoutMultiplier = 0; comm_to.WriteTotalTimeoutConstant = 1000; - SetCommTimeouts(ws->fd,&comm_to); + SetCommTimeouts(ws->fd, &comm_to); + /* Read some bytes */ if ((max_len > PY_BUF_SIZE) || (max_len < 0)) { max_len = PY_BUF_SIZE; } + if (ReadFile(ws->fd, &ws->buf, max_len, &ws->n_bytes, NULL)) { /* Check if some bytes available */ if (ws->n_bytes > 0) { @@ -207,14 +215,18 @@ static int win32_ser_select(struct win32_ser *ws, int max_len, struct timeval *t static int win32_ser_read(struct win32_ser *ws, uint8_t *p_msg, unsigned int max_len) { unsigned int n = ws->n_bytes; + if (max_len < n) { n = max_len; } + if (n > 0) { - memcpy(p_msg,ws->buf,n); + memcpy(p_msg, ws->buf, n); } + ws->n_bytes -= n; - return(n); + + return n; } #endif @@ -290,12 +302,12 @@ static int _modbus_rtu_connect(modbus_t *ctx) /* ctx_rtu->device should contain a string like "COMxx:" xx being a decimal number */ ctx_rtu->w_ser.fd = CreateFileA(ctx_rtu->device, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - 0, - NULL); + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL); /* Error checking */ if (ctx_rtu->w_ser.fd == INVALID_HANDLE_VALUE) { @@ -317,102 +329,102 @@ static int _modbus_rtu_connect(modbus_t *ctx) /* Speed setting */ switch (ctx_rtu->baud) { - case 110: - dcb.BaudRate = CBR_110; - break; - case 300: - dcb.BaudRate = CBR_300; - break; - case 600: - dcb.BaudRate = CBR_600; - break; - case 1200: - dcb.BaudRate = CBR_1200; - break; - case 2400: - dcb.BaudRate = CBR_2400; - break; - case 4800: - dcb.BaudRate = CBR_4800; - break; - case 9600: - dcb.BaudRate = CBR_9600; - break; - case 19200: - dcb.BaudRate = CBR_19200; - break; - case 38400: - dcb.BaudRate = CBR_38400; - break; - case 57600: - dcb.BaudRate = CBR_57600; - break; - case 115200: - dcb.BaudRate = CBR_115200; - break; - default: - dcb.BaudRate = CBR_9600; - printf("WARNING Unknown baud rate %d for %s (B9600 used)\n", - ctx_rtu->baud, ctx_rtu->device); - } + case 110: + dcb.BaudRate = CBR_110; + break; + case 300: + dcb.BaudRate = CBR_300; + break; + case 600: + dcb.BaudRate = CBR_600; + break; + case 1200: + dcb.BaudRate = CBR_1200; + break; + case 2400: + dcb.BaudRate = CBR_2400; + break; + case 4800: + dcb.BaudRate = CBR_4800; + break; + case 9600: + dcb.BaudRate = CBR_9600; + break; + case 19200: + dcb.BaudRate = CBR_19200; + break; + case 38400: + dcb.BaudRate = CBR_38400; + break; + case 57600: + dcb.BaudRate = CBR_57600; + break; + case 115200: + dcb.BaudRate = CBR_115200; + break; + default: + dcb.BaudRate = CBR_9600; + printf("WARNING Unknown baud rate %d for %s (B9600 used)\n", + ctx_rtu->baud, ctx_rtu->device); + } - /* Data bits */ - switch (ctx_rtu->data_bit) { - case 5: - dcb.ByteSize = 5; - break; - case 6: - dcb.ByteSize = 6; - break; - case 7: - dcb.ByteSize = 7; - break; - case 8: - default: - dcb.ByteSize = 8; - break; - } + /* Data bits */ + switch (ctx_rtu->data_bit) { + case 5: + dcb.ByteSize = 5; + break; + case 6: + dcb.ByteSize = 6; + break; + case 7: + dcb.ByteSize = 7; + break; + case 8: + default: + dcb.ByteSize = 8; + break; + } - /* Stop bits */ - if (ctx_rtu->stop_bit == 1) - dcb.StopBits = ONESTOPBIT; - else /* 2 */ - dcb.StopBits = TWOSTOPBITS; - - /* Parity */ - if (ctx_rtu->parity == 'N') { - dcb.Parity = NOPARITY; - dcb.fParity = FALSE; - } else if (ctx_rtu->parity == 'E') { - dcb.Parity = EVENPARITY; - dcb.fParity = TRUE; - } else { - /* odd */ - dcb.Parity = ODDPARITY; - dcb.fParity = TRUE; - } + /* Stop bits */ + if (ctx_rtu->stop_bit == 1) + dcb.StopBits = ONESTOPBIT; + else /* 2 */ + dcb.StopBits = TWOSTOPBITS; - /* Hardware handshaking left as default settings retrieved */ + /* Parity */ + if (ctx_rtu->parity == 'N') { + dcb.Parity = NOPARITY; + dcb.fParity = FALSE; + } else if (ctx_rtu->parity == 'E') { + dcb.Parity = EVENPARITY; + dcb.fParity = TRUE; + } else { + /* odd */ + dcb.Parity = ODDPARITY; + dcb.fParity = TRUE; + } - /* No software handshaking */ - dcb.fTXContinueOnXoff = TRUE; - dcb.fOutX = FALSE; - dcb.fInX = FALSE; + /* Hardware handshaking left as default settings retrieved */ - /* Binary mode (it's the only supported on Windows anyway) */ - dcb.fBinary = TRUE; + /* No software handshaking */ + dcb.fTXContinueOnXoff = TRUE; + dcb.fOutX = FALSE; + dcb.fInX = FALSE; - /* Don't want errors to be blocking */ - dcb.fAbortOnError = FALSE; + /* Binary mode (it's the only supported on Windows anyway) */ + dcb.fBinary = TRUE; - /* TODO: any other flags !? */ + /* Don't want errors to be blocking */ + dcb.fAbortOnError = FALSE; - /* Setup port */ - if (!SetCommState(ctx_rtu->w_ser.fd, &dcb)) { - fprintf(stderr, "ERROR Error setting new configuration (LastError %d)\n", - (int)GetLastError()); - return -1; - } + /* TODO: any other flags!? */ + + /* Setup port */ + if (!SetCommState(ctx_rtu->w_ser.fd, &dcb)) { + fprintf(stderr, "ERROR Error setting new configuration (LastError %d)\n", + (int)GetLastError()); + return -1; + } #else /* The O_NOCTTY flag tells UNIX that this program doesn't want to be the "controlling terminal" for that port. If you