[asterisk-commits] kharwell: branch kharwell/pimp_sip_diversion r385987 - in /team/kharwell/pimp...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 17 17:59:38 CDT 2013


Author: kharwell
Date: Wed Apr 17 17:59:34 2013
New Revision: 385987

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385987
Log:
won't compile - working on getting ast_party_redirecting updated

Added:
    team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c   (with props)
Modified:
    team/kharwell/pimp_sip_diversion/include/asterisk/res_sip.h
    team/kharwell/pimp_sip_diversion/res/res_sip.c
    team/kharwell/pimp_sip_diversion/res/res_sip_session.c

Modified: team/kharwell/pimp_sip_diversion/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_diversion/include/asterisk/res_sip.h?view=diff&rev=385987&r1=385986&r2=385987
==============================================================================
--- team/kharwell/pimp_sip_diversion/include/asterisk/res_sip.h (original)
+++ team/kharwell/pimp_sip_diversion/include/asterisk/res_sip.h Wed Apr 17 17:59:34 2013
@@ -1039,7 +1039,7 @@
  * \param src The pj_str_t to copy
  * \param size The size of the destination buffer.
  */
-void ast_copy_pj_str(char *dest, pj_str_t *src, size_t size);
+void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size);
 
 /*!
  * \brief Get the looked-up endpoint on an out-of dialog request or response

Modified: team/kharwell/pimp_sip_diversion/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_diversion/res/res_sip.c?view=diff&rev=385987&r1=385986&r2=385987
==============================================================================
--- team/kharwell/pimp_sip_diversion/res/res_sip.c (original)
+++ team/kharwell/pimp_sip_diversion/res/res_sip.c Wed Apr 17 17:59:34 2013
@@ -700,7 +700,7 @@
 	return std.fail;
 }
 
-void ast_copy_pj_str(char *dest, pj_str_t *src, size_t size)
+void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
 {
 	size_t chars_to_copy = MIN(size - 1, pj_strlen(src));
 	memcpy(dest, pj_strbuf(src), chars_to_copy);

Added: team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c?view=auto&rev=385987
==============================================================================
--- team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c (added)
+++ team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c Wed Apr 17 17:59:34 2013
@@ -1,0 +1,275 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Kevin Harwell <kharwell at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<depend>pjproject</depend>
+	<depend>res_sip</depend>
+	<depend>res_sip_session</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_sip.h"
+#include "asterisk/res_sip_session.h"
+#include "asterisk/callerid.h"
+#include "asterisk/channel.h"
+#include "asterisk/module.h"
+#include "asterisk/strings.h"
+
+#define DIV_HDR_MAX_SIZE 256
+
+/*! \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 reasons {
+	enum AST_REDIRECTING_REASON code;
+	char *const text;
+} 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"},
+	{ AST_REDIRECTING_REASON_SEND_TO_VM, "send_to_vm"},
+};
+
+static const char *reason_code_to_str(struct ast_party_redirecting_reason *reason)
+{
+	int code = reason->code;
+
+	/* use specific string if given */
+	if (!ast_strlen_zero(reason->str)) {
+		return reason->str;
+	}
+
+	if (code >= 0 && code < ARRAY_LEN(reason_table)) {
+		return reason_table[code].text;
+	}
+
+	return "unknown";
+}
+
+static pjsip_fromto_hdr *get_diversion_header(pjsip_rx_data *rdata)
+{
+	static const pj_str_t diversion = { "Diversion", 8 };
+	static const pj_str_t diversion = { "From", 4 };
+
+	pjsip_generic_string_hdr *hdr;
+	pjsip_fromto_hdr *parsed;
+	pj_str_t value;
+	int size;
+
+	if (!(hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &diversion, NULL))) {
+		return NULL;
+	}
+
+	pj_strdup_with_null(rdata->tp_info.pool, &value, &hdr->hvalue);
+
+	/* parse as a fromto header */
+	parsed = pjsip_parse_hdr(rdata->tp_info.pool, &from, value.ptr,
+				 pj_strlen(&header_content), &size);
+
+	return parsed ? parsed : NULL;
+}
+
+static void set_redirecting_value(char **dst, const pj_str_t *src)
+{
+	ast_free(*dst);
+	*dst = ast_malloc(pj_strlen(src) + 1);
+	ast_copy_pj_str(*dst, src, pj_strlen(src));
+}
+
+static void set_redirecting_id(pjsip_name_addr *hdr, struct ast_party_id *data,
+			       struct ast_set_party_id *update)
+{
+	pjsip_sip_uri *uri = pjsip_uri_get_uri(hdr->uri);
+
+	if (pj_strlen(uri->user)) {
+		update->number = 1;
+		data->number.valid = 1;
+		set_redirecting_value(&data->number.str, uri->user);
+	}
+
+	if (pj_strlen(hdr->display)) {
+		update->name = 1;
+		data->name.valid = 1;
+		set_redirecting_value(&data->name.str, hdr->display);
+	}
+}
+
+static int set_redirecting(pjsip_name_addr *div_hdr, pjsip_name_addr *to_hdr,
+			   struct ast_party_redirecting *data,
+			   struct ast_set_party_redirecting *update)
+{
+	set_redirecting_id(div_hdr, &data->from, &update.from);
+	set_redirecting_id(to_hdr, &data->to, &update.to);
+}
+
+static int set_redirecting(struct ast_sip_session *session,
+			   pjsip_name_addr *div_hdr,
+			   pjsip_name_addr *to_hdr)
+{
+	struct ast_party_redirecting data;
+	struct ast_set_party_redirecting update;
+
+	ast_party_redirecting_init(&data);
+	memset(&update, 0, sizeof(update));
+
+	set_redirecting(div_hdr, to_hdr, &data, &update);
+
+	ast_set_party_id_all(&update.priv_orig);
+	ast_set_party_id_all(&update.priv_from);
+	ast_set_party_id_all(&update.priv_to);
+
+	ast_channel_queue_redirecting_update(session->channel, &data, update);
+	ast_party_redirecting_free(&data);
+}
+
+static int diversion_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	/* check if diversion header is present, if so update channel's redirecting info */
+	pjsip_fromto_hdr *hdr = get_diversion_header(rdata);
+	
+	if (!hdr) {
+		return -1;
+	}
+
+	return 0;
+}
+
+static void diversion_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata)
+{
+	/* check if diversion header is present, if so update channel's redirecting info */
+	/* if 3xx and not present then update channel redirect info */
+	if (!session->channel) {
+		return;
+	}
+}
+
+/*!
+ * \internal
+ * \brief Adds diversion header information to an outbound SIP message
+ *
+ * \param session The session on which we will be sending the message
+ * \param tdata The outbound message
+ */
+static void add_diversion_header(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
+{
+	struct ast_str *buf = ast_str_alloca(DIV_HDR_MAX_SIZE);
+	const char *reason, *contact, *domain;
+	struct ast_party_id from = ast_channel_redirecting_effective_from(session->channel);
+
+	if (!from.number.valid || ast_strlen_zero(from.number.str)) {
+		return;
+	}
+
+	if (from.name.valid && !ast_strlen_zero(from.name.str)) {
+		ast_str_set(&buf, ast_str_size(buf), "\"%s\"", from.name.str);
+	}
+
+	contact = ast_sip_location_retrieve_contact_from_aor_list(session->endpoint->aors)->uri;
+	if ((domain = strchr(contact, '@'))) {
+		++domain;
+	}
+
+	reason = reason_code_to_str(&ast_channel_redirecting(session->channel)->reason);
+	ast_str_append(&buf, ast_str_size(buf) - ast_str_strlen(buf), "<sip:%s@%s>;reason=%s",
+		       from.number.str, domain ? domain : contact, reason);
+
+	ast_sip_add_header(tdata, "Diversion", ast_str_buffer(buf));
+}
+
+/*!
+ * \internal
+ * \brief Adds a diversion header to an outgoing INVITE request if
+ *  redirecting information is available.
+ *
+ * \param session The session on which the INVITE request is to be sent
+ * \param tdata The outbound INVITE request
+ */
+static void diversion_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	struct ast_party_redirecting *data;
+
+	if (session->channel && 
+	    (data = ast_channel_redirecting(session->channel))->count) {
+		add_diversion_header(session, tdata, data);
+	}
+}
+
+/*!
+ * \internal
+ * \brief Adds a diversion header to an outgoing 3XX response
+ *
+ * \param session The session on which the INVITE response is to be sent
+ * \param tdata The outbound INVITE response
+ */
+static void diversion_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
+{
+	struct pjsip_status_line status = tdata->msg->line.status;
+	struct ast_party_redirecting *data;
+
+	/* add to 302 and 181 */
+	if (((status.code >= 300) && (status.code < 400) ||
+	     (status.code == 181)) && session->channel &&
+	    (data = ast_channel_redirecting(session->channel))->count)) {
+		add_diversion_header(session, tdata, data);
+	}
+}
+
+static struct ast_sip_session_supplement diversion_supplement = {
+	.method = "INVITE",
+	.priority = AST_SIP_SESSION_SUPPLEMENT_PRIORITY_CHANNEL - 1000,
+	.incoming_request = diversion_incoming_request,
+	.incoming_response = diversion_incoming_response,
+	.outgoing_request = diversion_outgoing_request,
+	.outgoing_response = diversion_outgoing_response,
+};
+
+static int load_module(void)
+{
+	ast_sip_session_register_supplement(&diversion_supplement);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_session_unregister_supplement(&diversion_supplement);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP Add Diversion Header Support",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );

Propchange: team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: team/kharwell/pimp_sip_diversion/res/res_sip_diversion.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/kharwell/pimp_sip_diversion/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_diversion/res/res_sip_session.c?view=diff&rev=385987&r1=385986&r2=385987
==============================================================================
--- team/kharwell/pimp_sip_diversion/res/res_sip_session.c (original)
+++ team/kharwell/pimp_sip_diversion/res/res_sip_session.c Wed Apr 17 17:59:34 2013
@@ -1699,8 +1699,17 @@
 
 static pjsip_redirect_op session_inv_on_redirected(pjsip_inv_session *inv, const pjsip_uri *target, const pjsip_event *e)
 {
-	/* XXX STUB */
-	return PJSIP_REDIRECT_REJECT;
+	struct ast_sip_session *session = inv->mod_data[session_module.id];
+
+	if (PJSIP_URI_SCHEME_IS_SIP(target) || PJSIP_URI_SCHEME_IS_SIPS(target)) {
+		const pjsip_sip_uri *uri = pjsip_uri_get_uri(target);
+		char exten[AST_MAX_EXTENSION];
+
+		ast_copy_pj_str(exten, &uri->user, sizeof(exten));
+		ast_channel_call_forward_set(session->channel, exten);
+	}
+
+	return PJSIP_REDIRECT_STOP;
 }
 
 static pjsip_inv_callback inv_callback = {




More information about the asterisk-commits mailing list