diff options
Diffstat (limited to 'ui/qt/lte_rlc_graph_dialog.cpp')
-rw-r--r-- | ui/qt/lte_rlc_graph_dialog.cpp | 101 |
1 files changed, 63 insertions, 38 deletions
diff --git a/ui/qt/lte_rlc_graph_dialog.cpp b/ui/qt/lte_rlc_graph_dialog.cpp index f1ac2b46..6158c21b 100644 --- a/ui/qt/lte_rlc_graph_dialog.cpp +++ b/ui/qt/lte_rlc_graph_dialog.cpp @@ -31,6 +31,8 @@ #include "ui/qt/widgets/wireshark_file_dialog.h" #include <epan/dissectors/packet-rlc-lte.h> +#include <epan/dissectors/packet-rlc-3gpp-common.h> + #include <ui/tap-rlc-graph.h> @@ -62,7 +64,7 @@ LteRlcGraphDialog::LteRlcGraphDialog(QWidget &parent, CaptureFile &cf, bool chan rp->xAxis->setLabel(tr("Time")); rp->yAxis->setLabel(tr("Sequence Number")); - // TODO: couldn't work out how to tell rp->xAxis not to label fractions of a SN... + // TODO: couldn't work out how to tell rp->yAxis not to label fractions of a SN... ui->dragRadioButton->setChecked(mouse_drags_); @@ -95,6 +97,9 @@ LteRlcGraphDialog::LteRlcGraphDialog(QWidget &parent, CaptureFile &cf, bool chan ctx_menu_->addAction(ui->actionSwitchDirection); set_action_shortcuts_visible_in_context_menu(ctx_menu_->actions()); + rp->setContextMenuPolicy(Qt::CustomContextMenu); + connect(rp, &QCustomPlot::customContextMenuRequested, this, &LteRlcGraphDialog::showContextMenu); + // Zero out this struct. memset(&graph_, 0, sizeof(graph_)); @@ -111,15 +116,16 @@ LteRlcGraphDialog::~LteRlcGraphDialog() } // Set the channel information that this graph should show. -void LteRlcGraphDialog::setChannelInfo(guint16 ueid, guint8 rlcMode, - guint16 channelType, guint16 channelId, guint8 direction, +void LteRlcGraphDialog::setChannelInfo(uint8_t rat, uint16_t ueid, uint8_t rlcMode, + uint16_t channelType, uint16_t channelId, uint8_t direction, bool maybe_empty) { + graph_.rat = rat; graph_.ueid = ueid; graph_.rlcMode = rlcMode; graph_.channelType = channelType; graph_.channelId = channelId; - graph_.channelSet = TRUE; + graph_.channelSet = true; graph_.direction = direction; completeGraph(maybe_empty); @@ -135,7 +141,8 @@ void LteRlcGraphDialog::completeGraph(bool may_be_empty) // Set window title here. if (graph_.channelSet) { - QString dlg_title = tr("LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)") + QString dlg_title = tr("%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)") + .arg((graph_.rat == RLC_RAT_LTE) ? "LTE" : "NR") .arg(graph_.ueid) .arg((graph_.channelType == CHANNEL_TYPE_SRB) ? "SRB" : "DRB") .arg(graph_.channelId) @@ -144,7 +151,7 @@ void LteRlcGraphDialog::completeGraph(bool may_be_empty) setWindowTitle(dlg_title); } else { - setWindowTitle(tr("LTE RLC Graph - no channel selected")); + setWindowTitle(tr("3GPP RLC Graph - no channel selected")); } // Set colours/styles for each of the traces on the graph. @@ -186,7 +193,8 @@ void LteRlcGraphDialog::completeGraph(bool may_be_empty) // See if the given segment matches the channel this graph is plotting. bool LteRlcGraphDialog::compareHeaders(rlc_segment *seg) { - return compare_rlc_headers(graph_.ueid, graph_.channelType, + return compare_rlc_headers(graph_.rat, seg->rat, + graph_.ueid, graph_.channelType, graph_.channelId, graph_.rlcMode, graph_.direction, seg->ueid, seg->channelType, seg->channelId, seg->rlcMode, seg->direction, @@ -230,13 +238,13 @@ void LteRlcGraphDialog::fillGraph() return; } - tracer_->setGraph(NULL); - base_graph_->setLineStyle(QCPGraph::lsNone); // dot reseg_graph_->setLineStyle(QCPGraph::lsNone); // dot acks_graph_->setLineStyle(QCPGraph::lsStepLeft); // to get step effect... nacks_graph_->setLineStyle(QCPGraph::lsNone); // dot, but bigger. + tracer_->setGraph(NULL); + // Will show all graphs with data we find. for (int i = 0; i < sp->graphCount(); i++) { sp->graph(i)->data()->clear(); @@ -252,14 +260,13 @@ void LteRlcGraphDialog::fillGraph() // NACKs are shown bigger than others. nacks_graph_->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, pkt_point_size_*2)); - // Map timestamps -> segments in first pass. + // Map timestamps -> segments (time_stamp_map_) in first pass. time_stamp_map_.clear(); for (struct rlc_segment *seg = graph_.segments; seg != NULL; seg = seg->next) { if (!compareHeaders(seg)) { continue; } double ts = seg->rel_secs + seg->rel_usecs / 1000000.0; - time_stamp_map_.insert(ts, seg); } @@ -268,12 +275,23 @@ void LteRlcGraphDialog::fillGraph() reseg_seq_time, reseg_seq, acks_time, acks, nacks_time, nacks; + + uint32_t last_ackSN = uint32_t(-1); // start with invalid value + uint32_t maxSN = 0; + + // Note the max possible SN + if (graph_.segments) { + maxSN = (1 << graph_.segments->sequenceNumberLength); + } + + // Run through the segments to get data for (struct rlc_segment *seg = graph_.segments; seg != NULL; seg = seg->next) { double ts = seg->rel_secs + (seg->rel_usecs / 1000000.0); if (compareHeaders(seg)) { if (!seg->isControlPDU) { - // Data + // Data PDUs if (seg->isResegmented) { + // LTE only reseg_seq_time.append(ts); reseg_seq.append(seg->SN); } @@ -283,22 +301,31 @@ void LteRlcGraphDialog::fillGraph() } } else { - // Status (ACKs/NACKs) - acks_time.append(ts); - acks.append(seg->ACKNo-1); - for (int n=0; n < seg->noOfNACKs; n++) { - nacks_time.append(ts); - nacks.append(seg->NACKs[n]); + // Status PDUs + + // Filter out ACKS that are likely caused by MAC retx, so track last ACK + if (seg->ACKNo != last_ackSN) { + // Status (ACKs/NACKs) + acks_time.append(ts); + acks.append((seg->ACKNo-1) % maxSN); + last_ackSN = seg->ACKNo; + + // Any NACKs + for (int n=0; n < seg->noOfNACKs; n++) { + nacks_time.append(ts); + nacks.append(seg->NACKs[n]); + } } } } } // Add the data from the graphs. - base_graph_->setData(seq_time, seq); - reseg_graph_->setData(reseg_seq_time, reseg_seq); - acks_graph_->setData(acks_time, acks); - nacks_graph_->setData(nacks_time, nacks); + // N.B. passing true to assume the timestamps are already sorted.. + base_graph_->setData(seq_time, seq, true); + reseg_graph_->setData(reseg_seq_time, reseg_seq, true); + acks_graph_->setData(acks_time, acks, true); + nacks_graph_->setData(nacks_time, nacks, true); sp->setEnabled(true); @@ -533,19 +560,16 @@ QRectF LteRlcGraphDialog::getZoomRanges(QRect zoom_rect) return zoom_ranges; } +void LteRlcGraphDialog::showContextMenu(const QPoint &pos) +{ + ctx_menu_->popup(ui->rlcPlot->mapToGlobal(pos)); +} + void LteRlcGraphDialog::graphClicked(QMouseEvent *event) { QCustomPlot *rp = ui->rlcPlot; - if (event->button() == Qt::RightButton) { - // XXX We should find some way to get rlcPlot to handle a - // contextMenuEvent instead. -#if QT_VERSION >= QT_VERSION_CHECK(6, 0 ,0) - ctx_menu_->popup(event->globalPosition().toPoint()); -#else - ctx_menu_->popup(event->globalPos()); -#endif - } else if (mouse_drags_) { + if (mouse_drags_) { if (rp->axisRect()->rect().contains(event->pos())) { rp->setCursor(QCursor(Qt::ClosedHandCursor)); } @@ -675,21 +699,21 @@ void LteRlcGraphDialog::resetAxes() { QCustomPlot *rp = ui->rlcPlot; - QCPRange x_range = rp->xAxis->scaleType() == QCPAxis::stLogarithmic ? - rp->xAxis->range().sanitizedForLogScale() : rp->xAxis->range(); - double pixel_pad = 10.0; // per side rp->rescaleAxes(true); - base_graph_->rescaleValueAxis(false, true); + + QCPRange x_range = rp->xAxis->range(); double axis_pixels = rp->xAxis->axisRect()->width(); rp->xAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, x_range.center()); axis_pixels = rp->yAxis->axisRect()->height(); - rp->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, rp->yAxis->range().center()); + rp->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, + rp->yAxis->range().center()); - rp->replot(QCustomPlot::rpQueuedReplot); + // N.B. TCP Stream Dialog uses default (rpRefreshHint) - was using QCustomPlot::rpQueuedReplot + rp->replot(); } void LteRlcGraphDialog::on_actionGoToPacket_triggered() @@ -800,7 +824,8 @@ void LteRlcGraphDialog::on_actionSwitchDirection_triggered() { // Channel settings exactly the same, except change direction. // N.B. do not fail and close if there are no packets in opposite direction. - setChannelInfo(graph_.ueid, + setChannelInfo(graph_.rat, + graph_.ueid, graph_.rlcMode, graph_.channelType, graph_.channelId, |