-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathconnection.hpp
127 lines (105 loc) · 3.38 KB
/
connection.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Modbus for c++ <https://github.com/Mazurel/Modbus>
// Copyright (c) 2020 Mateusz Mazur aka Mazurel
// Licensed under: MIT License <http://opensource.org/licenses/MIT>
#pragma once
#include <sstream>
#include <stdexcept>
#include <string>
#include <tuple>
#include <vector>
#include <cerrno>
#include <fcntl.h>
#include <poll.h>
#include <termios.h>
#include <unistd.h>
#include "MB/modbusException.hpp"
#include "MB/modbusRequest.hpp"
#include "MB/modbusResponse.hpp"
#include "MB/modbusUtils.hpp"
namespace MB::Serial {
class Connection {
public:
// Pretty high timeout
static const unsigned int DefaultSerialTimeout = 100;
private:
struct termios _termios;
int _fd;
int _timeout = Connection::DefaultSerialTimeout;
public:
constexpr explicit Connection() : _termios(), _fd(-1) {}
explicit Connection(const std::string &path);
explicit Connection(const Connection &) = delete;
explicit Connection(Connection &&) noexcept;
Connection &operator=(Connection &&);
~Connection();
void connect();
std::vector<uint8_t> sendRequest(const MB::ModbusRequest &request);
std::vector<uint8_t> sendResponse(const MB::ModbusResponse &response);
std::vector<uint8_t> sendException(const MB::ModbusException &exception);
/**
* @brief Sends data through the serial
* @param data - Vectorized data
*/
std::vector<uint8_t> send(std::vector<uint8_t> data);
void clearInput();
[[nodiscard]] std::tuple<MB::ModbusResponse, std::vector<uint8_t>> awaitResponse();
[[nodiscard]] std::tuple<MB::ModbusRequest, std::vector<uint8_t>> awaitRequest();
[[nodiscard]] std::vector<uint8_t> awaitRawMessage();
void enableParity(const bool parity) {
if (parity)
getTTY().c_cflag |= PARENB;
else
getTTY().c_cflag &= ~PARENB;
}
void setEvenParity() {
enableParity(true);
getTTY().c_cflag &= ~PARODD;
}
void setOddParity() {
enableParity(true);
getTTY().c_cflag |= PARODD;
}
void setTwoStopBits(const bool two) {
if (two) {
getTTY().c_cflag |= CSTOPB;
} else {
getTTY().c_cflag &= ~CSTOPB;
}
}
#define setBaud(s) \
case s: \
speed = B##s; \
break;
void setBaudRate(speed_t speed) {
switch (speed) {
setBaud(0);
setBaud(50);
setBaud(75);
setBaud(110);
setBaud(134);
setBaud(150);
setBaud(200);
setBaud(300);
setBaud(600);
setBaud(1200);
setBaud(1800);
setBaud(2400);
setBaud(4800);
setBaud(9600);
setBaud(19200);
setBaud(38400);
setBaud(57600);
setBaud(115200);
setBaud(230400);
default:
throw std::runtime_error("Invalid baud rate");
}
cfsetospeed(&_termios, speed);
cfsetispeed(&_termios, speed);
}
#undef setBaud
termios &getTTY() { return _termios; }
int getTimeout() const { return _timeout; }
void setTimeout(int timeout) { _timeout = timeout; }
};
} // namespace MB::Serial