[asterisk-commits] mmichelson: branch group/issue8824 r143600 - /team/group/issue8824/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 18 19:46:21 CDT 2008


Author: mmichelson
Date: Thu Sep 18 19:46:20 2008
New Revision: 143600

URL: http://svn.digium.com/view/asterisk?view=rev&rev=143600
Log:
Redirecting reasons are now taken care of in chan_sip.

To be more specific, it means that

1. If we receive a Diversion header, then we properly
   set the channel's redirecting reason to be the
   reason in the Diversion header.

2. If we create a Diversion header, then we will add
   a reason corresponding to the owner channel's redirecting
   resason.

3. If we receive a 3XX response to an INVITE which does
   not have a Diversion header, then we will set a default
   reason of "unconditional" (maybe this should be changed
   to "unknown" though...)


Modified:
    team/group/issue8824/channels/chan_sip.c

Modified: team/group/issue8824/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/issue8824/channels/chan_sip.c?view=diff&rev=143600&r1=143599&r2=143600
==============================================================================
--- team/group/issue8824/channels/chan_sip.c (original)
+++ team/group/issue8824/channels/chan_sip.c Thu Sep 18 19:46:20 2008
@@ -637,6 +637,54 @@
 	{ SIP_OPT_TARGET_DIALOG,NOT_SUPPORTED,	"tdialog" },
 };
 
+/*! \brief Diversion header reasons
+ *
+ * The core defines a bunch of constants used to define
+ * redirecting reasons. This provides a translation table
+ * between those and the strings which may be present in 
+ * a SIP Diversion header
+ */
+static const struct sip_reasons {
+	enum AST_REDIRECTING_REASON code;
+	char * const text;
+} sip_reason_table[] = {
+	{ AST_REDIRECTING_REASON_UNKNOWN, "unknown" },
+	{ AST_REDIRECTING_REASON_USER_BUSY, "user-busy" },
+	{ AST_REDIRECTING_REASON_NO_ANSWER, "no-answer" },
+	{ AST_REDIRECTING_REASON_UNAVAILABLE, "unavailable" },
+	{ AST_REDIRECTING_REASON_UNCONDITIONAL, "unconditional" },
+	{ AST_REDIRECTING_REASON_TIME_OF_DAY, "time-of-day" },
+	{ AST_REDIRECTING_REASON_DO_NOT_DISTURB, "do-not-disturb" },
+	{ AST_REDIRECTING_REASON_DEFLECTION, "deflection" },
+	{ AST_REDIRECTING_REASON_FOLLOW_ME, "follow-me" },
+	{ AST_REDIRECTING_REASON_OUT_OF_ORDER, "out-of-service" },
+	{ AST_REDIRECTING_REASON_AWAY, "away" },
+	{ AST_REDIRECTING_REASON_CALL_FWD_DTE, "unknown"}
+};
+
+static enum AST_REDIRECTING_REASON sip_reason_str_to_code(const char *text) 
+{
+	enum AST_REDIRECTING_REASON ast = AST_REDIRECTING_REASON_UNKNOWN;
+	int i;
+
+	for (i = 0; i < ARRAY_LEN(sip_reason_table); ++i) {
+		if (!strcasecmp(text, sip_reason_table[i].text)) {
+			ast = sip_reason_table[i].code;
+			break;
+		}
+	}
+
+	return ast;
+}
+
+static const char *sip_reason_code_to_str(enum AST_REDIRECTING_REASON code)
+{
+	if (code >= 0 && code < ARRAY_LEN(sip_reason_table)) {
+		return sip_reason_table[code].text;
+	}
+
+	return "unknown";
+}
 
 /*! \brief SIP Methods we support 
 	\todo This string should be set dynamically. We only support REFER and SUBSCRIBE is we have
@@ -2118,7 +2166,7 @@
 static void check_via(struct sip_pvt *p, struct sip_request *req);
 static char *get_calleridname(const char *input, char *output, size_t outputsize);
 static int get_rpid(struct sip_pvt *p, struct sip_request *oreq);
-static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number);
+static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason);
 static int get_destination(struct sip_pvt *p, struct sip_request *oreq);
 static int get_msg_text(char *buf, int len, struct sip_request *req, int addnewline);
 static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout);
@@ -9070,6 +9118,7 @@
 {
 	const char *diverting_number;
 	const char *diverting_name;
+	const char *reason;
 	char header_text[256];
 
 	if (!pvt->owner) {
@@ -9079,6 +9128,7 @@
 	/* XXX Eventually change this to use pvt->owner->redirecting.from.number */
 	diverting_number = pvt->owner->cid.cid_rdnis;
 	diverting_name = pvt->owner->redirecting.from.name;
