17 #include "visiontransfer/parametertransfer.h" 18 #include "visiontransfer/exceptions.h" 19 #include "visiontransfer/internalinformation.h" 20 #include "visiontransfer/standardparameterids.h" 21 #include "visiontransfer/parametertransferdata.h" 32 constexpr
int ParameterTransfer::SOCKET_TIMEOUT_MS;
34 ParameterTransfer::ParameterTransfer(
const char* address,
const char* service)
35 : socket(INVALID_SOCKET) {
37 Networking::initNetworking();
38 addrinfo* addressInfo = Networking::resolveAddress(address, service);
40 socket = Networking::connectTcpSocket(addressInfo);
41 Networking::setSocketTimeout(socket, SOCKET_TIMEOUT_MS);
42 checkProtocolVersion();
44 freeaddrinfo(addressInfo);
47 ParameterTransfer::~ParameterTransfer() {
48 if(socket != INVALID_SOCKET) {
49 Networking::closeSocket(socket);
53 std::map<std::string, ParameterInfo> ParameterTransfer::recvEnumeration() {
54 std::map<std::string, ParameterInfo> pi;
55 const size_t bufsize = 4096;
59 int bytesReceived = recv(socket, recv_buf, 4, 0);
60 if(bytesReceived < 0) {
61 TransferException ex(
"Error receiving network packet: " +
string(strerror(errno)));
63 }
else if (bytesReceived == 0) {
66 }
else if (bytesReceived < 4) {
73 uint32_t num_params = ntohl(reinterpret_cast<uint32_t*>(buf)[0]);
76 if (expected_remaining_size > bufsize - 4) {
77 TransferException ex(
"Remote parameter enumeration exceeds expected maximum size");
80 while (expected_remaining_size > 0) {
81 bytesReceived = recv(socket, recv_buf, expected_remaining_size, 0);
82 if (bytesReceived < 0) {
83 TransferException ex(
"Error receiving network packet: " +
string(strerror(errno)));
85 }
else if (bytesReceived == 0) {
89 expected_remaining_size -= bytesReceived;
90 recv_buf += bytesReceived;
95 for (
unsigned int i = 0; i < num_params; ++i) {
96 StandardParameterIDs::ParameterID
id = (StandardParameterIDs::ParameterID) ntohl(tpi->id);
97 ParameterInfo::ParameterType type = (ParameterInfo::ParameterType) ntohl(tpi->type);
98 bool writeable = ntohl(tpi->flags & StandardParameterIDs::ParameterFlags::PARAMETER_WRITEABLE) != 0;
100 auto nameIt = internal::StandardParameterIDs::parameterNameByID.find(
id);
101 if (nameIt == StandardParameterIDs::parameterNameByID.end()) {
102 std::cerr <<
"Enumeration contained a ParameterID for which no name is known: " << std::to_string(
id) << std::endl;
103 std::cerr <<
"Parameter ignored; please ensure your libvisiontransfer is up to date." << std::endl;
106 case ParameterInfo::TYPE_INT: {
107 pi[nameIt->second] = visiontransfer::ParameterInfo::fromInt(nameIt->second, writeable,
108 ntohl(tpi->value.intVal), ntohl(tpi->min.intVal), ntohl(tpi->max.intVal), ntohl(tpi->inc.intVal)
112 case ParameterInfo::TYPE_BOOL: {
113 pi[nameIt->second] = visiontransfer::ParameterInfo::fromBool(nameIt->second, writeable, ntohl(tpi->value.boolVal) != 0);
116 case ParameterInfo::TYPE_DOUBLE: {
117 pi[nameIt->second] = visiontransfer::ParameterInfo::fromDouble(nameIt->second, writeable,
118 tpi->value.doubleVal, tpi->min.doubleVal, tpi->max.doubleVal, tpi->inc.doubleVal
131 void ParameterTransfer::recvData(
unsigned char* dest,
int length) {
132 int bytesReceived = recv(socket, reinterpret_cast<char*>(dest), length, 0);
133 if(bytesReceived < 0) {
134 TransferException ex(
"Error receiving network packet: " +
string(strerror(errno)));
136 }
else if(bytesReceived < length) {
141 void ParameterTransfer::checkProtocolVersion() {
142 unsigned int version = 0;
143 recvData(reinterpret_cast<unsigned char*>(&version),
sizeof(version));
145 if(ntohl(version) != static_cast<unsigned int>(InternalInformation::CURRENT_PROTOCOL_VERSION)) {
147 + std::to_string(InternalInformation::CURRENT_PROTOCOL_VERSION)
148 +
" but received " + std::to_string(ntohl(version)));
152 void ParameterTransfer::readParameter(
unsigned char messageType, int32_t
id,
unsigned char* dest,
int length) {
157 unsigned int networkId = htonl(
id);
158 unsigned char messageBuf[13];
159 memset(messageBuf, 0,
sizeof(messageBuf));
161 messageBuf[0] = messageType;
162 memcpy(&messageBuf[1], &networkId, 4);
164 int written = send(socket, reinterpret_cast<char*>(messageBuf),
sizeof(messageBuf), 0);
165 if(written !=
sizeof(messageBuf)) {
166 TransferException ex(
"Error sending parameter read request: " +
string(strerror(errno)));
170 unsigned char replyBuf[8];
171 recvData(replyBuf,
sizeof(replyBuf));
172 memcpy(dest, replyBuf, length);
176 void ParameterTransfer::writeParameter(
unsigned char messageType, int32_t
id, T value) {
177 static_assert(
sizeof(T) <= 8,
"Parameter type musst be smaller or equal to 8 bytes");
179 unsigned int networkId = htonl(
id);
180 unsigned char messageBuf[13];
182 memset(messageBuf, 0,
sizeof(messageBuf));
183 messageBuf[0] = messageType;
184 memcpy(&messageBuf[1], &networkId, 4);
185 memcpy(&messageBuf[5], &value,
sizeof(value));
187 int written = send(socket, reinterpret_cast<char*>(messageBuf),
sizeof(messageBuf), 0);
188 if(written !=
sizeof(messageBuf)) {
189 TransferException ex(
"Error sending parameter write request: " +
string(strerror(errno)));
193 unsigned char replyBuf[8];
194 recvData(replyBuf,
sizeof(replyBuf));
196 if(replyBuf[0] == 0 && replyBuf[1] == 0 && replyBuf[2] == 0 && replyBuf[3] == 0) {
203 readParameter(MESSAGE_READ_INT,
id, reinterpret_cast<unsigned char*>(&data),
sizeof(data));
204 return static_cast<int>(ntohl(data));
209 readParameter(MESSAGE_READ_DOUBLE,
id, reinterpret_cast<unsigned char*>(&data),
sizeof(data));
215 readParameter(MESSAGE_READ_BOOL,
id, reinterpret_cast<unsigned char*>(&data),
sizeof(data));
220 writeParameter(MESSAGE_WRITE_INT,
id, htonl(static_cast<uint32_t>(value)));
224 writeParameter(MESSAGE_WRITE_DOUBLE,
id, value);
228 writeParameter(MESSAGE_WRITE_BOOL,
id, htonl(static_cast<uint32_t>(value)));
232 unsigned char messageBuf[13];
233 memset(messageBuf, 0,
sizeof(messageBuf));
234 messageBuf[0] = MESSAGE_ENUMERATE_PARAMS;
236 int written = send(socket, reinterpret_cast<char*>(messageBuf),
sizeof(messageBuf), 0);
237 if(written !=
sizeof(messageBuf)) {
238 TransferException ex(
"Error sending parameter enumeration request: " +
string(strerror(errno)));
241 auto enumeration = recvEnumeration();
bool readBoolParameter(int32_t id)
Reads a boolean value from the parameter server.
int readIntParameter(int32_t id)
Reads an integer value from the parameter server.
void writeBoolParameter(int32_t id, int32_t value)
Writes a boolean value to a parameter of the parameter server.
Exception class that is used for all parameter-related exceptions.
void writeIntParameter(int32_t id, int32_t value)
Writes an integer value to a parameter of the parameter server.
void writeDoubleParameter(int32_t id, double value)
Writes a double precision floating point value to a parameter of the parameter server.
std::map< std::string, ParameterInfo > getAllParameters()
Enumerates all parameters as reported by the device.
double readDoubleParameter(int32_t id)
Reads a double precision floating point value from the parameter server.
Exception class that is used for all transfer exceptions.