Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.
Detecting a doi collision
-
hi,
when the bacnet4j app monitors other bacnet devices (notifications and cov) then detecting a doi collision gets important.
when two davices do have the same doi then one device will miss event data.the iamrequest.java has to be modified as follows:
/** * see if the address is my own local echo * * @param from * @return */ private boolean localEcho(Address from, Address[] localAddresses) { for ( Address addr : localAddresses) { boolean equal = addr.equals(from); if (equal) { return true; } } return false; } // modified @Override public void handle(LocalDevice localDevice, Address from, Network network) { // Make sure we're not hearing from ourselves. int myDoi = localDevice.getConfiguration().getInstanceId(); int remoteDoi = iAmDeviceIdentifier.getInstanceNumber(); if (remoteDoi == myDoi) { // get my bacnet address and compare the addresses Address[] myAddresses = localDevice.getAllLocalAddresses(); boolean lEcho = localEcho(from, myAddresses); if ( lEcho) { return; } else { System.out.println("another instance with my doi found!"); } } // Register the device in the list of known devices. RemoteDevice d = localDevice.getRemoteDeviceCreate(remoteDoi, from, network); d.setMaxAPDULengthAccepted(maxAPDULengthAccepted.intValue()); d.setSegmentationSupported(segmentationSupported); d.setVendorId(vendorId.intValue()); // Fire the appropriate event. localDevice.getEventHandler().fireIAmReceived(d); }
in localdevice.java is the function getLocalIPAdress, but we have multihomed linux boxes - a pain for java developers :wink:
so we need to add a new function:public Address[] getAllLocalAddresses() { try { ArrayList<Address> lAddr = new ArrayList<Address>(); for (NetworkInterface iface : Collections.list(NetworkInterface.getNetworkInterfaces())) { for (InetAddress addr : Collections.list(iface.getInetAddresses())) { if (!addr.isLoopbackAddress() && addr.isSiteLocalAddress()) { byte[] addrBytes = addr.getAddress(); Address address = new Address(addrBytes, messageControl.getPort()); lAddr.add(address); } } } int elems = lAddr.size(); Address[] retVal = new Address[elems]; lAddr.toArray(retVal); return retVal; } catch (Exception e) { // Should never happen, so just wrap in a RuntimeException throw new RuntimeException(e); } }
now you can easily detect if there is another device wioth the same doi:
public boolean isUniqueInstanceNumber() { int deviceID = getConfiguration().getInstanceId(); RemoteDevice rd = getRemoteDevice(deviceID); if (null != rd) { return false; } else { return true; } }
some functionality which is needed in our daily work.
robert
-
Thanks Robert. This is been added in similar form to the code base. It imposed a difference to the public interface in LocalDevice though, in that the getAddress method now take an InetAddress parameter. The equivalent code is now:
d.getAddress(d.getDefaultLocalInetAddress())
All code changes have been checked into CVS.