sip: Add support for Reason header text #138

It will be printed as a new column (call attribute), so only one
per call will be stored (the last one received).
This commit is contained in:
Kaian 2016-09-26 11:21:23 +02:00
parent 1e0ee528d0
commit 68e23c98ad
6 changed files with 39 additions and 1 deletions

View File

@ -172,6 +172,7 @@ sip_init(int limit, int only_calls, int no_incomplete)
regcomp(&calls.reg_valid, "^([A-Z]+ [a-zA-Z]+:|SIP/2.0 [0-9]{3})", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_valid, "^([A-Z]+ [a-zA-Z]+:|SIP/2.0 [0-9]{3})", match_flags & ~REG_NEWLINE);
regcomp(&calls.reg_cl, "^(Content-Length|l):[ ]*([0-9]+)\r$", match_flags); regcomp(&calls.reg_cl, "^(Content-Length|l):[ ]*([0-9]+)\r$", match_flags);
regcomp(&calls.reg_body, "\r\n\r\n(.*)", match_flags & ~REG_NEWLINE); regcomp(&calls.reg_body, "\r\n\r\n(.*)", match_flags & ~REG_NEWLINE);
regcomp(&calls.reg_reason, "Reason:[ ]*[^\r]*;text=\"([^\r]+)\"", match_flags);
} }
@ -196,6 +197,7 @@ sip_deinit()
regfree(&calls.reg_valid); regfree(&calls.reg_valid);
regfree(&calls.reg_cl); regfree(&calls.reg_cl);
regfree(&calls.reg_body); regfree(&calls.reg_body);
regfree(&calls.reg_reason);
} }
@ -378,6 +380,8 @@ sip_check_packet(packet_t *packet)
sip_parse_msg_media(msg, payload); sip_parse_msg_media(msg, payload);
// Update Call State // Update Call State
call_update_state(call, msg); call_update_state(call, msg);
// Parse extra fields
sip_parse_extra_headers(msg, payload);
// Check if this call should be in active call list // Check if this call should be in active call list
if (call_is_active(call)) { if (call_is_active(call)) {
if (sip_call_is_active(call)) { if (sip_call_is_active(call)) {
@ -676,6 +680,17 @@ sip_parse_msg_media(sip_msg_t *msg, const u_char *payload)
#undef ADD_STREAM #undef ADD_STREAM
} }
void
sip_parse_extra_headers(sip_msg_t *msg, const u_char *payload)
{
regmatch_t pmatch[4];
// Reason
if (regexec(&calls.reg_reason, (const char *)payload, 2, pmatch, 0) == 0) {
msg->call->reasontxt = sng_malloc((int)pmatch[1].rm_eo - pmatch[1].rm_so + 1);
strncpy(msg->call->reasontxt, (const char *)payload + pmatch[1].rm_so, (int)pmatch[1].rm_eo - pmatch[1].rm_so);
}
}
void void
sip_calls_clear() sip_calls_clear()

View File

@ -157,6 +157,7 @@ struct sip_call_list {
regex_t reg_valid; regex_t reg_valid;
regex_t reg_cl; regex_t reg_cl;
regex_t reg_body; regex_t reg_body;
regex_t reg_reason;
}; };
/** /**
@ -309,6 +310,18 @@ sip_find_by_index(int index);
sip_call_t * sip_call_t *
sip_find_by_callid(const char *callid); sip_find_by_callid(const char *callid);
/**
* @brief Parse extra fields only for dialogs strarting with invite
*
* @note This function assumes the msg is already part of a call
*
* @param msg SIP message structure
* @param payload SIP message payload
*/
void
sip_parse_extra_headers(sip_msg_t *msg, const u_char *payload);
/** /**
* @brief Remove al calls * @brief Remove al calls
* *

View File

@ -52,7 +52,8 @@ static sip_attr_hdr_t attrs[SIP_ATTR_COUNT] = {
{ SIP_ATTR_MSGCNT, "msgcnt", "Msgs", "Message Count", 5 }, { SIP_ATTR_MSGCNT, "msgcnt", "Msgs", "Message Count", 5 },
{ SIP_ATTR_CALLSTATE, "state", NULL, "Call State", 10, sip_attr_color_state }, { SIP_ATTR_CALLSTATE, "state", NULL, "Call State", 10, sip_attr_color_state },
{ SIP_ATTR_CONVDUR, "convdur", "ConvDur", "Conversation Duration", 7 }, { SIP_ATTR_CONVDUR, "convdur", "ConvDur", "Conversation Duration", 7 },
{ SIP_ATTR_TOTALDUR, "totaldur", "TotalDur", "Total Duration", 8 } { SIP_ATTR_TOTALDUR, "totaldur", "TotalDur", "Total Duration", 8 },
{ SIP_ATTR_REASON_TXT, "reason", "Reason Text", "Reason Text", 25 },
}; };
sip_attr_hdr_t * sip_attr_hdr_t *

View File

@ -81,6 +81,8 @@ enum sip_attr_id {
SIP_ATTR_CONVDUR, SIP_ATTR_CONVDUR,
//! Total call duration //! Total call duration
SIP_ATTR_TOTALDUR, SIP_ATTR_TOTALDUR,
//! Text from SIP Reason header
SIP_ATTR_REASON_TXT,
//! SIP Attribute count //! SIP Attribute count
SIP_ATTR_COUNT SIP_ATTR_COUNT
}; };

View File

@ -83,6 +83,7 @@ call_destroy(sip_call_t *call)
// Deallocate call memory // Deallocate call memory
sng_free(call->callid); sng_free(call->callid);
sng_free(call->xcallid); sng_free(call->xcallid);
sng_free(call->reasontxt);
sng_free(call); sng_free(call);
} }
@ -277,6 +278,10 @@ call_get_attribute(sip_call_t *call, enum sip_attr_id id, char *value)
last = vector_last(call->msgs); last = vector_last(call->msgs);
timeval_to_duration(msg_get_time(first), msg_get_time(last), value); timeval_to_duration(msg_get_time(first), msg_get_time(last), value);
break; break;
case SIP_ATTR_REASON_TXT:
if (call->reasontxt)
sprintf(value, "%s", call->reasontxt);
break;
default: default:
return msg_get_attribute(vector_first(call->msgs), id, value); return msg_get_attribute(vector_first(call->msgs), id, value);
break; break;

View File

@ -72,6 +72,8 @@ struct sip_call {
bool changed; bool changed;
//! Locked flag. Calls locked are never deleted //! Locked flag. Calls locked are never deleted
bool locked; bool locked;
//! Las reason text value for this call
char *reasontxt;
//! List of calls with with this call as X-Call-Id //! List of calls with with this call as X-Call-Id
vector_t *xcalls; vector_t *xcalls;
//! Cseq from invite startint the call //! Cseq from invite startint the call