mirror of
				https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
				synced 2025-11-03 20:27:54 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			402 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			402 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
package Tid;
 | 
						|
 | 
						|
use strict;
 | 
						|
use warnings;
 | 
						|
use diagnostics;
 | 
						|
use bigint;
 | 
						|
use bignum;
 | 
						|
use Carp;
 | 
						|
$SIG{ __DIE__  } = sub { Carp::confess( @_ ) };
 | 
						|
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
 | 
						|
 | 
						|
my $warn_dup_ba_once = 1;
 | 
						|
my $max_pkt_store = 250;
 | 
						|
 | 
						|
sub new {
 | 
						|
  my $class = shift;
 | 
						|
  my %options = @_;
 | 
						|
 | 
						|
  my $self = {
 | 
						|
              pkts => [],
 | 
						|
              rx_no_ack_found_all => 0,
 | 
						|
              rx_no_ack_found_big => 0,
 | 
						|
              tx_no_ack_found_all => 0,
 | 
						|
              tx_no_ack_found_big => 0,
 | 
						|
              tx_retrans_pkts => 0,
 | 
						|
              rx_retrans_pkts => 0,
 | 
						|
              tx_amsdu_retrans_pkts => 0,
 | 
						|
              rx_amsdu_retrans_pkts => 0,
 | 
						|
              rx_pkts => 0,
 | 
						|
              tx_pkts => 0,
 | 
						|
              rx_amsdu_pkts => 0,
 | 
						|
              tx_amsdu_pkts => 0,
 | 
						|
              dummy_rx_pkts => 0,
 | 
						|
              dummy_tx_pkts => 0,
 | 
						|
              tot_pkts => 0,
 | 
						|
              last_tot_pkts => 0,
 | 
						|
              last_rx_pkts => 0,
 | 
						|
              last_tx_pkts => 0,
 | 
						|
              last_rx_retrans_pkts => 0,
 | 
						|
              last_tx_retrans_pkts => 0,
 | 
						|
              last_dummy_rx_pkts => 0,
 | 
						|
              last_dummy_tx_pkts => 0,
 | 
						|
              last_ps_timestamp => 0,
 | 
						|
              last_rx_amsdu_pkts => 0,
 | 
						|
              last_tx_amsdu_pkts => 0,
 | 
						|
              last_tx_amsdu_retrans_pkts => 0,
 | 
						|
              last_rx_amsdu_retrans_pkts => 0,
 | 
						|
              %options,
 | 
						|
             };
 | 
						|
 | 
						|
  bless($self, $class);
 | 
						|
 | 
						|
  if (0) { # Skip per-tid reporting files for now.
 | 
						|
    # I am seeing failure due to > 1024 files being opened, and we don't
 | 
						|
    # use these anyway...
 | 
						|
    my $rpt_fname = $self->{report_prefix} .
 | 
						|
      "tid-" . $self->tidno() . "-" .
 | 
						|
        $self->{addr_a} . "." .
 | 
						|
          $self->{addr_b} . "-rpt.txt";
 | 
						|
    open(my $MCS, ">", $rpt_fname) or die("Can't open $rpt_fname for writing: $!\n");
 | 
						|
    $self->{mcs_fh} = $MCS;
 | 
						|
 | 
						|
    $rpt_fname = $self->{report_prefix} . "tid-" . $self->tidno() . "-" . $self->{addr_a} . "." . $self->{addr_b} . "-ps-rpt.txt";
 | 
						|
    open(my $MCS_PS, ">", $rpt_fname) or die("Can't open $rpt_fname for writing: $!\n");
 | 
						|
    $self->{mcs_fh_ps} = $MCS_PS;
 | 
						|
 | 
						|
    $rpt_fname = $self->{report_prefix} . "tid-" . $self->tidno() . "-" . $self->{addr_a} . "." . $self->{addr_b} . "-ba-rpt.txt";
 | 
						|
    open(my $BA, ">", $rpt_fname) or die("Can't open $rpt_fname for writing: $!\n");
 | 
						|
    $self->{fh_ba} = $BA;
 | 
						|
  }
 | 
						|
 | 
						|
  return $self;
 | 
						|
}
 | 
						|
 | 
						|
