From d41cc2f3cac9af656cc7f7b722d287d32369f269 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Fri, 4 Jan 2019 15:43:21 -0800 Subject: [PATCH] wifi-diag: Parse newer tshark output properly, retransmit improvements. Newer tshark had a different text output, so needed to modify the script to parse that properly. Report big vs all retransmits (big frames are likely Data, small ones may just be null-data frames or similar). --- wifi_diag/Packet.pm | 14 +++++-- wifi_diag/PeerConn.pm | 36 ++++++++++++++++++ wifi_diag/Tid.pm | 24 +++++++++++- wifi_diag/wifi_pcap_diag.pl | 73 +++++++++++++++++++++++++++---------- 4 files changed, 123 insertions(+), 24 deletions(-) diff --git a/wifi_diag/Packet.pm b/wifi_diag/Packet.pm index a18c4e73..c4442dae 100644 --- a/wifi_diag/Packet.pm +++ b/wifi_diag/Packet.pm @@ -15,6 +15,7 @@ sub new { wmm_info => "", raw_pkt => "", seqno => -1, # block-ack will not have a seqno + bytes_on_wire => 0, acked_by => -1, block_acked_by => -1, retrans => 0, @@ -24,6 +25,7 @@ sub new { dummy_rx_pkts => 0, is_last_ampdu => 0, is_ampdu => 0, + is_msdu => 0, is_malformed => 0, type_subtype => "UNKNOWN", receiver => "UNKNOWN", @@ -67,16 +69,21 @@ sub append { elsif ($ln =~ /^.* = Payload Type: A-MSDU/) { $self->{is_ampdu} = 1; } + elsif ($ln =~ /^.* = Payload Type: MSDU/) { + $self->{is_msdu} = 1; + } elsif ($ln =~ /^\s*\[Time delta from previous captured frame:\s+(\S+)/) { $self->{timedelta} = $1; } elsif ($ln =~ /^\s*Receiver address: .*\((\S+)\)/) { $self->{receiver} = $1; } - elsif ($ln =~ /^\s*Fragment number: (\d+)/) { + elsif (($ln =~ /^\s*Fragment number: (\d+)/) || + ($ln =~ /^.*\s+=\s+Fragment number: (\d+)/)) { $self->{fragno} = $1; } - elsif ($ln =~ /^\s*Sequence number: (\d+)/) { + elsif (($ln =~ /^\s*Sequence number: (\d+)/) || + ($ln =~ /^.*\s+=\s+Sequence number: (\d+)/)) { $self->{seqno} = $1; } elsif ($ln =~ /^\s*Type\/Subtype: (.*)/) { @@ -128,7 +135,8 @@ sub append { $self->{datarate} = 0; } } - elsif ($ln =~ /^\s*SSI Signal: (.*)/) { + elsif (($ln =~ /^\s*SSI Signal: (.*)/) || + ($ln =~ /^\s*Antenna signal: (.*)/)) { if ($self->{ssi_sig_found} == 0) { $self->{ssi_combined} = $1; $self->{ssi_sig_found}++; diff --git a/wifi_diag/PeerConn.pm b/wifi_diag/PeerConn.pm index f108e76d..c6cb744f 100644 --- a/wifi_diag/PeerConn.pm +++ b/wifi_diag/PeerConn.pm @@ -81,6 +81,42 @@ sub find_or_create_tid { return $tid; } +sub tx_no_ack_found { + my $self = shift; + my $tid_count = @{$self->{tids}}; + + my $rv = 0; + + my $i; + for ($i = 0; $i < $tid_count; $i++) { + #print "Checking tid: $i\n"; + if (exists $self->{tids}[$i]) { + #print "Printing tid: $i\n"; + $rv += $self->{tids}[$i]->tx_no_ack_found(); + #print "Done printing tid: $i\n"; + } + } + return $rv; +} + +sub rx_no_ack_found { + my $self = shift; + my $tid_count = @{$self->{tids}}; + + my $rv = 0; + + my $i; + for ($i = 0; $i < $tid_count; $i++) { + #print "Checking tid: $i\n"; + if (exists $self->{tids}[$i]) { + #print "Printing tid: $i\n"; + $rv += $self->{tids}[$i]->rx_no_ack_found(); + #print "Done printing tid: $i\n"; + } + } + return $rv; +} + sub printme { my $self = shift; my $tid_count = @{$self->{tids}}; diff --git a/wifi_diag/Tid.pm b/wifi_diag/Tid.pm index c255ef90..7db63175 100644 --- a/wifi_diag/Tid.pm +++ b/wifi_diag/Tid.pm @@ -15,6 +15,8 @@ sub new { my $self = { pkts => [], + rx_no_ack_found => 0, + tx_no_ack_found => 0, tx_retrans_pkts => 0, rx_retrans_pkts => 0, tx_amsdu_retrans_pkts => 0, @@ -129,7 +131,7 @@ sub add_pkt { for ($i = 0; $i<$pkt_count; $i++) { my $tmp = $self->{pkts}[$i]; - #print "checking tmp-pkt: " . $tmp->seqno(); + #print "checking tmp-pkt frame: " . $tmp->{frame_num} . " seqno: " . $tmp->seqno(); #print " transmitter: " . $tmp->transmitter(); #print " pkt-rcvr: " . $pkt->receiver() . "\n"; if ($tmp->transmitter() eq $pkt->receiver()) { @@ -228,6 +230,12 @@ sub add_pkt { 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"; + if ($tmp->transmitter() eq $self->{addr_a}) { + $self->{tx_no_ack_found}++; + } + else { + $self->{rx_no_ack_found}++; + } } } $pkt_count--; @@ -305,11 +313,23 @@ sub get_pkts { return @{$self->{pkts}}; } +sub tx_no_ack_found { + my $self = shift; + return $self->{tx_no_ack_found}; +} + +sub rx_no_ack_found { + my $self = shift; + return $self->{rx_no_ack_found}; +} + 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} . "\n"; + . " rx-pkts: " . $self->{rx_pkts} . " rx-retrans: " . $self->{rx_retrans_pkts} + . " tx-no-acks: " . $self->{tx_no_ack_found} . " rx-no-acks: " . $self->{rx_no_ack_found} + . "\n"; } 1; diff --git a/wifi_diag/wifi_pcap_diag.pl b/wifi_diag/wifi_pcap_diag.pl index ca661dd2..e6e616d3 100755 --- a/wifi_diag/wifi_pcap_diag.pl +++ b/wifi_diag/wifi_pcap_diag.pl @@ -52,6 +52,9 @@ my $glb_fh_mcs_rx; my $glb_fh_rtx_tx; my $glb_fh_rtx_rx; +my $tx_no_ack_found = 0; +my $rx_no_ack_found = 0; + my %glb_mcs_tx_hash = (); my %glb_mcs_rx_hash = (); my %glb_pkt_type_tx_hash = (); @@ -153,35 +156,38 @@ my $last_ps_timestamp = 0; my $tot_pkts = 0; my $rx_pkts = 0; my $rx_amsdu_pkts = 0; -my $rx_retrans_pkts = 0; +my $rx_retrans_pkts_all = 0; +my $rx_retrans_pkts_big = 0; my $rx_amsdu_retrans_pkts = 0; my $dummy_rx_pkts = 0; my $tx_pkts = 0; my $tx_amsdu_pkts = 0; -my $tx_retrans_pkts = 0; +my $tx_retrans_pkts_all = 0; +my $tx_retrans_pkts_big = 0; my $tx_amsdu_retrans_pkts = 0; my $dummy_tx_pkts = 0; my $last_tot_pkts = 0; my $last_rx_pkts = 0; my $last_rx_amsdu_pkts = 0; -my $last_rx_retrans_pkts = 0; +my $last_rx_retrans_pkts_all = 0; my $last_rx_amsdu_retrans_pkts = 0; my $last_dummy_rx_pkts = 0; my $last_tx_pkts = 0; my $last_tx_amsdu_pkts = 0; -my $last_tx_retrans_pkts = 0; +my $last_tx_retrans_pkts_all = 0; my $last_tx_amsdu_retrans_pkts = 0; my $last_dummy_tx_pkts = 0; while (<>) { my $ln = $_; $input_line_count++; - if ($ln =~ /^Frame (\d+):/) { + if ($ln =~ /^Frame (\d+):\s+(\d+) bytes on wire/) { if ($cur_pkt->raw_pkt() ne "") { processPkt($cur_pkt); } $cur_pkt = Packet->new(frame_num => $1, + bytes_on_write => $2, raw_pkt => $ln); } else { $cur_pkt->append($ln); @@ -194,6 +200,12 @@ if ($cur_pkt->raw_pkt() ne "") { printProgress(); +# Sum up some stats +for my $conn (values %peer_conns) { + $tx_no_ack_found += $conn->tx_no_ack_found(); + $rx_no_ack_found += $conn->rx_no_ack_found(); +} + $report_html .= genGlobalReports(); # Print out all peer-conns we found @@ -317,15 +329,20 @@ sub htmlMcsHistogram { my $html = ""; if ($rx_pkts) { - $html .= "RX Retransmit percentage: $rx_retrans_pkts/$rx_pkts == " . ($rx_retrans_pkts * 100.0) / $rx_pkts . "
\n"; + $html .= "RX (All) Retransmit percentage: $rx_retrans_pkts_all/$rx_pkts == " . ($rx_retrans_pkts_all * 100.0) / $rx_pkts . "
\n"; } else { - $html .= "RX Retransmit percentage: $rx_retrans_pkts/$rx_pkts == 0
\n"; + $html .= "RX (All) Retransmit percentage: $rx_retrans_pkts_all/$rx_pkts == 0
\n"; } + $html .= "RX (Big) Retransmit count: $rx_retrans_pkts_big
\n"; if ($tx_pkts) { - $html .= "TX Retransmit percentage: $tx_retrans_pkts/$tx_pkts == " . ($tx_retrans_pkts * 100.0) / $tx_pkts . "
\n"; + $html .= "TX (All) Retransmit percentage: $tx_retrans_pkts_all/$tx_pkts == " . ($tx_retrans_pkts_all * 100.0) / $tx_pkts . "
\n"; } else { - $html .= "TX Retransmit percentage: $tx_retrans_pkts/$tx_pkts == 0
\n"; + $html .= "TX (All) Retransmit percentage: $tx_retrans_pkts_all/$tx_pkts == 0
\n"; } + $html .= "TX (Big) Retransmit count: $tx_retrans_pkts_big
\n"; + + $html .= "RX no-ack-found: $rx_no_ack_found
\n"; + $html .= "TX no-ack-found: $tx_no_ack_found
\n"; if ($delta_time_tx_count) { $html .= "TX average gap between AMPDU frames (ms): " . (($delta_time_tx * 1000.0) / $delta_time_tx_count) . "
\n"; @@ -470,6 +487,9 @@ sub processPkt { return; } + #print "processPkt, frame: " . $pkt->{frame_num} . " seqno: " . $pkt->seqno() . " transmitter: " . $pkt->transmitter() + # . " receiver: " . $pkt->receiver() . "\n"; + $pkts_sofar++; if (($pkts_sofar % 10000) == 0) { printProgress(); @@ -561,8 +581,8 @@ sub processPkt { my $this_ampdu_pkt_count; my $ampdu_chain_time; my $is_last_ampdu = 0; - if ($pkt->{is_ampdu}) { - if ($last_pkt->frame_num() != -1 && (!$last_pkt->{is_ampdu})) { + if ($pkt->{is_ampdu} || $pkt->{is_msdu}) { + if ($last_pkt->frame_num() != -1 && (!($last_pkt->{is_ampdu} || $last_pkt->{is_msdu}))) { # This is first ampdu since a non-ampdu frame. Calculate diff between that and last BA if ($pkt->{is_rx} && ($last_ba_tx_pkt->frame_num() != -1)) { my $diff = $pkt->timestamp() - $last_ba_tx_pkt->timestamp(); @@ -675,7 +695,15 @@ sub processPkt { $rx_pkts++; $rx_amsdu_pkts += $pkt->{amsdu_frame_count}; if ($pkt->retrans()) { - $rx_retrans_pkts++; + $rx_retrans_pkts_all++; + if ($pkt->{bytes_on_wire} > 1000) { + print "Frame " . $pkt->{frame_num} . " is a BIG RX retransmit frame.\n"; + $rx_retrans_pkts_big++; + } + else { + print "Frame " . $pkt->{frame_num} . " is an RX retransmit frame.\n"; + } + $rx_amsdu_retrans_pkts += $pkt->{amsdu_frame_count}; } my $ln = "" . $pkt->timestamp() . "\t" . $pkt->datarate() . "\n"; @@ -716,7 +744,14 @@ sub processPkt { $tx_pkts++; $tx_amsdu_pkts += $pkt->{amsdu_frame_count}; if ($pkt->retrans()) { - $tx_retrans_pkts++; + $tx_retrans_pkts_all++; + if ($pkt->{bytes_on_wire} > 1000) { + print "Frame " . $pkt->{frame_num} . " is a BIG TX retransmit frame.\n"; + $tx_retrans_pkts_big++; + } + else { + print "Frame " . $pkt->{frame_num} . " is a TX retransmit frame.\n"; + } $tx_amsdu_retrans_pkts += $pkt->{amsdu_frame_count}; } my $ln = "" . $pkt->timestamp() . "\t" . $pkt->datarate() . "\n"; @@ -736,11 +771,11 @@ sub processPkt { my $period_tot_pkts = $tot_pkts - $last_tot_pkts; my $period_rx_pkts = $rx_pkts - $last_rx_pkts; my $period_rx_amsdu_pkts = $rx_amsdu_pkts - $last_rx_amsdu_pkts; - my $period_rx_retrans_pkts = $rx_retrans_pkts - $last_rx_retrans_pkts; + my $period_rx_retrans_pkts_all = $rx_retrans_pkts_all - $last_rx_retrans_pkts_all; my $period_rx_retrans_amsdu_pkts = $rx_amsdu_retrans_pkts - $last_rx_amsdu_retrans_pkts; my $period_tx_pkts = $tx_pkts - $last_tx_pkts; my $period_tx_amsdu_pkts = $tx_amsdu_pkts - $last_tx_amsdu_pkts; - my $period_tx_retrans_pkts = $tx_retrans_pkts - $last_tx_retrans_pkts; + my $period_tx_retrans_pkts_all = $tx_retrans_pkts_all - $last_tx_retrans_pkts_all; my $period_tx_retrans_amsdu_pkts = $tx_amsdu_retrans_pkts - $last_tx_amsdu_retrans_pkts; my $period_dummy_rx_pkts = $dummy_rx_pkts - $last_dummy_rx_pkts; my $period_dummy_tx_pkts = $dummy_tx_pkts - $last_dummy_tx_pkts; @@ -748,11 +783,11 @@ sub processPkt { my $period_tot_pkts_ps = ($period_tot_pkts + $period_dummy_tx_pkts + $period_dummy_rx_pkts) / $diff; my $period_rx_pkts_ps = ($period_rx_pkts + $period_dummy_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_pkts_ps = $period_rx_retrans_pkts_all / $diff; my $period_rx_retrans_amsdu_pkts_ps = $period_rx_retrans_amsdu_pkts / $diff; my $period_tx_pkts_ps = ($period_tx_pkts + $period_dummy_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_pkts_ps = $period_tx_retrans_pkts_all / $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; @@ -761,11 +796,11 @@ sub processPkt { $last_tot_pkts = $tot_pkts; $last_rx_pkts = $rx_pkts; $last_rx_amsdu_pkts = $rx_amsdu_pkts; - $last_rx_retrans_pkts = $rx_retrans_pkts; + $last_rx_retrans_pkts_all = $rx_retrans_pkts_all; $last_rx_amsdu_retrans_pkts = $rx_amsdu_retrans_pkts; $last_tx_pkts = $tx_pkts; $last_tx_amsdu_pkts = $tx_amsdu_pkts; - $last_tx_retrans_pkts = $tx_retrans_pkts; + $last_tx_retrans_pkts_all = $tx_retrans_pkts_all; $last_tx_amsdu_retrans_pkts = $tx_amsdu_retrans_pkts; $last_dummy_rx_pkts = $dummy_rx_pkts; $last_dummy_tx_pkts = $dummy_tx_pkts;