230 lines
8.3 KiB
C++
Executable File
230 lines
8.3 KiB
C++
Executable File
/*! \file pidiagnostics.h
|
|
* \brief Connection quality diagnostics
|
|
*/
|
|
/*
|
|
PIP - Platform Independent Primitives
|
|
Speed and quality in/out diagnostics
|
|
Copyright (C) 2018 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
|
|
|
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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef PIDIAGNOSTICS_H
|
|
#define PIDIAGNOSTICS_H
|
|
|
|
#include "pitimer.h"
|
|
#include "piqueue.h"
|
|
|
|
|
|
class PIP_EXPORT PIDiagnostics: public PITimer
|
|
{
|
|
PIOBJECT_SUBCLASS(PIDiagnostics, PITimer)
|
|
friend class PIConnection;
|
|
public:
|
|
|
|
//! Constructs an empty diagnostics and if "start_" start it
|
|
PIDiagnostics(bool start_ = true);
|
|
|
|
virtual ~PIDiagnostics() {;}
|
|
|
|
//! Connection quality
|
|
enum Quality {
|
|
Unknown /** Unknown, no one packet received yet */ = 1,
|
|
Failure /** No connection, no one correct packet received for last period */ = 2,
|
|
Bad /** Bad connection, correct packets received <= 20% */ = 3,
|
|
Average /** Average connection, correct packets received > 20% and <= 80% */ = 4,
|
|
Good /** Good connection, correct packets received > 80% */ = 5
|
|
};
|
|
|
|
//! Information about current diagnostics state
|
|
struct State {
|
|
State();
|
|
float immediate_freq;
|
|
float integral_freq;
|
|
ullong received_packets_per_sec;
|
|
ullong received_packets;
|
|
ullong received_packets_wrong;
|
|
ullong received_bytes_per_sec;
|
|
ullong received_bytes;
|
|
ullong received_bytes_wrong;
|
|
ullong sended_packets_per_sec;
|
|
ullong sended_packets;
|
|
ullong sended_bytes_per_sec;
|
|
ullong sended_bytes;
|
|
PIString receive_speed;
|
|
PIString send_speed;
|
|
PIDiagnostics::Quality quality;
|
|
};
|
|
|
|
|
|
//! Returns current state
|
|
PIDiagnostics::State state() const;
|
|
|
|
//! Returns period of full disconnect in seconds and period of averaging frequency
|
|
float disconnectTimeout() const {return disconn_;}
|
|
|
|
//! Returns period of full disconnect in seconds and period of averaging frequency
|
|
void setDisconnectTimeout(float s) {setProperty("disconnectTimeout", s);}
|
|
|
|
//! Returns immediate receive frequency, packets/s
|
|
float immediateFrequency() const {return cur_state.immediate_freq;}
|
|
|
|
//! Returns integral receive frequency for \a disconnectTimeout() seconds, packets/s
|
|
float integralFrequency() const {return cur_state.integral_freq;}
|
|
|
|
//! Returns correct received packets per second
|
|
ullong receiveCountPerSec() const {return cur_state.received_packets_per_sec;}
|
|
|
|
//! Returns sended packets per second
|
|
ullong sendCountPerSec() const {return cur_state.sended_packets_per_sec;}
|
|
|
|
//! Returns correct received bytes per second
|
|
ullong receiveBytesPerSec() const {return cur_state.received_bytes_per_sec;}
|
|
|
|
//! Returns sended bytes per second
|
|
ullong sendBytesPerSec() const {return cur_state.sended_bytes_per_sec;}
|
|
|
|
//! Returns overall correct received bytes
|
|
ullong receiveBytes() const {return cur_state.received_bytes;}
|
|
|
|
//! Returns overall wrong received bytes
|
|
ullong wrongBytes() const {return cur_state.received_bytes_wrong;}
|
|
|
|
//! Returns overall sended bytes
|
|
ullong sendBytes() const {return cur_state.sended_bytes;}
|
|
|
|
//! Returns overall correct received packets count
|
|
ullong receiveCount() const {return cur_state.received_packets;}
|
|
|
|
//! Returns overall wrong received packets count
|
|
ullong wrongCount() const {return cur_state.received_packets_wrong;}
|
|
|
|
//! Returns overall sended packets count
|
|
ullong sendCount() const {return cur_state.sended_packets;}
|
|
|
|
//! Returns connection quality
|
|
PIDiagnostics::Quality quality() const {return cur_state.quality;}
|
|
|
|
//! Returns receive speed in format "n {B|kB|MB|GB|TB}/s"
|
|
PIString receiveSpeed() const;
|
|
|
|
//! Returns send speed in format "n {B|kB|MB|GB|TB}/s"
|
|
PIString sendSpeed() const;
|
|
|
|
|
|
//! Returns immediate receive frequency pointer, packets/s. Useful for output to PIConsole
|
|
const float * immediateFrequency_ptr() const {return &cur_state.immediate_freq;}
|
|
|
|
//! Returns integral receive frequency pointer for period, packets/s. Useful for output to PIConsole
|
|
const float * integralFrequency_ptr() const {return &cur_state.integral_freq;}
|
|
|
|
//! Returns correct received packets per second pointer. Useful for output to PIConsole
|
|
const ullong * receiveCountPerSec_ptr() const {return &cur_state.received_packets_per_sec;}
|
|
|
|
//! Returns sended packets per second pointer. Useful for output to PIConsole
|
|
const ullong * sendCountPerSec_ptr() const {return &cur_state.sended_packets_per_sec;}
|
|
|
|
//! Returns correct received bytes per second pointer. Useful for output to PIConsole
|
|
const ullong * receiveBytesPerSec_ptr() const {return &cur_state.received_bytes_per_sec;}
|
|
|
|
//! Returns sended bytes per second pointer. Useful for output to PIConsole
|
|
const ullong * sendBytesPerSec_ptr() const {return &cur_state.sended_bytes_per_sec;}
|
|
|
|
//! Returns overall correct received bytes pointer. Useful for output to PIConsole
|
|
const ullong * receiveBytes_ptr() const {return &cur_state.received_bytes;}
|
|
|
|
//! Returns overall wrong received bytes pointer. Useful for output to PIConsole
|
|
const ullong * wrongBytes_ptr() const {return &cur_state.received_bytes_wrong;}
|
|
|
|
//! Returns overall sended bytes pointer. Useful for output to PIConsole
|
|
const ullong * sendBytes_ptr() const {return &cur_state.sended_bytes;}
|
|
|
|
//! Returns overall correct received packets count pointer. Useful for output to PIConsole
|
|
const ullong * receiveCount_ptr() const {return &cur_state.received_packets;}
|
|
|
|
//! Returns overall wrong received packets count pointer. Useful for output to PIConsole
|
|
const ullong * wrongCount_ptr() const {return &cur_state.received_packets_wrong;}
|
|
|
|
//! Returns overall sended packets count pointer. Useful for output to PIConsole
|
|
const ullong * sendCount_ptr() const {return &cur_state.sended_packets;}
|
|
|
|
//! Returns connection quality pointer. Useful for output to PIConsole
|
|
const int * quality_ptr() const {return (int * )&cur_state.quality;}
|
|
|
|
//! Returns receive speed pointer in format "n {B|kB|MB|GB|TB}/s". Useful for output to PIConsole
|
|
const PIString * receiveSpeed_ptr() const {return &cur_state.receive_speed;}
|
|
|
|
//! Returns send speed pointer in format "n {B|kB|MB|GB|TB}/s". Useful for output to PIConsole
|
|
const PIString * sendSpeed_ptr() const {return &cur_state.send_speed;}
|
|
|
|
EVENT_HANDLER0(void, start) {start(100.); changeDisconnectTimeout(disconn_);}
|
|
EVENT_HANDLER1(void, start, double, msecs) {if (msecs > 0.) {PITimer::start(msecs); changeDisconnectTimeout(disconn_);}}
|
|
EVENT_HANDLER0(void, stop) {PITimer::stop();}
|
|
EVENT_HANDLER0(void, reset);
|
|
|
|
EVENT_HANDLER1(void, received, int, size) {received(size, true);}
|
|
EVENT_HANDLER2(void, received, int, size, bool, correct);
|
|
EVENT_HANDLER1(void, sended, int, size);
|
|
|
|
EVENT2(qualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality)
|
|
|
|
//! \handlers
|
|
//! \{
|
|
|
|
//! \fn void start(double msecs = 1000.)
|
|
//! \brief Start diagnostics evaluations with period "msecs" milliseconds
|
|
|
|
//! \fn void reset()
|
|
//! \brief Reset diagnostics counters
|
|
|
|
//! \fn void received(int size, bool correct = true)
|
|
//! \brief Notify diagnostics about "correct" corected received packet
|
|
|
|
//! \fn void sended(int size)
|
|
//! \brief Notify diagnostics about sended packet
|
|
|
|
//! \}
|
|
//! \events
|
|
//! \{
|
|
|
|
//! \fn void qualityChanged(PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality)
|
|
//! \brief Raise on change receive quality from "old_quality" to "new_quality"
|
|
|
|
//! \}
|
|
|
|
private:
|
|
struct Entry {
|
|
Entry() {bytes_ok = bytes_fail = 0; cnt_ok = cnt_fail = 0; empty = true;}
|
|
ullong bytes_ok;
|
|
ullong bytes_fail;
|
|
uint cnt_ok;
|
|
uint cnt_fail;
|
|
bool empty;
|
|
};
|
|
|
|
void tick(void *, int);
|
|
Entry calcHistory(PIQueue<Entry> & hist, int & cnt);
|
|
void propertyChanged(const PIString &);
|
|
void changeDisconnectTimeout(float disct);
|
|
void constLock() const;
|
|
void constUnlock() const;
|
|
|
|
PIQueue<Entry> history_rec, history_send;
|
|
float disconn_;
|
|
State cur_state;
|
|
|
|
};
|
|
|
|
#endif // PIDIAGNOSTICS_H
|