/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtSerialBus module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmodbuspdu.h"
#include "qmodbus_symbols_p.h"

#include <QtCore/qdebug.h>
#include <QtCore/qhash.h>

QT_BEGIN_NAMESPACE

using ReqSizeCalc = QHash<quint8, QModbusRequest::CalcFuncPtr>;
Q_GLOBAL_STATIC(ReqSizeCalc, requestSizeCalculators);

using ResSizeCalc = QHash<quint8, QModbusResponse::CalcFuncPtr>;
Q_GLOBAL_STATIC(ResSizeCalc, responseSizeCalculators);

namespace Private {

enum struct Type {
    Request,
    Response
};

static int minimumDataSize(const QModbusPdu &pdu, Type type)
{
    if (pdu.isException())
        return 1;

    switch (pdu.functionCode()) {
    case QModbusPdu::ReadCoils:
    case QModbusPdu::ReadDiscreteInputs:
        return type == Type::Request ? 4 : 2;
    case QModbusPdu::WriteSingleCoil:
    case QModbusPdu::WriteSingleRegister:
        return 4;
    case QModbusPdu::ReadHoldingRegisters:
    case QModbusPdu::ReadInputRegisters:
        return type == Type::Request ? 4 : 3;
    case QModbusPdu::ReadExceptionStatus:
        return type == Type::Request ? 0 : 1;
    case QModbusPdu::Diagnostics:
        return 4;
    case QModbusPdu::GetCommEventCounter:
        return type == Type::Request ? 0 : 4;
    case QModbusPdu::GetCommEventLog:
        return type == Type::Request ? 0 : 8;
    case QModbusPdu::WriteMultipleCoils:
        return type == Type::Request ? 6 : 4;
    case QModbusPdu::WriteMultipleRegisters:
        return type == Type::Request ? 7 : 4;
    case QModbusPdu::ReportServerId:
        return type == Type::Request ? 0 : 3;
    case QModbusPdu::ReadFileRecord:
        return type == Type::Request ? 8 : 5;
    case QModbusPdu::WriteFileRecord:
        return 10;
    case QModbusPdu::MaskWriteRegister:
        return 6;
    case QModbusPdu::ReadWriteMultipleRegisters:
        return type == Type::Request ? 11 : 3;
    case QModbusPdu::ReadFifoQueue:
        return type == Type::Request ? 2 : 6;
    case QModbusPdu::EncapsulatedInterfaceTransport:
        return 2;
    case QModbusPdu::Invalid:
    case QModbusPdu::UndefinedFunctionCode:
        return -1;
    }
    return -1;
}

static QDataStream &pduFromStream(QDataStream &stream, QModbusPdu &pdu, Type type)
{
    quint8 codeByte = 0;
    if (stream.readRawData(reinterpret_cast<char *>(&codeByte), sizeof(quint8)) != sizeof(quint8))
        return stream;
    QModbusPdu::FunctionCode code = QModbusPdu::FunctionCode(codeByte);
    pdu.setFunctionCode(code);

    auto needsAdditionalRead = [](QModbusPdu &pdu, int size) -> bool {
        if (size < 0)
            pdu.setFunctionCode(QModbusResponse::Invalid);
        if (size <= 0)
            return false;
        return true;
    };

    const bool isResponse = (type == Type::Response);
    int size = isResponse ? QModbusResponse::minimumDataSize(pdu)
                          : QModbusRequest::minimumDataSize(pdu);
    if (!needsAdditionalRead(pdu, size))
        return stream;

    QByteArray data(size, Qt::Uninitialized);
    if (stream.device()->peek(data.data(), data.size()) != size)
        return stream;

    pdu.setData(data);
    size = isResponse ? QModbusResponse::calculateDataSize(pdu)
                      : QModbusRequest::calculateDataSize(pdu);
    if (!needsAdditionalRead(pdu, size))
        return stream;

    if (isResponse && (code == QModbusPdu::EncapsulatedInterfaceTransport)) {
        quint8 meiType;
        pdu.decodeData(&meiType);
        if (meiType == EncapsulatedInterfaceTransport::ReadDeviceIdentification) {
            int left = size, offset = 0;
            while ((left > 0) && (size <= 252)) { // The maximum PDU data size is 252 bytes.
                data.resize(size);
                const int read = stream.readRawData(data.data() + offset, size - offset);
                if ((read < 0) || (read != (size - offset))) {
                    size = 255; // bogus size
                    stream.setStatus(QDataStream::ReadCorruptData);
                    break; // error reading, bail, reset further down
                }
                offset += read;
                left = QModbusResponse::calculateDataSize(QModbusResponse(code, data)) - offset;
                size += left;
            }
            if ((stream.status() == QDataStream::Ok) && (size <= 252)) {
                pdu.setData(data);
                return stream; // early return to avoid second read
            }
        } else {
            data.resize(int(stream.device()->size() - 1)); // One byte for the function code.
        }
    } else if (pdu.functionCode() == QModbusPdu::Diagnostics) {
        quint16 subCode;
        pdu.decodeData(&subCode);
        if (subCode == Diagnostics::ReturnQueryData)
            data.resize(int(stream.device()->size() - 1)); // One byte for the function code.
    }

    // reset what we have so far, next read might fail as well
    pdu.setData(QByteArray());
    pdu.setFunctionCode(QModbusPdu::Invalid);

    if (data.size() <= 252) { // The maximum PDU data size is 252 bytes.
        data.resize(size);
        if (stream.readRawData(data.data(), data.size()) == size) {
            pdu.setData(data);
            pdu.setFunctionCode(code);
        }
    }
    return stream;
}

}   // namespace Private

