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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Sep 17 13:46:56 CDT 2008


Author: mmichelson
Date: Wed Sep 17 13:46:55 2008
New Revision: 143350

URL: http://svn.digium.com/view/asterisk?view=rev&rev=143350
Log:
Changed some functions around in chan_sip to be a bit more efficient
for the purposes of changing the redirecting information on a channel.
Redirecting information is all properly read from Contact: and 
Diversion: headers now. Next, I need to add the ability to read
from other potential headers (like if a 302 is received with no
Diversion header, we need to get the redirecting "from" information
from the To header of the original SIP request).

The other thing still left to do is to translate reasons specified
in Diversion headers into Q.931 reason codes so that they may be
stored properly in the redirecting information.


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=143350&r1=143349&r2=143350
==============================================================================
--- team/group/issue8824/channels/chan_sip.c (original)
+++ team/group/issue8824/channels/chan_sip.c Wed Sep 17 13:46:55 2008
@@ -1872,7 +1872,7 @@
 static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno);
 static void copy_request(struct sip_request *dst, const struct sip_request *src);
 static void receive_message(struct sip_pvt *p, struct sip_request *req);
-static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req);
+static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req, char **name, char **number);
 static int sip_send_mwi_to_peer(struct sip_peer *peer, const struct ast_event *event, int cache_only);
 
 /*--- Dialog management */
@@ -2118,12 +2118,13 @@
 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);
+static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number);
 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);
 static void update_connectedline(struct sip_pvt *p, const void *data, size_t datalen);
 static void update_redirecting(struct sip_pvt *p, const void *data, size_t datalen);
+static void change_redirecting_information(struct sip_pvt *p, struct sip_request *req);
 
 /*-- TCP connection handling ---*/
 static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_session_instance *ser);
@@ -11234,9 +11235,9 @@
 }
 
 /*! \brief Get referring dnis */
-static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq)
-{
-	char tmp[256], *exten, *rexten, *rdomain;
+static int get_rdnis(struct sip_pvt *p, struct sip_request *oreq, char **name, char **number)
+{
+	char tmp[256], *exten, *rexten, *rdomain, *rname = NULL;
 	char *params, *reason = NULL;
 	struct sip_request *req;
 	
@@ -11244,7 +11245,7 @@
 
 	ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
 	if (ast_strlen_zero(tmp))
-		return 0;
+		return -1;
 
 	params = strchr(tmp, ';');
 
@@ -11290,10 +11291,20 @@
 
 	ast_string_field_set(p, rdnis, rexten);
 
-	/*XXX Add logic here for updating the redirecting information for the owner channel.
-	 * The diversion header which we just parsed will have the from name and number. The "To"
-	 * will be taken care of either in the Contact: header or in the RURI 
-	 */
+	if (*tmp == '\"') {
+		char *end_quote;
+		rname = tmp + 1;
+		end_quote = strchr(rname, '\"');
+		*end_quote = '\0';
+	}
+
+	if (number) {
+		*number = ast_strdup(rexten);
+	}
+
+	if (name && rname) {
+		*name = ast_strdup(rname);
+	}
 
 	return 0;
 }
@@ -15192,16 +15203,85 @@
 	"- t38passthrough        1 if T38 is offered or enabled in this channel, otherwise 0\n"
 };
 
