First version of deconz network start procedure and factory reset
This commit is contained in:
parent
c9cdbb4413
commit
4472700160
@ -714,11 +714,7 @@ DeconzDeviceState ZigbeeBridgeControllerDeconz::parseDeviceStateFlag(quint8 devi
|
||||
|
||||
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;
|
||||
qCDebug(dcZigbeeController()) << deviceState;
|
||||
|
||||
if (m_networkState != deviceState.networkState) {
|
||||
qCDebug(dcZigbeeController()) << "Network state changed" << deviceState.networkState;
|
||||
@ -729,13 +725,15 @@ void ZigbeeBridgeControllerDeconz::processDeviceState(DeconzDeviceState deviceSt
|
||||
if (m_aspFreeSlotsAvailable != deviceState.aspDataRequestFreeSlots) {
|
||||
m_aspFreeSlotsAvailable = deviceState.aspDataRequestFreeSlots;
|
||||
|
||||
// FIXME: if true, send next asp request
|
||||
// FIXME: if changed to true, send next asp data request
|
||||
|
||||
}
|
||||
|
||||
if (m_networkState != Deconz::NetworkStateConnected)
|
||||
return;
|
||||
|
||||
// Check if we have to fech new data
|
||||
if (deviceState.aspDataConfirm) {
|
||||
// Check if we have to read a data indication message
|
||||
if (deviceState.aspDataIndication) {
|
||||
ZigbeeInterfaceDeconzReply *reply = requestReadReceivedDataIndication();
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
@ -744,77 +742,133 @@ void ZigbeeBridgeControllerDeconz::processDeviceState(DeconzDeviceState deviceSt
|
||||
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::DestinationAddressModeIeeeAddress)
|
||||
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::DestinationAddressModeIeeeAddress)
|
||||
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));
|
||||
// ASP data indication received, process the content
|
||||
qCDebug(dcZigbeeController()) << "Reading data indication finished successfully";
|
||||
processDataIndication(reply->responseData());
|
||||
});
|
||||
}
|
||||
|
||||
// Check if we have a response to read for a request
|
||||
if (deviceState.aspDataConfirm) {
|
||||
ZigbeeInterfaceDeconzReply *reply = requestQuerySendDataConfirm();
|
||||
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, process the content
|
||||
qCDebug(dcZigbeeController()) << "Reading data confirm finished successfully";
|
||||
processDataConfirm(reply->responseData());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ZigbeeBridgeControllerDeconz::processDataIndication(const QByteArray &data)
|
||||
{
|
||||
// ASP data indication
|
||||
QDataStream stream(data);
|
||||
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::DestinationAddressModeIeeeAddress)
|
||||
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;
|
||||
|
||||
// Print the information for debugging
|
||||
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::DestinationAddressModeIeeeAddress)
|
||||
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::processDataConfirm(const QByteArray &data)
|
||||
{
|
||||
QDataStream stream(data);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
quint16 payloadLenght = 0; quint8 deviceStateFlag = 0; quint8 requestId = 0; quint8 destinationAddressMode = 0;
|
||||
quint16 destinationShortAddress = 0; quint64 destinationIeeeAddress = 0; quint8 destinationEndpoint = 0;
|
||||
quint8 sourceEndpoint = 0; quint8 zigbeeConfirmStatus = 0;
|
||||
|
||||
stream >> payloadLenght >> deviceStateFlag >> requestId >> destinationAddressMode;
|
||||
if (destinationAddressMode == Zigbee::DestinationAddressModeGroup || destinationAddressMode == Zigbee::DestinationAddressModeShortAddress)
|
||||
stream >> destinationShortAddress;
|
||||
|
||||
if (destinationAddressMode == Zigbee::DestinationAddressModeIeeeAddress)
|
||||
stream >> destinationIeeeAddress;
|
||||
|
||||
stream >> destinationEndpoint >> sourceEndpoint >> zigbeeConfirmStatus;
|
||||
|
||||
// Print the information for debugging
|
||||
qCDebug(dcZigbeeController()) << "Data confirm received: Request" << requestId;
|
||||
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::DestinationAddressModeIeeeAddress)
|
||||
qCDebug(dcZigbeeController()) << " Destination IEEE address:" << ZigbeeAddress(destinationIeeeAddress).toString();
|
||||
|
||||
qCDebug(dcZigbeeController()) << " Destination endpoint" << ZigbeeUtils::convertByteToHexString(destinationEndpoint);
|
||||
qCDebug(dcZigbeeController()) << " Source endpoint" << ZigbeeUtils::convertByteToHexString(sourceEndpoint);
|
||||
qCDebug(dcZigbeeController()) << " Confirm status" << static_cast<Zigbee::ZigbeeStatus>(zigbeeConfirmStatus);
|
||||
}
|
||||
|
||||
void ZigbeeBridgeControllerDeconz::onInterfaceAvailableChanged(bool available)
|
||||
@ -903,3 +957,28 @@ void ZigbeeBridgeControllerDeconz::disable()
|
||||
{
|
||||
m_interface->disable();
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const DeconzDeviceState &deviceState)
|
||||
{
|
||||
debug.nospace() << "DeviceState(";
|
||||
switch (deviceState.networkState) {
|
||||
case Deconz::NetworkStateJoining:
|
||||
debug.nospace() << "Joining, ";
|
||||
break;
|
||||
case Deconz::NetworkStateLeaving:
|
||||
debug.nospace() << "Leaving, ";
|
||||
break;
|
||||
case Deconz::NetworkStateOffline:
|
||||
debug.nospace() << "Offline, ";
|
||||
break;
|
||||
case Deconz::NetworkStateConnected:
|
||||
debug.nospace() << "Connected, ";
|
||||
break;
|
||||
}
|
||||
|
||||
debug.nospace() << "Confirm=" << static_cast<int>(deviceState.aspDataConfirm) << ", ";
|
||||
debug.nospace() << "Indication=" << static_cast<int>(deviceState.aspDataIndication) << ", ";
|
||||
debug.nospace() << "ConfigChanged=" << static_cast<int>(deviceState.configurationChanged) << ", ";
|
||||
debug.nospace() << "CanSend=" << deviceState.aspDataRequestFreeSlots << ")";
|
||||
return debug.space();
|
||||
}
|
||||
|
||||
@ -70,8 +70,6 @@ typedef struct DeconzDeviceState {
|
||||
bool aspDataRequestFreeSlots = false;
|
||||
} DeconzDeviceState;
|
||||
|
||||
|
||||
|
||||
class ZigbeeBridgeControllerDeconz : public ZigbeeBridgeController
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -93,6 +91,7 @@ public:
|
||||
ZigbeeInterfaceDeconzReply *requestWriteParameter(Deconz::Parameter parameter, const QByteArray &data);
|
||||
ZigbeeInterfaceDeconzReply *requestChangeNetworkState(Deconz::NetworkState networkState);
|
||||
|
||||
// Receive data
|
||||
ZigbeeInterfaceDeconzReply *requestReadReceivedDataIndication(Deconz::SourceAddressMode sourceAddressMode = Deconz::SourceAddressModeShortSourceAddress);
|
||||
ZigbeeInterfaceDeconzReply *requestQuerySendDataConfirm();
|
||||
|
||||
@ -101,7 +100,6 @@ public:
|
||||
ZigbeeInterfaceDeconzReply *requestEnqueueSendDataShortAddress(quint8 requestId, quint16 shortAddress, quint8 destinationEndpoint, Zigbee::ZigbeeProfile profileId, Zigbee::ClusterId clusterId, quint8 sourceEndpoint, const QByteArray &asdu, quint8 radius = 0);
|
||||
ZigbeeInterfaceDeconzReply *requestEnqueueSendDataIeeeAddress(quint8 requestId, ZigbeeAddress ieeeAddress, quint8 destinationEndpoint, Zigbee::ZigbeeProfile profileId, Zigbee::ClusterId clusterId, quint8 sourceEndpoint, const QByteArray &asdu, quint8 radius = 0);
|
||||
|
||||
|
||||
private:
|
||||
ZigbeeInterfaceDeconz *m_interface = nullptr;
|
||||
quint8 m_sequenceNumber = 0;
|
||||
@ -126,6 +124,9 @@ private:
|
||||
DeconzDeviceState parseDeviceStateFlag(quint8 deviceStateFlag);
|
||||
void processDeviceState(DeconzDeviceState deviceState);
|
||||
|
||||
void processDataIndication(const QByteArray &data);
|
||||
void processDataConfirm(const QByteArray &data);
|
||||
|
||||
signals:
|
||||
void networkStateChanged(Deconz::NetworkState networkState);
|
||||
void networkConfigurationParameterChanged(const DeconzNetworkConfiguration &networkConfiguration);
|
||||
@ -141,4 +142,7 @@ public slots:
|
||||
void disable();
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, const DeconzDeviceState &deviceState);
|
||||
|
||||
|
||||
#endif // ZIGBEEBRIDGECONTROLLERDECONZ_H
|
||||
|
||||
@ -37,6 +37,11 @@ ZigbeeNetworkDeconz::ZigbeeNetworkDeconz(QObject *parent) :
|
||||
m_controller = new ZigbeeBridgeControllerDeconz(this);
|
||||
//connect(m_controller, &ZigbeeBridgeControllerDeconz::messageReceived, this, &ZigbeeNetworkDeconz::onMessageReceived);
|
||||
connect(m_controller, &ZigbeeBridgeControllerDeconz::availableChanged, this, &ZigbeeNetworkDeconz::onControllerAvailableChanged);
|
||||
|
||||
m_pollNetworkStateTimer = new QTimer(this);
|
||||
m_pollNetworkStateTimer->setInterval(1000);
|
||||
m_pollNetworkStateTimer->setSingleShot(false);
|
||||
connect(m_pollNetworkStateTimer, &QTimer::timeout, this, &ZigbeeNetworkDeconz::onPollNetworkStateTimeout);
|
||||
}
|
||||
|
||||
ZigbeeBridgeController *ZigbeeNetworkDeconz::bridgeController() const
|
||||
@ -47,11 +52,194 @@ ZigbeeBridgeController *ZigbeeNetworkDeconz::bridgeController() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkDeconz::setCreateNetworkState(ZigbeeNetworkDeconz::CreateNetworkState state)
|
||||
{
|
||||
if (m_createState == state)
|
||||
return;
|
||||
|
||||
m_createState = state;
|
||||
qCDebug(dcZigbeeNetwork()) << "Create network state changed" << m_createState;
|
||||
|
||||
switch (m_createState) {
|
||||
case CreateNetworkStateIdle:
|
||||
|
||||
break;
|
||||
case CreateNetworkStateStopNetwork: {
|
||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestChangeNetworkState(Deconz::NetworkStateOffline);
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
qCWarning(dcZigbeeController()) << "Could not stop network for creating a new one." << reply->statusCode();
|
||||
// FIXME: set an appropriate error
|
||||
return;
|
||||
}
|
||||
|
||||
// Start polling the device state, should be Online -> Leaving -> Offline
|
||||
m_pollNetworkStateTimer->start();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case CreateNetworkStateWriteConfiguration: {
|
||||
// - Set coordinator
|
||||
// - Set channel mask
|
||||
// - Set APS extended PANID (zero to reset)
|
||||
// - Set trust center address (coordinator address)
|
||||
// - Set security mode
|
||||
// - Set network key
|
||||
|
||||
QByteArray paramData;
|
||||
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream << static_cast<quint8>(Deconz::NodeTypeCoordinator);
|
||||
qCDebug(dcZigbeeNetwork()) << "Configure bridge to" << Deconz::NodeTypeCoordinator;
|
||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterNodeType, paramData);
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
qCWarning(dcZigbeeController()) << "Could not write parameter" << Deconz::ParameterNodeType << Deconz::NodeTypeCoordinator << reply->statusCode();
|
||||
// FIXME: set an appropriate error
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Configured successfully bridge to" << Deconz::NodeTypeCoordinator;
|
||||
|
||||
QByteArray paramData;
|
||||
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream << static_cast<quint32>(channelMask().toUInt32());
|
||||
qCDebug(dcZigbeeNetwork()) << "Configure channel mask" << channelMask();
|
||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterChannelMask, paramData);
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
qCWarning(dcZigbeeController()) << "Could not write parameter" << Deconz::ParameterChannelMask << reply->statusCode();
|
||||
// FIXME: set an appropriate error
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Configured channel mask successfully";
|
||||
|
||||
QByteArray paramData;
|
||||
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||
stream << static_cast<quint64>(0);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
qCDebug(dcZigbeeNetwork()) << "Configure APS extended PANID" << 0;
|
||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterApsExtendedPanId, paramData);
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
qCWarning(dcZigbeeController()) << "Could not write parameter" << Deconz::ParameterApsExtendedPanId << reply->statusCode();
|
||||
// FIXME: set an appropriate error
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Configured APS extended PANID successfully";
|
||||
|
||||
QByteArray paramData;
|
||||
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream << m_controller->networkConfiguration().ieeeAddress.toUInt64();
|
||||
qCDebug(dcZigbeeNetwork()) << "Configure trust center address" << m_controller->networkConfiguration().ieeeAddress.toString();
|
||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterTrustCenterAddress, paramData);
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
qCWarning(dcZigbeeController()) << "Could not write parameter" << Deconz::ParameterTrustCenterAddress << reply->statusCode();
|
||||
// FIXME: set an appropriate error
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Configured trust center address successfully";
|
||||
|
||||
QByteArray paramData;
|
||||
QDataStream stream(¶mData, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
stream << static_cast<quint8>(Deconz::SecurityModeNoMasterButTrustCenterKey);
|
||||
qCDebug(dcZigbeeNetwork()) << "Configure security mode" << Deconz::SecurityModeNoMasterButTrustCenterKey;
|
||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterSecurityMode, paramData);
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
qCWarning(dcZigbeeController()) << "Could not write parameter" << Deconz::ParameterSecurityMode << reply->statusCode();
|
||||
// FIXME: set an appropriate error
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Configured security mode successfully";
|
||||
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Configure network key" << securityConfiguration().networkKey().toString();
|
||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestWriteParameter(Deconz::ParameterNetworkKey, securityConfiguration().networkKey().toByteArray());
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
qCWarning(dcZigbeeController()) << "Could not write parameter" << Deconz::ParameterNetworkKey << reply->statusCode();
|
||||
// FIXME: set an appropriate error
|
||||
// Note: writing the network key fails all the time...
|
||||
//return;
|
||||
} else {
|
||||
qCDebug(dcZigbeeNetwork()) << "Configured network key successfully";
|
||||
}
|
||||
|
||||
// Configuration finished, lets start the network
|
||||
setCreateNetworkState(CreateNetworkStateStartNetwork);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
case CreateNetworkStateStartNetwork: {
|
||||
ZigbeeInterfaceDeconzReply *reply = m_controller->requestChangeNetworkState(Deconz::NetworkStateConnected);
|
||||
connect(reply, &ZigbeeInterfaceDeconzReply::finished, this, [this, reply](){
|
||||
if (reply->statusCode() != Deconz::StatusCodeSuccess) {
|
||||
qCWarning(dcZigbeeController()) << "Could not start network for creating a new one." << reply->statusCode();
|
||||
// FIXME: set an appropriate error
|
||||
return;
|
||||
}
|
||||
|
||||
// Start polling the device state, should be Online -> Leaving -> Offline
|
||||
m_pollNetworkStateTimer->start();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case CreateNetworkStateReadConfiguration: {
|
||||
// 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.";
|
||||
|
||||
setPanId(m_controller->networkConfiguration().panId);
|
||||
setExtendedPanId(m_controller->networkConfiguration().extendedPanId);
|
||||
setChannel(m_controller->networkConfiguration().currentChannel);
|
||||
|
||||
setCreateNetworkState(CreateNetworkStateInitializeCoordinatorNode);
|
||||
|
||||
});
|
||||
break;
|
||||
}
|
||||
case CreateNetworkStateInitializeCoordinatorNode: {
|
||||
ZigbeeNodeDeconz *coordinatorNode = qobject_cast<ZigbeeNodeDeconz *>(createNode(this));
|
||||
coordinatorNode->setShortAddress(m_controller->networkConfiguration().shortAddress);
|
||||
coordinatorNode->setExtendedAddress(m_controller->networkConfiguration().ieeeAddress);
|
||||
|
||||
// TODO: done when when node initialized
|
||||
m_coordinatorNode = coordinatorNode;
|
||||
addNode(coordinatorNode);
|
||||
|
||||
setCreateNetworkState(CreateNetworkStateIdle);
|
||||
setState(StateRunning);
|
||||
|
||||
//addUnitializedNode(coordinatorNode);
|
||||
//coordinatorNode->startInitialization();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ZigbeeNode *ZigbeeNetworkDeconz::createNode(QObject *parent)
|
||||
{
|
||||
//FIXME
|
||||
Q_UNUSED(parent)
|
||||
return nullptr;
|
||||
return new ZigbeeNodeDeconz(m_controller, parent);
|
||||
}
|
||||
|
||||
void ZigbeeNetworkDeconz::setPermitJoiningInternal(bool permitJoining)
|
||||
@ -64,11 +252,13 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
||||
{
|
||||
qCDebug(dcZigbeeNetwork()) << "Start network internally";
|
||||
|
||||
m_createNewNetwork = false;
|
||||
|
||||
// Check if we have to create a pan ID and select the channel
|
||||
if (extendedPanId() == 0) {
|
||||
if (panId() == 0) {
|
||||
m_createNewNetwork = true;
|
||||
setExtendedPanId(ZigbeeUtils::generateRandomPanId());
|
||||
qCDebug(dcZigbeeNetwork()) << "Created new PAN ID:" << extendedPanId();
|
||||
//setExtendedPanId(ZigbeeUtils::generateRandomPanId());
|
||||
//qCDebug(dcZigbeeNetwork()) << "Created new PAN ID:" << extendedPanId();
|
||||
}
|
||||
|
||||
if (securityConfiguration().networkKey().isNull()) {
|
||||
@ -79,7 +269,7 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Using" << securityConfiguration().networkKey() << "network link key";
|
||||
qCDebug(dcZigbeeNetwork()) << "Using" << securityConfiguration().globalTrustCenterLinkKey() << "global trust center link key";
|
||||
qCDebug(dcZigbeeNetwork()) << "Using" << securityConfiguration().globalTrustCenterLinkKey() << "global trust center link key";
|
||||
|
||||
|
||||
// - Read the firmware version
|
||||
@ -115,8 +305,8 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
||||
}
|
||||
|
||||
qCDebug(dcZigbeeNetwork()) << "Reading network parameters finished successfully.";
|
||||
QString protocolVersion = QString("%1.%2").arg(m_controller->networkConfiguration().protocolVersion & 0xFF00)
|
||||
.arg(m_controller->networkConfiguration().protocolVersion & 0x00FF);
|
||||
QString protocolVersion = QString("%1.%2").arg(m_controller->networkConfiguration().protocolVersion >> 8 & 0xFF)
|
||||
.arg(m_controller->networkConfiguration().protocolVersion & 0xFF);
|
||||
|
||||
m_controller->setFirmwareVersionString(QString("%1 - %2").arg(firmwareVersion).arg(protocolVersion));
|
||||
|
||||
@ -137,39 +327,31 @@ void ZigbeeNetworkDeconz::startNetworkInternally()
|
||||
m_controller->processDeviceState(m_controller->parseDeviceStateFlag(deviceStateFlag));
|
||||
|
||||
if (m_createNewNetwork) {
|
||||
// Write the configurations which need to be changed
|
||||
createNetwork();
|
||||
|
||||
// Initialize coordinator node
|
||||
|
||||
|
||||
setCreateNetworkState(CreateNetworkStateStopNetwork);
|
||||
} else {
|
||||
// Get the network state and start the network if required
|
||||
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
|
||||
qCDebug(dcZigbeeNetwork()) << "The network is already running.";
|
||||
setState(StateRunning);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ZigbeeNetworkDeconz::createNetwork()
|
||||
{
|
||||
// Set offline
|
||||
setCreateNetworkState(CreateNetworkStateStopNetwork);
|
||||
|
||||
// Write configurations
|
||||
|
||||
// Set online
|
||||
|
||||
// Read configurations
|
||||
|
||||
// Create and initialize coordinator node
|
||||
}
|
||||
|
||||
void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
|
||||
@ -190,6 +372,76 @@ void ZigbeeNetworkDeconz::onControllerAvailableChanged(bool available)
|
||||
}
|
||||
}
|
||||
|
||||
void ZigbeeNetworkDeconz::onPollNetworkStateTimeout()
|
||||
{
|
||||
// Stop the timer and make the request
|
||||
m_pollNetworkStateTimer->stop();
|
||||
|
||||
switch (m_createState) {
|
||||
case CreateNetworkStateStopNetwork: {
|
||||
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());
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
quint8 deviceStateFlag = 0;
|
||||
stream >> deviceStateFlag;
|
||||
// Update the device state in the controller
|
||||
m_controller->processDeviceState(m_controller->parseDeviceStateFlag(deviceStateFlag));
|
||||
if (m_controller->networkState() == Deconz::NetworkStateOffline) {
|
||||
qCDebug(dcZigbeeNetwork()) << "Network stopped successfully for creation";
|
||||
// The network is now offline, continue with the state machine
|
||||
setCreateNetworkState(CreateNetworkStateWriteConfiguration);
|
||||
} else {
|
||||
// Not offline yet, continue poll
|
||||
m_pollNetworkStateTimer->start();
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case CreateNetworkStateStartNetwork: {
|
||||
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());
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
quint8 deviceStateFlag = 0;
|
||||
stream >> deviceStateFlag;
|
||||
// Update the device state in the controller
|
||||
m_controller->processDeviceState(m_controller->parseDeviceStateFlag(deviceStateFlag));
|
||||
if (m_controller->networkState() == Deconz::NetworkStateConnected) {
|
||||
// The network is now online, continue with the state machine
|
||||
setCreateNetworkState(CreateNetworkStateReadConfiguration);
|
||||
} else if (m_controller->networkState() == Deconz::NetworkStateOffline) {
|
||||
qCWarning(dcZigbeeNetwork()) << "Failed to start the network.";
|
||||
setCreateNetworkState(CreateNetworkStateIdle);
|
||||
setState(StateOffline);
|
||||
setError(ErrorZigbeeError);
|
||||
return;
|
||||
} else {
|
||||
// Not offline yet, continue poll
|
||||
m_pollNetworkStateTimer->start();
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ZigbeeNetworkDeconz::startNetwork()
|
||||
{
|
||||
loadNetwork();
|
||||
@ -231,5 +483,9 @@ void ZigbeeNetworkDeconz::reset()
|
||||
|
||||
void ZigbeeNetworkDeconz::factoryResetNetwork()
|
||||
{
|
||||
// Wipe settings, and reconfigure network
|
||||
qCDebug(dcZigbeeNetwork()) << "Factory reset network and forget all information. This cannot be undone.";
|
||||
clearSettings();
|
||||
setState(StateUninitialized);
|
||||
qCDebug(dcZigbeeNetwork()) << "The factory reset is finished. Start restart with a fresh network.";
|
||||
startNetwork();
|
||||
}
|
||||
|
||||
@ -29,7 +29,9 @@
|
||||
#define ZIGBEENETWORKDECONZ_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "zigbeenetwork.h"
|
||||
#include "zigbeenodedeconz.h"
|
||||
#include "zigbeechannelmask.h"
|
||||
#include "zigbeebridgecontrollerdeconz.h"
|
||||
|
||||
@ -37,17 +39,34 @@ class ZigbeeNetworkDeconz : public ZigbeeNetwork
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum CreateNetworkState {
|
||||
CreateNetworkStateIdle,
|
||||
CreateNetworkStateStopNetwork,
|
||||
CreateNetworkStateWriteConfiguration,
|
||||
CreateNetworkStateStartNetwork,
|
||||
CreateNetworkStateReadConfiguration,
|
||||
CreateNetworkStateInitializeCoordinatorNode
|
||||
};
|
||||
Q_ENUM(CreateNetworkState)
|
||||
|
||||
explicit ZigbeeNetworkDeconz(QObject *parent = nullptr);
|
||||
|
||||
ZigbeeBridgeController *bridgeController() const override;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
ZigbeeBridgeControllerDeconz *m_controller = nullptr;
|
||||
bool m_networkRunning = false;
|
||||
CreateNetworkState m_createState = CreateNetworkStateIdle;
|
||||
bool m_createNewNetwork = false;
|
||||
|
||||
QTimer *m_pollNetworkStateTimer = nullptr;
|
||||
void setCreateNetworkState(CreateNetworkState state);
|
||||
|
||||
protected:
|
||||
ZigbeeNode *createNode(QObject *parent) override;
|
||||
|
||||
void setPermitJoiningInternal(bool permitJoining) override;
|
||||
|
||||
void startNetworkInternally();
|
||||
@ -56,6 +75,7 @@ protected:
|
||||
|
||||
private slots:
|
||||
void onControllerAvailableChanged(bool available);
|
||||
void onPollNetworkStateTimeout();
|
||||
|
||||
public slots:
|
||||
void startNetwork() override;
|
||||
|
||||
@ -27,8 +27,42 @@
|
||||
|
||||
#include "zigbeenodedeconz.h"
|
||||
|
||||
ZigbeeNodeDeconz::ZigbeeNodeDeconz(QObject *parent) :
|
||||
ZigbeeNode(parent)
|
||||
ZigbeeNodeDeconz::ZigbeeNodeDeconz(ZigbeeBridgeControllerDeconz *controller, QObject *parent) :
|
||||
ZigbeeNode(parent),
|
||||
m_controller(controller)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ZigbeeNodeDeconz::leaveNetworkRequest(bool rejoin, bool removeChildren)
|
||||
{
|
||||
Q_UNUSED(rejoin)
|
||||
Q_UNUSED(removeChildren)
|
||||
}
|
||||
|
||||
void ZigbeeNodeDeconz::setClusterAttributeReport(const ZigbeeClusterAttributeReport &report)
|
||||
{
|
||||
Q_UNUSED(report)
|
||||
}
|
||||
|
||||
void ZigbeeNodeDeconz::startInitialization()
|
||||
{
|
||||
/* Node initialisation steps (sequentially)
|
||||
* - Node descriptor
|
||||
* - Power descriptor
|
||||
* - Active endpoints
|
||||
* - for each endpoint do:
|
||||
* - Simple descriptor request
|
||||
* - for each endpoint
|
||||
* - read basic cluster
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
ZigbeeNodeEndpoint *ZigbeeNodeDeconz::createNodeEndpoint(quint8 endpointId, QObject *parent)
|
||||
{
|
||||
Q_UNUSED(endpointId)
|
||||
Q_UNUSED(parent)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
|
||||
#include "zigbee.h"
|
||||
#include "zigbeenode.h"
|
||||
#include "zigbeebridgecontrollerdeconz.h"
|
||||
|
||||
class ZigbeeNodeDeconz : public ZigbeeNode
|
||||
{
|
||||
@ -40,9 +41,21 @@ class ZigbeeNodeDeconz : public ZigbeeNode
|
||||
friend class ZigbeeNetworkDeconz;
|
||||
|
||||
public:
|
||||
explicit ZigbeeNodeDeconz(QObject *parent = nullptr);
|
||||
explicit ZigbeeNodeDeconz(ZigbeeBridgeControllerDeconz *controller, QObject *parent = nullptr);
|
||||
|
||||
void leaveNetworkRequest(bool rejoin = false, bool removeChildren = false) override;
|
||||
|
||||
private:
|
||||
ZigbeeBridgeControllerDeconz *m_controller = nullptr;
|
||||
|
||||
void setClusterAttributeReport(const ZigbeeClusterAttributeReport &report) override;
|
||||
|
||||
protected:
|
||||
void startInitialization() override;
|
||||
ZigbeeNodeEndpoint *createNodeEndpoint(quint8 endpointId, QObject *parent) override;
|
||||
|
||||
private slots:
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -23,6 +23,8 @@ SOURCES += \
|
||||
zigbeechannelmask.cpp \
|
||||
zigbeecluster.cpp \
|
||||
zigbeeclusterattribute.cpp \
|
||||
zigbeedeviceobject.cpp \
|
||||
zigbeedeviceprofile.cpp \
|
||||
zigbeemanufacturer.cpp \
|
||||
zigbeenetwork.cpp \
|
||||
zigbeenetworkkey.cpp \
|
||||
@ -30,6 +32,7 @@ SOURCES += \
|
||||
zigbee.cpp \
|
||||
loggingcategory.cpp \
|
||||
zigbeenetworkreply.cpp \
|
||||
zigbeenetworkrequest.cpp \
|
||||
zigbeenodeendpoint.cpp \
|
||||
zigbeesecurityconfiguration.cpp \
|
||||
zigbeeutils.cpp \
|
||||
@ -57,6 +60,8 @@ HEADERS += \
|
||||
zigbeechannelmask.h \
|
||||
zigbeecluster.h \
|
||||
zigbeeclusterattribute.h \
|
||||
zigbeedeviceobject.h \
|
||||
zigbeedeviceprofile.h \
|
||||
zigbeemanufacturer.h \
|
||||
zigbeenetwork.h \
|
||||
zigbeenetworkkey.h \
|
||||
@ -64,6 +69,7 @@ HEADERS += \
|
||||
zigbee.h \
|
||||
loggingcategory.h \
|
||||
zigbeenetworkreply.h \
|
||||
zigbeenetworkrequest.h \
|
||||
zigbeenodeendpoint.h \
|
||||
zigbeesecurityconfiguration.h \
|
||||
zigbeeutils.h \
|
||||
|
||||
@ -41,6 +41,7 @@ class Zigbee
|
||||
|
||||
public:
|
||||
enum ZigbeeProfile {
|
||||
ZigbeeProfileDevice = 0x0000,
|
||||
ZigbeeProfileIndustrialPlantMonitoring = 0x0101,
|
||||
ZigbeeProfileHomeAutomation = 0x0104,
|
||||
ZigbeeProfileCommercialBuildingAutomation = 0x0105,
|
||||
|
||||
@ -111,6 +111,6 @@ bool ZigbeeAddress::operator!=(const ZigbeeAddress &other) const
|
||||
|
||||
QDebug operator<<(QDebug debug, const ZigbeeAddress &address)
|
||||
{
|
||||
debug << address.toString();
|
||||
return debug;
|
||||
debug.nospace() << address.toString();
|
||||
return debug.space();
|
||||
}
|
||||
|
||||
@ -32,25 +32,44 @@ ZigbeeAdpu::ZigbeeAdpu(QObject *parent) : QObject(parent)
|
||||
|
||||
}
|
||||
|
||||
quint8 ZigbeeAdpu::buildFrameControl(ZigbeeAdpu::FrameType frameType, ZigbeeAdpu::DeliveryMode deliveryMode, bool apsAckFormat, bool securitySubField, bool acknowledgementRequest, bool extendedHeaderPresent)
|
||||
ZigbeeAdpu::FrameControl ZigbeeAdpu::frameControl() const
|
||||
{
|
||||
quint8 frameControl = 0;
|
||||
frameControl &= static_cast<quint8>(frameType); // Bit 0 - 1
|
||||
frameControl &= static_cast<quint8>(deliveryMode); // Bit 2 - 3
|
||||
if (apsAckFormat)
|
||||
frameControl &= static_cast<quint8>(0x08); // Bit 4
|
||||
return m_frameControl;
|
||||
}
|
||||
|
||||
if (securitySubField)
|
||||
frameControl &= static_cast<quint8>(0x04); // Bit 5
|
||||
void ZigbeeAdpu::setFrameControl(ZigbeeAdpu::FrameControl frameControl)
|
||||
{
|
||||
m_frameControl = frameControl;
|
||||
}
|
||||
|
||||
if (securitySubField)
|
||||
frameControl &= static_cast<quint8>(0x04); // Bit 6
|
||||
quint8 ZigbeeAdpu::buildFrameControlByte(FrameControl frameControl)
|
||||
{
|
||||
quint8 frameControlByte = 0;
|
||||
frameControlByte |= static_cast<quint8>(frameControl.frameType); // Bit 0 - 1
|
||||
frameControlByte |= static_cast<quint8>(frameControl.deliveryMode); // Bit 2 - 3
|
||||
if (frameControl.apsAckFormat)
|
||||
frameControlByte |= static_cast<quint8>(0x10); // Bit 4
|
||||
|
||||
if (acknowledgementRequest)
|
||||
frameControl &= static_cast<quint8>(0x02); // Bit 7
|
||||
if (frameControl.security)
|
||||
frameControlByte |= static_cast<quint8>(0x20); // Bit 5
|
||||
|
||||
if (extendedHeaderPresent)
|
||||
frameControl &= static_cast<quint8>(0x01); // Bit 8
|
||||
if (frameControl.acknowledgementRequest)
|
||||
frameControlByte |= static_cast<quint8>(0x40); // Bit 6
|
||||
|
||||
if (frameControl.extendedHeader)
|
||||
frameControlByte |= static_cast<quint8>(0x80); // Bit 7
|
||||
|
||||
return frameControlByte;
|
||||
}
|
||||
|
||||
ZigbeeAdpu::FrameControl ZigbeeAdpu::readFrameControlByte(quint8 frameControlByte)
|
||||
{
|
||||
FrameControl frameControl;
|
||||
frameControl.frameType = static_cast<FrameType>(frameControlByte | 0x03);
|
||||
frameControl.deliveryMode = static_cast<DeliveryMode>(frameControlByte | 0x0C);
|
||||
frameControl.apsAckFormat = frameControlByte | 0x10;
|
||||
frameControl.security = frameControlByte | 0x20;
|
||||
frameControl.acknowledgementRequest = frameControlByte | 0x40;
|
||||
frameControl.extendedHeader = frameControlByte | 0x80;
|
||||
return frameControl;
|
||||
}
|
||||
|
||||
@ -30,39 +30,60 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
typedef struct FrameControl {
|
||||
|
||||
} FrameControl;
|
||||
|
||||
class ZigbeeAdpu : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
// Note: zigbee Pro Specification 2.2.5.1 General APDU Frame Format
|
||||
|
||||
/* Frame control */
|
||||
enum FrameType {
|
||||
FrameTypeData = 0x00,
|
||||
FrameTypeCommand = 0x40,
|
||||
FrameTypeAck = 0x80,
|
||||
FrameTypeInterPanAps = 0xC0
|
||||
FrameTypeCommand = 0x01,
|
||||
FrameTypeAck = 0x02,
|
||||
FrameTypeInterPanAps = 0x03
|
||||
};
|
||||
Q_ENUM(FrameType)
|
||||
|
||||
enum DeliveryMode {
|
||||
DeliveryModeNormalUnicast = 0x00,
|
||||
DeliveryModeBroadcast = 0x20,
|
||||
DeliveryModeGroupAddressing = 0x30,
|
||||
DeliveryModeBroadcast = 0x08,
|
||||
DeliveryModeGroupAddressing = 0x0C,
|
||||
};
|
||||
Q_ENUM(DeliveryMode)
|
||||
|
||||
|
||||
typedef struct FrameControl {
|
||||
FrameType frameType = FrameTypeData;
|
||||
DeliveryMode deliveryMode = DeliveryModeNormalUnicast;
|
||||
bool security = false;
|
||||
bool apsAckFormat = false;
|
||||
bool acknowledgementRequest = true;
|
||||
bool extendedHeader = false;
|
||||
} FrameControl;
|
||||
|
||||
explicit ZigbeeAdpu(QObject *parent = nullptr);
|
||||
|
||||
quint8 buildFrameControl(FrameType frameType, DeliveryMode deliveryMode, bool apsAckFormat, bool securitySubField, bool acknowledgementRequest, bool extendedHeaderPresent);
|
||||
FrameControl frameControl() const;
|
||||
void setFrameControl(FrameControl frameControl);
|
||||
|
||||
quint8 destinationEndpoint() const;
|
||||
void setDestinationEndpoint(quint8 destinationEndpoint);
|
||||
|
||||
quint16 groupAddress() const;
|
||||
void setGroupAddress(quint16 groupAddress);
|
||||
|
||||
quint16 clusterId() const;
|
||||
void setClusterId(quint16 clusterId);
|
||||
|
||||
private:
|
||||
FrameControl m_frameControl;
|
||||
quint8 m_destinationEndpoint;
|
||||
|
||||
|
||||
quint8 buildFrameControlByte(FrameControl frameControl);
|
||||
FrameControl readFrameControlByte(quint8 frameControlByte);
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
@ -54,6 +54,60 @@ Zigbee::ZigbeeChannels ZigbeeChannelMask::channels() const
|
||||
return static_cast<Zigbee::ZigbeeChannels>(m_channelMask);
|
||||
}
|
||||
|
||||
QList<int> ZigbeeChannelMask::channelArray() const
|
||||
{
|
||||
QList<int> array;
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel11))
|
||||
array.append(11);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel12))
|
||||
array.append(12);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel13))
|
||||
array.append(13);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel14))
|
||||
array.append(14);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel15))
|
||||
array.append(15);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel16))
|
||||
array.append(16);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel17))
|
||||
array.append(17);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel18))
|
||||
array.append(18);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel19))
|
||||
array.append(19);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel20))
|
||||
array.append(20);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel21))
|
||||
array.append(21);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel22))
|
||||
array.append(22);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel23))
|
||||
array.append(23);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel24))
|
||||
array.append(24);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel25))
|
||||
array.append(25);
|
||||
|
||||
if (channels().testFlag(Zigbee::ZigbeeChannel26))
|
||||
array.append(26);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
bool ZigbeeChannelMask::isSet(Zigbee::ZigbeeChannel channel) const
|
||||
{
|
||||
return channels().testFlag(channel);
|
||||
@ -90,17 +144,7 @@ bool ZigbeeChannelMask::operator!=(const ZigbeeChannelMask &other) const
|
||||
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() << "])";
|
||||
debug.nospace() << ", " << channelMaks.channelArray();
|
||||
debug.nospace() << ")";
|
||||
return debug.space();
|
||||
}
|
||||
|
||||
@ -53,6 +53,8 @@ public:
|
||||
|
||||
Zigbee::ZigbeeChannels channels() const;
|
||||
|
||||
QList<int> channelArray() const;
|
||||
|
||||
bool isSet(Zigbee::ZigbeeChannel channel) const;
|
||||
void setChannel(Zigbee::ZigbeeChannel channel);
|
||||
void unsetChannel(Zigbee::ZigbeeChannel channel);
|
||||
|
||||
33
libnymea-zigbee/zigbeedeviceobject.cpp
Normal file
33
libnymea-zigbee/zigbeedeviceobject.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "zigbeedeviceobject.h"
|
||||
|
||||
ZigbeeDeviceObject::ZigbeeDeviceObject(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
43
libnymea-zigbee/zigbeedeviceobject.h
Normal file
43
libnymea-zigbee/zigbeedeviceobject.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 ZIGBEEDEVICEOBJECT_H
|
||||
#define ZIGBEEDEVICEOBJECT_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class ZigbeeDeviceObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ZigbeeDeviceObject(QObject *parent = nullptr);
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // ZIGBEEDEVICEOBJECT_H
|
||||
28
libnymea-zigbee/zigbeedeviceprofile.cpp
Normal file
28
libnymea-zigbee/zigbeedeviceprofile.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "zigbeedeviceprofile.h"
|
||||
144
libnymea-zigbee/zigbeedeviceprofile.h
Normal file
144
libnymea-zigbee/zigbeedeviceprofile.h
Normal file
@ -0,0 +1,144 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 ZIGBEEDEVICEPROFILE_H
|
||||
#define ZIGBEEDEVICEPROFILE_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class ZigbeeDeviceProfile
|
||||
{
|
||||
Q_GADGET
|
||||
|
||||
public:
|
||||
|
||||
enum ZdoCommand {
|
||||
/* Requests */
|
||||
/*Device and service discovery */
|
||||
NetworkAddressRequest = 0x0000,
|
||||
IeeeAddressRequest = 0x0001,
|
||||
NodeDescriptorRequest = 0x0002,
|
||||
PowerDescriptorRequest = 0x0003,
|
||||
SimpleDescriptorRequest = 0x0004,
|
||||
ActiveEndpointsRequest = 0x0005,
|
||||
MatchDescriptorsRequest = 0x0006,
|
||||
ComplexDescriptorRequest = 0x0010,
|
||||
UserDescriptorRequest = 0x0011,
|
||||
DiscoveryCacheRequest = 0x0012,
|
||||
DeviceAnnounce = 0x0013,
|
||||
UserDescriptorSet = 0x0014,
|
||||
SystemServerDiscoveryRequest = 0x0015,
|
||||
DiscoveryStoreRequest = 0x0016,
|
||||
NodeDescriptorStoreRequest = 0x0017,
|
||||
PowerDescriptorStoreRequest = 0x0018,
|
||||
ActiveEndpointStoreRequest = 0x0019,
|
||||
SimpleDescriptorStoreRequest = 0x001A,
|
||||
RemoveNodeCacheRequest = 0x001B,
|
||||
FindNodeCacheRequest = 0x001C,
|
||||
ExtendedSimpleDescriptorRequest = 0x001D,
|
||||
ExtendedActiveEndpointRequest = 0x001E,
|
||||
ParentAnnounceRequest = 0x001F,
|
||||
|
||||
/* Binding */
|
||||
EndDeviceBindRequest = 0x0020,
|
||||
BindRequest = 0x0021,
|
||||
UnbindRequest = 0x0022,
|
||||
BindRegisterRequest = 0x0023,
|
||||
ReplaceDeviceRequest = 0x0024,
|
||||
StoreBackupBindEntryRequest = 0x0025,
|
||||
RemoveBackupBindEntryRequest = 0x0026,
|
||||
BackupBindTableRequest = 0x0027,
|
||||
RecoverBindTableRequest = 0x0028,
|
||||
BackupSourceBindRequest = 0x0029,
|
||||
RecoverSourceBindRequest = 0x002A,
|
||||
|
||||
/* Network management */
|
||||
MgmtNetworkDiscoveryRequest = 0x0030,
|
||||
MgmtLqiRequest = 0x0031,
|
||||
MgmtRoutingTableRequest = 0x0032,
|
||||
MgmtBindRequest = 0x0033,
|
||||
MgmtLeaveRequest = 0x0034,
|
||||
MgmtDirectJoinRequest = 0x0035,
|
||||
MgmtPermitJoinRequest = 0x0036,
|
||||
MgmtCacheRequest = 0x0037,
|
||||
MgmtNetworkUpdateRequest = 0x0038,
|
||||
|
||||
/* Responses */
|
||||
/*Device and service discovery */
|
||||
NetworkAddressResponse = 0x8000,
|
||||
IeeeAddressResponse = 0x8001,
|
||||
NodeDescriptorResponse = 0x8002,
|
||||
PowerDescriptorResponse = 0x8003,
|
||||
SimpleDescriptorResponse = 0x8004,
|
||||
ActiveEndpointsResponse = 0x8005,
|
||||
MatchDescriptorsResponse = 0x8006,
|
||||
ComplexDescriptorResponse = 0x8010,
|
||||
UserDescriptorResponse = 0x8011,
|
||||
DiscoveryCacheResponse = 0x8012,
|
||||
UserDescriptorSetResponse = 0x8014,
|
||||
SystemServerDiscoveryResponse = 0x8015,
|
||||
DiscoveryStoreResponse = 0x8016,
|
||||
NodeDescriptorStoreResponse = 0x8017,
|
||||
PowerDescriptorStoreResponse = 0x8018,
|
||||
ActiveEndpointStoreResponse = 0x8019,
|
||||
SimpleDescriptorStoreResponse = 0x801A,
|
||||
RemoveNodeCacheResponse = 0x801B,
|
||||
FindNodeCacheResponse = 0x801C,
|
||||
ExtendedSimpleDescriptorResponse = 0x801D,
|
||||
ExtendedActiveEndpointResponse = 0x801E,
|
||||
ParentAnnounceRespone = 0x801F,
|
||||
|
||||
/* Binding */
|
||||
EndDeviceBindResponse = 0x8020,
|
||||
BindResponse = 0x8021,
|
||||
UnbindResponse = 0x8022,
|
||||
BindRegisterResponse = 0x8023,
|
||||
ReplaceDeviceResponse = 0x8024,
|
||||
StoreBackupBindEntryResponse = 0x8025,
|
||||
RemoveBackupBindEntryResponse = 0x8026,
|
||||
BackupBindTableResponse = 0x8027,
|
||||
RecoverBindTableResponse = 0x8028,
|
||||
BackupSourceBindResponse = 0x8029,
|
||||
RecoverSourceBindResponse = 0x802A,
|
||||
|
||||
/* Network management */
|
||||
MgmtNetworkDiscoveryResponse = 0x8030,
|
||||
MgmtLqiResponse = 0x8031,
|
||||
MgmtRoutingTableResponse = 0x8032,
|
||||
MgmtBindResponse = 0x8033,
|
||||
MgmtLeaveResponse = 0x8034,
|
||||
MgmtDirectJoinResponse = 0x8035,
|
||||
MgmtPermitJoinResponse = 0x8036,
|
||||
MgmtCacheResponse = 0x8037,
|
||||
MgmtNetworkUpdateResponse = 0x8038
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // ZIGBEEDEVICEPROFILE_H
|
||||
@ -87,6 +87,20 @@ void ZigbeeNetwork::setSerialBaudrate(qint32 baudrate)
|
||||
emit serialBaudrateChanged(m_serialBaudrate);
|
||||
}
|
||||
|
||||
quint16 ZigbeeNetwork::panId()
|
||||
{
|
||||
return m_panId;
|
||||
}
|
||||
|
||||
void ZigbeeNetwork::setPanId(quint16 panId)
|
||||
{
|
||||
if (m_panId == panId)
|
||||
return;
|
||||
|
||||
m_panId = panId;
|
||||
emit panIdChanged(m_panId);
|
||||
}
|
||||
|
||||
quint64 ZigbeeNetwork::extendedPanId() const
|
||||
{
|
||||
return m_extendedPanId;
|
||||
@ -243,7 +257,7 @@ void ZigbeeNetwork::saveNetwork()
|
||||
qCDebug(dcZigbeeNetwork()) << "Save current network configuration to" << m_settingsFileName;
|
||||
QSettings settings(m_settingsFileName, QSettings::IniFormat, this);
|
||||
settings.beginGroup("Network");
|
||||
settings.setValue("panId", extendedPanId());
|
||||
settings.setValue("panId", panId());
|
||||
settings.setValue("channel", channel());
|
||||
settings.setValue("networkKey", securityConfiguration().networkKey().toString());
|
||||
settings.setValue("trustCenterLinkKey", securityConfiguration().globalTrustCenterLinkKey().toString());
|
||||
@ -260,8 +274,8 @@ void ZigbeeNetwork::loadNetwork()
|
||||
QSettings settings(m_settingsFileName, QSettings::IniFormat, this);
|
||||
|
||||
settings.beginGroup("Network");
|
||||
quint64 extendedPanId = static_cast<quint64>(settings.value("panId", 0).toULongLong());
|
||||
setExtendedPanId(extendedPanId);
|
||||
quint16 panId = static_cast<quint16>(settings.value("panId", 0).toUInt());
|
||||
setPanId(panId);
|
||||
setChannel(settings.value("channel", 0).toUInt());
|
||||
ZigbeeNetworkKey netKey(settings.value("networkKey", QString()).toString());
|
||||
if (netKey.isValid())
|
||||
@ -420,6 +434,11 @@ void ZigbeeNetwork::removeNodeFromSettings(ZigbeeNode *node)
|
||||
void ZigbeeNetwork::addNode(ZigbeeNode *node)
|
||||
{
|
||||
qCDebug(dcZigbeeNetwork()) << "Add node" << node;
|
||||
if (hasNode(node->extendedAddress())) {
|
||||
qCWarning(dcZigbeeNetwork()) << "Not adding node to the system since already added" << node;
|
||||
return;
|
||||
}
|
||||
|
||||
addNodeInternally(node);
|
||||
saveNode(node);
|
||||
}
|
||||
|
||||
@ -76,6 +76,9 @@ public:
|
||||
void setSerialBaudrate(qint32 baudrate);
|
||||
|
||||
// Network configurations
|
||||
quint16 panId();
|
||||
void setPanId(quint16 panId);
|
||||
|
||||
quint64 extendedPanId() const;
|
||||
void setExtendedPanId(quint64 extendedPanId);
|
||||
|
||||
@ -109,6 +112,7 @@ private:
|
||||
qint32 m_serialBaudrate = 115200;
|
||||
|
||||
// Network configurations
|
||||
quint16 m_panId = 0;
|
||||
quint64 m_extendedPanId = 0;
|
||||
quint32 m_channel = 0;
|
||||
ZigbeeChannelMask m_channelMask = ZigbeeChannelMask(ZigbeeChannelMask::ChannelConfigurationAllChannels);
|
||||
@ -151,6 +155,7 @@ signals:
|
||||
void serialPortNameChanged(const QString &serialPortName);
|
||||
void serialBaudrateChanged(qint32 serialBaudrate);
|
||||
|
||||
void panIdChanged(quint16 panId);
|
||||
void extendedPanIdChanged(quint64 extendedPanId);
|
||||
void channelChanged(uint channel);
|
||||
void channelMaskChanged(const ZigbeeChannelMask &channelMask);
|
||||
|
||||
@ -32,12 +32,19 @@ ZigbeeNetworkReply::Error ZigbeeNetworkReply::error() const
|
||||
return m_error;
|
||||
}
|
||||
|
||||
ZigbeeNetworkRequest ZigbeeNetworkReply::request() const
|
||||
{
|
||||
return m_request;
|
||||
}
|
||||
|
||||
Zigbee::ZigbeeStatus ZigbeeNetworkReply::zigbeeStatus() const
|
||||
{
|
||||
return m_zigbeeStatus;
|
||||
}
|
||||
|
||||
ZigbeeNetworkReply::ZigbeeNetworkReply(QObject *parent) : QObject(parent)
|
||||
ZigbeeNetworkReply::ZigbeeNetworkReply(const ZigbeeNetworkRequest &request, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_request(request)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include <QObject>
|
||||
|
||||
#include "zigbee.h"
|
||||
#include "zigbeenetworkrequest.h"
|
||||
|
||||
class ZigbeeNetworkReply : public QObject
|
||||
{
|
||||
@ -48,10 +49,13 @@ public:
|
||||
Q_ENUM(Error)
|
||||
|
||||
Error error() const;
|
||||
ZigbeeNetworkRequest request() const;
|
||||
Zigbee::ZigbeeStatus zigbeeStatus() const;
|
||||
|
||||
private:
|
||||
explicit ZigbeeNetworkReply(QObject *parent = nullptr);
|
||||
explicit ZigbeeNetworkReply(const ZigbeeNetworkRequest &request, QObject *parent = nullptr);
|
||||
ZigbeeNetworkRequest m_request;
|
||||
|
||||
bool m_finished = false;
|
||||
Error m_error = ErrorNoError;
|
||||
Zigbee::ZigbeeStatus m_zigbeeStatus = Zigbee::ZigbeeStatusSuccess;
|
||||
|
||||
143
libnymea-zigbee/zigbeenetworkrequest.cpp
Normal file
143
libnymea-zigbee/zigbeenetworkrequest.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 "zigbeenetworkrequest.h"
|
||||
|
||||
ZigbeeNetworkRequest::ZigbeeNetworkRequest()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
quint8 ZigbeeNetworkRequest::requestId() const
|
||||
{
|
||||
return m_requestId;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setRequestId(quint8 requestId)
|
||||
{
|
||||
m_requestId = requestId;
|
||||
}
|
||||
|
||||
Zigbee::DestinationAddressMode ZigbeeNetworkRequest::destinationAddressMode() const
|
||||
{
|
||||
return m_destinationAddressMode;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setDestinationAddressMode(Zigbee::DestinationAddressMode destinationAddressMode)
|
||||
{
|
||||
m_destinationAddressMode = destinationAddressMode;
|
||||
}
|
||||
|
||||
quint16 ZigbeeNetworkRequest::destinationShortAddress() const
|
||||
{
|
||||
return m_destinationShortAddress;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setDestinationShortAddress(quint16 destinationShortAddress)
|
||||
{
|
||||
m_destinationShortAddress = destinationShortAddress;
|
||||
}
|
||||
|
||||
ZigbeeAddress ZigbeeNetworkRequest::destinationIeeeAddress() const
|
||||
{
|
||||
return m_destinationIeeeAddress;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setDestinationIeeeAddress(const ZigbeeAddress &destinationIeeeAddress)
|
||||
{
|
||||
m_destinationIeeeAddress = destinationIeeeAddress;
|
||||
}
|
||||
|
||||
quint8 ZigbeeNetworkRequest::destinationEndpoint() const
|
||||
{
|
||||
return m_destinationEndpoint;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setDestinationEndpoint(quint8 destinationEndpoint)
|
||||
{
|
||||
m_destinationEndpoint = destinationEndpoint;
|
||||
}
|
||||
|
||||
quint16 ZigbeeNetworkRequest::profileId() const
|
||||
{
|
||||
return m_profileId;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setProfileId(quint16 profileId)
|
||||
{
|
||||
m_profileId = profileId;
|
||||
}
|
||||
|
||||
quint16 ZigbeeNetworkRequest::clusterId() const
|
||||
{
|
||||
return m_clusterId;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setClusterId(quint16 clusterId)
|
||||
{
|
||||
m_clusterId = clusterId;
|
||||
}
|
||||
|
||||
quint8 ZigbeeNetworkRequest::sourceEndpoint() const
|
||||
{
|
||||
return m_sourceEndpoint;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setSourceEndpoint(quint8 sourceEndpoint)
|
||||
{
|
||||
m_sourceEndpoint = sourceEndpoint;
|
||||
}
|
||||
|
||||
QByteArray ZigbeeNetworkRequest::asdu() const
|
||||
{
|
||||
return m_asdu;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setAsdu(const QByteArray &asdu)
|
||||
{
|
||||
m_asdu = asdu;
|
||||
}
|
||||
|
||||
Zigbee::ZigbeeTxOptions ZigbeeNetworkRequest::txOptions() const
|
||||
{
|
||||
return m_txOptions;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setTxOptions(Zigbee::ZigbeeTxOptions txOptions)
|
||||
{
|
||||
m_txOptions = txOptions;
|
||||
}
|
||||
|
||||
quint8 ZigbeeNetworkRequest::radius() const
|
||||
{
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
void ZigbeeNetworkRequest::setRadius(quint8 radius)
|
||||
{
|
||||
m_radius = radius;
|
||||
}
|
||||
88
libnymea-zigbee/zigbeenetworkrequest.h
Normal file
88
libnymea-zigbee/zigbeenetworkrequest.h
Normal file
@ -0,0 +1,88 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* 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 ZIGBEENETWORKREQUEST_H
|
||||
#define ZIGBEENETWORKREQUEST_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "zigbee.h"
|
||||
#include "zigbeeaddress.h"
|
||||
|
||||
class ZigbeeNetworkRequest
|
||||
{
|
||||
public:
|
||||
ZigbeeNetworkRequest();
|
||||
|
||||
quint8 requestId() const;
|
||||
void setRequestId(quint8 requestId);
|
||||
|
||||
Zigbee::DestinationAddressMode destinationAddressMode() const;
|
||||
void setDestinationAddressMode(Zigbee::DestinationAddressMode destinationAddressMode);
|
||||
|
||||
quint16 destinationShortAddress() const;
|
||||
void setDestinationShortAddress(quint16 destinationShortAddress);
|
||||
|
||||
ZigbeeAddress destinationIeeeAddress() const;
|
||||
void setDestinationIeeeAddress(const ZigbeeAddress &destinationIeeeAddress);
|
||||
|
||||
quint8 destinationEndpoint() const;
|
||||
void setDestinationEndpoint(quint8 destinationEndpoint);
|
||||
|
||||
quint16 profileId() const;
|
||||
void setProfileId(quint16 profileId);
|
||||
|
||||
quint16 clusterId() const;
|
||||
void setClusterId(quint16 clusterId);
|
||||
|
||||
quint8 sourceEndpoint() const;
|
||||
void setSourceEndpoint(quint8 sourceEndpoint);
|
||||
|
||||
QByteArray asdu() const;
|
||||
void setAsdu(const QByteArray &asdu);
|
||||
|
||||
Zigbee::ZigbeeTxOptions txOptions() const;
|
||||
void setTxOptions(Zigbee::ZigbeeTxOptions txOptions);
|
||||
|
||||
quint8 radius() const;
|
||||
void setRadius(quint8 radius);
|
||||
|
||||
private:
|
||||
quint8 m_requestId = 0;
|
||||
Zigbee::DestinationAddressMode m_destinationAddressMode = Zigbee::DestinationAddressModeShortAddress;
|
||||
quint16 m_destinationShortAddress = 0;
|
||||
ZigbeeAddress m_destinationIeeeAddress;
|
||||
quint8 m_destinationEndpoint = 0;
|
||||
quint16 m_profileId = 0;
|
||||
quint16 m_clusterId = 0;
|
||||
quint8 m_sourceEndpoint = 0;
|
||||
QByteArray m_asdu;
|
||||
Zigbee::ZigbeeTxOptions m_txOptions = Zigbee::ZigbeeTxOptions(Zigbee::ZigbeeTxOptionAckTransmission);
|
||||
quint8 m_radius = 0;
|
||||
};
|
||||
|
||||
#endif // ZIGBEENETWORKREQUEST_H
|
||||
@ -155,9 +155,9 @@ void ZigbeeNodeEndpoint::addOutputCluster(ZigbeeCluster *cluster)
|
||||
m_outputClusters.insert(cluster->clusterId(), cluster);
|
||||
}
|
||||
|
||||
ZigbeeNetworkReply *ZigbeeNodeEndpoint::createNetworkReply()
|
||||
ZigbeeNetworkReply *ZigbeeNodeEndpoint::createNetworkReply(const ZigbeeNetworkRequest &request)
|
||||
{
|
||||
ZigbeeNetworkReply *reply = new ZigbeeNetworkReply(this);
|
||||
ZigbeeNetworkReply *reply = new ZigbeeNetworkReply(request, this);
|
||||
// Make sure the reply will be deleted
|
||||
connect(reply, &ZigbeeNetworkReply::finished, reply, &ZigbeeNetworkReply::deleteLater);
|
||||
return reply;
|
||||
|
||||
@ -131,7 +131,7 @@ protected:
|
||||
void addOutputCluster(ZigbeeCluster *cluster);
|
||||
|
||||
// Network reply methods
|
||||
ZigbeeNetworkReply *createNetworkReply();
|
||||
ZigbeeNetworkReply *createNetworkReply(const ZigbeeNetworkRequest &request = ZigbeeNetworkRequest());
|
||||
void finishNetworkReply(ZigbeeNetworkReply *reply, ZigbeeNetworkReply::Error error = ZigbeeNetworkReply::ErrorNoError, Zigbee::ZigbeeStatus zigbeeStatus = Zigbee::ZigbeeStatusSuccess);
|
||||
|
||||
signals:
|
||||
|
||||
@ -173,6 +173,11 @@ QByteArray ZigbeeUtils::convertBitArrayToByteArray(const QBitArray &bitArray)
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
bool ZigbeeUtils::checkBitUint8(const quint8 &value, const int &bitNumber)
|
||||
{
|
||||
return value & (1 << bitNumber);
|
||||
}
|
||||
|
||||
bool ZigbeeUtils::checkBitUint16(const quint16 &value, const int &bitNumber)
|
||||
{
|
||||
return value & (1 << bitNumber);
|
||||
|
||||
@ -38,6 +38,16 @@
|
||||
#include "zigbee.h"
|
||||
#include "zigbeecluster.h"
|
||||
|
||||
template<class TYPE> inline TYPE ZigbeeBit(const TYPE & x)
|
||||
{
|
||||
return TYPE(1) << x;
|
||||
}
|
||||
|
||||
template<class TYPE> inline bool ZigbeeIsBitSet(const TYPE & x, const TYPE & y)
|
||||
{
|
||||
return (x & y) != 0;
|
||||
}
|
||||
|
||||
class ZigbeeUtils
|
||||
{
|
||||
Q_GADGET
|
||||
@ -46,6 +56,7 @@ public:
|
||||
// Data utils
|
||||
QBitArray convertByteArrayToBitArray(const QByteArray &byteArray);
|
||||
QByteArray convertBitArrayToByteArray(const QBitArray &bitArray);
|
||||
static bool checkBitUint8(const quint8 &value, const int &bitNumber);
|
||||
static bool checkBitUint16(const quint16 &value, const int &bitNumber);
|
||||
|
||||
static quint16 convertByteArrayToUint16(const QByteArray &data);
|
||||
|
||||
Reference in New Issue
Block a user