/*!
    \class QModbusPdu
    \inmodule QtSerialBus
    \since 5.8

    \brief QModbusPdu is a abstract container class containing the function code and
    payload that is stored inside a Modbus ADU.

    The class provides access to the raw Modbus protocol packets as defined by
    the  Modbus Application Protocol Specification 1.1b.
*/

/*!
    \enum QModbusPdu::ExceptionCode

    This enum describes all the possible error conditions as defined by Modbus Exception Codes.
    They are set by the server after checking the appropriate error conditions in the reply to a
    request and must be decoded by the client to operate on the exception code.

    \value IllegalFunction                      Function code is not supported by device.
    \value IllegalDataAddress                   The received data address in the query is not an
                                                allowable address for the Modbus server.
    \value IllegalDataValue                     The contained value in the request data field is
                                                not an allowable value for the Modbus server.
    \value ServerDeviceFailure                  An irrecoverable error occurred while the server
                                                was attempting to perform the requested action.
    \value Acknowledge                          Specialized use in conjunction with programming
                                                commands.
    \value ServerDeviceBusy                     The server is engaged in processing a long duration
                                                program command.
    \value NegativeAcknowledge                  The server cannot perform the program function
                                                received in the query. This code is returned for an
                                                unsuccessful programming request. The client should
                                                request diagnostic or error information from the
                                                server.
    \value MemoryParityError                    Indicates that the extended file area failed to
                                                pass a consistency check. Used in conjunction with
                                                function codes 20 and 21. The exception code does
                                                not refer to any parity settings of the
                                                transmission line but only to the servers' internal
                                                memory of file records.
    \value GatewayPathUnavailable               Indicates that the gateway was unable to allocate
                                                an internal communication path from the input port
                                                to the output port for processing the request.
    \value GatewayTargetDeviceFailedToRespond   Indicates that no response was obtained from the
                                                target device behind a gateway.
                                                Usually this means the target device is not online
                                                on the network.
    \value ExtendedException                    This is an extended exception as per Modbus
                                                specification. Generally this code is used to
                                                describe an exception that is otherwise further
                                                described.
*/

