Added Message Color by CSeq and cycle through colors using 'C' key

This commit is contained in:
Kaian 2014-03-20 20:20:08 +01:00
parent 3b53b3873e
commit a05dc6e1d7
10 changed files with 113 additions and 19 deletions

View File

@ -268,7 +268,7 @@ uninstall-binPROGRAMS:
clean-binPROGRAMS: clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
sngrep$(EXEEXT): $(sngrep_OBJECTS) $(sngrep_DEPENDENCIES) $(EXTRA_sngrep_DEPENDENCIES) sngrep$(EXEEXT): $(sngrep_OBJECTS) $(sngrep_DEPENDENCIES) $(EXTRA_sngrep_DEPENDENCIES)
@rm -f sngrep$(EXEEXT) @rm -f sngrep$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(sngrep_OBJECTS) $(sngrep_LDADD) $(LIBS) $(AM_V_CCLD)$(LINK) $(sngrep_OBJECTS) $(sngrep_LDADD) $(LIBS)

View File

@ -38,6 +38,7 @@ call_group_create()
return NULL; return NULL;
} }
memset(group, 0, sizeof(sip_call_group_t)); memset(group, 0, sizeof(sip_call_group_t));
group->color = 0;
return group; return group;
} }

View File

@ -54,6 +54,7 @@ struct sip_call_group
{ {
sip_call_t *calls[1024]; sip_call_t *calls[1024];
int callcnt; int callcnt;
int color;
}; };
extern sip_call_group_t * extern sip_call_group_t *

View File

@ -50,8 +50,11 @@ init_options()
// Custom user conf file // Custom user conf file
char userconf[128]; char userconf[128];
// Add basic optionurations // Set default color options
set_option_value("color", "on"); set_option_value("color", "on");
set_option_value("color.request", "on");
set_option_value("color.callid", "off");
set_option_value("color.cseq", "off");
// Add Call list column options // Add Call list column options
set_option_value("cl.columns", "6"); set_option_value("cl.columns", "6");

View File

