@Test public void testReceiveZclCommand() throws Exception { TestUtilities.outputTestHeader(); ZigBeeNetworkManager networkManager = mockZigBeeNetworkManager(); networkManager.setSerializer(DefaultSerializer.class, DefaultDeserializer.class); networkManager.addSupportedServerCluster(6); ZigBeeEndpoint endpoint = Mockito.mock(ZigBeeEndpoint.class); ZclCluster cluster = new ZclOnOffCluster(endpoint); Mockito.when(endpoint.getOutputCluster(6)).thenReturn(cluster); ZigBeeNode node = Mockito.mock(ZigBeeNode.class); Mockito.when(node.getIeeeAddress()).thenReturn(new IeeeAddress("1111111111111111")); Mockito.when(node.getNetworkAddress()).thenReturn(1234); Mockito.when(node.getEndpoint(5)).thenReturn(endpoint); networkManager.updateNode(node); ZigBeeApsFrame apsFrame = new ZigBeeApsFrame(); apsFrame.setSourceAddress(1234); apsFrame.setDestinationAddress(0); apsFrame.setApsCounter(1); apsFrame.setCluster(6); apsFrame.setDestinationEndpoint(1); apsFrame.setProfile(0x104); apsFrame.setSourceEndpoint(5); ZclHeader zclHeader = new ZclHeader(); zclHeader.setCommandId(0); zclHeader.setFrameType(ZclFrameType.ENTIRE_PROFILE_COMMAND); zclHeader.setSequenceNumber(1); zclHeader.setDirection(ZclCommandDirection.CLIENT_TO_SERVER); DefaultSerializer serializer = new DefaultSerializer(); ZclFieldSerializer fieldSerializer = new ZclFieldSerializer(serializer); apsFrame.setPayload(zclHeader.serialize(fieldSerializer, new int[] {})); TestUtilities.setField(ZigBeeNetworkManager.class, networkManager, "networkState", ZigBeeNetworkState.ONLINE); networkManager.receiveCommand(apsFrame); Awaitility.await().until(() -> commandListenerUpdated()); ReadAttributesCommand response = (ReadAttributesCommand) commandListenerCapture.get(0); assertEquals(6, (int) response.getClusterId()); assertEquals(0, (int) response.getCommandId()); assertEquals(1, (int) response.getTransactionId()); assertEquals(new ZigBeeEndpointAddress(1234, 5), response.getSourceAddress()); ZigBeeAnnounceListener announceListener = Mockito.mock(ZigBeeAnnounceListener.class); networkManager.addAnnounceListener(announceListener); apsFrame.setSourceAddress(4321); networkManager.receiveCommand(apsFrame); Mockito.verify(announceListener, Mockito.timeout(TIMEOUT).times(1)).announceUnknownDevice(4321); }
private ZigBeeCommand receiveZclCommand(final ZclFieldDeserializer fieldDeserializer, final ZigBeeApsFrame apsFrame) { if (apsFrame.getDestinationEndpoint() != localEndpointId && apsFrame.getDestinationEndpoint() != BROADCAST_ENDPOINT_ID) { logger.debug("Unknown local endpoint for APS frame {}", apsFrame); return null; } ZclHeader zclHeader = new ZclHeader(fieldDeserializer); logger.debug("RX ZCL: {}", zclHeader); ZigBeeNode node = getNode(apsFrame.getSourceAddress()); if (node == null) { logger.debug("Unknown remote node {}", String.format("%04X", apsFrame.getSourceAddress())); return null; } ZigBeeEndpoint endpoint = node.getEndpoint(apsFrame.getSourceEndpoint()); if (endpoint == null) { logger.debug("{}: Endpoint {}. Unknown remote endpoint", node.getIeeeAddress(), apsFrame.getSourceEndpoint()); return null; } ZclCommand command; if (zclHeader.getDirection() == ZclCommandDirection.SERVER_TO_CLIENT) { if (!isClientClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local client cluster {}", String.format("%04X", apsFrame.getCluster())); } ZclCluster cluster = endpoint.getInputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown input cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setInputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getInputCluster(apsFrame.getCluster()); } command = cluster.getResponseFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } else { if (!isServerClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local server cluster {}", String.format("%04X", apsFrame.getCluster())); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } ZclCluster cluster = endpoint.getOutputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown output cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setOutputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getOutputCluster(apsFrame.getCluster()); } command = cluster.getCommandFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } if (command == null) { logger.debug("{}: Unknown command {}", node.getIeeeAddress(), zclHeader.getCommandId()); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } command.setCommandDirection(zclHeader.getDirection()); command.deserialize(fieldDeserializer); command.setClusterId(apsFrame.getCluster()); command.setTransactionId(zclHeader.getSequenceNumber()); command.setDisableDefaultResponse(zclHeader.isDisableDefaultResponse()); return command; }
ZigBeeNetworkManager implements ZigBeeTransportReceive { private ZigBeeCommand receiveZclCommand(final ZclFieldDeserializer fieldDeserializer, final ZigBeeApsFrame apsFrame) { if (apsFrame.getDestinationEndpoint() != localEndpointId && apsFrame.getDestinationEndpoint() != BROADCAST_ENDPOINT_ID) { logger.debug("Unknown local endpoint for APS frame {}", apsFrame); return null; } ZclHeader zclHeader = new ZclHeader(fieldDeserializer); logger.debug("RX ZCL: {}", zclHeader); ZigBeeNode node = getNode(apsFrame.getSourceAddress()); if (node == null) { logger.debug("Unknown remote node {}", String.format("%04X", apsFrame.getSourceAddress())); return null; } ZigBeeEndpoint endpoint = node.getEndpoint(apsFrame.getSourceEndpoint()); if (endpoint == null) { logger.debug("{}: Endpoint {}. Unknown remote endpoint", node.getIeeeAddress(), apsFrame.getSourceEndpoint()); return null; } ZclCommand command; if (zclHeader.getDirection() == ZclCommandDirection.SERVER_TO_CLIENT) { if (!isClientClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local client cluster {}", String.format("%04X", apsFrame.getCluster())); } ZclCluster cluster = endpoint.getInputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown input cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setInputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getInputCluster(apsFrame.getCluster()); } command = cluster.getResponseFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } else { if (!isServerClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local server cluster {}", String.format("%04X", apsFrame.getCluster())); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } ZclCluster cluster = endpoint.getOutputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown output cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setOutputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getOutputCluster(apsFrame.getCluster()); } command = cluster.getCommandFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } if (command == null) { logger.debug("{}: Unknown command {}", node.getIeeeAddress(), zclHeader.getCommandId()); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } command.setCommandDirection(zclHeader.getDirection()); command.deserialize(fieldDeserializer); command.setClusterId(apsFrame.getCluster()); command.setTransactionId(zclHeader.getSequenceNumber()); command.setDisableDefaultResponse(zclHeader.isDisableDefaultResponse()); return command; } }
ZigBeeNetworkManager implements ZigBeeTransportReceive { private ZigBeeCommand receiveZclCommand(final ZclFieldDeserializer fieldDeserializer, final ZigBeeApsFrame apsFrame) { if (apsFrame.getDestinationEndpoint() != localEndpointId && apsFrame.getDestinationEndpoint() != BROADCAST_ENDPOINT_ID) { logger.debug("Unknown local endpoint for APS frame {}", apsFrame); return null; } ZclHeader zclHeader = new ZclHeader(fieldDeserializer); logger.debug("RX ZCL: {}", zclHeader); ZigBeeNode node = getNode(apsFrame.getSourceAddress()); if (node == null) { logger.debug("Unknown remote node {}", String.format("%04X", apsFrame.getSourceAddress())); return null; } ZigBeeEndpoint endpoint = node.getEndpoint(apsFrame.getSourceEndpoint()); if (endpoint == null) { logger.debug("{}: Endpoint {}. Unknown remote endpoint", node.getIeeeAddress(), apsFrame.getSourceEndpoint()); return null; } ZclCommand command; if (zclHeader.getDirection() == ZclCommandDirection.SERVER_TO_CLIENT) { if (!isClientClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local client cluster {}", String.format("%04X", apsFrame.getCluster())); } ZclCluster cluster = endpoint.getInputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown input cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setInputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getInputCluster(apsFrame.getCluster()); } command = cluster.getResponseFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } else { if (!isServerClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local server cluster {}", String.format("%04X", apsFrame.getCluster())); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } ZclCluster cluster = endpoint.getOutputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown output cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setOutputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getOutputCluster(apsFrame.getCluster()); } command = cluster.getCommandFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } if (command == null) { logger.debug("{}: Unknown command {}", node.getIeeeAddress(), zclHeader.getCommandId()); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } command.setCommandDirection(zclHeader.getDirection()); command.deserialize(fieldDeserializer); command.setClusterId(apsFrame.getCluster()); command.setTransactionId(zclHeader.getSequenceNumber()); command.setDisableDefaultResponse(zclHeader.isDisableDefaultResponse()); return command; } ZigBeeNetworkManager(final ZigBeeTransportTransmit transport); }
ZigBeeNetworkManager implements ZigBeeTransportReceive { private ZigBeeCommand receiveZclCommand(final ZclFieldDeserializer fieldDeserializer, final ZigBeeApsFrame apsFrame) { if (apsFrame.getDestinationEndpoint() != localEndpointId && apsFrame.getDestinationEndpoint() != BROADCAST_ENDPOINT_ID) { logger.debug("Unknown local endpoint for APS frame {}", apsFrame); return null; } ZclHeader zclHeader = new ZclHeader(fieldDeserializer); logger.debug("RX ZCL: {}", zclHeader); ZigBeeNode node = getNode(apsFrame.getSourceAddress()); if (node == null) { logger.debug("Unknown remote node {}", String.format("%04X", apsFrame.getSourceAddress())); return null; } ZigBeeEndpoint endpoint = node.getEndpoint(apsFrame.getSourceEndpoint()); if (endpoint == null) { logger.debug("{}: Endpoint {}. Unknown remote endpoint", node.getIeeeAddress(), apsFrame.getSourceEndpoint()); return null; } ZclCommand command; if (zclHeader.getDirection() == ZclCommandDirection.SERVER_TO_CLIENT) { if (!isClientClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local client cluster {}", String.format("%04X", apsFrame.getCluster())); } ZclCluster cluster = endpoint.getInputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown input cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setInputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getInputCluster(apsFrame.getCluster()); } command = cluster.getResponseFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } else { if (!isServerClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local server cluster {}", String.format("%04X", apsFrame.getCluster())); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } ZclCluster cluster = endpoint.getOutputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown output cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setOutputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getOutputCluster(apsFrame.getCluster()); } command = cluster.getCommandFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } if (command == null) { logger.debug("{}: Unknown command {}", node.getIeeeAddress(), zclHeader.getCommandId()); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } command.setCommandDirection(zclHeader.getDirection()); command.deserialize(fieldDeserializer); command.setClusterId(apsFrame.getCluster()); command.setTransactionId(zclHeader.getSequenceNumber()); command.setDisableDefaultResponse(zclHeader.isDisableDefaultResponse()); return command; } ZigBeeNetworkManager(final ZigBeeTransportTransmit transport); void setNetworkDataStore(ZigBeeNetworkDataStore dataStore); void serializeNetworkDataStore(IeeeAddress nodeAddress); @SuppressWarnings("unchecked") void setSerializer(Class<?> serializer, Class<?> deserializer); void setLocalEndpointId(int localEndpointId); ZigBeeStatus initialize(); ZigBeeTransportTransmit getZigBeeTransport(); ZigBeeChannel getZigBeeChannel(); ZigBeeStatus setZigBeeChannel(ZigBeeChannel channel); int getZigBeePanId(); ZigBeeStatus setZigBeePanId(int panId); ExtendedPanId getZigBeeExtendedPanId(); ZigBeeStatus setZigBeeExtendedPanId(ExtendedPanId panId); ZigBeeStatus setDefaultProfileId(int defaultProfileId); ZigBeeStatus setDefaultDeviceId(int defaultDeviceId); ZigBeeStatus setZigBeeNetworkKey(final ZigBeeKey key); ZigBeeKey getZigBeeNetworkKey(); ZigBeeStatus setZigBeeLinkKey(final ZigBeeKey key); ZigBeeKey getZigBeeLinkKey(); ZigBeeStatus setZigBeeInstallKey(final ZigBeeKey key); ZigBeeStatus startup(boolean reinitialize); ZigBeeStatus reinitialize(); void shutdown(); void executeTask(Runnable runnableTask); ScheduledFuture<?> scheduleTask(Runnable runnableTask, long delay); ScheduledFuture<?> rescheduleTask(ScheduledFuture<?> futureTask, Runnable runnableTask, long delay); ScheduledFuture<?> scheduleTask(Runnable runnableTask, long initialDelay, long period); String getTransportVersionString(); boolean sendCommand(ZigBeeCommand command); void addCommandListener(ZigBeeCommandListener commandListener); void removeCommandListener(ZigBeeCommandListener commandListener); @Override void receiveCommand(final ZigBeeApsFrame incomingApsFrame); void createDefaultResponse(ZigBeeApsFrame apsFrame, ZclHeader zclHeader, ZclStatus status); void addAnnounceListener(ZigBeeAnnounceListener announceListener); void removeAnnounceListener(ZigBeeAnnounceListener announceListener); @Override void nodeStatusUpdate(final ZigBeeNodeStatus deviceStatus, final Integer networkAddress,
            final IeeeAddress ieeeAddress); void addNetworkStateListener(ZigBeeNetworkStateListener stateListener); void removeNetworkStateListener(ZigBeeNetworkStateListener stateListener); @Override synchronized void setTransportState(final ZigBeeTransportState state); ZigBeeStatus permitJoin(final int duration); ZigBeeStatus permitJoin(final ZigBeeEndpointAddress destination, final int duration); void leave(final Integer destinationAddress, final IeeeAddress leaveAddress); void leave(final Integer destinationAddress, final IeeeAddress leaveAddress, boolean forceNodeRemoval); void addGroup(final ZigBeeGroupAddress group); void updateGroup(ZigBeeGroupAddress group); ZigBeeGroupAddress getGroup(final int groupId); void removeGroup(final int groupId); List<ZigBeeGroupAddress> getGroups(); void addNetworkNodeListener(final ZigBeeNetworkNodeListener networkNodeListener); void removeNetworkNodeListener(final ZigBeeNetworkNodeListener networkNodeListener); void rediscoverNode(IeeeAddress address); Set<ZigBeeNode> getNodes(); ZigBeeNode getNode(final Integer networkAddress); ZigBeeNode getNode(final IeeeAddress ieeeAddress); void removeNode(final ZigBeeNode node); void updateNode(final ZigBeeNode node); @Deprecated void addSupportedCluster(int cluster); ZigBeeStatus addSupportedClientCluster(int cluster); ZigBeeStatus addSupportedServerCluster(int cluster); boolean isClientClusterSupported(int cluster); boolean isServerClusterSupported(int cluster); ZigBeeStatus addExtension(ZigBeeNetworkExtension extension); ZigBeeNetworkExtension getExtension(Class<T> requestedExtension); ZigBeeNetworkState getNetworkState(); IeeeAddress getLocalIeeeAddress(); Integer getLocalNwkAddress(); NotificationService getNotificationService(); void sendTransaction(ZigBeeCommand command); Future<CommandResult> sendTransaction(ZigBeeCommand command, ZigBeeTransactionMatcher responseMatcher); @Override void receiveCommandState(int msgTag, ZigBeeTransportProgressState state); }
