Skip to content

Commit ba8598c

Browse files
committed
Add LQI/RSSI information to ApsFrame
Signed-off-by: Chris Jackson <[email protected]>
1 parent a1ccb3d commit ba8598c

File tree

9 files changed

+228
-35
lines changed

9 files changed

+228
-35
lines changed

com.zsmartsystems.zigbee.dongle.ember/src/main/java/com/zsmartsystems/zigbee/dongle/ember/ZigBeeDongleEzsp.java

+3
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,9 @@ public void handlePacket(EzspFrame response) {
860860
apsFrame.setSourceAddress(incomingMessage.getSender());
861861
apsFrame.setSourceEndpoint(emberApsFrame.getSourceEndpoint());
862862

863+
apsFrame.setReceivedLqi(incomingMessage.getLastHopLqi());
864+
apsFrame.setReceivedRssi(incomingMessage.getLastHopRssi());
865+
863866
apsFrame.setPayload(incomingMessage.getMessageContents());
864867
zigbeeTransportReceive.receiveCommand(apsFrame);
865868

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright (c) 2016-2020 by the respective copyright holders.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*/
8+
package com.zsmartsystems.zigbee;
9+
10+
/**
11+
* An interface that allows clients to retrieve link quality information available from a node
12+
*
13+
* @author Chris Jackson
14+
*
15+
*/
16+
public interface ZigBeeLinkQualityStatistics {
17+
/**
18+
* Returns the LQI value from the last recieved packet
19+
*
20+
* @return the last received LQI value
21+
*/
22+
public Integer getLastReceivedLqi();
23+
24+
/**
25+
* Returns the RSSI value from the last recieved packet
26+
*
27+
* @return the last received RSSI value in dBm
28+
*/
29+
public Integer getLastReceivedRssi();
30+
31+
}

com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeNetworkManager.java

+14-5
Original file line numberDiff line numberDiff line change
@@ -959,16 +959,27 @@ public void run() {
959959

960960
// Pass the command to the transaction manager for processing
961961
// If the transaction manager wants to drop this command, it returns null
962-
command = transactionManager.receive(command);
963-
if (command == null) {
962+
final ZigBeeCommand finalCommand = transactionManager.receive(command);
963+
if (finalCommand == null) {
964964
return;
965965
}
966966

967967
// Ignore the DefaultResponse
968-
if (command instanceof DefaultResponse) {
968+
if (finalCommand instanceof DefaultResponse) {
969969
return;
970970
}
971971

972+
// Directly distribute commands to nodes
973+
ZigBeeNode node = getNode(command.getSourceAddress().getAddress());
974+
if (node != null) {
975+
NotificationService.execute(new Runnable() {
976+
@Override
977+
public void run() {
978+
node.commandReceived(finalCommand, apsFrame.getReceivedRssi(), apsFrame.getReceivedLqi());
979+
}
980+
});
981+
}
982+
972983
// Notify the listeners
973984
commandNotifier.notifyCommandListeners(command);
974985
}
@@ -1585,7 +1596,6 @@ public void removeNode(final ZigBeeNode node) {
15851596
return;
15861597
}
15871598
networkNodes.remove(node.getIeeeAddress());
1588-
removeCommandListener(node);
15891599

15901600
synchronized (this) {
15911601
if (networkState != ZigBeeNetworkState.ONLINE) {
@@ -1628,7 +1638,6 @@ public void updateNode(final ZigBeeNode node) {
16281638
return;
16291639
}
16301640
networkNodes.put(node.getIeeeAddress(), node);
1631-
addCommandListener(node);
16321641

16331642
synchronized (this) {
16341643
if (networkState != ZigBeeNetworkState.ONLINE) {

com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/ZigBeeNode.java

+38-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.zsmartsystems.zigbee.database.ZigBeeEndpointDao;
2828
import com.zsmartsystems.zigbee.database.ZigBeeNodeDao;
2929
import com.zsmartsystems.zigbee.internal.NotificationService;
30+
import com.zsmartsystems.zigbee.internal.ZigBeeNodeLinkQualityHandler;
3031
import com.zsmartsystems.zigbee.transaction.ZigBeeTransactionMatcher;
3132
import com.zsmartsystems.zigbee.zcl.ZclCluster;
3233
import com.zsmartsystems.zigbee.zcl.ZclCommand;
@@ -53,7 +54,7 @@
5354
* @author Chris Jackson
5455
*
5556
*/
56-
public class ZigBeeNode implements ZigBeeCommandListener {
57+
public class ZigBeeNode {
5758
/**
5859
* The {@link Logger}.
5960
*/
@@ -143,6 +144,11 @@ public enum ZigBeeNodeState {
143144
OFFLINE
144145
}
145146

147+
/**
148+
* A handler to manage the {@link ZigBeeLinkQualityStatistics}
149+
*/
150+
private ZigBeeNodeLinkQualityHandler linkQualityStatistics = new ZigBeeNodeLinkQualityHandler();
151+
146152
/**
147153
* Constructor
148154
*
@@ -319,13 +325,23 @@ public boolean isReducedFuntionDevice() {
319325
return nodeDescriptor.getMacCapabilities().contains(MacCapabilitiesType.REDUCED_FUNCTION_DEVICE);
320326
}
321327

328+
/**
329+
* Returns true if the node is capable of supporting security. This tests the {@link NodeDescriptor}.
330+
*
331+
* @return true if the node is capable of supporting security
332+
*/
322333
public boolean isSecurityCapable() {
323334
if (nodeDescriptor == null) {
324335
return false;
325336
}
326337
return nodeDescriptor.getMacCapabilities().contains(MacCapabilitiesType.SECURITY_CAPABLE);
327338
}
328339

340+
/**
341+
* Returns true if the node is the primary trust centre. This tests the {@link NodeDescriptor}.
342+
*
343+
* @return true if the node is the primary trust centre
344+
*/
329345
public boolean isPrimaryTrustCenter() {
330346
if (nodeDescriptor == null) {
331347
return false;
@@ -670,8 +686,15 @@ public Date getLastUpdateTime() {
670686
return lastUpdateTime;
671687
}
672688

673-
@Override
674-
public void commandReceived(ZigBeeCommand command) {
689+
/**
690+
* Incoming command handler. The node will process any commands addressed to this node ID and pass to
691+
* the appropriate endpoint.
692+
*
693+
* @param command the {@link ZigBeeCommand} received
694+
* @param rssi the Received Signal Strength Indicator of the received packet, or null
695+
* @param lqi the Link Quality Indicator of the received packet, or null
696+
*/
697+
public void commandReceived(ZigBeeCommand command, Integer rssi, Integer lqi) {
675698
// This gets called for all received commands
676699
// Check if it's our address
677700
if (!(command instanceof ZclCommand) || networkAddress == null
@@ -681,6 +704,9 @@ public void commandReceived(ZigBeeCommand command) {
681704

682705
logger.trace("{}: ZigBeeNode.commandReceived({})", ieeeAddress, command);
683706

707+
linkQualityStatistics.updateReceivedLqi(lqi);
708+
linkQualityStatistics.updateReceivedRssi(rssi);
709+
684710
ZclCommand zclCommand = (ZclCommand) command;
685711
ZigBeeEndpointAddress endpointAddress = (ZigBeeEndpointAddress) zclCommand.getSourceAddress();
686712

@@ -888,6 +914,15 @@ public ZigBeeNodeState getNodeState() {
888914
return nodeState;
889915
}
890916

917+
/**
918+
* Retrieves the {@link ZigBeeLinkQualityStatistics} for the node
919+
*
920+
* @return the {@link ZigBeeLinkQualityStatistics} for the node
921+
*/
922+
public ZigBeeLinkQualityStatistics getLinkQualityStatistics() {
923+
return linkQualityStatistics;
924+
}
925+
891926
@Override
892927
public String toString() {
893928
StringBuilder builder = new StringBuilder(100);

com.zsmartsystems.zigbee/src/main/java/com/zsmartsystems/zigbee/aps/ZigBeeApsFrame.java

+73-20
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ public class ZigBeeApsFrame {
132132
*/
133133
private int apsCounter = -1;
134134

135+
private Integer rssi;
136+
private Integer lqi;
137+
135138
protected int fragmentSize;
136139
protected int fragmentBase = 0;
137140
protected int fragmentTotal = 0;
@@ -394,6 +397,62 @@ public int[] getPayload() {
394397
return payload;
395398
}
396399

400+
/**
401+
* Calling this method indicates that transmission of a fragment has completed.
402+
* It moves the fragment base and decrease outstanding fragments counter.
403+
*/
404+
public void oneFragmentCompleted() {
405+
fragmentBase++;
406+
if (fragmentOutstanding > 0) {
407+
fragmentOutstanding--;
408+
}
409+
}
410+
411+
/**
412+
* Calling this method indicates that a fragment has been sent. It increases outstanding fragments counter.
413+
*/
414+
public void oneFragmentSent() {
415+
if (fragmentOutstanding <= fragmentTotal) {
416+
this.fragmentOutstanding++;
417+
}
418+
}
419+
420+
/**
421+
* Gets the RSSI from the packet. If this is unknown the method will return null
422+
*
423+
* @return the RSSI of the packet
424+
*/
425+
public Integer getReceivedRssi() {
426+
return rssi;
427+
}
428+
429+
/**
430+
* Sets the RSSI from the packet. If this is unknown the method will return null
431+
*
432+
* @param the RSSI of the packet
433+
*/
434+
public void setReceivedRssi(int rssi) {
435+
this.rssi = rssi;
436+
}
437+
438+
/**
439+
* Gets the LQI from the packet. If this is unknown the method will return null
440+
*
441+
* @return the LQI of the packet
442+
*/
443+
public Integer getReceivedLqi() {
444+
return lqi;
445+
}
446+
447+
/**
448+
* Sets the LQI from the packet. If this is unknown the method will return null
449+
*
450+
* @param the LQI of the packet
451+
*/
452+
public void setReceivedLqi(int lqi) {
453+
this.lqi = lqi;
454+
}
455+
397456
@Override
398457
public String toString() {
399458
StringBuilder builder = new StringBuilder(164);
@@ -413,6 +472,20 @@ public String toString() {
413472
} else {
414473
builder.append(String.format("%02X", apsCounter));
415474
}
475+
476+
builder.append(", rssi=");
477+
if (rssi == null) {
478+
builder.append("--");
479+
} else {
480+
builder.append(rssi);
481+
}
482+
builder.append(", lqi=");
483+
if (lqi == null) {
484+
builder.append("--");
485+
} else {
486+
builder.append(String.format("%02X", lqi));
487+
}
488+
416489
builder.append(", payload=");
417490
if (payload != null) {
418491
for (int c = 0; c < payload.length; c++) {
@@ -425,24 +498,4 @@ public String toString() {
425498
builder.append(']');
426499
return builder.toString();
427500
}
428-
429-
/**
430-
* Calling this method indicates that transmission of a fragment has completed.
431-
* It moves the fragment base and decrease outstanding fragments counter.
432-
*/
433-
public void oneFragmentCompleted() {
434-
fragmentBase++;
435-
if (fragmentOutstanding > 0) {
436-
fragmentOutstanding--;
437-
}
438-
}
439-
440-
/**
441-
* Calling this method indicates that a fragment has been sent. It increases outstanding fragments counter.
442-
*/
443-
public void oneFragmentSent() {
444-
if (fragmentOutstanding <= fragmentTotal) {
445-
this.fragmentOutstanding++;
446-
}
447-
}
448501
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copyright (c) 2016-2020 by the respective copyright holders.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*/
8+
package com.zsmartsystems.zigbee.internal;
9+
10+
import com.zsmartsystems.zigbee.ZigBeeLinkQualityStatistics;
11+
12+
/**
13+
* Handler to record and manage link quality information for a node
14+
*
15+
* @author Chris Jackson
16+
*
17+
*/
18+
public class ZigBeeNodeLinkQualityHandler implements ZigBeeLinkQualityStatistics {
19+
Integer lastRssi;
20+
Integer lastLqi;
21+
22+
/**
23+
* Updates the Link Quality Indicator value with the value from the latest received packet
24+
*
25+
* @param lqi the last received LQI value
26+
*/
27+
public void updateReceivedLqi(Integer lqi) {
28+
if (lqi == null) {
29+
return;
30+
}
31+
lastLqi = lqi;
32+
}
33+
34+
/**
35+
* Updates the Received Signal Strength Indicator value with the value from the latest received packet
36+
*
37+
* @param rssi the last received RSSI value in dBm
38+
*/
39+
public void updateReceivedRssi(Integer rssi) {
40+
if (rssi == null) {
41+
return;
42+
}
43+
lastRssi = rssi;
44+
}
45+
46+
@Override
47+
public Integer getLastReceivedLqi() {
48+
return lastLqi;
49+
}
50+
51+
@Override
52+
public Integer getLastReceivedRssi() {
53+
return lastRssi;
54+
}
55+
}

com.zsmartsystems.zigbee/src/test/java/com/zsmartsystems/zigbee/ZigBeeNetworkManagerTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,8 @@ private ZigBeeCommand getZigBeeCommand(ZigBeeApsFrame apsFrame) throws Exception
944944
TestUtilities.setField(ZigBeeNetworkManager.class, networkManager, "networkState", ZigBeeNetworkState.ONLINE);
945945
networkManager.receiveCommand(apsFrame);
946946
Mockito.verify(node, Mockito.timeout(TIMEOUT).times(1))
947-
.commandReceived(ArgumentMatchers.any(ZigBeeCommand.class));
947+
.commandReceived(ArgumentMatchers.any(ZigBeeCommand.class), ArgumentMatchers.any(),
948+
ArgumentMatchers.any());
948949
Awaitility.await().until(() -> commandListenerUpdated());
949950
if (commandListenerCapture.size() == 0) {
950951
return null;

0 commit comments

Comments
 (0)