From 5d07e9fd7a17f969981761a1f94666d9fe03b5fd Mon Sep 17 00:00:00 2001 From: Chris Jackson Date: Thu, 3 Oct 2024 16:34:00 +1300 Subject: [PATCH] Update to set IEEE address in Ember NCP Signed-off-by: Chris Jackson --- .../zigbee/console/main/ZigBeeDataStore.java | 42 +++++-- .../ZigBeeConsoleNetworkBackupCommand.java | 52 ++++++-- .../src/main/resources/ezsp_protocol.xml | 44 ++++--- .../zigbee/dongle/ember/EmberNcp.java | 34 +++++ .../zigbee/dongle/ember/ZigBeeDongleEzsp.java | 33 +++++ .../zigbee/dongle/ember/ezsp/EzspFrame.java | 6 +- .../command/EzspBecomeTrustCenterRequest.java | 91 -------------- .../EzspBecomeTrustCenterResponse.java | 78 ------------ .../ezsp/command/EzspResetNodeRequest.java | 57 +++++++++ .../ezsp/command/EzspResetNodeResponse.java | 44 +++++++ .../command/EzspTokenFactoryResetRequest.java | 117 +++++++++++++++++ .../EzspTokenFactoryResetResponse.java | 44 +++++++ .../zigbee/ZigBeeBackupManager.java | 15 ++- .../zigbee/ZigBeeNetworkManager.java | 119 ++++++++++++++++++ .../database/ZigBeeNetworkDataStore.java | 17 +++ .../ZigBeeNetworkDatabaseManager.java | 13 ++ .../transport/ZigBeeTransportTransmit.java | 36 ++++++ 17 files changed, 625 insertions(+), 217 deletions(-) delete mode 100644 com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspBecomeTrustCenterRequest.java delete mode 100644 com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspBecomeTrustCenterResponse.java create mode 100644 com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspResetNodeRequest.java create mode 100644 com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspResetNodeResponse.java create mode 100644 com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspTokenFactoryResetRequest.java create mode 100644 com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspTokenFactoryResetResponse.java diff --git a/com.zsmartsystems.zigbee.console.main/src/main/java/com/zsmartsystems/zigbee/console/main/ZigBeeDataStore.java b/com.zsmartsystems.zigbee.console.main/src/main/java/com/zsmartsystems/zigbee/console/main/ZigBeeDataStore.java index 317346faa..f520639d1 100644 --- a/com.zsmartsystems.zigbee.console.main/src/main/java/com/zsmartsystems/zigbee/console/main/ZigBeeDataStore.java +++ b/com.zsmartsystems.zigbee.console.main/src/main/java/com/zsmartsystems/zigbee/console/main/ZigBeeDataStore.java @@ -14,7 +14,6 @@ import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.UUID; @@ -65,9 +64,9 @@ public ZigBeeDataStore(String networkId) { if (!file.exists() && !file.mkdirs()) { logger.error("Error creating network database folder {}", file); } - file = new File(this.networkId + "/" + BACKUP); + file = new File(DATABASE + BACKUP); if (!file.exists() && !file.mkdirs()) { - logger.error("Error creating network database folder {}", file); + logger.error("Error creating network backup folder {}", file); } } @@ -151,7 +150,6 @@ public ZigBeeNodeDao readNode(IeeeAddress address) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), CHARSET))) { node = (ZigBeeNodeDao) stream.fromXML(reader); reader.close(); - logger.info("{}: ZigBee reading network state complete.", address); } catch (Exception e) { logger.error("{}: Error reading network state: ", address, e); } @@ -167,7 +165,6 @@ public void writeNode(ZigBeeNodeDao node) { try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), CHARSET))) { stream.marshal(node, new PrettyPrintWriter(writer)); writer.close(); - logger.info("{}: ZigBee saving network state complete.", node.getIeeeAddress()); } catch (Exception e) { logger.error("{}: Error writing network state: ", node.getIeeeAddress(), e); } @@ -189,7 +186,6 @@ public void writeObject(String key, Object object) { try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), CHARSET))) { stream.marshal(object, new PrettyPrintWriter(writer)); writer.close(); - logger.info("{}: ZigBee saving key complete.", key); } catch (Exception e) { logger.error("{}: Error writing key: ", key, e); } @@ -208,12 +204,12 @@ public boolean writeBackup(ZigBeeNetworkBackupDao backup) { try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), CHARSET))) { stream.marshal(backup, new PrettyPrintWriter(writer)); writer.close(); - logger.info("ZigBee saving network backup {} complete.", backup.getUuid()); } catch (Exception e) { logger.error("Error writing network backup: ", backup.getUuid(), e); + return false; } - return false; + return true; } @Override @@ -225,7 +221,6 @@ public ZigBeeNetworkBackupDao readBackup(UUID uuid) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), CHARSET))) { backup = (ZigBeeNetworkBackupDao) stream.fromXML(reader); reader.close(); - logger.info("ZigBee reading network backup {} complete.", uuid); } catch (Exception e) { logger.error("{}: Error reading network backup: ", uuid, e); } @@ -235,6 +230,33 @@ public ZigBeeNetworkBackupDao readBackup(UUID uuid) { @Override public Set listBackups() { - return Collections.emptySet(); + Set backups = new HashSet<>(); + File dir = new File(DATABASE + BACKUP); + File[] files = dir.listFiles(); + + if (files == null) { + return backups; + } + + for (File file : files) { + if (!file.getName().toLowerCase().endsWith(".xml")) { + continue; + } + + try { + String filename = file.getName(); + UUID uuid = UUID.fromString(filename.substring(0, filename.length() - 4)); + ZigBeeNetworkBackupDao backup = readBackup(uuid); + for (ZigBeeNodeDao node : backup.getNodes()) { + node.setEndpoints(null); + node.setBindingTable(null); + } + backups.add(backup); + } catch (IllegalArgumentException e) { + logger.error("Error parsing database filename: {}", file.getName()); + } + } + + return backups; } } diff --git a/com.zsmartsystems.zigbee.console/src/main/java/com/zsmartsystems/zigbee/console/ZigBeeConsoleNetworkBackupCommand.java b/com.zsmartsystems.zigbee.console/src/main/java/com/zsmartsystems/zigbee/console/ZigBeeConsoleNetworkBackupCommand.java index 594d0cae2..2dfc02adc 100644 --- a/com.zsmartsystems.zigbee.console/src/main/java/com/zsmartsystems/zigbee/console/ZigBeeConsoleNetworkBackupCommand.java +++ b/com.zsmartsystems.zigbee.console/src/main/java/com/zsmartsystems/zigbee/console/ZigBeeConsoleNetworkBackupCommand.java @@ -8,8 +8,14 @@ package com.zsmartsystems.zigbee.console; import java.io.PrintStream; +import java.util.Map; +import java.util.TreeMap; +import java.util.UUID; import com.zsmartsystems.zigbee.ZigBeeNetworkManager; +import com.zsmartsystems.zigbee.ZigBeeStatus; +import com.zsmartsystems.zigbee.database.ZigBeeNetworkBackupDao; +import com.zsmartsystems.zigbee.database.ZigBeeNodeDao; /** * Console command to backup the network. @@ -47,28 +53,58 @@ public void process(ZigBeeNetworkManager networkManager, String[] args, PrintStr switch (args[1].toUpperCase()) { case "LIST": - listBackups(); + listBackups(out, networkManager); break; case "BACKUP": - createBackup(); + createBackup(out, networkManager); break; case "RESTORE": - restoreBackup(); + restoreBackup(out, networkManager, UUID.fromString(args[2])); break; default: throw new IllegalArgumentException("Unknown option '" + args[1] + "'"); } } - private void listBackups() { + private void listBackups(PrintStream out, ZigBeeNetworkManager networkManager) { + Map sortedBackups = new TreeMap<>(); + for (ZigBeeNetworkBackupDao backup : networkManager.listBackups()) { + sortedBackups.put(backup.getDate().getTime(), backup); + } + out.println( + "DATE UUID PANID EPANID CHANNEL COORDINATOR NODES"); + for (ZigBeeNetworkBackupDao backup : sortedBackups.values()) { + ZigBeeNodeDao coordinator = null; + for (ZigBeeNodeDao node : backup.getNodes()) { + if (node.getNetworkAddress() == 0) { + coordinator = node; + break; + } + } + out.println( + String.format("%s %s %04X %s %s %s %d", backup.getDate().toInstant().toString(), + backup.getUuid(), + backup.getPan(), backup.getEpan(), backup.getChannel(), + (coordinator != null ? coordinator.getIeeeAddress() : " "), + backup.getNodes().size())); + } } - private void createBackup() { - + private void createBackup(PrintStream out, ZigBeeNetworkManager networkManager) { + UUID uuid = networkManager.createBackup(); + if (uuid == null) { + out.println("Error creating backup!!"); + } else { + out.println("Backup created with UUID " + uuid); + } } - private void restoreBackup() { - + private void restoreBackup(PrintStream out, ZigBeeNetworkManager networkManager, UUID uuid) { + if (networkManager.restoreBackup(uuid) == ZigBeeStatus.SUCCESS) { + out.println("Backup restored from " + uuid.toString()); + } else { + out.println("Error restoring backup " + uuid.toString()); + } } } \ No newline at end of file diff --git a/com.zsmartsystems.zigbee.dongle.ember.autocode/src/main/resources/ezsp_protocol.xml b/com.zsmartsystems.zigbee.dongle.ember.autocode/src/main/resources/ezsp_protocol.xml index c524199a8..126b54c50 100644 --- a/com.zsmartsystems.zigbee.dongle.ember.autocode/src/main/resources/ezsp_protocol.xml +++ b/com.zsmartsystems.zigbee.dongle.ember.autocode/src/main/resources/ezsp_protocol.xml @@ -1964,26 +1964,6 @@ - - becomeTrustCenter - 0x77 - This function causes a coordinator to become the Trust Center when it is operating in a network that is not using one. It will send out an updated Network Key to all devices that will indicate a transition of the network to now use a Trust Center. The Trust Center should also switch all devices to using this new network key with the appropriate API. - - - EmberKeyData - newNetworkKey - The key data for the Updated Network Key. - - - - - EmberStatus - status - The response status. - - - - aesMmoHash 0x6F @@ -3916,6 +3896,30 @@ A command which does nothing. The Host can use this to set the sleep mode or check the status of the NCP. + + tokenFactoryReset + 0x0077 + Factory reset all configured Zigbee tokens. + + + bool + excludeOutgoingFC + Exclude network and APS outgoing frame counter tokens. + + + bool + excludeBootCounter + Exclude stack boot counter token. + + + + + + resetNode + 0x0104 + Reset the node by calling halReboot. + + EmberCertificateData The implicit certificate used in CBKE. diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/EmberNcp.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/EmberNcp.java index 2829d53ae..cd33c2365 100644 --- a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/EmberNcp.java +++ b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/EmberNcp.java @@ -132,6 +132,8 @@ import com.zsmartsystems.zigbee.dongle.ember.ezsp.command.EzspSetValueResponse; import com.zsmartsystems.zigbee.dongle.ember.ezsp.command.EzspStartScanRequest; import com.zsmartsystems.zigbee.dongle.ember.ezsp.command.EzspStartScanResponse; +import com.zsmartsystems.zigbee.dongle.ember.ezsp.command.EzspTokenFactoryResetRequest; +import com.zsmartsystems.zigbee.dongle.ember.ezsp.command.EzspTokenFactoryResetResponse; import com.zsmartsystems.zigbee.dongle.ember.ezsp.command.EzspVersionRequest; import com.zsmartsystems.zigbee.dongle.ember.ezsp.command.EzspVersionResponse; import com.zsmartsystems.zigbee.dongle.ember.ezsp.structure.EmberAesMmoHashContext; @@ -1073,6 +1075,16 @@ public IeeeAddress getMfgCustomEui64() { return new IeeeAddress(response); } + /** + * Sets the custom EUI64 (long address) from the manufacturer information block on the NCP + * + * @param address {@link IeeeAddress} containing the custom address + * @return {@link EmberStatus} + */ + public EmberStatus setMfgCustomEui64(IeeeAddress address) { + return setMfgToken(EzspMfgTokenId.EZSP_MFG_CUSTOM_EUI_64, address.getValue()); + } + /** * Gets the install code stored in the NCP memory * @@ -1333,6 +1345,28 @@ public EzspStatus resetToFactoryDefaults() { return response.getStatus(); } + /** + * Factory reset all configured Zigbee tokens. + * + * @param excludeOutgoingFC Exclude network and APS outgoing frame counter tokens. + * @param excludeBootCounter Exclude stack boot counter token. + * @return the response {@link EzspStatus} + */ + public EzspStatus tokenFactoryReset(boolean excludeOutgoingFC, boolean excludeBootCounter) { + EzspTokenFactoryResetRequest request = new EzspTokenFactoryResetRequest(); + request.setExcludeOutgoingFC(excludeOutgoingFC); + request.setExcludeBootCounter(excludeBootCounter); + EzspTransaction transaction = protocolHandler + .sendEzspTransaction( + new EzspSingleResponseTransaction(request, EzspTokenFactoryResetResponse.class)); + EzspTokenFactoryResetResponse response = (EzspTokenFactoryResetResponse) transaction + .getResponse(); + if (response == null) { + return EzspStatus.UNKNOWN; + } + return EzspStatus.EZSP_SUCCESS; + } + private String intArrayToString(int[] payload) { int length = payload.length; for (int cnt = 0; cnt < length; cnt++) { diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ZigBeeDongleEzsp.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ZigBeeDongleEzsp.java index f63ff13b3..c349b56e6 100644 --- a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ZigBeeDongleEzsp.java +++ b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ZigBeeDongleEzsp.java @@ -30,6 +30,7 @@ import com.zsmartsystems.zigbee.ZigBeeDeviceType; import com.zsmartsystems.zigbee.ZigBeeExecutors; import com.zsmartsystems.zigbee.ZigBeeNetworkManager; +import com.zsmartsystems.zigbee.ZigBeeNetworkState; import com.zsmartsystems.zigbee.ZigBeeNodeStatus; import com.zsmartsystems.zigbee.ZigBeeNwkAddressMode; import com.zsmartsystems.zigbee.ZigBeeProfileType; @@ -745,11 +746,43 @@ public IeeeAddress getIeeeAddress() { return ieeeAddress; } + @Override + public boolean setIeeeAddress(IeeeAddress ieeeAddress) { + EmberNcp ncp = getEmberNcp(); + if (ncp.getIeeeAddress().equals(ieeeAddress)) { + // Don't write the IEEE address unless it's different since there are limitations on how many times this can + // be changed in some firmware versions. + return true; + } + return ncp.setMfgCustomEui64(ieeeAddress) == EmberStatus.EMBER_SUCCESS; + } + @Override public Integer getNwkAddress() { return nwkAddress; } + @Override + public ZigBeeStatus setNetworkState(ZigBeeNetworkState networkState) { + EmberNcp ncp = getEmberNcp(); + switch (networkState) { + case UNINITIALISED: + // Reset the NCP to "factory default" + // Note that tokenFactoryReset was introduced in firmware 7.3 (approx) and older versions used the same + // ID for another function. + // We don't check the result here for that reason. + // Note that the impact of this function not working is that the IEEE address can only be written to the + // token area once - subsequent writes will fail, and therefore changing IEEE address (eg from a + // backup/restore) may fail. + ncp.tokenFactoryReset(false, false); + return ncp.leaveNetwork() == EmberStatus.EMBER_SUCCESS ? ZigBeeStatus.SUCCESS : ZigBeeStatus.FAILURE; + case ONLINE: + return ncp.networkInit() == EmberStatus.EMBER_SUCCESS ? ZigBeeStatus.SUCCESS : ZigBeeStatus.FAILURE; + default: + return ZigBeeStatus.INVALID_ARGUMENTS; + } + } + @Override public void sendCommand(final int msgTag, final ZigBeeApsFrame apsFrame) { if (!isConfigured) { diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/EzspFrame.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/EzspFrame.java index 73ec2489f..a5f9edf3b 100644 --- a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/EzspFrame.java +++ b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/EzspFrame.java @@ -95,7 +95,6 @@ public abstract class EzspFrame { protected static final int FRAME_ID_ADD_TRANSIENT_LINK_KEY = 0xAF; protected static final int FRAME_ID_ADDRESS_TABLE_ENTRY_IS_ACTIVE = 0x5B; protected static final int FRAME_ID_AES_MMO_HASH = 0x6F; - protected static final int FRAME_ID_BECOME_TRUST_CENTER = 0x77; protected static final int FRAME_ID_BINDING_IS_ACTIVE = 0x2E; protected static final int FRAME_ID_CALCULATE_SMACS = 0x9F; protected static final int FRAME_ID_CALCULATE_SMACS283K1 = 0xEA; @@ -213,6 +212,7 @@ public abstract class EzspFrame { protected static final int FRAME_ID_REMOTE_SET_BINDING_HANDLER = 0x31; protected static final int FRAME_ID_REMOVE_DEVICE = 0xA8; protected static final int FRAME_ID_REQUEST_LINK_KEY = 0x14; + protected static final int FRAME_ID_RESET_NODE = 0x104; protected static final int FRAME_ID_RESET_TO_FACTORY_DEFAULTS = 0xCC; protected static final int FRAME_ID_SCAN_COMPLETE_HANDLER = 0x1C; protected static final int FRAME_ID_SEND_BROADCAST = 0x36; @@ -248,6 +248,7 @@ public abstract class EzspFrame { protected static final int FRAME_ID_START_SCAN = 0x1A; protected static final int FRAME_ID_STOP_SCAN = 0x1D; protected static final int FRAME_ID_SWITCH_NETWORK_KEY_HANDLER = 0x6E; + protected static final int FRAME_ID_TOKEN_FACTORY_RESET = 0x77; protected static final int FRAME_ID_TRUST_CENTER_JOIN_HANDLER = 0x24; protected static final int FRAME_ID_VERSION = 0x00; protected static final int FRAME_ID_ZIGBEE_KEY_ESTABLISHMENT_HANDLER = 0x9B; @@ -265,7 +266,6 @@ public abstract class EzspFrame { ezspHandlerMap.put(FRAME_ID_ADD_TRANSIENT_LINK_KEY, EzspAddTransientLinkKeyResponse.class); ezspHandlerMap.put(FRAME_ID_ADDRESS_TABLE_ENTRY_IS_ACTIVE, EzspAddressTableEntryIsActiveResponse.class); ezspHandlerMap.put(FRAME_ID_AES_MMO_HASH, EzspAesMmoHashResponse.class); - ezspHandlerMap.put(FRAME_ID_BECOME_TRUST_CENTER, EzspBecomeTrustCenterResponse.class); ezspHandlerMap.put(FRAME_ID_BINDING_IS_ACTIVE, EzspBindingIsActiveResponse.class); ezspHandlerMap.put(FRAME_ID_CALCULATE_SMACS, EzspCalculateSmacsResponse.class); ezspHandlerMap.put(FRAME_ID_CALCULATE_SMACS283K1, EzspCalculateSmacs283k1Response.class); @@ -383,6 +383,7 @@ public abstract class EzspFrame { ezspHandlerMap.put(FRAME_ID_REMOTE_SET_BINDING_HANDLER, EzspRemoteSetBindingHandler.class); ezspHandlerMap.put(FRAME_ID_REMOVE_DEVICE, EzspRemoveDeviceResponse.class); ezspHandlerMap.put(FRAME_ID_REQUEST_LINK_KEY, EzspRequestLinkKeyResponse.class); + ezspHandlerMap.put(FRAME_ID_RESET_NODE, EzspResetNodeResponse.class); ezspHandlerMap.put(FRAME_ID_RESET_TO_FACTORY_DEFAULTS, EzspResetToFactoryDefaultsResponse.class); ezspHandlerMap.put(FRAME_ID_SCAN_COMPLETE_HANDLER, EzspScanCompleteHandler.class); ezspHandlerMap.put(FRAME_ID_SEND_BROADCAST, EzspSendBroadcastResponse.class); @@ -418,6 +419,7 @@ public abstract class EzspFrame { ezspHandlerMap.put(FRAME_ID_START_SCAN, EzspStartScanResponse.class); ezspHandlerMap.put(FRAME_ID_STOP_SCAN, EzspStopScanResponse.class); ezspHandlerMap.put(FRAME_ID_SWITCH_NETWORK_KEY_HANDLER, EzspSwitchNetworkKeyHandler.class); + ezspHandlerMap.put(FRAME_ID_TOKEN_FACTORY_RESET, EzspTokenFactoryResetResponse.class); ezspHandlerMap.put(FRAME_ID_TRUST_CENTER_JOIN_HANDLER, EzspTrustCenterJoinHandler.class); ezspHandlerMap.put(FRAME_ID_VERSION, EzspVersionResponse.class); ezspHandlerMap.put(FRAME_ID_ZIGBEE_KEY_ESTABLISHMENT_HANDLER, EzspZigbeeKeyEstablishmentHandler.class); diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspBecomeTrustCenterRequest.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspBecomeTrustCenterRequest.java deleted file mode 100644 index dd4f151fe..000000000 --- a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspBecomeTrustCenterRequest.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2016-2024 by the respective copyright holders. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.zsmartsystems.zigbee.dongle.ember.ezsp.command; - -import com.zsmartsystems.zigbee.dongle.ember.ezsp.EzspFrameRequest; -import com.zsmartsystems.zigbee.dongle.ember.ezsp.structure.EmberKeyData; -import com.zsmartsystems.zigbee.dongle.ember.internal.serializer.EzspSerializer; - -/** - * Class to implement the Ember EZSP command becomeTrustCenter. - *

- * This function causes a coordinator to become the Trust Center when it is operating in a - * network that is not using one. It will send out an updated Network Key to all devices that will - * indicate a transition of the network to now use a Trust Center. The Trust Center should also - * switch all devices to using this new network key with the appropriate API. - *

- * This class provides methods for processing EZSP commands. - *

- * Note that this code is autogenerated. Manual changes may be overwritten. - * - * @author Chris Jackson - Initial contribution of Java code generator - */ -public class EzspBecomeTrustCenterRequest extends EzspFrameRequest { - public static final int FRAME_ID = 0x77; - - /** - * The key data for the Updated Network Key. - *

- * EZSP type is EmberKeyData - Java type is {@link EmberKeyData} - */ - private EmberKeyData newNetworkKey; - - /** - * Serialiser used to serialise to binary line data - */ - private EzspSerializer serializer; - - /** - * Request constructor - */ - public EzspBecomeTrustCenterRequest() { - frameId = FRAME_ID; - serializer = new EzspSerializer(); - } - - /** - * The key data for the Updated Network Key. - *

- * EZSP type is EmberKeyData - Java type is {@link EmberKeyData} - * - * @return the current newNetworkKey as {@link EmberKeyData} - */ - public EmberKeyData getNewNetworkKey() { - return newNetworkKey; - } - - /** - * The key data for the Updated Network Key. - * - * @param newNetworkKey the newNetworkKey to set as {@link EmberKeyData} - */ - public void setNewNetworkKey(EmberKeyData newNetworkKey) { - this.newNetworkKey = newNetworkKey; - } - - @Override - public int[] serialize() { - // Serialize the header - serializeHeader(serializer); - - // Serialize the fields - serializer.serializeEmberKeyData(newNetworkKey); - return serializer.getPayload(); - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(81); - builder.append("EzspBecomeTrustCenterRequest [networkId="); - builder.append(networkId); - builder.append(", newNetworkKey="); - builder.append(newNetworkKey); - builder.append(']'); - return builder.toString(); - } -} diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspBecomeTrustCenterResponse.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspBecomeTrustCenterResponse.java deleted file mode 100644 index 51638321a..000000000 --- a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspBecomeTrustCenterResponse.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright (c) 2016-2024 by the respective copyright holders. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package com.zsmartsystems.zigbee.dongle.ember.ezsp.command; - -import com.zsmartsystems.zigbee.dongle.ember.ezsp.EzspFrameResponse; -import com.zsmartsystems.zigbee.dongle.ember.ezsp.structure.EmberStatus; - -/** - * Class to implement the Ember EZSP command becomeTrustCenter. - *

- * This function causes a coordinator to become the Trust Center when it is operating in a - * network that is not using one. It will send out an updated Network Key to all devices that will - * indicate a transition of the network to now use a Trust Center. The Trust Center should also - * switch all devices to using this new network key with the appropriate API. - *

- * This class provides methods for processing EZSP commands. - *

- * Note that this code is autogenerated. Manual changes may be overwritten. - * - * @author Chris Jackson - Initial contribution of Java code generator - */ -public class EzspBecomeTrustCenterResponse extends EzspFrameResponse { - public static final int FRAME_ID = 0x77; - - /** - * The response status. - *

- * EZSP type is EmberStatus - Java type is {@link EmberStatus} - */ - private EmberStatus status; - - /** - * Response and Handler constructor - */ - public EzspBecomeTrustCenterResponse(int[] inputBuffer) { - // Super creates deserializer and reads header fields - super(inputBuffer); - - // Deserialize the fields - status = deserializer.deserializeEmberStatus(); - } - - /** - * The response status. - *

- * EZSP type is EmberStatus - Java type is {@link EmberStatus} - * - * @return the current status as {@link EmberStatus} - */ - public EmberStatus getStatus() { - return status; - } - - /** - * The response status. - * - * @param status the status to set as {@link EmberStatus} - */ - public void setStatus(EmberStatus status) { - this.status = status; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(82); - builder.append("EzspBecomeTrustCenterResponse [networkId="); - builder.append(networkId); - builder.append(", status="); - builder.append(status); - builder.append(']'); - return builder.toString(); - } -} diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspResetNodeRequest.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspResetNodeRequest.java new file mode 100644 index 000000000..b3bcee96b --- /dev/null +++ b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspResetNodeRequest.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2016-2024 by the respective copyright holders. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.zsmartsystems.zigbee.dongle.ember.ezsp.command; + +import com.zsmartsystems.zigbee.dongle.ember.ezsp.EzspFrameRequest; +import com.zsmartsystems.zigbee.dongle.ember.internal.serializer.EzspSerializer; + +/** + * Class to implement the Ember EZSP command resetNode. + *

+ * Reset the node by calling halReboot. + *

+ * This class provides methods for processing EZSP commands. + *

+ * Note that this code is autogenerated. Manual changes may be overwritten. + * + * @author Chris Jackson - Initial contribution of Java code generator + */ +public class EzspResetNodeRequest extends EzspFrameRequest { + public static final int FRAME_ID = 0x104; + + /** + * Serialiser used to serialise to binary line data + */ + private EzspSerializer serializer; + + /** + * Request constructor + */ + public EzspResetNodeRequest() { + frameId = FRAME_ID; + serializer = new EzspSerializer(); + } + + @Override + public int[] serialize() { + // Serialize the header + serializeHeader(serializer); + + // Serialize the fields + return serializer.getPayload(); + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(48); + builder.append("EzspResetNodeRequest [networkId="); + builder.append(networkId); + builder.append(']'); + return builder.toString(); + } +} diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspResetNodeResponse.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspResetNodeResponse.java new file mode 100644 index 000000000..c94a34d94 --- /dev/null +++ b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspResetNodeResponse.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2016-2024 by the respective copyright holders. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.zsmartsystems.zigbee.dongle.ember.ezsp.command; + +import com.zsmartsystems.zigbee.dongle.ember.ezsp.EzspFrameResponse; + +/** + * Class to implement the Ember EZSP command resetNode. + *

+ * Reset the node by calling halReboot. + *

+ * This class provides methods for processing EZSP commands. + *

+ * Note that this code is autogenerated. Manual changes may be overwritten. + * + * @author Chris Jackson - Initial contribution of Java code generator + */ +public class EzspResetNodeResponse extends EzspFrameResponse { + public static final int FRAME_ID = 0x104; + + /** + * Response and Handler constructor + */ + public EzspResetNodeResponse(int[] inputBuffer) { + // Super creates deserializer and reads header fields + super(inputBuffer); + + // Deserialize the fields + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(49); + builder.append("EzspResetNodeResponse [networkId="); + builder.append(networkId); + builder.append(']'); + return builder.toString(); + } +} diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspTokenFactoryResetRequest.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspTokenFactoryResetRequest.java new file mode 100644 index 000000000..ac0f4c058 --- /dev/null +++ b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspTokenFactoryResetRequest.java @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2016-2024 by the respective copyright holders. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.zsmartsystems.zigbee.dongle.ember.ezsp.command; + +import com.zsmartsystems.zigbee.dongle.ember.ezsp.EzspFrameRequest; +import com.zsmartsystems.zigbee.dongle.ember.internal.serializer.EzspSerializer; + +/** + * Class to implement the Ember EZSP command tokenFactoryReset. + *

+ * Factory reset all configured Zigbee tokens. + *

+ * This class provides methods for processing EZSP commands. + *

+ * Note that this code is autogenerated. Manual changes may be overwritten. + * + * @author Chris Jackson - Initial contribution of Java code generator + */ +public class EzspTokenFactoryResetRequest extends EzspFrameRequest { + public static final int FRAME_ID = 0x77; + + /** + * Exclude network and APS outgoing frame counter tokens. + *

+ * EZSP type is bool - Java type is {@link boolean} + */ + private boolean excludeOutgoingFC; + + /** + * Exclude stack boot counter token. + *

+ * EZSP type is bool - Java type is {@link boolean} + */ + private boolean excludeBootCounter; + + /** + * Serialiser used to serialise to binary line data + */ + private EzspSerializer serializer; + + /** + * Request constructor + */ + public EzspTokenFactoryResetRequest() { + frameId = FRAME_ID; + serializer = new EzspSerializer(); + } + + /** + * Exclude network and APS outgoing frame counter tokens. + *

+ * EZSP type is bool - Java type is {@link boolean} + * + * @return the current excludeOutgoingFC as {@link boolean} + */ + public boolean getExcludeOutgoingFC() { + return excludeOutgoingFC; + } + + /** + * Exclude network and APS outgoing frame counter tokens. + * + * @param excludeOutgoingFC the excludeOutgoingFC to set as {@link boolean} + */ + public void setExcludeOutgoingFC(boolean excludeOutgoingFC) { + this.excludeOutgoingFC = excludeOutgoingFC; + } + + /** + * Exclude stack boot counter token. + *

+ * EZSP type is bool - Java type is {@link boolean} + * + * @return the current excludeBootCounter as {@link boolean} + */ + public boolean getExcludeBootCounter() { + return excludeBootCounter; + } + + /** + * Exclude stack boot counter token. + * + * @param excludeBootCounter the excludeBootCounter to set as {@link boolean} + */ + public void setExcludeBootCounter(boolean excludeBootCounter) { + this.excludeBootCounter = excludeBootCounter; + } + + @Override + public int[] serialize() { + // Serialize the header + serializeHeader(serializer); + + // Serialize the fields + serializer.serializeBool(excludeOutgoingFC); + serializer.serializeBool(excludeBootCounter); + return serializer.getPayload(); + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(106); + builder.append("EzspTokenFactoryResetRequest [networkId="); + builder.append(networkId); + builder.append(", excludeOutgoingFC="); + builder.append(excludeOutgoingFC); + builder.append(", excludeBootCounter="); + builder.append(excludeBootCounter); + builder.append(']'); + return builder.toString(); + } +} diff --git a/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspTokenFactoryResetResponse.java b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspTokenFactoryResetResponse.java new file mode 100644 index 000000000..72f3f46b9 --- /dev/null +++ b/com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ezsp/command/EzspTokenFactoryResetResponse.java @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2016-2024 by the respective copyright holders. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package com.zsmartsystems.zigbee.dongle.ember.ezsp.command; + +import com.zsmartsystems.zigbee.dongle.ember.ezsp.EzspFrameResponse; + +/** + * Class to implement the Ember EZSP command tokenFactoryReset. + *

+ * Factory reset all configured Zigbee tokens. + *

+ * This class provides methods for processing EZSP commands. + *

+ * Note that this code is autogenerated. Manual changes may be overwritten. + * + * @author Chris Jackson - Initial contribution of Java code generator + */ +public class EzspTokenFactoryResetResponse extends EzspFrameResponse { + public static final int FRAME_ID = 0x77; + + /** + * Response and Handler constructor + */ + public EzspTokenFactoryResetResponse(int[] inputBuffer) { + // Super creates deserializer and reads header fields + super(inputBuffer); + + // Deserialize the fields + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(57); + builder.append("EzspTokenFactoryResetResponse [networkId="); + builder.append(networkId); + builder.append(']'); + return builder.toString(); + } +} diff --git a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeBackupManager.java b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeBackupManager.java index ccf13b1f8..58a5da62e 100644 --- a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeBackupManager.java +++ b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeBackupManager.java @@ -9,12 +9,12 @@ import java.util.Date; import java.util.HashSet; -import java.util.Random; import java.util.Set; import java.util.UUID; import com.zsmartsystems.zigbee.database.ZigBeeNetworkBackupDao; import com.zsmartsystems.zigbee.database.ZigBeeNetworkDataStore; +import com.zsmartsystems.zigbee.database.ZigBeeNetworkDatabaseManager; import com.zsmartsystems.zigbee.database.ZigBeeNodeDao; /** @@ -22,17 +22,17 @@ */ public class ZigBeeBackupManager { private final ZigBeeNetworkManager networkManager; - private final ZigBeeNetworkDataStore dataStore; + private final ZigBeeNetworkDatabaseManager databaseManager; /** * Instantiates the {@link ZigBeeBackupManager} class * * @param networkManager - * @param dataStore + * @param databaseManager */ - public ZigBeeBackupManager(ZigBeeNetworkManager networkManager, ZigBeeNetworkDataStore dataStore) { + public ZigBeeBackupManager(ZigBeeNetworkManager networkManager, ZigBeeNetworkDatabaseManager databaseManager) { this.networkManager = networkManager; - this.dataStore = dataStore; + this.databaseManager = databaseManager; } /** @@ -43,8 +43,7 @@ public ZigBeeBackupManager(ZigBeeNetworkManager networkManager, ZigBeeNetworkDat public UUID createBackup() { ZigBeeNetworkBackupDao backup = new ZigBeeNetworkBackupDao(); - Random random = new Random(); - backup.setUuid(new UUID(random.nextLong(), random.nextLong())); + backup.setUuid(UUID.randomUUID()); backup.setDate(new Date()); backup.setPan(networkManager.getZigBeePanId()); @@ -59,7 +58,7 @@ public UUID createBackup() { } backup.setNodes(nodesDao); - return dataStore.writeBackup(backup) ? backup.getUuid() : null; + return databaseManager.writeBackup(backup) ? backup.getUuid() : null; } /** diff --git a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeNetworkManager.java b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeNetworkManager.java index e6f90e251..19fd880e0 100644 --- a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeNetworkManager.java +++ b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeNetworkManager.java @@ -13,11 +13,13 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; @@ -36,8 +38,10 @@ import com.zsmartsystems.zigbee.app.discovery.ZigBeeDiscoveryExtension; import com.zsmartsystems.zigbee.aps.ApsDataEntity; import com.zsmartsystems.zigbee.aps.ZigBeeApsFrame; +import com.zsmartsystems.zigbee.database.ZigBeeNetworkBackupDao; import com.zsmartsystems.zigbee.database.ZigBeeNetworkDataStore; import com.zsmartsystems.zigbee.database.ZigBeeNetworkDatabaseManager; +import com.zsmartsystems.zigbee.database.ZigBeeNodeDao; import com.zsmartsystems.zigbee.groups.ZigBeeGroup; import com.zsmartsystems.zigbee.groups.ZigBeeNetworkGroupManager; import com.zsmartsystems.zigbee.groups.ZigBeeNetworkGroupManager.GroupSynchronizationMethod; @@ -2048,4 +2052,119 @@ public void receiveCommandState(int msgTag, ZigBeeTransportProgressState state) transactionManager.receiveCommandState(msgTag, state); } } + + /** + * Creates a backup of the {@link ZigBeeNetworkManager}, storing it in the {@link ZigBeeNetworkDataStore} + * + * @return a unique {@link UUID} referencing the backup + */ + public UUID createBackup() { + ZigBeeNetworkBackupDao backup = new ZigBeeNetworkBackupDao(); + + backup.setUuid(UUID.randomUUID()); + backup.setDate(new Date()); + + backup.setPan(getZigBeePanId()); + backup.setEpan(getZigBeeExtendedPanId()); + backup.setChannel(getZigBeeChannel()); + backup.setNetworkKey(getZigBeeNetworkKey()); + backup.setLinkKey(getZigBeeLinkKey()); + + Set nodesDao = new HashSet<>(); + for (ZigBeeNode node : getNodes()) { + nodesDao.add(node.getDao()); + } + backup.setNodes(nodesDao); + + return databaseManager.writeBackup(backup) ? backup.getUuid() : null; + } + + /** + * Restores the backup referenced from the provided {@link UUID}. + * + * @param uuid the unique {@link UUID} referencing the backup to restore + * @return ZigBeeStatus.SUCCESS if the backup was restored + */ + public ZigBeeStatus restoreBackup(UUID uuid) { + ZigBeeNetworkBackupDao backup = databaseManager.readBackup(uuid); + if (backup == null) { + logger.debug("Unable to restore from backup {}", uuid); + return ZigBeeStatus.INVALID_ARGUMENTS; + } + + switch (getNetworkState()) { + case UNINITIALISED: + break; + case INITIALISING: + break; + case ONLINE: + break; + case OFFLINE: + break; + case SHUTDOWN: + break; + default: + break; + } + + // Take the network offline for reconfiguration + transport.setNetworkState(ZigBeeNetworkState.UNINITIALISED); + + // To properly re-add nodes, we must be INITIALIZING + // To call startup, we must be INITIALIZING + // Setting the state to INITIALIZING should also stop listeners receiving + // notifications as the nodes are removed and added. + setNetworkState(ZigBeeNetworkState.INITIALISING); + + // Find the coordinator + ZigBeeNodeDao coordinator = null; + for (ZigBeeNodeDao node : backup.getNodes()) { + if (node.getNetworkAddress() == 0) { + coordinator = node; + break; + } + } + + // Set the coordinator address + if (coordinator != null) { + transport.setIeeeAddress(coordinator.getIeeeAddress()); + transport.setNwkAddress(coordinator.getNetworkAddress()); + } + + // Set the network configuration + setZigBeePanId(backup.getPan()); + setZigBeeExtendedPanId(backup.getEpan()); + setZigBeeChannel(backup.getChannel()); + setZigBeeNetworkKey(backup.getNetworkKey()); + setZigBeeLinkKey(backup.getLinkKey()); + + // Remove all existing nodes + for (ZigBeeNode node : networkNodes.values()) { + removeNode(node); + } + + // Clear the data store + databaseManager.clear(); + + // Restore + for (ZigBeeNodeDao nodeDao : backup.getNodes()) { + ZigBeeNode node = new ZigBeeNode(this, nodeDao.getIeeeAddress()); + node.setDao(nodeDao); + logger.debug("{}: Data store: Node was restored from backup.", node.getIeeeAddress()); + updateNode(node); + } + + return startup(true); + } + + /** + * Returns a list of all backups found on the system (ie in the {@link ZigBeeDataStore}). + * The returned Set of {@link ZigBeeNetworkBackupDao} contains only the network information, and not all the + * {@link ZigBeeNode} data + * + * @return Set of {@link ZigBeeNetworkBackupDao} containing the network information + */ + public Set listBackups() { + return databaseManager.listBackups(); + } } diff --git a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/database/ZigBeeNetworkDataStore.java b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/database/ZigBeeNetworkDataStore.java index 5d7d43afa..d4a1305a6 100644 --- a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/database/ZigBeeNetworkDataStore.java +++ b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/database/ZigBeeNetworkDataStore.java @@ -88,14 +88,31 @@ default Object readObject(String key) { return null; } + /** + * Writes a {@link ZigBeeNetworkBackupDao} to the data store + * + * @param backup + * @return + */ default boolean writeBackup(ZigBeeNetworkBackupDao backup) { return false; } + /** + * Reads a {@link ZigBeeNetworkBackupDao} from the data store + * + * @param uuid the {@link UUID} of the backup + * @return the restored {@link ZigBeeNetworkBackupDao} or null + */ default ZigBeeNetworkBackupDao readBackup(UUID uuid) { return null; } + /** + * Returns a summary of all backups in the system. + * + * @return A {@link Set} of {@link ZigBeeNetworkBackupDao} containing at least the network information + */ default Set listBackups() { return Collections.emptySet(); } diff --git a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/database/ZigBeeNetworkDatabaseManager.java b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/database/ZigBeeNetworkDatabaseManager.java index 323867303..6e93bd244 100644 --- a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/database/ZigBeeNetworkDatabaseManager.java +++ b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/database/ZigBeeNetworkDatabaseManager.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -308,4 +309,16 @@ public void writeKey(String key, Object value) { dataStore.writeObject(key, value); } + public boolean writeBackup(ZigBeeNetworkBackupDao backup) { + return dataStore.writeBackup(backup); + } + + public ZigBeeNetworkBackupDao readBackup(UUID uuid) { + return dataStore.readBackup(uuid); + } + + public Set listBackups() { + return dataStore.listBackups(); + } + } diff --git a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/transport/ZigBeeTransportTransmit.java b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/transport/ZigBeeTransportTransmit.java index 47bcad152..c3408b043 100644 --- a/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/transport/ZigBeeTransportTransmit.java +++ b/com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/transport/ZigBeeTransportTransmit.java @@ -10,6 +10,7 @@ import com.zsmartsystems.zigbee.ExtendedPanId; import com.zsmartsystems.zigbee.IeeeAddress; import com.zsmartsystems.zigbee.ZigBeeChannel; +import com.zsmartsystems.zigbee.ZigBeeNetworkState; import com.zsmartsystems.zigbee.ZigBeeStatus; import com.zsmartsystems.zigbee.aps.ZigBeeApsFrame; import com.zsmartsystems.zigbee.security.ZigBeeKey; @@ -80,6 +81,18 @@ public interface ZigBeeTransportTransmit { */ IeeeAddress getIeeeAddress(); + /** + * Sets the {@link IeeeAddress}. Not all devices may allow the address to be set. + * + * This is used to restore the network. + * + * @param ieeeAddress the {@link IeeeAddress} to set + * @return true if the address was set + */ + default boolean setIeeeAddress(IeeeAddress ieeeAddress) { + return false; + } + /** * Returns the network address of the local device * @@ -87,6 +100,18 @@ public interface ZigBeeTransportTransmit { */ Integer getNwkAddress(); + /** + * Sets the network address. Not all devices may allow the address to be set. + * + * This is used to restore the network. + * + * @param networkAddress the address to set + * @return true if the address was set + */ + default boolean setNwkAddress(int networkAddress) { + return false; + } + /** * Sends ZigBee Cluster Library command without waiting for response. Responses are provided to the framework * through the {@link ZigBeeTransportReceive#receiveCommand(ZigBeeApsFrame)} callback. @@ -239,4 +264,15 @@ default void setDefaultLocalEndpointId(int localEndpointId) { */ default void setNodeDescriptor(IeeeAddress ieeeAddress, NodeDescriptor nodeDescriptor) { } + + /** + * Allows the network manager to set the state of the dongle. This allows the network to be taken offline for + * reconfiguration. + * + * @param networkState the {@link ZigBeeNetworkState} to set the network + * @return {@link ZigBeeStatus} with the status of function + */ + default ZigBeeStatus setNetworkState(ZigBeeNetworkState networkState) { + return ZigBeeStatus.UNSUPPORTED; + } }