Try to squeeze some bytes out of the frame_data structure.
[gd/wireshark/.git] / ui / qt / lbm_lbtru_transport_dialog.cpp
1 /* lbm_lbtru_transport_dialog.cpp
2  *
3  * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11
12 #include "lbm_lbtru_transport_dialog.h"
13 #include <ui_lbm_lbtru_transport_dialog.h>
14
15 #include "file.h"
16
17 #include <ui/qt/utils/qt_ui_utils.h>
18 #include "wireshark_application.h"
19
20 #include <QClipboard>
21 #include <QMessageBox>
22 #include <QTreeWidget>
23 #include <QTreeWidgetItemIterator>
24 #include <QMenu>
25 #include <QTreeWidgetItem>
26
27 #include <epan/packet_info.h>
28 #include <epan/tap.h>
29 #include <epan/to_str.h>
30 #include <epan/dissectors/packet-lbm.h>
31 #include <wsutil/nstime.h>
32
33 #include <QDebug>
34
35 namespace
36 {
37     static const int Source_AddressTransport_Column = 0;
38     static const int Source_DataFrames_Column = 1;
39     static const int Source_DataBytes_Column = 2;
40     static const int Source_DataFramesBytes_Column = 3;
41     static const int Source_DataRate_Column = 4;
42     static const int Source_RXDataFrames_Column = 5;
43     static const int Source_RXDataBytes_Column = 6;
44     static const int Source_RXDataFramesBytes_Column = 7;
45     static const int Source_RXDataRate_Column = 8;
46     static const int Source_NCFFrames_Column = 9;
47     static const int Source_NCFCount_Column = 10;
48     static const int Source_NCFBytes_Column = 11;
49     static const int Source_NCFFramesBytes_Column = 12;
50     static const int Source_NCFCountBytes_Column = 13;
51     static const int Source_NCFFramesCount_Column = 14;
52     static const int Source_NCFFramesCountBytes_Column = 15;
53     static const int Source_NCFRate_Column = 16;
54     static const int Source_SMFrames_Column = 17;
55     static const int Source_SMBytes_Column = 18;
56     static const int Source_SMFramesBytes_Column = 19;
57     static const int Source_SMRate_Column = 20;
58     static const int Source_RSTFrames_Column = 21;
59     static const int Source_RSTBytes_Column = 22;
60     static const int Source_RSTFramesBytes_Column = 23;
61     static const int Source_RSTRate_Column = 24;
62
63     static const int Receiver_AddressTransport_Column = 0;
64     static const int Receiver_NAKFrames_Column = 1;
65     static const int Receiver_NAKCount_Column = 2;
66     static const int Receiver_NAKBytes_Column = 3;
67     static const int Receiver_NAKFramesCount_Column = 4;
68     static const int Receiver_NAKCountBytes_Column = 5;
69     static const int Receiver_NAKFramesBytes_Column = 6;
70     static const int Receiver_NAKFramesCountBytes_Column = 7;
71     static const int Receiver_NAKRate_Column = 8;
72     static const int Receiver_ACKFrames_Column = 9;
73     static const int Receiver_ACKBytes_Column = 10;
74     static const int Receiver_ACKFramesBytes_Column = 11;
75     static const int Receiver_ACKRate_Column = 12;
76     static const int Receiver_CREQFrames_Column = 13;
77     static const int Receiver_CREQBytes_Column = 14;
78     static const int Receiver_CREQFramesBytes_Column = 15;
79     static const int Receiver_CREQRate_Column = 16;
80
81     static const int Detail_SQNReasonType_Column = 0;
82     static const int Detail_Count_Column = 1;
83     static const int Detail_Frame_Column = 2;
84
85     static const double OneKilobit = 1000.0;
86     static const double OneMegabit = OneKilobit * OneKilobit;
87     static const double OneGigabit = OneMegabit * OneKilobit;
88 }
89
90 static QString format_rate(const nstime_t & elapsed, guint64 bytes)
91 {
92     QString result;
93     double elapsed_sec;
94     double rate;
95
96     if (((elapsed.secs == 0) && (elapsed.nsecs == 0)) || (bytes == 0))
97     {
98         return (QString("0"));
99     }
100
101     elapsed_sec = elapsed.secs + (((double)elapsed.nsecs) / 1000000000.0);
102     rate = ((double)(bytes * 8)) / elapsed_sec;
103
104     // Currently rate is in bps
105     if (rate >= OneGigabit)
106     {
107         rate /= OneGigabit;
108         result = QString("%1G").arg(rate, 0, 'f', 2);
109     }
110     else if (rate >= OneMegabit)
111     {
112         rate /= OneMegabit;
113         result = QString("%1M").arg(rate, 0, 'f', 2);
114     }
115     else if (rate >= OneKilobit)
116     {
117         rate /= OneKilobit;
118         result = QString("%1K").arg(rate, 0, 'f', 2);
119     }
120     else
121     {
122         result = QString("%1").arg(rate, 0, 'f', 2);
123     }
124     return (result);
125 }
126
127 // Note:
128 // LBMLBTRUFrameEntry, LBMLBTRUSQNEntry, LBMLBTRUNCFReasonEntry, LBMLBTRUNCFSQNEntry, LBMLBTRURSTReasonEntry, LBMLBTRUCREQRequestEntry,
129 // LBMLBTRUSourceTransportEntry, LBMLBTRUSourceEntry, LBMLBTRUReceiverTransportEntry, and LBMLBTRUReceiverEntry are all derived from
130 // a QTreeWidgetItem. Each instantiation can exist in two places: in a QTreeWidget, and in a containing QMap.
131 //
132 // For example:
133 // - LBMLBTRUTransportDialogInfo contains a QMap of the sources (LBMLBTRUSourceEntry) and receivers (LBMLBTRUReceiverEntry)
134 // - A source (LBMLBTRUSourceEntry) contains a QMap of the source transports originating from it (LBMLBTRUSourceTransportEntry)
135 // - A source transport (LBMLBTRUSourceTransportEntry) contains QMaps of data, RX data, and SM SQNs (LBMLBTRUSQNEntry), NCF SQNs
136 //   (LBMLBTRUNCFSQNEntry), and RST reasons (LBMLBTRURSTReasonEntry)
137 // - A data SQN (LBMLBTRUSQNEntry) contains a QMap of the frames (LBMLBTRUFrameEntry) in which that SQN appears
138 //
139 // Not all of the entries actually appear in a QTreeWidget at one time. For example, in the source details, if no specific source
140 // transport is selected, nothing is in the source details tree. If Data SQNs is selected, then those details appear in the source
141 // details tree. Switching to RX Data SQNs removes whatever is currently in the source details tree, and adds the RX details for
142 // the selected transport.
143 //
144 // The actual owner of one of the above QTreeWidgetItem-derived items is the QMap container in its parent. The item is "loaned" to
145 // the QTreeWidget for display.
146 //
147 // All of this is to explain why
148 // 1) we are frequently adding things to a QTreeWidget
149 // 2) things are removed (takeTopLevelItem) from a QTreeWidget
150 // 3) destruction involves removing all items from all QTreeWidgets (rather than letting QTreeWidget delete them)
151 // 4) the destructor for each item has the form
152 //    <for each QMap container>
153 //      for (XXXMapIterator it = m_xxx.begin(); it != m_xxx.end(); ++it)
154 //      {
155 //          delete *it;
156 //      }
157 //      m_xxx.clear();
158 //    The for-loop calls the destructor for each item, while the clear() cleans up the space used by the QMap itself.
159
160 // A frame entry
161 class LBMLBTRUFrameEntry : public QTreeWidgetItem
162 {
163     public:
164         LBMLBTRUFrameEntry(guint32 frame);
165         virtual ~LBMLBTRUFrameEntry(void) { }
166         guint32 getFrame(void) { return (m_frame); }
167
168     private:
169         guint32 m_frame;
170 };
171
172 LBMLBTRUFrameEntry::LBMLBTRUFrameEntry(guint32 frame) :
173     QTreeWidgetItem(),
174     m_frame(frame)
175 {
176     setText(Detail_SQNReasonType_Column, QString(" "));
177     setText(Detail_Count_Column, QString(" "));
178     setText(Detail_Frame_Column, QString("%1").arg(m_frame));
179 }
180
181 typedef QMap<guint32, LBMLBTRUFrameEntry *> LBMLBTRUFrameMap;
182 typedef QMap<guint32, LBMLBTRUFrameEntry *>::iterator LBMLBTRUFrameMapIterator;
183
184 // An SQN (SeQuence Number) entry
185 class LBMLBTRUSQNEntry : public QTreeWidgetItem
186 {
187     public:
188         LBMLBTRUSQNEntry(guint32 sqn);
189         virtual ~LBMLBTRUSQNEntry(void);
190         void processFrame(guint32 frame);
191
192     private:
193         LBMLBTRUSQNEntry(void);
194         guint32 m_sqn;
195         guint32 m_count;
196         LBMLBTRUFrameMap m_frames;
197 };
198
199 LBMLBTRUSQNEntry::LBMLBTRUSQNEntry(guint32 sqn) :
200     QTreeWidgetItem(),
201     m_sqn(sqn),
202     m_count(0),
203     m_frames()
204 {
205     setText(Detail_SQNReasonType_Column, QString("%1").arg(m_sqn));
206     setTextAlignment(Detail_SQNReasonType_Column, Qt::AlignRight);
207     setText(Detail_Count_Column, QString("%1").arg(m_count));
208     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
209     setText(Detail_Frame_Column, QString(" "));
210 }
211
212 LBMLBTRUSQNEntry::~LBMLBTRUSQNEntry(void)
213 {
214     for (LBMLBTRUFrameMapIterator it = m_frames.begin(); it != m_frames.end(); ++it)
215     {
216         delete *it;
217     }
218     m_frames.clear();
219 }
220
221 void LBMLBTRUSQNEntry::processFrame(guint32 frame)
222 {
223     LBMLBTRUFrameMapIterator it;
224
225     it = m_frames.find(frame);
226     if (m_frames.end() == it)
227     {
228         LBMLBTRUFrameEntry * entry = new LBMLBTRUFrameEntry(frame);
229         m_frames.insert(frame, entry);
230         addChild(entry);
231         sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
232     }
233     m_count++;
234     setText(Detail_Count_Column, QString("%1").arg(m_count));
235     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
236 }
237
238 // An NCF (Nak ConFirmation) Reason entry
239 class LBMLBTRUNCFReasonEntry : public QTreeWidgetItem
240 {
241     public:
242         LBMLBTRUNCFReasonEntry(guint8 reason);
243         virtual ~LBMLBTRUNCFReasonEntry(void);
244         void processFrame(guint32 frame);
245
246     private:
247         LBMLBTRUNCFReasonEntry(void);
248         guint8 m_reason;
249         guint32 m_count;
250         LBMLBTRUFrameMap m_frames;
251 };
252
253 LBMLBTRUNCFReasonEntry::LBMLBTRUNCFReasonEntry(guint8 reason) :
254     QTreeWidgetItem(),
255     m_reason(reason),
256     m_count(0),
257     m_frames()
258 {
259     switch (m_reason)
260     {
261         case LBTRU_NCF_REASON_NO_RETRY:
262             setText(Detail_SQNReasonType_Column, QString("No Retry"));
263             break;
264         case LBTRU_NCF_REASON_IGNORED:
265             setText(Detail_SQNReasonType_Column, QString("Ignored"));
266             break;
267         case LBTRU_NCF_REASON_RX_DELAY:
268             setText(Detail_SQNReasonType_Column, QString("Retransmit Delay"));
269             break;
270         case LBTRU_NCF_REASON_SHED:
271             setText(Detail_SQNReasonType_Column, QString("Shed"));
272             break;
273         default:
274             setText(Detail_SQNReasonType_Column, QString("Unknown"));
275             break;
276     }
277     setText(Detail_Count_Column, QString("%1").arg(m_count));
278     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
279     setText(Detail_Frame_Column, QString(" "));
280 }
281
282 LBMLBTRUNCFReasonEntry::~LBMLBTRUNCFReasonEntry(void)
283 {
284     for (LBMLBTRUFrameMapIterator it = m_frames.begin(); it != m_frames.end(); ++it)
285     {
286         delete *it;
287     }
288     m_frames.clear();
289 }
290
291 void LBMLBTRUNCFReasonEntry::processFrame(guint32 frame)
292 {
293     LBMLBTRUFrameMapIterator it;
294
295     it = m_frames.find(frame);
296     if (m_frames.end() == it)
297     {
298         LBMLBTRUFrameEntry * entry = new LBMLBTRUFrameEntry(frame);
299         m_frames.insert(frame, entry);
300         addChild(entry);
301         sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
302     }
303     m_count++;
304     setText(Detail_Count_Column, QString("%1").arg(m_count));
305     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
306 }
307
308 typedef QMap<guint8, LBMLBTRUNCFReasonEntry *> LBMLBTRUNCFReasonMap;
309 typedef QMap<guint8, LBMLBTRUNCFReasonEntry *>::iterator LBMLBTRUNCFReasonMapIterator;
310
311 // An NCF SQN entry
312 class LBMLBTRUNCFSQNEntry : public QTreeWidgetItem
313 {
314     public:
315         LBMLBTRUNCFSQNEntry(guint32 sqn);
316         virtual ~LBMLBTRUNCFSQNEntry(void);
317         void processFrame(guint8 reason, guint32 frame);
318
319     private:
320         LBMLBTRUNCFSQNEntry(void);
321         guint32 m_sqn;
322         guint32 m_count;
323         LBMLBTRUNCFReasonMap m_reasons;
324 };
325
326 LBMLBTRUNCFSQNEntry::LBMLBTRUNCFSQNEntry(guint32 sqn) :
327     QTreeWidgetItem(),
328     m_sqn(sqn),
329     m_count(0),
330     m_reasons()
331 {
332     setText(Detail_SQNReasonType_Column, QString("%1").arg(m_sqn));
333     setTextAlignment(Detail_SQNReasonType_Column, Qt::AlignRight);
334     setText(Detail_Count_Column, QString("%1").arg(m_count));
335     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
336     setText(Detail_Frame_Column, QString(" "));
337 }
338
339 LBMLBTRUNCFSQNEntry::~LBMLBTRUNCFSQNEntry(void)
340 {
341     for (LBMLBTRUNCFReasonMapIterator it = m_reasons.begin(); it != m_reasons.end(); ++it)
342     {
343         delete *it;
344     }
345     m_reasons.clear();
346 }
347
348 void LBMLBTRUNCFSQNEntry::processFrame(guint8 reason, guint32 frame)
349 {
350     LBMLBTRUNCFReasonMapIterator it;
351     LBMLBTRUNCFReasonEntry * entry = NULL;
352
353     it = m_reasons.find(reason);
354     if (m_reasons.end() == it)
355     {
356         entry = new LBMLBTRUNCFReasonEntry(reason);
357         m_reasons.insert(reason, entry);
358         addChild(entry);
359         sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
360     }
361     else
362     {
363         entry = it.value();
364     }
365     m_count++;
366     setText(Detail_Count_Column, QString("%1").arg(m_count));
367     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
368     entry->processFrame(frame);
369 }
370
371 // An RST (ReSeT) Reason entry
372 class LBMLBTRURSTReasonEntry : public QTreeWidgetItem
373 {
374     public:
375         LBMLBTRURSTReasonEntry(guint32 reason);
376         virtual ~LBMLBTRURSTReasonEntry(void);
377         void processFrame(guint32 frame);
378
379     private:
380         LBMLBTRURSTReasonEntry(void);
381         guint32 m_reason;
382         QString m_reason_string;
383         guint32 m_count;
384         LBMLBTRUFrameMap m_frames;
385 };
386
387 LBMLBTRURSTReasonEntry::LBMLBTRURSTReasonEntry(guint32 reason) :
388     QTreeWidgetItem(),
389     m_reason(reason),
390     m_reason_string(),
391     m_count(0),
392     m_frames()
393 {
394     switch (m_reason)
395     {
396         case LBTRU_RST_REASON_DEFAULT:
397             m_reason_string = "Default";
398             break;
399         default:
400             m_reason_string = QString("Unknown (%1)").arg(m_reason);
401             break;
402     }
403     setText(Detail_SQNReasonType_Column, m_reason_string);
404     setTextAlignment(Detail_SQNReasonType_Column, Qt::AlignLeft);
405     setText(Detail_Count_Column, QString("%1").arg(m_count));
406     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
407     setText(Detail_Frame_Column, QString(" "));
408 }
409
410 LBMLBTRURSTReasonEntry::~LBMLBTRURSTReasonEntry(void)
411 {
412     for (LBMLBTRUFrameMapIterator it = m_frames.begin(); it != m_frames.end(); ++it)
413     {
414         delete *it;
415     }
416     m_frames.clear();
417 }
418
419 void LBMLBTRURSTReasonEntry::processFrame(guint32 frame)
420 {
421     LBMLBTRUFrameMapIterator it;
422
423     it = m_frames.find(frame);
424     if (m_frames.end() == it)
425     {
426         LBMLBTRUFrameEntry * entry = new LBMLBTRUFrameEntry(frame);
427         m_frames.insert(frame, entry);
428         addChild(entry);
429         sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
430     }
431     m_count++;
432     setText(Detail_Count_Column, QString("%1").arg(m_count));
433     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
434 }
435
436 // A CREQ (Connection REQuest) Request entry
437 class LBMLBTRUCREQRequestEntry : public QTreeWidgetItem
438 {
439     public:
440         LBMLBTRUCREQRequestEntry(guint32 request);
441         virtual ~LBMLBTRUCREQRequestEntry(void);
442         void processFrame(guint32 frame);
443
444     private:
445         LBMLBTRUCREQRequestEntry(void);
446         guint32 m_request;
447         QString m_request_string;
448         guint32 m_count;
449         LBMLBTRUFrameMap m_frames;
450 };
451
452 LBMLBTRUCREQRequestEntry::LBMLBTRUCREQRequestEntry(guint32 request) :
453     QTreeWidgetItem(),
454     m_request(request),
455     m_request_string(),
456     m_count(0),
457     m_frames()
458 {
459     switch (m_request)
460     {
461         case LBTRU_CREQ_REQUEST_SYN:
462             m_request_string = "SYN";
463             break;
464         default:
465             m_request_string = QString("Unknown (%1)").arg(m_request);
466             break;
467     }
468     setText(Detail_SQNReasonType_Column, m_request_string);
469     setTextAlignment(Detail_SQNReasonType_Column, Qt::AlignLeft);
470     setText(Detail_Count_Column, QString("%1").arg(m_count));
471     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
472     setText(Detail_Frame_Column, QString(" "));
473 }
474
475 LBMLBTRUCREQRequestEntry::~LBMLBTRUCREQRequestEntry(void)
476 {
477     for (LBMLBTRUFrameMapIterator it = m_frames.begin(); it != m_frames.end(); ++it)
478     {
479         delete *it;
480     }
481     m_frames.clear();
482 }
483
484 void LBMLBTRUCREQRequestEntry::processFrame(guint32 frame)
485 {
486     LBMLBTRUFrameMapIterator it;
487
488     it = m_frames.find(frame);
489     if (m_frames.end() == it)
490     {
491         LBMLBTRUFrameEntry * entry = new LBMLBTRUFrameEntry(frame);
492         m_frames.insert(frame, entry);
493         addChild(entry);
494         sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
495     }
496     m_count++;
497     setText(Detail_Count_Column, QString("%1").arg(m_count));
498     setTextAlignment(Detail_Count_Column, Qt::AlignRight);
499 }
500
501 typedef QMap<guint32, LBMLBTRUSQNEntry *> LBMLBTRUSQNMap;
502 typedef QMap<guint32, LBMLBTRUSQNEntry *>::iterator LBMLBTRUSQNMapIterator;
503 typedef QMap<guint32, LBMLBTRUNCFSQNEntry *> LBMLBTRUNCFSQNMap;
504 typedef QMap<guint32, LBMLBTRUNCFSQNEntry *>::iterator LBMLBTRUNCFSQNMapIterator;
505 typedef QMap<guint32, LBMLBTRURSTReasonEntry *> LBMLBTRURSTReasonMap;
506 typedef QMap<guint32, LBMLBTRURSTReasonEntry *>::iterator LBMLBTRURSTReasonMapIterator;
507 typedef QMap<guint32, LBMLBTRUCREQRequestEntry *> LBMLBTRUCREQRequestMap;
508 typedef QMap<guint32, LBMLBTRUCREQRequestEntry *>::iterator LBMLBTRUCREQRequestMapIterator;
509
510 // A source transport entry
511 class LBMLBTRUSourceTransportEntry : public QTreeWidgetItem
512 {
513         friend class LBMLBTRUTransportDialog;
514
515     public:
516         LBMLBTRUSourceTransportEntry(const QString & transport);
517         virtual ~LBMLBTRUSourceTransportEntry(void);
518         void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
519
520     protected:
521         QString m_transport;
522
523     private:
524         void fillItem(void);
525         guint64 m_data_frames;
526         guint64 m_data_bytes;
527         guint64 m_rx_data_frames;
528         guint64 m_rx_data_bytes;
529         guint64 m_ncf_frames;
530         guint64 m_ncf_count;
531         guint64 m_ncf_bytes;
532         guint64 m_sm_frames;
533         guint64 m_sm_bytes;
534         guint64 m_rst_frames;
535         guint64 m_rst_bytes;
536         nstime_t m_first_frame_timestamp;
537         bool m_first_frame_timestamp_valid;
538         nstime_t m_last_frame_timestamp;
539
540     protected:
541         LBMLBTRUSQNMap m_data_sqns;
542         LBMLBTRUSQNMap m_rx_data_sqns;
543         LBMLBTRUNCFSQNMap m_ncf_sqns;
544         LBMLBTRUSQNMap m_sm_sqns;
545         LBMLBTRURSTReasonMap m_rst_reasons;
546 };
547
548 LBMLBTRUSourceTransportEntry::LBMLBTRUSourceTransportEntry(const QString & transport) :
549     QTreeWidgetItem(),
550     m_transport(transport),
551     m_data_frames(0),
552     m_data_bytes(0),
553     m_rx_data_frames(0),
554     m_rx_data_bytes(0),
555     m_ncf_frames(0),
556     m_ncf_count(0),
557     m_ncf_bytes(0),
558     m_sm_frames(0),
559     m_sm_bytes(0),
560     m_rst_frames(0),
561     m_rst_bytes(0),
562     m_first_frame_timestamp_valid(false),
563     m_data_sqns(),
564     m_rx_data_sqns(),
565     m_ncf_sqns(),
566     m_sm_sqns(),
567     m_rst_reasons()
568 {
569     m_first_frame_timestamp.secs = 0;
570     m_first_frame_timestamp.nsecs = 0;
571     m_last_frame_timestamp.secs = 0;
572     m_last_frame_timestamp.nsecs = 0;
573     setText(Source_AddressTransport_Column, m_transport);
574 }
575
576 LBMLBTRUSourceTransportEntry::~LBMLBTRUSourceTransportEntry(void)
577 {
578     for (LBMLBTRUSQNMapIterator it = m_data_sqns.begin(); it != m_data_sqns.end(); ++it)
579     {
580         delete *it;
581     }
582     m_data_sqns.clear();
583
584     for (LBMLBTRUSQNMapIterator it = m_rx_data_sqns.begin(); it != m_rx_data_sqns.end(); ++it)
585     {
586         delete *it;
587     }
588     m_rx_data_sqns.clear();
589
590     for (LBMLBTRUNCFSQNMapIterator it = m_ncf_sqns.begin(); it != m_ncf_sqns.end(); ++it)
591     {
592         delete *it;
593     }
594     m_ncf_sqns.clear();
595
596     for (LBMLBTRUSQNMapIterator it = m_sm_sqns.begin(); it != m_sm_sqns.end(); ++it)
597     {
598         delete *it;
599     }
600     m_sm_sqns.clear();
601
602     for (LBMLBTRURSTReasonMapIterator it = m_rst_reasons.begin(); it != m_rst_reasons.end(); ++it)
603     {
604         delete *it;
605     }
606     m_rst_reasons.clear();
607 }
608
609 void LBMLBTRUSourceTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
610 {
611     if (m_first_frame_timestamp_valid)
612     {
613         if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0)
614         {
615             nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
616         }
617     }
618     else
619     {
620         nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
621         m_first_frame_timestamp_valid = true;
622     }
623     if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0)
624     {
625         nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts));
626     }
627     if (tap_info->type == LBTRU_PACKET_TYPE_DATA)
628     {
629         LBMLBTRUSQNEntry * sqn = NULL;
630         LBMLBTRUSQNMapIterator it;
631
632         if (tap_info->retransmission)
633         {
634             m_rx_data_frames++;
635             m_rx_data_bytes += pinfo->fd->pkt_len;
636             it = m_rx_data_sqns.find(tap_info->sqn);
637             if (m_rx_data_sqns.end() == it)
638             {
639                 sqn = new LBMLBTRUSQNEntry(tap_info->sqn);
640                 m_rx_data_sqns.insert(tap_info->sqn, sqn);
641             }
642             else
643             {
644                 sqn = it.value();
645             }
646             sqn->processFrame(pinfo->num);
647         }
648         else
649         {
650             m_data_frames++;
651             m_data_bytes += pinfo->fd->pkt_len;
652             it = m_data_sqns.find(tap_info->sqn);
653             if (m_data_sqns.end() == it)
654             {
655                 sqn = new LBMLBTRUSQNEntry(tap_info->sqn);
656                 m_data_sqns.insert(tap_info->sqn, sqn);
657             }
658             else
659             {
660                 sqn = it.value();
661             }
662         }
663         sqn->processFrame(pinfo->num);
664     }
665     else if (tap_info->type == LBTRU_PACKET_TYPE_NCF)
666     {
667         guint16 idx;
668         LBMLBTRUNCFSQNMapIterator it;
669         LBMLBTRUNCFSQNEntry * sqn = NULL;
670
671         m_ncf_frames++;
672         m_ncf_bytes += pinfo->fd->pkt_len;
673         m_ncf_count += (guint64)tap_info->num_sqns;
674         for (idx = 0; idx < tap_info->num_sqns; idx++)
675         {
676             it = m_ncf_sqns.find(tap_info->sqns[idx]);
677             if (m_ncf_sqns.end() == it)
678             {
679                 sqn = new LBMLBTRUNCFSQNEntry(tap_info->sqns[idx]);
680                 m_ncf_sqns.insert(tap_info->sqns[idx], sqn);
681             }
682             else
683             {
684                 sqn = it.value();
685             }
686             sqn->processFrame(tap_info->ncf_reason, pinfo->num);
687         }
688     }
689     else if (tap_info->type == LBTRU_PACKET_TYPE_SM)
690     {
691         LBMLBTRUSQNEntry * sqn = NULL;
692         LBMLBTRUSQNMapIterator it;
693
694         m_sm_frames++;
695         m_sm_bytes += pinfo->fd->pkt_len;
696         it = m_sm_sqns.find(tap_info->sqn);
697         if (m_sm_sqns.end() == it)
698         {
699             sqn = new LBMLBTRUSQNEntry(tap_info->sqn);
700             m_sm_sqns.insert(tap_info->sqn, sqn);
701         }
702         else
703         {
704             sqn = it.value();
705         }
706         sqn->processFrame(pinfo->num);
707     }
708     else if (tap_info->type == LBTRU_PACKET_TYPE_RST)
709     {
710         LBMLBTRURSTReasonEntry * reason = NULL;
711         LBMLBTRURSTReasonMapIterator it;
712
713         m_rst_frames++;
714         m_rst_bytes += pinfo->fd->pkt_len;
715         it = m_rst_reasons.find(tap_info->rst_type);
716         if (m_rst_reasons.end() == it)
717         {
718             reason = new LBMLBTRURSTReasonEntry(tap_info->rst_type);
719             m_rst_reasons.insert((unsigned int) tap_info->rst_type, reason);
720         }
721         else
722         {
723             reason = it.value();
724         }
725         reason->processFrame(pinfo->num);
726     }
727     else
728     {
729         return;
730     }
731     fillItem();
732 }
733
734 void LBMLBTRUSourceTransportEntry::fillItem(void)
735 {
736     nstime_t delta;
737
738     nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
739     setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames));
740     setTextAlignment(Source_DataFrames_Column, Qt::AlignRight);
741     setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes));
742     setTextAlignment(Source_DataBytes_Column, Qt::AlignRight);
743     setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes));
744     setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter);
745     setText(Source_DataRate_Column, format_rate(delta, m_data_bytes));
746     setTextAlignment(Source_DataRate_Column, Qt::AlignRight);
747     setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames));
748     setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight);
749     setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes));
750     setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight);
751     setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes));
752     setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter);
753     setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes));
754     setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight);
755     setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames));
756     setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight);
757     setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count));
758     setTextAlignment(Source_NCFCount_Column, Qt::AlignRight);
759     setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes));
760     setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight);
761     setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes));
762     setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter);
763     setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes));
764     setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter);
765     setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_count));
766     setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter);
767     setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes));
768     setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter);
769     setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes));
770     setTextAlignment(Source_NCFRate_Column, Qt::AlignRight);
771     setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames));
772     setTextAlignment(Source_SMFrames_Column, Qt::AlignRight);
773     setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes));
774     setTextAlignment(Source_SMBytes_Column, Qt::AlignRight);
775     setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes));
776     setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignHCenter);
777     setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes));
778     setTextAlignment(Source_SMRate_Column, Qt::AlignRight);
779     setText(Source_RSTFrames_Column, QString("%1").arg(m_rst_frames));
780     setTextAlignment(Source_RSTFrames_Column, Qt::AlignRight);
781     setText(Source_RSTBytes_Column, QString("%1").arg(m_rst_bytes));
782     setTextAlignment(Source_RSTBytes_Column, Qt::AlignRight);
783     setText(Source_RSTFramesBytes_Column, QString("%1/%2").arg(m_rst_frames).arg(m_rst_bytes));
784     setTextAlignment(Source_RSTFramesBytes_Column, Qt::AlignHCenter);
785     setText(Source_RSTRate_Column, format_rate(delta, m_rst_bytes));
786     setTextAlignment(Source_RSTRate_Column, Qt::AlignRight);
787 }
788
789 typedef QMap<QString, LBMLBTRUSourceTransportEntry *> LBMLBTRUSourceTransportMap;
790 typedef QMap<QString, LBMLBTRUSourceTransportEntry *>::iterator LBMLBTRUSourceTransportMapIterator;
791
792 // A source (address) entry
793 class LBMLBTRUSourceEntry : public QTreeWidgetItem
794 {
795     public:
796         LBMLBTRUSourceEntry(const QString & source_address);
797         virtual ~LBMLBTRUSourceEntry(void);
798         void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
799
800     private:
801         void fillItem(void);
802         QString m_address;
803         QString m_transport;
804         guint64 m_data_frames;
805         guint64 m_data_bytes;
806         guint64 m_rx_data_frames;
807         guint64 m_rx_data_bytes;
808         guint64 m_ncf_frames;
809         guint64 m_ncf_count;
810         guint64 m_ncf_bytes;
811         guint64 m_sm_frames;
812         guint64 m_sm_bytes;
813         guint64 m_rst_frames;
814         guint64 m_rst_bytes;
815         nstime_t m_first_frame_timestamp;
816         bool m_first_frame_timestamp_valid;
817         nstime_t m_last_frame_timestamp;
818         LBMLBTRUSourceTransportMap m_transports;
819 };
820
821 LBMLBTRUSourceEntry::LBMLBTRUSourceEntry(const QString & source_address) :
822     QTreeWidgetItem(),
823     m_address(source_address),
824     m_data_frames(0),
825     m_data_bytes(0),
826     m_rx_data_frames(0),
827     m_rx_data_bytes(0),
828     m_ncf_frames(0),
829     m_ncf_count(0),
830     m_ncf_bytes(0),
831     m_sm_frames(0),
832     m_sm_bytes(0),
833     m_rst_frames(0),
834     m_rst_bytes(0),
835     m_first_frame_timestamp_valid(false),
836     m_transports()
837 {
838     m_first_frame_timestamp.secs = 0;
839     m_first_frame_timestamp.nsecs = 0;
840     m_last_frame_timestamp.secs = 0;
841     m_last_frame_timestamp.nsecs = 0;
842     setText(Source_AddressTransport_Column, m_address);
843 }
844
845 LBMLBTRUSourceEntry::~LBMLBTRUSourceEntry(void)
846 {
847     for (LBMLBTRUSourceTransportMapIterator it = m_transports.begin(); it != m_transports.end(); ++it)
848     {
849         delete *it;
850     }
851     m_transports.clear();
852 }
853
854 void LBMLBTRUSourceEntry::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
855 {
856     LBMLBTRUSourceTransportEntry * transport = NULL;
857     LBMLBTRUSourceTransportMapIterator it;
858
859     if (m_first_frame_timestamp_valid)
860     {
861         if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0)
862         {
863             nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
864         }
865     }
866     else
867     {
868         nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
869         m_first_frame_timestamp_valid = true;
870     }
871     if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0)
872     {
873         nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts));
874     }
875     switch (tap_info->type)
876     {
877         case LBTRU_PACKET_TYPE_DATA:
878             if (tap_info->retransmission)
879             {
880                 m_rx_data_frames++;
881                 m_rx_data_bytes += pinfo->fd->pkt_len;
882             }
883             else
884             {
885                 m_data_frames++;
886                 m_data_bytes += pinfo->fd->pkt_len;
887             }
888             break;
889         case LBTRU_PACKET_TYPE_NCF:
890             m_ncf_frames++;
891             m_ncf_bytes += pinfo->fd->pkt_len;
892             m_ncf_count += tap_info->num_sqns;
893             break;
894         case LBTRU_PACKET_TYPE_SM:
895             m_sm_frames++;
896             m_sm_bytes += pinfo->fd->pkt_len;
897             break;
898         case LBTRU_PACKET_TYPE_RST:
899             m_rst_frames++;
900             m_rst_bytes += pinfo->fd->pkt_len;
901             break;
902     }
903
904     it = m_transports.find(tap_info->transport);
905     if (m_transports.end() == it)
906     {
907         transport = new LBMLBTRUSourceTransportEntry(tap_info->transport);
908         m_transports.insert(tap_info->transport, transport);
909         addChild(transport);
910         sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder);
911     }
912     else
913     {
914         transport = it.value();
915     }
916     fillItem();
917     transport->processPacket(pinfo, tap_info);
918 }
919
920 void LBMLBTRUSourceEntry::fillItem(void)
921 {
922     nstime_t delta;
923
924     nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
925     setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames));
926     setTextAlignment(Source_DataFrames_Column, Qt::AlignRight);
927     setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes));
928     setTextAlignment(Source_DataBytes_Column, Qt::AlignRight);
929     setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes));
930     setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter);
931     setText(Source_DataRate_Column, format_rate(delta, m_data_bytes));
932     setTextAlignment(Source_DataRate_Column, Qt::AlignRight);
933     setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames));
934     setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight);
935     setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes));
936     setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight);
937     setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes));
938     setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter);
939     setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes));
940     setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight);
941     setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames));
942     setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight);
943     setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count));
944     setTextAlignment(Source_NCFCount_Column, Qt::AlignRight);
945     setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes));
946     setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight);
947     setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes));
948     setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter);
949     setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes));
950     setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter);
951     setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_count));
952     setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter);
953     setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes));
954     setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter);
955     setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes));
956     setTextAlignment(Source_NCFRate_Column, Qt::AlignRight);
957     setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames));
958     setTextAlignment(Source_SMFrames_Column, Qt::AlignRight);
959     setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes));
960     setTextAlignment(Source_SMBytes_Column, Qt::AlignRight);
961     setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes));
962     setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignRight);
963     setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes));
964     setTextAlignment(Source_SMRate_Column, Qt::AlignRight);
965     setText(Source_RSTFrames_Column, QString("%1").arg(m_rst_frames));
966     setTextAlignment(Source_RSTFrames_Column, Qt::AlignRight);
967     setText(Source_RSTBytes_Column, QString("%1").arg(m_rst_bytes));
968     setTextAlignment(Source_RSTBytes_Column, Qt::AlignRight);
969     setText(Source_RSTFramesBytes_Column, QString("%1/%2").arg(m_rst_frames).arg(m_rst_bytes));
970     setTextAlignment(Source_RSTFramesBytes_Column, Qt::AlignHCenter);
971     setText(Source_RSTRate_Column, format_rate(delta, m_rst_bytes));
972     setTextAlignment(Source_RSTRate_Column, Qt::AlignRight);
973 }
974
975 typedef QMap<QString, LBMLBTRUSourceEntry *> LBMLBTRUSourceMap;
976 typedef QMap<QString, LBMLBTRUSourceEntry *>::iterator LBMLBTRUSourceMapIterator;
977
978 // A receiver transport entry
979 class LBMLBTRUReceiverTransportEntry : public QTreeWidgetItem
980 {
981         friend class LBMLBTRUTransportDialog;
982
983     public:
984         LBMLBTRUReceiverTransportEntry(const QString & transport);
985         virtual ~LBMLBTRUReceiverTransportEntry(void);
986         void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
987
988     private:
989         void fillItem(void);
990         QString m_transport;
991         guint64 m_nak_frames;
992         guint64 m_nak_count;
993         guint64 m_nak_bytes;
994         guint64 m_ack_frames;
995         guint64 m_ack_bytes;
996         guint64 m_creq_frames;
997         guint64 m_creq_bytes;
998         nstime_t m_first_frame_timestamp;
999         bool m_first_frame_timestamp_valid;
1000         nstime_t m_last_frame_timestamp;
1001
1002     protected:
1003         LBMLBTRUSQNMap m_nak_sqns;
1004         LBMLBTRUSQNMap m_ack_sqns;
1005         LBMLBTRUCREQRequestMap m_creq_requests;
1006 };
1007
1008 LBMLBTRUReceiverTransportEntry::LBMLBTRUReceiverTransportEntry(const QString & transport) :
1009     QTreeWidgetItem(),
1010     m_transport(transport),
1011     m_nak_frames(0),
1012     m_nak_count(0),
1013     m_nak_bytes(0),
1014     m_ack_frames(0),
1015     m_ack_bytes(0),
1016     m_creq_frames(0),
1017     m_creq_bytes(0),
1018     m_first_frame_timestamp_valid(false),
1019     m_nak_sqns(),
1020     m_ack_sqns(),
1021     m_creq_requests()
1022 {
1023     m_first_frame_timestamp.secs = 0;
1024     m_first_frame_timestamp.nsecs = 0;
1025     m_last_frame_timestamp.secs = 0;
1026     m_last_frame_timestamp.nsecs = 0;
1027     setText(Receiver_AddressTransport_Column, m_transport);
1028 }
1029
1030 LBMLBTRUReceiverTransportEntry::~LBMLBTRUReceiverTransportEntry(void)
1031 {
1032     for (LBMLBTRUSQNMapIterator it = m_nak_sqns.begin(); it != m_nak_sqns.end(); ++it)
1033     {
1034         delete *it;
1035     }
1036     m_nak_sqns.clear();
1037
1038     for (LBMLBTRUSQNMapIterator it = m_ack_sqns.begin(); it != m_ack_sqns.end(); ++it)
1039     {
1040         delete *it;
1041     }
1042     m_ack_sqns.clear();
1043
1044     for (LBMLBTRUCREQRequestMapIterator it = m_creq_requests.begin(); it != m_creq_requests.end(); ++it)
1045     {
1046         delete *it;
1047     }
1048     m_creq_requests.clear();
1049 }
1050
1051 void LBMLBTRUReceiverTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
1052 {
1053     if (m_first_frame_timestamp_valid)
1054     {
1055         if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0)
1056         {
1057             nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
1058         }
1059     }
1060     else
1061     {
1062         nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
1063         m_first_frame_timestamp_valid = true;
1064     }
1065     if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0)
1066     {
1067         nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts));
1068     }
1069     switch (tap_info->type)
1070     {
1071         case LBTRU_PACKET_TYPE_NAK:
1072             {
1073                 guint16 idx;
1074                 LBMLBTRUSQNEntry * sqn = NULL;
1075                 LBMLBTRUSQNMapIterator it;
1076
1077                 m_nak_frames++;
1078                 m_nak_bytes += pinfo->fd->pkt_len;
1079                 m_nak_count += tap_info->num_sqns;
1080                 for (idx = 0; idx < tap_info->num_sqns; idx++)
1081                 {
1082                     it = m_nak_sqns.find(tap_info->sqns[idx]);
1083                     if (m_nak_sqns.end() == it)
1084                     {
1085                         sqn = new LBMLBTRUSQNEntry(tap_info->sqns[idx]);
1086                         m_nak_sqns.insert(tap_info->sqns[idx], sqn);
1087                     }
1088                     else
1089                     {
1090                         sqn = it.value();
1091                     }
1092                     sqn->processFrame(pinfo->num);
1093                 }
1094             }
1095             break;
1096         case LBTRU_PACKET_TYPE_ACK:
1097             {
1098                 LBMLBTRUSQNEntry * sqn = NULL;
1099                 LBMLBTRUSQNMapIterator it;
1100
1101                 m_ack_frames++;
1102                 m_ack_bytes += pinfo->fd->pkt_len;
1103                 it = m_ack_sqns.find(tap_info->sqn);
1104                 if (m_ack_sqns.end() == it)
1105                 {
1106                     sqn = new LBMLBTRUSQNEntry(tap_info->sqn);
1107                     m_ack_sqns.insert(tap_info->sqn, sqn);
1108                 }
1109                 else
1110                 {
1111                     sqn = it.value();
1112                 }
1113                 sqn->processFrame(pinfo->num);
1114             }
1115             break;
1116         case LBTRU_PACKET_TYPE_CREQ:
1117             {
1118                 LBMLBTRUCREQRequestEntry * req = NULL;
1119                 LBMLBTRUCREQRequestMapIterator it;
1120
1121                 m_creq_frames++;
1122                 m_creq_bytes += pinfo->fd->pkt_len;
1123                 it = m_creq_requests.find(tap_info->creq_type);
1124                 if (m_creq_requests.end() == it)
1125                 {
1126                     req = new LBMLBTRUCREQRequestEntry(tap_info->creq_type);
1127                     m_creq_requests.insert(tap_info->creq_type, req);
1128                 }
1129                 else
1130                 {
1131                     req = it.value();
1132                 }
1133                 req->processFrame(pinfo->num);
1134             }
1135             break;
1136         default:
1137             return;
1138             break;
1139     }
1140     fillItem();
1141 }
1142
1143 void LBMLBTRUReceiverTransportEntry::fillItem(void)
1144 {
1145     nstime_t delta;
1146
1147     nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
1148     setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames));
1149     setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight);
1150     setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count));
1151     setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight);
1152     setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes));
1153     setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight);
1154     setText(Receiver_NAKFramesCount_Column, QString("%1/%2").arg(m_nak_frames).arg(m_nak_count));
1155     setTextAlignment(Receiver_NAKFramesCount_Column, Qt::AlignHCenter);
1156     setText(Receiver_NAKCountBytes_Column, QString("%1/%2").arg(m_nak_count).arg(m_nak_bytes));
1157     setTextAlignment(Receiver_NAKCountBytes_Column, Qt::AlignHCenter);
1158     setText(Receiver_NAKFramesBytes_Column, QString("%1/%2").arg(m_nak_frames).arg(m_nak_bytes));
1159     setTextAlignment(Receiver_NAKFramesBytes_Column, Qt::AlignHCenter);
1160     setText(Receiver_NAKFramesCountBytes_Column, QString("%1/%2/%3").arg(m_nak_frames).arg(m_nak_count).arg(m_nak_bytes));
1161     setTextAlignment(Receiver_NAKFramesCountBytes_Column, Qt::AlignHCenter);
1162     setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes));
1163     setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight);
1164     setText(Receiver_ACKFrames_Column, QString("%1").arg(m_ack_frames));
1165     setTextAlignment(Receiver_ACKFrames_Column, Qt::AlignRight);
1166     setText(Receiver_ACKBytes_Column, QString("%1").arg(m_ack_bytes));
1167     setTextAlignment(Receiver_ACKBytes_Column, Qt::AlignRight);
1168     setText(Receiver_ACKFramesBytes_Column, QString("%1/%2").arg(m_ack_frames).arg(m_ack_bytes));
1169     setTextAlignment(Receiver_ACKFramesBytes_Column, Qt::AlignHCenter);
1170     setText(Receiver_ACKRate_Column, format_rate(delta, m_ack_bytes));
1171     setTextAlignment(Receiver_ACKRate_Column, Qt::AlignRight);
1172     setText(Receiver_CREQFrames_Column, QString("%1").arg(m_creq_frames));
1173     setTextAlignment(Receiver_CREQFrames_Column, Qt::AlignRight);
1174     setText(Receiver_CREQBytes_Column, QString("%1").arg(m_creq_bytes));
1175     setTextAlignment(Receiver_CREQBytes_Column, Qt::AlignRight);
1176     setText(Receiver_CREQFramesBytes_Column, QString("%1/%2").arg(m_creq_frames).arg(m_creq_bytes));
1177     setTextAlignment(Receiver_CREQFramesBytes_Column, Qt::AlignHCenter);
1178     setText(Receiver_CREQRate_Column, format_rate(delta, m_creq_bytes));
1179     setTextAlignment(Receiver_CREQRate_Column, Qt::AlignRight);
1180 }
1181
1182 typedef QMap<QString, LBMLBTRUReceiverTransportEntry *> LBMLBTRUReceiverTransportMap;
1183 typedef QMap<QString, LBMLBTRUReceiverTransportEntry *>::iterator LBMLBTRUReceiverTransportMapIterator;
1184
1185 // A receiver (address) entry
1186 class LBMLBTRUReceiverEntry : public QTreeWidgetItem
1187 {
1188     public:
1189         LBMLBTRUReceiverEntry(const QString & receiver_address);
1190         virtual ~LBMLBTRUReceiverEntry(void);
1191         void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
1192
1193     private:
1194         void fillItem(void);
1195         QString m_address;
1196         QString m_transport;
1197         guint64 m_nak_frames;
1198         guint64 m_nak_count;
1199         guint64 m_nak_bytes;
1200         guint64 m_ack_frames;
1201         guint64 m_ack_bytes;
1202         guint64 m_creq_frames;
1203         guint64 m_creq_bytes;
1204         nstime_t m_first_frame_timestamp;
1205         bool m_first_frame_timestamp_valid;
1206         nstime_t m_last_frame_timestamp;
1207         LBMLBTRUReceiverTransportMap m_transports;
1208 };
1209
1210 LBMLBTRUReceiverEntry::LBMLBTRUReceiverEntry(const QString & receiver_address) :
1211     QTreeWidgetItem(),
1212     m_address(receiver_address),
1213     m_nak_frames(0),
1214     m_nak_count(0),
1215     m_nak_bytes(0),
1216     m_ack_frames(0),
1217     m_ack_bytes(0),
1218     m_creq_frames(0),
1219     m_creq_bytes(0),
1220     m_first_frame_timestamp_valid(false),
1221     m_transports()
1222 {
1223     m_first_frame_timestamp.secs = 0;
1224     m_first_frame_timestamp.nsecs = 0;
1225     m_last_frame_timestamp.secs = 0;
1226     m_last_frame_timestamp.nsecs = 0;
1227     setText(Receiver_AddressTransport_Column, m_address);
1228 }
1229
1230 LBMLBTRUReceiverEntry::~LBMLBTRUReceiverEntry(void)
1231 {
1232     for (LBMLBTRUReceiverTransportMapIterator it = m_transports.begin(); it != m_transports.end(); ++it)
1233     {
1234         delete *it;
1235     }
1236     m_transports.clear();
1237 }
1238
1239 void LBMLBTRUReceiverEntry::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
1240 {
1241     LBMLBTRUReceiverTransportEntry * transport = NULL;
1242     LBMLBTRUReceiverTransportMapIterator it;
1243
1244     if (m_first_frame_timestamp_valid)
1245     {
1246         if (nstime_cmp(&(pinfo->abs_ts), &m_first_frame_timestamp) < 0)
1247         {
1248             nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
1249         }
1250     }
1251     else
1252     {
1253         nstime_copy(&(m_first_frame_timestamp), &(pinfo->abs_ts));
1254         m_first_frame_timestamp_valid = true;
1255     }
1256     if (nstime_cmp(&(pinfo->abs_ts), &m_last_frame_timestamp) > 0)
1257     {
1258         nstime_copy(&(m_last_frame_timestamp), &(pinfo->abs_ts));
1259     }
1260     switch (tap_info->type)
1261     {
1262         case LBTRU_PACKET_TYPE_NAK:
1263             m_nak_frames++;
1264             m_nak_bytes += pinfo->fd->pkt_len;
1265             m_nak_count += tap_info->num_sqns;
1266             break;
1267         case LBTRU_PACKET_TYPE_ACK:
1268             m_ack_frames++;
1269             m_ack_bytes += pinfo->fd->pkt_len;
1270             break;
1271         case LBTRU_PACKET_TYPE_CREQ:
1272             m_creq_frames++;
1273             m_creq_bytes += pinfo->fd->pkt_len;
1274             break;
1275     }
1276
1277     it = m_transports.find(tap_info->transport);
1278     if (m_transports.end() == it)
1279     {
1280         transport = new LBMLBTRUReceiverTransportEntry(tap_info->transport);
1281         m_transports.insert(tap_info->transport, transport);
1282         addChild(transport);
1283         sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder);
1284     }
1285     else
1286     {
1287         transport = it.value();
1288     }
1289     fillItem();
1290     transport->processPacket(pinfo, tap_info);
1291 }
1292
1293 void LBMLBTRUReceiverEntry::fillItem(void)
1294 {
1295     nstime_t delta;
1296
1297     nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
1298     setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames));
1299     setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight);
1300     setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count));
1301     setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight);
1302     setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes));
1303     setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight);
1304     setText(Receiver_NAKFramesCount_Column, QString("%1/%2").arg(m_nak_frames).arg(m_nak_count));
1305     setTextAlignment(Receiver_NAKFramesCount_Column, Qt::AlignHCenter);
1306     setText(Receiver_NAKCountBytes_Column, QString("%1/%2").arg(m_nak_count).arg(m_nak_bytes));
1307     setTextAlignment(Receiver_NAKCountBytes_Column, Qt::AlignHCenter);
1308     setText(Receiver_NAKFramesBytes_Column, QString("%1/%2").arg(m_nak_frames).arg(m_nak_bytes));
1309     setTextAlignment(Receiver_NAKFramesBytes_Column, Qt::AlignHCenter);
1310     setText(Receiver_NAKFramesCountBytes_Column, QString("%1/%2/%3").arg(m_nak_frames).arg(m_nak_count).arg(m_nak_bytes));
1311     setTextAlignment(Receiver_NAKFramesCountBytes_Column, Qt::AlignHCenter);
1312     setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes));
1313     setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight);
1314     setText(Receiver_ACKFrames_Column, QString("%1").arg(m_ack_frames));
1315     setTextAlignment(Receiver_ACKFrames_Column, Qt::AlignRight);
1316     setText(Receiver_ACKBytes_Column, QString("%1").arg(m_ack_bytes));
1317     setTextAlignment(Receiver_ACKBytes_Column, Qt::AlignRight);
1318     setText(Receiver_ACKFramesBytes_Column, QString("%1/%2").arg(m_ack_frames).arg(m_ack_bytes));
1319     setTextAlignment(Receiver_ACKFramesBytes_Column, Qt::AlignHCenter);
1320     setText(Receiver_ACKRate_Column, format_rate(delta, m_ack_bytes));
1321     setTextAlignment(Receiver_ACKRate_Column, Qt::AlignRight);
1322     setText(Receiver_CREQFrames_Column, QString("%1").arg(m_creq_frames));
1323     setTextAlignment(Receiver_CREQFrames_Column, Qt::AlignRight);
1324     setText(Receiver_CREQBytes_Column, QString("%1").arg(m_creq_bytes));
1325     setTextAlignment(Receiver_CREQBytes_Column, Qt::AlignRight);
1326     setText(Receiver_CREQFramesBytes_Column, QString("%1/%2").arg(m_creq_frames).arg(m_creq_bytes));
1327     setTextAlignment(Receiver_CREQFramesBytes_Column, Qt::AlignHCenter);
1328     setText(Receiver_CREQRate_Column, format_rate(delta, m_creq_bytes));
1329     setTextAlignment(Receiver_CREQRate_Column, Qt::AlignRight);
1330 }
1331
1332 typedef QMap<QString, LBMLBTRUReceiverEntry *> LBMLBTRUReceiverMap;
1333 typedef QMap<QString, LBMLBTRUReceiverEntry *>::iterator LBMLBTRUReceiverMapIterator;
1334
1335 class LBMLBTRUTransportDialogInfo
1336 {
1337     public:
1338         LBMLBTRUTransportDialogInfo(void);
1339         ~LBMLBTRUTransportDialogInfo(void);
1340         void setDialog(LBMLBTRUTransportDialog * dialog);
1341         LBMLBTRUTransportDialog * getDialog(void);
1342         void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
1343         void clearMaps(void);
1344
1345     private:
1346         LBMLBTRUTransportDialog * m_dialog;
1347         LBMLBTRUSourceMap m_sources;
1348         LBMLBTRUReceiverMap m_receivers;
1349 };
1350
1351 LBMLBTRUTransportDialogInfo::LBMLBTRUTransportDialogInfo(void) :
1352     m_dialog(NULL),
1353     m_sources(),
1354     m_receivers()
1355 {
1356 }
1357
1358 LBMLBTRUTransportDialogInfo::~LBMLBTRUTransportDialogInfo(void)
1359 {
1360     clearMaps();
1361 }
1362
1363 void LBMLBTRUTransportDialogInfo::setDialog(LBMLBTRUTransportDialog * dialog)
1364 {
1365     m_dialog = dialog;
1366 }
1367
1368 LBMLBTRUTransportDialog * LBMLBTRUTransportDialogInfo::getDialog(void)
1369 {
1370     return (m_dialog);
1371 }
1372
1373 void LBMLBTRUTransportDialogInfo::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
1374 {
1375     switch (tap_info->type)
1376     {
1377         case LBTRU_PACKET_TYPE_DATA:
1378         case LBTRU_PACKET_TYPE_SM:
1379         case LBTRU_PACKET_TYPE_NCF:
1380         case LBTRU_PACKET_TYPE_RST:
1381             {
1382                 LBMLBTRUSourceEntry * source = NULL;
1383                 LBMLBTRUSourceMapIterator it;
1384                 QString src_address = address_to_qstring(&(pinfo->src));
1385
1386                 it = m_sources.find(src_address);
1387                 if (m_sources.end() == it)
1388                 {
1389                     QTreeWidgetItem * parent = NULL;
1390                     Ui::LBMLBTRUTransportDialog * ui = NULL;
1391
1392                     source = new LBMLBTRUSourceEntry(src_address);
1393                     it = m_sources.insert(src_address, source);
1394                     ui = m_dialog->getUI();
1395                     ui->sources_TreeWidget->addTopLevelItem(source);
1396                     parent = ui->sources_TreeWidget->invisibleRootItem();
1397                     parent->sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder);
1398                     ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column);
1399                 }
1400                 else
1401                 {
1402                     source = it.value();
1403                 }
1404                 source->processPacket(pinfo, tap_info);
1405             }
1406             break;
1407         case LBTRU_PACKET_TYPE_NAK:
1408         case LBTRU_PACKET_TYPE_ACK:
1409         case LBTRU_PACKET_TYPE_CREQ:
1410             {
1411                 LBMLBTRUReceiverEntry * receiver = NULL;
1412                 LBMLBTRUReceiverMapIterator it;
1413                 QString src_address = address_to_qstring(&(pinfo->src));
1414
1415                 it = m_receivers.find(src_address);
1416                 if (m_receivers.end() == it)
1417                 {
1418                     QTreeWidgetItem * parent = NULL;
1419                     Ui::LBMLBTRUTransportDialog * ui = NULL;
1420
1421                     receiver = new LBMLBTRUReceiverEntry(src_address);
1422                     it = m_receivers.insert(src_address, receiver);
1423                     ui = m_dialog->getUI();
1424                     ui->receivers_TreeWidget->addTopLevelItem(receiver);
1425                     parent = ui->receivers_TreeWidget->invisibleRootItem();
1426                     parent->sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder);
1427                     ui->receivers_TreeWidget->resizeColumnToContents(Receiver_AddressTransport_Column);
1428                 }
1429                 else
1430                 {
1431                     receiver = it.value();
1432                 }
1433                 receiver->processPacket(pinfo, tap_info);
1434             }
1435             break;
1436         default:
1437             break;
1438     }
1439 }
1440
1441 void LBMLBTRUTransportDialogInfo::clearMaps(void)
1442 {
1443     for (LBMLBTRUSourceMapIterator it = m_sources.begin(); it != m_sources.end(); ++it)
1444     {
1445         delete *it;
1446     }
1447     m_sources.clear();
1448
1449     for (LBMLBTRUReceiverMapIterator it = m_receivers.begin(); it != m_receivers.end(); ++it)
1450     {
1451         delete *it;
1452     }
1453     m_receivers.clear();
1454 }
1455
1456 LBMLBTRUTransportDialog::LBMLBTRUTransportDialog(QWidget * parent, capture_file * cfile) :
1457     QDialog(parent),
1458     m_ui(new Ui::LBMLBTRUTransportDialog),
1459     m_dialog_info(NULL),
1460     m_capture_file(cfile),
1461     m_current_source_transport(NULL),
1462     m_current_receiver_transport(NULL),
1463     m_source_context_menu(NULL),
1464     m_source_header(NULL)
1465 {
1466     m_ui->setupUi(this);
1467
1468     m_dialog_info = new LBMLBTRUTransportDialogInfo();
1469     m_ui->tabWidget->setCurrentIndex(0);
1470     m_ui->sources_detail_ComboBox->setCurrentIndex(0);
1471     m_ui->sources_detail_transport_Label->setText(QString(" "));
1472     m_ui->sources_stackedWidget->setCurrentIndex(0);
1473     m_ui->receivers_detail_ComboBox->setCurrentIndex(0);
1474     m_ui->receivers_detail_transport_Label->setText(QString(" "));
1475     m_ui->receivers_stackedWidget->setCurrentIndex(0);
1476
1477     // Setup the source context menu
1478     m_source_header = m_ui->sources_TreeWidget->header();
1479     m_source_context_menu = new QMenu(m_source_header);
1480
1481     m_source_context_menu->addAction(m_ui->action_SourceAutoResizeColumns);
1482     connect(m_ui->action_SourceAutoResizeColumns, SIGNAL(triggered()), this, SLOT(actionSourceAutoResizeColumns_triggered()));
1483     m_source_context_menu->addSeparator();
1484
1485     m_ui->action_SourceDataFrames->setChecked(true);
1486     m_source_context_menu->addAction(m_ui->action_SourceDataFrames);
1487     connect(m_ui->action_SourceDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFrames_triggered(bool)));
1488     m_ui->action_SourceDataBytes->setChecked(true);
1489     m_source_context_menu->addAction(m_ui->action_SourceDataBytes);
1490     connect(m_ui->action_SourceDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataBytes_triggered(bool)));
1491     m_ui->action_SourceDataFramesBytes->setChecked(false);
1492     m_source_context_menu->addAction(m_ui->action_SourceDataFramesBytes);
1493     connect(m_ui->action_SourceDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFramesBytes_triggered(bool)));
1494     m_ui->action_SourceDataRate->setChecked(true);
1495     m_source_context_menu->addAction(m_ui->action_SourceDataRate);
1496     connect(m_ui->action_SourceDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataRate_triggered(bool)));
1497
1498     m_ui->action_SourceRXDataFrames->setChecked(true);
1499     m_source_context_menu->addAction(m_ui->action_SourceRXDataFrames);
1500     connect(m_ui->action_SourceRXDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFrames_triggered(bool)));
1501     m_ui->action_SourceRXDataBytes->setChecked(true);
1502     m_source_context_menu->addAction(m_ui->action_SourceRXDataBytes);
1503     connect(m_ui->action_SourceRXDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataBytes_triggered(bool)));
1504     m_ui->action_SourceRXDataFramesBytes->setChecked(false);
1505     m_source_context_menu->addAction(m_ui->action_SourceRXDataFramesBytes);
1506     connect(m_ui->action_SourceRXDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFramesBytes_triggered(bool)));
1507     m_ui->action_SourceRXDataRate->setChecked(true);
1508     m_source_context_menu->addAction(m_ui->action_SourceRXDataRate);
1509     connect(m_ui->action_SourceRXDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataRate_triggered(bool)));
1510
1511     m_ui->action_SourceNCFFrames->setChecked(true);
1512     m_source_context_menu->addAction(m_ui->action_SourceNCFFrames);
1513     connect(m_ui->action_SourceNCFFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFrames_triggered(bool)));
1514     m_ui->action_SourceNCFCount->setChecked(true);
1515     m_source_context_menu->addAction(m_ui->action_SourceNCFCount);
1516     connect(m_ui->action_SourceNCFCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCount_triggered(bool)));
1517     m_ui->action_SourceNCFBytes->setChecked(true);
1518     m_source_context_menu->addAction(m_ui->action_SourceNCFBytes);
1519     connect(m_ui->action_SourceNCFBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFBytes_triggered(bool)));
1520     m_ui->action_SourceNCFFramesBytes->setChecked(false);
1521     m_source_context_menu->addAction(m_ui->action_SourceNCFFramesBytes);
1522     connect(m_ui->action_SourceNCFFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesBytes_triggered(bool)));
1523     m_ui->action_SourceNCFCountBytes->setChecked(false);
1524     m_source_context_menu->addAction(m_ui->action_SourceNCFCountBytes);
1525     connect(m_ui->action_SourceNCFCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCountBytes_triggered(bool)));
1526     m_ui->action_SourceNCFFramesCount->setChecked(false);
1527     m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCount);
1528     connect(m_ui->action_SourceNCFFramesCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCount_triggered(bool)));
1529     m_ui->action_SourceNCFFramesCountBytes->setChecked(false);
1530     m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCountBytes);
1531     connect(m_ui->action_SourceNCFFramesCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCountBytes_triggered(bool)));
1532     m_ui->action_SourceNCFRate->setChecked(true);
1533     m_source_context_menu->addAction(m_ui->action_SourceNCFRate);
1534     connect(m_ui->action_SourceNCFRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFRate_triggered(bool)));
1535
1536     m_ui->action_SourceSMFrames->setChecked(true);
1537     m_source_context_menu->addAction(m_ui->action_SourceSMFrames);
1538     connect(m_ui->action_SourceSMFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFrames_triggered(bool)));
1539     m_ui->action_SourceSMBytes->setChecked(true);
1540     m_source_context_menu->addAction(m_ui->action_SourceSMBytes);
1541     connect(m_ui->action_SourceSMBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMBytes_triggered(bool)));
1542     m_ui->action_SourceSMFramesBytes->setChecked(false);
1543     m_source_context_menu->addAction(m_ui->action_SourceSMFramesBytes);
1544     connect(m_ui->action_SourceSMFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFramesBytes_triggered(bool)));
1545     m_ui->action_SourceSMRate->setChecked(true);
1546     m_source_context_menu->addAction(m_ui->action_SourceSMRate);
1547     connect(m_ui->action_SourceSMRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMRate_triggered(bool)));
1548
1549     m_source_header->setContextMenuPolicy(Qt::CustomContextMenu);
1550     connect(m_source_header, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(custom_source_context_menuRequested(const QPoint &)));
1551
1552     // Setup the receiver context menu
1553     m_receiver_header = m_ui->receivers_TreeWidget->header();
1554     m_receiver_context_menu = new QMenu(m_receiver_header);
1555
1556     m_receiver_context_menu->addAction(m_ui->action_ReceiverAutoResizeColumns);
1557     connect(m_ui->action_ReceiverAutoResizeColumns, SIGNAL(triggered()), this, SLOT(actionReceiverAutoResizeColumns_triggered()));
1558     m_receiver_context_menu->addSeparator();
1559
1560     m_ui->action_ReceiverNAKFrames->setChecked(true);
1561     m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKFrames);
1562     connect(m_ui->action_ReceiverNAKFrames, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKFrames_triggered(bool)));
1563     m_ui->action_ReceiverNAKCount->setChecked(true);
1564     m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKCount);
1565     connect(m_ui->action_ReceiverNAKCount, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKCount_triggered(bool)));
1566     m_ui->action_ReceiverNAKBytes->setChecked(true);
1567     m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKBytes);
1568     connect(m_ui->action_ReceiverNAKBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKBytes_triggered(bool)));
1569     m_ui->action_ReceiverNAKFramesBytes->setChecked(false);
1570     m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKFramesBytes);
1571     connect(m_ui->action_ReceiverNAKFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKFramesBytes_triggered(bool)));
1572     m_ui->action_ReceiverNAKCountBytes->setChecked(false);
1573     m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKCountBytes);
1574     connect(m_ui->action_ReceiverNAKCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKCountBytes_triggered(bool)));
1575     m_ui->action_ReceiverNAKFramesCount->setChecked(false);
1576     m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKFramesCount);
1577     connect(m_ui->action_ReceiverNAKFramesCount, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKFramesCount_triggered(bool)));
1578     m_ui->action_ReceiverNAKFramesCountBytes->setChecked(false);
1579     m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKFramesCountBytes);
1580     connect(m_ui->action_ReceiverNAKFramesCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKFramesCountBytes_triggered(bool)));
1581     m_ui->action_ReceiverNAKRate->setChecked(true);
1582     m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKRate);
1583     connect(m_ui->action_ReceiverNAKRate, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKRate_triggered(bool)));
1584
1585     m_ui->action_ReceiverACKFrames->setChecked(true);
1586     m_receiver_context_menu->addAction(m_ui->action_ReceiverACKFrames);
1587     connect(m_ui->action_ReceiverACKFrames, SIGNAL(triggered(bool)), this, SLOT(actionReceiverACKFrames_triggered(bool)));
1588     m_ui->action_ReceiverACKBytes->setChecked(true);
1589     m_receiver_context_menu->addAction(m_ui->action_ReceiverACKBytes);
1590     connect(m_ui->action_ReceiverACKBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverACKBytes_triggered(bool)));
1591     m_ui->action_ReceiverACKFramesBytes->setChecked(false);
1592     m_receiver_context_menu->addAction(m_ui->action_ReceiverACKFramesBytes);
1593     connect(m_ui->action_ReceiverACKFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverACKFramesBytes_triggered(bool)));
1594     m_ui->action_ReceiverACKRate->setChecked(true);
1595     m_receiver_context_menu->addAction(m_ui->action_ReceiverACKRate);
1596     connect(m_ui->action_ReceiverACKRate, SIGNAL(triggered(bool)), this, SLOT(actionReceiverACKRate_triggered(bool)));
1597
1598     m_ui->action_ReceiverCREQFrames->setChecked(true);
1599     m_receiver_context_menu->addAction(m_ui->action_ReceiverCREQFrames);
1600     connect(m_ui->action_ReceiverCREQFrames, SIGNAL(triggered(bool)), this, SLOT(actionReceiverCREQFrames_triggered(bool)));
1601     m_ui->action_ReceiverCREQBytes->setChecked(true);
1602     m_receiver_context_menu->addAction(m_ui->action_ReceiverCREQBytes);
1603     connect(m_ui->action_ReceiverCREQBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverCREQBytes_triggered(bool)));
1604     m_ui->action_ReceiverCREQFramesBytes->setChecked(false);
1605     m_receiver_context_menu->addAction(m_ui->action_ReceiverCREQFramesBytes);
1606     connect(m_ui->action_ReceiverCREQFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverCREQFramesBytes_triggered(bool)));
1607     m_ui->action_ReceiverCREQRate->setChecked(true);
1608     m_receiver_context_menu->addAction(m_ui->action_ReceiverCREQRate);
1609     connect(m_ui->action_ReceiverCREQRate, SIGNAL(triggered(bool)), this, SLOT(actionReceiverCREQRate_triggered(bool)));
1610
1611     m_receiver_header->setContextMenuPolicy(Qt::CustomContextMenu);
1612     connect(m_receiver_header, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(custom_receiver_context_menuRequested(const QPoint &)));
1613
1614     // Setup the source tree widget header
1615     m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, true);
1616     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, true);
1617     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, true);
1618     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, true);
1619     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, true);
1620     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, true);
1621     m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, true);
1622     m_ui->sources_TreeWidget->setColumnHidden(Source_RSTFramesBytes_Column, true);
1623
1624     // Setup the receiver tree widget header
1625     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesBytes_Column, true);
1626     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKCountBytes_Column, true);
1627     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesCount_Column, true);
1628     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesCountBytes_Column, true);
1629     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKFramesBytes_Column, true);
1630     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQFramesBytes_Column, true);
1631
1632     connect(this, SIGNAL(accepted()), this, SLOT(closeDialog()));
1633     connect(this, SIGNAL(rejected()), this, SLOT(closeDialog()));
1634     fillTree();
1635 }
1636
1637 LBMLBTRUTransportDialog::~LBMLBTRUTransportDialog(void)
1638 {
1639     resetSourcesDetail();
1640     resetSources();
1641     resetReceiversDetail();
1642     resetReceivers();
1643     if (m_dialog_info != NULL)
1644     {
1645         delete m_dialog_info;
1646         m_dialog_info = NULL;
1647     }
1648     delete m_source_context_menu;
1649     m_source_context_menu = NULL;
1650     delete m_ui;
1651     m_ui = NULL;
1652     m_capture_file = NULL;
1653 }
1654
1655 void LBMLBTRUTransportDialog::setCaptureFile(capture_file * cfile)
1656 {
1657     if (cfile == NULL) // We only want to know when the file closes.
1658     {
1659         m_capture_file = NULL;
1660         m_ui->displayFilterLineEdit->setEnabled(false);
1661         m_ui->applyFilterButton->setEnabled(false);
1662     }
1663 }
1664
1665 void LBMLBTRUTransportDialog::resetSources(void)
1666 {
1667     while (m_ui->sources_TreeWidget->takeTopLevelItem(0) != NULL)
1668     {}
1669 }
1670
1671 void LBMLBTRUTransportDialog::resetReceivers(void)
1672 {
1673     while (m_ui->receivers_TreeWidget->takeTopLevelItem(0) != NULL)
1674     {}
1675 }
1676
1677 void LBMLBTRUTransportDialog::resetSourcesDetail(void)
1678 {
1679     while (m_ui->sources_detail_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
1680     {}
1681     while (m_ui->sources_detail_ncf_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
1682     {}
1683     while (m_ui->sources_detail_rst_TreeWidget->takeTopLevelItem(0) != NULL)
1684     {}
1685     m_ui->sources_detail_transport_Label->setText(QString(" "));
1686     m_current_source_transport = NULL;
1687 }
1688
1689 void LBMLBTRUTransportDialog::resetReceiversDetail(void)
1690 {
1691     while (m_ui->receivers_detail_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
1692     {}
1693     while (m_ui->receivers_detail_reason_TreeWidget->takeTopLevelItem(0) != NULL)
1694     {}
1695     m_ui->receivers_detail_transport_Label->setText(QString(" "));
1696     m_current_receiver_transport = NULL;
1697 }
1698
1699 void LBMLBTRUTransportDialog::fillTree(void)
1700 {
1701     GString * error_string;
1702
1703     if (m_capture_file == NULL)
1704     {
1705         return;
1706     }
1707     m_dialog_info->setDialog(this);
1708
1709     error_string = register_tap_listener("lbm_lbtru",
1710         (void *)m_dialog_info,
1711         m_ui->displayFilterLineEdit->text().toUtf8().constData(),
1712         TL_REQUIRES_COLUMNS,
1713         resetTap,
1714         tapPacket,
1715         drawTreeItems,
1716         NULL);
1717     if (error_string)
1718     {
1719         QMessageBox::critical(this, tr("LBT-RU Statistics failed to attach to tap"),
1720             error_string->str);
1721         g_string_free(error_string, TRUE);
1722         reject();
1723     }
1724
1725     cf_retap_packets(m_capture_file);
1726     drawTreeItems(&m_dialog_info);
1727     remove_tap_listener((void *)m_dialog_info);
1728 }
1729
1730 void LBMLBTRUTransportDialog::resetTap(void * tap_data)
1731 {
1732     LBMLBTRUTransportDialogInfo * info = (LBMLBTRUTransportDialogInfo *)tap_data;
1733     LBMLBTRUTransportDialog * dialog = info->getDialog();
1734     if (dialog == NULL)
1735     {
1736         return;
1737     }
1738     dialog->resetSourcesDetail();
1739     dialog->resetSources();
1740     dialog->resetReceiversDetail();
1741     dialog->resetReceivers();
1742     info->clearMaps();
1743 }
1744
1745 gboolean LBMLBTRUTransportDialog::tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t *, const void * tap_info)
1746 {
1747     if (pinfo->fd->passed_dfilter == 1)
1748     {
1749         const lbm_lbtru_tap_info_t * tapinfo = (const lbm_lbtru_tap_info_t *)tap_info;
1750         LBMLBTRUTransportDialogInfo * info = (LBMLBTRUTransportDialogInfo *)tap_data;
1751
1752         info->processPacket(pinfo, tapinfo);
1753     }
1754     return (TRUE);
1755 }
1756
1757 void LBMLBTRUTransportDialog::drawTreeItems(void *)
1758 {
1759 }
1760
1761 void LBMLBTRUTransportDialog::on_applyFilterButton_clicked(void)
1762 {
1763     fillTree();
1764 }
1765
1766 void LBMLBTRUTransportDialog::closeDialog(void)
1767 {
1768     delete this;
1769 }
1770
1771 void LBMLBTRUTransportDialog::sourcesDetailCurrentChanged(int index)
1772 {
1773     // Index 0: Data
1774     // Index 1: RX data
1775     // Index 2: NCF
1776     // Index 3: SM
1777     // Index 4: RST
1778     switch (index)
1779     {
1780         case 0:
1781         case 1:
1782         case 3:
1783             m_ui->sources_stackedWidget->setCurrentIndex(0);
1784             break;
1785         case 2:
1786             m_ui->sources_stackedWidget->setCurrentIndex(2);
1787             break;
1788         case 4:
1789             m_ui->sources_stackedWidget->setCurrentIndex(1);
1790             break;
1791         default:
1792             return;
1793     }
1794     sourcesItemClicked(m_current_source_transport, 0);
1795 }
1796
1797 void LBMLBTRUTransportDialog::sourcesItemClicked(QTreeWidgetItem * item, int)
1798 {
1799     LBMLBTRUSourceTransportEntry * transport = dynamic_cast<LBMLBTRUSourceTransportEntry *>(item);
1800
1801     resetSourcesDetail();
1802     if (transport == NULL)
1803     {
1804         // Must be a source item, ignore it?
1805         return;
1806     }
1807     m_current_source_transport = transport;
1808     m_ui->sources_detail_transport_Label->setText(transport->m_transport);
1809     int cur_idx = m_ui->sources_detail_ComboBox->currentIndex();
1810     switch (cur_idx)
1811     {
1812         case 0:
1813             loadSourceDataDetails(transport);
1814             break;
1815         case 1:
1816             loadSourceRXDataDetails(transport);
1817             break;
1818         case 2:
1819             loadSourceNCFDetails(transport);
1820             break;
1821         case 3:
1822             loadSourceSMDetails(transport);
1823             break;
1824         case 4:
1825             loadSourceRSTDetails(transport);
1826             break;
1827         default:
1828             break;
1829     }
1830 }
1831
1832 void LBMLBTRUTransportDialog::loadSourceDataDetails(LBMLBTRUSourceTransportEntry * transport)
1833 {
1834     for (LBMLBTRUSQNMapIterator it = transport->m_data_sqns.begin(); it != transport->m_data_sqns.end(); ++it)
1835     {
1836         LBMLBTRUSQNEntry * sqn = it.value();
1837         m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
1838     }
1839 }
1840
1841 void LBMLBTRUTransportDialog::loadSourceRXDataDetails(LBMLBTRUSourceTransportEntry * transport)
1842 {
1843     for (LBMLBTRUSQNMapIterator it = transport->m_rx_data_sqns.begin(); it != transport->m_rx_data_sqns.end(); ++it)
1844     {
1845         LBMLBTRUSQNEntry * sqn = it.value();
1846         m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
1847     }
1848 }
1849
1850 void LBMLBTRUTransportDialog::loadSourceNCFDetails(LBMLBTRUSourceTransportEntry * transport)
1851 {
1852     for (LBMLBTRUNCFSQNMapIterator it = transport->m_ncf_sqns.begin(); it != transport->m_ncf_sqns.end(); ++it)
1853     {
1854         LBMLBTRUNCFSQNEntry * sqn = it.value();
1855         m_ui->sources_detail_ncf_sqn_TreeWidget->addTopLevelItem(sqn);
1856     }
1857 }
1858
1859 void LBMLBTRUTransportDialog::loadSourceSMDetails(LBMLBTRUSourceTransportEntry * transport)
1860 {
1861     for (LBMLBTRUSQNMapIterator it = transport->m_sm_sqns.begin(); it != transport->m_sm_sqns.end(); ++it)
1862     {
1863         LBMLBTRUSQNEntry * sqn = it.value();
1864         m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
1865     }
1866 }
1867
1868 void LBMLBTRUTransportDialog::loadSourceRSTDetails(LBMLBTRUSourceTransportEntry * transport)
1869 {
1870     for (LBMLBTRURSTReasonMapIterator it = transport->m_rst_reasons.begin(); it != transport->m_rst_reasons.end(); ++it)
1871     {
1872         LBMLBTRURSTReasonEntry * reason = it.value();
1873         m_ui->sources_detail_rst_TreeWidget->addTopLevelItem(reason);
1874     }
1875 }
1876
1877 void LBMLBTRUTransportDialog::sourcesDetailItemDoubleClicked(QTreeWidgetItem * item, int)
1878 {
1879     LBMLBTRUFrameEntry * frame = dynamic_cast<LBMLBTRUFrameEntry *>(item);
1880     if (frame == NULL)
1881     {
1882         // Must have double-clicked on something other than an expanded frame entry
1883         return;
1884     }
1885     emit goToPacket((int)frame->getFrame());
1886 }
1887
1888 void LBMLBTRUTransportDialog::receiversDetailCurrentChanged(int index)
1889 {
1890     // Index 0: NAK
1891     // Index 1: ACK
1892     // Index 2: CREQ
1893     switch (index)
1894     {
1895         case 0:
1896         case 1:
1897             m_ui->receivers_stackedWidget->setCurrentIndex(0);
1898             break;
1899         case 2:
1900             m_ui->receivers_stackedWidget->setCurrentIndex(1);
1901             break;
1902         default:
1903             return;
1904     }
1905     receiversItemClicked(m_current_receiver_transport, 0);
1906 }
1907
1908 void LBMLBTRUTransportDialog::receiversItemClicked(QTreeWidgetItem * item, int)
1909 {
1910     LBMLBTRUReceiverTransportEntry * transport = dynamic_cast<LBMLBTRUReceiverTransportEntry *>(item);
1911
1912     resetReceiversDetail();
1913     if (transport == NULL)
1914     {
1915         // Must be a receiver item, ignore it?
1916         return;
1917     }
1918     m_current_receiver_transport = transport;
1919     m_ui->receivers_detail_transport_Label->setText(transport->m_transport);
1920     int cur_idx = m_ui->receivers_detail_ComboBox->currentIndex();
1921     switch (cur_idx)
1922     {
1923         case 0:
1924             loadReceiverNAKDetails(transport);
1925             break;
1926         case 1:
1927             loadReceiverACKDetails(transport);
1928             break;
1929         case 2:
1930             loadReceiverCREQDetails(transport);
1931             break;
1932         default:
1933             break;
1934     }
1935 }
1936
1937 void LBMLBTRUTransportDialog::loadReceiverNAKDetails(LBMLBTRUReceiverTransportEntry * transport)
1938 {
1939     for (LBMLBTRUSQNMapIterator it = transport->m_nak_sqns.begin(); it != transport->m_nak_sqns.end(); ++it)
1940     {
1941         LBMLBTRUSQNEntry * sqn = it.value();
1942         m_ui->receivers_detail_sqn_TreeWidget->addTopLevelItem(sqn);
1943     }
1944 }
1945
1946 void LBMLBTRUTransportDialog::loadReceiverACKDetails(LBMLBTRUReceiverTransportEntry * transport)
1947 {
1948     for (LBMLBTRUSQNMapIterator it = transport->m_ack_sqns.begin(); it != transport->m_ack_sqns.end(); ++it)
1949     {
1950         LBMLBTRUSQNEntry * sqn = it.value();
1951         m_ui->receivers_detail_sqn_TreeWidget->addTopLevelItem(sqn);
1952     }
1953 }
1954
1955 void LBMLBTRUTransportDialog::loadReceiverCREQDetails(LBMLBTRUReceiverTransportEntry * transport)
1956 {
1957     for (LBMLBTRUCREQRequestMapIterator it = transport->m_creq_requests.begin(); it != transport->m_creq_requests.end(); ++it)
1958     {
1959         LBMLBTRUCREQRequestEntry * req = it.value();
1960         m_ui->receivers_detail_reason_TreeWidget->addTopLevelItem(req);
1961     }
1962 }
1963
1964 void LBMLBTRUTransportDialog::receiversDetailItemDoubleClicked(QTreeWidgetItem * item, int)
1965 {
1966     LBMLBTRUFrameEntry * frame = dynamic_cast<LBMLBTRUFrameEntry *>(item);
1967     if (frame == NULL)
1968     {
1969         // Must have double-clicked on something other than an expanded frame entry
1970         return;
1971     }
1972     emit goToPacket((int)frame->getFrame());
1973 }
1974
1975 void LBMLBTRUTransportDialog::custom_source_context_menuRequested(const QPoint & pos)
1976 {
1977     m_source_context_menu->exec(m_source_header->mapToGlobal(pos));
1978 }
1979
1980 void LBMLBTRUTransportDialog::actionSourceDataFrames_triggered(bool checked)
1981 {
1982     m_ui->sources_TreeWidget->setColumnHidden(Source_DataFrames_Column, !checked);
1983 }
1984
1985 void LBMLBTRUTransportDialog::actionSourceDataBytes_triggered(bool checked)
1986 {
1987     m_ui->sources_TreeWidget->setColumnHidden(Source_DataBytes_Column, !checked);
1988 }
1989
1990 void LBMLBTRUTransportDialog::actionSourceDataFramesBytes_triggered(bool checked)
1991 {
1992     m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, !checked);
1993 }
1994
1995 void LBMLBTRUTransportDialog::actionSourceDataRate_triggered(bool checked)
1996 {
1997     m_ui->sources_TreeWidget->setColumnHidden(Source_DataRate_Column, !checked);
1998 }
1999
2000 void LBMLBTRUTransportDialog::actionSourceRXDataFrames_triggered(bool checked)
2001 {
2002     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFrames_Column, !checked);
2003 }
2004
2005 void LBMLBTRUTransportDialog::actionSourceRXDataBytes_triggered(bool checked)
2006 {
2007     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataBytes_Column, !checked);
2008 }
2009
2010 void LBMLBTRUTransportDialog::actionSourceRXDataFramesBytes_triggered(bool checked)
2011 {
2012     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, !checked);
2013 }
2014
2015 void LBMLBTRUTransportDialog::actionSourceRXDataRate_triggered(bool checked)
2016 {
2017     m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataRate_Column, !checked);
2018 }
2019
2020 void LBMLBTRUTransportDialog::actionSourceNCFFrames_triggered(bool checked)
2021 {
2022     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked);
2023 }
2024
2025 void LBMLBTRUTransportDialog::actionSourceNCFCount_triggered(bool checked)
2026 {
2027     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCount_Column, !checked);
2028 }
2029
2030 void LBMLBTRUTransportDialog::actionSourceNCFBytes_triggered(bool checked)
2031 {
2032     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked);
2033 }
2034
2035 void LBMLBTRUTransportDialog::actionSourceNCFFramesBytes_triggered(bool checked)
2036 {
2037     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, !checked);
2038 }
2039
2040 void LBMLBTRUTransportDialog::actionSourceNCFCountBytes_triggered(bool checked)
2041 {
2042     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, !checked);
2043 }
2044
2045 void LBMLBTRUTransportDialog::actionSourceNCFFramesCount_triggered(bool checked)
2046 {
2047     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, !checked);
2048 }
2049
2050 void LBMLBTRUTransportDialog::actionSourceNCFFramesCountBytes_triggered(bool checked)
2051 {
2052     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, !checked);
2053 }
2054
2055 void LBMLBTRUTransportDialog::actionSourceNCFRate_triggered(bool checked)
2056 {
2057     m_ui->sources_TreeWidget->setColumnHidden(Source_NCFRate_Column, !checked);
2058 }
2059
2060 void LBMLBTRUTransportDialog::actionSourceSMFrames_triggered(bool checked)
2061 {
2062     m_ui->sources_TreeWidget->setColumnHidden(Source_SMFrames_Column, !checked);
2063 }
2064
2065 void LBMLBTRUTransportDialog::actionSourceSMBytes_triggered(bool checked)
2066 {
2067     m_ui->sources_TreeWidget->setColumnHidden(Source_SMBytes_Column, !checked);
2068 }
2069
2070 void LBMLBTRUTransportDialog::actionSourceSMFramesBytes_triggered(bool checked)
2071 {
2072     m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, !checked);
2073 }
2074
2075 void LBMLBTRUTransportDialog::actionSourceSMRate_triggered(bool checked)
2076 {
2077     m_ui->sources_TreeWidget->setColumnHidden(Source_SMRate_Column, !checked);
2078 }
2079
2080 void LBMLBTRUTransportDialog::actionSourceAutoResizeColumns_triggered(void)
2081 {
2082     m_ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column);
2083     m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFrames_Column);
2084     m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataBytes_Column);
2085     m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFramesBytes_Column);
2086     m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataRate_Column);
2087     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFrames_Column);
2088     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataBytes_Column);
2089     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFramesBytes_Column);
2090     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataRate_Column);
2091     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFrames_Column);
2092     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCount_Column);
2093     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFBytes_Column);
2094     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesBytes_Column);
2095     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCountBytes_Column);
2096     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCount_Column);
2097     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCountBytes_Column);
2098     m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFRate_Column);
2099     m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFrames_Column);
2100     m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMBytes_Column);
2101     m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFramesBytes_Column);
2102     m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMRate_Column);
2103     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RSTFrames_Column);
2104     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RSTBytes_Column);
2105     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RSTFramesBytes_Column);
2106     m_ui->sources_TreeWidget->resizeColumnToContents(Source_RSTRate_Column);
2107 }
2108
2109 void LBMLBTRUTransportDialog::custom_receiver_context_menuRequested(const QPoint & pos)
2110 {
2111     m_receiver_context_menu->exec(m_receiver_header->mapToGlobal(pos));
2112 }
2113
2114 void LBMLBTRUTransportDialog::actionReceiverNAKFrames_triggered(bool checked)
2115 {
2116     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFrames_Column, !checked);
2117 }
2118
2119 void LBMLBTRUTransportDialog::actionReceiverNAKCount_triggered(bool checked)
2120 {
2121     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKCount_Column, !checked);
2122 }
2123
2124 void LBMLBTRUTransportDialog::actionReceiverNAKBytes_triggered(bool checked)
2125 {
2126     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKBytes_Column, !checked);
2127 }
2128
2129 void LBMLBTRUTransportDialog::actionReceiverNAKFramesCount_triggered(bool checked)
2130 {
2131     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesCount_Column, !checked);
2132 }
2133
2134 void LBMLBTRUTransportDialog::actionReceiverNAKCountBytes_triggered(bool checked)
2135 {
2136     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKCountBytes_Column, !checked);
2137 }
2138
2139 void LBMLBTRUTransportDialog::actionReceiverNAKFramesBytes_triggered(bool checked)
2140 {
2141     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesBytes_Column, !checked);
2142 }
2143
2144 void LBMLBTRUTransportDialog::actionReceiverNAKFramesCountBytes_triggered(bool checked)
2145 {
2146     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesCountBytes_Column, !checked);
2147 }
2148
2149 void LBMLBTRUTransportDialog::actionReceiverNAKRate_triggered(bool checked)
2150 {
2151     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKRate_Column, !checked);
2152 }
2153
2154 void LBMLBTRUTransportDialog::actionReceiverACKFrames_triggered(bool checked)
2155 {
2156     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKFrames_Column, !checked);
2157 }
2158
2159 void LBMLBTRUTransportDialog::actionReceiverACKBytes_triggered(bool checked)
2160 {
2161     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKBytes_Column, !checked);
2162 }
2163
2164 void LBMLBTRUTransportDialog::actionReceiverACKFramesBytes_triggered(bool checked)
2165 {
2166     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKFramesBytes_Column, !checked);
2167 }
2168
2169 void LBMLBTRUTransportDialog::actionReceiverACKRate_triggered(bool checked)
2170 {
2171     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKRate_Column, !checked);
2172 }
2173
2174 void LBMLBTRUTransportDialog::actionReceiverCREQFrames_triggered(bool checked)
2175 {
2176     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQFrames_Column, !checked);
2177 }
2178
2179 void LBMLBTRUTransportDialog::actionReceiverCREQBytes_triggered(bool checked)
2180 {
2181     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQBytes_Column, !checked);
2182 }
2183
2184 void LBMLBTRUTransportDialog::actionReceiverCREQFramesBytes_triggered(bool checked)
2185 {
2186     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQFramesBytes_Column, !checked);
2187 }
2188
2189 void LBMLBTRUTransportDialog::actionReceiverCREQRate_triggered(bool checked)
2190 {
2191     m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQRate_Column, !checked);
2192 }
2193
2194 void LBMLBTRUTransportDialog::actionReceiverAutoResizeColumns_triggered(void)
2195 {
2196     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_AddressTransport_Column);
2197     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKFrames_Column);
2198     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKCount_Column);
2199     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKBytes_Column);
2200     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKFramesBytes_Column);
2201     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKCountBytes_Column);
2202     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKFramesCount_Column);
2203     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKFramesCountBytes_Column);
2204     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKRate_Column);
2205     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_ACKFrames_Column);
2206     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_ACKBytes_Column);
2207     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_ACKFramesBytes_Column);
2208     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_ACKRate_Column);
2209     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_CREQFrames_Column);
2210     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_CREQBytes_Column);
2211     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_CREQFramesBytes_Column);
2212     m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_CREQRate_Column);
2213 }
2214
2215 /*
2216  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2217  *
2218  * Local variables:
2219  * c-basic-offset: 4
2220  * tab-width: 8
2221  * indent-tabs-mode: nil
2222  * End:
2223  *
2224  * vi: set shiftwidth=4 tabstop=8 expandtab:
2225  * :indentSize=4:tabSize=8:noTabs=true:
2226  */