2014-03-29 10:18:05 -04:00
|
|
|
/****************************************************************
|
|
|
|
* RetroShare is distributed under the following license:
|
|
|
|
*
|
|
|
|
* Copyright (C) 20011, RetroShare Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
****************************************************************/
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QObject>
|
2014-05-11 17:42:57 -04:00
|
|
|
#include <QFontMetrics>
|
2014-06-21 17:12:27 -04:00
|
|
|
#include <time.h>
|
2014-03-29 10:18:05 -04:00
|
|
|
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QStylePainter>
|
|
|
|
#include <QLayout>
|
|
|
|
|
|
|
|
#include <retroshare/rsgrouter.h>
|
|
|
|
#include <retroshare/rspeers.h>
|
|
|
|
#include "GlobalRouterStatistics.h"
|
|
|
|
|
|
|
|
#include "gui/settings/rsharesettings.h"
|
|
|
|
|
|
|
|
static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ;
|
|
|
|
|
|
|
|
static QColor colorScale(float f)
|
|
|
|
{
|
|
|
|
if(f == 0)
|
|
|
|
return QColor::fromHsv(0,0,192) ;
|
|
|
|
else
|
|
|
|
return QColor::fromHsv((int)((1.0-f)*280),200,255) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalRouterStatistics::GlobalRouterStatistics(QWidget *parent)
|
2015-01-23 07:13:13 -05:00
|
|
|
: RsAutoUpdatePage(2000,parent)
|
2014-03-29 10:18:05 -04:00
|
|
|
{
|
|
|
|
setupUi(this) ;
|
|
|
|
|
|
|
|
m_bProcessSettings = false;
|
|
|
|
|
|
|
|
_router_F->setWidget( _tst_CW = new GlobalRouterStatisticsWidget() ) ;
|
|
|
|
|
|
|
|
// load settings
|
|
|
|
processSettings(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalRouterStatistics::~GlobalRouterStatistics()
|
|
|
|
{
|
|
|
|
|
|
|
|
// save settings
|
|
|
|
processSettings(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalRouterStatistics::processSettings(bool bLoad)
|
|
|
|
{
|
|
|
|
m_bProcessSettings = true;
|
|
|
|
|
|
|
|
Settings->beginGroup(QString("GlobalRouterStatistics"));
|
|
|
|
|
|
|
|
if (bLoad) {
|
|
|
|
// load settings
|
|
|
|
|
|
|
|
// state of splitter
|
|
|
|
//splitter->restoreState(Settings->value("Splitter").toByteArray());
|
|
|
|
} else {
|
|
|
|
// save settings
|
|
|
|
|
|
|
|
// state of splitter
|
|
|
|
//Settings->setValue("Splitter", splitter->saveState());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Settings->endGroup();
|
|
|
|
|
|
|
|
m_bProcessSettings = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalRouterStatistics::updateDisplay()
|
|
|
|
{
|
|
|
|
_tst_CW->updateContent() ;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString GlobalRouterStatistics::getPeerName(const RsPeerId &peer_id)
|
|
|
|
{
|
|
|
|
static std::map<RsPeerId, QString> names ;
|
|
|
|
|
|
|
|
std::map<RsPeerId,QString>::const_iterator it = names.find(peer_id) ;
|
|
|
|
|
|
|
|
if( it != names.end())
|
|
|
|
return it->second ;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RsPeerDetails detail ;
|
|
|
|
if(!rsPeers->getPeerDetails(peer_id,detail))
|
|
|
|
return tr("Unknown Peer");
|
|
|
|
|
|
|
|
return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalRouterStatisticsWidget::GlobalRouterStatisticsWidget(QWidget *parent)
|
|
|
|
: QWidget(parent)
|
|
|
|
{
|
|
|
|
maxWidth = 400 ;
|
|
|
|
maxHeight = 0 ;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalRouterStatisticsWidget::updateContent()
|
|
|
|
{
|
|
|
|
std::vector<RsGRouter::GRouterRoutingCacheInfo> cache_infos ;
|
|
|
|
RsGRouter::GRouterRoutingMatrixInfo matrix_info ;
|
|
|
|
|
|
|
|
rsGRouter->getRoutingCacheInfo(cache_infos) ;
|
|
|
|
rsGRouter->getRoutingMatrixInfo(matrix_info) ;
|
|
|
|
|
|
|
|
// What do we need to draw?
|
|
|
|
//
|
|
|
|
// Routing matrix
|
|
|
|
// Key [][][][][][][][][][]
|
|
|
|
//
|
2014-12-30 06:11:08 -05:00
|
|
|
// -> each [] shows a square (one per friend node) that is the routing probabilities for all connected friends
|
2014-03-29 10:18:05 -04:00
|
|
|
// computed using the "computeRoutingProbabilitites()" method.
|
|
|
|
//
|
|
|
|
// Own key ids
|
|
|
|
// key service id description
|
|
|
|
//
|
|
|
|
// Data items
|
|
|
|
// Msg id Local origin Destination Time Status
|
|
|
|
//
|
|
|
|
QPixmap tmppixmap(maxWidth, maxHeight);
|
|
|
|
tmppixmap.fill(this, 0, 0);
|
|
|
|
setFixedHeight(maxHeight);
|
|
|
|
|
|
|
|
QPainter painter(&tmppixmap);
|
|
|
|
painter.initFrom(this);
|
|
|
|
painter.setPen(QColor::fromRgb(0,0,0)) ;
|
|
|
|
|
2014-05-11 17:42:57 -04:00
|
|
|
QFont times_f("Times") ;
|
|
|
|
QFont monospace_f("Monospace") ;
|
|
|
|
monospace_f.setStyleHint(QFont::TypeWriter) ;
|
|
|
|
|
|
|
|
QFontMetrics fm_monospace(monospace_f) ;
|
|
|
|
QFontMetrics fm_times(times_f) ;
|
|
|
|
|
|
|
|
static const int cellx = fm_monospace.width(QString(" ")) ;
|
|
|
|
static const int celly = fm_monospace.height() ;
|
|
|
|
|
2014-03-29 10:18:05 -04:00
|
|
|
maxHeight = 500 ;
|
|
|
|
|
|
|
|
// std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl;
|
|
|
|
// draw...
|
|
|
|
int ox=5,oy=5 ;
|
2014-08-29 10:18:50 -04:00
|
|
|
|
|
|
|
|
2014-05-11 17:42:57 -04:00
|
|
|
painter.setFont(times_f) ;
|
2014-03-29 10:18:05 -04:00
|
|
|
painter.drawText(ox,oy+celly,tr("Managed keys")+":" + QString::number(matrix_info.published_keys.size())) ; oy += celly*2 ;
|
|
|
|
|
2014-05-11 17:42:57 -04:00
|
|
|
painter.setFont(monospace_f) ;
|
2015-01-23 07:13:13 -05:00
|
|
|
for(std::map<Sha1CheckSum,RsGRouter::GRouterPublishedKeyInfo>::const_iterator it(matrix_info.published_keys.begin());it!=matrix_info.published_keys.end();++it)
|
2014-03-29 10:18:05 -04:00
|
|
|
{
|
|
|
|
QString packet_string ;
|
2015-01-23 07:13:13 -05:00
|
|
|
packet_string += QString::fromStdString(it->second.authentication_key.toStdString()) ;
|
2014-03-29 10:18:05 -04:00
|
|
|
packet_string += tr(" : Service ID = ")+QString::number(it->second.service_id,16) ;
|
|
|
|
packet_string += " \""+QString::fromUtf8(it->second.description_string.c_str()) + "\"" ;
|
|
|
|
|
|
|
|
painter.drawText(ox+2*cellx,oy+celly,packet_string ) ; oy += celly ;
|
|
|
|
}
|
|
|
|
oy += celly ;
|
|
|
|
|
2014-08-29 10:18:50 -04:00
|
|
|
painter.setFont(times_f) ;
|
|
|
|
painter.drawText(ox,oy+celly,tr("Pending packets")+":" + QString::number(cache_infos.size())) ; oy += celly*2 ;
|
|
|
|
|
|
|
|
painter.setFont(monospace_f) ;
|
|
|
|
|
2015-04-18 15:59:27 -04:00
|
|
|
static const QString data_status_string[6] = { "Unkown","Pending","Sent","Receipt OK","Ongoing","Done" } ;
|
2015-04-26 16:10:18 -04:00
|
|
|
static const QString tunnel_status_string[4] = { "Unmanaged", "Pending", "Ready" } ;
|
2015-01-23 07:13:13 -05:00
|
|
|
|
|
|
|
time_t now = time(NULL) ;
|
2015-04-26 16:10:18 -04:00
|
|
|
std::map<QString, std::vector<QString> > tos ;
|
|
|
|
static const int nb_fields = 8 ;
|
|
|
|
|
|
|
|
static const QString fname[nb_fields] = {
|
|
|
|
tr("Id"),
|
|
|
|
tr("Destination"),
|
|
|
|
tr("Data status"),
|
|
|
|
tr("Tunnel status"),
|
|
|
|
tr("Data size"),
|
|
|
|
tr("Data hash"),
|
|
|
|
tr("Received"),
|
|
|
|
tr("Send") } ;
|
|
|
|
|
|
|
|
std::vector<int> max_column_width(nb_fields,0) ;
|
|
|
|
|
|
|
|
for(int i=0;i<cache_infos.size();++i)
|
|
|
|
{
|
|
|
|
std::vector<QString> strings;
|
|
|
|
strings.push_back( QString::number(cache_infos[i].mid,16) ) ;
|
|
|
|
strings.push_back( QString::fromStdString(cache_infos[i].destination.toStdString()) ) ;
|
2014-08-29 10:18:50 -04:00
|
|
|
|
2015-04-26 16:10:18 -04:00
|
|
|
//for(std::set<RsPeerId>::const_iterator it(cache_infos[i].local_origin.begin());it!=cache_infos[i].local_origin.end();++it)
|
|
|
|
// packet_string += QString::fromStdString((*it).toStdString()) + " - ";
|
2014-08-29 10:18:50 -04:00
|
|
|
|
2015-04-26 16:10:18 -04:00
|
|
|
strings.push_back( data_status_string[cache_infos[i].data_status % 6]) ;
|
|
|
|
strings.push_back( tunnel_status_string[cache_infos[i].tunnel_status % 3]) ;
|
|
|
|
strings.push_back( QString::number(cache_infos[i].data_size) );
|
|
|
|
strings.push_back( QString::fromStdString(cache_infos[i].item_hash.toStdString())) ;
|
|
|
|
strings.push_back( QString::number(now - cache_infos[i].routing_time)) ;
|
|
|
|
strings.push_back( QString::number(now - cache_infos[i].last_sent_time)) ;
|
2014-08-29 10:18:50 -04:00
|
|
|
|
2015-04-26 16:10:18 -04:00
|
|
|
tos[ strings[0] ] = strings ;
|
|
|
|
|
|
|
|
// now compute max column sizes
|
|
|
|
|
|
|
|
for(int j=0;j<nb_fields;++j)
|
|
|
|
max_column_width[j] = std::max(max_column_width[j],fm_monospace.width(strings[j])) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// compute cumulated sizes
|
|
|
|
|
|
|
|
std::vector<int> cumulated_sizes(nb_fields+1,0) ;
|
|
|
|
|
|
|
|
for(int i=1;i<=nb_fields;++i)
|
|
|
|
{
|
|
|
|
cumulated_sizes[i] = std::max(max_column_width[i-1],fm_monospace.width(fname[i-1])) ;
|
|
|
|
cumulated_sizes[i] += cumulated_sizes[i-1] ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now draw the matrix
|
|
|
|
|
|
|
|
for(int i=0;i<nb_fields;++i)
|
|
|
|
painter.drawText(ox+cumulated_sizes[i]+2,oy+celly,fname[i]) ;
|
|
|
|
|
|
|
|
painter.drawLine(ox,oy,ox+cumulated_sizes.back(),oy) ;
|
|
|
|
|
|
|
|
int top_matrix_oy = oy ;
|
|
|
|
oy += celly +2;
|
|
|
|
|
|
|
|
painter.drawLine(ox,oy,ox+cumulated_sizes.back(),oy) ;
|
|
|
|
|
|
|
|
for(std::map<QString,std::vector<QString> >::const_iterator it(tos.begin());it!=tos.end();++it)
|
|
|
|
{
|
|
|
|
for(int i=0;i<it->second.size();++i)
|
|
|
|
painter.drawText(ox+cumulated_sizes[i]+2,oy+celly,it->second[i] ) ;
|
|
|
|
|
|
|
|
oy += celly ;
|
|
|
|
}
|
|
|
|
|
|
|
|
oy += 2;
|
|
|
|
|
|
|
|
for(int i=0;i<=nb_fields;++i)
|
|
|
|
painter.drawLine(ox+cumulated_sizes[i],top_matrix_oy,ox+cumulated_sizes[i],oy) ;
|
|
|
|
|
|
|
|
painter.drawLine(ox,oy,ox+cumulated_sizes.back(),oy) ;
|
2015-01-23 10:16:04 -05:00
|
|
|
oy += celly ;
|
|
|
|
|
2015-01-23 07:13:13 -05:00
|
|
|
QString prob_string ;
|
|
|
|
painter.setFont(times_f) ;
|
|
|
|
QString Q = tr("Routing matrix (") ;
|
|
|
|
|
|
|
|
painter.drawText(ox+0*cellx,oy+fm_times.height(),Q) ;
|
|
|
|
|
|
|
|
// draw scale
|
|
|
|
|
|
|
|
for(int i=0;i<100;++i)
|
|
|
|
{
|
|
|
|
painter.setPen(colorScale(i/100.0)) ;
|
|
|
|
painter.drawLine(fm_times.width(Q)+i,oy+celly+2,fm_times.width(Q)+i,oy+2) ;
|
|
|
|
}
|
|
|
|
painter.setPen(QColor::fromRgb(0,0,0)) ;
|
|
|
|
|
|
|
|
painter.drawText(ox+fm_times.width(Q) + 100,oy+celly,")") ;
|
|
|
|
|
|
|
|
oy += celly ;
|
|
|
|
oy += celly ;
|
|
|
|
|
|
|
|
static const int MaxKeySize = 20 ;
|
|
|
|
painter.setFont(monospace_f) ;
|
|
|
|
|
|
|
|
for(std::map<GRouterKeyId,std::vector<float> >::const_iterator it(matrix_info.per_friend_probabilities.begin());it!=matrix_info.per_friend_probabilities.end();++it)
|
|
|
|
{
|
|
|
|
QString ids = QString::fromStdString(it->first.toStdString())+" : " ;
|
|
|
|
painter.drawText(ox+2*cellx,oy+celly,ids) ;
|
|
|
|
|
|
|
|
for(uint32_t i=0;i<matrix_info.friend_ids.size();++i)
|
|
|
|
painter.fillRect(ox+i*cellx+fm_monospace.width(ids),oy,cellx,celly,colorScale(it->second[i])) ;
|
|
|
|
|
|
|
|
oy += celly ;
|
|
|
|
}
|
|
|
|
|
2014-08-29 10:18:50 -04:00
|
|
|
|
2014-03-29 10:18:05 -04:00
|
|
|
|
|
|
|
oy += celly ;
|
|
|
|
oy += celly ;
|
|
|
|
|
|
|
|
// update the pixmap
|
|
|
|
//
|
|
|
|
pixmap = tmppixmap;
|
|
|
|
maxHeight = oy ;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString GlobalRouterStatisticsWidget::speedString(float f)
|
|
|
|
{
|
|
|
|
if(f < 1.0f)
|
|
|
|
return QString("0 B/s") ;
|
|
|
|
if(f < 1024.0f)
|
|
|
|
return QString::number((int)f)+" B/s" ;
|
|
|
|
|
|
|
|
return QString::number(f/1024.0,'f',2) + " KB/s";
|
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalRouterStatisticsWidget::paintEvent(QPaintEvent */*event*/)
|
|
|
|
{
|
|
|
|
QStylePainter(this).drawPixmap(0, 0, pixmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GlobalRouterStatisticsWidget::resizeEvent(QResizeEvent *event)
|
|
|
|
{
|
|
|
|
QRect TaskGraphRect = geometry();
|
|
|
|
maxWidth = TaskGraphRect.width();
|
|
|
|
maxHeight = TaskGraphRect.height() ;
|
|
|
|
|
|
|
|
QWidget::resizeEvent(event);
|
|
|
|
updateContent();
|
|
|
|
}
|
|
|
|
|