--- chan_sip.c 2005-10-20 16:13:51.000000000 +0200 +++ chan_sip_jt.c 2005-10-20 16:09:36.000000000 +0200 @@ -624,6 +624,7 @@ char language[MAX_LANGUAGE]; /* Default language for this call */ char musicclass[MAX_MUSICCLASS]; /* Music on Hold class */ char rdnis[256]; /* Referring DNIS */ + char redircause[256]; /* Referring cause */ char theirtag[256]; /* Their tag */ char username[256]; /* [user] name */ char peername[256]; /* [peer] name, not set if [user] */ @@ -2768,6 +2769,8 @@ tmp->cid.cid_name = strdup(i->cid_name); if (!ast_strlen_zero(i->rdnis)) tmp->cid.cid_rdnis = strdup(i->rdnis); + if (!ast_strlen_zero(i->redircause)) + pbx_builtin_setvar_helper(tmp, "__PRIREDIRECTREASON", i->redircause); if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s")) tmp->cid.cid_dnid = strdup(i->exten); tmp->priority = 1; @@ -6435,10 +6438,40 @@ return res; } +static void sip_set_redirstr(struct sip_pvt *p, char *reason) { + + if (strcmp(reason, "unknown")==0) { + ast_copy_string(p->redircause, "UNKNOWN", sizeof(p->redircause)); + } else if (strcmp(reason, "user-busy")==0) { + ast_copy_string(p->redircause, "BUSY", sizeof(p->redircause)); + } else if (strcmp(reason, "no-answer")==0) { + ast_copy_string(p->redircause, "NOANSWER", sizeof(p->redircause)); + } else if (strcmp(reason, "unavailable")==0) { + ast_copy_string(p->redircause, "UNREACHABLE", sizeof(p->redircause)); + } else if (strcmp(reason, "unconditional")==0) { + ast_copy_string(p->redircause, "UNCONDITIONAL", sizeof(p->redircause)); + } else if (strcmp(reason, "time-of-day")==0) { + ast_copy_string(p->redircause, "UNKNOWN", sizeof(p->redircause)); + } else if (strcmp(reason, "do-not-disturb")==0) { + ast_copy_string(p->redircause, "UNKNOWN", sizeof(p->redircause)); + } else if (strcmp(reason, "deflection")==0) { + ast_copy_string(p->redircause, "UNKNOWN", sizeof(p->redircause)); + } else if (strcmp(reason, "follow-me")==0) { + ast_copy_string(p->redircause, "UNKNOWN", sizeof(p->redircause)); + } else if (strcmp(reason, "out-of-service")==0) { + ast_copy_string(p->redircause, "UNREACHABLE", sizeof(p->redircause)); + } else if (strcmp(reason, "away")==0) { + ast_copy_string(p->redircause, "UNREACHABLE", sizeof(p->redircause)); + } else { + ast_copy_string(p->redircause, "UNKNOWN", sizeof(p->redircause)); + } +} + /*--- get_rdnis: get referring dnis ---*/ static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq) { char tmp[256], *c, *a; + char *params, *reason, *stop; struct sip_request *req; req = oreq; @@ -6447,6 +6480,41 @@ ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp)); if (ast_strlen_zero(tmp)) return 0; + + /* Get diversion-reason param if present */ + params = strchr(tmp, ';'); + if (params && *params == ';' && *(params+1) != '\0') { + while (*params == ';' || *params == ' ') params++; + if (strlen(params) >= strlen("reason=")) { + if (strncasecmp(params, "reason", strlen("reason")) == 0) { + reason = strchr(params, '='); + if (reason && *reason == '=') { + reason++; + /* Remove enclosing double-quotes */ + if (*reason == '"') { + reason++; + stop = reason; + while (*stop != '"') { + if (*stop == '\0') { + /* Missing end-quote */ + *reason = '\0'; + break; + } + stop++; + } + *stop = '\0'; + } else { + stop = reason; + while (*stop && *stop != ';' && *stop != '"') stop++; + *stop = '\0'; + } + if (*reason) + sip_set_redirstr(p, reason); + } + } + } + } + c = get_in_brackets(tmp); if (strncmp(c, "sip:", 4)) { ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c);