Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix change detection for node tables #1315

Merged
merged 1 commit into from Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -93,21 +93,41 @@ public class ZigBeeNode {
*/
private final Set<Integer> associatedDevices = new HashSet<Integer>();

/**
* Boolean used to allow change detection on the table
*/
private boolean associatedDevicesSet = false;

/**
* List of neighbors for the node, specified in a {@link NeighborTable}
*/
private final Set<NeighborTable> neighbors = new HashSet<NeighborTable>();

/**
* Boolean used to allow change detection on the table
*/
private boolean neighborsSet = false;

/**
* List of routes within the node, specified in a {@link RoutingTable}
*/
private final Set<RoutingTable> routes = new HashSet<RoutingTable>();

/**
* Boolean used to allow change detection on the table
*/
private boolean routesSet = false;

/**
* List of binding records
*/
private final Set<BindingTable> bindingTable = new HashSet<BindingTable>();

/**
* Boolean used to allow change detection on the table
*/
private boolean bindingTableSet = false;

/**
* List of endpoints this node exposes
*/
Expand Down Expand Up @@ -401,6 +421,7 @@ public LogicalType getLogicalType() {

private void setBindingTable(List<BindingTable> bindingTable) {
synchronized (this.bindingTable) {
bindingTableSet = true;
this.bindingTable.clear();
this.bindingTable.addAll(bindingTable);
logger.debug("{}: Binding table updated: {}", ieeeAddress, bindingTable);
Expand Down Expand Up @@ -619,6 +640,7 @@ public boolean setNeighbors(Set<NeighborTable> neighbors) {
}

synchronized (this.neighbors) {
neighborsSet = true;
this.neighbors.clear();
if (neighbors != null) {
this.neighbors.addAll(neighbors);
Expand Down Expand Up @@ -656,6 +678,7 @@ public boolean setAssociatedDevices(Set<Integer> associatedDevices) {
}

synchronized (this.associatedDevices) {
associatedDevicesSet = true;
this.associatedDevices.clear();
this.associatedDevices.addAll(associatedDevices);
}
Expand Down Expand Up @@ -693,6 +716,7 @@ public boolean setRoutes(Set<RoutingTable> routes) {
}

synchronized (this.routes) {
routesSet = true;
this.routes.clear();
if (routes != null) {
this.routes.addAll(routes);
Expand Down Expand Up @@ -786,64 +810,72 @@ protected boolean updateNode(ZigBeeNode node) {
boolean updated = false;

if (node.getNodeState() != ZigBeeNodeState.UNKNOWN && nodeState != node.getNodeState()) {
logger.debug("{}: Node state updated from {} to {}", ieeeAddress, nodeState, node.getNodeState());
logger.debug("{}: Node state updated FROM {} TO {}", ieeeAddress, nodeState, node.getNodeState());
nodeState = node.getNodeState();
updated = true;
}

if (node.getNetworkAddress() != null
&& (networkAddress == null || !networkAddress.equals(node.getNetworkAddress()))) {
logger.debug("{}: Network address updated from {} to {}", ieeeAddress, networkAddress,
logger.debug("{}: Network address updated FROM {} TO {}", ieeeAddress, networkAddress,
node.getNetworkAddress());
updated = true;
networkAddress = node.getNetworkAddress();
}

if (node.getNodeDescriptor() != null
&& (nodeDescriptor == null || !nodeDescriptor.equals(node.getNodeDescriptor()))) {
logger.debug("{}: Node descriptor updated", ieeeAddress);
logger.debug("{}: Node descriptor updated FROM {} TO {}", ieeeAddress, nodeDescriptor,
node.getNodeDescriptor());
updated = true;
nodeDescriptor = node.getNodeDescriptor();
}

if (node.getPowerDescriptor() != null
&& (powerDescriptor == null || !powerDescriptor.equals(node.getPowerDescriptor()))) {
logger.debug("{}: Power descriptor updated", ieeeAddress);
logger.debug("{}: Power descriptor updated FROM {} TO {}", ieeeAddress, powerDescriptor,
node.getPowerDescriptor());
updated = true;
powerDescriptor = node.getPowerDescriptor();
}

synchronized (associatedDevices) {
if (!associatedDevices.equals(node.getAssociatedDevices())) {
logger.debug("{}: Associated devices updated", ieeeAddress);
if (node.associatedDevicesSet && !associatedDevices.equals(node.getAssociatedDevices())) {
logger.debug("{}: Associated devices updated FROM {} TO {}", ieeeAddress, associatedDevices,
node.getAssociatedDevices());
updated = true;
associatedDevicesSet = true;
associatedDevices.clear();
associatedDevices.addAll(node.getAssociatedDevices());
}
}

synchronized (bindingTable) {
if (!bindingTable.equals(node.getBindingTable())) {
logger.debug("{}: Binding table updated", ieeeAddress);
if (node.bindingTableSet && !bindingTable.equals(node.getBindingTable())) {
logger.debug("{}: Binding table updated FROM {} TO {}", ieeeAddress, bindingTable,
node.getBindingTable());
updated = true;
bindingTableSet = true;
bindingTable.clear();
bindingTable.addAll(node.getBindingTable());
}
}

synchronized (neighbors) {
if (!neighbors.equals(node.getNeighbors())) {
logger.debug("{}: Neighbors updated", ieeeAddress);
if (node.neighborsSet && !neighbors.equals(node.getNeighbors())) {
logger.debug("{}: Neighbors updated FROM {} TO {}", ieeeAddress, neighbors, node.getNeighbors());
updated = true;
neighborsSet = true;
neighbors.clear();
neighbors.addAll(node.getNeighbors());
}
}

synchronized (routes) {
if (!routes.equals(node.getRoutes())) {
logger.debug("{}: Routes updated", ieeeAddress);
if (node.routesSet && !routes.equals(node.getRoutes())) {
logger.debug("{}: Routes updated FROM {} TO {}", ieeeAddress, routes, node.getRoutes());
updated = true;
routesSet = true;
routes.clear();
routes.addAll(node.getRoutes());
}
Expand Down
Expand Up @@ -265,8 +265,9 @@ public boolean equals(Object obj) {
@Override
public String toString() {
return "NeighborTable [extendedPanId=" + extendedPanId + ", extendedAddress=" + extendedAddress
+ ", networkAddress=" + networkAddress + ", deviceType=" + deviceType + ", rxOnWhenIdle=" + rxOnWhenIdle
+ ", relationship=" + relationship + ", permitJoining=" + permitJoining + ", depth=" + depth + ", lqi="
+ ", networkAddress=" + String.format("%04X", networkAddress) + ", deviceType=" + deviceType
+ ", rxOnWhenIdle=" + rxOnWhenIdle + ", relationship=" + relationship + ", permitJoining="
+ permitJoining + ", depth=" + depth + ", lqi="
+ lqi + "]";
}

Expand Down
Expand Up @@ -130,6 +130,8 @@ public void testNeighborTableUpdate() {
ZigBeeNode node = new ZigBeeNode(getMocketNetworkManager(), new IeeeAddress());
Set<NeighborTable> neighbors;

assertTrue(node.getNeighbors().isEmpty());

NeighborTable neighbor1 = getNeighborTable(12345, "123456789", 0);
NeighborTable neighbor2 = getNeighborTable(12345, "123456789", 0);
NeighborTable neighbor3 = getNeighborTable(54321, "987654321", 0);
Expand Down Expand Up @@ -442,9 +444,17 @@ public void testUpdated() throws Exception {
assertEquals(0, node.getBindingTable().size());
newNode = new ZigBeeNode(getMocketNetworkManager(), new IeeeAddress("1234567890"));
TestUtilities.setField(ZigBeeNode.class, newNode, "bindingTable", bindingTable);
assertFalse(node.updateNode(newNode));
assertEquals(0, node.getBindingTable().size());

TestUtilities.setField(ZigBeeNode.class, newNode, "bindingTableSet", true);
assertTrue(node.updateNode(newNode));
assertEquals(1, node.getBindingTable().size());

newNode = new ZigBeeNode(getMocketNetworkManager(), new IeeeAddress("1234567890"));
assertFalse(node.updateNode(newNode));
assertEquals(1, node.getBindingTable().size());

Set<RoutingTable> routeTable = new HashSet<RoutingTable>();
routeTable.add(new RoutingTable());
assertEquals(0, node.getRoutes().size());
Expand Down