@ -95,6 +95,10 @@ static sip_attr_hdr_t attrs[] = {
.id = SIP_ATTR_REQUEST, .id = SIP_ATTR_REQUEST,
.name = "request", .name = "request",
.desc = "Request" }, .desc = "Request" },
{
.id = SIP_ATTR_CSEQ,
.name = "CSeq",
.desc = "CSeq" },
{ {
.id = SIP_ATTR_SDP, .id = SIP_ATTR_SDP,
.name = "sdp", .name = "sdp",
@ -119,6 +123,7 @@ sip_msg_create(const char *header, const char *payload)
msg->headerptr = strdup(header); msg->headerptr = strdup(header);
msg->payloadptr = strdup(payload); msg->payloadptr = strdup(payload);
msg->parsed = 0; msg->parsed = 0;
msg->color = -1;
return msg; return msg;
} }
@ -129,6 +134,7 @@ sip_call_create(char *callid)
sip_call_t *call = malloc(sizeof(sip_call_t)); sip_call_t *call = malloc(sizeof(sip_call_t));
memset(call, 0, sizeof(sip_call_t)); memset(call, 0, sizeof(sip_call_t));
call->attrs = NULL; call->attrs = NULL;
call->color = -1;
// Initialize call lock // Initialize call lock
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
@ -627,12 +633,13 @@ msg_parse_payload(sip_msg_t *msg, const char *payload)
} }
continue; continue;
} }
if (sscanf(pch, "CSeq: %d %[^\t\n\r]", &irest, value)) { if (sscanf(pch, "CSeq: %s %[^\t\n\r]", rest, value)) {
if (!msg_get_attribute(msg, SIP_ATTR_METHOD)) { if (!msg_get_attribute(msg, SIP_ATTR_METHOD)) {
// ACK Messages are not considered requests // ACK Messages are not considered requests
if (strcasecmp(value, "ACK")) msg_set_attribute(msg, SIP_ATTR_REQUEST, "1"); if (strcasecmp(value, "ACK")) msg_set_attribute(msg, SIP_ATTR_REQUEST, "1");
msg_set_attribute(msg, SIP_ATTR_METHOD, value); msg_set_attribute(msg, SIP_ATTR_METHOD, value);
} }
msg_set_attribute(msg, SIP_ATTR_CSEQ, rest);
continue; continue;
} }
if (sscanf(pch, "From: %[^:]:%[^\t\n\r>;]", rest, value)) { if (sscanf(pch, "From: %[^:]:%[^\t\n\r>;]", rest, value)) {

View File

@ -75,6 +75,8 @@ enum sip_attr_id
SIP_ATTR_METHOD, SIP_ATTR_METHOD,
//! SIP Message is a request //! SIP Message is a request
SIP_ATTR_REQUEST, SIP_ATTR_REQUEST,
//! SIP CSeq number
SIP_ATTR_CSEQ,
//! SIP Message has sdp //! SIP Message has sdp
SIP_ATTR_SDP, SIP_ATTR_SDP,
//! SIP Call first message method //! SIP Call first message method
@ -148,6 +150,8 @@ struct sip_msg
sip_call_t *call; sip_call_t *call;
//! Messages linked list //! Messages linked list
sip_msg_t *next; sip_msg_t *next;
//! Color for this message (in color.cseq mode)
int color;
}; };
/** /**
@ -167,6 +171,8 @@ struct sip_call
pthread_mutex_t lock; pthread_mutex_t lock;
//! Calls double linked list //! Calls double linked list
sip_call_t *next, *prev; sip_call_t *next, *prev;
//! Last used color (for color.cseq)
int color;
}; };
/** /**

View File

@ -149,6 +149,7 @@ call_flow_draw(PANEL *panel)
sip_msg_t *msg; sip_msg_t *msg;
WINDOW *win; WINDOW *win;
int height, width, cline; int height, width, cline;
char title[256];
// Get panel information // Get panel information
info = call_flow_info(panel); info = call_flow_info(panel);
@ -160,6 +161,24 @@ call_flow_draw(PANEL *panel)
wattron(win, COLOR_PAIR(DETAIL_BORDER_COLOR)); wattron(win, COLOR_PAIR(DETAIL_BORDER_COLOR));
title_foot_box(win); title_foot_box(win);
wattroff(win, COLOR_PAIR(DETAIL_BORDER_COLOR)); wattroff(win, COLOR_PAIR(DETAIL_BORDER_COLOR));
// Set title
if (info->group->callcnt == 1) {
sprintf(title, "Call flow for %s", call_get_attribute(*info->group->calls, SIP_ATTR_CALLID));
} else {
sprintf(title, "Call flow for %d dialogs", info->group->callcnt);
}
// Print color mode in title
if (is_option_enabled("color")) {
if (is_option_enabled("color.request")) sprintf(title, "%s (%s)", title, "Color by Request/Response");
if (is_option_enabled("color.callid")) sprintf(title, "%s (%s)", title, "Color by Call-Id");
if (is_option_enabled("color.cseq")) sprintf(title, "%s (%s)", title, "Color by CSeq");
}
mvwprintw(win, 1, (width - strlen(title))/2, "%s", title);
// Show some keybinding
mvwprintw(win, height - 2, 2, "Q/Esc: Quit"); mvwprintw(win, height - 2, 2, "Q/Esc: Quit");
mvwprintw(win, height - 2, 16, "F1: Help"); mvwprintw(win, height - 2, 16, "F1: Help");
mvwprintw(win, height - 2, 27, "x: Call-Flow"); mvwprintw(win, height - 2, 27, "x: Call-Flow");
@ -183,7 +202,6 @@ call_flow_draw(PANEL *panel)
} }
// If there are only three columns, then draw the raw message on this panel // If there are only three columns, then draw the raw message on this panel
//if ((20 + info->columns->colpos * 30 + get_option_int_value("cf.rawminwidth") < width)
if (is_option_enabled("cf.forceraw")) { if (is_option_enabled("cf.forceraw")) {
call_flow_draw_raw(panel, info->cur_msg); call_flow_draw_raw(panel, info->cur_msg);
} }
@ -230,6 +248,7 @@ call_flow_draw_message(PANEL *panel, sip_msg_t *msg, int cline)
{ {
call_flow_info_t *info; call_flow_info_t *info;
WINDOW *win; WINDOW *win;
sip_msg_t *prev;
const char *msg_time; const char *msg_time;
const char *msg_callid; const char *msg_callid;
const char *msg_method; const char *msg_method;
@ -283,11 +302,11 @@ call_flow_draw_message(PANEL *panel, sip_msg_t *msg, int cline)
int endpos = 20 + 30 * column2->colpos; int endpos = 20 + 30 * column2->colpos;
int distance = abs(endpos - startpos) - 3; int distance = abs(endpos - startpos) - 3;
// Highlight current message
if (msg == info->cur_msg) wattron(win, A_BOLD); if (msg == info->cur_msg) wattron(win, A_BOLD);
if (is_option_enabled("color.callid")) { // Color the message
wattron(win, COLOR_PAIR(call_group_color(info->group, msg->call))); if (is_option_enabled("color.request")) {
} else {
// Determine arrow color // Determine arrow color
if (msg_get_attribute(msg, SIP_ATTR_REQUEST)) { if (msg_get_attribute(msg, SIP_ATTR_REQUEST)) {
wattron(win, COLOR_PAIR(OUTGOING_COLOR)); wattron(win, COLOR_PAIR(OUTGOING_COLOR));
@ -295,6 +314,27 @@ call_flow_draw_message(PANEL *panel, sip_msg_t *msg, int cline)
wattron(win, COLOR_PAIR(INCOMING_COLOR)); wattron(win, COLOR_PAIR(INCOMING_COLOR));
} }
} }
// Color by call-id
if (is_option_enabled("color.callid")) {
wattron(win, COLOR_PAIR(call_group_color(info->group, msg->call)));
}
// Color by CSeq within the same call
if (is_option_enabled("color.cseq")) {
if (msg->call->color == -1) {
msg->call->color = (info->group->color++ % 7) + 1;
}
if (msg->color == -1) {
if ((prev = call_get_prev_msg(msg->call, msg))) {
if (strcmp(msg_get_attribute(msg, SIP_ATTR_CSEQ),
msg_get_attribute(prev, SIP_ATTR_CSEQ))) {
info->group->color = msg->call->color = (info->group->color++ % 7) + 1;
}
}
msg->color = msg->call->color;
}
// Turn on the message color
wattron(win, COLOR_PAIR(msg->color));
}
mvwprintw(win, cline, startpos + 2, "%.*s", distance, ""); mvwprintw(win, cline, startpos + 2, "%.*s", distance, "");
mvwprintw(win, cline, startpos + distance / 2 - msglen / 2 + 2, "%.26s", method); mvwprintw(win, cline, startpos + distance / 2 - msglen / 2 + 2, "%.26s", method);
@ -302,12 +342,16 @@ call_flow_draw_message(PANEL *panel, sip_msg_t *msg, int cline)
// Write the arrow at the end of the message (two arros if this is a retrans) // Write the arrow at the end of the message (two arros if this is a retrans)
if (!strcasecmp(msg_src, column1->addr)) { if (!strcasecmp(msg_src, column1->addr)) {
mvwaddch(win, cline + 1, endpos - 2, ACS_RARROW); mvwaddch(win, cline + 1, endpos - 2, ACS_RARROW);
if (msg_is_retrans(msg)) if (msg_is_retrans(msg)) {
mvwaddch(win, cline + 1, endpos - 3, ACS_RARROW); mvwaddch(win, cline + 1, endpos - 3, ACS_RARROW);
mvwaddch(win, cline + 1, endpos - 4, ACS_RARROW);
}
} else { } else {
mvwaddch(win, cline + 1, startpos + 2, ACS_LARROW); mvwaddch(win, cline + 1, startpos + 2, ACS_LARROW);
if (msg_is_retrans(msg)) if (msg_is_retrans(msg)) {
mvwaddch(win, cline + 1, startpos + 2, ACS_LARROW); mvwaddch(win, cline + 1, startpos + 3, ACS_LARROW);
mvwaddch(win, cline + 1, startpos + 4, ACS_LARROW);
}
} }
// Turn off colors // Turn off colors
@ -550,9 +594,9 @@ call_flow_help(PANEL *panel)
mvwprintw(help_win, 9, 2, "F1 Show this screen."); mvwprintw(help_win, 9, 2, "F1 Show this screen.");
mvwprintw(help_win, 10, 2, "q/Esc Go back to Call list window."); mvwprintw(help_win, 10, 2, "q/Esc Go back to Call list window.");
mvwprintw(help_win, 11, 2, "c Turn on/off window colours."); mvwprintw(help_win, 11, 2, "c Turn on/off window colours.");
mvwprintw(help_win, 12, 2, "C Turn on/off colour by Call-ID."); mvwprintw(help_win, 12, 2, "C Cycle between available color modes");
mvwprintw(help_win, 13, 2, "Up/Down Move to previous/next message."); mvwprintw(help_win, 13, 2, "Up/Down Move to previous/next message.");
mvwprintw(help_win, 14, 2, "x Show call-flow (Normal) for original call."); mvwprintw(help_win, 14, 2, "x Show call-flow with X-CID/X-Call-ID dialog");
mvwprintw(help_win, 15, 2, "r Show original call messages in raw mode."); mvwprintw(help_win, 15, 2, "r Show original call messages in raw mode.");
mvwprintw(help_win, 16, 2, "t Toggle raw preview display"); mvwprintw(help_win, 16, 2, "t Toggle raw preview display");
mvwprintw(help_win, 17, 2, "9/0 Increase/Decrease raw preview size"); mvwprintw(help_win, 17, 2, "9/0 Increase/Decrease raw preview size");

View File

@ -154,7 +154,7 @@ call_list_draw(PANEL *panel)
getmaxyx(win, height, width); getmaxyx(win, height, width);
// Print in the header if we're actually capturing // Print in the header if we're actually capturing
mvwprintw(win, 3, 23, "%s", is_option_enabled("sip.capture")?" ":"(Paused)"); mvwprintw(win, 3, 23, "%s", is_option_enabled("sip.capture")?" ":" (Paused)");
// Get available calls counter (we'll use it here a couple of times) // Get available calls counter (we'll use it here a couple of times)
if (!(callcnt = sip_calls_count())) return 0; if (!(callcnt = sip_calls_count())) return 0;

View File

@ -90,6 +90,9 @@ call_raw_draw(PANEL *panel)
int int
call_raw_print_msg(PANEL *panel, sip_msg_t *msg) call_raw_print_msg(PANEL *panel, sip_msg_t *msg)
{ {
// Previous message pointer
sip_msg_t *prev;
// Variables for drawing each message character // Variables for drawing each message character
int raw_line, raw_char, column; int raw_line, raw_char, column;
@ -111,10 +114,8 @@ call_raw_print_msg(PANEL *panel, sip_msg_t *msg)
info->pad = pad; info->pad = pad;
} }
// Determine arrow color // Color the message
if (info->group && is_option_enabled("color.callid")) { if (is_option_enabled("color.request")) {
wattron(pad, COLOR_PAIR(call_group_color(info->group, msg->call)));
} else {
// Determine arrow color // Determine arrow color
if (msg_get_attribute(msg, SIP_ATTR_REQUEST)) { if (msg_get_attribute(msg, SIP_ATTR_REQUEST)) {
wattron(pad, COLOR_PAIR(OUTGOING_COLOR)); wattron(pad, COLOR_PAIR(OUTGOING_COLOR));
@ -122,6 +123,27 @@ call_raw_print_msg(PANEL *panel, sip_msg_t *msg)
wattron(pad, COLOR_PAIR(INCOMING_COLOR)); wattron(pad, COLOR_PAIR(INCOMING_COLOR));
} }
} }
// Color by call-id
if (info->group && is_option_enabled("color.callid")) {
wattron(pad, COLOR_PAIR(call_group_color(info->group, msg->call)));
}
// Color by CSeq within the same call
if (info->group && is_option_enabled("color.cseq")) {
if (msg->call->color == -1) {
msg->call->color = (info->group->color++ % 7) + 1;
}
if (msg->color == -1) {
if ((prev = call_get_prev_msg(msg->call, msg))) {
if (strcmp(msg_get_attribute(msg, SIP_ATTR_CSEQ),
msg_get_attribute(prev, SIP_ATTR_CSEQ))) {
info->group->color = msg->call->color = (info->group->color++ % 7) + 1;
}
}
msg->color = msg->call->color;
}
// Turn on the message color
wattron(pad, COLOR_PAIR(msg->color));
}
// Print msg header // Print msg header
wattron(pad, A_BOLD); wattron(pad, A_BOLD);

View File

@ -280,11 +280,20 @@ wait_for_input(ui_t *ui)
switch (c) { switch (c) {
case 'c': case 'c':
// @todo general application config structure // @todo general application config structure
set_option_value("color", is_option_enabled("color") ? "off" : "on"); toggle_option("color");
toggle_color(is_option_enabled("color")); toggle_color(is_option_enabled("color"));
break; break;
case 'C': case 'C':
set_option_value("color.callid", is_option_enabled("color.callid") ? "off" : "on"); if (is_option_enabled("color.request")) {
toggle_option("color.request");
toggle_option("color.callid");
} else if (is_option_enabled("color.callid")) {
toggle_option("color.callid");
toggle_option("color.cseq");
} else if (is_option_enabled("color.cseq")) {
toggle_option("color.cseq");
toggle_option("color.request");
}
break; break;
case 'p': case 'p':
// Toggle capture option // Toggle capture option
@ -295,6 +304,7 @@ wait_for_input(ui_t *ui)
ui_help(ui); ui_help(ui);
break; break;
case 'q': case 'q':
case 'Q':
case 27: /* KEY_ESC */ case 27: /* KEY_ESC */
ui_destroy(ui); ui_destroy(ui);
return 0; return 0;