Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Titan » 'ifpresent' or ternary operator in parametric send templates
'ifpresent' or ternary operator in parametric send templates [message #1781028] Wed, 31 January 2018 16:26 Go to next message
Harald Welte is currently offline Harald WelteFriend
Messages: 140
Registered: July 2017
Location: Berlin, Germany
Senior Member

I'm often running into use cases where I have TLV type structures in protocols.

Now if I want to have a parametric template that can be used for encoding a message both with and without the TLV, I end up with something like this:

//24.008/ 10.5.1.7
type record MobileStationClassmark3_TLV
{
  OCT1  elementIdentifier,
  LIN1  lengthIndicator,
  OCTN  valuePart
} with {
  variant "PRESENCE (elementIdentifier = '20'O)"
  variant (lengthIndicator) "LENGTHTO (valuePart)"
};


template PDU_ML3_MS_NW ts_RRM_CM_CHG(MobileStationClassmark2_LV cm2,
                                             template MobileStationClassmark3_TLV cm3 := omit) := {
        discriminator := '0110'B,
        tiOrSkip := {
                skipIndicator := '0000'B
        },
        msgs := {
                rrm := {
                        classmarkChange := {
                                messageType := '00010110'B,
                                mobileStationClassmark2 := cm2,
                                mobileStationClassmark3 := cm3
                }
        }
}


This way I can use the template to send a message with CM2 only, or one that also has CM3. fine.

However, from a usability point of view it is "ugly" because it's not user friendly. What the user actually wants to specify is the MobileStationClassmark3_TLV.valuePArt, and not the "TLV wrapper", so the template should look like this:

template MobileStationClassmark3_TLV ts_CM3_TLV(OCTN cm3) := {
        elementIdentifier := '20'O,
        lengthIndicator := 0, /* overwritten */
        valuePart := cm3
}

template PDU_ML3_MS_NW ts_RRM_CM_CHG(MobileStationClassmark2_LV cm2, template OCTN cm3 := omit) := {
       discriminator := '0110'B,
        tiOrSkip := {
                skipIndicator := '0000'B
        },
        msgs := {
                rrm := {
                        classmarkChange := {
                                messageType := '00010110'B,
                                mobileStationClassmark2 := cm2,
                                mobileStationClassmark3 := ts_CM3_TLV(cm3),
                }
        }
}


but now the problem is, that the ts_CM3_TLV() will always return a MobileStationClassmark3_TLV - whether or not the input argument 'cm3' is 'omit' or whether it's an actual value.

So basically, I would like to create templates which return omit if their argument/parameter is omit.

In C, one would be able to use this with the ternary operator in a syntax like "mobileStationClassmark3 = cm3 ? ts_CM3_TLV(cm3) : NULL" and I would love if something like that existed in TTCN3. However, it apparently doesn't.

On the matching / receiving side, I've seen the "ifpresent" qualifier which is very useful in simiar cases. However, for the transmit / send template site I haven't found any solution. Please let me know if I simply haven't studied the language spec sufficiently, or if it really doesn't exist. To me, it's one of the most common patterns in generating send/generate/transmit messages in protocol testing.

One workaround seems to be to define a function which returns a template, and then in that function one can of course use conditional expressions like:

function ts_RRM_CM_CHG(MobileStationClassmark2_LV cm2, template MobileStationClassmark3_TLV cm3 := omit) return template PDU_ML3_MS_NW {
        var template PDU_ML3_MS_NW ret;
        if (not ispresent(cm3)) {
                return omit;
        }
        ret := {
             discriminator := '0110'B,
             tiOrSkip := {
                    skipIndicator := '0000'B
            },
            msgs := {
                    rrm := {
                            classmarkChange := {
                                    messageType := '00010110'B,
                                    mobileStationClassmark2 := cm2,
                                    mobileStationClassmark3 := ts_CM3_TLV(cm3)
                    }
            }
       }
       return ret;
}


but as you can see, it's quite verbose / lengthy, and it is using a very imperative programming approach, whereas I've perceived the strengty of TTCN-3 to be its declarative nature - which allows it to be extremely expressive without having to write lots of code. Declaring separate copy+pasted templates for the CM2-only and the CM2+CM3 case is also not really nice, as it's copy+paste programming.

Another approach is

function ts_CM3_TLV(template OCTN cm3) return template MobileStationClassmark3_TLV {
        if (not isvalue(cm3)) {
                return omit;
        }
        var template MobileStationClassmark3_TLV ret := {
            elementIdentifier := '20'O,
            lengthIndicator := 0, /* overwritten */
            valuePart := cm3
        }
        return ret;
}

template PDU_ML3_MS_NW ts_RRM_CM_CHG(MobileStationClassmark2_LV cm2, template OCTN cm3 := omit) := {
       discriminator := '0110'B,
        tiOrSkip := {
                skipIndicator := '0000'B
        },
        msgs := {
                rrm := {
                        classmarkChange := {
                                messageType := '00010110'B,
                                mobileStationClassmark2 := cm2,
                                mobileStationClassmark3 := ts_CM3_TLV(cm3),
                }
        }
}


But that's still quite verbose and my aesthetics sense says it's just a hack and not an elegant and/or expressive solution.

Any hints from those more experienced?
Re: 'ifpresent' or ternary operator in parametric send templates [message #1781069 is a reply to message #1781028] Thu, 01 February 2018 07:43 Go to previous messageGo to next message
roland gecse is currently offline roland gecseFriend
Messages: 20
Registered: December 2015
Junior Member
I would advise to separate the transport handling from the protocol business logic. It does not extend TTCN-3 templates' capabilities but improves the readability of your test suite.

You could introduce some transport ASPs representing the methods you intend to use the underlying transport. One ASP could have the PDU as its sole content. It could be used when you want the TAG and LENGTH calculated automatically. Another ASP could additionally include TAG and LENGTH for those cases when you want to set TAG and LENGTH explicitly.

You have the option to implement your ASPs in C++ as a Test Port or in TTCN-3 as dual-faced/translation port. (Refer to Elemer's article for hints and examples about the latter!)
An instance of this test port or component would act as a port mapper between your Tester and SUT. It would abstract away lower level transport related functionality. The test cases would then send/receive PDUs by invoking the appropriate ASPs instead of encoding/decoding transport layer data.

Hope this makes sense.
Re: 'ifpresent' or ternary operator in parametric send templates [message #1781081 is a reply to message #1781069] Thu, 01 February 2018 09:18 Go to previous messageGo to next message
Harald Welte is currently offline Harald WelteFriend
Messages: 140
Registered: July 2017
Location: Berlin, Germany
Senior Member

Hi Roland,

I completely agree with your statement - if I want to implement/emulate the entire "transport protocol". Whenever that's the case, I implement PTCs just doing thaty "protocol emulation". Or Whenever I need to encode/decode, I use dual-faced or translation ports.

However, in this particular case, what I want to do is to test the implementation of the same protocol in the IUT. So I need to (very flexibly) construct PDUs and send them to the IUT, and then match on the proper response. Let's say I want to have one test where the PDU contains Classmark3, and another one that doesn't contain Classmark3. And then I end up exactly with the problem outlined above.

Isn't it then the job of the templates to help me to be very expressive in writing such tests, rather than copy+pasting every single template N number of times?

What's the best approach to handle this in TTCN-3/TITAN, using the most expressive/declarative, least verbose/time-consuming/copy-pasting/imperative way?
Re: 'ifpresent' or ternary operator in parametric send templates [message #1781170 is a reply to message #1781081] Fri, 02 February 2018 09:33 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Harald,

the language does not offer such a feature currently; however if there is a strong use case and you make a proposal, we'll consider
implementing it and and also submitting it as a change request to the standard.

Deviating from the standard, even with extensions, has its downside: it makes your code less portable.
Practically , as there are only a handful of tools, and the test adapter/codec part not being standardized, this is a weak argument as you cannot get away without serious
modding when migrating from one tool to another.

Best regards
Elemer








Re: 'ifpresent' or ternary operator in parametric send templates [message #1807737 is a reply to message #1781170] Fri, 07 June 2019 06:24 Go to previous messageGo to next message
Vadim Yanitskiy is currently offline Vadim YanitskiyFriend
Messages: 5
Registered: May 2018
Junior Member
Hello everyone!

I am agree with Harald, it really feels like a missing feature when you have to complement templates for TLV-based protocols with supplementary functions like the one mentioned above, or even additional templates. A good example I personally had to deal with is the RELEASE COMPLETE message defined in GSM TS 04.80 "Supplementary services specification, Formats and coding", section 2.5, which is used to terminate SS/USSD sessions:

+------+-------------------------------+-----------+---------+---------+
| IEI  | Type of Information Element   | Presence  | Format  | Length  |
+------+-------------------------------+-----------+---------+---------+
|      | Protocol discriminator (3.2)  |     M     |    V    |   1/2   |
+------+-------------------------------+-----------+---------+---------+
|      | Transaction identifier (3.3)  |     M     |    V    |   1/2   |
+------+-------------------------------+-----------+---------+---------+
|      | Message type (3.4, REL COMPL) |     M     |    V    |    1    |
+------+-------------------------------+-----------+---------+---------+
|  08  | Cause (see GSM 04.08)         |     O     |   TLV   |   4-32  |
+------+-------------------------------+-----------+---------+---------+
|  1C  | Facility (3.5)                |     O     |   TLV   |   2-?   |
+------+-------------------------------+-----------+---------+---------+


where we basically have two optional IEs represented by TLVs. Our templates for GSM 04.80 are based on 'MobileL3_Types.ttcn' from 'titan.ProtocolModules.MobileL3_v13.4.0', so we define RELEASE COMPLETE message (let's focus on Mobile Originated matching template) as follows:

private template Facility_TLV tr_FacTLV(template OCTN facility) := {
	elementIdentifier := '1C'O,
	lengthIndicator := ?,
	facilityInformation := facility
}

private function f_facility_or_wc(template OCTN facility)
return template Facility_TLV {
	if (istemplatekind(facility, "*")) {
		return *;
	} else if (istemplatekind(facility, "?")) {
		return ?;
	} else if (istemplatekind(facility, "omit")) {
		return omit;
	} else {
		return tr_FacTLV(facility);
	}
}


template PDU_ML3_MS_NW tr_ML3_MO_SS_RELEASE_COMPLETE(
	template uint3_t tid, template BIT1 ti_flag,
	template ML3_Cause_TLV cause := *,
	template OCTN facility := *
) := {
	discriminator := '1011'B,
	tiOrSkip := {
		transactionId := {
			/* Transaction Identifier */
			tio := f_tid_or_wc(tid),
			tiFlag := ti_flag,
			tIExtension := omit
		}
	},
	msgs := {
		ss := {
			releaseComplete_MS_NW := {
				messageType := '101010'B,
				nsd := '00'B,
				/* Optional Cause IE (TLV) */
				cause := cause,
				/* Optional Facility IE (TLV) */
				facility := f_facility_or_wc(facility)
			}
		}
	}
}


where both f_tid_or_wc() and f_facility_or_wc() return either a matching pattern (* or ?), or BIT3 and Facility_TLV templates respectively. For the Cause IE, we do accept a template of type ML3_Cause_TLV, because it is not trivial. But for the Facility IE, I want to pass the encoded payload, but not the whole TLV of type tr_FacTLV.

Of course, having something like the ternary operator would allow to avoid introducing both f_facility_or_wc() and f_tid_or_wc() functions. However, we still would have to mix the imperative and declarative approaches.

What if we could extend the existing declarative approach for that? I was thinking about the 'PRESENCE' attribute, which allows to define presence of particular fields, as well as presence of the whole record. In module 'MobileL3_CommonIE_Types.ttcn' of 'titan.ProtocolModules.MobileL3_v13.4.0' we have the following definition:

//10.5.4.15 Facility IE (see also 24.080/3.6)
type record Facility_TLV
{
	OCT1  elementIdentifier, // H'1C
	LIN1  lengthIndicator, // 0..?
	OCTN  facilityInformation  optional //see 24.080/3.6
} with {
	variant (lengthIndicator) "LENGTHTO (facilityInformation)"
};


which could have an alternative form:

//10.5.4.15 Facility IE (see also 24.080/3.6)
type record Facility_XTLV
{
	OCT1  elementIdentifier, // H'1C
	LIN1  lengthIndicator, // 0..?
	OCTN  facilityInformation
} with {
	variant (lengthIndicator) "LENGTHTO (facilityInformation)"
	variant                   "PRESENCE (facilityInformation)"
};

private template Facility_XTLV tr_FacXTLV(template OCTN facility) := {
	elementIdentifier := '1C'O,
	lengthIndicator := ?,
	facilityInformation := facility
}


where 'facilityInformation' defines presence of the whole record. If isvalue(facility), then we consider the whole TLV is present. Otherwise, e.g. tr_FacXTLV(*) would turn into *, tr_FacXTLV(?) would turn into ?, and tr_FacXTLV(omit) would turn into omit. The main difference is that the existing tr_FacTLV(*) would turn into LV (length = 0) if 'facilityInformation' is ommited, what is not acceptable in GSM 04.80.

As far as I know, this attribute itself is an extension of TTCN-3, so we could make the existing extension a bit more flexible instead of introducing even more extensions, such as the ternary operator. This is just an idea, and it may look/sound stupid since my TTCN-3 experience is limited. But anyway, what do you think?


With best regards,
Vadim Yanitskiy.
Re: 'ifpresent' or ternary operator in parametric send templates [message #1807902 is a reply to message #1807737] Wed, 12 June 2019 06:04 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Vadim,

thank you for your feedback,

we will look into it in detail in come back to you;

I can only reiterate my offer above: if you have a concrete request we can submit it to ETSI on your behalf to be accepted as an addition to the existing standard, pending acceptance of the
other members of the TTCN-3 language committee.


Best regards
Elemer


Re: 'ifpresent' or ternary operator in parametric send templates [message #1808036 is a reply to message #1807902] Fri, 14 June 2019 09:55 Go to previous messageGo to next message
Gyorgy Rethy is currently offline Gyorgy RethyFriend
Messages: 31
Registered: April 2015
Member
Actually, two things are mixing here. Templates are part of the type/data system of TTCN-3, they are *basically* not meant to have dynamic behaviour - though have limited abilities to be constructed dynamically (parameterization, functions called in actual parameters, template fields etc.). For the full fletched dynamic behavior functions (testcase, control part etc.) and variables are intended.
So, Harald's solution with
function ts_CM3_TLV(template OCTN cm3) return template MobileStationClassmark3_TLV {...}
is not a workaround, but the way how such situation are meant to be solved.

Still, the PRESENCE encoding instruction could work; it's PRO is its simplicity and convenience; it's CON is that part of the dynamic behavior happens in the codec, in a hidden way, hardly seen from the TTCN-3 code (one shall be real expert to know what is *actually* happening due to the presence of PRESENCE :)) that may raise maintainability questions.
Re: 'ifpresent' or ternary operator in parametric send templates [message #1808261 is a reply to message #1808036] Thu, 20 June 2019 17:50 Go to previous messageGo to next message
Harald Welte is currently offline Harald WelteFriend
Messages: 140
Registered: July 2017
Location: Berlin, Germany
Senior Member

Quote:

Templates are part of the type/data system of TTCN-3, they are *basically* not meant to have dynamic behaviour


I would argue that we're not actually adding dynamic behavior (like test logic or arbitrary code),but we're just creating _useable_ templates. I don't want any complex logic, but simply a user/caller friendly template that constructs (or matches) a given parametrized message.

I guess part of this problem comes from the RAW codec and how you can use it to express encoding of the binary data. So the "abstract" TTCN-3 type is actually not all that abstract anymore, but it resembles the binary data only in as far as you can convert from that abstract data type using RAW codec syntax to the concrete binary encoding and vice-versa. While I really love it, it has some constraints on how you define your "abstract" TTCN-3 types.

To me, the templates exist as a way to make it as convenient as possible for the user (testcase and testcase author) to express a given message of a communication system. And the existing TTCN-3 language, particularly in its TITAN implementation togetherwith the RAW codec make it - IMHO- unneccessarily hard. So you end up having to write three, four different send and receive templates for a single "message type" of your protocol, just because you're lacking some "expressivity'. Not being able to use the '&' operator with templates but only with values is a related problem that really affects me literally every day, but that is discussed in a separate thread.

Of course, if you were to write your encoders/decoders by hand in C++ and had completely abstract data types, then you could hide all that complexity in the C++ encoder/decoder. But that would neither be elegant nor time/resource saving.

To me, the high-level goals are
* write as little as code that's as easy as possible to read ("expressivity + maintainable code")
* make receive and templates as convenient as possible to use by test cases, i.e. their arguments should be 'user friendly' and as abstract as possible from the actual binary representation
* reduce code duplication at all cost

Having to write template-generating functions for each and every type, full of "istemplatekind" select/case constructs checking for omit/*/? is very verbose, duplicates the same principal code all over the place and is difficult to read and maintain. It also is easy to make mistakes when copy+pasting code all over again and again. It actually makes me think of wantin to generate TTCN-3 code from other code, as this is way too much mechanical/boilerplate repetition for a human developer to spend time on.

For my most recent example, see http://git.osmocom.org/osmo-ttcn3-hacks/tree/library/CBSP_Templates.ttcn?h=laforge/cbsp#n325 and the following lines. and look for all the istemplatekind clauses :/

So whatever construct that can help us to avoid that, I'm all in for it :)
Re: 'ifpresent' or ternary operator in parametric send templates [message #1809070 is a reply to message #1808261] Mon, 08 July 2019 09:36 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Harald,


if we receive a consistent proposal, we can submit it to ETSI to be accepted as part of the standard.
Of course we have only one vote in the board that will accept the change request, so the outcome is not guaranteed.

In case it's rejected we can still implement it as an extension, but firstly, we'd prefer not to go against the ( hard to define, I admit ) spirit of the standard.,
and secondly , any non-standard extension decreases the portability of the code ( in full honesty, more a theoretical concern ).

So I 'd suggest to start from a proposal that formulates a construct that solves your problem and integrates with the standard as seamlessly as possible.

Thank you and best regards
Elemer




Re: 'ifpresent' or ternary operator in parametric send templates [message #1809072 is a reply to message #1809070] Mon, 08 July 2019 09:51 Go to previous message
Gyorgy Rethy is currently offline Gyorgy RethyFriend
Messages: 31
Registered: April 2015
Member
Actually, the ETSI TTCN-3 maintenance team is quite open minded to user proposals. It would be even more efficient, if - after discussing and agreeing on the content - OSMOCOM is submitted the CR. CRs coming from real users get more focus.
The "danger" here is that other experts in the STF will have ideas, how to make the solution even better, more general; so often not the original proposal, as is, will be the final solution.
That's why it doesn't make sense to implement something before ETSI decides regarding a concrete proposal.
BR, Gyorgy
Previous Topic:ETSI ES 201 873-1 V4.10.1 (2018-05) question
Next Topic:Minimalistic assistance for CSN.1 L/H in the RAW codec?
Goto Forum:
  


Current Time: Thu Mar 28 18:09:26 GMT 2024

Powered by FUDForum. Page generated in 0.02757 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top