Introduce channel mask class and continue deCONZ UART protocol
This commit is contained in:
parent
95caaab5ce
commit
6449654820
@ -93,6 +93,16 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(NodeType)
|
Q_ENUM(NodeType)
|
||||||
|
|
||||||
|
enum SourceAddressMode {
|
||||||
|
SourceAddressModeNone = 0x00,
|
||||||
|
SourceAddressModeShortSourceAddress = 0x01,
|
||||||
|
SourceAddressModeAddLastHoppAddress = 0x02, // since 0x0108
|
||||||
|
SourceAddressModeIeeeSourceAddress = 0x03,
|
||||||
|
SourceAddressModeShortAndIeeeSourceAddress = 0x04 // since 0x010B
|
||||||
|
};
|
||||||
|
Q_ENUM(SourceAddressMode)
|
||||||
|
|
||||||
|
|
||||||
enum SecurityMode {
|
enum SecurityMode {
|
||||||
SecurityModeNoSecurity = 0x00,
|
SecurityModeNoSecurity = 0x00,
|
||||||
SecurityModePreconfiguredNetworkKey = 0x01,
|
SecurityModePreconfiguredNetworkKey = 0x01,
|
||||||
@ -109,4 +119,5 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // DECONZ_H
|
#endif // DECONZ_H
|
||||||
|
|||||||
@ -47,6 +47,17 @@ Deconz::StatusCode ZigbeeInterfaceDeconzReply::statusCode() const
|
|||||||
return m_statusCode;
|
return m_statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZigbeeInterfaceDeconzReply::aborted() const
|
||||||
|
{
|
||||||
|
return m_aborted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeInterfaceDeconzReply::abort()
|
||||||
|
{
|
||||||
|
m_aborted = true;
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeInterfaceDeconzReply::ZigbeeInterfaceDeconzReply(Deconz::Command command, quint8 sequenceNumber, QObject *parent) :
|
ZigbeeInterfaceDeconzReply::ZigbeeInterfaceDeconzReply(Deconz::Command command, quint8 sequenceNumber, QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
m_command(command),
|
m_command(command),
|
||||||
|
|||||||
@ -47,9 +47,14 @@ public:
|
|||||||
// Response content
|
// Response content
|
||||||
Deconz::StatusCode statusCode() const;
|
Deconz::StatusCode statusCode() const;
|
||||||
|
|
||||||
|
bool aborted() const;
|
||||||
|
void abort();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ZigbeeInterfaceDeconzReply(Deconz::Command command, quint8 sequenceNumber, QObject *parent = nullptr);
|
explicit ZigbeeInterfaceDeconzReply(Deconz::Command command, quint8 sequenceNumber, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
bool m_aborted = false;
|
||||||
|
|
||||||
// Request content
|
// Request content
|
||||||
Deconz::Command m_command;
|
Deconz::Command m_command;
|
||||||
quint8 m_sequenceNumber = 0;
|
quint8 m_sequenceNumber = 0;
|
||||||
|
|||||||
@ -41,7 +41,7 @@ ZigbeeBridgeControllerDeconz::ZigbeeBridgeControllerDeconz(QObject *parent) :
|
|||||||
m_watchdogTimer = new QTimer(this);
|
m_watchdogTimer = new QTimer(this);
|
||||||
m_watchdogTimer->setSingleShot(false);
|
m_watchdogTimer->setSingleShot(false);
|
||||||
m_watchdogTimer->setInterval(m_watchdogResetTimout * 1000); // Set the watchdog to 85 seconds, reset every 60 s
|
m_watchdogTimer->setInterval(m_watchdogResetTimout * 1000); // Set the watchdog to 85 seconds, reset every 60 s
|
||||||
connect(m_watchdogTimer, &QTimer::timeout, this, &ZigbeeBridgeControllerDeconz::onWatchdogTimerTimeout);
|
connect(m_watchdogTimer, &QTimer::timeout, this, &ZigbeeBridgeControllerDeconz::resetControllerWatchdog);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeBridgeControllerDeconz::~ZigbeeBridgeControllerDeconz()
|
ZigbeeBridgeControllerDeconz::~ZigbeeBridgeControllerDeconz()
|
||||||
@ -49,6 +49,17 @@ ZigbeeBridgeControllerDeconz::~ZigbeeBridgeControllerDeconz()
|
|||||||
qCDebug(dcZigbeeController()) << "Destroy controller";
|
qCDebug(dcZigbeeController()) << "Destroy controller";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeconzNetworkConfiguration ZigbeeBridgeControllerDeconz::networkConfiguration() const
|
||||||
|
{
|
||||||
|
return m_networkConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeBridgeControllerDeconz::setFirmwareVersionString(const QString &firmwareVersion)
|
||||||
|
{
|
||||||
|
m_firmwareVersion = firmwareVersion;
|
||||||
|
emit firmwareVersionChanged(m_firmwareVersion);
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestVersion()
|
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestVersion()
|
||||||
{
|
{
|
||||||
quint8 sequenceNumber = generateSequenceNumber();
|
quint8 sequenceNumber = generateSequenceNumber();
|
||||||
@ -120,14 +131,15 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestWriteParameter(
|
|||||||
quint8 sequenceNumber = generateSequenceNumber();
|
quint8 sequenceNumber = generateSequenceNumber();
|
||||||
qCDebug(dcZigbeeController()) << "Request write parameter. SQN:" << sequenceNumber << parameter << ZigbeeUtils::convertByteArrayToHexString(data);
|
qCDebug(dcZigbeeController()) << "Request write parameter. SQN:" << sequenceNumber << parameter << ZigbeeUtils::convertByteArrayToHexString(data);
|
||||||
|
|
||||||
|
quint16 payloadLength = static_cast<quint16>(1 + data.length());
|
||||||
QByteArray message;
|
QByteArray message;
|
||||||
QDataStream stream(&message, QIODevice::WriteOnly);
|
QDataStream stream(&message, QIODevice::WriteOnly);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
stream << static_cast<quint8>(Deconz::CommandWriteParameter);
|
stream << static_cast<quint8>(Deconz::CommandWriteParameter);
|
||||||
stream << static_cast<quint8>(sequenceNumber);
|
stream << static_cast<quint8>(sequenceNumber);
|
||||||
stream << static_cast<quint8>(0); // Reserverd
|
stream << static_cast<quint8>(0); // Reserverd
|
||||||
stream << static_cast<quint16>(7 + 1 + data.length()); // Frame length 7 + 1 parameter + payload length
|
stream << static_cast<quint16>(7 + payloadLength); // Frame length 7 + payload length
|
||||||
stream << static_cast<quint16>(1 + data.length()); // 1 parameter + payload length
|
stream << static_cast<quint16>(payloadLength); // 1 parameter + parameter data length
|
||||||
stream << static_cast<quint8>(parameter);
|
stream << static_cast<quint8>(parameter);
|
||||||
for (int i = 0; i < data.length(); i++) {
|
for (int i = 0; i < data.length(); i++) {
|
||||||
stream << static_cast<quint8>(data.at(i));
|
stream << static_cast<quint8>(data.at(i));
|
||||||
@ -157,6 +169,31 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestChangeNetworkSt
|
|||||||
return createReply(Deconz::CommandChangeNetworkState, sequenceNumber, this);
|
return createReply(Deconz::CommandChangeNetworkState, sequenceNumber, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::requestReadReceivedDataIndication(Deconz::SourceAddressMode sourceAddressMode)
|
||||||
|
{
|
||||||
|
quint8 sequenceNumber = generateSequenceNumber();
|
||||||
|
qCDebug(dcZigbeeController()) << "Request read received data indication. SQN:" << sequenceNumber << ZigbeeUtils::convertByteToHexString(sourceAddressMode);
|
||||||
|
|
||||||
|
quint16 payloadLength = 0;
|
||||||
|
if (sourceAddressMode != Deconz::SourceAddressModeNone) {
|
||||||
|
payloadLength = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray message;
|
||||||
|
QDataStream stream(&message, QIODevice::WriteOnly);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
stream << static_cast<quint8>(Deconz::CommandApsDataIndication);
|
||||||
|
stream << static_cast<quint8>(sequenceNumber);
|
||||||
|
stream << static_cast<quint8>(0); // Reserverd
|
||||||
|
stream << static_cast<quint16>(7 + payloadLength); // Frame length + payload length
|
||||||
|
stream << static_cast<quint16>(payloadLength); // payload length
|
||||||
|
if (payloadLength > 0)
|
||||||
|
stream << static_cast<quint8>(sourceAddressMode);
|
||||||
|
|
||||||
|
m_interface->sendPackage(message);
|
||||||
|
|
||||||
|
return createReply(Deconz::CommandApsDataIndication, sequenceNumber, this);
|
||||||
|
}
|
||||||
|
|
||||||
quint8 ZigbeeBridgeControllerDeconz::generateSequenceNumber()
|
quint8 ZigbeeBridgeControllerDeconz::generateSequenceNumber()
|
||||||
{
|
{
|
||||||
@ -464,6 +501,7 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
m_watchdogTimer->stop();
|
m_watchdogTimer->stop();
|
||||||
|
|
||||||
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
||||||
|
emit networkConfigurationParameterChanged(m_networkConfiguration);
|
||||||
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
||||||
readNetworkParametersReply->finished();
|
readNetworkParametersReply->finished();
|
||||||
return;
|
return;
|
||||||
@ -491,10 +529,11 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
|
|
||||||
// Note: this value describes how much seconds are left until the watchdog triggers. Reset it right the way
|
// Note: this value describes how much seconds are left until the watchdog triggers. Reset it right the way
|
||||||
if (watchdogTimeout < 15) {
|
if (watchdogTimeout < 15) {
|
||||||
onWatchdogTimerTimeout();
|
resetControllerWatchdog();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
// Finished reading all parameters. Finish the independent reply in order to indicate the process has finished
|
||||||
|
emit networkConfigurationParameterChanged(m_networkConfiguration);
|
||||||
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
readNetworkParametersReply->m_statusCode = Deconz::StatusCodeSuccess;
|
||||||
readNetworkParametersReply->finished();
|
readNetworkParametersReply->finished();
|
||||||
});
|
});
|
||||||
@ -515,20 +554,121 @@ ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::readNetworkParameters(
|
|||||||
return readNetworkParametersReply;
|
return readNetworkParametersReply;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *ZigbeeBridgeControllerDeconz::resetWatchdog()
|
DeconzDeviceState ZigbeeBridgeControllerDeconz::parseDeviceStateFlag(quint8 deviceStateFlag)
|
||||||
{
|
{
|
||||||
QByteArray parameterData;
|
DeconzDeviceState state;
|
||||||
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
state.networkState = static_cast<Deconz::NetworkState>(deviceStateFlag & 0x03);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
state.aspDataConfirm = (deviceStateFlag & 0x04);
|
||||||
stream << m_watchdogTimeout;
|
state.aspDataIndication = (deviceStateFlag & 0x08);
|
||||||
return requestWriteParameter(Deconz::ParameterWatchdogTtl, parameterData);
|
state.configurationChanged = (deviceStateFlag & 0x10);
|
||||||
|
state.aspDataRequestFreeSlots = (deviceStateFlag & 0x20);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeBridgeControllerDeconz::processDeviceState(DeconzDeviceState deviceState)
|
||||||
|
{
|
||||||
|
qCDebug(dcZigbeeController()) << "Device state changed notification:" << deviceState.networkState
|
||||||
|
<< "ASPDE-DATA.confirm:" << deviceState.aspDataConfirm
|
||||||
|
<< "ASPDE-DATA.indication:" << deviceState.aspDataIndication
|
||||||
|
<< "configuration changed:" << deviceState.configurationChanged
|
||||||
|
<< "ASPDE-DATA.request free slots:" << deviceState.aspDataRequestFreeSlots;
|
||||||
|
|
||||||
|
// Check if we have to fech new data
|
||||||
|
if (deviceState.aspDataConfirm) {
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = requestReadReceivedDataIndication();
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could not read data indication." << reply->statusCode();
|
||||||
|
// FIXME: set an appropriate error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ASP data indication received
|
||||||
|
|
||||||
|
QDataStream stream(reply->responseData());
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
quint16 payloadLenght = 0; quint8 deviceStateFlag = 0; quint8 destinationAddressModeFlag = 0;
|
||||||
|
quint16 destinationShortAddress = 0; quint64 destinationIeeeAddress = 0; quint8 destinationEndpoint = 0;
|
||||||
|
quint8 sourceAddressModeFlag = 0; quint16 sourceShortAddress = 0; quint64 sourceIeeeAddress = 0; quint8 sourceEndpoint = 0;
|
||||||
|
quint16 profileId = 0; quint16 clusterId = 0; quint16 asduLength = 0; QByteArray asdu; quint8 reserved = 0;
|
||||||
|
quint8 lqi = 0; qint8 rssi = 0;
|
||||||
|
|
||||||
|
stream >> payloadLenght >> deviceStateFlag >> destinationAddressModeFlag;
|
||||||
|
Zigbee::DestinationAddressMode destinationAddressMode = static_cast<Zigbee::DestinationAddressMode>(destinationAddressModeFlag);
|
||||||
|
if (destinationAddressMode == Zigbee::DestinationAddressModeGroup || destinationAddressMode == Zigbee::DestinationAddressModeShortAddress)
|
||||||
|
stream >> destinationShortAddress;
|
||||||
|
|
||||||
|
if (destinationAddressMode == Zigbee::DestinationAddressModeUnicastIeee)
|
||||||
|
stream >> destinationIeeeAddress;
|
||||||
|
|
||||||
|
stream >> destinationEndpoint >> sourceAddressModeFlag;
|
||||||
|
|
||||||
|
Zigbee::SourceAddressMode sourceAddressMode = static_cast<Zigbee::SourceAddressMode>(sourceAddressModeFlag);
|
||||||
|
if (sourceAddressMode == Zigbee::SourceAddressModeShortAddress || sourceAddressMode == Zigbee::SourceAddressModeShortAndIeeeAddress)
|
||||||
|
stream >> sourceShortAddress;
|
||||||
|
|
||||||
|
if (sourceAddressMode == Zigbee::SourceAddressModeIeeeAddress || sourceAddressMode == Zigbee::SourceAddressModeShortAndIeeeAddress)
|
||||||
|
stream >> sourceIeeeAddress;
|
||||||
|
|
||||||
|
stream >> sourceEndpoint >> profileId >> clusterId >> asduLength;
|
||||||
|
|
||||||
|
// Fill asdu data
|
||||||
|
for (int i = 0; i < asduLength; i++) {
|
||||||
|
quint8 byte = 0;
|
||||||
|
stream >> byte;
|
||||||
|
asdu.append(static_cast<char>(byte));
|
||||||
|
}
|
||||||
|
|
||||||
|
stream >> reserved >> reserved >> lqi >> reserved >> reserved >> reserved >> reserved >> rssi;
|
||||||
|
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeController()) << "Data indication received:";
|
||||||
|
qCDebug(dcZigbeeController()) << " Destination address mode:" << destinationAddressMode;
|
||||||
|
if (destinationAddressMode == Zigbee::DestinationAddressModeGroup)
|
||||||
|
qCDebug(dcZigbeeController()) << " Destination address (group):" << ZigbeeUtils::convertUint16ToHexString(destinationShortAddress);
|
||||||
|
|
||||||
|
if (destinationAddressMode == Zigbee::DestinationAddressModeShortAddress)
|
||||||
|
qCDebug(dcZigbeeController()) << " Destination short address:" << ZigbeeUtils::convertUint16ToHexString(destinationShortAddress);
|
||||||
|
|
||||||
|
if (destinationAddressMode == Zigbee::DestinationAddressModeUnicastIeee)
|
||||||
|
qCDebug(dcZigbeeController()) << " Destination IEEE address:" << ZigbeeAddress(destinationIeeeAddress).toString();
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeController()) << " Destination endpoint" << ZigbeeUtils::convertByteToHexString(destinationEndpoint);
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeController()) << " Source address mode:" << sourceAddressMode;
|
||||||
|
if (sourceAddressMode == Zigbee::SourceAddressModeShortAddress || sourceAddressMode == Zigbee::SourceAddressModeShortAndIeeeAddress)
|
||||||
|
qCDebug(dcZigbeeController()) << " Source address:" << ZigbeeUtils::convertUint16ToHexString(sourceShortAddress);
|
||||||
|
|
||||||
|
if (sourceAddressMode == Zigbee::SourceAddressModeIeeeAddress || sourceAddressMode == Zigbee::SourceAddressModeShortAndIeeeAddress)
|
||||||
|
qCDebug(dcZigbeeController()) << " Source IEEE address:" << ZigbeeAddress(sourceIeeeAddress).toString();
|
||||||
|
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeController()) << " Source endpoint:" << ZigbeeUtils::convertByteToHexString(sourceEndpoint);
|
||||||
|
qCDebug(dcZigbeeController()) << " Profile:" << static_cast<Zigbee::ZigbeeProfile>(profileId);
|
||||||
|
qCDebug(dcZigbeeController()) << " Cluster:" << static_cast<Zigbee::ClusterId>(clusterId);
|
||||||
|
qCDebug(dcZigbeeController()) << " ASDU:" << ZigbeeUtils::convertByteArrayToHexString(asdu);
|
||||||
|
qCDebug(dcZigbeeController()) << " LQI:" << lqi;
|
||||||
|
qCDebug(dcZigbeeController()) << " RSSI:" << rssi << "dBm";
|
||||||
|
|
||||||
|
processDeviceState(parseDeviceStateFlag(deviceStateFlag));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged(bool available)
|
void ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged(bool available)
|
||||||
{
|
{
|
||||||
if (available) {
|
if (available) {
|
||||||
|
// FIXME: only start if the protocol version is >= 0x0108
|
||||||
m_watchdogTimer->start();
|
m_watchdogTimer->start();
|
||||||
} else {
|
} else {
|
||||||
|
// Clean up any pending replies
|
||||||
|
foreach (quint8 id, m_pendingReplies.keys()) {
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_pendingReplies.take(id);
|
||||||
|
reply->abort();
|
||||||
|
}
|
||||||
|
|
||||||
m_watchdogTimer->stop();
|
m_watchdogTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,20 +679,20 @@ void ZigbeeBridgeControllerDeconz::onInterfacePackageReceived(const QByteArray &
|
|||||||
{
|
{
|
||||||
QDataStream stream(package);
|
QDataStream stream(package);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint8 command = 0; quint8 sequenceNumber = 0; quint8 status = 0; quint16 frameLength = 0;
|
quint8 commandInt = 0; quint8 sequenceNumber = 0; quint8 statusInt = 0; quint16 frameLength = 0;
|
||||||
stream >> command >> sequenceNumber >> status >> frameLength;
|
stream >> commandInt >> sequenceNumber >> statusInt >> frameLength;
|
||||||
|
|
||||||
qCDebug(dcZigbeeController()) << "Interface message received"
|
QByteArray data = package.right(package.length() - 5);
|
||||||
<< static_cast<Deconz::Command>(command)
|
Deconz::Command command = static_cast<Deconz::Command>(commandInt);
|
||||||
<< "SQN:" << sequenceNumber
|
Deconz::StatusCode status = static_cast<Deconz::StatusCode>(statusInt);
|
||||||
<< static_cast<Deconz::StatusCode>(status)
|
qCDebug(dcZigbeeController()) << "Interface message received" << command << "SQN:" << sequenceNumber
|
||||||
<< "Frame length:" << frameLength;
|
<< status << "Frame length:" << frameLength << ZigbeeUtils::convertByteArrayToHexString(data);
|
||||||
|
|
||||||
// Check if this is an interface response for a pending reply
|
// Check if this is an interface response for a pending reply
|
||||||
if (m_pendingReplies.contains(sequenceNumber) && m_pendingReplies.value(sequenceNumber)->command() == command) {
|
if (m_pendingReplies.contains(sequenceNumber) && m_pendingReplies.value(sequenceNumber)->command() == command) {
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_pendingReplies.take(sequenceNumber);
|
ZigbeeInterfaceDeconzReply *reply = m_pendingReplies.take(sequenceNumber);
|
||||||
reply->m_responseData = package.right(package.length() - 5);
|
reply->m_responseData = data;
|
||||||
reply->m_statusCode = static_cast<Deconz::StatusCode>(status);
|
reply->m_statusCode = status;
|
||||||
reply->finished();
|
reply->finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -563,12 +703,28 @@ void ZigbeeBridgeControllerDeconz::onInterfacePackageReceived(const QByteArray &
|
|||||||
m_sequenceNumber = sequenceNumber;
|
m_sequenceNumber = sequenceNumber;
|
||||||
|
|
||||||
// No request for this data, lets check which notification and process the data
|
// No request for this data, lets check which notification and process the data
|
||||||
|
switch (command) {
|
||||||
|
case Deconz::CommandDeviceStateChanged: {
|
||||||
|
quint8 deviceStateFlag = 0;
|
||||||
|
stream >> deviceStateFlag;
|
||||||
|
processDeviceState(parseDeviceStateFlag(deviceStateFlag));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
qCWarning(dcZigbeeController()) << "Unhandled interface package received" << command << "SQN:" << sequenceNumber
|
||||||
|
<< status << "Frame length:" << frameLength << ZigbeeUtils::convertByteArrayToHexString(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeBridgeControllerDeconz::onWatchdogTimerTimeout()
|
void ZigbeeBridgeControllerDeconz::resetControllerWatchdog()
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeController()) << "Reset application watchdog on the deCONZ controller";
|
QByteArray parameterData;
|
||||||
ZigbeeInterfaceDeconzReply *reply = resetWatchdog();
|
QDataStream stream(¶meterData, QIODevice::WriteOnly);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
stream << m_watchdogTimeout;
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = requestWriteParameter(Deconz::ParameterWatchdogTtl, parameterData);
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [reply](){
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [reply](){
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
qCWarning(dcZigbeeController()) << "Could not reset the application watchdog on the deCONZ controller." << reply->statusCode();
|
qCWarning(dcZigbeeController()) << "Could not reset the application watchdog on the deCONZ controller." << reply->statusCode();
|
||||||
|
|||||||
@ -41,24 +41,37 @@
|
|||||||
#include "interface/zigbeeinterfacedeconz.h"
|
#include "interface/zigbeeinterfacedeconz.h"
|
||||||
#include "interface/zigbeeinterfacedeconzreply.h"
|
#include "interface/zigbeeinterfacedeconzreply.h"
|
||||||
|
|
||||||
|
// This struct describes the current deCONZ network configuration parameters
|
||||||
typedef struct DeconzNetworkConfiguration {
|
typedef struct DeconzNetworkConfiguration {
|
||||||
ZigbeeAddress ieeeAddress; // R
|
ZigbeeAddress ieeeAddress; // R
|
||||||
quint16 panId; // R
|
quint16 panId = 0; // R
|
||||||
quint16 shortAddress; // R
|
quint16 shortAddress = 0; // R
|
||||||
quint64 extendedPanId; // R
|
quint64 extendedPanId = 0; // R
|
||||||
Deconz::NodeType nodeType; // RW
|
Deconz::NodeType nodeType = Deconz::NodeTypeCoordinator; // RW
|
||||||
quint32 channelMask; // RW
|
quint32 channelMask = 0; // RW
|
||||||
quint64 apsExtendedPanId; // RW
|
quint64 apsExtendedPanId = 0; // RW
|
||||||
ZigbeeAddress trustCenterAddress; // RW
|
ZigbeeAddress trustCenterAddress; // RW
|
||||||
Deconz::SecurityMode securityMode; // RW
|
Deconz::SecurityMode securityMode = Deconz::SecurityModeNoMasterButTrustCenterKey; // RW
|
||||||
ZigbeeNetworkKey networkKey; // RW
|
ZigbeeNetworkKey networkKey; // RW
|
||||||
quint8 currentChannel; // R
|
quint8 currentChannel = 0; // R
|
||||||
quint16 protocolVersion; // R
|
quint16 protocolVersion = 0; // R
|
||||||
quint8 networkUpdateId; // RW
|
quint8 networkUpdateId = 0; // RW
|
||||||
quint32 watchdogTimeout; // RW
|
quint32 watchdogTimeout = 85; // RW
|
||||||
} DeconzNetworkConfiguration;
|
} DeconzNetworkConfiguration;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// This struct describes the deCONZ device state
|
||||||
|
typedef struct DeconzDeviceState {
|
||||||
|
Deconz::NetworkState networkState = Deconz::NetworkStateOffline;
|
||||||
|
bool aspDataConfirm = false;
|
||||||
|
bool aspDataIndication = false;
|
||||||
|
bool configurationChanged = false;
|
||||||
|
bool aspDataRequestFreeSlots = false;
|
||||||
|
} DeconzDeviceState;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ZigbeeBridgeControllerDeconz : public ZigbeeBridgeController
|
class ZigbeeBridgeControllerDeconz : public ZigbeeBridgeController
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -69,11 +82,16 @@ public:
|
|||||||
explicit ZigbeeBridgeControllerDeconz(QObject *parent = nullptr);
|
explicit ZigbeeBridgeControllerDeconz(QObject *parent = nullptr);
|
||||||
~ZigbeeBridgeControllerDeconz() override;
|
~ZigbeeBridgeControllerDeconz() override;
|
||||||
|
|
||||||
|
DeconzNetworkConfiguration networkConfiguration() const;
|
||||||
|
void setFirmwareVersionString(const QString &firmwareVersion);
|
||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *requestVersion();
|
ZigbeeInterfaceDeconzReply *requestVersion();
|
||||||
ZigbeeInterfaceDeconzReply *requestDeviceState();
|
ZigbeeInterfaceDeconzReply *requestDeviceState();
|
||||||
ZigbeeInterfaceDeconzReply *requestReadParameter(Deconz::Parameter parameter);
|
ZigbeeInterfaceDeconzReply *requestReadParameter(Deconz::Parameter parameter);
|
||||||
ZigbeeInterfaceDeconzReply *requestWriteParameter(Deconz::Parameter parameter, const QByteArray &data);
|
ZigbeeInterfaceDeconzReply *requestWriteParameter(Deconz::Parameter parameter, const QByteArray &data);
|
||||||
ZigbeeInterfaceDeconzReply *requestStartJoinNetwork();
|
ZigbeeInterfaceDeconzReply *requestChangeNetworkState(Deconz::NetworkState networkState);
|
||||||
|
ZigbeeInterfaceDeconzReply *requestReadReceivedDataIndication(Deconz::SourceAddressMode sourceAddressMode = Deconz::SourceAddressModeShortSourceAddress);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ZigbeeInterfaceDeconz *m_interface = nullptr;
|
ZigbeeInterfaceDeconz *m_interface = nullptr;
|
||||||
@ -92,15 +110,18 @@ private:
|
|||||||
// The data can be fetched from m_networkConfiguration on success.
|
// The data can be fetched from m_networkConfiguration on success.
|
||||||
ZigbeeInterfaceDeconzReply *readNetworkParameters();
|
ZigbeeInterfaceDeconzReply *readNetworkParameters();
|
||||||
|
|
||||||
ZigbeeInterfaceDeconzReply *resetWatchdog();
|
DeconzDeviceState parseDeviceStateFlag(quint8 deviceStateFlag);
|
||||||
|
|
||||||
|
void processDeviceState(DeconzDeviceState deviceState);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void networkConfigurationParameterChanged(const DeconzNetworkConfiguration &networkConfiguration);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onInterfaceAvailableChanged(bool available);
|
void onInterfaceAvailableChanged(bool available);
|
||||||
void onInterfacePackageReceived(const QByteArray &package);
|
void onInterfacePackageReceived(const QByteArray &package);
|
||||||
|
|
||||||
void onWatchdogTimerTimeout();
|
void resetControllerWatchdog();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool enable(const QString &serialPort, qint32 baudrate);
|
bool enable(const QString &serialPort, qint32 baudrate);
|
||||||
|
|||||||
@ -29,6 +29,8 @@
|
|||||||
#include "loggingcategory.h"
|
#include "loggingcategory.h"
|
||||||
#include "zigbeeutils.h"
|
#include "zigbeeutils.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
ZigbeeNetworkDeconz::ZigbeeNetworkDeconz(QObject *parent) :
|
ZigbeeNetworkDeconz::ZigbeeNetworkDeconz(QObject *parent) :
|
||||||
ZigbeeNetwork(parent)
|
ZigbeeNetwork(parent)
|
||||||
{
|
{
|
||||||
@ -58,65 +60,117 @@ void ZigbeeNetworkDeconz::setPermitJoiningInternal(bool permitJoining)
|
|||||||
Q_UNUSED(permitJoining)
|
Q_UNUSED(permitJoining)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetworkDeconz::startNetworkInternally()
|
||||||
|
{
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Start network internally";
|
||||||
|
|
||||||
|
// Check if we have to create a pan ID and select the channel
|
||||||
|
if (extendedPanId() == 0) {
|
||||||
|
m_createNewNetwork = true;
|
||||||
|
setExtendedPanId(ZigbeeUtils::generateRandomPanId());
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Created new PAN ID:" << extendedPanId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (securityConfiguration().networkKey().isNull()) {
|
||||||
|
m_createNewNetwork = true;
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Create a new network key";
|
||||||
|
ZigbeeNetworkKey key = ZigbeeNetworkKey::generateKey();
|
||||||
|
m_securityConfiguration.setNetworkKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Using" << securityConfiguration().networkKey() << "network link key";
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Using" << securityConfiguration().globalTrustCenterLinkKey() << "global trust center link key";
|
||||||
|
|
||||||
|
|
||||||
|
// - Read the firmware version
|
||||||
|
// - Read the network configuration parameters
|
||||||
|
// - Read the network state
|
||||||
|
|
||||||
|
// - If network running and we don't have configurations, write them
|
||||||
|
// - If network running and configurations match, we are done
|
||||||
|
|
||||||
|
// Read the firmware version
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestVersion();
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
|
||||||
|
// FIXME: set an appropriate error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Version request finished" << reply->statusCode() << ZigbeeUtils::convertByteArrayToHexString(reply->responseData());
|
||||||
|
// Note: version is an uint32 value, little endian, but we can read the individual bytes in reversed order
|
||||||
|
quint8 majorVersion = static_cast<quint8>(reply->responseData().at(3));
|
||||||
|
quint8 minorVersion = static_cast<quint8>(reply->responseData().at(2));
|
||||||
|
Deconz::Platform platform = static_cast<Deconz::Platform>(reply->responseData().at(1));
|
||||||
|
QString firmwareVersion = QString("%1.%2").arg(majorVersion).arg(minorVersion);
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Firmware version" << firmwareVersion << platform;
|
||||||
|
|
||||||
|
// Read all network parameters
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply, firmwareVersion](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could not read network parameters during network start up." << reply->statusCode();
|
||||||
|
// FIXME: set an appropriate error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully.";
|
||||||
|
QString protocolVersion = QString("%1.%2").arg(m_controller->networkConfiguration().protocolVersion & 0xFF00)
|
||||||
|
.arg(m_controller->networkConfiguration().protocolVersion & 0x00FF);
|
||||||
|
|
||||||
|
m_controller->setFirmwareVersionString(QString("%1 - %2").arg(firmwareVersion).arg(protocolVersion));
|
||||||
|
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestDeviceState();
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could not read device state during network start up." << reply->statusCode();
|
||||||
|
// FIXME: set an appropriate error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Read device state finished successfully";
|
||||||
|
QDataStream stream(reply->responseData());
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (m_createNewNetwork) {
|
||||||
|
// Write the configurations which need to be changed
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize coordinator node
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Get the network state and start the network if required
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
|
void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
|
||||||
{
|
{
|
||||||
qCDebug(dcZigbeeNetwork()) << "Hardware controller is" << (available ? "now available" : "not available");
|
qCDebug(dcZigbeeNetwork()) << "Hardware controller is" << (available ? "now available" : "not available");
|
||||||
|
|
||||||
if (!available) {
|
if (!available) {
|
||||||
// foreach (ZigbeeNode *node, nodes()) {
|
|
||||||
// qobject_cast<ZigbeeNodeNxp *>(node)->setConnected(false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
setError(ErrorHardwareUnavailable);
|
setError(ErrorHardwareUnavailable);
|
||||||
m_permitJoining = false;
|
m_permitJoining = false;
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
emit permitJoiningChanged(m_permitJoining);
|
||||||
//setStartingState(StartingStateNone);
|
|
||||||
setState(StateOffline);
|
setState(StateOffline);
|
||||||
} else {
|
} else {
|
||||||
m_error = ErrorNoError;
|
m_error = ErrorNoError;
|
||||||
m_permitJoining = false;
|
m_permitJoining = false;
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
emit permitJoiningChanged(m_permitJoining);
|
||||||
// Note: if we are factory resetting, erase also the data on the controller before resetting
|
|
||||||
// if (m_factoryResetting) {
|
|
||||||
// setStartingState(StartingStateErase);
|
|
||||||
// } else {
|
|
||||||
// setStartingState(StartingStateReset);
|
|
||||||
// }
|
|
||||||
|
|
||||||
setState(StateStarting);
|
setState(StateStarting);
|
||||||
|
startNetworkInternally();
|
||||||
// FIXME: do this in the startig state machine
|
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestVersion();
|
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
|
||||||
qCWarning(dcZigbeeController()) << "Request" << reply->command() << "finished with error" << reply->statusCode();
|
|
||||||
// FIXME: set an appropriate error
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Version request finished" << reply->statusCode() << ZigbeeUtils::convertByteArrayToHexString(reply->responseData());
|
|
||||||
// Note: version is an uint32 value, little endian, but we can read the individual bytes in reversed order
|
|
||||||
quint8 majorVersion = static_cast<quint8>(reply->responseData().at(3));
|
|
||||||
quint8 minorVersion = static_cast<quint8>(reply->responseData().at(2));
|
|
||||||
Deconz::Platform platform = static_cast<Deconz::Platform>(reply->responseData().at(1));
|
|
||||||
QString firmwareVersion = QString("%1.%2").arg(majorVersion).arg(minorVersion);
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Firmware version" << firmwareVersion << platform;
|
|
||||||
|
|
||||||
// Read all network parameters
|
|
||||||
ZigbeeInterfaceDeconzReply *reply = m_controller->readNetworkParameters();
|
|
||||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
|
||||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
|
||||||
qCWarning(dcZigbeeController()) << "Could not read network parameters during network start up." << reply->statusCode();
|
|
||||||
// FIXME: set an appropriate error
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully.";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,23 +178,6 @@ void ZigbeeNetworkDeconz::startNetwork()
|
|||||||
{
|
{
|
||||||
loadNetwork();
|
loadNetwork();
|
||||||
|
|
||||||
// Check if we have to create a pan ID and select the channel
|
|
||||||
if (extendedPanId() == 0) {
|
|
||||||
setExtendedPanId(ZigbeeUtils::generateRandomPanId());
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Created new PAN ID:" << extendedPanId();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (securityConfiguration().networkKey().isNull()) {
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Create a new network key";
|
|
||||||
ZigbeeNetworkKey key = ZigbeeNetworkKey::generateKey();
|
|
||||||
m_securityConfiguration.setNetworkKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Using network link key" << securityConfiguration().networkKey();
|
|
||||||
qCDebug(dcZigbeeNetwork()) << "Using global trust center link key" << securityConfiguration().globalTrustCenterLinkKey();
|
|
||||||
|
|
||||||
// TODO: get desired channel, by default use all
|
|
||||||
|
|
||||||
if (!m_controller->enable(serialPortName(), serialBaudrate())) {
|
if (!m_controller->enable(serialPortName(), serialBaudrate())) {
|
||||||
m_permitJoining = false;
|
m_permitJoining = false;
|
||||||
emit permitJoiningChanged(m_permitJoining);
|
emit permitJoiningChanged(m_permitJoining);
|
||||||
@ -157,15 +194,26 @@ void ZigbeeNetworkDeconz::startNetwork()
|
|||||||
|
|
||||||
void ZigbeeNetworkDeconz::stopNetwork()
|
void ZigbeeNetworkDeconz::stopNetwork()
|
||||||
{
|
{
|
||||||
|
ZigbeeInterfaceDeconzReply *reply = m_controller->requestChangeNetworkState(Deconz::NetworkStateOffline);
|
||||||
|
setState(StateStopping);
|
||||||
|
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||||
|
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||||
|
qCWarning(dcZigbeeController()) << "Could not leave network." << reply->statusCode();
|
||||||
|
// FIXME: set an appropriate error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dcZigbeeNetwork()) << "Network left successfully";
|
||||||
|
setState(StateOffline);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::reset()
|
void ZigbeeNetworkDeconz::reset()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZigbeeNetworkDeconz::factoryResetNetwork()
|
void ZigbeeNetworkDeconz::factoryResetNetwork()
|
||||||
{
|
{
|
||||||
|
// Wipe settings, and reconfigure network
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "zigbeenetwork.h"
|
#include "zigbeenetwork.h"
|
||||||
|
#include "zigbeechannelmask.h"
|
||||||
#include "zigbeebridgecontrollerdeconz.h"
|
#include "zigbeebridgecontrollerdeconz.h"
|
||||||
|
|
||||||
class ZigbeeNetworkDeconz : public ZigbeeNetwork
|
class ZigbeeNetworkDeconz : public ZigbeeNetwork
|
||||||
@ -44,11 +44,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
ZigbeeBridgeControllerDeconz *m_controller = nullptr;
|
ZigbeeBridgeControllerDeconz *m_controller = nullptr;
|
||||||
bool m_networkRunning = false;
|
bool m_networkRunning = false;
|
||||||
|
bool m_createNewNetwork = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ZigbeeNode *createNode(QObject *parent) override;
|
ZigbeeNode *createNode(QObject *parent) override;
|
||||||
void setPermitJoiningInternal(bool permitJoining) override;
|
void setPermitJoiningInternal(bool permitJoining) override;
|
||||||
|
|
||||||
|
void startNetworkInternally();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onControllerAvailableChanged(bool available);
|
void onControllerAvailableChanged(bool available);
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@ SOURCES += \
|
|||||||
nxp/zigbeenodeendpointnxp.cpp \
|
nxp/zigbeenodeendpointnxp.cpp \
|
||||||
nxp/zigbeenodenxp.cpp \
|
nxp/zigbeenodenxp.cpp \
|
||||||
zigbeebridgecontroller.cpp \
|
zigbeebridgecontroller.cpp \
|
||||||
|
zigbeechannelmask.cpp \
|
||||||
zigbeecluster.cpp \
|
zigbeecluster.cpp \
|
||||||
zigbeeclusterattribute.cpp \
|
zigbeeclusterattribute.cpp \
|
||||||
zigbeemanufacturer.cpp \
|
zigbeemanufacturer.cpp \
|
||||||
@ -47,6 +48,7 @@ HEADERS += \
|
|||||||
nxp/zigbeenodeendpointnxp.h \
|
nxp/zigbeenodeendpointnxp.h \
|
||||||
nxp/zigbeenodenxp.h \
|
nxp/zigbeenodenxp.h \
|
||||||
zigbeebridgecontroller.h \
|
zigbeebridgecontroller.h \
|
||||||
|
zigbeechannelmask.h \
|
||||||
zigbeecluster.h \
|
zigbeecluster.h \
|
||||||
zigbeeclusterattribute.h \
|
zigbeeclusterattribute.h \
|
||||||
zigbeemanufacturer.h \
|
zigbeemanufacturer.h \
|
||||||
|
|||||||
@ -53,21 +53,22 @@ public:
|
|||||||
Q_ENUM(ZigbeeProfile)
|
Q_ENUM(ZigbeeProfile)
|
||||||
|
|
||||||
enum ZigbeeChannel {
|
enum ZigbeeChannel {
|
||||||
ZigbeeChannel11,
|
ZigbeeChannel11 = 0x00000800,
|
||||||
ZigbeeChannel12,
|
ZigbeeChannel12 = 0x00001000,
|
||||||
ZigbeeChannel13,
|
ZigbeeChannel13 = 0x00002000,
|
||||||
ZigbeeChannel14,
|
ZigbeeChannel14 = 0x00004000,
|
||||||
ZigbeeChannel15,
|
ZigbeeChannel15 = 0x00008000,
|
||||||
ZigbeeChannel16,
|
ZigbeeChannel16 = 0x00010000,
|
||||||
ZigbeeChannel17,
|
ZigbeeChannel17 = 0x00020000,
|
||||||
ZigbeeChannel18,
|
ZigbeeChannel18 = 0x00040000,
|
||||||
ZigbeeChannel19,
|
ZigbeeChannel19 = 0x00080000,
|
||||||
ZigbeeChannel20,
|
ZigbeeChannel20 = 0x00100000,
|
||||||
ZigbeeChannel21,
|
ZigbeeChannel21 = 0x00200000,
|
||||||
ZigbeeChannel22,
|
ZigbeeChannel22 = 0x00400000,
|
||||||
ZigbeeChannel23,
|
ZigbeeChannel23 = 0x00800000,
|
||||||
ZigbeeChannel24,
|
ZigbeeChannel24 = 0x01000000,
|
||||||
ZigbeeChannel25
|
ZigbeeChannel25 = 0x02000000,
|
||||||
|
ZigbeeChannel26 = 0x04000000
|
||||||
};
|
};
|
||||||
Q_ENUM(ZigbeeChannel)
|
Q_ENUM(ZigbeeChannel)
|
||||||
Q_DECLARE_FLAGS(ZigbeeChannels, ZigbeeChannel)
|
Q_DECLARE_FLAGS(ZigbeeChannels, ZigbeeChannel)
|
||||||
@ -540,6 +541,13 @@ public:
|
|||||||
};
|
};
|
||||||
Q_ENUM(DestinationAddressMode)
|
Q_ENUM(DestinationAddressMode)
|
||||||
|
|
||||||
|
enum SourceAddressMode {
|
||||||
|
SourceAddressModeShortAddress = 0x02,
|
||||||
|
SourceAddressModeIeeeAddress = 0x03,
|
||||||
|
SourceAddressModeShortAndIeeeAddress = 0x04
|
||||||
|
};
|
||||||
|
Q_ENUM(SourceAddressMode)
|
||||||
|
|
||||||
enum ZigbeeZclStatus {
|
enum ZigbeeZclStatus {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
106
libnymea-zigbee/zigbeechannelmask.cpp
Normal file
106
libnymea-zigbee/zigbeechannelmask.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea-zigbee.
|
||||||
|
* This project including source code and documentation is protected by copyright law, and
|
||||||
|
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||||
|
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||||
|
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||||
|
* of use of nymea GmbH, available under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||||
|
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||||
|
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||||
|
* If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under contact@nymea.io
|
||||||
|
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "zigbeechannelmask.h"
|
||||||
|
#include "zigbeeutils.h"
|
||||||
|
|
||||||
|
ZigbeeChannelMask::ZigbeeChannelMask()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeChannelMask::ZigbeeChannelMask(quint32 channelMask) :
|
||||||
|
m_channelMask(channelMask)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeChannelMask::ZigbeeChannelMask(Zigbee::ZigbeeChannels channels)
|
||||||
|
{
|
||||||
|
m_channelMask = static_cast<quint32>(channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 ZigbeeChannelMask::toUInt32() const
|
||||||
|
{
|
||||||
|
return m_channelMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
Zigbee::ZigbeeChannels ZigbeeChannelMask::channels() const
|
||||||
|
{
|
||||||
|
return static_cast<Zigbee::ZigbeeChannels>(m_channelMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigbeeChannelMask::isSet(Zigbee::ZigbeeChannel channel) const
|
||||||
|
{
|
||||||
|
return channels().testFlag(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeChannelMask::setChannel(Zigbee::ZigbeeChannel channel)
|
||||||
|
{
|
||||||
|
// Set channel bit
|
||||||
|
m_channelMask |= 1 << channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeChannelMask::unsetChannel(Zigbee::ZigbeeChannel channel)
|
||||||
|
{
|
||||||
|
// Clear channel bit
|
||||||
|
m_channelMask &= ~(1 << channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZigbeeChannelMask &ZigbeeChannelMask::operator=(const ZigbeeChannelMask &other)
|
||||||
|
{
|
||||||
|
m_channelMask = other.toUInt32();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigbeeChannelMask::operator==(const ZigbeeChannelMask &other) const
|
||||||
|
{
|
||||||
|
return m_channelMask == other.toUInt32();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZigbeeChannelMask::operator!=(const ZigbeeChannelMask &other) const
|
||||||
|
{
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeChannelMask &channelMaks)
|
||||||
|
{
|
||||||
|
debug.nospace() << "ChannelMask(" << ZigbeeUtils::convertUint32ToHexString(channelMaks.toUInt32());
|
||||||
|
debug.nospace() << ", [";
|
||||||
|
for (int i = 11; i <= 25; i++) {
|
||||||
|
if (channelMaks.isSet(static_cast<Zigbee::ZigbeeChannel>(i))) {
|
||||||
|
if (i < 25) {
|
||||||
|
debug.nospace() << i << ", ";
|
||||||
|
} else {
|
||||||
|
debug.nospace() << i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.nospace() << "])";
|
||||||
|
return debug.space();
|
||||||
|
}
|
||||||
71
libnymea-zigbee/zigbeechannelmask.h
Normal file
71
libnymea-zigbee/zigbeechannelmask.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea-zigbee.
|
||||||
|
* This project including source code and documentation is protected by copyright law, and
|
||||||
|
* remains the property of nymea GmbH. All rights, including reproduction, publication,
|
||||||
|
* editing and translation, are reserved. The use of this project is subject to the terms of a
|
||||||
|
* license agreement to be concluded with nymea GmbH in accordance with the terms
|
||||||
|
* of use of nymea GmbH, available under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU Lesser General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the terms of the GNU
|
||||||
|
* Lesser General Public License as published by the Free Software Foundation; version 3.
|
||||||
|
* this project is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with this project.
|
||||||
|
* If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under contact@nymea.io
|
||||||
|
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef ZIGBEECHANNELMASK_H
|
||||||
|
#define ZIGBEECHANNELMASK_H
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "zigbee.h"
|
||||||
|
|
||||||
|
class ZigbeeChannelMask
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ChannelConfiguration {
|
||||||
|
ChannelConfigurationNoChannel = 0x00000000,
|
||||||
|
ChannelConfigurationPrimaryLightLink = 0x02108800,
|
||||||
|
ChannelConfigurationAllChannels = 0x07fff800
|
||||||
|
};
|
||||||
|
Q_ENUM(ChannelConfiguration)
|
||||||
|
|
||||||
|
ZigbeeChannelMask();
|
||||||
|
ZigbeeChannelMask(quint32 channelMask);
|
||||||
|
ZigbeeChannelMask(Zigbee::ZigbeeChannels channels);
|
||||||
|
|
||||||
|
quint32 toUInt32() const;
|
||||||
|
|
||||||
|
Zigbee::ZigbeeChannels channels() const;
|
||||||
|
|
||||||
|
bool isSet(Zigbee::ZigbeeChannel channel) const;
|
||||||
|
void setChannel(Zigbee::ZigbeeChannel channel);
|
||||||
|
void unsetChannel(Zigbee::ZigbeeChannel channel);
|
||||||
|
|
||||||
|
ZigbeeChannelMask &operator=(const ZigbeeChannelMask &other);
|
||||||
|
bool operator==(const ZigbeeChannelMask &other) const;
|
||||||
|
bool operator!=(const ZigbeeChannelMask &other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint32 m_channelMask = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug debug, const ZigbeeChannelMask &channelMaks);
|
||||||
|
|
||||||
|
#endif // ZIGBEECHANNELMASK_H
|
||||||
@ -115,6 +115,20 @@ void ZigbeeNetwork::setChannel(quint32 channel)
|
|||||||
emit channelChanged(m_channel);
|
emit channelChanged(m_channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZigbeeChannelMask ZigbeeNetwork::channelMask() const
|
||||||
|
{
|
||||||
|
return m_channelMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZigbeeNetwork::setChannelMask(const ZigbeeChannelMask &channelMask)
|
||||||
|
{
|
||||||
|
if (m_channelMask == channelMask)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_channelMask = channelMask;
|
||||||
|
emit channelMaskChanged(m_channelMask);
|
||||||
|
}
|
||||||
|
|
||||||
ZigbeeSecurityConfiguration ZigbeeNetwork::securityConfiguration() const
|
ZigbeeSecurityConfiguration ZigbeeNetwork::securityConfiguration() const
|
||||||
{
|
{
|
||||||
return m_securityConfiguration;
|
return m_securityConfiguration;
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
#include "zigbeenode.h"
|
#include "zigbeenode.h"
|
||||||
|
#include "zigbeechannelmask.h"
|
||||||
#include "zigbeebridgecontroller.h"
|
#include "zigbeebridgecontroller.h"
|
||||||
#include "zigbeesecurityconfiguration.h"
|
#include "zigbeesecurityconfiguration.h"
|
||||||
|
|
||||||
@ -81,6 +82,9 @@ public:
|
|||||||
quint32 channel() const;
|
quint32 channel() const;
|
||||||
void setChannel(quint32 channel);
|
void setChannel(quint32 channel);
|
||||||
|
|
||||||
|
ZigbeeChannelMask channelMask() const;
|
||||||
|
void setChannelMask(const ZigbeeChannelMask &channelMask);
|
||||||
|
|
||||||
ZigbeeSecurityConfiguration securityConfiguration() const;
|
ZigbeeSecurityConfiguration securityConfiguration() const;
|
||||||
void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration);
|
void setSecurityConfiguration(const ZigbeeSecurityConfiguration &securityConfiguration);
|
||||||
|
|
||||||
@ -107,6 +111,7 @@ private:
|
|||||||
// Network configurations
|
// Network configurations
|
||||||
quint64 m_extendedPanId = 0;
|
quint64 m_extendedPanId = 0;
|
||||||
quint32 m_channel = 0;
|
quint32 m_channel = 0;
|
||||||
|
ZigbeeChannelMask m_channelMask = ZigbeeChannelMask(ZigbeeChannelMask::ChannelConfigurationAllChannels);
|
||||||
ZigbeeNode::NodeType m_nodeType = ZigbeeNode::NodeTypeCoordinator;
|
ZigbeeNode::NodeType m_nodeType = ZigbeeNode::NodeTypeCoordinator;
|
||||||
|
|
||||||
QString m_settingsFileName = "/etc/nymea/nymea-zigbee.conf";
|
QString m_settingsFileName = "/etc/nymea/nymea-zigbee.conf";
|
||||||
@ -148,6 +153,7 @@ signals:
|
|||||||
|
|
||||||
void extendedPanIdChanged(quint64 extendedPanId);
|
void extendedPanIdChanged(quint64 extendedPanId);
|
||||||
void channelChanged(uint channel);
|
void channelChanged(uint channel);
|
||||||
|
void channelMaskChanged(const ZigbeeChannelMask &channelMask);
|
||||||
void securityConfigurationChanged(const ZigbeeSecurityConfiguration &securityConfiguration);
|
void securityConfigurationChanged(const ZigbeeSecurityConfiguration &securityConfiguration);
|
||||||
|
|
||||||
void nodeAdded(ZigbeeNode *node);
|
void nodeAdded(ZigbeeNode *node);
|
||||||
|
|||||||
@ -505,7 +505,6 @@ void ZigbeeNode::onClusterAttributeChanged(const ZigbeeClusterAttribute &attribu
|
|||||||
// qCDebug(dcZigbeeNode()) << " Data:" << data;
|
// qCDebug(dcZigbeeNode()) << " Data:" << data;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, ZigbeeNode *node)
|
QDebug operator<<(QDebug debug, ZigbeeNode *node)
|
||||||
{
|
{
|
||||||
debug.nospace().noquote() << "ZigbeeNode(" << ZigbeeUtils::convertUint16ToHexString(node->shortAddress());
|
debug.nospace().noquote() << "ZigbeeNode(" << ZigbeeUtils::convertUint16ToHexString(node->shortAddress());
|
||||||
|
|||||||
Reference in New Issue
Block a user