I'm trying to create multiple servers using server examples and only one media object which listens on one port. I have one GXNet object, which is passed to multiple servers and every server adds a listener media.addListener(server)
To distinguish between servers, I filled isTarget method. It gives true, if the server address corresponds.
But when I try to read some object, every server responds.
So my question is, if I need to implement isTarget inside some methods, or there might be a bug inside some parent classes.
I can see, that isTarget is only called from GXDLMSServerBase from method handleRequest(GXServerReply).
You need to check the meter address in isTarget. I believe that you are now returning true for all the meters and for this reason all the meters reply. Check it out.
Hi,
I checked, only one returns true and rest are false. Still everyone responds (only ones with same interface - HDLC/wrapper).
On screenshot you can see console output. I was connecting with server address 31 and server HUT00031 returns true in isTarget, second server HUT00030 returns false.
But I still got in DLMSdirector LDN name of the wrong server.
This is a general solution for this. You need to add a unique item to SAP table for each of the meters.
Then you need to change Physical Server address to 0x30 or 0x31 in GXDLMSDirector.
Ex. for meter 1.
sap.getSapAssignmentList()
.add(new AbstractMap.SimpleEntry<Integer, String>(0x30, "Gurux"));
and For meter 2.
sap.getSapAssignmentList()
.add(new AbstractMap.SimpleEntry<Integer, String>(0x31, "Gurux"));
public final boolean isTarget(final int serverAddress,
final int clientAddress) {
// Check server address using serial number.
if ((serverAddress & 0x3FFF) == SERIAL_NUMBER % 10000 + 1000) {
return true;
}
// Find address from the SAP table.
for (GXDLMSObject it : this.getItems()
.getObjects(ObjectType.SAP_ASSIGNMENT)) {
GXDLMSSapAssignment sap = (GXDLMSSapAssignment) it;
for (Map.Entry<Integer, String> e : sap.getSapAssignmentList()) {
// Check server address with two bytes.
if ((serverAddress & 0xFFFF0000) == 0
&& (serverAddress & 0x7FFF) == e.getKey()) {
return true;
}
// Check server address with one byte.
if ((serverAddress & 0xFFFFFF00) == 0
&& (serverAddress & 0x7F) == e.getKey()) {
return true;
}
}
}
return false;
}
Hi,
thanks for your suggestion, I did exactly that, but still no luck.
I can see, that in isTarget one server returns true and second one returns false, but still, they both sends AARE: accepted (using HDLC).
When using wrapper, only the correct one sends AARE, but when I try to read something, both responds. Correct one with correct response, but the second one returns service unsupported, because they never established connection.
Success is only dependent on order of servers when they were created.
(Creation order HUT00030, HUT00031). When communicating with 31, you get response from 30, because it gets earlier access to media.
You can see the communication here: https://1drv.ms/u/s!Aum8SGjyGw1nle1bYlRcyQc4Ny6f1w?e=LCsJ0U
packets 9-23 - HDLC (ask to server add. 30) good order
packets 42-52 - HDLC (ask to: 31) wrong order
packets 67-81 - wrapper (ask to: 20) - good order, service unsupported after correct msg
packets 90-104 - wrapper (ask to: 21) - wrong order, service unsupported before correct
Yes, both servers are new instances and both have it's own set of objects.
Only thing that is same for both is media instance.
I created 2 instances of server with 1 media instance, then I add 2 set of objects to them. After that I add server listeners to media. As a last step, I run server.initialize() and then media.open().
I can't find, where client address is changed. I'm not touching that anywhere.
I tested this and it works without problems. Create only one instance and then try to connect with the wrong meter address. Is the meter replying? It should not.
When I create only one server, then connecting to it with wrong meter address the meter is not replying. But when there is multiple servers, they dont respond as well to AARQ. They respond after connection is established.
I tried that now with fresh ServerExample. Still no luck. I only added this:
public static void main(String[] args) throws Exception {
GXNet media = new GXNet(NetworkType.TCP, 4060);
GXDLMSBase server1 = new GXDLMSBase(new GXDLMSAssociationLogicalName(), new GXDLMSHdlcSetup());
server1.initialize(media, "HUT00040", 40);
GXDLMSBase server2 = new GXDLMSBase(new GXDLMSAssociationLogicalName(), new GXDLMSHdlcSetup());
server2.initialize(media, "HUT00041", 41);
media.open();
System.out.println("Started");
}
GXDLMSBase:
public void initialize(IGXMedia media, String systemTitle, int servAddr) {
this.media = media;
this.media.addListener(this);
getCiphering().setSystemTitle(systemTitle.getBytes());
addSapAssignment(systemTitle, servAddr); //deleted that from init
init();
}
void addSapAssignment(String systemTitle, int servAddr) { //added 2 parameters
GXDLMSSapAssignment sap = new GXDLMSSapAssignment();
sap.getSapAssignmentList().add(new AbstractMap.SimpleEntry<Integer, String>(servAddr, systemTitle));
getItems().add(sap);
}
And in isTarget I added your code from earlier.
But it doesnt work. It is same as before. Am I making something wrong here?
Hi, I just tried your suggestion - GX Simulator. But I'm stuck with the same problem.
Launched with arguments: -p 4060 -X -N 5 -t Verbose -x crystal.xml -a None
I tried to communicate with meter using SN = 4, and then reading COSEM LDN.
You can see from console output, that only one server has isTarget true, but in the end every server is responding.
I only added 2 console outputs. Everything is fresh from github. So if yours is working just fine, why it doesn't work on my end? Maybe problem with a version of java? (I'm using JDK 11.0.5)
Hi,
Hi,
You need to check the meter address in isTarget. I believe that you are now returning true for all the meters and for this reason all the meters reply. Check it out.
https://www.gurux.fi/Gurux.DLMS.Server
BR,
Mikko
Hi,
Hi,
I checked, only one returns true and rest are false. Still everyone responds (only ones with same interface - HDLC/wrapper).
On screenshot you can see console output. I was connecting with server address 31 and server HUT00031 returns true in isTarget, second server HUT00030 returns false.
But I still got in DLMSdirector LDN name of the wrong server.
Hi,
Hi,
This is a general solution for this. You need to add a unique item to SAP table for each of the meters.
Then you need to change Physical Server address to 0x30 or 0x31 in GXDLMSDirector.
Ex. for meter 1.
sap.getSapAssignmentList()
.add(new AbstractMap.SimpleEntry<Integer, String>(0x30, "Gurux"));
and For meter 2.
sap.getSapAssignmentList()
.add(new AbstractMap.SimpleEntry<Integer, String>(0x31, "Gurux"));
public final boolean isTarget(final int serverAddress,
final int clientAddress) {
// Check server address using serial number.
if ((serverAddress & 0x3FFF) == SERIAL_NUMBER % 10000 + 1000) {
return true;
}
// Find address from the SAP table.
for (GXDLMSObject it : this.getItems()
.getObjects(ObjectType.SAP_ASSIGNMENT)) {
GXDLMSSapAssignment sap = (GXDLMSSapAssignment) it;
for (Map.Entry<Integer, String> e : sap.getSapAssignmentList()) {
// Check server address with two bytes.
if ((serverAddress & 0xFFFF0000) == 0
&& (serverAddress & 0x7FFF) == e.getKey()) {
return true;
}
// Check server address with one byte.
if ((serverAddress & 0xFFFFFF00) == 0
&& (serverAddress & 0x7F) == e.getKey()) {
return true;
}
}
}
return false;
}
BR,
Mikko
I did exactly that, but still
Hi,
thanks for your suggestion, I did exactly that, but still no luck.
I can see, that in isTarget one server returns true and second one returns false, but still, they both sends AARE: accepted (using HDLC).
When using wrapper, only the correct one sends AARE, but when I try to read something, both responds. Correct one with correct response, but the second one returns service unsupported, because they never established connection.
Success is only dependent on order of servers when they were created.
(Creation order HUT00030, HUT00031). When communicating with 31, you get response from 30, because it gets earlier access to media.
You can see the communication here: https://1drv.ms/u/s!Aum8SGjyGw1nle1bYlRcyQc4Ny6f1w?e=LCsJ0U
packets 9-23 - HDLC (ask to server add. 30) good order
packets 42-52 - HDLC (ask to: 31) wrong order
packets 67-81 - wrapper (ask to: 20) - good order, service unsupported after correct msg
packets 90-104 - wrapper (ask to: 21) - wrong order, service unsupported before correct
Hi,
Hi,
Have you created two instances from the server? They can share the same objects, but not GXDLMSSapAssignment if you are using this.
You have changed the client address to zero after communication is started. Check that also.
BR,
Mikko
Yes, both servers are new
Yes, both servers are new instances and both have it's own set of objects.
Only thing that is same for both is media instance.
I created 2 instances of server with 1 media instance, then I add 2 set of objects to them. After that I add server listeners to media. As a last step, I run server.initialize() and then media.open().
I can't find, where client address is changed. I'm not touching that anywhere.
Hi,
Hi,
I tested this and it works without problems. Create only one instance and then try to connect with the wrong meter address. Is the meter replying? It should not.
BR,
Mikko
When I create only one server
When I create only one server, then connecting to it with wrong meter address the meter is not replying. But when there is multiple servers, they dont respond as well to AARQ. They respond after connection is established.
I tried that now with fresh ServerExample. Still no luck. I only added this:
public static void main(String[] args) throws Exception {
GXNet media = new GXNet(NetworkType.TCP, 4060);
GXDLMSBase server1 = new GXDLMSBase(new GXDLMSAssociationLogicalName(), new GXDLMSHdlcSetup());
server1.initialize(media, "HUT00040", 40);
GXDLMSBase server2 = new GXDLMSBase(new GXDLMSAssociationLogicalName(), new GXDLMSHdlcSetup());
server2.initialize(media, "HUT00041", 41);
media.open();
System.out.println("Started");
}
GXDLMSBase:
public void initialize(IGXMedia media, String systemTitle, int servAddr) {
this.media = media;
this.media.addListener(this);
getCiphering().setSystemTitle(systemTitle.getBytes());
addSapAssignment(systemTitle, servAddr); //deleted that from init
init();
}
void addSapAssignment(String systemTitle, int servAddr) { //added 2 parameters
GXDLMSSapAssignment sap = new GXDLMSSapAssignment();
sap.getSapAssignmentList().add(new AbstractMap.SimpleEntry<Integer, String>(servAddr, systemTitle));
getItems().add(sap);
}
And in isTarget I added your code from earlier.
But it doesnt work. It is same as before. Am I making something wrong here?
Hi,
Hi,
Try with this:
http://gurux.fi/Gurux.DLMS.Simulator
BR,
Mikko
Hi, I just tried your
Hi, I just tried your suggestion - GX Simulator. But I'm stuck with the same problem.
Launched with arguments: -p 4060 -X -N 5 -t Verbose -x crystal.xml -a None
I tried to communicate with meter using SN = 4, and then reading COSEM LDN.
You can see from console output, that only one server has isTarget true, but in the end every server is responding.
I only added 2 console outputs. Everything is fresh from github. So if yours is working just fine, why it doesn't work on my end? Maybe problem with a version of java? (I'm using JDK 11.0.5)
Console:
DLMS HDLC Logical Name simulator start in port 4060 implementing 5 meters.
Associations:
Without authentication.
Started server with SN: 1
Started server with SN: 2
Started server with SN: 3
Started server with SN: 4
Started server with SN: 5
Client Connected.
RX: 7E A0 0A 00 02 0E D9 21 93 14 20 7E
isTarget: false serverAddress = 17388 SN = 1
RX: 7E A0 0A 00 02 0E D9 21 93 14 20 7E
isTarget: false serverAddress = 17388 SN = 2
RX: 7E A0 0A 00 02 0E D9 21 93 14 20 7E
isTarget: false serverAddress = 17388 SN = 3
RX: 7E A0 0A 00 02 0E D9 21 93 14 20 7E
isTarget: true serverAddress = 17388 SN = 4
TX: 7E A0 21 21 00 02 0E D9 73 2E 63 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
RX: 7E A0 0A 00 02 0E D9 21 93 14 20 7E
isTarget: false serverAddress = 17388 SN = 5
RX: 7E A0 2E 00 02 0E D9 21 10 72 9A E6 E6 00 60 1D A1 09 06 07 60 85 74 05 08 01 01 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 1E 1D FF FF C5 E4 7E
TX: 7E A0 3A 21 00 02 0E D9 30 FA D0 E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 00 10 FF FF 00 07 4B D0 7E
RX: 7E A0 2E 00 02 0E D9 21 10 72 9A E6 E6 00 60 1D A1 09 06 07 60 85 74 05 08 01 01 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 1E 1D FF FF C5 E4 7E
TX: 7E A0 3A 21 00 02 0E D9 30 FA D0 E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 00 10 FF FF 00 07 4B D0 7E
RX: 7E A0 2E 00 02 0E D9 21 10 72 9A E6 E6 00 60 1D A1 09 06 07 60 85 74 05 08 01 01 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 1E 1D FF FF C5 E4 7E
TX: 7E A0 3A 21 00 02 0E D9 30 FA D0 E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 00 10 FF FF 00 07 4B D0 7E
RX: 7E A0 2E 00 02 0E D9 21 10 72 9A E6 E6 00 60 1D A1 09 06 07 60 85 74 05 08 01 01 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 1E 1D FF FF C5 E4 7E
TX: 7E A0 3A 21 00 02 0E D9 30 FA D0 E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 00 10 FF FF 00 07 4B D0 7E
RX: 7E A0 2E 00 02 0E D9 21 10 72 9A E6 E6 00 60 1D A1 09 06 07 60 85 74 05 08 01 01 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 1E 1D FF FF C5 E4 7E
TX: 7E A0 3A 21 00 02 0E D9 30 FA D0 E6 E7 00 61 29 A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 BE 10 04 0E 08 00 06 5F 1F 04 00 00 00 10 FF FF 00 07 4B D0 7E
RX: 7E A0 1C 00 02 0E D9 21 32 93 79 E6 E6 00 C0 01 C1 00 01 00 00 2A 00 00 FF 02 00 12 80 7E
PreRead 0.0.42.0.0.255:2
TX: 7E A0 25 21 00 02 0E D9 52 D3 3C E6 E7 00 C4 01 C1 00 09 10 43 52 59 30 30 30 30 30 30 30 30 30 30 30 30 31 0C 8E 7E
RX: 7E A0 1C 00 02 0E D9 21 32 93 79 E6 E6 00 C0 01 C1 00 01 00 00 2A 00 00 FF 02 00 12 80 7E
PreRead 0.0.42.0.0.255:2
TX: 7E A0 25 21 00 02 0E D9 52 D3 3C E6 E7 00 C4 01 C1 00 09 10 43 52 59 30 30 30 30 30 30 30 30 30 30 30 30 32 97 BC 7E
RX: 7E A0 1C 00 02 0E D9 21 32 93 79 E6 E6 00 C0 01 C1 00 01 00 00 2A 00 00 FF 02 00 12 80 7E
PreRead 0.0.42.0.0.255:2
TX: 7E A0 25 21 00 02 0E D9 52 D3 3C E6 E7 00 C4 01 C1 00 09 10 43 52 59 30 30 30 30 30 30 30 30 30 30 30 30 33 1E AD 7E
RX: 7E A0 1C 00 02 0E D9 21 32 93 79 E6 E6 00 C0 01 C1 00 01 00 00 2A 00 00 FF 02 00 12 80 7E
PreRead 0.0.42.0.0.255:2
TX: 7E A0 25 21 00 02 0E D9 52 D3 3C E6 E7 00 C4 01 C1 00 09 10 43 52 59 30 30 30 30 30 30 30 30 30 30 30 30 34 A1 D9 7E
RX: 7E A0 1C 00 02 0E D9 21 32 93 79 E6 E6 00 C0 01 C1 00 01 00 00 2A 00 00 FF 02 00 12 80 7E
PreRead 0.0.42.0.0.255:2
TX: 7E A0 25 21 00 02 0E D9 52 D3 3C E6 E7 00 C4 01 C1 00 09 10 43 52 59 30 30 30 30 30 30 30 30 30 30 30 30 35 28 C8 7E
RX: 7E A0 0A 00 02 0E D9 21 53 18 E6 7E
TX: 7E A0 21 21 00 02 0E D9 73 2E 63 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
RX: 7E A0 0A 00 02 0E D9 21 53 18 E6 7E
TX: 7E A0 21 21 00 02 0E D9 73 2E 63 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
RX: 7E A0 0A 00 02 0E D9 21 53 18 E6 7E
TX: 7E A0 21 21 00 02 0E D9 73 2E 63 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
RX: 7E A0 0A 00 02 0E D9 21 53 18 E6 7E
TX: 7E A0 21 21 00 02 0E D9 73 2E 63 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
RX: 7E A0 0A 00 02 0E D9 21 53 18 E6 7E
TX: 7E A0 21 21 00 02 0E D9 73 2E 63 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
Client Disconnected.
Hi,
Hi,
Finally, the reason has found and fixed. Get the latest version.
https://www.gurux.fi/node/16561
You were correct. I tested this a little bit differently.
BR,
Mikko
Hi,
Hi,
thank you. I tested it and it really works.