ZigBeeNetworkManager implements ZigBeeTransportReceive { private ZigBeeCommand receiveZclCommand(final ZclFieldDeserializer fieldDeserializer, final ZigBeeApsFrame apsFrame) { if (apsFrame.getDestinationEndpoint() != localEndpointId && apsFrame.getDestinationEndpoint() != BROADCAST_ENDPOINT_ID) { logger.debug("Unknown local endpoint for APS frame {}", apsFrame); return null; } ZclHeader zclHeader = new ZclHeader(fieldDeserializer); logger.debug("RX ZCL: {}", zclHeader); ZigBeeNode node = getNode(apsFrame.getSourceAddress()); if (node == null) { logger.debug("Unknown remote node {}", String.format("%04X", apsFrame.getSourceAddress())); return null; } ZigBeeEndpoint endpoint = node.getEndpoint(apsFrame.getSourceEndpoint()); if (endpoint == null) { logger.debug("{}: Endpoint {}. Unknown remote endpoint", node.getIeeeAddress(), apsFrame.getSourceEndpoint()); return null; } ZclCommand command; if (zclHeader.getDirection() == ZclCommandDirection.SERVER_TO_CLIENT) { if (!isClientClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local client cluster {}", String.format("%04X", apsFrame.getCluster())); } ZclCluster cluster = endpoint.getInputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown input cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setInputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown input cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getInputCluster(apsFrame.getCluster()); } command = cluster.getResponseFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } else { if (!isServerClusterSupported(apsFrame.getCluster())) { logger.debug("Unsupported local server cluster {}", String.format("%04X", apsFrame.getCluster())); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } ZclCluster cluster = endpoint.getOutputCluster(apsFrame.getCluster()); if (cluster == null) { logger.debug("{}: Endpoint {}. Unknown output cluster {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster())); ZigBeeNode newNode = new ZigBeeNode(this, node.getIeeeAddress()); ZigBeeEndpoint newEndpoint = new ZigBeeEndpoint(node, endpoint.getEndpointId()); newEndpoint.setOutputClusterIds(Collections.singletonList(apsFrame.getCluster())); newEndpoint.updateEndpoint(newEndpoint); newNode.addEndpoint(newEndpoint); try { boolean state = refreshNode(newNode).get(); logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node complete state {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), state); } catch (InterruptedException | ExecutionException e) { logger.debug("{}: Endpoint {}. Unknown output cluster {} updated node failed with {}", node.getIeeeAddress(), endpoint.getEndpointId(), String.format("%04X", apsFrame.getCluster()), e.getClass().getSimpleName()); } cluster = endpoint.getOutputCluster(apsFrame.getCluster()); } command = cluster.getCommandFromId(zclHeader.getFrameType(), zclHeader.getCommandId()); } if (command == null) { logger.debug("{}: Unknown command {}", node.getIeeeAddress(), zclHeader.getCommandId()); createDefaultResponse(apsFrame, zclHeader, ZclStatus.FAILURE); return null; } command.setCommandDirection(zclHeader.getDirection()); command.deserialize(fieldDeserializer); command.setClusterId(apsFrame.getCluster()); command.setTransactionId(zclHeader.getSequenceNumber()); command.setDisableDefaultResponse(zclHeader.isDisableDefaultResponse()); return command; } ZigBeeNetworkManager(final ZigBeeTransportTransmit transport); void setNetworkDataStore(ZigBeeNetworkDataStore dataStore); void serializeNetworkDataStore(IeeeAddress nodeAddress); @SuppressWarnings("unchecked") void setSerializer(Class<?> serializer, Class<?> deserializer); void setLocalEndpointId(int localEndpointId); ZigBeeStatus initialize(); ZigBeeTransportTransmit getZigBeeTransport(); ZigBeeChannel getZigBeeChannel(); ZigBeeStatus setZigBeeChannel(ZigBeeChannel channel); int getZigBeePanId(); ZigBeeStatus setZigBeePanId(int panId); ExtendedPanId getZigBeeExtendedPanId(); ZigBeeStatus setZigBeeExtendedPanId(ExtendedPanId panId); ZigBeeStatus setDefaultProfileId(int defaultProfileId); ZigBeeStatus setDefaultDeviceId(int defaultDeviceId); ZigBeeStatus setZigBeeNetworkKey(final ZigBeeKey key); ZigBeeKey getZigBeeNetworkKey(); ZigBeeStatus setZigBeeLinkKey(final ZigBeeKey key); ZigBeeKey getZigBeeLinkKey(); ZigBeeStatus setZigBeeInstallKey(final ZigBeeKey key); ZigBeeStatus startup(boolean reinitialize); ZigBeeStatus reinitialize(); void shutdown(); void executeTask(Runnable runnableTask); ScheduledFuture<?> scheduleTask(Runnable runnableTask, long delay); ScheduledFuture<?> rescheduleTask(ScheduledFuture<?> futureTask, Runnable runnableTask, long delay); ScheduledFuture<?> scheduleTask(Runnable runnableTask, long initialDelay, long period); String getTransportVersionString(); boolean sendCommand(ZigBeeCommand command); void addCommandListener(ZigBeeCommandListener commandListener); void removeCommandListener(ZigBeeCommandListener commandListener); @Override void receiveCommand(final ZigBeeApsFrame incomingApsFrame); void createDefaultResponse(ZigBeeApsFrame apsFrame, ZclHeader zclHeader, ZclStatus status); void addAnnounceListener(ZigBeeAnnounceListener announceListener); void removeAnnounceListener(ZigBeeAnnounceListener announceListener); @Override void nodeStatusUpdate(final ZigBeeNodeStatus deviceStatus, final Integer networkAddress,
            final IeeeAddress ieeeAddress); void addNetworkStateListener(ZigBeeNetworkStateListener stateListener); void removeNetworkStateListener(ZigBeeNetworkStateListener stateListener); @Override synchronized void setTransportState(final ZigBeeTransportState state); ZigBeeStatus permitJoin(final int duration); ZigBeeStatus permitJoin(final ZigBeeEndpointAddress destination, final int duration); void leave(final Integer destinationAddress, final IeeeAddress leaveAddress); void leave(final Integer destinationAddress, final IeeeAddress leaveAddress, boolean forceNodeRemoval); void addGroup(final ZigBeeGroupAddress group); void updateGroup(ZigBeeGroupAddress group); ZigBeeGroupAddress getGroup(final int groupId); void removeGroup(final int groupId); List<ZigBeeGroupAddress> getGroups(); void addNetworkNodeListener(final ZigBeeNetworkNodeListener networkNodeListener); void removeNetworkNodeListener(final ZigBeeNetworkNodeListener networkNodeListener); void rediscoverNode(IeeeAddress address); Set<ZigBeeNode> getNodes(); ZigBeeNode getNode(final Integer networkAddress); ZigBeeNode getNode(final IeeeAddress ieeeAddress); void removeNode(final ZigBeeNode node); void updateNode(final ZigBeeNode node); @Deprecated void addSupportedCluster(int cluster); ZigBeeStatus addSupportedClientCluster(int cluster); ZigBeeStatus addSupportedServerCluster(int cluster); boolean isClientClusterSupported(int cluster); boolean isServerClusterSupported(int cluster); ZigBeeStatus addExtension(ZigBeeNetworkExtension extension); ZigBeeNetworkExtension getExtension(Class<T> requestedExtension); ZigBeeNetworkState getNetworkState(); IeeeAddress getLocalIeeeAddress(); Integer getLocalNwkAddress(); NotificationService getNotificationService(); void sendTransaction(ZigBeeCommand command); Future<CommandResult> sendTransaction(ZigBeeCommand command, ZigBeeTransactionMatcher responseMatcher); @Override void receiveCommandState(int msgTag, ZigBeeTransportProgressState state);  }