Add SIP CANCEL Cause processing

SIP CANCEL Causes are now processed and forwarded to OSMO-CC.
- Q.850 cause 127 = "internetwork, unspecified" will be ignored as if no cause was given.
- SIP cause 200 with description "call completed elsewhere" will be translated to ISDN cause 26 = "non-selected user clearing"
  This translation should avoid ISDN terminals logging a missed call, if another ringing SIP extension answers an incoming call.
This commit is contained in:
Dennis Grunert 2024-02-03 18:55:30 +01:00
parent c28cdd4b43
commit b5ea89e780
1 changed files with 33 additions and 2 deletions

View File

@ -1593,12 +1593,40 @@ static void call_r_bye(call_t *call, int status, char const *phrase)
release_and_destroy(call, 0, status, 0, 0, "");
}
static void call_i_cancel(call_t *call, nua_handle_t *nh)
static void call_i_cancel(call_t *call, nua_handle_t *nh, sip_t const *sip)
{
sip_reason_t *reason;
uint8_t isdn_cause = 0;
uint16_t sip_cause = 0;
char sip_cause_text[32] = {0};
osmo_cc_msg_t *msg;
LOGP(DSIP, LOGL_INFO, "Received CANCEL (callref %d)\n", call->cc_callref);
for (reason = sip->sip_reason; reason; reason = reason->re_next) {
if (!reason->re_protocol)
continue;
if (!isdn_cause && !strcasecmp(sip->sip_reason->re_protocol, "Q.850") && sip->sip_reason->re_cause) {
isdn_cause = atoi(sip->sip_reason->re_cause);
LOGP(DSIP, LOGL_INFO, " -> ISDN cause: %d\n", isdn_cause);
}
if (!sip_cause && !strcasecmp(sip->sip_reason->re_protocol, "SIP") && sip->sip_reason->re_cause) {
sip_cause = atoi(sip->sip_reason->re_cause);
if (sip->sip_reason->re_text)
strncpy(sip_cause_text, sip->sip_reason->re_text, sizeof(sip_cause_text) - 1);
LOGP(DSIP, LOGL_INFO, " -> SIP cause: %d (%s)\n", sip_cause, sip_cause_text);
}
}
/* translate "call completed elsewhere" to isdn cause "non-selected user clearing" */
if (sip_cause == 200 && isdn_cause == 0 && !strcasecmp(sip_cause_text, "\"Call completed elsewhere\"")) {
isdn_cause = 26;
LOGP(DSIP, LOGL_INFO, "Translating SIP cause %d (%s) to ISDN cause %d\n", sip_cause, sip_cause_text, isdn_cause);
}
/* ignore isdn cause "internetwork, unspecified" */
if (isdn_cause == 127)
isdn_cause = 0;
LOGP(DSIP, LOGL_INFO, "Sending CANCEL response: %d %s (callref %d)\n", SIP_200_OK, call->cc_callref);
nua_respond(nh, SIP_200_OK, TAG_END());
@ -1606,6 +1634,9 @@ static void call_i_cancel(call_t *call, nua_handle_t *nh)
/* create osmo-cc message */
msg = osmo_cc_new_msg(OSMO_CC_MSG_REL_IND);
/* cause */
osmo_cc_add_ie_cause(msg, OSMO_CC_LOCATION_BEYOND_INTERWORKING, isdn_cause, sip_cause, 0);
/* send message to osmo-cc */
osmo_cc_ll_msg(&call->sip_ep->cc_ep, call->cc_callref, msg);
@ -1753,7 +1784,7 @@ static void sip_message(nua_event_t event, int status, char const *phrase, nua_t
call_r_bye(call, status, phrase);
break;
case nua_i_cancel:
call_i_cancel(call, nh);
call_i_cancel(call, nh, sip);
break;
case nua_r_cancel:
call_r_cancel(call, status, phrase);