blob: 77c2663aa847c3b8a602dde2e4f19e17b03b3e5d [file] [log] [blame]
/****************************************************************************
**
** 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 "qmodbusdeviceidentification.h"
#include "qmodbus_symbols_p.h"
QT_BEGIN_NAMESPACE
/*!
\class QModbusDeviceIdentification
\inmodule QtSerialBus
\since 5.8
\brief The QModbusDeviceIdentification is a container class representing
the physical and functional description of a Modbus server.
The Device Identification interface is modeled as an address space composed
of a set of addressable data elements. The data elements are called objects
and an \l ObjectId identifies them.
*/
/*!
\enum QModbusDeviceIdentification::ObjectId
This enum describes the possible server objects. The interface consists of
three categories of objects:
Basic Device Identification. All objects of this category are mandatory.
\value VendorNameObjectId The vendor name of the device.
\value ProductCodeObjectId The product code of the device.
\value MajorMinorRevisionObjectId The product version numbering.
Regular Device Identification. All objects of this category are standard
defined and optional.
\value VendorUrlObjectId The vendor URL of the device.
\value ProductNameObjectId The product name of the device.
\value ModelNameObjectId The model name of the device.
\value UserApplicationNameObjectId The user application name of the device.
Reserved range (i.e., ReservedObjectId >= ObjectId < ProductDependentObjectId).
Do not use.
\value ReservedObjectId First value of reserved object Ids.
Extended Device Identification. All of these data are device dependent and
optional.
\value ProductDependentObjectId First possible value of product dependent
identifiers.
\value UndefinedObjectId Do not use.
*/
/*!
\enum QModbusDeviceIdentification::ReadDeviceIdCode
Defines the access type of the read identification request.
Stream access:
\value BasicReadDeviceIdCode Request to get the basic device
identification.
\value RegularReadDeviceIdCode Request to get the regular device
identification.
\value ExtendedReadDeviceIdCode Request to get the extended device
identification.
Individual access:
\value IndividualReadDeviceIdCode Request to get one specific identification
object.
*/
/*!
\enum QModbusDeviceIdentification::ConformityLevel
Defines the identification conformity level of the device and type of
supported access.
\value BasicConformityLevel Basic identification (stream access).
\value RegularConformityLevel Regular identification (stream access).
\value ExtendedConformityLevel Extended identification (stream access).
\value BasicIndividualConformityLevel Basic identification (stream access and
individual access).
\value RegularIndividualConformityLevel Regular identification (stream access
and individual access).
\value ExtendedIndividualConformityLevel Extended identification (stream access
and individual access).
\sa ReadDeviceIdCode
*/
/*!
\fn QModbusDeviceIdentification::QModbusDeviceIdentification()
Constructs an invalid QModbusDeviceIdentification object.
*/
/*!
\fn bool QModbusDeviceIdentification::isValid() const
Returns \c true if the device identification object is valid; otherwise
\c false.
A device identification object is considered valid if \l ProductNameObjectId,
\l ProductCodeObjectId and \l MajorMinorRevisionObjectId are set to a
non-empty value. Still the object can contain valid object id's and
associated data.
\note A default constructed device identification object is invalid.
*/
/*!
\fn QList<int> QModbusDeviceIdentification::objectIds() const
Returns a list containing all the object id's in the
\c QModbusDeviceIdentification object in ascending order.
\sa ObjectId
*/
/*!
\fn void QModbusDeviceIdentification::remove(uint objectId)
Removes the item for the given \a objectId.
\sa ObjectId
*/
/*!
\fn bool QModbusDeviceIdentification::contains(uint objectId) const
Returns \c true if there is an item for the given \a objectId; otherwise \c
false.
\sa ObjectId
*/
/*!
\fn QByteArray QModbusDeviceIdentification::value(uint objectId) const
Returns the value associated with the \a objectId. If there is no item with
the \a objectId, the function returns a \l{default-constructed value}.
\sa ObjectId
*/
/*!
\fn bool QModbusDeviceIdentification::insert(uint objectId, const QByteArray &value)
Inserts a new item with the \a objectId and a value of \a value. If there
is already an item with the \a objectId, that item's value is replaced with
\a value.
Returns \c true if the size of \a value is less than 245 bytes and the
\a objectId is less then \l QModbusDeviceIdentification::UndefinedObjectId.
\sa ObjectId
*/
/*!
\fn ConformityLevel QModbusDeviceIdentification::conformityLevel() const
Returns the identification conformity level of the device and type of
supported access.
*/
/*!
\fn void QModbusDeviceIdentification::setConformityLevel(ConformityLevel level)
Sets the identification conformity level of the device and type of
supported access to \a level.
*/
/*!
Converts the byte array \a ba to a QModbusDeviceIdentification object.
\note: The returned object might be empty or even invalid if some error
occurs while processing the byte array.
\sa isValid()
*/
QModbusDeviceIdentification QModbusDeviceIdentification::fromByteArray(const QByteArray &ba)
{
QModbusDeviceIdentification qmdi;
// header 6 bytes: mei type + read device id + conformity level + more follows
// + next object id + number of object
// data 2 bytes: + object id + object size of the first object -> 8
if (ba.size() >= 8) {
if (ba[0] != EncapsulatedInterfaceTransport::ReadDeviceIdentification)
return qmdi;
if (ba.size() < (8 + quint8(ba[7])))
return qmdi;
} else {
return qmdi;
}
ConformityLevel level = ConformityLevel(quint8(ba[2]));
switch (level) {
case BasicConformityLevel:
case RegularConformityLevel:
case ExtendedConformityLevel:
case BasicIndividualConformityLevel:
case RegularIndividualConformityLevel:
case ExtendedIndividualConformityLevel:
qmdi.setConformityLevel(level);
break;
default:
return qmdi;
}
quint8 numOfObjects = ba[5];
quint8 objectSize = quint8(ba[7]);
qmdi.insert(quint8(ba[6]), ba.mid(8, objectSize));
// 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 (ba.size() <= nextSizeField)
break;
objectSize = ba[nextSizeField];
if (ba.size() < (nextSizeField + objectSize))
break;
qmdi.insert(quint8(ba[nextSizeField - 1]), ba.mid(nextSizeField + 1, objectSize));
nextSizeField += objectSize + 2; // object size + object id field + object size field
}
return qmdi;
}
QT_END_NAMESPACE