+/*XXX TODO Write this*/
+static int read_ruri_parts(struct sip_pvt *p, struct sip_request *req, char **name, char **number)
+{
+	return 0;
+}
+
+/*! \brief update redirecting information for a channel based on headers
+ *
+ */
+static void change_redirecting_information(struct sip_pvt *p, struct sip_request *req)
+{
+	char *redirecting_from_name = NULL;
+	char *redirecting_from_number = NULL;
+	char *redirecting_to_name = NULL;
+	char *redirecting_to_number = NULL;
+	int is_response = req->method == SIP_RESPONSE;
+	int res = 0;
+
+	res = get_rdnis(p, req, &redirecting_from_name, &redirecting_from_number);
+	if (res == -1) {
+		if (is_response) {
+			read_ruri_parts(p, req, &redirecting_from_name, &redirecting_from_number);
+		} else {
+			return;
+		}
+	}
+
+	/* At this point, all redirecting "from" info should be filled in appropriately
+	 * on to the "to" info
+	 */
+
+	if (is_response) {
+		parse_moved_contact(p, req, &redirecting_to_name, &redirecting_to_number);
+	} else {
+		read_ruri_parts(p, req, &redirecting_to_name, &redirecting_to_number);
+	}
+
+	/* This check could probably moved up higher so we don't do any unnecessary
+	 * parsing
+	 */
+	if (!p->owner) {
+		return;
+	}
+
+	/* The only item that is not correctly set here at this point is the
+	 * reason from the Diversion
+	 */
+	if (!ast_strlen_zero(redirecting_from_number)) {
+		if (p->owner->cid.cid_rdnis) {
+			ast_free(p->owner->cid.cid_rdnis);
+		}
+		p->owner->cid.cid_rdnis = ast_strdup(redirecting_from_number);
+	}
+	if (!ast_strlen_zero(redirecting_from_name)) {
+		if (p->owner->redirecting.from.name) {
+			ast_free(p->owner->redirecting.from.name);
+		}
+		p->owner->redirecting.from.name = ast_strdup(redirecting_from_name);
+	}
+	if (!ast_strlen_zero(redirecting_to_number)) {
+		if (p->owner->redirecting.to.number) {
+			ast_free(p->owner->redirecting.to.number);
+		}
+		p->owner->redirecting.to.number = redirecting_to_number;
+	}
+	if (!ast_strlen_zero(redirecting_to_name)) {
+		if (p->owner->redirecting.to.name) {
+			ast_free(p->owner->redirecting.to.name);
+		}
+		p->owner->redirecting.to.name = redirecting_to_name;
+	}
+}
+
 /*! \brief Parse 302 Moved temporalily response */
-static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
+static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req, char **name, char **number)
 {
 	char contact[SIPBUFSIZE];
 	char *contact_name = NULL;
 	char *contact_number = NULL;
-#if 0
-	char *redirecting_name = NULL;
-	char *redirecting_number = NULL;
-#endif
 	char *separator, *trans;
 	char *domain;
 	enum sip_transport transport = SIP_TRANSPORT_UDP;
@@ -15292,20 +15372,12 @@
 		}
 	}
 
-	if (p->owner) {
-		if (p->owner->redirecting.to.number) {
-			ast_free(p->owner->redirecting.to.number);
-		}
-		p->owner->redirecting.to.number = ast_strdup(contact_number);
-		if (p->owner->redirecting.to.name) {
-			ast_free(p->owner->redirecting.to.name);
-		}
-		p->owner->redirecting.to.name = ast_strdup(contact_name);
-	}
-
-	/*XXX Add logic for obtaining redirecting-from information. This may be
-	 * in a diversion header or by getting the request's original RURI
-	 */
+	if (name && !ast_strlen_zero(contact_name)) {
+		*name = ast_strdup(contact_name);
+	}
+	if (number) {
+		*number = ast_strdup(contact_number);
+	}
 }
 
 /*! \brief Check pending actions on SIP call */
@@ -16257,7 +16329,7 @@
 				case 301: /* Moved permanently */
 				case 302: /* Moved temporarily */
 				case 305: /* Use Proxy */
-					parse_moved_contact(p, req);
+					change_redirecting_information(p, req);
 					/* Fall through */
 				case 486: /* Busy here */
 				case 600: /* Busy everywhere */
@@ -17626,7 +17698,7 @@
 			return 0;
 		}
 		gotdest = get_destination(p, NULL);	/* Get destination right away */
-		get_rdnis(p, NULL);			/* Get redirect information */
+		change_redirecting_information(p, req); /*Will return immediately if no Diversion header is present */
 		extract_uri(p, req);			/* Get the Contact URI */
 		build_contact(p);			/* Build our contact header */
 




More information about the asterisk-commits mailing list