/*!
    \enum QModbusPdu::FunctionCode

    Defines the function code and the implicit type of action required by the server. Not all
    Modbus devices can handle the same set of function codes.

    \value Invalid                          Set by the default constructor, do not use.
    \value ReadCoils                        Requests the status of one or more coils from a device.
    \value ReadDiscreteInputs               Requests the status of one or more input registers from
                                            a device.
    \value ReadHoldingRegisters             Requests the status of one or more holding register
                                            values from a device.
    \value ReadInputRegisters               Requests the status of one or more input register
                                            values from a device.
    \value WriteSingleCoil                  Requests to write a single coil on a device.
    \value WriteSingleRegister              Requests to write a single holding register on a device.
    \value ReadExceptionStatus              Requests the status of the eight Exception Status
                                            outputs on a device.
    \value Diagnostics                      Used to provide a series of tests for checking the
                                            client server communication system, or checking internal
    \value GetCommEventCounter              Requests a status word and an event count from the
                                            device's communication event counter.
    \value GetCommEventLog                  Requests a status word, event count, message count,
                                            and a field of event bytes from a device.
    \value WriteMultipleCoils               Requests to write one or more coils on a device.
    \value WriteMultipleRegisters           Requests to write one or more holding registers on a
                                            device.
    \value ReportServerId                   Requests the description of the type, the current
                                            status, and other information specific to a device.
    \value ReadFileRecord                   Requests a file record read.
    \value WriteFileRecord                  Requests a file record write.
    \value MaskWriteRegister                Requests to modify the contents of a specified holding
                                            register using a combination of an AND or OR mask, and
                                            the register's current contents.
    \value ReadWriteMultipleRegisters       Requests the status of one or more holding register and
                                            at the same time to write one or more holding registers
                                            on a device.
    \value ReadFifoQueue                    Requests to read the contents of a First-In-First-Out
                                            (FIFO) queue of register in a remote device.
    \value EncapsulatedInterfaceTransport   Please refer to Annex A of the Modbus specification.
    \value UndefinedFunctionCode            Do not use.
*/

/*!
    \fn QModbusPdu::QModbusPdu()

    Constructs an invalid QModbusPdu.
*/

/*!
    \fn QModbusPdu::~QModbusPdu()

    Destroys a QModbusPdu.
*/

/*!
    \fn QModbusPdu::QModbusPdu(const QModbusPdu &other)

    Constructs a QModbusPdu that is a copy of \a other.

*/

/*!
    \fn QModbusPdu &QModbusPdu::operator=(const QModbusPdu &other)

    Makes a copy of the \a other and assigns it to this QModbusPdu object.
*/

/*!
    \fn QModbusPdu::QModbusPdu(FunctionCode code, const QByteArray &data)

    Constructs a QModbusPdu with function code set to \a code and payload set to \a data.
    The data is expected to be stored in big-endian byte order already.
*/

/*!
    \internal
    \fn template <typename ... Args> QModbusPdu::QModbusPdu(FunctionCode code, Args ... data)

    Constructs a QModbusPdu with function code set to \a code and payload set to \a data.
    The data is converted and stored in big-endian byte order.

    \note Usage is limited \c quint8 and \c quint16 only. This is because
    \c QDataStream stream operators will not only append raw data, but also
    e.g. size, count, etc. for complex types.
*/

/*!
    \fn bool QModbusPdu::isValid() const

    Returns true if the PDU is valid; otherwise false.

    A PDU is considered valid if the message code is in the range of 1 to 255 decimal and the
    PDU's compound size (function code + data) does not exceed 253 bytes. A default constructed
    PDU is invalid.
*/

/*!
    \variable QModbusPdu::ExceptionByte

    The variable is initialized to 0x80.

    Exceptions are reported in a defined packet format. A function code
    is returned to the requesting client equal to the original function code,
    except with its most significant bit set. This is equivalent to adding 0x80
    to the value of the original function code.

    This field may be used to mask the exception bit in the function field
    of a raw Modbus packet.
*/

/*!
    \fn bool QModbusPdu::isException() const

    Returns true if the PDU contains an exception code; otherwise false.
*/

/*!
    \fn QModbusPdu::ExceptionCode QModbusPdu::exceptionCode() const

    Returns the response's exception code.
*/

/*!
    \fn qint16 QModbusPdu::size() const

    Returns the PDU's full size, including function code and data size.
*/

/*!
    \fn qint16 QModbusPdu::dataSize() const

    Returns the PDU's data size, excluding the function code.
*/

