callflowcanvas.pm
来自「radius协议源码÷The Radius Stack will connect」· PM 代码 · 共 1,127 行 · 第 1/3 页
PM
1,127 行
#Set a default color for unknown reqres's. if (!defined $color) { $color = 'black'; } print "its color is $color\n" if DEBUG; return $color; }; #! This function could be cleaned up considerably by making %server_hash #! into an object capable of returning false (i.e. '') when a value #! can't be looked up. my $_draw_arrow = sub { my ($self, $sip_message) = @_; unless (ref $sip_message eq 'Telephony::SipMessage') { warn "\$sip_message is a " . ref ($sip_message); return; } my $canvas = $self->{canvas}; my $message_number = $self->{arrow_number}; print "in \&\$_draw_arrow\n" if DEBUG; print "Drawing arrow for SIP message\n" . Data::Dumper->Dump ([ $sip_message ]) if DEBUG_SIP_MESSAGES; my $source_ip = $sip_message->{source_ip}; my $source_port = $sip_message->{source_port}; if (!defined $source_ip) { warn "\&\$_draw_arrow got a message with no source IP; skipping...\n" . "\tthe message was " . Data::Dumper->Dump ([ $sip_message ]) . "\n\n" if DEBUG_SIP_MESSAGES; return; } if (!defined $source_port) { warn "\&\$_draw_arrow got a message with no source port; skipping...\n" . "\tthe message was " . Data::Dumper->Dump ([ $sip_message ]) . "\n\n" if DEBUG_SIP_MESSAGES; return; } my $destination_ip = $sip_message->{destination_ip}; my $destination_port = $sip_message->{destination_port}; if (!defined $destination_ip) { warn "\&\$_draw_arrow got a message with no destination IP; skipping...\n" . "\tthe message was " . Data::Dumper->Dump ([ $sip_message ]) . "\n\n" if DEBUG_SIP_MESSAGES; return; } if (!defined $destination_port) { warn "\&\$_draw_arrow got a message with no destination port; skipping...\n" . "\tthe message was " . Data::Dumper->Dump ([ $sip_message ]) . "\n\n" if DEBUG_SIP_MESSAGES; return; } my $source_ip_and_port = $source_ip . ':' . $source_port; my $destination_ip_and_port = $destination_ip . ':' . $destination_port; my $source = $self->{server_hash}->{$source_ip_and_port}; print "Got corresponding server: " . Data::Dumper->Dump ([ $source ]) . "\n" if DEBUG_SIP_MESSAGES; my $source_hposition = (ref $source eq 'Telephony::SipServer') ? $source->{hposition} : 0; my $destination = $self->{server_hash}->{$destination_ip_and_port}; print "Got corresponding server: " . Data::Dumper->Dump ([ $destination ]) . "\n" if DEBUG_SIP_MESSAGES; my $destination_hposition = (ref $destination eq 'Telephony::SipServer') ? $destination->{hposition} : 0; print "Drawing arrow for source $source_ip_and_port and destination $destination_ip_and_port...\n" if DEBUG_SIP_MESSAGES; my $x1 = $source_hposition; my $x2 = $destination_hposition; my $y1 = my $y2 = $self->{arrow_vposition}; my $color_coding = &$_get_arrow_color ($sip_message->{reqres}); print "Drawing $color_coding arrow from ($x1, $y1) to ($x2, $y2)\n" if DEBUG; $canvas->createLine ($x1, $y1, $x2, $y2, arrow => 'last', smooth => 1, fill => $color_coding, tags => [ "message_arrow_$message_number" ] ); my $label = $canvas->createText ($x1 < $x2 ? $x1 : $x2, $y1 - 12, text => "$message_number. $sip_message->{reqres}", anchor => 'nw', fill => $color_coding, font => $settings{canvas_default_font}, tags => [ "message_label_$message_number" ] ); $canvas->bind ($label, '<Button-1>', sub { print "Before call to \&\$draw_header_balloons, \$message_number is $message_number\n" if DEBUG; &$_draw_header_balloons ($self, $message_number, $sip_message, #closure! $x1 < $x2 ? $x1 : $x2, $y1); } ); #Move down the screen... $self->{arrow_vposition} += $settings{space_between_arrows}; $self->{arrow_number}++; }; #Insert a number into a filename, so that the various pages written #by $self->_take_snapshot_page have unique names. my $_increment_filename = sub { my ($self) = @_; print "Incrementing $self->{filename} to " if DEBUG; print "(the number is $self->{file_number}; incrementing it to " if DEBUG; $self->{file_number}++; print "$self->{file_number})... " if DEBUG; #For Windows users' sake, put the number before the first dot, #if there is one. { my $filename = $self->{filename}; my $file_number = $self->{file_number}; last if $filename =~ s|(\..*)|$file_number$1|; $self->{filename} .= $self->{file_number}; } print "$self->{filename}\n" if DEBUG; }; my $_take_snapshot_page = sub { my ($self) = @_; my $canvas = $self->{canvas}; #!my ($x1, $y1, $x2, $y2) = @{$self->{'x1', 'x2', 'y1', 'y2'}}; my $x1 = $self->{x1}; my $y1 = $self->{y1}; my $x2 = $self->{x2}; my $y2 = $self->{y2}; print "Saving snapshot for coordinates ($x1, $y1), ($x2, $y2) in $self->{output_filename}\n" if DEBUG_SNAPSHOTS; my $width = $x2 - $x1; my $height = $y2 - $y1; print "Width is $width; height is $height\n" if DEBUG_SNAPSHOTS == 2; my $snapshot_preferences = $self->{snapshot_preferences}; print "Making postscript with " . Data::Dumper->Dump ([ $snapshot_preferences, '$snapshot_preferences' ]) if DEBUG_SNAPSHOTS; my $postscript = $canvas->postscript (x => $x1, y => $y1, width => $width, height => $height, colormode => $snapshot_preferences->{colormode}, rotate => $snapshot_preferences->{rotate} ); print "Got postscript:\n$postscript" if DEBUG_POSTSCRIPT; my $output_filename = $self->{output_filename}; if (! open DIAGRAM, ">$output_filename") { carp ("Could not open the Postscript output file $output_filename for writing: $!"); return; } print "Printing Postscript to $output_filename...\n" if DEBUG_SNAPSHOTS == 2; print DIAGRAM $postscript; if (! close DIAGRAM) { &show_error ("Could not close the Postscript output file $output_filename: $!" ); return; } print "Closed $output_filename.\n" if DEBUG_SNAPSHOTS == 2; }; my $_do_snapshot = sub { my ($self) = @_; my $canvas = $self->{canvas}; $canvas->createRectangle ($self->{x1}, $self->{y1}, $self->{x2}, $self->{y2}, outline => 'blue') if UEBER_DEBUG_SNAPSHOTS; &$_increment_filename ($self); &$_take_snapshot_page ($self); }; my $_do_horizontal = sub { my ($self) = @_; if ($self->{x2} >= $self->{greatest_x}) { $self->{x2} = $self->{greatest_x}; &$_do_snapshot ($self); return; } while (1) { &$_do_snapshot ($self); } continue { $self->{x1} = $self->{x2}; $self->{x2} += $page_width; if ($self->{x2} >= $self->{greatest_x}) { $self->{x2} = $self->{greatest_x}; &$_do_snapshot ($self); return; } } }; my $_in_bbox = sub { my ($self, $arrow_id, $items) = @_; my @items = @$items; my $canvas = $self->{canvas}; foreach my $item (@items) { print "Looking in " . $canvas->gettags ($item) . "...\n" if DEBUG_SNAPSHOTS == 2; return 1 if grep /$arrow_id/, $canvas->gettags ($item); } return 0; }; #Push orphaned SIP messages onto the next page. The idea #is to keep separate instances of a single request or response #together when they are propagating through a series of servers. #For instance, all the 200 messages in a response to a BYE should #appear on the same page, even if that means leaving some blank space #on the preceding page. my $_adjust_snapshot_boundaries = sub { my ($self) = @_; my $canvas = $self->{canvas}; my $x1 = $self->{x1}; my $y1 = $self->{y1}; my $x2 = $self->{x2}; my $y2 = $self->{y2}; my @items = $canvas->find ('enclosed', $x1, $y1, $x2, $y2); print "The enclosed test gave coordinates ($items[0], $items[1]), ($items[3], $items[4])\n" if DEBUG_SNAPSHOTS; if (DEBUG_SNAPSHOTS == 2) { print "Adjusting items:\n"; foreach my $item (@items) { print "$item: " . $canvas->gettags ($item) . "\n"; } print "\n"; } #The items are already ordered from first-drawn (i.e. lowest on the #canvas) to last-drawn (i.e. highest on the canvas). #If the last-drawn item is a label, it must be an orphan to a message #arrow on the following page. my @filtered_items; foreach my $item (@items) { my $type = $canvas->type ($item); print "$item is a $type. " if DEBUG_SNAPSHOTS == 2; if ($type ne 'text') { #It's either an arrow or a bit of window dressing like a server #box's horizontal line. Either way, it's guaranteed not to be an #orphan. Include it. print "Keeping it...\n" if DEBUG_SNAPSHOTS == 2; push @filtered_items, $item; } else { my $text = $canvas->itemcget ($item, '-text'); print ": '$text'.\n" if DEBUG_SNAPSHOTS == 2; #Keep server boxes and labels and the lines drawn under them if (grep /server|line/, $canvas->gettags ($item)) { push @filtered_items, $item; print "It's a server glyph. Keeping it.\n" if DEBUG_SNAPSHOTS == 2; next; } $item =~ m|^(\d+)|; if (&$_in_bbox ($self, "message_arrow_$1", \@items)) { print "Keeping $item (a label with text $text)." if DEBUG_SNAPSHOTS == 2; push @filtered_items, $item; } #Otherwise leave $item out of the new list, since its arrow is out. elsif (DEBUG_SNAPSHOTS == 2) { print "Throwing out $item (a label with text $text):" . "\tIts corresponding message arrow was not included in this page.\n"; } } } #Find the type of SIP message label that belongs to the first #arrow on the next page (i.e. the first canvas item after the last #item on this page) my $last_item = $filtered_items[$#filtered_items]; my $next_label = $canvas->find ('above', $last_item); until ($canvas->type ($next_label) eq 'text') { $next_label = $canvas->find ('above', $next_label); if (! defined $next_label) { #An undefined label means we've reached the end of the output. @{$self->{'x1', 'y1', 'x2', 'y2'}} = $canvas->bbox (@items); last; } print "...and \$next_label is $next_label\n" if DEBUG_SNAPSHOTS == 2; } if (DEBUG_SNAPSHOTS == 2) { my @tags = $canvas->gettags ($next_label); print "The first label on the next page is " . Data::Dumper->Dump ([ $next_label ]) . "\nIts tags are " . Data::Dumper->Dump ([ \@tags ]) if DEBUG_SNAPSHOTS == 2; } my $next_label_text = $canvas->itemcget ($next_label, '-text'); print "\n\tIts text is $next_label_text\n" if DEBUG_SNAPSHOTS == 2; #Extract the SIP message type itself. my $next_SIP_message_type = ''; if (defined $next_label_text) { $next_label_text =~ m|\d+\.\s+(.*)|; $next_SIP_message_type = $1; print "Its message type is $next_SIP_message_type\n\n" if DEBUG_SNAPSHOTS == 2; } #Go backwards through the all the labels on the last page. for (my $i = $#filtered_items; $i > 0; $i--) { my $label = $filtered_items[$i]; next unless $canvas->type ($label) eq 'text'; my $label_text = $canvas->itemcget ($label, '-text'); if (defined $label_text) { print "Examining message '$label_text'...\n" if DEBUG_SNAPSHOTS == 2; $label_text =~ m|\d+\.\s+(.*)|; my $SIP_message_type = $1; if ($SIP_message_type eq $next_SIP_message_type) { print "It's another $next_SIP_message_type. Push it to the next page.\n" if DEBUG_SNAPSHOTS == 2; #If it's the same kind of message, it belongs on the next #page. Remove both its label and its arrow from our list #of items. splice @filtered_items, $i, 2; } else { print "It's a different type of message.\nLeave it where it is, and stop looking for orphans.\n\n" if DEBUG_SNAPSHOTS == 2; last; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?