sub tidno {
 | 
						|
  my $self = shift;
 | 
						|
  return $self->{tidno};
 | 
						|
}
 | 
						|
 | 
						|
sub add_pkt {
 | 
						|
  my $self = shift;
 | 
						|
  my $pkt = shift;
 | 
						|
 | 
						|
  $self->{tot_pkts}++;
 | 
						|
  if ($pkt->receiver() eq $self->{addr_a}) {
 | 
						|
    $pkt->{is_rx} = 1;
 | 
						|
    $self->{rx_pkts}++;
 | 
						|
    $self->{rx_amsdu_pkts} += $pkt->{amsdu_frame_count};
 | 
						|
    if ($pkt->retrans()) {
 | 
						|
      $self->{rx_retrans_pkts}++;
 | 
						|
      $self->{rx_amsdu_retrans_pkts} += $pkt->{amsdu_frame_count}
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    $pkt->{is_rx} = 0;
 | 
						|
    $self->{tx_pkts}++;
 | 
						|
    $self->{tx_amsdu_pkts} += $pkt->{amsdu_frame_count};
 | 
						|
    if ($pkt->retrans()) {
 | 
						|
      $self->{tx_retrans_pkts}++;
 | 
						|
      $self->{tx_amsdu_retrans_pkts} += $pkt->{amsdu_frame_count};
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if ($self->{last_ps_timestamp} == 0) {
 | 
						|
    $self->{last_ps_timestamp} = $pkt->timestamp();
 | 
						|
  }
 | 
						|
 | 
						|
  my $pkt_count = @{$self->{pkts}};
 | 
						|
 | 
						|
  # If this is a block-ack, then check for previous frames that would match.
 | 
						|
  if ($pkt->type_subtype() eq "802.11 Block Ack (0x0019)") {
 | 
						|
    my $ba_dup = 0;
 | 
						|
    my $ba_tot = 0;
 | 
						|
    my $transmitter = $pkt->transmitter();
 | 
						|
    my $starting_seqno = $pkt->{ba_starting_seq};
 | 
						|
    my $i;
 | 
						|
    my $bitmap = $pkt->{ba_bitmap}; # 0100000000000000 for instance
 | 
						|
    my $bi_as_long = 0;
 | 
						|
    my $bi_mask = 0;
 | 
						|
    my $q;
 | 
						|
    my $last_timestamp = 0;
 | 
						|
    my $glb;
 | 
						|
 | 
						|
    if ($pkt->transmitter() eq $self->{addr_a}) {
 | 
						|
      $glb = $self->{glb_fh_ba_tx};
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      $glb = $self->{glb_fh_ba_rx};
 | 
						|
    }
 | 
						|
    for ($q = 0; $q < 8; $q++) {
 | 
						|
      my $bmap_octet = substr($bitmap, $q * 2, 2);
 | 
						|
      my $bmi = hex($bmap_octet);
 | 
						|
      #print STDERR "bmap-octet: $bmap_octet bmi: " . hex($bmi) . "\n";
 | 
						|
      $bi_as_long |= ($bmi << ($q * 8));
 | 
						|
    }
 | 
						|
 | 
						|
    for ($i = 0; $i<$pkt_count; $i++) {
 | 
						|
      my $tmp = $self->{pkts}[$i];
 | 
						|
      #print "checking tmp-pkt frame: " . $tmp->{frame_num} . " seqno: " . $tmp->seqno();
 | 
						|
      #print " transmitter: " . $tmp->transmitter();
 | 
						|
      #print " pkt-rcvr: " . $pkt->receiver() . "\n";
 | 
						|
      #print "Starting_seqno:$starting_seqno\n";
 | 
						|
      if ($tmp->transmitter() eq $pkt->receiver()) {
 | 
						|
        if (($tmp->seqno() >= $starting_seqno) && ($tmp->seqno() < ($starting_seqno + 64))) {
 | 
						|
          # tmp pkt might match this BA bitmap..check closer.
 | 
						|
          my $diff = $tmp->seqno() - $starting_seqno;
 | 
						|
          if ($bi_as_long & (1 << $diff)) {
 | 
						|
            # Found a matching frame.
 | 
						|
            $bi_mask |= (1 << $diff);
 | 
						|
 | 
						|
            if ($tmp->block_acked_by() != -1) {
 | 
						|
              # This seems to be a common thing, warn once and not again.
 | 
						|
              if ($warn_dup_ba_once) {
 | 
						|
                print "WARNING:  block-ack frame: " . $pkt->frame_num() . " acking frame: " .
 | 
						|
                  $tmp->frame_num() . " already block-acked by frame: " . $tmp->block_acked_by() . ".  This warning will not be shown again.\n";
 | 
						|
                $warn_dup_ba_once = 0;
 | 
						|
              }
 | 
						|
              $ba_dup++;
 | 
						|
            }
 | 
						|
            elsif ($tmp->acked_by() != -1) {
 | 
						|
              print "WARNING:  block-ack frame: " . $pkt->frame_num() . " acking frame: " .
 | 
						|
                $tmp->frame_num() . " already acked by frame: " . $tmp->acked_by() . "\n";
 | 
						|
            }
 | 
						|
            $tmp->set_block_acked_by($pkt->frame_num());
 | 
						|
            $ba_tot++;
 | 
						|
 | 
						|
            # Only calculate timestamp if previous packet was last one ACKd and it is not a dummy
 | 
						|
            # otherwise we probably failed to capture some frames.
 | 
						|
            if ($i == ($pkt_count - 1)) {
 | 
						|
              if ($tmp->{raw_pkt} ne "") {
 | 
						|
                $last_timestamp = $tmp->timestamp();
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }# for all pkts
 | 
						|
 | 
						|
    # See if we block-acked anything we could not find?
 | 
						|
    if ($bi_mask != $bi_as_long) {
 | 
						|
      my $missing = $bi_mask ^ $bi_as_long;
 | 
						|
      my $missing_str = "";
 | 
						|
      for ($i = 0; $i<64; $i++) {
 | 
						|
        if ($missing & (1<<$i)) {
 | 
						|
          my $missing_seqno = $starting_seqno + $i;
 | 
						|
          $missing_str .= $missing_seqno . " ";
 | 
						|
 | 
						|
          # Add a dummy pkt
 | 
						|
          my $dummy = Packet->new(dbg => "tid-add-pkt",
 | 
						|
                                  frame_num => -1,
 | 
						|
                                  receiver => $pkt->transmitter(),
 | 
						|
                                  transmitter => $pkt->receiver(),
 | 
						|
                                  data_subtype => "DUMMY_BA_ACKED",
 | 
						|
                                  timestamp => $pkt->timestamp(),
 | 
						|
                                  seqno => $missing_seqno,
 | 
						|
                                  tid => $self->tidno());
 | 
						|
          $dummy->set_block_acked_by($pkt->frame_num());
 | 
						|
          push(@{$self->{pkts}}, $dummy);
 | 
						|
          # A transmitting block-ack indicates we dropped pkts sent to us.
 | 
						|
          if ($pkt->transmitter() eq $self->{addr_a}) {
 | 
						|
            $self->{dummy_rx_pkts}++;
 | 
						|
            $pkt->{dummy_rx_pkts}++;
 | 
						|
          }
 | 
						|
          else {
 | 
						|
            $self->{dummy_tx_pkts}++;
 | 
						|
            $pkt->{dummy_tx_pkts}++;
 | 
						|
          }
 | 
						|
          #print "pushing dummy pkt, seqno: $missing_seqno\n";
 | 
						|
          $ba_tot++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      print "WARNING:  block-ack frame: " . $pkt->frame_num() . " acked frames we did not capture, found-these: " . $bi_mask->as_hex .
 | 
						|
        " acked these: " . $bi_as_long->as_hex . " missing: " . $missing->as_hex . "($missing_str), starting-seq-no: $starting_seqno\n";
 | 
						|
    }
 | 
						|
 | 
						|
    my $new_ba = $ba_tot - $ba_dup;
 | 
						|
    #my $fh_ba = $self->{fh_ba};
 | 
						|
    my $ts_diff;
 | 
						|
    if ($last_timestamp == 0) {
 | 
						|
      $ts_diff = "0.0";
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      $ts_diff = sprintf("%.10f", $pkt->timestamp() - $last_timestamp);
 | 
						|
    }
 | 
						|
    my $ln = "" . $pkt->timestamp() . "\t" . $self->tidno() . "\t$ba_tot\t$ba_dup\t$new_ba\t$ts_diff\n";
 | 
						|
 | 
						|
    #print $fh_ba $ln; # Tid specific data file
 | 
						|
    print $glb $ln; # Global data file
 | 
						|
  }# if block-ack frame
 | 
						|
 | 
						|
  # Shift off old frames.
 | 
						|
  while ($pkt_count > 0) {
 | 
						|
    my $tmp = shift(@{$self->{pkts}});
 | 
						|
    if (($tmp->timestamp() + 60 < $pkt->timestamp()) ||
 | 
						|
        ($pkt_count > $max_pkt_store)) {
 | 
						|
      if (! $tmp->was_acked()) {
 | 
						|
        if ($tmp->wants_ack()) {
 | 
						|
          if ($tmp->transmitter() eq $self->{addr_a}) {
 | 
						|
            $self->{tx_no_ack_found_all}++;
 | 
						|
            if ($tmp->{bytes_on_wire} > 1000) {
 | 
						|
              print "WARNING:  did not find ack for BIG TX frame: " . $tmp->desc() . ", removing after processing frame: " . $pkt->frame_num() . "\n";
 | 
						|
              $self->{tx_no_ack_found_big}++;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
              print "WARNING:  did not find ack for small TX frame: " . $tmp->desc() . ", removing after processing frame: " . $pkt->frame_num() . "\n";
 | 
						|
            }
 | 
						|
          }
 | 
						|
          else {
 | 
						|
            $self->{rx_no_ack_found_all}++;
 | 
						|
            if ($tmp->{bytes_on_wire} > 1000) {
 | 
						|
              print "WARNING:  did not find ack for BIG RX frame: " . $tmp->desc() . ", removing after processing frame: " . $pkt->frame_num() . "\n";
 | 
						|
              $self->{rx_no_ack_found_big}++;
 | 
						|
            }
 | 
						|
            else {
 | 
						|
              print "WARNING:  did not find ack for small RX frame: " . $tmp->desc() . ", removing after processing frame: " . $pkt->frame_num() . "\n";
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
      $pkt_count--;
 | 
						|
      next; # Drop frames when we have more than $max_pkt_store or they are older than 1 minute ago
 | 
						|
    }
 | 
						|
    # Put this one back on
 | 
						|
    unshift(@{$self->{pkts}}, $tmp);
 | 
						|
    last;
 | 
						|
  }
 | 
						|
 | 
						|
  if (0) { # Skip per-tid reporting files for now...global info seems enough
 | 
						|
    my $tsp1 = $self->{last_ps_timestamp} + 1.0;
 | 
						|
    my $gen_ps = $tsp1 < $pkt->{timestamp};
 | 
						|
    #print STDERR "last-ps-timestamp: " . $self->{last_ps_timestamp} . " tsp1: $tsp1 gen-ps: $gen_ps "
 | 
						|
    #  . $self->{last_ps_timestamp} . " pkt-ts: " . $pkt->{timestamp} . "\n";
 | 
						|
    if ($gen_ps) {
 | 
						|
      my $diff =  $pkt->{timestamp} - $self->{last_ps_timestamp};
 | 
						|
      my $period_tot_pkts = $self->{tot_pkts} - $self->{last_tot_pkts};
 | 
						|
      my $period_rx_pkts = $self->{rx_pkts} - $self->{last_rx_pkts};
 | 
						|
      my $period_rx_amsdu_pkts = $self->{rx_amsdu_pkts} - $self->{last_rx_amsdu_pkts};
 | 
						|
      my $period_rx_retrans_pkts = $self->{rx_retrans_pkts} - $self->{last_rx_retrans_pkts};
 | 
						|
      my $period_rx_retrans_amsdu_pkts = $self->{rx_amsdu_retrans_pkts} - $self->{last_rx_amsdu_retrans_pkts};
 | 
						|
      my $period_tx_pkts = $self->{tx_pkts} - $self->{last_tx_pkts};
 | 
						|
      my $period_tx_amsdu_pkts = $self->{tx_amsdu_pkts} - $self->{last_tx_amsdu_pkts};
 | 
						|
      my $period_tx_retrans_pkts = $self->{tx_retrans_pkts} - $self->{last_tx_retrans_pkts};
 | 
						|
      my $period_tx_retrans_amsdu_pkts = $self->{tx_amsdu_retrans_pkts} - $self->{last_tx_amsdu_retrans_pkts};
 | 
						|
      my $period_dummy_rx_pkts = $self->{dummy_rx_pkts} - $self->{last_dummy_rx_pkts};
 | 
						|
      my $period_dummy_tx_pkts = $self->{dummy_tx_pkts} - $self->{last_dummy_tx_pkts};
 | 
						|
 | 
						|
      my $period_tot_pkts_ps = $period_tot_pkts / $diff;
 | 
						|
      my $period_rx_pkts_ps = $period_rx_pkts / $diff;
 | 
						|
      my $period_rx_amsdu_pkts_ps = $period_rx_amsdu_pkts / $diff;
 | 
						|
      my $period_rx_retrans_pkts_ps = $period_rx_retrans_pkts / $diff;
 | 
						|
      my $period_rx_retrans_amsdu_pkts_ps = $period_rx_retrans_amsdu_pkts / $diff;
 | 
						|
      my $period_tx_pkts_ps = $period_tx_pkts / $diff;
 | 
						|
      my $period_tx_amsdu_pkts_ps = $period_tx_amsdu_pkts / $diff;
 | 
						|
      my $period_tx_retrans_pkts_ps = $period_tx_retrans_pkts / $diff;
 | 
						|
      my $period_tx_retrans_amsdu_pkts_ps = $period_tx_retrans_amsdu_pkts / $diff;
 | 
						|
      my $period_dummy_rx_pkts_ps = $period_dummy_rx_pkts / $diff;
 | 
						|
      my $period_dummy_tx_pkts_ps = $period_dummy_tx_pkts / $diff;
 | 
						|
 | 
						|
      $self->{last_ps_timestamp} = $pkt->timestamp();
 | 
						|
      $self->{last_tot_pkts} = $self->{tot_pkts};
 | 
						|
      $self->{last_rx_pkts} = $self->{rx_pkts};
 | 
						|
      $self->{last_rx_amsdu_pkts} = $self->{rx_amsdu_pkts};
 | 
						|
      $self->{last_rx_retrans_pkts} = $self->{rx_retrans_pkts};
 | 
						|
      $self->{last_rx_amsdu_retrans_pkts} = $self->{rx_amsdu_retrans_pkts};
 | 
						|
      $self->{last_tx_pkts} = $self->{tx_pkts};
 | 
						|
      $self->{last_tx_amsdu_pkts} = $self->{tx_amsdu_pkts};
 | 
						|
      $self->{last_tx_retrans_pkts} = $self->{tx_retrans_pkts};
 | 
						|
      $self->{last_tx_amsdu_retrans_pkts} = $self->{tx_amsdu_retrans_pkts};
 | 
						|
      $self->{last_dummy_rx_pkts} = $self->{dummy_rx_pkts};
 | 
						|
      $self->{last_dummy_tx_pkts} = $self->{dummy_tx_pkts};
 | 
						|
 | 
						|
      my $fh_ps = $self->{mcs_fh_ps};
 | 
						|
 | 
						|
      my $ln =  "" . $pkt->timestamp() . "\t" . $self->tidno() . "\t$diff\t$period_tot_pkts_ps\t" .
 | 
						|
        "$period_rx_pkts_ps\t$period_rx_retrans_pkts_ps\t$period_rx_amsdu_pkts_ps\t$period_rx_retrans_amsdu_pkts_ps\t$period_dummy_rx_pkts_ps\t" .
 | 
						|
          "$period_tx_pkts_ps\t$period_tx_retrans_pkts_ps\t$period_tx_amsdu_pkts_ps\t$period_tx_retrans_amsdu_pkts_ps\t$period_dummy_tx_pkts_ps\n";
 | 
						|
      print $fh_ps $ln;
 | 
						|
    }
 | 
						|
 | 
						|
    # Generate reporting data for this pkt
 | 
						|
    my $fh = $self->{mcs_fh};
 | 
						|
    my $ln = "" . $pkt->timestamp() . "\t" . $self->tidno() . "\t" . $pkt->datarate() . "\t" . $pkt->retrans() . "\n";
 | 
						|
 | 
						|
    print $fh $ln;
 | 
						|
  }
 | 
						|
 | 
						|
  push(@{$self->{pkts}}, $pkt);
 | 
						|
}
 | 
						|
 | 
						|
sub check_remaining_pkts {
 | 
						|
  my $self = shift;
 | 
						|
 | 
						|
  my $pkt_count = @{$self->{pkts}};
 | 
						|
 | 
						|
  # Shift off old frames.
 | 
						|
  while ($pkt_count > 0) {
 | 
						|
    my $tmp = shift(@{$self->{pkts}});
 | 
						|
    if (! $tmp->was_acked()) {
 | 
						|
      if ($tmp->wants_ack()) {
 | 
						|
        if ($tmp->transmitter() eq $self->{addr_a}) {
 | 
						|
          $self->{tx_no_ack_found_all}++;
 | 
						|
          if ($tmp->{bytes_on_wire} > 1000) {
 | 
						|
            print "WARNING:  did not find ack for BIG TX frame: " . $tmp->desc() . ", removing at end of file.\n";
 | 
						|
            $self->{tx_no_ack_found_big}++;
 | 
						|
          }
 | 
						|
          else {
 | 
						|
            print "WARNING:  did not find ack for small TX frame: " . $tmp->desc() . ", removing at end of file.\n";
 | 
						|
          }
 | 
						|
        }
 | 
						|
        else {
 | 
						|
          $self->{rx_no_ack_found_all}++;
 | 
						|
          if ($tmp->{bytes_on_wire} > 1000) {
 | 
						|
            print "WARNING:  did not find ack for BIG RX frame: " . $tmp->desc() . ", removing at end of file.\n";
 | 
						|
            $self->{rx_no_ack_found_big}++;
 | 
						|
          }
 | 
						|
          else {
 | 
						|
            print "WARNING:  did not find ack for small RX frame: " . $tmp->desc() . ", removing at end of file.\n";
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    $pkt_count--;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
sub get_pkts {
 | 
						|
  my $self = shift;
 | 
						|
  return @{$self->{pkts}};
 | 
						|
}
 | 
						|
 | 
						|
sub tx_no_ack_found_all {
 | 
						|
  my $self = shift;
 | 
						|
  return $self->{tx_no_ack_found_all};
 | 
						|
}
 | 
						|
 | 
						|
sub tx_no_ack_found_big {
 | 
						|
  my $self = shift;
 | 
						|
  return $self->{tx_no_ack_found_big};
 | 
						|
}
 | 
						|
 | 
						|
sub rx_no_ack_found_all {
 | 
						|
  my $self = shift;
 | 
						|
  return $self->{rx_no_ack_found_all};
 | 
						|
}
 | 
						|
 | 
						|
sub rx_no_ack_found_big {
 | 
						|
  my $self = shift;
 | 
						|
  return $self->{rx_no_ack_found_big};
 | 
						|
}
 | 
						|
 | 
						|
sub printme {
 | 
						|
  my $self = shift;
 | 
						|
  print "   tidno: " . $self->tidno() . " pkt-count: " . $self->get_pkts()
 | 
						|
    . " tx-pkts: " . $self->{tx_pkts} . " tx-retrans: " . $self->{tx_retrans_pkts}
 | 
						|
    . " rx-pkts: " . $self->{rx_pkts} . " rx-retrans: " . $self->{rx_retrans_pkts}
 | 
						|
    . " tx-no-acks-all: " . $self->{tx_no_ack_found_all} . " tx-no-acks-big: " . $self->{tx_no_ack_found_big}
 | 
						|
    . " rx-no-acks-all: " . $self->{rx_no_ack_found_all} . " rx-no-acks-big: " . $self->{rx_no_ack_found_big}
 | 
						|
    . "\n";
 | 
						|
}
 | 
						|
 | 
						|
1;
 |