Skip to content

Commit

Permalink
Updates following Smart Energy certification
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Jackson <[email protected]>
  • Loading branch information
cdjackson committed Jan 8, 2020
1 parent 4032a5f commit a1ccb3d
Show file tree
Hide file tree
Showing 9 changed files with 4,467 additions and 1,531 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,17 @@ public void commandReceived(ZclCommand command) {
return;
}

// Ensure security is used if required
if (cluster.getApsSecurityRequired() && !command.getApsSecurity()) {
logger.debug("{}: Endpoint {}. Cluster '{}' requires security but command is not secured", getIeeeAddress(),
getEndpointId(), cluster.getClusterName());
DefaultResponse response = ZclCluster.createDefaultResponse(command, ZclStatus.UNSECURED);
if (response != null) {
sendTransaction(response);
}
return;
}

cluster.handleCommand(command);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1019,13 +1019,19 @@ private ZigBeeCommand receiveZclCommand(final ZclFieldDeserializer fieldDeserial
ZigBeeNode node = getNode(apsFrame.getSourceAddress());
if (node == null) {
logger.debug("Unknown remote node {}", String.format("%04X", apsFrame.getSourceAddress()));
if (zclHeader.getDirection() == ZclCommandDirection.CLIENT_TO_SERVER) {
createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE);
}
return null;
}

