/*! \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 . */ #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 & hist, int & cnt); void propertyChanged(const PIString &); void changeDisconnectTimeout(float disct); void constLock() const; void constUnlock() const; PIQueue history_rec, history_send; float disconn_; State cur_state; }; #endif // PIDIAGNOSTICS_H