Skip to content

Commit

Permalink
Update bind request to return ZigBeeStatus and allow NOT_SUPPORTED (#629
Browse files Browse the repository at this point in the history
)

Signed-off-by: Chris Jackson <chris@cd-jackson.com>
  • Loading branch information
cdjackson authored May 14, 2019
1 parent aae295c commit b9c93a3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.zsmartsystems.zigbee.IeeeAddress;
import com.zsmartsystems.zigbee.ZigBeeNetworkManager;
import com.zsmartsystems.zigbee.ZigBeeNode;
import com.zsmartsystems.zigbee.ZigBeeStatus;
import com.zsmartsystems.zigbee.zcl.protocol.ZclClusterType;
import com.zsmartsystems.zigbee.zdo.field.BindingTable;

Expand Down Expand Up @@ -52,9 +53,9 @@ public void process(ZigBeeNetworkManager networkManager, String[] args, PrintStr

ZigBeeNode node = getNode(networkManager, args[1]);

final Boolean result = node.updateBindingTable().get();
if (!result) {
out.println("Binding table read error");
final ZigBeeStatus result = node.updateBindingTable().get();
if (result != ZigBeeStatus.SUCCESS) {
out.println("Binding table read error: " + result);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.zsmartsystems.zigbee.internal.NotificationService;
import com.zsmartsystems.zigbee.transaction.ZigBeeTransactionMatcher;
import com.zsmartsystems.zigbee.zcl.ZclCommand;
import com.zsmartsystems.zigbee.zdo.ZdoStatus;
import com.zsmartsystems.zigbee.zdo.command.ManagementBindRequest;
import com.zsmartsystems.zigbee.zdo.command.ManagementBindResponse;
import com.zsmartsystems.zigbee.zdo.command.ManagementPermitJoiningRequest;
Expand Down Expand Up @@ -353,29 +354,38 @@ public Set<BindingTable> getBindingTable() {
/**
* Request an update of the binding table for this node.
* <p>
* This method returns a future to a boolean. Upon success the caller should call {@link #getBindingTable()}
* This method returns a future to a {@link ZigBeeStatus}. Upon success the caller should call
* {@link #getBindingTable()}
* <p>
* Note that some devices will not support this command and the method will return ZigBeeStatus.UNSUPPORTED
*
* @return {@link Future} returning a {@link Boolean}
* @return {@link Future} returning a {@link ZigBeeStatus}
*/
public Future<Boolean> updateBindingTable() {
RunnableFuture<Boolean> future = new FutureTask<Boolean>(new Callable<Boolean>() {
public Future<ZigBeeStatus> updateBindingTable() {
RunnableFuture<ZigBeeStatus> future = new FutureTask<ZigBeeStatus>(new Callable<ZigBeeStatus>() {
@Override
public Boolean call() throws Exception {
public ZigBeeStatus call() throws Exception {
int index = 0;
int tableSize = 0;
List<BindingTable> bindingTable = new ArrayList<BindingTable>();
List<BindingTable> bindingTable = new ArrayList<>();

do {
ManagementBindRequest bindingRequest = new ManagementBindRequest();
bindingRequest.setDestinationAddress(new ZigBeeEndpointAddress(networkAddress));
bindingRequest.setStartIndex(index);

CommandResult result = network.sendTransaction(bindingRequest, new ManagementBindRequest()).get();
if (result.isError()) {
return false;
if (result.isTimeout()) {
return ZigBeeStatus.FAILURE;
}

ManagementBindResponse response = (ManagementBindResponse) result.getResponse();

// Some devices do not support reading the binding table
if (response.getStatus() == ZdoStatus.NOT_SUPPORTED) {
return ZigBeeStatus.UNSUPPORTED;
}

if (response.getStartIndex() == index) {
tableSize = response.getBindingTableEntries();
index += response.getBindingTableList().size();
Expand All @@ -384,7 +394,7 @@ public Boolean call() throws Exception {
} while (index < tableSize);

setBindingTable(bindingTable);
return true;
return ZigBeeStatus.SUCCESS;
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,28 @@
import static org.junit.Assert.assertTrue;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.junit.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import com.zsmartsystems.zigbee.ZigBeeNode.ZigBeeNodeState;
import com.zsmartsystems.zigbee.serialization.DefaultDeserializer;
import com.zsmartsystems.zigbee.transaction.ZigBeeTransactionFuture;
import com.zsmartsystems.zigbee.transaction.ZigBeeTransactionMatcher;
import com.zsmartsystems.zigbee.zcl.ZclCommand;
import com.zsmartsystems.zigbee.zdo.ZdoCommand;
import com.zsmartsystems.zigbee.zdo.ZdoCommandType;
import com.zsmartsystems.zigbee.zdo.ZdoStatus;
import com.zsmartsystems.zigbee.zdo.command.ManagementBindResponse;
import com.zsmartsystems.zigbee.zdo.field.NeighborTable;
import com.zsmartsystems.zigbee.zdo.field.NodeDescriptor;
import com.zsmartsystems.zigbee.zdo.field.NodeDescriptor.LogicalType;
Expand Down Expand Up @@ -466,4 +477,35 @@ public void setNodeState() {
assertFalse(node.setNodeState(ZigBeeNodeState.OFFLINE));
assertEquals(ZigBeeNodeState.OFFLINE, node.getNodeState());
}

@Test
public void updateBindingTable() throws InterruptedException, ExecutionException {
ZigBeeNetworkManager networkManager = Mockito.mock(ZigBeeNetworkManager.class);
Map<Integer, ZigBeeCommand> responses = new HashMap<Integer, ZigBeeCommand>();

Mockito.doAnswer(new Answer<Future<CommandResult>>() {
@Override
public Future<CommandResult> answer(InvocationOnMock invocation) {
ZigBeeCommand command = (ZigBeeCommand) invocation.getArguments()[0];

ZigBeeTransactionFuture commandFuture = new ZigBeeTransactionFuture();
CommandResult result = new CommandResult(responses.get(command.getClusterId()));
commandFuture.set(result);
return commandFuture;
}
}).when(networkManager).sendTransaction(ArgumentMatchers.any(ZigBeeCommand.class),
ArgumentMatchers.any(ZigBeeTransactionMatcher.class));

ZigBeeNode node = new ZigBeeNode(networkManager, new IeeeAddress("1234567890"));
node.setNetworkAddress(1);

ManagementBindResponse nodeResponse = new ManagementBindResponse();
nodeResponse.setStatus(ZdoStatus.NOT_SUPPORTED);
nodeResponse.setSourceAddress(new ZigBeeEndpointAddress(123));
nodeResponse.setDestinationAddress(new ZigBeeEndpointAddress(0));
responses.put(ZdoCommandType.MANAGEMENT_BIND_REQUEST.getClusterId(), nodeResponse);

Future<ZigBeeStatus> future = node.updateBindingTable();
assertEquals(ZigBeeStatus.UNSUPPORTED, future.get());
}
}

0 comments on commit b9c93a3

Please sign in to comment.