/*!
    \fn FunctionCode QModbusPdu::functionCode() const

    Returns the PDU's function code.
*/

/*!
    \fn void QModbusPdu::setFunctionCode(FunctionCode code)

    Sets the PDU's function code to \a code.
*/

/*!
    \fn QByteArray QModbusPdu::data() const

    Returns the PDU's payload, excluding the function code.
    The payload is stored in big-endian byte order.
*/

/*!
    \fn void QModbusPdu::setData(const QByteArray &data)

    Sets the PDU's function payload to \a data. The data is expected to be stored in big-endian
    byte order already.
*/

/*!
    \fn template <typename ... Args> void QModbusPdu::decodeData(Args && ... data) const

    Converts the payload into host endianness and reads it into \a data. Data can be a variable
    length argument list.

    \code
        QModbusResponsePdu response(QModbusPdu::ReportServerId);
        response.encodeData(quint8(0x02), quint8(0x01), quint8(0xff));
        quint8 count, id, run;
        response.decodeData(&count, &id, &run);
    \endcode

    \note Usage is limited \c quint8 and \c quint16 only. This is because
    \c QDataStream stream operators will not only append raw data, but also
    e.g. size, count, etc. for complex types.
*/

/*!
    \fn template <typename ... Args> void QModbusPdu::encodeData(Args ... data)

    Sets the payload to \a data. The data is converted and stored in big-endian byte order.

    \code
        QModbusRequestPdu request(QModbusPdu::ReadCoils);
        // starting address and quantity of coils
        request.encodeData(quint16(0x0c), quint16(0x0a));
    \endcode

    \note Usage is limited \c quint8 and \c quint16 only. This is because
    \c QDataStream stream operators will not only append raw data, but also
    e.g. size, count, etc. for complex types.
*/

/*!
    \relates QModbusPdu

    Writes the Modbus \a pdu to the \a debug stream.
*/
QDebug operator<<(QDebug debug, const QModbusPdu &pdu)
{
    QDebugStateSaver _(debug);
    debug.nospace().noquote() << "0x" << Qt::hex << qSetFieldWidth(2) << qSetPadChar('0')
        << (pdu.isException() ? pdu.functionCode() | QModbusPdu::ExceptionByte : pdu.functionCode())
        << qSetFieldWidth(0) << pdu.data().toHex();
    return debug;
}

/*!
    \relates QModbusPdu

    Writes a \a pdu to the \a stream and returns a reference to the stream.
*/
QDataStream &operator<<(QDataStream &stream, const QModbusPdu &pdu)
{
    if (pdu.isException())
        stream << static_cast<quint8> (pdu.functionCode() | QModbusPdu::ExceptionByte);
    else
        stream << static_cast<quint8> (pdu.functionCode());
    if (!pdu.data().isEmpty())
        stream.writeRawData(pdu.data().constData(), pdu.data().size());

    return stream;
}

/*!
    \class QModbusRequest
    \inmodule QtSerialBus
    \since 5.8

    \brief QModbusRequest is a container class containing the function code and payload that is
    stored inside a Modbus ADU.

    A Modbus request usually consists of a single byte describing the \c FunctionCode and N bytes
    of payload

    A typical Modbus request can looks like this:
    \code
        QModbusRequest request(QModbusRequest::WriteMultipleCoils,
            QByteArray::fromHex("0013000a02cd01"));
    \endcode
    \note When using the constructor taking the \c QByteArray, please make sure to convert the
        containing data to big-endian byte order before creating the request.

    The same request can be created like this, if the values are known at compile time:
    \code
        quint16 startAddress = 19, numberOfCoils = 10;
        quint8 payloadInBytes = 2, outputHigh = 0xcd, outputLow = 0x01;
        QModbusRequest request(QModbusRequest::WriteMultipleCoils, startAddress, numberOfCoils,
            payloadInBytes, outputHigh, outputLow);
    \endcode
*/

/*!
  \typedef QModbusRequest::CalcFuncPtr

  Typedef for a pointer to a custom calculator function with the same signature as
  \l QModbusRequest::calculateDataSize.
*/

