#define MAX_STATS 1024
+enum {
+ FIREPERF_RECV,
+ FIREPERF_SENT,
+};
+
struct fireperf_tui {
struct fireperf_ctx* ctx;
return peak;
}
+static size_t fireperf_tui_get_avg_bytes(
+ struct fireperf_tui* tui, const int direction, int max) {
+ const struct fireperf_stats* stats = NULL;
+
+ size_t counter = 0;
+ size_t total_bytes = 0;
+
+ for (unsigned int i = 0; i < max; i++) {
+ stats = fireperf_tui_get_stats(tui, i);
+ if (!stats)
+ continue;
+
+ counter++;
+
+ switch (direction) {
+ case FIREPERF_RECV:
+ total_bytes += stats->bytes_received;
+ break;
+
+ case FIREPERF_SENT:
+ total_bytes += stats->bytes_sent;
+ break;
+ }
+ }
+
+ if (!counter)
+ return 0;
+
+ return total_bytes / counter;
+}
+
static int fireperf_tui_setup_graph(struct fireperf_tui* tui) {
int r;
return 0;
}
+static int fireperf_tui_draw_line(struct fireperf_tui* tui, double value, const char* label) {
+ size_t l = 0;
+
+ // How long is the label?
+ if (label)
+ l = strlen(label);
+
+ int max_x = 0;
+ int max_y = 0;
+
+ // Fetch the dimensions of the frame
+ getmaxyx(tui->graph, max_y, max_x);
+
+ // Draw a horizontal line
+ for (unsigned int x = 0; x < max_x - l - 1; x++) {
+ mvwaddch(tui->graph, max_y - value, x, ACS_HLINE);
+ }
+
+ // Write the label
+ if (label)
+ mvwaddnstr(tui->graph, max_y - value, max_x - l, label, l);
+
+ return 0;
+}
+
/*
Draws the big graph
*/
static int fireperf_tui_draw_graph(struct fireperf_tui* tui) {
const struct fireperf_stats* stats = NULL;
- char scale[32];
+ char label[32];
int r;
int max_x = 0;
// Fetch the dimensions of the frame
getmaxyx(tui->graph, max_y, max_x);
- size_t peak_bps = fireperf_tui_get_peak_bps(tui, max_x);
+ // Fetch total transfer
+ size_t avg_rcvd_bytes = fireperf_tui_get_avg_bytes(tui, FIREPERF_RECV, max_x);
+ size_t avg_sent_bytes = fireperf_tui_get_avg_bytes(tui, FIREPERF_SENT, max_x);
+
+ // Fetch peak bandwidth
+ size_t peak_bps = fireperf_tui_get_peak_bps(tui, max_x) * 1.2;
// Figure out how many bps a step represents
- double step = peak_bps / (max_y + 0);
+ double step = peak_bps / (max_y - 4);
// Make the brush yellow
wattron(tui->graph, COLOR_PAIR(5));
// Draw the grid
for (double line = 0; line <= 1; line += 0.25) {
- r = format_size(scale, line * peak_bps, FIREPERF_FORMAT_BITS);
+ r = format_size(label, line * peak_bps, FIREPERF_FORMAT_BYTES);
if (r < 0)
continue;
- size_t l = strlen(scale);
-
- // Draw a horizontal line
- for (unsigned int x = 0; x < max_x - l - 1; x++) {
- mvwaddch(tui->graph, max_y - (max_y * line), x, ACS_HLINE);
- }
-
- // Write the scale
- mvwaddnstr(tui->graph, max_y - (max_y * line), max_x - l, scale, l);
+ // Write the line
+ r = fireperf_tui_draw_line(tui, max_y * line, label);
+ if (r)
+ return r;
}
wattroff(tui->graph, COLOR_PAIR(5));
// Make the brush red
wattron(tui->graph, COLOR_PAIR(1));
+ // Show the average
+ if (avg_sent_bytes) {
+ r = format_size(label, avg_sent_bytes, FIREPERF_FORMAT_BYTES);
+ if (r < 0)
+ return r;
+
+ // Write the line
+ r = fireperf_tui_draw_line(tui, avg_sent_bytes / step, label);
+ if (r)
+ return r;
+ }
+
// Draw any sent traffic
for (unsigned int x = 0; x < max_x; x++) {
stats = fireperf_tui_get_stats(tui, x);
// Make the brush green
wattron(tui->graph, COLOR_PAIR(2));
+ // Show the average
+ if (avg_rcvd_bytes) {
+ r = format_size(label, avg_rcvd_bytes, FIREPERF_FORMAT_BYTES);
+ if (r < 0)
+ return r;
+
+ // Write the line
+ r = fireperf_tui_draw_line(tui, avg_rcvd_bytes / step, label);
+ if (r)
+ return r;
+ }
+
// Draw any received traffic
for (unsigned int x = 0; x < max_x; x++) {
stats = fireperf_tui_get_stats(tui, x);