initial commit of tool to generate ladder diagrams

master
Harald Welte 13 years ago
commit a831a2a80b
  1. 16
      Makefile
  2. 156
      gen_ladder.pl
  3. 19
      test.lad

@ -0,0 +1,16 @@
GL=./gen_ladder.pl
DOT=dot
default:
%.dot: %.lad
$(GL) $^ > $@
%.ps: %.dot
$(DOT) -Tps < $^ > $@
%.svg: %.dot
$(DOT) -Tsvg < $^ > $@
clean:
rm *.dot *.ps *.svg

@ -0,0 +1,156 @@
#!/usr/bin/perl -w
use strict;
# Script to generate Graphviz (.dot) based ladder diagrams for network
# protocols
#
# (C) 2010 by Harald Welte <laforge@gnumonks.org>
my $cfg_parse_state;
my $cfg_parse_section;
my %cfg_entities;
my @cfg_entity_arr;
my $cfg_nr_entities = 0;
my @cfg_messages;
# parse a line of the config file
sub parse_cfg_line($)
{
my $line = shift;
if ($line =~ /^\#/ ||
$line =~ /^\s*$/) {
return;
}
#printf("sec=%s\n", $cfg_parse_section);
if ($line =~ /^\[/) {
($cfg_parse_section) = $line =~ /^\[(.*)\]/;
return;
}
if ($cfg_parse_section eq 'entities') {
my ($entity) = $line =~ /^(\w+)/;
$cfg_entities{$entity} = $cfg_nr_entities++;
push(@cfg_entity_arr, $entity);
} elsif ($cfg_parse_section eq 'messages') {
my ($src, $dst, $label, $flags) =
$line =~ /(\w+)\s+(\w+)\s+"(.*)"(.*)/;
my %msg;
$msg{'src'} = $src;
$msg{'dst'} = $dst;
$msg{'label'} = $label;
$msg{'flags'} = $flags;
# store a reference to the new hash on the global pile of
# message hash references
#print("$src $dst $label $flags\n");
push(@cfg_messages, \%msg);
}
}
# parse a line of the config file
sub parse_cfg_file($)
{
my $fname = shift;
open(INFILE, "<$fname");
while (my $line = <INFILE>) {
#print($line);
chomp($line);
parse_cfg_line($line);
}
close(INFILE);
}
# generate the nodes between which we will transfer messages
sub gen_nodes()
{
my $num_msgs = @cfg_messages;
foreach my $m (@cfg_entity_arr) {
printf(" %s [shape=none]\n", $m);
}
print("\n");
foreach my $m (@cfg_entity_arr) {
my $first = 0;
my $count;
# initial edge between header entity and the chain
printf(" %s -> %s0 [style=invis]\n", $m, $m);
# chain of edges between the individual nodes of one entity
for ($count = 0; $count < $num_msgs+1; $count++) {
my $name = sprintf("%s%u", $m, $count);
if ($first == 0) {
printf(" %s ", $name);
} else {
printf("-> %s ", $name);
}
$first = 1;
}
print(" [weight=1000]\n");
}
print("\n");
# invisible chain of edges between all entities
my $first = 1;
print(" { rank=same;\n edge[style=invis]\n");
foreach my $e (@cfg_entity_arr) {
if ($first) {
printf(" %s0 ", $e);
$first = 0;
} else {
printf("-> %s0 ", $e);
}
}
print("\n }\n");
print("\n");
}
sub entity_left_of($$)
{
my $l = shift;
my $r = shift;
if ($cfg_entities{$l} < $cfg_entities{$r}) {
return 1;
} else {
return 0;
}
}
# generate edges for the individual messages
sub gen_edges()
{
my $count = 1;
my $l; my $r; my $dir;
foreach my $m (@cfg_messages) {
if (entity_left_of($$m{'src'}, $$m{'dst'})) {
$l = $$m{'src'};
$r = $$m{'dst'};
$dir = 'forward';
} else {
$l = $$m{'dst'};
$r = $$m{'src'};
$dir = 'back';
}
print(" { rank=same;\n");
printf(" %s%u -> %s%u [dir=%s label=\"%s\"]\n }\n",
$l, $count, $r, $count, $dir, $$m{'label'});
$count++;
}
}
parse_cfg_file($ARGV[0]);
# print static header
print("digraph ladder {\n");
print(" node [shape=point]\n");
print(" edge [dir=none]\n");
# generate and print dynamic content
gen_nodes();
gen_edges();
# print footer
print("}\n");

@ -0,0 +1,19 @@
[entities]
# define the entities in the system (in order)
ms
bts
bsc
msc
hlr
[messages]
# define the protocol messages in-order
ms bts "L1 RACH burst"
bts bsc "RSL CHAN RQD"
bsc bts "RSL CHAN ACT REQ"
bts bsc "RSL CHAN ACT ACK"
bsc bts "RSL IMM ASS CMD"
bts ms "IMMEDIATE ASSIGN"
ms bsc "CM SERVICE REQUEST"
bsc msc "COMPL L3 INFO (CM SERV REQ)"
ms msc "Dedicated Channel" both dashed
Loading…
Cancel
Save