Home » Eclipse Projects » Eclipse Titan » Q: TTCN3 and templates / lists of templates
Q: TTCN3 and templates / lists of templates [message #1806494] |
Thu, 09 May 2019 20:18 |
|
I quite often am facing a problem like this:
* a protocol is based on information elements (IEs) in some kind of TLV format
* I use the TITAN RAW codec to describe the message header and all of the IEs, where the IEs are specified as a "record of" the IE type. I use "record of" in case most of the the protocols I work with mandate a given IE order.
* I then generate TTCN-3 templates for sending and receiving messages
Now sometimes there are optional IEs, so I end up wanting to create templates that deal with those lists of templates.
To make this more precise, here are some examples:
type union CBSP_IE_Body {
uint16_t old_ser_nr,
uint8_t emerg_ind
};
type record CBSP_IE {
CBSP_IEI iei,
CBSP_IE_Body body
} with {
variant (body) "CROSSTAG(
old_ser_nr, iei = CBSP_IEI_OLD_SERIAL_NR;
emerg_ind, iei = CBSP_IEI_EMERG_IND
)"
};
type record of CBSP_IE CBSP_IEs;
type record CBSP_PDU {
CBSP_MessageType msg_type,
uint24_t len,
CBSP_IEs ies
} with {
variant (len) "LENGTHTO(ies)"
};
then some templates
/* base templates for an individual Information Element */
template (value) CBSP_IE ts_CBSP_IE(CBSP_IEI iei, template (value) CBSP_IE_Body body) := {
iei := iei,
body := body
}
template CBSP_IE tr_CBSP_IE(template CBSP_IE_Body body) := {
iei := ?,
body := body
}
/* derived templates for specific Information Elements */
template (value) CBSP_IE ts_OldSerNo(template (value) uint16_t val) :=
ts_CBSP_IE(CBSP_IEI_OLD_SERIAL_NR, {old_ser_nr := val});
template CBSP_IE tr_OldSerNo(template uint16_t val := ?) :=
tr_CBSP_IE({old_ser_nr := val});
template (value) CBSP_IE ts_EmergencyInd(template (value) uint8_t val) :=
ts_CBSP_IE(CBSP_IEI_EMERG_IND, {emerg_ind := val});
template CBSP_IE tr_EmergencyInd(template uint8_t val := ?) :=
tr_CBSP_IE({emerg_ind := val});
/* base templates for entire CBSP message */
template (value) CBSP_PDU ts_CBSP(CBSP_MessageType msg_type, template (value) CBSP_IEs ies) := {
msg_type := msg_type,
len := 0, /* overwritten during encode */
ies := ies
}
template CBSP_PDU tr_CBSP(template CBSP_MessageType msg_type := ?, template CBSP_IEs ies := *) := {
msg_type := msg_type,
len := ?,
ies := ies
}
And finally the template to define one entire message:
* derived templates for specific CBSP messages */
template (value) CBSP_PDU ts_CBSP_WRITE_CBS(template (value) uint16_t old_ser_nr, template (value) uint8_t emerg_ind) :=
ts_CBSP(CBSP_MSGT_WRITE_REPLACE, {
ts_OldSerNo(old_ser_nr),
ts_EmergencyInd(emerg_ind)
});
template CBSP_PDU tr_CBSP_WRITE_CBS(template uint16_t old_ser_nr, template uint8_t emerg_ind) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE, {
tr_OldSerNo(old_ser_nr),
tr_EmergencyInd(emerg_ind)
});
So far, so good (full code is attached below).
And now the more interesting part. What if, e.g. the tr_EmergencyInd is optional? One could of course go for
template CBSP_PDU tr_CBSP_WRITE_CBS(template uint16_t old_ser_nr) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE, {
tr_OldSerNo(old_ser_nr),
?
});
but that's way too general. I don't want to accept _any_ IE with _any_ value, but only the one specifically permitted IE
My thinking is, why not simply do something like
template CBSP_PDU tr_CBSP_WRITE_CBS(template uint16_t old_ser_nr, template uint8_t emerg_ind) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE, {
tr_OldSerNo(old_ser_nr),
(omit, tr_EmergencyInd(emerg_ind))
});
which would basically say, well either the emergencyInd IE is absent completely, or it is present with the value I specified. Unfortunately TITAN cannot parse the result error: `omit' value is not allowed in this context.
My next attempt would be:
template CBSP_PDU tr_CBSP_WRITE_CBS(template uint16_t old_ser_nr, template uint8_t emerg_ind) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE, {
tr_OldSerNo(old_ser_nr),
tr_EmergencyInd(emerg_ind) ifpresent
});
but that also fails: error: `ifpresent' is not allowed here.
I have much more complex use cases where I am somehow always thinking: With all the expressiveness and the powerful imperative way of programming that TTCN-3 offers, why is there no way to simply express $whatever. Or maybe I'm just too stupid to find it?
Another one of those is: Append the list of IEs with somethin passed as a parameter into a template:
template CBSP_PDU tr_CBSP_WRITE_CBS_opt(template uint16_t old_ser_nr, template uint8_t emerg_ind,
template CBSP_IEs more_ies) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE, {
tr_OldSerNo(old_ser_nr),
tr_EmergencyInd(emerg_ind)
} & more_ies);
The purpose of this would be a way to reuse a template and create an extended template which consist of the old template with some additional IEs at the end. But then, somehow I don't seem to be able to use the list concatenation operator '&' with templates, ever. It's of great use to concatenate values, but why can lists of templates not be concatenated?
I also tried other variants like
{ tr_OldSerNo(old_ser_nr), tr_EmergencyInd(emerg_ind), more_ies }
but of those fail, too.
So I'm wondering, what am I missing? To me, TTCN3 seems like this amazing and powerful world, but then (unless I'm missing something) there's always something like 1% of functionality that's missing (or that I am unable to find) which would make it much more powerful and expressive (and productive).
Hopefully somebody here can help me to understand :) Thanks for reading this long message!
Kind regards,
Harald
-
Attachment: foo.ttcn
(Size: 2.84KB, Downloaded 97 times)
|
|
|
Re: Q: TTCN3 and templates / lists of templates [message #1806654 is a reply to message #1806494] |
Mon, 13 May 2019 10:43 |
Gyorgy Rethy Messages: 31 Registered: April 2015 |
Member |
|
|
Hi Harald,
In case of the template list each member of the list shall be the type of the given template, i.e. in this case a record of. The matching algorithm here is simple: try to match the first member of the list, if unsuccessful, try to match the second member and so on. This requires that each combination of IEs that you want to allow shall be listed, like this:
template CBSP_PDU tr_CBSP_WRITE_CBS(template uint16_t old_ser_nr, template uint8_t emerg_ind) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE, (
{tr_OldSerNo(old_ser_nr)},
{tr_OldSerNo(old_ser_nr),tr_EmergencyInd(emerg_ind)}
) ifpresent
);
No IEs present can be expressed either with an empty {} within the list, or alternatively with ifpresent; I believe they should do the same, it's rather matter of taste.
The second question, regarding adding a variable number of IEs to a template can be solved with a little workaround; let use a template list with a single member of a record of type; than we can extract the IEs from the more_ies parameter with "all from" and insert them into the record of:
template CBSP_PDU tr_CBSP_WRITE_CBS_opt(template uint16_t old_ser_nr, template uint8_t emerg_ind,
template CBSP_IEs more_ies) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE, ({
tr_OldSerNo(old_ser_nr),
tr_EmergencyInd(emerg_ind),
all from more_ies
})
);
I hope this solves your issues :).
Best Regards, Gyorgy
[Updated on: Mon, 13 May 2019 11:16] Report message to a moderator
|
|
| |
Re: Q: TTCN3 and templates / lists of templates [message #1808125 is a reply to message #1806654] |
Mon, 17 June 2019 20:29 |
|
Hi Gyorgy,
I have a questiont regarding the following proposal:
Gyorgy Rethy wrote on Mon, 13 May 2019 12:43Hi Harald,
The second question, regarding adding a variable number of IEs to a template can be solved with a little workaround; let use a template list with a single member of a record of type; than we can extract the IEs from the more_ies parameter with "all from" and insert them into the record of:
template CBSP_PDU tr_CBSP_WRITE_CBS_opt(template uint16_t old_ser_nr, template uint8_t emerg_ind,
template CBSP_IEs more_ies) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE, ({
tr_OldSerNo(old_ser_nr),
tr_EmergencyInd(emerg_ind),
all from more_ies
})
);
This construct appears to be working for receive templates. It somehow doesn't appear to work if I'm doing the exact same for send templates. Even if all template arguments and the template itself have "template (value)", I get the following TITAN compiler error:
CBSP_Templates.ttcn:189.35-198.58: error: Restriction on template formal parameter does not allow usage of value list match
Any ideas?
|
|
|
Re: Q: TTCN3 and templates / lists of templates [message #1808249 is a reply to message #1808125] |
Thu, 20 June 2019 09:51 |
Gyorgy Rethy Messages: 31 Registered: April 2015 |
Member |
|
|
Hi herald,
correct, the all from is defined as a matching mechanism, which is working at receiving only.
For sending concatenation can be used. As I recall, concatenation is implemented for values only in Titan, so in this case the formal parameters shall be value-type, not template-type parameters. Like this:
template CBSP_PDU tr_CBSP_WRITE_CBS_opt (
uint16_t old_ser_nr,
uint8_t emerg_ind,
CBSP_IEs more_ies) :=
tr_CBSP(CBSP_MSGT_WRITE_REPLACE,
valueof({tr_OldSerNo(old_ser_nr),
tr_EmergencyInd(emerg_ind }) &
more_ies
)
);
[Updated on: Thu, 20 June 2019 09:54] Report message to a moderator
|
|
|
Re: Q: TTCN3 and templates / lists of templates [message #1809550 is a reply to message #1808249] |
Thu, 18 July 2019 05:31 |
|
Quote:As I recall, concatenation is implemented for values only in Titan, so in this case the formal parameters shall be value-type, not template-type parameters
This sounds if it's an implementation shortcoming? Is that correct, i.e. does the TTCN-3 spec permit for concatenation of templates? If yes, I would like to launch a feature request to have this implemented, if it doesn't exist yet. I know you guys have tons of things to do, and I'm not a customer. But it would be great to at least have it as a low-priority item on the feature list. Thanks!
|
|
| |
Goto Forum:
Current Time: Fri Apr 26 07:05:52 GMT 2024
Powered by FUDForum. Page generated in 0.06046 seconds
|