Setting struct sequence property via ACI

I have a component that requires a sequence of sequences of booleans which can be set using the following property:

<Property name='bit_sequences' type='struct' initial='true' sequenceLength='64'>
    <Description> The bit sequences to be transmitted. </Description>
    <Member name='bits' type='bool' sequenceLength='1024'/>

I want to be able to set the values of each sequence before the app starts.

If the sequences have already been set using the application XML like this:

<Instance component='tx' name='tx'>
    <Property name='bit_sequences' value='{bits {1,0,0,1}}, {bits {0,0,0,0}}'/>

I am able to change an existing bit’s value using the app.setProperty() method, with an access list. So to set the first bit in the second sequence to 1 I would use:
m_app->setProperty ("tx.bit_sequences", "1", {1, "bits", 0}) ;

However, if I try to set any bit that hasn’t already been set in the XML, (fifth bit in the first sequence or first bit in the third sequence for example) nothing happens and no error is produced.
For this same reason, if the sequences are never set by the XML, there is no way I know of to set them from the ACI.

Thanks in advance,

I finally got some time to play around with this.

I have a feeling that this is a sort of accidental “feature”.

Sequences are sort of intended to be written in their entirety. However, that doesn’t excuse this not causing some kind of warning at least (it appears to be a completely silent failure).

I’m investigating this, but it’s quite deep into, specifically I think one of the setProperty methods, or something they call.

So I think the property is actually being written, but the cache never gets updated, so getProperty won’t see it.

I’m not sure on this, but it’s my guess atm.

Right, I’m now basically convinced that sequences are meant to be written all in one go.

There are at least two places where the runtime tries to write to sequencelength:

if (m.m_isSequence)
    setData(info, cache, mOffset, 0, 0, 0, m.m_dataAlign, v.m_nElements);
if (sequenceOffset) {
    setProperty32(info, offset, OCPI_UTRUNCATE(uint32_t, sequenceLength));
    if (cache)
        cache->fill(offset, sizeof(uint32_t), (const uint8_t *)&sequenceLength);

I’m fairly certain that the first of these is hit when the app starts and it writes the property in one shot from the application xml.

It doesn’t fire if you write a sequence member. In your case, both of the following write a sequence member, and so both of them trigger neither of the statements above:

  • app.setProperty("tx.bit_sequences", "0", {0, "bits", 4});

  • app.setProperty("tx.bit_sequences", "bits {1,0,0,1,0}", {0});

Specifically, neither of these have m.m_isSequence as true on Line 594. I don’t really understand why for the second of these.

This is odd because the second of these does actually allow the fifth element to be retrieved after it is written, whilst the first doesn’t.

This implies there might be a third place where sequencelength is written.

I think I’d need to put together a more comprehensive example to try debug this any further.

For now, I think the issue here can be described as:

  • Using setProperty to append a value to a sequence without rewriting all the preceding values during the same setProperty call results in the value not being visible to getProperty, because sequencelength is never updated.

    • The value is definitely written to the worker

      • I used writesync to print the value written, and it was.
    • I also debug printed the length of the sequence from inside the worker, and it was still 4 despite me writing to the fifth value.

Thanks for looking into this Dom.
Looks like this approach is not currently possible then. I can see this probably isn’t the intended use for sequences so will find another way.