ZigBeeEndpoint endpoint = node.getEndpoint(apsFrame.getSourceEndpoint());
if (endpoint == null) {
logger.debug("{}: Endpoint {}. Unknown remote endpoint", node.getIeeeAddress(),
apsFrame.getSourceEndpoint());
if (zclHeader.getDirection() == ZclCommandDirection.CLIENT_TO_SERVER) {
createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE);
}
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,8 +560,7 @@ private void discoverServices(Integer destination, int clusterId) {

MatchDescriptorRequest matchRequest = new MatchDescriptorRequest();
matchRequest.setInClusterList(clusterList);
matchRequest.setOutClusterList(clusterList);
matchRequest.setDestinationAddress(new ZigBeeEndpointAddress(destination));
matchRequest.setOutClusterList(Collections.emptyList());
matchRequest.setDestinationAddress(new ZigBeeEndpointAddress(destination));
matchRequest.setProfileId(ZigBeeProfileType.ZIGBEE_SMART_ENERGY.getKey());
matchRequest.setNwkAddrOfInterest(destination);
Expand Down Expand Up @@ -678,8 +677,8 @@ private ZigBeeStatus requestSimpleDescriptor(final ZigBeeEndpoint endpoint)
CommandResult response = networkManager.sendTransaction(simpleDescriptorRequest, simpleDescriptorRequest).get();

final SimpleDescriptorResponse simpleDescriptorResponse = (SimpleDescriptorResponse) response.getResponse();
logger.debug("{}: SEP Extension: SimpleDescriptorResponse returned {}", endpoint.getIeeeAddress(),
simpleDescriptorResponse);
logger.debug("{}: SEP Extension: Endpoint {} SimpleDescriptorResponse returned {}", endpoint.getIeeeAddress(),
endpoint.getEndpointId(), simpleDescriptorResponse);
if (simpleDescriptorResponse == null) {
return ZigBeeStatus.FAILURE;
}
Expand Down Expand Up @@ -771,26 +770,32 @@ private void handleMatchDescriptorResponse(MatchDescriptorResponse response) {
case DISCOVER_METERING_SERVERS:
ZigBeeNode node = networkManager.getNode(response.getSourceAddress().getAddress());
if (node == null) {
logger.debug("SEP Extension: SEP discovery Node {} is unknown - getting IEEE address.",
logger.debug("{}: SEP Extension: SEP discovery node is unknown - getting IEEE address.",
response.getSourceAddress().getAddress());
// This node is unknown to us - get the long address
IeeeAddress ieeeAddress = requestIeeeAddress(response.getSourceAddress().getAddress());
node = new ZigBeeNode(networkManager, ieeeAddress);
networkManager.updateNode(node);
}

// Check if this node is authorised to communicate securely
if (!cbkeProvider.isAuthorised(node.getIeeeAddress())) {
logger.debug("{}: SEP Extension: SEP discovery node is not authorised", node.getIeeeAddress());
return;
}

ZigBeeNode updatedNode = new ZigBeeNode(networkManager, node.getIeeeAddress(),
node.getNetworkAddress());
for (Integer endpointId : response.getMatchList()) {
ZigBeeEndpoint endpoint = new ZigBeeEndpoint(updatedNode, endpointId);
logger.debug("SEP Extension: Metering endpoint {} being added/updated",
endpoint.getEndpointAddress());
logger.debug("{}: SEP Extension: Endpoint {} Metering endpoint being added/updated",
node.getIeeeAddress(), endpoint.getEndpointAddress());

try {
requestSimpleDescriptor(endpoint);
} catch (InterruptedException | ExecutionException e) {
logger.debug("SEP Extension: Exception getting simple descriptor from endpoint {}",
endpoint.getEndpointAddress());
logger.debug("{}: SEP Extension: Endpoint {} Exception getting simple descriptor",
node.getIeeeAddress(), endpoint.getEndpointAddress());
}
updatedNode.addEndpoint(endpoint);
}
Expand Down Expand Up @@ -927,12 +932,12 @@ private void setProfileSecurity(ZigBeeNode node) {
logger.debug("{}: SEP Extension: Node is not authorised", node.getIeeeAddress());
return;
}
logger.debug("{}: SEP node is authorised", node.getIeeeAddress());
logger.debug("{}: SEP Extension: Node is authorised", node.getIeeeAddress());

for (ZigBeeEndpoint endpoint : node.getEndpoints()) {
if (endpoint.getProfileId() != ZigBeeProfileType.ZIGBEE_SMART_ENERGY.getKey()) {
logger.debug("{}: SEP Extension: Endpoint {} is not SmartEnergy", node.getIeeeAddress(),
endpoint.getEndpointId());
logger.debug("{}: SEP Extension: Endpoint {} is not SmartEnergy [{}]", node.getIeeeAddress(),
endpoint.getEndpointId(), String.format("%04X", endpoint.getProfileId()));
continue;
}

Expand All @@ -942,8 +947,8 @@ private void setProfileSecurity(ZigBeeNode node) {
continue;
}

logger.debug("{}: SEP Extension: Setting profile security for input cluster {}", node.getIeeeAddress(),
clusterType);
logger.debug("{}: SEP Extension: Endpoint {} Setting profile security for input cluster {}",
node.getIeeeAddress(), endpoint.getEndpointId(), clusterType);
cluster.setApsSecurityRequired(true);
}

Expand All @@ -953,8 +958,8 @@ private void setProfileSecurity(ZigBeeNode node) {
continue;
}

logger.debug("{}: SEP Extension: Setting profile security for output cluster {}", node.getIeeeAddress(),
clusterType);
logger.debug("{}: SEP Extension: Endpoint {} Setting profile security for output cluster {}",
node.getIeeeAddress(), endpoint.getEndpointId(), clusterType);
cluster.setApsSecurityRequired(true);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,9 @@ public void run() {

setState(KeyEstablishmentState.COMPLETE);
stopCbke(0);

// Send the default response since we don't handle this in the main handler
keCluster.sendDefaultResponse(response, ZclStatus.SUCCESS);
}
}

Expand Down Expand Up @@ -602,6 +605,9 @@ public void run() {
logger.debug("{}: CBKE Terminate Key establishment client: Terminate status={}, suite={}, wait={} seconds",
ieeeAddress, status, suite, waitTime);
stopCbke(waitTime);

// Send the default response since we don't handle this in the main handler
keCluster.sendDefaultResponse(response, ZclStatus.SUCCESS);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.zsmartsystems.zigbee.zcl.ZclAttribute;
import com.zsmartsystems.zigbee.zcl.ZclCommand;
import com.zsmartsystems.zigbee.zcl.ZclCommandListener;
import com.zsmartsystems.zigbee.zcl.ZclStatus;
import com.zsmartsystems.zigbee.zcl.clusters.ZclKeyEstablishmentCluster;
import com.zsmartsystems.zigbee.zcl.clusters.keyestablishment.ConfirmKeyDataRequestCommand;
import com.zsmartsystems.zigbee.zcl.clusters.keyestablishment.EphemeralDataRequestCommand;
Expand Down Expand Up @@ -399,6 +400,9 @@ public void run() {

setState(KeyEstablishmentState.COMPLETE);
stopCbke();

// Send the default response since we don't handle this in the main handler
keCluster.sendDefaultResponse(request, ZclStatus.SUCCESS);
}
}

Expand All @@ -417,6 +421,9 @@ public void run() {

setState(KeyEstablishmentState.FAILED);
stopCbke();

// Send the default response since we don't handle this in the main handler
keCluster.sendDefaultResponse(request, ZclStatus.SUCCESS);
}
}

Expand Down
Loading

0 comments on commit a1ccb3d

Please sign in to comment.