/*!
    \fn QModbusRequest::QModbusRequest()

    Constructs an invalid QModbusRequest.
*/

/*!
    \fn QModbusRequest::QModbusRequest(const QModbusPdu &pdu)

    Constructs a copy of \a pdu.
*/

/*!
    \fn template <typename ... Args> QModbusRequest::QModbusRequest(FunctionCode code, Args... data)

    Constructs a QModbusRequest with function code set to \a code and payload set to \a data.
    The data is converted and stored in big-endian byte order.

    \note Usage is limited \c quint8 and \c quint16 only. This is because
    \c QDataStream stream operators will not only append raw data, but also
    e.g. size, count, etc. for complex types.
*/

/*!
    \fn QModbusRequest::QModbusRequest(FunctionCode code, const QByteArray &data = QByteArray())

    Constructs a QModbusResponse with function code set to \a code and payload set to \a data.
    The data is expected to be stored in big-endian byte order already.
*/

/*!
    Returns the expected minimum data size for \a request based on the
    request's function code; \c {-1} if the function code is not known.
*/
int QModbusRequest::minimumDataSize(const QModbusRequest &request)
{
    return Private::minimumDataSize(request, Private::Type::Request);
}

/*!
    Calculates the expected data size for \a request based on the request's
    function code and data. Returns the full size of the request's data part;
    \c {-1} if the size could not be properly calculated.

    \sa minimumDataSize
    \sa registerDataSizeCalculator
*/
int QModbusRequest::calculateDataSize(const QModbusRequest &request)
{
    if (requestSizeCalculators.exists()) {
        if (auto ptr = requestSizeCalculators()->value(quint8(request.functionCode()), nullptr))
            return ptr(request);
    }

    if (request.isException())
        return 1;

    int size = -1;
    int minimum = Private::minimumDataSize(request, Private::Type::Request);
    if (minimum < 0)
        return size;

    switch (request.functionCode()) {
    case QModbusPdu::WriteMultipleCoils:
        minimum -= 1; // first payload payload byte
        if (request.dataSize() >= minimum)
            size = minimum + quint8(request.data().at(minimum - 1)) /*byte count*/;
        break;
    case QModbusPdu::WriteMultipleRegisters:
    case QModbusPdu::ReadWriteMultipleRegisters:
        minimum -= 2; // first 2 payload payload bytes
        if (request.dataSize() >= minimum)
            size = minimum + quint8(request.data().at(minimum - 1)) /*byte count*/;
        break;
    case QModbusPdu::ReadFileRecord:
    case QModbusPdu::WriteFileRecord:
        if (request.dataSize() >= 1)
            size = 1 /*byte count*/ + quint8(request.data().at(0)) /*actual bytes*/;
        break;
    case QModbusPdu::EncapsulatedInterfaceTransport: {
        if (request.dataSize() < minimum)
            break;  // can't calculate, let's return -1 to indicate error
        quint8 meiType;
        request.decodeData(&meiType);
        // ReadDeviceIdentification -> 3 == MEI type + Read device ID + Object Id
        size = (meiType == EncapsulatedInterfaceTransport::ReadDeviceIdentification) ? 3 : minimum;
    }   break;
    default:
        size = minimum;
        break;
    }
    return size;
}

/*!
    This function registers a user-defined implementation to calculate the
    request data size for function code \a fc. It can be used to extend or
    override the implementation inside \l QModbusRequest::calculateDataSize().

    The \c CalcFuncPtr is a typedef for a pointer to a custom \a calculator
    function with the following signature:
    \code
        int myCalculateDataSize(const QModbusRequest &pdu);
    \endcode
*/
void QModbusRequest::registerDataSizeCalculator(FunctionCode fc, CalcFuncPtr calculator)
{
    requestSizeCalculators()->insert(quint8(fc), calculator);
}

