-
Notifications
You must be signed in to change notification settings - Fork 17
/
backend.cpp
116 lines (110 loc) · 3.55 KB
/
backend.cpp
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
#include <QCoreApplication>
#include <QHostAddress>
#include <QTcpSocket>
#include "adu.h"
#include "backend.h"
#include "backend_request.h"
#include "QsLog.h"
Backend::Backend(QObject *parent) :
QObject(parent)
{
}
void Backend::modbusRequest(ADU * const modbusRequest)
{
uint functionCode = modbusRequest->getFunctionCode();
quint16 address = modbusRequest->getAddres();
uint unitID = modbusRequest->getUnitID();
switch(functionCode) {
case PDU::ReadHoldingRegisters:
case PDU::ReadInputRegisters:
{
quint16 quantity = modbusRequest->getQuantity();
QLOG_TRACE() << "Read registers" << functionCode << "address =" << address << "quantity =" << quantity;
if (quantity == 0 || quantity > 125) {
logError("Requested quantity invalid for this function", modbusRequest);
modbusRequest->setExceptionCode(PDU::IllegalDataValue);
emit modbusReply(modbusRequest);
} else {
BackendRequest *r = new BackendRequest(modbusRequest, ReadValues, address, unitID, quantity);
emit mappingRequest(r);
}
break;
}
case PDU::WriteSingleRegister:
{
QLOG_TRACE() << "PDU::WriteSingleRegister Address = " << address;
BackendRequest *r = new BackendRequest(modbusRequest, WriteValues, address, unitID, 1);
r->data() = modbusRequest->getData();
r->data().remove(0, 2); // Remove header
emit mappingRequest(r);
break;
}
case PDU::WriteMultipleRegisters:
{
quint16 quantity = modbusRequest->getQuantity();
quint8 byteCount = modbusRequest->getByteCount();
QLOG_TRACE() << "Write multiple registers" << functionCode << "address =" << address << "quantity =" << quantity;
if ((quantity == 0 || quantity > 125) || (byteCount != (quantity * 2))) {
logError("Requested quantity invalid for this function", modbusRequest);
modbusRequest->setExceptionCode(PDU::IllegalDataValue);
emit modbusReply(modbusRequest);
} else {
BackendRequest *r = new BackendRequest(modbusRequest, WriteValues, address, unitID, quantity);
r->data() = modbusRequest->getData();
r->data().remove(0, 5); // Remove header
emit mappingRequest(r);
}
break;
}
default:
logError("Illegal function", modbusRequest);
modbusRequest->setExceptionCode(PDU::IllegalFunction);
emit modbusReply(modbusRequest);
break;
}
}
void Backend::requestCompleted(MappingRequest *request)
{
ADU *reply = static_cast<BackendRequest *>(request)->adu();
if (request->error() == NoError) {
reply->setReplyData(request->data());
} else {
logError(request->errorString(), reply);
reply->setExceptionCode(getExceptionCode(request->error()));
}
emit modbusReply(reply);
delete request;
}
void Backend::logError(const QString &message, ADU *request)
{
QString errorMessage = QString("Error processing function code %1, unit id %2, start address %3, quantity %4, src %5: %6").
arg(request->getFunctionCode()).
arg(request->getUnitID()).
arg(request->getAddres()).
arg(request->getQuantity()).
arg(request->getSocket()->peerAddress().toString()).
arg(message);
QLOG_ERROR() << errorMessage;
}
PDU::ExceptionCode Backend::getExceptionCode(MappingErrors error)
{
switch (error) {
case NoError:
return PDU::NoExeption;
case StartAddressError:
return PDU::IllegalDataAddress;
case AddressError:
return PDU::IllegalDataAddress;
case QuantityError:
return PDU::IllegalDataValue;
case UnitIdError:
return PDU::GatewayTargetDeviceFailedToRespond;
case ServiceError:
return PDU::GatewayPathUnavailable;
case PermissionError:
return PDU::IllegalDataAddress;
default:
QLOG_ERROR() << "Pitfall for error code handling:" + QString::number(error);
return PDU::IllegalDataAddress;
}
}