OpenTTCN/Knowledge base/Message Interceptors

From OpenTTCN

Jump to: navigation, search

  OpenTTCN DocZone

  Home | Developer's corner | Knowledge base | Working documents | Documentation | OpenTTCN IDE | Tutorials | Training | How do I | Frequently asked questions | Technical support


Message Interceptors



Message interceptor concept: Normal message flow (1) vs. Message flow through interception point (2)
Message interceptor concept: Normal message flow (1) vs. Message flow through interception point (2)

This short article discusses creation of custom message interceptors and attaching them to port implementations using OpenTTCN SDK for C#.

Tools used: Technical preview of OpenTTCN Tester 2012, more specifically version 4.2.0beta5.0, and OpenTTCN SDK for C# (shipped with OpenTTCN Tester package).

Message interceptors allow modifying encoded messages going to/from SUT in a way that is transparent to the rest of the adapter/test system setup. This can be useful for example when a checksum needs to be inserted, a lower-layer header needs to be added/extracted, random frame errors need to be introduced for testing purposes, or comparable activities need to be performed with encoded messages.

Stateful message interceptor may even be used as a simple protocol layer simulator.

An interceptor can be attached to a port implementation. After it is attached, it starts receiving notifications whenever a message is going from TE to SUT, or whenever a message is enqueued from SUT to TE. Message is not forwarded further in the transmission chain before interceptor event handler returns. A message can be modified as a result of processing in the interceptor event handler. If the event handler modifies the message, the modified message is forwarded further in the transmission chain instead of the original one.

If the interceptor event handler assigns null to the modified message as a result of its processing, the message is not forwarded further in the transmission chain at all. Hence null is used by the interceptor to indicate that it has consumed the message completely, and it does not need to be forwarded any further.

Contents

Effect

The following methods are affected by the interceptor mechanism whenever it is in effect:


Image:language_mapping_c_sharp.png

  • Etsi.Ttcn3.Tri.ITriCommunicationSA.TriSend()
  • Etsi.Ttcn3.Tri.ITriCommunicationSA.TriSendBC()
  • Etsi.Ttcn3.Tri.ITriCommunicationSA.TriSendMC()
  • Etsi.Ttcn3.Tri.ITriCommunicationTE.EnqueueMessage()


ITriCommunicationSA callback handlers receive encoded message that might have already been modified by the interceptor attached to the relevant port. Modification (if any) happens after the original message is encoded by the encoder.

An interceptor attached to a port may modify a message going in the opposite direction transparently with regard to the rest of the adapter setup after the EnqueueMessage() method in the ITriCommunicationTE interface is called, but before the message is passed to the decoder. Hence the decoder receives a modified message if the modification is actually performed.

Attaching Interceptor to a Port

Before an interceptor can be used, it needs to be attached to the port, message traffic of which it is going to intercept.

Attaching and detaching an interceptor is done by using the following API calls:


Image:language_mapping_c_sharp.png

  • OpenTTCN.Sdk.StartHereSA.AttachMessageInterceptor()
  • OpenTTCN.Sdk.StartHereSA.DetachMessageInterceptor()


See relevant SDK documentation section for more details on using these calls.

Currently only one interceptor can be attached to a port at a time.

Attaching a new interceptor to the same port silently detaches an old interceptor before attaching the new one.

Code Example

A simple interceptor in the example below adds a fixed-length header to every message going to the SUT and extracts a fixed-length header from every message received from the SUT. Header length is two octets. Header value is also constant and contains a sequence of 0xA1, 0xB5 octets.

Example of interceptor implementation:


Image:language_mapping_c_sharp.png

using System;

using OpenTTCN.Sdk;

using Etsi.Ttcn3.Tci;
using Etsi.Ttcn3.Tri;

using EncodeBuffer = OpenTTCN.Sdk.Util.EncodeBuffer;

public class SimpleInterceptor : IMessageInterceptor
{
    public void EnqueuedMessageToSUT(ref ITriMessage msg, InterceptorContext ctx)
    {
        EncodeBuffer buff = new EncodeBuffer();
        buff.Append(new byte[] { 0xA1, 0xB5 }); // fixed-length header
        buff.Append(msg);

        msg = buff.ToTriMessage();
    }

    public void EnqueuedMessageToTE(ref ITriMessage msg, InterceptorContext ctx)
    {
        // Remove fixed-length header:

        EncodeBuffer buff = new EncodeBuffer();
        buff.Append(msg.EncodedMessage, msg.NumberOfBits - 16, 16);

        msg = buff.ToTriMessage();
    }

    public void Reset()
    {
        // Called when TriSAReset() in the Etsi.Ttcn3.Tri.ITriCommunicationSA
        // interface is called.

        // Does nothing for now. Add your own handler of the reset event here.
    }
}


Example of attaching the above interceptor to a port:


Image:language_mapping_c_sharp.png

using OpenTTCN.Sdk;

...

StartHereSA.AttachMessageInterceptor("myTsiPort", new SimpleInterceptor());

...


Example of detaching an already attached interceptor from the port:


Image:language_mapping_c_sharp.png

using OpenTTCN.Sdk;

...

StartHereSA.DetachMessageInterceptor("myTsiPort");

...

Possible Use Cases

The message interceptor concept can be used, for example, for:

  • encryption and decryption of messages sent and received,
  • printing additional debug information for messages sent and received,
  • recording time stamp information,
  • introducing single or multiple bit errors when sending messages controlled by control messages or external function calls, or
  • calculation of checksums.
Views
Personal tools