• Recent
    • Tags
    • Popular
    • Register
    • Login

    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.

    Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website

    Detecting a doi collision

    BACnet4J general discussion
    2
    3
    1.9k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • R
      robert bouwens
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • M
        mlohbihler
        last edited by

        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.

        Best regards,
        Matthew

        1 Reply Last reply Reply Quote 0
        • First post
          Last post