use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.
the class ApplicationCommandMessageClass method handleRequest.
@Override
public boolean handleRequest(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) {
logger.trace("Handle Message Application Command Request");
int nodeId = incomingMessage.getMessagePayloadByte(1);
ZWaveNode node = zController.getNode(nodeId);
if (node == null) {
logger.warn("NODE {}: Not initialized yet, ignoring message.", nodeId);
return false;
}
logger.debug("NODE {}: Application Command Request ({}:{})", nodeId, node.getNodeState().toString(), node.getNodeInitializationStage().toString());
// If the node is DEAD, but we've just received a message from it, then it's not dead!
if (node.isDead()) {
node.setNodeState(ZWaveNodeState.ALIVE);
}
node.resetResendCount();
node.incrementReceiveCount();
int commandClassCode = incomingMessage.getMessagePayloadByte(3);
ZWaveCommandClass zwaveCommandClass = resolveZWaveCommandClass(node, commandClassCode, zController);
if (zwaveCommandClass == null) {
// Error message was logged in resolveZWaveCommandClass
return false;
}
final int commandByte = incomingMessage.getMessagePayloadByte(4);
if (zwaveCommandClass instanceof ZWaveSecurityCommandClass && (ZWaveSecurityCommandClass.bytesAreEqual(ZWaveSecurityCommandClass.SECURITY_MESSAGE_ENCAP, commandByte) || ZWaveSecurityCommandClass.bytesAreEqual(ZWaveSecurityCommandClass.SECURITY_MESSAGE_ENCAP_NONCE_GET, commandByte))) {
boolean isEncapNonceGet = ZWaveSecurityCommandClass.bytesAreEqual(ZWaveSecurityCommandClass.SECURITY_MESSAGE_ENCAP_NONCE_GET, commandByte);
// Intercept security encapsulated messages here and decrypt them.
ZWaveSecurityCommandClass zwaveSecurityCommandClass = (ZWaveSecurityCommandClass) zwaveCommandClass;
logger.trace("NODE {}: Preparing to decrypt security encapsulated message, messagePayload={}", nodeId, SerialMessage.bb2hex(incomingMessage.getMessagePayload()));
int toDecryptLength = incomingMessage.getMessageBuffer().length - 9;
byte[] toDecrypt = new byte[toDecryptLength];
System.arraycopy(incomingMessage.getMessageBuffer(), 8, toDecrypt, 0, toDecryptLength);
byte[] decryptedBytes = zwaveSecurityCommandClass.decryptMessage(toDecrypt, 0);
if (decryptedBytes == null) {
logger.error("NODE {}: Failed to decrypt message out of {} .", nodeId, incomingMessage);
} else {
// call handleApplicationCommandRequest with the decrypted message. Note that we do NOT set
// incomingMessage as that needs to be processed below with the original security encapsulated message
final SerialMessage decryptedMessage = new SerialMessage(incomingMessage.getMessageClass(), incomingMessage.getMessageType(), incomingMessage.getExpectedReply(), incomingMessage.getPriority());
decryptedMessage.setMessagePayload(decryptedBytes);
// Get the new command class with the decrypted contents
zwaveCommandClass = resolveZWaveCommandClass(node, decryptedBytes[1], zController);
// Use a flag bc we need to handle isEncapNonceGet either way
boolean failed = false;
if (zwaveCommandClass == null) {
// Error message was logged in resolveZWaveCommandClass
failed = true;
} else {
// Note that we do not call node.doesMessageRequireSecurityEncapsulation since it was encapsulated.
// Messages that are not required to be are allowed to be, just not the other way around
logger.debug("NODE {}: After decrypt, found Command Class {}, passing to handleApplicationCommandRequest", nodeId, zwaveCommandClass.getCommandClass().getLabel());
zwaveCommandClass.handleApplicationCommandRequest(decryptedMessage, 2, 0);
}
if (isEncapNonceGet) {
// the device also needs another nonce; send it regardless of the success/failure of decryption
zwaveSecurityCommandClass.sendNonceReport();
}
if (failed) {
return false;
}
}
} else {
// Message does not require decryption
if (node.doesMessageRequireSecurityEncapsulation(incomingMessage)) {
// Should have been security encapsulation but wasn't!
logger.error("NODE {}: Command Class {} {} was required to be security encapsulation but it wasn't! Dropping message.", nodeId, zwaveCommandClass.getCommandClass().getKey(), zwaveCommandClass.getCommandClass().getLabel());
// do not call zwaveCommandClass.handleApplicationCommandRequest();
} else {
logger.trace("NODE {}: Found Command Class {}, passing to handleApplicationCommandRequest", nodeId, zwaveCommandClass.getCommandClass().getLabel());
zwaveCommandClass.handleApplicationCommandRequest(incomingMessage, 4, 0);
}
}
if (node.getNodeId() == lastSentMessage.getMessageNode()) {
checkTransactionComplete(lastSentMessage, incomingMessage);
} else {
logger.debug("NODE {}: Transaction not completed: node address inconsistent. lastSent={}, incoming={}", lastSentMessage.getMessageNode(), lastSentMessage.getMessageNode(), incomingMessage.getMessageNode());
}
return true;
}
use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.
the class AssignReturnRouteMessageClass method doRequest.
public SerialMessage doRequest(int nodeId, int destinationId, int callbackId) {
logger.debug("NODE {}: Assigning return route to node {}", nodeId, destinationId);
// Queue the request
SerialMessage newMessage = new SerialMessage(SerialMessageClass.AssignReturnRoute, SerialMessageType.Request, SerialMessageClass.AssignReturnRoute, SerialMessagePriority.High);
byte[] newPayload = { (byte) nodeId, (byte) destinationId, (byte) callbackId };
newMessage.setMessagePayload(newPayload);
return newMessage;
}
use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.
the class ZWaveThermostatFanStateCommandClass method getValueMessage.
/**
* {@inheritDoc}
*/
@Override
public SerialMessage getValueMessage() {
if (isGetSupported == false) {
logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId());
return null;
}
logger.debug("NODE {}: Creating new message for application command THERMOSTAT_FAN_STATE_GET", this.getNode().getNodeId());
SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get);
byte[] payload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), THERMOSTAT_FAN_STATE_GET };
result.setMessagePayload(payload);
return result;
}
use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.
the class ZWaveThermostatModeCommandClass method getValueMessage.
/**
* {@inheritDoc}
*/
@Override
public SerialMessage getValueMessage() {
if (isGetSupported == false) {
logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId());
return null;
}
logger.debug("NODE {}: Creating new message for application command THERMOSTAT_MODE_GET", this.getNode().getNodeId());
SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get);
byte[] payload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), THERMOSTAT_MODE_GET };
result.setMessagePayload(payload);
return result;
}
use of org.openhab.binding.zwave.internal.protocol.SerialMessage in project openhab1-addons by openhab.
the class ZWaveThermostatOperatingStateCommandClass method getValueMessage.
/**
* {@inheritDoc}
*/
@Override
public SerialMessage getValueMessage() {
if (isGetSupported == false) {
logger.debug("NODE {}: Node doesn't support get requests", this.getNode().getNodeId());
return null;
}
logger.debug("NODE {}: Creating new message for application command THERMOSTAT_OPERATING_STATE_GET", this.getNode().getNodeId());
SerialMessage result = new SerialMessage(this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get);
byte[] payload = { (byte) this.getNode().getNodeId(), 2, (byte) getCommandClass().getKey(), THERMOSTAT_OPERATING_STATE_GET };
result.setMessagePayload(payload);
return result;
}
Aggregations