summaryrefslogtreecommitdiffstats
path: root/src/router/display_status.c
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2020-09-27 14:17:11 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2020-12-29 19:02:56 +0100
commitfde7cc2ce319bf294ded54da0822672fe33b1923 (patch)
treeb3c87039dbc99fa5dc2f67a11a91ae8196e7ab4c /src/router/display_status.c
Initial GIT import
Diffstat (limited to 'src/router/display_status.c')
-rw-r--r--src/router/display_status.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/src/router/display_status.c b/src/router/display_status.c
new file mode 100644
index 0000000..7f3723f
--- /dev/null
+++ b/src/router/display_status.c
@@ -0,0 +1,235 @@
+/* display status functions
+ *
+ * (C) 2020 by Andreas Eversberg <jolly@eversberg.eu>
+ * All Rights Reserved
+ *
+ * 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/>.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include "../libdebug/debug.h"
+#include "call.h"
+#include "display.h"
+
+static int status_on = 0;
+static int line_count = 0;
+static int lines_total = 0;
+static char screen[MAX_HEIGHT_STATUS][MAX_DISPLAY_WIDTH];
+static char screen_color[MAX_HEIGHT_STATUS][MAX_DISPLAY_WIDTH];
+
+static void print_status(int on)
+{
+ int i, j;
+ int w, h;
+ char color, last_color = -1;
+
+ get_win_size(&w, &h);
+ if (w > MAX_DISPLAY_WIDTH - 1)
+ w = MAX_DISPLAY_WIDTH - 1;
+
+ if (w > MAX_DISPLAY_WIDTH)
+ w = MAX_DISPLAY_WIDTH;
+ h--;
+ if (h > lines_total)
+ h = lines_total;
+
+ printf("\0337\033[H");
+ for (i = 0; i < h; i++) {
+ j = 0;
+ if (on) {
+ for (j = 0; j < w; j++) {
+ color = screen_color[i][j];
+ if (screen[i][j] > ' ' && last_color != color) {
+ printf("\033[%d;3%dm", color / 10, color % 10);
+ last_color = color;
+ }
+ putchar(screen[i][j]);
+ }
+ } else {
+ for (j = 0; j < w; j++)
+ putchar(' ');
+ }
+ putchar('\n');
+ }
+ printf("\033[0;39m\0338"); fflush(stdout);
+}
+
+void display_status_on(int on)
+{
+ if (status_on)
+ print_status(0);
+
+ if (on < 0)
+ status_on = 1 - status_on;
+ else
+ status_on = on;
+
+ if (status_on)
+ print_status(1);
+
+ if (status_on)
+ debug_limit_scroll = lines_total;
+ else
+ debug_limit_scroll = 0;
+}
+
+/* start status display */
+void display_status_start(void)
+{
+ memset(screen, ' ', sizeof(screen));
+ memset(screen_color, 7, sizeof(screen_color));
+ memset(screen[0], '-', sizeof(screen[0]));
+ memcpy(screen[0] + 4, "Call Status", 11);
+ line_count = 1;
+}
+
+void display_status_line(const char *from_if, int from_count, const char *from_id, int to_count, const char *to_if, const char *to_id, enum call_state to_state)
+{
+ char line[MAX_DISPLAY_WIDTH + 4096];
+ char color[MAX_DISPLAY_WIDTH + 4096];
+ static int from_id_pos, to_if_pos;
+
+ memset(color, 7, sizeof(color)); // make valgrind happy
+
+ if (line_count == MAX_HEIGHT_STATUS)
+ return;
+
+ if (!from_if)
+ from_if = "<unknown>";
+
+ /* at first interface or when it changes */
+ if (!from_count && !to_count) {
+ from_id_pos = strlen(from_if) + 1;
+ line_count++;
+ }
+
+ /* at first call */
+ if (from_id && !to_count) {
+ to_if_pos = from_id_pos + 1 + strlen(from_id) + 1 + 4; /* quote,id,quote,arrow */
+ }
+
+ /* check line count again */
+ if (line_count == MAX_HEIGHT_STATUS)
+ return;
+
+ if (!from_id) {
+ /* only interface is given, since there is no call */
+ strcpy(line, from_if);
+ memset(color, 3, strlen(from_if));
+ } else {
+ /* originating call */
+ memset(line, ' ', to_if_pos);
+ if (!from_count && !to_count) {
+ /* <if> */
+ memcpy(line, from_if, strlen(from_if));
+ memset(color, 3, strlen(from_if));
+ }
+ if (!to_count) {
+ /* '<id>' */
+ line[from_id_pos] = '\'';
+ memcpy(line + from_id_pos + 1, from_id, strlen(from_id));
+ line[from_id_pos + 1 + strlen(from_id)] = '\'';
+ memset(color + from_id_pos, 1, 1 + strlen(from_id) + 1);
+ }
+ line[to_if_pos] = '\0';
+ /* terminating call */
+ if (to_if && to_id) {
+ int to_id_pos, to_state_pos;
+ /* arrow in the first line of a call */
+ if (!to_count) {
+ /* -> <if> '<id>' */
+ line[to_if_pos - 3] = '-';
+ line[to_if_pos - 2] = '>';
+ color[to_if_pos - 3] = 7;
+ color[to_if_pos - 2] = 7;
+ }
+ sprintf(line + to_if_pos, "%s '%s' ", to_if, to_id);
+ memset(color + to_if_pos, 3, strlen(to_if));
+ to_id_pos = to_if_pos + strlen(to_if) + 1;
+ memset(color + to_id_pos, 2, 1 + strlen(to_id) + 1);
+ to_state_pos = to_id_pos + 1 + strlen(to_id) + 1 + 1;
+
+ switch (to_state) {
+ case CALL_STATE_SETUP:
+ strcpy(line + to_state_pos, "[setup]");
+ /* magenta */
+ memset(color + to_state_pos + 1, 15, 5);
+ break;
+ case CALL_STATE_OVERLAP:
+ strcpy(line + to_state_pos, "[overlap]");
+ /* green */
+ memset(color + to_state_pos + 1, 12, 7);
+ break;
+ case CALL_STATE_PROCEEDING:
+ strcpy(line + to_state_pos, "[proceeding]");
+ /* cyan */
+ memset(color + to_state_pos + 1, 16, 10);
+ break;
+ case CALL_STATE_ALERTING:
+ strcpy(line + to_state_pos, "[alerting]");
+ /* yellow */
+ memset(color + to_state_pos + 1, 13, 8);
+ break;
+ case CALL_STATE_CONNECT:
+ strcpy(line + to_state_pos, "[connect]");
+ /* white */
+ memset(color + to_state_pos + 1, 17, 7);
+ break;
+ case CALL_STATE_DISC_FROM_ORIG:
+ strcpy(line + to_state_pos, "[out disconnect]");
+ /* red */
+ memset(color + to_state_pos + 1, 11, 14);
+ break;
+ case CALL_STATE_DISC_FROM_TERM:
+ strcpy(line + to_state_pos, "[in disconnect]");
+ /* red */
+ memset(color + to_state_pos + 1, 11, 13);
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+ /* store line without CR, but not more than MAX_DISPLAY_WIDTH - 1 */
+ line[MAX_DISPLAY_WIDTH - 1] = '\0';
+ memcpy(screen[line_count], line, strlen(line));
+ memcpy(screen_color[line_count], color, strlen(line));
+ line_count++;
+}
+
+void display_status_end(void)
+{
+ if (line_count < MAX_HEIGHT_STATUS)
+ line_count++;
+
+ if (line_count < MAX_HEIGHT_STATUS) {
+ memset(screen[line_count], '-', sizeof(screen[line_count]));
+ line_count++;
+ }
+ /* if last total lines exceed current line count, keep it, so removed lines are overwritten with spaces */
+ if (line_count > lines_total)
+ lines_total = line_count;
+ if (status_on)
+ print_status(1);
+ /* set new total lines */
+ lines_total = line_count;
+ if (status_on)
+ debug_limit_scroll = lines_total;
+}
+
+