[asterisk-commits] kmoore: branch kmoore/pjsip_path_support r403363 - /team/kmoore/pjsip_path_su...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Dec 4 14:43:06 CST 2013


Author: kmoore
Date: Wed Dec  4 14:43:04 2013
New Revision: 403363

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=403363
Log:
Initial implementation of Path support

Added:
    team/kmoore/pjsip_path_support/res/res_pjsip_path.c   (with props)

Added: team/kmoore/pjsip_path_support/res/res_pjsip_path.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/pjsip_path_support/res/res_pjsip_path.c?view=auto&rev=403363
==============================================================================
--- team/kmoore/pjsip_path_support/res/res_pjsip_path.c (added)
+++ team/kmoore/pjsip_path_support/res/res_pjsip_path.c Wed Dec  4 14:43:04 2013
@@ -1,0 +1,268 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Kinsey Moore <kmoore 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_pjsip</depend>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+#include <pjsip_ua.h>
+
+#include "asterisk/res_pjsip.h"
+#include "asterisk/module.h"
+#include "asterisk/strings.h"
+
+static const pj_str_t path_name = { "Path", 4 };
+static const pj_str_t path_supported_name = { "path", 4 };
+static const pj_str_t route_name = { "Route", 5 };
+
+static struct ast_sip_aor *find_aor(struct ast_sip_endpoint *endpoint, pjsip_uri *uri)
+{
+	char *configured_aors, *aor_name;
+	pjsip_sip_uri *sip_uri;
+	char user_name[64], domain_name[64];
+
+	if (ast_strlen_zero(endpoint->aors)) {
+		return NULL;
+	}
+
+	sip_uri = pjsip_uri_get_uri(uri);
+	ast_copy_pj_str(user_name, &sip_uri->user, sizeof(user_name));
+	ast_copy_pj_str(domain_name, &sip_uri->host, sizeof(domain_name));
+
+	configured_aors = ast_strdupa(endpoint->aors);
+
+	/* Iterate the configured AORs to see if the user or the user+domain match */
+	while ((aor_name = strsep(&configured_aors, ","))) {
+		char id[AST_UUID_STR_LEN];
+		RAII_VAR(struct ast_sip_domain_alias *, alias, NULL, ao2_cleanup);
+
+		snprintf(id, sizeof(id), "%s@%s", user_name, domain_name);
+		if (!strcmp(aor_name, id)) {
+			break;
+		}
+
+		if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
+			snprintf(id, sizeof(id), "%s@%s", user_name, alias->domain);
+			if (!strcmp(aor_name, id)) {
+				break;
+			}
+		}
+
+		if (!strcmp(aor_name, user_name)) {
+			break;
+		}
+	}
+
+	if (ast_strlen_zero(aor_name)) {
+		return NULL;
+	}
+	
+	return ast_sip_location_retrieve_aor(aor_name);
+}
+
+/*! \brief Callback function for finding a contact */
+static int find_contact(void *obj, void *arg, void *data, int flags)
+{
+	struct ast_sip_contact *contact = obj;
+	pjsip_uri *uri = arg;
+	pj_pool_t *pool = data;
+	pjsip_uri *contact_uri = pjsip_parse_uri(pool, (char*)contact->uri, strlen(contact->uri), 0);
+
+	return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH | CMP_STOP : 0;
+}
+
+/*!
+ * \brief Get the path string associated with this endpoint and tdata
+ *
+ * \param endpoint The endpoint from which to pull associated path data
+ * \param contact_uri The URI identifying the associated contact
+ * \param path_str The place to store the retrieved path information
+ *
+ * \retval zero on success
+ * \retval non-zero on failure or no available path information
+ */
+static int path_get_string(pj_pool_t *pool, struct ast_sip_aor *aor, pjsip_uri *contact_uri, pj_str_t *path_str)
+{
+	RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+
+	contacts = ast_sip_location_retrieve_aor_contacts(aor);
+	if (!contacts) {
+		return -1;
+	}
+
+	contact = ao2_callback_data(contacts, OBJ_UNLINK, find_contact, pjsip_uri_get_uri(contact_uri), pool);
+	if (!contact) {
+		return -1;
+	}
+
+	if (ast_strlen_zero(contact->path)) {
+		return -1;
+	}
+
+	*path_str = pj_strdup3(pool, contact->path);
+	return 0;
+}
+
+static int add_supported(pjsip_tx_data *tdata)
+{
+	pjsip_supported_hdr *hdr;
+
+	hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
+	if (!hdr) {
+		/* insert a new Supported header */
+		hdr = pjsip_supported_hdr_create(tdata->pool);
+		if (!hdr) {
+			return -1;
+		}
+
+		pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
+	}
+
+	/* add on to the existing Supported header */
+	pj_strdup(tdata->pool, &hdr->values[hdr->count++], &path_supported_name);
+
+	return 0;
+}
+
+/*!
+ * \internal
+ * \brief Adds a path 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 path_outgoing_request(struct ast_sip_endpoint *endpoint, pjsip_tx_data *tdata)
+{
+	pj_str_t path_dup;
+	pjsip_generic_string_hdr *route_hdr;
+	RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
+
+	if (!endpoint) {
+		return;
+	}
+
+	aor = find_aor(endpoint, tdata->msg->line.req.uri);
+	if (!aor || !aor->support_path) {
+		return;
+	}
+
+	if (add_supported(tdata)) {
+		return;
+	}
+
+	if (path_get_string(tdata->pool, aor, tdata->msg->line.req.uri, &path_dup)) {
+		return;
+	}
+
+	route_hdr = pjsip_generic_string_hdr_create(tdata->pool, &route_name, &path_dup);
+	if (!route_hdr) {
+		return;
+	}
+
+	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route_hdr);
+}
+
+/*!
+ * \internal
+ * \brief Adds a path header to an outgoing 2XX response
+ *
+ * \param session The session on which the INVITE response is to be sent
+ * \param tdata The outbound INVITE response
+ */
+static void path_outgoing_register_response(struct ast_sip_endpoint *endpoint, pjsip_tx_data *tdata)
+{
+	struct pjsip_status_line status = tdata->msg->line.status;
+	pj_str_t path_dup;
+	pjsip_generic_string_hdr *path_hdr;
+	pjsip_contact_hdr *contact_hdr;
+	RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
+
+	if (!endpoint) {
+		return;
+	}
+
+	if (status.code != 200) {
+		return;
+	}
+
+	contact_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
+	if (!contact_hdr) {
+		return;
+	}
+
+	aor = find_aor(endpoint, contact_hdr->uri);
+	if (!aor || !aor->support_path) {
+		return;
+	}
+
+	if (path_get_string(tdata->pool, aor, contact_hdr->uri, &path_dup)) {
+		return;
+	}
+
+	path_hdr = pjsip_generic_string_hdr_create(tdata->pool, &path_name, &path_dup);
+	if (!path_hdr) {
+		return;
+	}
+
+	pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)path_hdr);
+}
+
+static struct ast_sip_supplement path_supplement = {
+	.priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL - 100,
+	.outgoing_request = path_outgoing_request,
+};
+
+static struct ast_sip_supplement path_register_supplement = {
+	.method = "REGISTER",
+	.priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL - 100,
+	.outgoing_response = path_outgoing_register_response,
+};
+
+static int load_module(void)
+{
+	if (ast_sip_register_supplement(&path_supplement)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	if (ast_sip_register_supplement(&path_register_supplement)) {
+		ast_sip_unregister_supplement(&path_supplement);
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	ast_sip_unregister_supplement(&path_register_supplement);
+	ast_sip_unregister_supplement(&path_supplement);
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Path Header Support",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	       );

Propchange: team/kmoore/pjsip_path_support/res/res_pjsip_path.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/kmoore/pjsip_path_support/res/res_pjsip_path.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/kmoore/pjsip_path_support/res/res_pjsip_path.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the asterisk-commits mailing list