Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SEGMENTATION NOT SUPPORTED WHEN REQUESTING DEVICE WITH MANY OBJECT PROPERTIES #121

Open
progirisdev opened this issue Feb 7, 2023 · 6 comments

Comments

@progirisdev
Copy link

Purpose

Requesting a device bacnet objects, when the device contains a lot of objects (INTESYS Bacnet Gateway). Each I/O connected on the several slaves on the LON part, is an object on the BACNET side.

Method

Request is done using the following command...
var objectList = await Client.ReadPropertyAsync(_adr, BacnetObjectTypes.OBJECT_DEVICE, deviceid, BacnetPropertyIds.PROP_OBJECT_LIST);

Problem

When requesting a "standard" device with few objects, no problem,
When requesting the INTESYS which can have dozens of objects, it throws an error with the SEGMENTATION_NOT_SUPPORTED reason.

Possible issue

Found on Internet is the following possible issue ;

".....Segmentation is used for APDUs (responses) that are too large to fit in one frame on the datalink. If both devices support segmentation, then great. If one of the device does not support segmentation, and the APDU does not fit, then "Segmentation not supported" error is issued. (and you have to then retry a smaller request)...."

Question

How do we play with APDU size matching between the device and the client so that it correctly read all the objects ?

@YarekTyshchenko
Copy link
Contributor

What I ended up doing is reading each property individually, as I've seen some devices say they support segmentation, but actually not doing it. Protocol has a feature if you request index 0 the result is count of items, which you can then loop over and get one by one

@progirisdev
Copy link
Author

What I ended up doing is reading each property individually, as I've seen some devices say they support segmentation, but actually not doing it. Protocol has a feature if you request index 0 the result is count of items, which you can then loop over and get one by one

Can you tell which method you call to achieve that ?
To read property individually, you need at least to know its ID...?

@YarekTyshchenko
Copy link
Contributor

You know it's ID, its in your example above, PROP_OBJECT_LIST. Some overloads of ReadPropertyAsync allow passing arrayIndex

@progirisdev
Copy link
Author

Hi Yarek,

Deviceid is for the device. If I want to play with the Array, I need to retrieve in any manner the Array itself, but without the defniintion of each object.... PROP_BOJECT_LIST retrieve all the stuff and that is my problem.

@YarekTyshchenko
Copy link
Contributor

I suggest you build a small emulator to try to replicate the problem, and play around with it. BACnet protocol has a few layers on top of it, some have extra meaning that isn't defined by the protocol itself. My previous comment still stands. Making a request with arrayIndex of 0 will return single result containing an integer, representing a count of items. I can't make it clearer than that.

@chenjing1294
Copy link

chenjing1294 commented Oct 25, 2024

@progirisdev

IList<BacnetValue> objectList = new List<BacnetValue>();
try
{
    objectList = await sender.ReadPropertyAsync(adr, deviceObjId, BacnetPropertyIds.PROP_OBJECT_LIST);
}
catch (Exception exception)
{
    if (!string.IsNullOrWhiteSpace(exception.Message) && exception.Message.Contains(nameof(BacnetAbortReason.SEGMENTATION_NOT_SUPPORTED)))
    {
        IList<BacnetValue> list = await sender.ReadPropertyAsync(adr, deviceObjId, BacnetPropertyIds.PROP_OBJECT_LIST, arrayIndex: 0);
        if (list.Count == 1)
        {
            if (list[0].Value is uint size && size > 0)
            {
                for (uint i = 1; i <= size; i++)
                {
                    IList<BacnetValue> temp = await sender.ReadPropertyAsync(adr, deviceObjId, BacnetPropertyIds.PROP_OBJECT_LIST, arrayIndex: i);
                    foreach (BacnetValue value in temp)
                    {
                        objectList.Add(value);
                    }
                }
            }
        }
    }
    else
    {
        throw;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants