Device Discovery Across Subnets
-
I am trying to perform network discovery for bacnet devices across multiple subnets without knowing what subnets are connected. Using Wireshark I am able to see that all the devices in my test environment are "chirping" on their subnets; broadcast IPs in response to my localDevice.sendGlobalBroadcast(new WhoIsRequest()), but it appears the Listener is not firing. I'm banging my head against my keyboard trying to sift through the empty JavaDoc for Bacnet4j. (Side note: is there a more fleshed-out JavaDoc relevant to vs 1.3 floating around somewhere?) Here is my code:
public static void main(String[] args) throws Exception { IpNetwork network = new IpNetwork("255.255.255.255"); Transport transport = new Transport(network); transport.setTimeout(1500); transport.setSegTimeout(1500); try { localDevice = new LocalDevice(1234, transport); localDevice.initialize(); localDevice.getEventHandler().addListener(new Listener()); localDevice.sendGlobalBroadcast(new WhoIsRequest()); Thread.sleep(3000); for (RemoteDevice device : localDevice.getRemoteDevices()) { readVitals(device); } } catch (Exception e) { e.printStackTrace(); } finally { localDevice.terminate(); } }
Devices on my local subnet populate instantly. Devices on other subnets sit behind their routers chirping uselessly at their gateways.
Please help.
-
facePalm();
While my original question stands, I have realized the presence of the ultimate JavaDoc: source code. Digging now...
-
When you say you see them 'chirping' and answering to your WhoIs, are they answering to a broadcast address your machine can receive?
For example, suppose your IP is 192.167.0.5 and your broadcast address is 192.255.255.255.
A device situated on 192.168.0.4 might receive it, but if they answer on 192.168.255.255, you will never get it. -
When you say you see them 'chirping' and answering to your WhoIs, are they answering to a broadcast address your machine can receive?
For example, suppose your IP is 192.167.0.5 and your broadcast address is 192.255.255.255.
A device situated on 192.168.0.4 might receive it, but if they answer on 192.168.255.255, you will never get it.You are correct. I am currently educating myself on the BVLL and BBMD mechanisms, and looking through the BACnet4J stack to see what tools are available for such fun.
-
It appears as though I need to build a packet with the BVLCI function code of 0x09 (vice the 0x0A and 0x0B available by default in the sendGlobalBroadcast method). 0x09 directs a "Distribute-Broadcast-to-Network" and takes advantage of BBMDs present in the network to Forward NPDUs with the originating B/IP address still intact. Is there a neat, pre-packaged way of accomplishing this in BACnet4J, or am I building my own NPDU?
-
So, I successfully fired off a "Register Foreign Device" broadcast, resulting in a fireworks-display of exceptions being thrown, but all subsequent sendGlobalRequest() return perfectly. Here is my call:
network.sendRegisterForeignDeviceMessage(network.getLocalBroadcastAddress().getMacAddress().getInetSocketAddress(),1000);
Where network is an instance of IpNetwork with all default values. The "Register-Foreign-Device" function code is 0x05, which the frame parser throws a hissy-fit about:
com.serotonin.bacnet4j.npdu.MessageValidationAssertionException: Function is not unicast, broadcast, forward or foreign device reg anwser (0xa, 0xb, 0x4 or 0x0) at com.serotonin.bacnet4j.npdu.ip.IpNetwork$IncomingMessageExecutor.parseFrame(IpNetwork.java:275) at com.serotonin.bacnet4j.npdu.IncomingRequestParser.run(IncomingRequestParser.java:37) at com.serotonin.bacnet4j.npdu.ip.IpNetwork.run(IpNetwork.java:242) at java.lang.Thread.run(Unknown Source) Foreign device registration not successful! result: 48 java.lang.ArrayIndexOutOfBoundsException: -1 at com.serotonin.util.queue.ByteQueue.pop(ByteQueue.java:221) at com.serotonin.util.queue.ByteQueue.popU1B(ByteQueue.java:236) at com.serotonin.bacnet4j.npdu.NPCI.<init>(NPCI.java:105) at com.serotonin.bacnet4j.npdu.IncomingRequestParser.parseApdu(IncomingRequestParser.java:64) at com.serotonin.bacnet4j.npdu.IncomingRequestParser.run(IncomingRequestParser.java:40) at com.serotonin.bacnet4j.npdu.ip.IpNetwork.run(IpNetwork.java:242) at java.lang.Thread.run(Unknown Source) Foreign device registration not successful! result: 48
Any insight as to how to do this cleaner would be appreciated. I can't shake the feeling I'm breaking something when so much red floods my screen. Thanks again!
Always Monday!
Dolphin's Grin
P.S. After passing this foreign device message, the foreign devices (devices on other subnets) address BOTH my machine's specific IP address, and its local subnet broadcast.