CPN Tools 4: Message Sequence Charts

While colored Petri nets are graphical, they are also quite complex to explain to non-experts. This has previously been addressed by domain-specific visualizations (see also Mimic/CPN and the BRITNeY Suite).  One particularly useful visualization is message sequence charts.  This visualization is so useful, it has previously been implemented for Design/CPN, the predecessor of CPN Tools, and externally for CPN Tools using the BRITNeY Suite.

CPN Tools 4 brings this feature natively into CPN Tools (really it does so using simulator extensions, but that is completely transparent to users).  Users of the BRITNeY libraries will feel immediately at home.  In fact, most of the implementation comes directly from the BRITNeY Suite, but has been simplified slightly, and no longer requires any external programs.


The basic API is shown below:

Screen Shot 2013-09-29 at 17.54.19

This code is generated automatically from a Java interface, so it is more instructional to look at the original interface:

[java] public class MSCDispatcher implements NamedRPCHandler {
String structureName()

String createMSC(String name)

void addProcess(String id, String name)
void addEvent(String id, String from, String to, String text)
void addInternalEvent(String id, String process, String text)
void addLine(String id, String text)

String startEvent(String id, String from, String text)
void endEvent(String id, String identifier, String to)
void dropEvent(String id, String identifier)

String createStyle(String id, String foreground, String background)
void addProcessStyle(String id, String name, String style)
void addEventStyle(String id, String from, String to, String text, String style)
void addInternalEventStyle(String id, String process, String text, String style)
String startEventStyle(String id, String from, String text, String style)
void endEventStyle(String id, String identifier, String to, String style)

The structureName method is needed for the framework (fore reference it returns MSC; feel free to call it as much as you want). The createMSC creates a new MSC with the given name. The return value is an identifier, which is passed as the first parameter for all following functions. Creating a fresh MSC yields:

Screen Shot 2013-09-29 at 18.10.37

The initial MSC is a bit boring, so we can use the addProcess (l. 6) allows to add processes (or lifelines) to the chart.  addProcess just requires a MSC id (which we got from createMSC) and a process name:

Screen Shot 2013-09-29 at 18.14.01

We can no start adding events between the processes (ll. 7-8).  addEvent adds an event from one process to another, and addInternalEvent adds an event that is local to one process.  addInternalEvent is just a shorthand for using addEvent with the same process as from and to argument:

Screen Shot 2013-09-29 at 18.22.29

If our process has milestones or phases, we can indicate the switch by adding a line to the chart using addLine (l. 9):

Screen Shot 2013-09-29 at 18.24.48

So far, we have been dealing with atomic events only.  We can also deal with non-atomic events.  This is handled by the tartEvent, endEvent, and dropEvent methods (ll. 11-13).  startEvent initiates transmission from a process and returns a handle:

Screen Shot 2013-09-29 at 18.29.18

Event handles returned by startEvent can be used to either finish transmission successfully (endEvent) or unsuccessfully (dropEvent).  The order of doing so does not have to be the same as transmission order, allowing packages to overtake one another or simply disappear:

Screen Shot 2013-09-29 at 18.34.05

We can of course freely interleave all of these calls as desired.

We can also style all elements as we see fit.  We can create style handles with a background and foreground color (l. 15) and have styled versions of all calls (ll. 16-20) to create styled elements.  Colors are decoded with Java’s Color.decode method and accepts anything it accepts.

Screen Shot 2013-09-29 at 18.45.30


CPN Tools 4 ships with many example models.  One of these is a simple stop-and-wait protocol transmitting over an unreliable network.  This model also comes in a version which can draw a MSC from the execution.  The model overview looks like this:

Screen Shot 2013-09-29 at 18.50.41

For a detailed overview of the model, refer to the description of the simple protocol example.  Here, we only describe the modifications necessary to allow us to draw a MSC from the execution.  We have added declarations to the model:

[raw] (* MSC Setup *)
val msc = MSC.createMSC “MSC”
val sender = “Sender”
val receiver = “Receiver”
val _ = MSC.addProcess(msc, sender)
val _ = MSC.addProcess(msc, receiver)
fun mk_pk (n, p) =
String.concat [“(“, Int.toString n, “, \””, p, “\”)”] fun mk_ack n = Int.toString n
colset STRING = string;
var evt, evt’: STRING;
colset INTxDATAxEVT = product INT * DATA * STRING;
colset INTxEVT = product INT * STRING;

Lines 2-6 sets up the MSC and two processes, much like in our API overview above. mk_pk and mk_ack (ll. 7-9) are convenience methods for converting packages and acknowledgements to strings.

We have added a code segment to the Send Packet Transition using the startEvent method. This means we need to subsequently end or drop events, so we need to also transmit the package identifier. This is done by defining a STRING type (l. 10) and making sure to transmit the identifier along with packages and acknowledgements (ll. 11-13).

Transmit Packet and Transmit Ack have a code segment that drop the package/acknowledgement if the packet transmission is not successful. If transmission is successful, the packet is either received by the Receive Packet or Receive Acknowledgement transition, which ends the event correctly. The Receive Packet transition is also responsible for sending the acknowledgement, so it makes sure to also start the acknowledgement event.

As unique identifiers are used for each event, we can see individual packages overtaking one another even if they have the same content:

Screen Shot 2013-09-29 at 19.03.26

Despite the simplicity of the visualization, we can see many interesting concepts. We see packages overtaking one another (box 1), we see packages crossing one another (box 2), and we can see outstanding packages (box 3). We can of course also see dropped packages and how many retransmissions we have. For this example, we could also add milestones whenever we increment the sender counter (but remember that the counter may be decremented).

Here, we have used code segments to add visualizations. It is also possible to use monitors to achieve that. For an example of how to do that, see this example for the BRITNeY Suite. The idea is exactly the same here, except we need to provide the MSC identifier as the first parameter.


The astute reader may have noticed that the MSCs in this introduction all have a yellow tint whereas the evaluated code has a gray tint. This is not accidental.  This means that the yellow-tinted pages are “canvas” pages and not saved with the model.

Visualizations are expected to not be sufficiently important to save – they can easily be regenerated by simulating the model after all.  Saving each visualization is therefore wasteful.  This does not mean that is may not be interesting to perform actions that would normally be useful for pages, so instead of inventing an entirely new concept, we use canvas pages.  You can think of them as a draft page you trash as soon as your main product is finished.

You can do anything to elements on canvas pages you can do to regular elements.  All message sequence charts are nothing but completely standard auxiliary graphics.  This means we can use the standard style tools on them:

Screen Shot 2013-09-29 at 19.19.14

Canvas pages can be placed in binders like regular pages, and we can delete and move elements as we wish, and add new information if needed:

Screen Shot 2013-09-29 at 19.21.37

We can export a canvas page to EPS, which makes it possible to use it as a figure in a paper, and we can even clone the elements comprising the MSC:


Finally, if we clone a canvas page, the clone becomes a regular page that is saved with the net, reinforcing our metaphor that the canvas page is a draft page to be discarded for the final version.

Screen Shot 2013-09-29 at 19.25.59


In this introduction, we have see how to create message sequence charts in CPN Tools. We have been thru the API primitives and seen a practical example. We have also seen that visualizations in CPN Tools 4 are made on special canvas or draft pages, which are not saved with the model, but which can otherwise be manipulated as regular pages, including producing high-quality vector graphics for inclusion in papers and being turned into regular pages.

Too see this in action, check out this video.  MSCs start around 3:01:

3 thoughts on “CPN Tools 4: Message Sequence Charts

  1. Hi Michael,

    I would suggest two points:

    1- Adding to the current simulator extensions a library about drawing. Therefore, a CPN about traffic light, for example, could be visualized via CPN tool.

    2- Developing the simulator extensions by adding a button allows a new extension to be installed and added to the simulator extensions. Afterward, a new section about the extensions could be introduced on this website.

    Thank you for the series of CPN Tools 4 Extensions

    1. Hi Noah,

      Actually, both are handled.

      1) The extension server contains a graphics library (see https://westergaard.eu/2013/03/advanced-visualization-in-cpn-tools-4/ from around 5:35 and https://westergaard.eu/2013/10/cpn-tools-4-extensions-part-3-graphics-and-callbacks/ under Visualization callbacks). The library is written in Java because I feel more people are familiar with Java than SML and also because that kind of visualization is easier made using Java than SML. The old primitives (from the BRITNeY Suite and Mimic/CPN) were very cumbersome and rarely used outside of the Aarhus group where they were developed. The new primitives use paradigms (scenegraphs/composite design-pattern) that are very familiar to Java programmers. It is fairly easy to make a thin library on top of the Java library to allow simple visualizations (actually the MSC library contains such a wrapper for the higher level primitives provided by the MSC package).

      2) Adding a new extension is even simpler – just pack it in a JAR file and dump it in the <Install Dir>/extensions/plugins directory; any class implementing the Extension interface will be automatically loaded as an extension. If you’re doing active development, make sure that the extension server and your plugin is on the class path in your IDE, and launch the extension server (the one with auto-discovery). It will automatically recognize the extension and load it. For rapid development, you can even just close all nets, restart the extension server, and create a new model in CPN Tools without restarting the GUI or simulator. This also allows you to single-step thru your code and use break-points. Early plans included explicit tools for debugging extensions similar to what you described, but it would require tricky and error-prone messing with the class-path in Java, and have risks of leaving resources like TCP sockets or open files confusing things. Also, such tols would never be as powerful as what would be available in a real debugging IDE.

      Extensions are supposed to be de-centralized, so anybody creating an extension puts up their own documentation. Of course, at the request of authors, they are listed on the CPN Tools web-page, and particularly useful and well-tested extensions may move into the CPN Tools distribution.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.