+	reason = sip_reason_code_to_str(pvt->owner->redirecting.reason);
 
 	if (ast_strlen_zero(diverting_number)) {
 		return;
@@ -9086,12 +9136,10 @@
 
 	/* We at least have a number to place in the Diversion header, which is enough */
 	if (ast_strlen_zero(diverting_name)) {
-		snprintf(header_text, sizeof(header_text), "sip:%s@%s", diverting_number, pvt->fromdomain);
+		snprintf(header_text, sizeof(header_text), "sip:%s@%s;reason=\"%s\"", diverting_number, pvt->fromdomain, reason);
 	} else {
-		snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>", diverting_name, diverting_number, pvt->fromdomain);
-	}
-
-	/* XXX Need to add a "reason" to the header text as well. */
+		snprintf(header_text, sizeof(header_text), "\"%s\" <sip:%s@%s>;\"%s\"", diverting_name, diverting_number, pvt->fromdomain, reason);
+	}
 
 	add_header(req, "Diversion", header_text);
 }
@@ -11235,10 +11283,10 @@
 }
 
 /*! \brief Get referring dnis */
-static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number)
+static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number, int *reason)
 {
 	char tmp[256], *exten, *rexten, *rdomain, *rname = NULL;
-	char *params, *reason = NULL;
+	char *params, *reason_param = NULL;
 	struct sip_request *req;
 	
 	req = oreq ? oreq : &p->initreq;
@@ -11266,16 +11314,16 @@
 		while (*params == ';' || *params == ' ')
 			params++;
 		/* Check if we have a reason parameter */
-		if ((reason = strcasestr(params, "reason="))) {
-			reason+=7;
+		if ((reason_param = strcasestr(params, "reason="))) {
+			reason_param+=7;
 			/* Remove enclosing double-quotes */
-			if (*reason == '"') 
-				ast_strip_quoted(reason, "\"", "\"");
-			if (!ast_strlen_zero(reason)) {
-				sip_set_redirstr(p, reason);
+			if (*reason_param == '"') 
+				ast_strip_quoted(reason_param, "\"", "\"");
+			if (!ast_strlen_zero(reason_param)) {
+				sip_set_redirstr(p, reason_param);
 				if (p->owner) {
 					pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause);
-					pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason);
+					pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason_param);
 				}
 			}
 		}
@@ -11287,7 +11335,7 @@
 		pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain);
 
 	if (sip_debug_test_pvt(p))
-		ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, reason ? reason : "");
+		ast_verbose("RDNIS for this call is %s (reason %s)\n", exten, reason ? reason_param : "");
 
 	ast_string_field_set(p, rdnis, rexten);
 
@@ -11304,6 +11352,10 @@
 
 	if (name && rname) {
 		*name = ast_strdup(rname);
+	}
+
+	if (reason && !ast_strlen_zero(reason_param)) {
+		*reason = sip_reason_str_to_code(reason_param);
 	}
 
 	return 0;
@@ -15261,10 +15313,11 @@
 	char *redirecting_from_number = NULL;
 	char *redirecting_to_name = NULL;
 	char *redirecting_to_number = NULL;
+	int reason = AST_REDIRECTING_REASON_UNCONDITIONAL;
 	int is_response = req->method == SIP_RESPONSE;
 	int res = 0;
 
-	res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number);
+	res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number, &reason);
 	if (res == -1) {
 		if (is_response) {
 			read_to_parts(p, req, &redirecting_from_name, &redirecting_from_number);
@@ -15321,6 +15374,7 @@
 		ast_debug(3, "Got redirecting to name %s\n", redirecting_from_number);
 		p->owner->redirecting.to.name = redirecting_to_name;
 	}
+	p->owner->redirecting.reason = reason;
 }
 
 /*! \brief Parse 302 Moved temporalily response */




More information about the asterisk-commits mailing list