[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