diff --git a/include/protocols/d0.h b/include/protocols/d0.h index 87a14e9..f489f1a 100644 --- a/include/protocols/d0.h +++ b/include/protocols/d0.h @@ -61,4 +61,6 @@ size_t meter_read_d0(struct meter *mtr, struct reading *rds, size_t n); */ int meter_d0_open_socket(const char *node, const char *service); +int meter_d0_open_device(const char *device, struct termios *old_tio, speed_t baudrate); + #endif /* _D0_H_ */ diff --git a/src/protocols/d0.c b/src/protocols/d0.c index 6dc1af4..52bb2bd 100644 --- a/src/protocols/d0.c +++ b/src/protocols/d0.c @@ -36,6 +36,7 @@ #include #include #include +#include /* socket */ #include @@ -114,8 +115,7 @@ int meter_open_d0(meter_t *mtr) { meter_handle_d0_t *handle = &mtr->handle.d0; if (handle->device != NULL) { - print(log_error, "TODO: implement serial interface", mtr); - return ERR; + handle->fd = meter_d0_open_device(handle->device, &handle->oldtio, handle->baudrate); } else if (handle->host != NULL) { char *addr = strdup(handle->host); @@ -304,3 +304,36 @@ int meter_d0_open_socket(const char *node, const char *service) { return fd; } + +int meter_d0_open_device(const char *device, struct termios *old_tio, speed_t baudrate) { + int bits; + struct termios tio; + memset(&tio, 0, sizeof(struct termios)); + + int fd = open(device, O_RDWR); + if (fd < 0) { + print(log_error, "open(%s): %s", NULL, device, strerror(errno)); + return ERR; + } + + /* get old configuration */ + tcgetattr(fd, &tio) ; + + /* backup old configuration to restore it when closing the meter connection */ + memcpy(old_tio, &tio, sizeof(struct termios)); + + /* set 7-N-1 */ + tio.c_iflag &= ~(BRKINT | INLCR | IMAXBEL); + tio.c_oflag &= ~(OPOST | ONLCR); + tio.c_lflag &= ~(ISIG | ICANON | IEXTEN | ECHO); + tio.c_cflag |= (CS7 | PARENB); + + /* set baudrate */ + cfsetispeed(&tio, baudrate); + cfsetospeed(&tio, baudrate); + + /* apply new configuration */ + tcsetattr(fd, TCSANOW, &tio); + + return fd; +}