mirror of
https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
synced 2025-10-30 18:27:53 +00:00
wifi-diag: reporting data.
This commit is contained in:
@@ -8,6 +8,7 @@ sub new {
|
||||
my %options = @_;
|
||||
|
||||
my $self = {
|
||||
raw_pkt => "",
|
||||
seqno => -1, # block-ack will not have a seqno
|
||||
acked_by => -1,
|
||||
block_acked_by => -1,
|
||||
@@ -63,6 +64,7 @@ sub append {
|
||||
$self->{ba_starting_seq} = $1;
|
||||
}
|
||||
elsif ($ln =~ /.* = TID for which a Basic BlockAck frame is requested: (\S+)/) {
|
||||
#print STDERR "tid: $1\n";
|
||||
$self->{ba_tid} = hex($1);
|
||||
}
|
||||
elsif ($ln =~ /^\s*Block Ack Bitmap: (\S+)/) {
|
||||
@@ -195,7 +197,13 @@ sub was_acked {
|
||||
|
||||
sub wants_ack {
|
||||
my $self = shift;
|
||||
my $rcvr_b0 = substring(self->receiver(), 0, 1);
|
||||
my $rcvr_b0 = substr($self->receiver(), 0, 1);
|
||||
if ($rcvr_b0 eq "U") {
|
||||
#print STDERR "wants-ack, receiver: " . $self->receiver() . "\n";
|
||||
#print STDERR $self->raw_pkt() . "\n";
|
||||
#exit(1);
|
||||
return 0;
|
||||
}
|
||||
my $rb0 = hex("$rcvr_b0");
|
||||
if ($rb0 & 0x1) {
|
||||
return 0; # Don't ack bcast/bcast frames
|
||||
|
||||
@@ -16,7 +16,7 @@ sub new {
|
||||
|
||||
bless($self, $class);
|
||||
|
||||
my $mcs_fname = $self->hash_str() . "-rpt.txt";
|
||||
my $mcs_fname = $self->{report_prefix} . "conn-" . $self->hash_str() . "-rpt.txt";
|
||||
open(my $MCS, ">", $mcs_fname) or die("Can't open $mcs_fname for writing: $!\n");
|
||||
$self->{mcs_fh} = $MCS;
|
||||
|
||||
@@ -62,7 +62,9 @@ sub find_or_create_tid {
|
||||
$tid = $self->{tids}[$tidno];
|
||||
}
|
||||
else {
|
||||
$tid = Tid->new(tidno => $tidno,
|
||||
$tid = Tid->new(glb_fh_ba => $self->{glb_fh_ba},
|
||||
tidno => $tidno,
|
||||
report_prefix => $self->{report_prefix},
|
||||
addr_a => $self->local_addr(),
|
||||
addr_b => $self->peer_addr(),
|
||||
);
|
||||
|
||||
150
wifi_diag/Tid.pm
150
wifi_diag/Tid.pm
@@ -2,9 +2,11 @@ package Tid;
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use bigint;
|
||||
|
||||
my $warn_dup_ba_once = 1;
|
||||
my $max_pkt_store = 250;
|
||||
|
||||
sub new {
|
||||
my $class = shift;
|
||||
@@ -12,20 +14,49 @@ sub new {
|
||||
|
||||
my $self = {
|
||||
pkts => [],
|
||||
tx_retrans => 0,
|
||||
rx_retrans => 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_pks => 0,
|
||||
last_rx_pks => 0,
|
||||
last_tx_pks => 0,
|
||||
last_rx_retrans_pks => 0,
|
||||
last_tx_retrans_pks => 0,
|
||||
last_dummy_rx_pks => 0,
|
||||
last_dummy_tx_pks => 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);
|
||||
|
||||
my $rpt_fname = $self->{addr_a} . "." . $self->{addr_b} . "-" . $self->tidno() . "-" . "rpt.txt";
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -41,19 +72,31 @@ sub add_pkt {
|
||||
$self->{tot_pkts}++;
|
||||
if ($pkt->receiver() eq $self->{addr_a}) {
|
||||
$self->{rx_pkts}++;
|
||||
$self->{rx_amsdu_pkts} += $pkt->{amsdu_frame_count};
|
||||
if ($pkt->retrans()) {
|
||||
$self->{rx_retrans}++;
|
||||
$self->{rx_retrans_pkts}++;
|
||||
$self->{rx_amsdu_retrans_pkts} += $pkt->{amsdu_frame_count}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->{tx_pkts}++;
|
||||
$self->{tx_retrans}++;
|
||||
$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;
|
||||
@@ -61,10 +104,12 @@ sub add_pkt {
|
||||
my $bi_as_long = 0;
|
||||
my $bi_mask = 0;
|
||||
my $q;
|
||||
my $last_timestamp = 0;
|
||||
|
||||
for ($q = 0; $q < 8; $q++) {
|
||||
my $bmap_octet = substr($bitmap, $q * 2, 2);
|
||||
my $bmi = hex($bmap_octet);
|
||||
#print "bmap-octet: $bmap_octet bmi: " . hex($bmi) . "\n";
|
||||
#print STDERR "bmap-octet: $bmap_octet bmi: " . hex($bmi) . "\n";
|
||||
$bi_as_long |= ($bmi << ($q * 8));
|
||||
}
|
||||
|
||||
@@ -89,12 +134,22 @@ sub add_pkt {
|
||||
$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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,39 +165,108 @@ sub add_pkt {
|
||||
$missing_str .= $missing_seqno . " ";
|
||||
|
||||
# Add a dummy pkt
|
||||
my $dummy = Packet->new(transmitter => $pkt->receiver(),
|
||||
my $dummy = Packet->new(frame_num => -1,
|
||||
receiver => $pkt->transmitter(),
|
||||
transmitter => $pkt->receiver(),
|
||||
data_subtype => "DUMMY_BA_ACKED",
|
||||
timestamp => $pkt->timestamp(),
|
||||
seqno => $missing_seqno,
|
||||
tid => $self->tidno());
|
||||
$dummy->block_acked_by($pkt->frame_num());
|
||||
$dummy->set_block_acked_by($pkt->frame_num());
|
||||
push(@{$self->{pkts}}, $dummy);
|
||||
if ($pkt->transmitter() eq $self->{addr_b}) {
|
||||
$self->{dummy_rx_pkts}++;
|
||||
}
|
||||
else {
|
||||
$self->{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 $glb = $self->{glb_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 > 1000)) {
|
||||
($pkt_count > $max_pkt_store)) {
|
||||
if (! $tmp->was_acked()) {
|
||||
if ($tmp->wants_ack()) {
|
||||
print "WARNING: did not find ack for frame: " . $tmp->frame_num() . ", removing after processing frame: " . $pkt->frame_num() . "\n";
|
||||
}
|
||||
}
|
||||
$pkt_count--;
|
||||
next; # Drop frames when we have more than 1000 or they are older than 1 minute ago
|
||||
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 ($self->{last_ps_timestamp} + 1.0 < $pkt->{timestamp}) {
|
||||
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_retrans_amsdu_pkts} - $self->{last_rx_retrans_amsdu_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_retrans_amsdu_pkts} - $self->{last_tx_retrans_amsdu_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_retrans_amsdu_pkts} = $self->{rx_retrans_amsdu_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_retrans_amsdu_pkts} = $self->{tx_retrans_amsdu_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};
|
||||
print $fh_ps "" . $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";
|
||||
}
|
||||
|
||||
# Generate reporting data for this pkt
|
||||
my $fh = $self->{mcs_fh};
|
||||
print $fh "" . $pkt->timestamp() . "\t" . $self->tidno() . "\t" . $pkt->datarate() . "\t" . $pkt->retrans() . "\n";
|
||||
@@ -158,8 +282,8 @@ sub get_pkts {
|
||||
sub printme {
|
||||
my $self = shift;
|
||||
print " tidno: " . $self->tidno() . " pkt-count: " . $self->get_pkts()
|
||||
. " tx-pkts: " . $self->{tx_pkts} . " tx-retrans: " . $self->{tx_retrans}
|
||||
. " rx-pkts: " . $self->{rx_pkts} . " rx-retrans: " . $self->{rx_retrans} . "\n";
|
||||
. " tx-pkts: " . $self->{tx_pkts} . " tx-retrans: " . $self->{tx_retrans_pkts}
|
||||
. " rx-pkts: " . $self->{rx_pkts} . " rx-retrans: " . $self->{rx_retrans_pkts} . "\n";
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -10,11 +10,45 @@ use Carp;
|
||||
|
||||
use PeerConn;
|
||||
use Packet;
|
||||
use Getopt::Long;
|
||||
|
||||
my %peer_conns = ();
|
||||
|
||||
my $pkts_sofar = 0;
|
||||
my $start_time = time();
|
||||
|
||||
my $cur_pkt = Packet->new(raw_pkt => "");
|
||||
my $last_pkt = Packet->new(raw_pkt => "");
|
||||
my $glb_fh_ba;
|
||||
|
||||
my $dut = "";
|
||||
my $report_prefix = "wifi-diag-";
|
||||
my $non_dut_frames = 0;
|
||||
my $show_help = 0;
|
||||
|
||||
my $usage = "$0
|
||||
--dut {bssid-of-DUT} # Orient reports with this as upstream peer (lower-case MAC address)
|
||||
--report_prefix {string} # Prefix used for report files (default is $report_prefix)
|
||||
--help # Show this help info.
|
||||
";
|
||||
|
||||
|
||||
GetOptions
|
||||
(
|
||||
'help|h' => \$show_help,
|
||||
'dut=s' => \$dut,
|
||||
'report_prefix=s' => \$report_prefix,
|
||||
) || (print($usage) && exit(1));
|
||||
|
||||
|
||||
if ($show_help) {
|
||||
print $usage;
|
||||
exit 0
|
||||
}
|
||||
|
||||
my $rpt_fname = $report_prefix . "glb-ba-rpt.txt";
|
||||
open($glb_fh_ba, ">", $rpt_fname) or die("Can't open $rpt_fname for writing: $!\n");
|
||||
|
||||
|
||||
while (<>) {
|
||||
my $ln = $_;
|
||||
@@ -34,14 +68,29 @@ if ($cur_pkt->raw_pkt() ne "") {
|
||||
processPkt($cur_pkt);
|
||||
}
|
||||
|
||||
printProgress();
|
||||
|
||||
# Print out all peer-conns we found
|
||||
for my $conn (values %peer_conns) {
|
||||
$conn->printme();
|
||||
$conn->gen_graphs();
|
||||
}
|
||||
|
||||
if ($dut ne "") {
|
||||
print "NON-DUT frames in capture: $non_dut_frames\n";
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
sub printProgress {
|
||||
my $now = time();
|
||||
my $diff_sec = $now - $start_time;
|
||||
my $hour = int($diff_sec / (60 * 60));
|
||||
my $min = int($diff_sec / 60);
|
||||
my $sec = $diff_sec - ($hour * 60 * 60 + $min * 60);
|
||||
my $pps = int($pkts_sofar / $diff_sec);
|
||||
print STDERR "NOTE: Processed $pkts_sofar packets in $hour:$min:$sec far ($pps pps).\n";
|
||||
}
|
||||
|
||||
sub processPkt {
|
||||
my $pkt = shift;
|
||||
@@ -51,6 +100,11 @@ sub processPkt {
|
||||
# Add graph point for retransmits
|
||||
# Check sequence-no gap
|
||||
|
||||
$pkts_sofar++;
|
||||
if (($pkts_sofar % 10000) == 0) {
|
||||
printProgress();
|
||||
}
|
||||
|
||||
# If pkt is an ACK, it will not have a sender address. Guess based on
|
||||
# previous packet.
|
||||
if ($pkt->type_subtype() eq "Acknowledgement (0x001d)") {
|
||||
@@ -75,6 +129,15 @@ sub processPkt {
|
||||
}
|
||||
}
|
||||
|
||||
if ($dut ne "") {
|
||||
# Ignore frames not to/from DUT
|
||||
if (!(($dut eq $pkt->receiver()) ||
|
||||
($dut eq $pkt->transmitter()))) {
|
||||
$non_dut_frames++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $hash = $pkt->receiver() . "." . $pkt->transmitter();
|
||||
my $hash2 = $pkt->transmitter() . "." . $pkt->receiver();
|
||||
|
||||
@@ -87,8 +150,18 @@ sub processPkt {
|
||||
$peer_conn = $peer_conns{$hash2};
|
||||
}
|
||||
else {
|
||||
$peer_conn = PeerConn->new(local_addr => $pkt->receiver(),
|
||||
peer_addr => $pkt->transmitter());
|
||||
if ($dut eq $pkt->receiver()) {
|
||||
$peer_conn = PeerConn->new(glb_fh_ba => $glb_fh_ba,
|
||||
report_prefix => $report_prefix,
|
||||
local_addr => $pkt->transmitter(),
|
||||
peer_addr => $pkt->receiver());
|
||||
}
|
||||
else {
|
||||
$peer_conn = PeerConn->new(glb_fh_ba => $glb_fh_ba,
|
||||
report_prefix => $report_prefix,
|
||||
local_addr => $pkt->receiver(),
|
||||
peer_addr => $pkt->transmitter());
|
||||
}
|
||||
$peer_conns{$hash} = $peer_conn;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user