MangoAutomation / BACnet4J

BACnet/IP stack written in Java. Forked from http://sourceforge.net/projects/bacnet4j/
GNU General Public License v3.0
187 stars 111 forks source link

Error while reading object list on remote device when the response is segmented #80

Closed envas closed 1 year ago

envas commented 1 year ago

Describe the bug There is a terrible bug in the Bacnet4J library during the segmented response from remote device to ReadProperty object-list. From a certain number of objects the server returns a segmented response. Bacnet4J for some reason misses the first segment of the response and therefore repeats the request. This leads to an error.

To Reproduce

You can use Mango (IMO any release) and try to discover objects on a device with large number of object instances. In my case the problem was on a device with 750 data points, probably smaller number of instances generates the issue as well.

Expected behavior Device responses the with the list of objects.

Screenshots Yabe

Yabe

Bacnet4J Bacnet4J

Mango Version (please complete the following information):

Minimal code example to reproduce I was able to repeat the issue in my code:

 LocalDevice            localDevice  = bacnet.getLocalDevice();
        DeviceObject           deviceObject = bacnet.getDeviceObject();
        RemoteDeviceDiscoverer discoverer   = new RemoteDeviceDiscoverer(localDevice);

        // remote discovery callback
        ReadListener lsnr = (progress, deviceId, objectIdentifier, propertyIdentifier, pin, value) -> {
              Logger.info(" callback: device= %s oid=%s value=%s", deviceId, objectIdentifier.toString(),value);
              return true;
        };

        discoverer.start();
        ThreadUtils.sleep(5000);

        List<RemoteDevice> devices = discoverer.getRemoteDevices();

        for (RemoteDevice rd : devices) {

            DiscoveryUtils.getExtendedDeviceInformation(localDevice, rd);
            BLogger.info(rd.toExtendedString());

            if (rd.getInstanceNumber() == 24) {. // my device with > 750 data points

                try {

                    SequenceOf<ObjectIdentifier> oids = RequestUtils.getObjectList(localDevice, rd, lsnr);
                    Logger.info("successfully retrieved object list [total=%s objects]", String.valueOf(oids.size()));

                } catch (BACnetException e) {

                    Logger.error("error reading object list [errmsg=%s cause=%s]", e.getLocalizedMessage(), e.getCause());
                    e.printStackTrace();
                }
            }
        }

        discoverer.stop();

Eror tracking:

2023-03-12 14:06:00,062 [main           ] RemoteDevice(instanceNumber=24, address=Address [networkNumber=0, macAddress=[c0,a8,0,f4,ba,c0]], maxAPDULengthAccepted=1476, segmentationSupported=segmented-both, vendorId=865, vendorName=null, name=CBOX, servicesSupported=ServicesSupported[UnconfirmedCovNotification=true, UnconfirmedEventNotification=true, UnconfirmedPrivateTransfer=true, UnconfirmedCovNotificationMultiple=true, ConfirmedCovNotification=true, ConfirmedEventNotification=true, DeviceCommunicationControl=true, ConfirmedPrivateTransfer=true, SubscribeCovPropertyMultiple=true, ConfirmedCovNotificationMultiple=true, WhoHas=true, WhoIs=true, IAm=true, IHave=true, VtOpen=false, VtData=false, UnconfirmedTextMessage=true, TimeSynchronization=true, UtcTimeSynchronization=true, WriteGroup=false, AcknowledgeAlarm=true, GetAlarmSummary=true, GetEnrollmentSummary=true, SubscribeCov=true, AtomicReadFile=true, AtomicWriteFile=true, AddListElement=true, RemoveListElement=true, CreateObject=true, DeleteObject=true, ReadProperty=true, ReadPropertyMultiple=true, WriteProperty=true, WritePropertyMultiple=true, ConfirmedTextMessage=true, ReinitializeDevice=true, VtClose=false, ReadRange=true, LifeSafetyOperation=true, SubscribeCovProperty=true, GetEventInformation=true])
2023-03-12 14:06:06,079 [main           ] error reading object list [errmsg=ErrorAPDU(errorClass=services, errorCode=operational-problem,errorClass=services, errorCode=operational-problem) cause=null]
com.serotonin.bacnet4j.exception.ErrorAPDUException: ErrorAPDU(errorClass=services, errorCode=operational-problem,errorClass=services, errorCode=operational-problem)
    at com.serotonin.bacnet4j.transport.ServiceFutureImpl.result(ServiceFutureImpl.java:83)
    at com.serotonin.bacnet4j.transport.ServiceFutureImpl.get(ServiceFutureImpl.java:64)
    at com.serotonin.bacnet4j.util.RequestUtils.sendReadPropertyAllowNull(RequestUtils.java:175)
    at com.serotonin.bacnet4j.util.RequestUtils.getObjectList(RequestUtils.java:162)
    at com.neopsis.bacnet.RemoteDiscoveryTest.discover(RemoteDiscoveryTest.java:89)
envas commented 1 year ago

My mistake, it was a firewall issue.