/* lbm_lbtrm_transport_dialog.cpp * * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved. * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "lbm_lbtrm_transport_dialog.h" #include #include "file.h" #include #include "main_application.h" #include #include #include #include #include #include #include #include #include #include #include namespace { static const int Source_AddressTransport_Column = 0; static const int Source_DataFrames_Column = 1; static const int Source_DataBytes_Column = 2; static const int Source_DataFramesBytes_Column = 3; static const int Source_DataRate_Column = 4; static const int Source_RXDataFrames_Column = 5; static const int Source_RXDataBytes_Column = 6; static const int Source_RXDataFramesBytes_Column = 7; static const int Source_RXDataRate_Column = 8; static const int Source_NCFFrames_Column = 9; static const int Source_NCFCount_Column = 10; static const int Source_NCFBytes_Column = 11; static const int Source_NCFFramesBytes_Column = 12; static const int Source_NCFCountBytes_Column = 13; static const int Source_NCFFramesCount_Column = 14; static const int Source_NCFFramesCountBytes_Column = 15; static const int Source_NCFRate_Column = 16; static const int Source_SMFrames_Column = 17; static const int Source_SMBytes_Column = 18; static const int Source_SMFramesBytes_Column = 19; static const int Source_SMRate_Column = 20; static const int Receiver_AddressTransport_Column = 0; static const int Receiver_NAKFrames_Column = 1; static const int Receiver_NAKCount_Column = 2; static const int Receiver_NAKBytes_Column = 3; static const int Receiver_NAKRate_Column = 4; static const int Detail_SQN_Column = 0; static const int Detail_Count_Column = 1; static const int Detail_Frame_Column = 2; static const double OneKilobit = 1000.0; static const double OneMegabit = OneKilobit * OneKilobit; static const double OneGigabit = OneMegabit * OneKilobit; } static QString format_rate(const nstime_t & elapsed, guint64 bytes) { QString result; double elapsed_sec; double rate; if (((elapsed.secs == 0) && (elapsed.nsecs == 0)) || (bytes == 0)) { return (QString("0")); } elapsed_sec = elapsed.secs + (((double)elapsed.nsecs) / 1000000000.0); rate = ((double)(bytes * 8)) / elapsed_sec; // Currently rate is in bps if (rate >= OneGigabit) { rate /= OneGigabit; result = QString("%1G").arg(rate, 0, 'f', 2); } else if (rate >= OneMegabit) { rate /= OneMegabit; result = QString("%1M").arg(rate, 0, 'f', 2); } else if (rate >= OneKilobit) { rate /= OneKilobit; result = QString("%1K").arg(rate, 0, 'f', 2); } else { result = QString("%1").arg(rate, 0, 'f', 2); } return (result); } // Note: // LBMLBTRMFrameEntry, LBMLBTRMSQNEntry, LBMLBTRMNCFReasonEntry, LBMLBTRMNCFSQNEntry, LBMLBTRMSourceTransportEntry, LBMLBTRMSourceEntry, // LBMLBTRMReceiverTransportEntry, and LBMLBTRMReceiverEntry are all derived from a QTreeWidgetItem. Each instantiation can exist // in two places: in a QTreeWidget, and in a containing QMap. // // For example: // - LBMLBTRMTransportDialogInfo contains a QMap of the sources (LBMLBTRMSourceEntry) and receivers (LBMLBTRMReceiverEntry) // - A source (LBMLBTRMSourceEntry) contains a QMap of the source transports originating from it (LBMLBTRMSourceTransportEntry) // - A source transport (LBMLBTRMSourceTransportEntry) contains QMaps of data, RX data, and SM SQNs (LBMLBTRMSQNEntry) and NCF SQNs // (LBMLBTRMNCFSQNEntry) // - A data SQN (LBMLBTRMSQNEntry) contains a QMap of the frames (LBMLBTRMFrameEntry) in which that SQN appears // // Not all of the entries actually appear in a QTreeWidget at one time. For example, in the source details, if no specific source // transport is selected, nothing is in the source details tree. If Data SQNs is selected, then those details appear in the source // details tree. Switching to RX Data SQNs removes whatever is currently in the source details tree, and adds the RX details for // the selected transport. // // The actual owner of one of the above QTreeWidgetItem-derived items is the QMap container in its parent. The item is "loaned" to // the QTreeWidget for display. // // All of this is to explain why // 1) we are frequently adding things to a QTreeWidget // 2) things are removed (takeTopLevelItem) from a QTreeWidget // 3) destruction involves removing all items from all QTreeWidgets (rather than letting QTreeWidget delete them) // 4) the destructor for each item has the form // // for (XXXMapIterator it = m_xxx.begin(); it != m_xxx.end(); it++) // { // delete *it; // } // m_xxx.clear(); // The for-loop calls the destructor for each item, while the clear() cleans up the space used by the QMap itself. // A frame entry class LBMLBTRMFrameEntry : public QTreeWidgetItem { public: LBMLBTRMFrameEntry(guint32 frame); virtual ~LBMLBTRMFrameEntry(void) { } guint32 getFrame(void) { return (m_frame); } private: guint32 m_frame; }; LBMLBTRMFrameEntry::LBMLBTRMFrameEntry(guint32 frame) : QTreeWidgetItem(), m_frame(frame) { setText(Detail_SQN_Column, QString(" ")); setText(Detail_Count_Column, QString(" ")); setText(Detail_Frame_Column, QString("%1").arg(m_frame)); } typedef QMap LBMLBTRMFrameMap; typedef QMap::iterator LBMLBTRMFrameMapIterator; // A SQN (SeQuence Number) entry class LBMLBTRMSQNEntry : public QTreeWidgetItem { public: LBMLBTRMSQNEntry(guint32 sqn); virtual ~LBMLBTRMSQNEntry(void); void processFrame(guint32 frame); private: LBMLBTRMSQNEntry(void); guint32 m_sqn; guint32 m_count; LBMLBTRMFrameMap m_frames; }; LBMLBTRMSQNEntry::LBMLBTRMSQNEntry(guint32 sqn) : QTreeWidgetItem(), m_sqn(sqn), m_count(0), m_frames() { setText(Detail_SQN_Column, QString("%1").arg(m_sqn)); setTextAlignment(Detail_SQN_Column, Qt::AlignRight); setText(Detail_Count_Column, QString("%1").arg(m_count)); setTextAlignment(Detail_Count_Column, Qt::AlignRight); setText(Detail_Frame_Column, QString(" ")); } LBMLBTRMSQNEntry::~LBMLBTRMSQNEntry(void) { for (LBMLBTRMFrameMapIterator it = m_frames.begin(); it != m_frames.end(); ++it) { delete *it; } m_frames.clear(); } void LBMLBTRMSQNEntry::processFrame(guint32 frame) { LBMLBTRMFrameMapIterator it; it = m_frames.find(frame); if (m_frames.end() == it) { LBMLBTRMFrameEntry * entry = new LBMLBTRMFrameEntry(frame); m_frames.insert(frame, entry); addChild(entry); sortChildren(Detail_Frame_Column, Qt::AscendingOrder); } m_count++; setText(Detail_Count_Column, QString("%1").arg(m_count)); setTextAlignment(Detail_Count_Column, Qt::AlignRight); } // An NCF (Nak ConFirmation) Reason entry class LBMLBTRMNCFReasonEntry : public QTreeWidgetItem { public: LBMLBTRMNCFReasonEntry(guint8 reason); virtual ~LBMLBTRMNCFReasonEntry(void); void processFrame(guint32 frame); private: LBMLBTRMNCFReasonEntry(void); guint8 m_reason; QString m_reason_string; guint32 m_count; LBMLBTRMFrameMap m_frames; }; LBMLBTRMNCFReasonEntry::LBMLBTRMNCFReasonEntry(guint8 reason) : QTreeWidgetItem(), m_reason(reason), m_reason_string(), m_count(0), m_frames() { switch (m_reason) { case LBTRM_NCF_REASON_NO_RETRY: m_reason_string = "No Retry"; break; case LBTRM_NCF_REASON_IGNORED: m_reason_string = "Ignored"; break; case LBTRM_NCF_REASON_RX_DELAY: m_reason_string = "Retransmit Delay"; break; case LBTRM_NCF_REASON_SHED: m_reason_string = "Shed"; break; default: m_reason_string = QString("Unknown (%1)").arg(m_reason); break; } setText(Detail_SQN_Column, m_reason_string); setText(Detail_Count_Column, QString("%1").arg(m_count)); setTextAlignment(Detail_Count_Column, Qt::AlignRight); setText(Detail_Frame_Column, QString(" ")); } LBMLBTRMNCFReasonEntry::~LBMLBTRMNCFReasonEntry(void) { for (LBMLBTRMFrameMapIterator it = m_frames.begin(); it != m_frames.end(); ++it) { delete *it; } m_frames.clear(); } void LBMLBTRMNCFReasonEntry::processFrame(guint32 frame) { LBMLBTRMFrameMapIterator it; it = m_frames.find(frame); if (m_frames.end() == it) { LBMLBTRMFrameEntry * entry = new LBMLBTRMFrameEntry(frame); m_frames.insert(frame, entry); addChild(entry); sortChildren(Detail_Frame_Column, Qt::AscendingOrder); } m_count++; setText(Detail_Count_Column, QString("%1").arg(m_count)); setTextAlignment(Detail_Count_Column, Qt::AlignRight); } typedef QMap LBMLBTRMNCFReasonMap; typedef QMap::iterator LBMLBTRMNCFReasonMapIterator; // An NCF SQN entry class LBMLBTRMNCFSQNEntry : public QTreeWidgetItem { public: LBMLBTRMNCFSQNEntry(guint32 sqn); virtual ~LBMLBTRMNCFSQNEntry(void); void processFrame(guint8 reason, guint32 frame); private: LBMLBTRMNCFSQNEntry(void); guint32 m_sqn; guint32 m_count; LBMLBTRMNCFReasonMap m_reasons; }; LBMLBTRMNCFSQNEntry::LBMLBTRMNCFSQNEntry(guint32 sqn) : QTreeWidgetItem(), m_sqn(sqn), m_count(0), m_reasons() { setText(Detail_SQN_Column, QString("%1").arg(m_sqn)); setTextAlignment(Detail_SQN_Column, Qt::AlignRight); setText(Detail_Count_Column, QString("%1").arg(m_count)); setTextAlignment(Detail_Count_Column, Qt::AlignRight); setText(Detail_Frame_Column, QString(" ")); } LBMLBTRMNCFSQNEntry::~LBMLBTRMNCFSQNEntry(void) { for (LBMLBTRMNCFReasonMapIterator it = m_reasons.begin(); it != m_reasons.end(); ++it) { delete *it; } m_reasons.clear(); } void LBMLBTRMNCFSQNEntry::processFrame(guint8 reason, guint32 frame) { LBMLBTRMNCFReasonMapIterator it; LBMLBTRMNCFReasonEntry * entry = NULL; it = m_reasons.find(reason); if (m_reasons.end() == it) { entry = new LBMLBTRMNCFReasonEntry(reason); m_reasons.insert(reason, entry); addChild(entry); sortChildren(Detail_Frame_Column, Qt::AscendingOrder); } else { entry = it.value(); } m_count++; setText(Detail_Count_Column, QString("%1").arg(m_count)); setTextAlignment(Detail_Count_Column, Qt::AlignRight); entry->processFrame(frame); } typedef QMap LBMLBTRMSQNMap; typedef QMap::iterator LBMLBTRMSQNMapIterator; typedef QMap LBMLBTRMNCFSQNMap; typedef QMap::iterator LBMLBTRMNCFSQNMapIterator; // A source transport entry class LBMLBTRMSourceTransportEntry : public QTreeWidgetItem { friend class LBMLBTRMTransportDialog; public: LBMLBTRMSourceTransportEntry(const QString & transport); virtual ~LBMLBTRMSourceTransportEntry(void); void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info); protected: QString m_transport; private: void fillItem(void); guint64 m_data_frames; guint64 m_data_bytes; guint64 m_rx_data_frames; guint64 m_rx_data_bytes; guint64 m_ncf_frames; guint64 m_ncf_count; guint64 m_ncf_bytes; guint64 m_sm_frames; guint64 m_sm_bytes; nstime_t m_first_frame_timestamp; bool m_first_frame_timestamp_valid; nstime_t m_last_frame_timestamp; protected: LBMLBTRMSQNMap m_data_sqns; LBMLBTRMSQNMap m_rx_data_sqns; LBMLBTRMNCFSQNMap m_ncf_sqns; LBMLBTRMSQNMap m_sm_sqns; }; LBMLBTRMSourceTransportEntry::LBMLBTRMSourceTransportEntry(const QString & transport) : QTreeWidgetItem(), m_transport(transport), m_data_frames(0), m_data_bytes(0), m_rx_data_frames(0), m_rx_data_bytes(0), m_ncf_frames(0), m_ncf_count(0), m_ncf_bytes(0), m_sm_frames(0), m_sm_bytes(0), m_first_frame_timestamp_valid(false), m_data_sqns(), m_rx_data_sqns(), m_ncf_sqns(), m_sm_sqns() { m_first_frame_timestamp.secs = 0; m_first_frame_timestamp.nsecs = 0; m_last_frame_timestamp.secs = 0; m_last_frame_timestamp.nsecs = 0; setText(Source_AddressTransport_Column, m_transport); } LBMLBTRMSourceTransportEntry::~LBMLBTRMSourceTransportEntry(void) { for (LBMLBTRMSQNMapIterator it = m_data_sqns.begin(); it != m_data_sqns.end(); ++it) { delete *it; } m_data_sqns.clear(); for (LBMLBTRMSQNMapIterator it = m_rx_data_sqns.begin(); it != m_rx_data_sqns.end(); ++it) { delete *it; } m_rx_data_sqns.clear(); for (LBMLBTRMNCFSQNMapIterator it = m_ncf_sqns.begin(); it != m_ncf_sqns.end(); ++it) { delete *it; } m_ncf_sqns.clear(); for (LBMLBTRMSQNMapIterator it = m_sm_sqns.begin(); it != m_sm_sqns.end(); ++it) { delete *it; } m_sm_sqns.clear(); } void LBMLBTRMSourceTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info) { if (m_first_frame_timestamp_valid) { if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0) { nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts)); } } else { nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts)); m_first_frame_timestamp_valid = true; } if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0) { nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts)); } if (tap_info->type == LBTRM_PACKET_TYPE_DATA) { LBMLBTRMSQNEntry * sqn = NULL; LBMLBTRMSQNMapIterator it; if (tap_info->retransmission) { m_rx_data_frames++; m_rx_data_bytes += pinfo->fd->pkt_len; it = m_rx_data_sqns.find(tap_info->sqn); if (m_rx_data_sqns.end() == it) { sqn = new LBMLBTRMSQNEntry(tap_info->sqn); m_rx_data_sqns.insert(tap_info->sqn, sqn); } else { sqn = it.value(); } } else { m_data_frames++; m_data_bytes += pinfo->fd->pkt_len; it = m_data_sqns.find(tap_info->sqn); if (m_data_sqns.end() == it) { sqn = new LBMLBTRMSQNEntry(tap_info->sqn); m_data_sqns.insert(tap_info->sqn, sqn); } else { sqn = it.value(); } } sqn->processFrame(pinfo->num); } else if (tap_info->type == LBTRM_PACKET_TYPE_NCF) { guint16 idx; LBMLBTRMNCFSQNMapIterator it; LBMLBTRMNCFSQNEntry * sqn = NULL; m_ncf_frames++; m_ncf_bytes += pinfo->fd->pkt_len; m_ncf_count += (guint64)tap_info->num_sqns; for (idx = 0; idx < tap_info->num_sqns; idx++) { it = m_ncf_sqns.find(tap_info->sqns[idx]); if (m_ncf_sqns.end() == it) { sqn = new LBMLBTRMNCFSQNEntry(tap_info->sqns[idx]); m_ncf_sqns.insert(tap_info->sqns[idx], sqn); } else { sqn = it.value(); } sqn->processFrame(tap_info->ncf_reason, pinfo->num); } } else if (tap_info->type == LBTRM_PACKET_TYPE_SM) { LBMLBTRMSQNEntry * sqn = NULL; LBMLBTRMSQNMapIterator it; m_sm_frames++; m_sm_bytes += pinfo->fd->pkt_len; it = m_sm_sqns.find(tap_info->sqn); if (m_sm_sqns.end() == it) { sqn = new LBMLBTRMSQNEntry(tap_info->sqn); m_sm_sqns.insert(tap_info->sqn, sqn); } else { sqn = it.value(); } sqn->processFrame(pinfo->num); } else { return; } fillItem(); } void LBMLBTRMSourceTransportEntry::fillItem(void) { nstime_t delta; nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp); setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames)); setTextAlignment(Source_DataFrames_Column, Qt::AlignRight); setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes)); setTextAlignment(Source_DataBytes_Column, Qt::AlignRight); setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes)); setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter); setText(Source_DataRate_Column, format_rate(delta, m_data_bytes)); setTextAlignment(Source_DataRate_Column, Qt::AlignRight); setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames)); setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight); setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes)); setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight); setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes)); setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter); setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes)); setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight); setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames)); setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight); setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count)); setTextAlignment(Source_NCFCount_Column, Qt::AlignRight); setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes)); setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight); setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes)); setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter); setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes)); setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter); setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_count)); setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter); setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes)); setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter); setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes)); setTextAlignment(Source_NCFRate_Column, Qt::AlignRight); setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames)); setTextAlignment(Source_SMFrames_Column, Qt::AlignRight); setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes)); setTextAlignment(Source_SMBytes_Column, Qt::AlignRight); setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes)); setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignHCenter); setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes)); setTextAlignment(Source_SMRate_Column, Qt::AlignRight); } typedef QMap LBMLBTRMSourceTransportMap; typedef QMap::iterator LBMLBTRMSourceTransportMapIterator; // A source (address) entry class LBMLBTRMSourceEntry : public QTreeWidgetItem { public: LBMLBTRMSourceEntry(const QString & source_address); virtual ~LBMLBTRMSourceEntry(void); void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info); private: void fillItem(void); QString m_address; QString m_transport; guint64 m_data_frames; guint64 m_data_bytes; guint64 m_rx_data_frames; guint64 m_rx_data_bytes; guint64 m_ncf_frames; guint64 m_ncf_count; guint64 m_ncf_bytes; guint64 m_sm_frames; guint64 m_sm_bytes; nstime_t m_first_frame_timestamp; bool m_first_frame_timestamp_valid; nstime_t m_last_frame_timestamp; LBMLBTRMSourceTransportMap m_transports; }; LBMLBTRMSourceEntry::LBMLBTRMSourceEntry(const QString & source_address) : QTreeWidgetItem(), m_address(source_address), m_data_frames(0), m_data_bytes(0), m_rx_data_frames(0), m_rx_data_bytes(0), m_ncf_frames(0), m_ncf_count(0), m_ncf_bytes(0), m_sm_frames(0), m_sm_bytes(0), m_first_frame_timestamp_valid(false), m_transports() { m_first_frame_timestamp.secs = 0; m_first_frame_timestamp.nsecs = 0; m_last_frame_timestamp.secs = 0; m_last_frame_timestamp.nsecs = 0; setText(Source_AddressTransport_Column, m_address); } LBMLBTRMSourceEntry::~LBMLBTRMSourceEntry(void) { for (LBMLBTRMSourceTransportMapIterator it = m_transports.begin(); it != m_transports.end(); ++it) { delete *it; } m_transports.clear(); } void LBMLBTRMSourceEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info) { LBMLBTRMSourceTransportEntry * transport = NULL; LBMLBTRMSourceTransportMapIterator it; if (m_first_frame_timestamp_valid) { if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0) { nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts)); } } else { nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts)); m_first_frame_timestamp_valid = true; } if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0) { nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts)); } if (tap_info->type == LBTRM_PACKET_TYPE_DATA) { if (tap_info->retransmission) { m_rx_data_frames++; m_rx_data_bytes += pinfo->fd->pkt_len; } else { m_data_frames++; m_data_bytes += pinfo->fd->pkt_len; } } else if (tap_info->type == LBTRM_PACKET_TYPE_NCF) { m_ncf_frames++; m_ncf_bytes += pinfo->fd->pkt_len; m_ncf_count += tap_info->num_sqns; } else if (tap_info->type == LBTRM_PACKET_TYPE_SM) { m_sm_frames++; m_sm_bytes += pinfo->fd->pkt_len; } it = m_transports.find(tap_info->transport); if (m_transports.end() == it) { transport = new LBMLBTRMSourceTransportEntry(tap_info->transport); m_transports.insert(tap_info->transport, transport); addChild(transport); sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder); } else { transport = it.value(); } fillItem(); transport->processPacket(pinfo, tap_info); } void LBMLBTRMSourceEntry::fillItem(void) { nstime_t delta; nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp); setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames)); setTextAlignment(Source_DataFrames_Column, Qt::AlignRight); setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes)); setTextAlignment(Source_DataBytes_Column, Qt::AlignRight); setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes)); setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter); setText(Source_DataRate_Column, format_rate(delta, m_data_bytes)); setTextAlignment(Source_DataRate_Column, Qt::AlignRight); setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames)); setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight); setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes)); setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight); setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes)); setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter); setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes)); setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight); setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames)); setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight); setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count)); setTextAlignment(Source_NCFCount_Column, Qt::AlignRight); setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes)); setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight); setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes)); setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter); setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes)); setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter); setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_count)); setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter); setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes)); setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter); setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes)); setTextAlignment(Source_NCFRate_Column, Qt::AlignRight); setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames)); setTextAlignment(Source_SMFrames_Column, Qt::AlignRight); setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes)); setTextAlignment(Source_SMBytes_Column, Qt::AlignRight); setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes)); setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignRight); setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes)); setTextAlignment(Source_SMRate_Column, Qt::AlignRight); } typedef QMap LBMLBTRMSourceMap; typedef QMap::iterator LBMLBTRMSourceMapIterator; // A receiver transport entry class LBMLBTRMReceiverTransportEntry : public QTreeWidgetItem { friend class LBMLBTRMTransportDialog; public: LBMLBTRMReceiverTransportEntry(const QString & transport); virtual ~LBMLBTRMReceiverTransportEntry(void); void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info); private: void fillItem(void); QString m_transport; guint64 m_nak_frames; guint64 m_nak_count; guint64 m_nak_bytes; nstime_t m_first_frame_timestamp; bool m_first_frame_timestamp_valid; nstime_t m_last_frame_timestamp; protected: LBMLBTRMSQNMap m_nak_sqns; }; LBMLBTRMReceiverTransportEntry::LBMLBTRMReceiverTransportEntry(const QString & transport) : QTreeWidgetItem(), m_transport(transport), m_nak_frames(0), m_nak_count(0), m_nak_bytes(0), m_first_frame_timestamp_valid(false), m_nak_sqns() { m_first_frame_timestamp.secs = 0; m_first_frame_timestamp.nsecs = 0; m_last_frame_timestamp.secs = 0; m_last_frame_timestamp.nsecs = 0; setText(Receiver_AddressTransport_Column, m_transport); } LBMLBTRMReceiverTransportEntry::~LBMLBTRMReceiverTransportEntry(void) { for (LBMLBTRMSQNMapIterator it = m_nak_sqns.begin(); it != m_nak_sqns.end(); ++it) { delete *it; } m_nak_sqns.clear(); } void LBMLBTRMReceiverTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info) { if (m_first_frame_timestamp_valid) { if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0) { nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts)); } } else { nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts)); m_first_frame_timestamp_valid = true; } if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0) { nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts)); } if (tap_info->type == LBTRM_PACKET_TYPE_NAK) { guint16 idx; LBMLBTRMSQNEntry * sqn = NULL; LBMLBTRMSQNMapIterator it; m_nak_frames++; m_nak_bytes += pinfo->fd->pkt_len; m_nak_count += tap_info->num_sqns; for (idx = 0; idx < tap_info->num_sqns; idx++) { it = m_nak_sqns.find(tap_info->sqns[idx]); if (m_nak_sqns.end() == it) { sqn = new LBMLBTRMSQNEntry(tap_info->sqns[idx]); m_nak_sqns.insert(tap_info->sqns[idx], sqn); } else { sqn = it.value(); } sqn->processFrame(pinfo->num); } } else { return; } fillItem(); } void LBMLBTRMReceiverTransportEntry::fillItem(void) { nstime_t delta; nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp); setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames)); setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight); setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count)); setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight); setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes)); setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight); setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes)); setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight); } typedef QMap LBMLBTRMReceiverTransportMap; typedef QMap::iterator LBMLBTRMReceiverTransportMapIterator; // A receiver (address) entry class LBMLBTRMReceiverEntry : public QTreeWidgetItem { public: LBMLBTRMReceiverEntry(const QString & receiver_address); virtual ~LBMLBTRMReceiverEntry(void); void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info); private: LBMLBTRMReceiverEntry(void); void fillItem(void); QString m_address; QString m_transport; guint64 m_nak_frames; guint64 m_nak_count; guint64 m_nak_bytes; nstime_t m_first_frame_timestamp; bool m_first_frame_timestamp_valid; nstime_t m_last_frame_timestamp; LBMLBTRMReceiverTransportMap m_transports; }; LBMLBTRMReceiverEntry::LBMLBTRMReceiverEntry(const QString & receiver_address) : QTreeWidgetItem(), m_address(receiver_address), m_nak_frames(0), m_nak_count(0), m_nak_bytes(0), m_first_frame_timestamp_valid(false), m_transports() { m_first_frame_timestamp.secs = 0; m_first_frame_timestamp.nsecs = 0; m_last_frame_timestamp.secs = 0; m_last_frame_timestamp.nsecs = 0; setText(Receiver_AddressTransport_Column, m_address); } LBMLBTRMReceiverEntry::~LBMLBTRMReceiverEntry(void) { for (LBMLBTRMReceiverTransportMapIterator it = m_transports.begin(); it != m_transports.end(); ++it) { delete *it; } m_transports.clear(); } void LBMLBTRMReceiverEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info) { LBMLBTRMReceiverTransportEntry * transport = NULL; LBMLBTRMReceiverTransportMapIterator it; if (m_first_frame_timestamp_valid) { if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0) { nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts)); } } else { nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts)); m_first_frame_timestamp_valid = true; } if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0) { nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts)); } if (tap_info->type == LBTRM_PACKET_TYPE_NAK) { m_nak_frames++; m_nak_bytes += pinfo->fd->pkt_len; m_nak_count += tap_info->num_sqns; } it = m_transports.find(tap_info->transport); if (m_transports.end() == it) { transport = new LBMLBTRMReceiverTransportEntry(tap_info->transport); m_transports.insert(tap_info->transport, transport); addChild(transport); sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder); } else { transport = it.value(); } fillItem(); transport->processPacket(pinfo, tap_info); } void LBMLBTRMReceiverEntry::fillItem(void) { nstime_t delta; nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp); setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames)); setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight); setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count)); setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight); setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes)); setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight); setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes)); setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight); } typedef QMap LBMLBTRMReceiverMap; typedef QMap::iterator LBMLBTRMReceiverMapIterator; class LBMLBTRMTransportDialogInfo { public: LBMLBTRMTransportDialogInfo(void); ~LBMLBTRMTransportDialogInfo(void); void setDialog(LBMLBTRMTransportDialog * dialog); LBMLBTRMTransportDialog * getDialog(void); void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info); void clearMaps(void); private: LBMLBTRMTransportDialog * m_dialog; LBMLBTRMSourceMap m_sources; LBMLBTRMReceiverMap m_receivers; }; LBMLBTRMTransportDialogInfo::LBMLBTRMTransportDialogInfo(void) : m_dialog(NULL), m_sources(), m_receivers() { } LBMLBTRMTransportDialogInfo::~LBMLBTRMTransportDialogInfo(void) { clearMaps(); } void LBMLBTRMTransportDialogInfo::setDialog(LBMLBTRMTransportDialog * dialog) { m_dialog = dialog; } LBMLBTRMTransportDialog * LBMLBTRMTransportDialogInfo::getDialog(void) { return (m_dialog); } void LBMLBTRMTransportDialogInfo::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info) { switch (tap_info->type) { case LBTRM_PACKET_TYPE_DATA: case LBTRM_PACKET_TYPE_SM: case LBTRM_PACKET_TYPE_NCF: { LBMLBTRMSourceEntry * source = NULL; LBMLBTRMSourceMapIterator it; QString src_address = address_to_qstring(&(pinfo->src)); it = m_sources.find(src_address); if (m_sources.end() == it) { QTreeWidgetItem * parent = NULL; Ui::LBMLBTRMTransportDialog * ui = NULL; source = new LBMLBTRMSourceEntry(src_address); it = m_sources.insert(src_address, source); ui = m_dialog->getUI(); ui->sources_TreeWidget->addTopLevelItem(source); parent = ui->sources_TreeWidget->invisibleRootItem(); parent->sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder); ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column); } else { source = it.value(); } source->processPacket(pinfo, tap_info); } break; case LBTRM_PACKET_TYPE_NAK: { LBMLBTRMReceiverEntry * receiver = NULL; LBMLBTRMReceiverMapIterator it; QString src_address = address_to_qstring(&(pinfo->src)); it = m_receivers.find(src_address); if (m_receivers.end() == it) { QTreeWidgetItem * parent = NULL; Ui::LBMLBTRMTransportDialog * ui = NULL; receiver = new LBMLBTRMReceiverEntry(src_address); it = m_receivers.insert(src_address, receiver); ui = m_dialog->getUI(); ui->receivers_TreeWidget->addTopLevelItem(receiver); parent = ui->receivers_TreeWidget->invisibleRootItem(); parent->sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder); ui->receivers_TreeWidget->resizeColumnToContents(Receiver_AddressTransport_Column); } else { receiver = it.value(); } receiver->processPacket(pinfo, tap_info); } break; default: break; } } void LBMLBTRMTransportDialogInfo::clearMaps(void) { for (LBMLBTRMSourceMapIterator it = m_sources.begin(); it != m_sources.end(); ++it) { delete *it; } m_sources.clear(); for (LBMLBTRMReceiverMapIterator it = m_receivers.begin(); it != m_receivers.end(); ++it) { delete *it; } m_receivers.clear(); } LBMLBTRMTransportDialog::LBMLBTRMTransportDialog(QWidget * parent, capture_file * cfile) : QDialog(parent), m_ui(new Ui::LBMLBTRMTransportDialog), m_dialog_info(NULL), m_capture_file(cfile), m_current_source_transport(NULL), m_current_receiver_transport(NULL), m_source_context_menu(NULL), m_source_header(NULL) { m_ui->setupUi(this); m_dialog_info = new LBMLBTRMTransportDialogInfo(); m_ui->tabWidget->setCurrentIndex(0); m_ui->sources_detail_ComboBox->setCurrentIndex(0); m_ui->sources_detail_transport_Label->setText(QString(" ")); m_ui->receivers_detail_transport_Label->setText(QString(" ")); m_ui->stackedWidget->setCurrentIndex(0); m_source_header = m_ui->sources_TreeWidget->header(); m_source_context_menu = new QMenu(m_source_header); m_source_context_menu->addAction(m_ui->action_SourceAutoResizeColumns); connect(m_ui->action_SourceAutoResizeColumns, SIGNAL(triggered()), this, SLOT(actionSourceAutoResizeColumns_triggered())); m_source_context_menu->addSeparator(); m_ui->action_SourceDataFrames->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceDataFrames); connect(m_ui->action_SourceDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFrames_triggered(bool))); m_ui->action_SourceDataBytes->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceDataBytes); connect(m_ui->action_SourceDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataBytes_triggered(bool))); m_ui->action_SourceDataFramesBytes->setChecked(false); m_source_context_menu->addAction(m_ui->action_SourceDataFramesBytes); connect(m_ui->action_SourceDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFramesBytes_triggered(bool))); m_ui->action_SourceDataRate->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceDataRate); connect(m_ui->action_SourceDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataRate_triggered(bool))); m_ui->action_SourceRXDataFrames->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceRXDataFrames); connect(m_ui->action_SourceRXDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFrames_triggered(bool))); m_ui->action_SourceRXDataBytes->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceRXDataBytes); connect(m_ui->action_SourceRXDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataBytes_triggered(bool))); m_ui->action_SourceRXDataFramesBytes->setChecked(false); m_source_context_menu->addAction(m_ui->action_SourceRXDataFramesBytes); connect(m_ui->action_SourceRXDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFramesBytes_triggered(bool))); m_ui->action_SourceRXDataRate->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceRXDataRate); connect(m_ui->action_SourceRXDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataRate_triggered(bool))); m_ui->action_SourceNCFFrames->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceNCFFrames); connect(m_ui->action_SourceNCFFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFrames_triggered(bool))); m_ui->action_SourceNCFCount->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceNCFCount); connect(m_ui->action_SourceNCFCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCount_triggered(bool))); m_ui->action_SourceNCFBytes->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceNCFBytes); connect(m_ui->action_SourceNCFBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFBytes_triggered(bool))); m_ui->action_SourceNCFFramesBytes->setChecked(false); m_source_context_menu->addAction(m_ui->action_SourceNCFFramesBytes); connect(m_ui->action_SourceNCFFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesBytes_triggered(bool))); m_ui->action_SourceNCFCountBytes->setChecked(false); m_source_context_menu->addAction(m_ui->action_SourceNCFCountBytes); connect(m_ui->action_SourceNCFCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCountBytes_triggered(bool))); m_ui->action_SourceNCFFramesCount->setChecked(false); m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCount); connect(m_ui->action_SourceNCFFramesCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCount_triggered(bool))); m_ui->action_SourceNCFFramesCountBytes->setChecked(false); m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCountBytes); connect(m_ui->action_SourceNCFFramesCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCountBytes_triggered(bool))); m_ui->action_SourceNCFRate->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceNCFRate); connect(m_ui->action_SourceNCFRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFRate_triggered(bool))); m_ui->action_SourceSMFrames->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceSMFrames); connect(m_ui->action_SourceSMFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFrames_triggered(bool))); m_ui->action_SourceSMBytes->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceSMBytes); connect(m_ui->action_SourceSMBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMBytes_triggered(bool))); m_ui->action_SourceSMFramesBytes->setChecked(false); m_source_context_menu->addAction(m_ui->action_SourceSMFramesBytes); connect(m_ui->action_SourceSMFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFramesBytes_triggered(bool))); m_ui->action_SourceSMRate->setChecked(true); m_source_context_menu->addAction(m_ui->action_SourceSMRate); connect(m_ui->action_SourceSMRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMRate_triggered(bool))); m_source_header->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_source_header, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(custom_source_context_menuRequested(const QPoint &))); m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, true); m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, true); m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, true); m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, true); m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, true); m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, true); m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, true); setAttribute(Qt::WA_DeleteOnClose, true); fillTree(); } LBMLBTRMTransportDialog::~LBMLBTRMTransportDialog(void) { resetSourcesDetail(); resetSources(); resetReceiversDetail(); resetReceivers(); if (m_dialog_info != NULL) { delete m_dialog_info; m_dialog_info = NULL; } delete m_source_context_menu; m_source_context_menu = NULL; delete m_ui; m_ui = NULL; m_capture_file = NULL; } void LBMLBTRMTransportDialog::setCaptureFile(capture_file * cfile) { if (cfile == NULL) // We only want to know when the file closes. { m_capture_file = NULL; m_ui->displayFilterLineEdit->setEnabled(false); m_ui->applyFilterButton->setEnabled(false); } } void LBMLBTRMTransportDialog::resetSources(void) { while (m_ui->sources_TreeWidget->takeTopLevelItem(0) != NULL) {} } void LBMLBTRMTransportDialog::resetReceivers(void) { while (m_ui->receivers_TreeWidget->takeTopLevelItem(0) != NULL) {} } void LBMLBTRMTransportDialog::resetSourcesDetail(void) { while (m_ui->sources_detail_sqn_TreeWidget->takeTopLevelItem(0) != NULL) {} while (m_ui->sources_detail_ncf_sqn_TreeWidget->takeTopLevelItem(0) != NULL) {} m_ui->sources_detail_transport_Label->setText(QString(" ")); m_current_source_transport = NULL; } void LBMLBTRMTransportDialog::resetReceiversDetail(void) { while (m_ui->receivers_detail_TreeWidget->takeTopLevelItem(0) != NULL) {} m_ui->receivers_detail_transport_Label->setText(QString(" ")); m_current_receiver_transport = NULL; } void LBMLBTRMTransportDialog::fillTree(void) { GString * error_string; if (m_capture_file == NULL) { return; } m_dialog_info->setDialog(this); error_string = register_tap_listener("lbm_lbtrm", (void *)m_dialog_info, m_ui->displayFilterLineEdit->text().toUtf8().constData(), TL_REQUIRES_COLUMNS, resetTap, tapPacket, drawTreeItems, NULL); if (error_string) { QMessageBox::critical(this, tr("LBT-RM Statistics failed to attach to tap"), error_string->str); g_string_free(error_string, TRUE); reject(); } cf_retap_packets(m_capture_file); drawTreeItems(&m_dialog_info); remove_tap_listener((void *)m_dialog_info); } void LBMLBTRMTransportDialog::resetTap(void * tap_data) { LBMLBTRMTransportDialogInfo * info = (LBMLBTRMTransportDialogInfo *) tap_data; LBMLBTRMTransportDialog * dialog = info->getDialog(); if (dialog == NULL) { return; } dialog->resetSourcesDetail(); dialog->resetSources(); dialog->resetReceiversDetail(); dialog->resetReceivers(); info->clearMaps(); } tap_packet_status LBMLBTRMTransportDialog::tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t *, const void * tap_info, tap_flags_t) { if (pinfo->fd->passed_dfilter == 1) { const lbm_lbtrm_tap_info_t * tapinfo = (const lbm_lbtrm_tap_info_t *)tap_info; LBMLBTRMTransportDialogInfo * info = (LBMLBTRMTransportDialogInfo *)tap_data; info->processPacket(pinfo, tapinfo); } return (TAP_PACKET_REDRAW); } void LBMLBTRMTransportDialog::drawTreeItems(void *) { } void LBMLBTRMTransportDialog::on_applyFilterButton_clicked(void) { fillTree(); } void LBMLBTRMTransportDialog::sourcesDetailCurrentChanged(int index) { // Index 0: Data // Index 1: RX data // Index 2: NCF // Index 3: SM switch (index) { case 0: case 1: case 3: m_ui->stackedWidget->setCurrentIndex(0); break; case 2: m_ui->stackedWidget->setCurrentIndex(1); break; default: return; } sourcesItemClicked(m_current_source_transport, 0); } void LBMLBTRMTransportDialog::sourcesItemClicked(QTreeWidgetItem * item, int) { LBMLBTRMSourceTransportEntry * transport = dynamic_cast(item); resetSourcesDetail(); if (transport == NULL) { // Must be a source item, ignore it? return; } m_current_source_transport = transport; m_ui->sources_detail_transport_Label->setText(transport->m_transport); int cur_idx = m_ui->sources_detail_ComboBox->currentIndex(); switch (cur_idx) { case 0: loadSourceDataDetails(transport); break; case 1: loadSourceRXDataDetails(transport); break; case 2: loadSourceNCFDetails(transport); break; case 3: loadSourceSMDetails(transport); break; default: break; } } void LBMLBTRMTransportDialog::loadSourceDataDetails(LBMLBTRMSourceTransportEntry * transport) { for (LBMLBTRMSQNMapIterator it = transport->m_data_sqns.begin(); it != transport->m_data_sqns.end(); ++it) { LBMLBTRMSQNEntry * sqn = it.value(); m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn); } } void LBMLBTRMTransportDialog::loadSourceRXDataDetails(LBMLBTRMSourceTransportEntry * transport) { for (LBMLBTRMSQNMapIterator it = transport->m_rx_data_sqns.begin(); it != transport->m_rx_data_sqns.end(); ++it) { LBMLBTRMSQNEntry * sqn = it.value(); m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn); } } void LBMLBTRMTransportDialog::loadSourceNCFDetails(LBMLBTRMSourceTransportEntry * transport) { for (LBMLBTRMNCFSQNMapIterator it = transport->m_ncf_sqns.begin(); it != transport->m_ncf_sqns.end(); ++it) { LBMLBTRMNCFSQNEntry * sqn = it.value(); m_ui->sources_detail_ncf_sqn_TreeWidget->addTopLevelItem(sqn); } } void LBMLBTRMTransportDialog::loadSourceSMDetails(LBMLBTRMSourceTransportEntry * transport) { for (LBMLBTRMSQNMapIterator it = transport->m_sm_sqns.begin(); it != transport->m_sm_sqns.end(); ++it) { LBMLBTRMSQNEntry * sqn = it.value(); m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn); } } void LBMLBTRMTransportDialog::receiversItemClicked(QTreeWidgetItem * item, int) { LBMLBTRMReceiverTransportEntry * transport = dynamic_cast(item); resetReceiversDetail(); if (transport == NULL) { // Must be a receiver item, ignore it? return; } m_current_receiver_transport = transport; m_ui->receivers_detail_transport_Label->setText(transport->m_transport); loadReceiverNAKDetails(transport); } void LBMLBTRMTransportDialog::loadReceiverNAKDetails(LBMLBTRMReceiverTransportEntry * transport) { for (LBMLBTRMSQNMapIterator it = transport->m_nak_sqns.begin(); it != transport->m_nak_sqns.end(); ++it) { LBMLBTRMSQNEntry * sqn = it.value(); m_ui->receivers_detail_TreeWidget->addTopLevelItem(sqn); } } void LBMLBTRMTransportDialog::sourcesDetailItemDoubleClicked(QTreeWidgetItem * item, int) { LBMLBTRMFrameEntry * frame = dynamic_cast(item); if (frame == NULL) { // Must have double-clicked on something other than an expanded frame entry return; } emit goToPacket((int)frame->getFrame()); } void LBMLBTRMTransportDialog::receiversDetailItemDoubleClicked(QTreeWidgetItem * item, int) { LBMLBTRMFrameEntry * frame = dynamic_cast(item); if (frame == NULL) { // Must have double-clicked on something other than an expanded frame entry return; } emit goToPacket((int)frame->getFrame()); } void LBMLBTRMTransportDialog::custom_source_context_menuRequested(const QPoint & pos) { m_source_context_menu->popup(m_source_header->mapToGlobal(pos)); } void LBMLBTRMTransportDialog::actionSourceDataFrames_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_DataFrames_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceDataBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_DataBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceDataFramesBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceDataRate_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_DataRate_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceRXDataFrames_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFrames_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceRXDataBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceRXDataFramesBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceRXDataRate_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataRate_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceNCFFrames_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceNCFCount_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCount_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceNCFBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceNCFFramesBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceNCFCountBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceNCFFramesCount_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceNCFFramesCountBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceNCFRate_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_NCFRate_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceSMFrames_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_SMFrames_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceSMBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_SMBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceSMFramesBytes_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceSMRate_triggered(bool checked) { m_ui->sources_TreeWidget->setColumnHidden(Source_SMRate_Column, !checked); } void LBMLBTRMTransportDialog::actionSourceAutoResizeColumns_triggered(void) { m_ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFrames_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFramesBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataRate_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFrames_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFramesBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataRate_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFrames_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCount_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCountBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCount_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCountBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFRate_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFrames_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFramesBytes_Column); m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMRate_Column); }