/*!
    \relates QModbusRequest

    Reads a \a pdu from the \a stream and returns a reference to the stream.

    \note The function might fail to properly stream PDU's with function code
    \l QModbusPdu::Diagnostics or \l QModbusPdu::EncapsulatedInterfaceTransport
    because of the missing size indicator inside the PDU. In particular this may
    happen when the PDU is embedded into a stream that doesn't end with the
    diagnostic/encapsulated request itself.
*/
QDataStream &operator>>(QDataStream &stream, QModbusRequest &pdu)
{
    return Private::pduFromStream(stream, pdu, Private::Type::Request);
}

/*!
    \class QModbusResponse
    \inmodule QtSerialBus
    \since 5.8

    \brief QModbusResponse is a container class containing the function code and payload that is
        stored inside a Modbus ADU.

    A typical Modbus response can looks like this:
    \code
        QModbusResponse response(QModbusResponse::ReadCoils, QByteArray::fromHex("02cd01"));
    \endcode
    \note When using the constructor taking the \c QByteArray, please make sure to convert the
        containing data to big-endian byte order before creating the request.

    The same response can be created like this, if the values are known at compile time:
    \code
        quint8 payloadInBytes = 2, outputHigh = 0xcd, outputLow = 0x01;
        QModbusResponse response(QModbusResponse::ReadCoils, payloadInBytes, outputHigh, outputLow);
    \endcode
*/


/*!
  \typedef QModbusResponse::CalcFuncPtr

  Typedef for a pointer to a custom calculator function with the same signature as
  \l QModbusResponse::calculateDataSize.
*/

/*!
    \fn QModbusResponse::QModbusResponse()

    Constructs an invalid QModbusResponse.
*/

/*!
    \fn QModbusResponse::QModbusResponse(const QModbusPdu &pdu)

    Constructs a copy of \a pdu.
*/

/*!
    \fn template <typename ... Args> QModbusResponse::QModbusResponse(FunctionCode code, Args... data)

    Constructs a QModbusResponse with function code set to \a code and payload set to \a data.
    The data is converted and stored in big-endian byte order.

    \note Usage is limited \c quint8 and \c quint16 only. This is because
    \c QDataStream stream operators will not only append raw data, but also
    e.g. size, count, etc. for complex types.
*/

/*!
    \fn QModbusResponse::QModbusResponse(FunctionCode code, const QByteArray &data = QByteArray())

    Constructs a QModbusResponse with function code set to \a code and payload set to \a data.
    The data is expected to be stored in big-endian byte order already.
*/

/*!
    Returns the expected minimum data size for \a response based on the
    response's function code; \c {-1} if the function code is not known.
*/
int QModbusResponse::minimumDataSize(const QModbusResponse &response)
{
    return Private::minimumDataSize(response, Private::Type::Response);
}

