|
|
|
|
@ -9,10 +9,10 @@ ZigbeeNetworkNxp::ZigbeeNetworkNxp(QObject *parent) :
|
|
|
|
|
{
|
|
|
|
|
m_controller = new ZigbeeBridgeControllerNxp(this);
|
|
|
|
|
connect(m_controller, &ZigbeeBridgeControllerNxp::availableChanged, this, &ZigbeeNetworkNxp::onControllerAvailableChanged);
|
|
|
|
|
connect(m_controller, &ZigbeeBridgeControllerNxp::interfaceNotificationReceived, this, &ZigbeeNetworkNxp::onInterfaceNotificationReceived);
|
|
|
|
|
connect(m_controller, &ZigbeeBridgeControllerNxp::controllerStateChanged, this, &ZigbeeNetworkNxp::onControllerStateChanged);
|
|
|
|
|
//connect(m_controller, &ZigbeeBridgeControllerNxp::apsDataConfirmReceived, this, &ZigbeeNetworkNxp::onApsDataConfirmReceived);
|
|
|
|
|
//connect(m_controller, &ZigbeeBridgeControllerNxp::apsDataIndicationReceived, this, &ZigbeeNetworkNxp::onApsDataIndicationReceived);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ZigbeeBridgeController *ZigbeeNetworkNxp::bridgeController() const
|
|
|
|
|
@ -39,17 +39,24 @@ ZigbeeNetworkReply *ZigbeeNetworkNxp::setPermitJoin(quint16 shortAddress, quint8
|
|
|
|
|
void ZigbeeNetworkNxp::onControllerAvailableChanged(bool available)
|
|
|
|
|
{
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Controller is" << (available ? "now available" : "not available any more");
|
|
|
|
|
|
|
|
|
|
if (available) {
|
|
|
|
|
// Get controller state
|
|
|
|
|
|
|
|
|
|
// Get network state, depending on the controller state
|
|
|
|
|
|
|
|
|
|
//reset();
|
|
|
|
|
factoryResetNetwork();
|
|
|
|
|
} else {
|
|
|
|
|
setState(StateOffline);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::ControllerState controllerState)
|
|
|
|
|
{
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Controller state changed" << controllerState;
|
|
|
|
|
switch (controllerState) {
|
|
|
|
|
case ZigbeeBridgeControllerNxp::ControllerStateRunning: {
|
|
|
|
|
setState(StateStarting);
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Request controller version";
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
|
|
|
|
@ -64,16 +71,74 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Controller version" << versionString;
|
|
|
|
|
m_controller->setFirmwareVersion(versionString);
|
|
|
|
|
|
|
|
|
|
// We are done here...
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Get the current network state";
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestNetworkState();
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Get network state response" << reply->status();
|
|
|
|
|
//FIXME: error handling
|
|
|
|
|
|
|
|
|
|
QByteArray data = reply->responseData();
|
|
|
|
|
QDataStream payloadStream(&data, QIODevice::ReadOnly);
|
|
|
|
|
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
|
|
|
|
quint16 networkAddress; quint64 ieeeAddress; quint8 channel;
|
|
|
|
|
quint16 panId; quint64 extendedPanId;
|
|
|
|
|
payloadStream >> networkAddress >> ieeeAddress >> channel >> panId >> extendedPanId;
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Network running" << ZigbeeUtils::convertUint16ToHexString(networkAddress)
|
|
|
|
|
<< ZigbeeAddress(ieeeAddress).toString()
|
|
|
|
|
<< "Channel:" << channel
|
|
|
|
|
<< "PAN ID:" << panId << "Extended PAN ID:" << ZigbeeUtils::convertUint64ToHexString(extendedPanId);
|
|
|
|
|
|
|
|
|
|
setPanId(panId);
|
|
|
|
|
setChannel(channel);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize the coordinator node if not already done.
|
|
|
|
|
|
|
|
|
|
if (m_coordinatorNode) {
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "We already have the coordinator node. Network starting done.";
|
|
|
|
|
m_database->saveNode(m_coordinatorNode);
|
|
|
|
|
setState(StateRunning);
|
|
|
|
|
setPermitJoiningInternal(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ZigbeeNode *coordinatorNode = createNode(networkAddress, ZigbeeAddress(ieeeAddress), this);
|
|
|
|
|
m_coordinatorNode = coordinatorNode;
|
|
|
|
|
|
|
|
|
|
// TODO: initialize
|
|
|
|
|
|
|
|
|
|
m_database->saveNode(m_coordinatorNode);
|
|
|
|
|
saveNetwork();
|
|
|
|
|
setState(StateRunning);
|
|
|
|
|
|
|
|
|
|
// // Network creation done when coordinator node is initialized
|
|
|
|
|
// connect(coordinatorNode, &ZigbeeNode::stateChanged, this, [this, coordinatorNode](ZigbeeNode::State state){
|
|
|
|
|
// if (state == ZigbeeNode::StateInitialized) {
|
|
|
|
|
// qCDebug(dcZigbeeNetwork()) << "Coordinator initialized successfully." << coordinatorNode;
|
|
|
|
|
// m_initializing = false;
|
|
|
|
|
// setState(StateRunning);
|
|
|
|
|
// setPermitJoiningInternal(false);
|
|
|
|
|
// return;
|
|
|
|
|
// }
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
// coordinatorNode->startInitialization();
|
|
|
|
|
// addUnitializedNode(coordinatorNode);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ZigbeeBridgeControllerNxp::ControllerStateStarting:
|
|
|
|
|
setState(StateStarting);
|
|
|
|
|
break;
|
|
|
|
|
case ZigbeeBridgeControllerNxp::ControllerStateBooting:
|
|
|
|
|
setState(StateStarting);
|
|
|
|
|
break;
|
|
|
|
|
case ZigbeeBridgeControllerNxp::ControllerStateRunningUninitialized: {
|
|
|
|
|
setState(StateStarting);
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Request controller version";
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestVersion();
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
|
|
|
|
@ -90,38 +155,48 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Controller version" << versionString;
|
|
|
|
|
m_controller->setFirmwareVersion(versionString);
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set pan id" << ZigbeeUtils::convertUint64ToHexString(extendedPanId()) << extendedPanId();
|
|
|
|
|
if (extendedPanId() == 0) {
|
|
|
|
|
quint64 panId = ZigbeeUtils::generateRandomPanId();
|
|
|
|
|
setExtendedPanId(panId);
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "There is no pan id set yet. Generated new PAN ID" << panId << ZigbeeUtils::convertUint64ToHexString(panId);
|
|
|
|
|
|
|
|
|
|
ZigbeeSecurityConfiguration securityConfiguration;
|
|
|
|
|
securityConfiguration.setNetworkKey(ZigbeeNetworkKey::generateKey());
|
|
|
|
|
setSecurityConfiguration(securityConfiguration);
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Generated new network key" << securityConfiguration.networkKey().toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set PAN ID" << ZigbeeUtils::convertUint64ToHexString(extendedPanId()) << extendedPanId();
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSetPanId(extendedPanId());
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set PAN ID reply finished" << reply->status();
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set PAN ID reply response" << reply->status();
|
|
|
|
|
//FIXME: error handling
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set channel mask" << channelMask() << ZigbeeUtils::convertUint32ToHexString(channelMask().toUInt32()) << channelMask().toUInt32();
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set channel mask" << channelMask();
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSetChannelMask(channelMask().toUInt32());
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set channel mask reply finished" << reply->status();
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set channel mask reply response" << reply->status();
|
|
|
|
|
//FIXME: error handling
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set global link key" << securityConfiguration().globalTrustCenterLinkKey().toString();
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSetSecurityKey(Nxp::KeyTypeGlobalLinkKey, securityConfiguration().globalTrustCenterLinkKey());
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set global link key" << reply->status();
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set global link key response" << reply->status();
|
|
|
|
|
//FIXME: error handling
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set network link key" << securityConfiguration().networkKey().toString();
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSetSecurityKey(Nxp::KeyTypeUniqueLinkKey, securityConfiguration().networkKey());
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set network link key" << reply->status();
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set network link key response" << reply->status();
|
|
|
|
|
//FIXME: error handling
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Start the network";
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestStartNetwork();
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Start network" << reply->status();
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Start network response" << reply->status();
|
|
|
|
|
//FIXME: error handling
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Waiting for the network to start...";
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
@ -131,13 +206,50 @@ void ZigbeeNetworkNxp::onControllerStateChanged(ZigbeeBridgeControllerNxp::Contr
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case ZigbeeBridgeControllerNxp::ControllerStateNotRunning:
|
|
|
|
|
setState(StateOffline);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ZigbeeNetworkNxp::onInterfaceNotificationReceived(Nxp::Notification notification, const QByteArray &payload)
|
|
|
|
|
{
|
|
|
|
|
switch (notification) {
|
|
|
|
|
case Nxp::NotificationNetworkStarted: {
|
|
|
|
|
QByteArray data = payload;
|
|
|
|
|
QDataStream payloadStream(&data, QIODevice::ReadOnly);
|
|
|
|
|
payloadStream.setByteOrder(QDataStream::LittleEndian);
|
|
|
|
|
quint16 networkAddress; quint64 ieeeAddress; quint8 channel;
|
|
|
|
|
payloadStream >> networkAddress >> ieeeAddress >> channel;
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Network started" << ZigbeeUtils::convertUint16ToHexString(networkAddress) << ZigbeeAddress(ieeeAddress).toString() << "Channel:" << channel;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
qCWarning(dcZigbeeNetwork()) << "Unhandeld interface notification received" << notification << ZigbeeUtils::convertByteArrayToHexString(payload);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ZigbeeNetworkNxp::setPermitJoiningInternal(bool permitJoining)
|
|
|
|
|
{
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set permit join internal" << permitJoining;
|
|
|
|
|
|
|
|
|
|
quint8 duration = 0;
|
|
|
|
|
if (permitJoining) {
|
|
|
|
|
duration = 255;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: send broadcast message using ZDO and refrash
|
|
|
|
|
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set permit join in the coordinator node to" << duration << "[s]";
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSetPermitJoinCoordinator(duration);
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [this, reply, permitJoining](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Set permit join in the coordinator finished" << reply->status();
|
|
|
|
|
m_permitJoining = permitJoining;
|
|
|
|
|
emit permitJoiningChanged(m_permitJoining);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ZigbeeNetworkNxp::startNetwork()
|
|
|
|
|
@ -165,16 +277,18 @@ void ZigbeeNetworkNxp::stopNetwork()
|
|
|
|
|
|
|
|
|
|
void ZigbeeNetworkNxp::reset()
|
|
|
|
|
{
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Soft reset the controller. The stack will perform a restart.";
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestSoftResetController();
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Soft reset reply finished";
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Soft reset reply finished" << reply->status();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ZigbeeNetworkNxp::factoryResetNetwork()
|
|
|
|
|
{
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Factory reset network and forget all information. This cannot be undone.";
|
|
|
|
|
ZigbeeInterfaceNxpReply *reply = m_controller->requestFactoryResetController();
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Factory reset reply finished";
|
|
|
|
|
connect(reply, &ZigbeeInterfaceNxpReply::finished, this, [reply](){
|
|
|
|
|
qCDebug(dcZigbeeNetwork()) << "Factory reset reply finished" << reply->status();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|