/*!
    Calculates the expected data size for \a response, based on the response's
    function code and data. Returns the full size of the response's data part;
    \c {-1} if the size could not be properly calculated.

    \sa minimumDataSize
    \sa registerDataSizeCalculator
*/
int QModbusResponse::calculateDataSize(const QModbusResponse &response)
{
    if (responseSizeCalculators.exists()) {
        if (auto ptr = responseSizeCalculators()->value(quint8(response.functionCode()), nullptr))
            return ptr(response);
    }

    if (response.isException())
        return 1;

    int size = -1;
    int minimum = Private::minimumDataSize(response, Private::Type::Response);
    if (minimum < 0)
        return size;

    switch (response.functionCode()) {
    case QModbusResponse::ReadCoils:
    case QModbusResponse::ReadDiscreteInputs:
    case QModbusResponse::ReadHoldingRegisters:
    case QModbusResponse::ReadInputRegisters:
    case QModbusResponse::GetCommEventLog:
    case QModbusResponse::ReadFileRecord:
    case QModbusResponse::WriteFileRecord:
    case QModbusResponse::ReadWriteMultipleRegisters:
    case QModbusResponse::ReportServerId:
        if (response.dataSize() >= 1)
            size = 1 /*byte count*/ + quint8(response.data().at(0)) /*actual bytes*/;
        break;
    case QModbusResponse::ReadFifoQueue: {
        if (response.dataSize() >= 2) {
            quint16 rawSize;
            response.decodeData(&rawSize);
            size = rawSize + 2; // 2 bytes size info
        }
    }   break;
    case QModbusPdu::EncapsulatedInterfaceTransport: {
        if (response.dataSize() < minimum)
            break;  // can't calculate, let's return -1 to indicate error

        quint8 meiType = 0;
        response.decodeData(&meiType);

        // update size, header 6 bytes: mei type + read device id + conformity level + more follows
        //                              + next object id + number of object
        // response data part  2 bytes: + object id + object size of the first object -> 8
        size = (meiType == EncapsulatedInterfaceTransport::ReadDeviceIdentification) ? 8 : minimum;
        if (meiType != EncapsulatedInterfaceTransport::ReadDeviceIdentification
            || response.dataSize() < size) {
            break; // TODO: calculate CanOpenGeneralReference instead of break
        }

        const QByteArray data = response.data();
        quint8 numOfObjects = quint8(data[5]);
        quint8 objectSize = quint8(data[7]);

        // 6 byte header size + (2 * n bytes fixed per object) + first object size
        size = 6 + (2 * numOfObjects) + objectSize;
        if ((numOfObjects == 1) || (data.size() < size))
            break;

        // header + object id + object size + second object id (9 bytes) + first object size
        int nextSizeField = 9 + objectSize;
        for (int i = 1; i < numOfObjects; ++i) {
            if (data.size() <= nextSizeField)
                break;
            objectSize = quint8(data[nextSizeField]);
            size += objectSize;
            nextSizeField += objectSize + 2; // object size + object id field + object size field
        }
    }   break;
    default:
        size = minimum;
        break;
    }
    return size;
}

/*!
    This function registers a user-defined implementation to calculate the
    response data size for function code \a fc. It can be used to extend or
    override the implementation inside \l QModbusResponse::calculateDataSize().

    The \c CalcFuncPtr is a typedef for a pointer to a custom \a calculator
    function with the following signature:
    \code
        int myCalculateDataSize(const QModbusResponse &pdu);
    \endcode
*/
void QModbusResponse::registerDataSizeCalculator(FunctionCode fc, CalcFuncPtr calculator)
{
    responseSizeCalculators()->insert(quint8(fc), calculator);
}

/*!
    \relates QModbusResponse

    Reads a \a pdu from the \a stream and returns a reference to the stream.

    \note The function might fail to properly stream PDU's with function code
    \l QModbusPdu::Diagnostics or \l QModbusPdu::EncapsulatedInterfaceTransport
    because of the missing size indicator inside the PDU. In particular this may
    happen when the PDU is embedded into a stream that doesn't end with the
    diagnostic/encapsulated request itself.
*/
QDataStream &operator>>(QDataStream &stream, QModbusResponse &pdu)
{
    return Private::pduFromStream(stream, pdu, Private::Type::Response);
}

/*!
    \class QModbusExceptionResponse
    \inmodule QtSerialBus
    \since 5.8

    \brief QModbusExceptionResponse is a container class containing the function and error code
        inside a Modbus ADU.

    A typical QModbusExceptionResponse response can looks like this:
    \code
        QModbusExceptionResponse exception(QModbusExceptionResponse::ReportServerId,
            QModbusExceptionResponse::ServerDeviceFailure);
    \endcode
*/

/*!
    \fn QModbusExceptionResponse::QModbusExceptionResponse()

    Constructs an invalid QModbusExceptionResponse.
*/

/*!
    \fn QModbusExceptionResponse::QModbusExceptionResponse(const QModbusPdu &pdu)

    Constructs a copy of \a pdu.
*/

/*!
    \fn QModbusExceptionResponse::QModbusExceptionResponse(FunctionCode code, ExceptionCode ec)

    Constructs a QModbusExceptionResponse with function code set to \a code and exception error
    code set to \a ec.
*/

/*!
    \fn void QModbusExceptionResponse::setFunctionCode(FunctionCode c)

    Sets the response's function code to \a c.
*/

/*!
    \fn void QModbusExceptionResponse::setExceptionCode(ExceptionCode ec)

    Sets the response's exception code to \a ec.
*/

QT_END_NAMESPACE
