[asterisk-commits] file: branch file/pimp_sip_location r381278 - in /team/file/pimp_sip_location...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Feb 12 12:08:33 CST 2013


Author: file
Date: Tue Feb 12 12:08:30 2013
New Revision: 381278

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381278
Log:
Add a first stab location code prototype.

Added:
    team/file/pimp_sip_location/res/res_sip/location.c   (with props)
Modified:
    team/file/pimp_sip_location/channels/chan_gulp.c
    team/file/pimp_sip_location/include/asterisk/res_sip.h
    team/file/pimp_sip_location/include/asterisk/res_sip_session.h
    team/file/pimp_sip_location/res/res_sip.c
    team/file/pimp_sip_location/res/res_sip.exports.in
    team/file/pimp_sip_location/res/res_sip/sip_configuration.c
    team/file/pimp_sip_location/res/res_sip_session.c

Modified: team/file/pimp_sip_location/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/channels/chan_gulp.c?view=diff&rev=381278&r1=381277&r2=381278
==============================================================================
--- team/file/pimp_sip_location/channels/chan_gulp.c (original)
+++ team/file/pimp_sip_location/channels/chan_gulp.c Tue Feb 12 12:08:30 2013
@@ -502,22 +502,44 @@
 /*! \brief Function called by core to create a new outgoing Gulp session */
 static struct ast_channel *gulp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
 {
-	struct ast_sip_endpoint *endpoint = ast_sip_endpoint_alloc("constant");
+	char *tmp = ast_strdupa(data), *endpoint_name = NULL, *request_user = NULL;
+	struct ast_sip_endpoint *endpoint = NULL;
 	struct ast_sip_session *session = NULL;
-
-	if (!endpoint) {
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(endpoint);
+		AST_APP_ARG(location);
+	);
+
+	if (ast_strlen_zero(data)) {
+		ast_log(LOG_ERROR, "Unable to create Gulp channel with empty destination\n");
+		*cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
 		return NULL;
 	}
 
-	/* TODO: This needs to actually grab a proper endpoint and such */
-	ast_string_field_set(endpoint, context, "default");
-	ast_parse_allow_disallow(&endpoint->prefs, endpoint->codecs, "ulaw", 1);
-	endpoint->min_se = 90;
-	endpoint->sess_expires = 1800;
+	AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
+
+	/* If a request user has been specified extract it from the endpoint name portion */
+	if ((endpoint_name = strchr(args.endpoint, '@'))) {
+		request_user = args.endpoint;
+		*endpoint_name++ = '\0';
+	} else {
+		endpoint_name = args.endpoint;
+	}
+
+	if (ast_strlen_zero(endpoint_name)) {
+		ast_log(LOG_ERROR, "Unable to create Gulp channel with empty endpoint name\n");
+		*cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
+		return NULL;
+	} else if (!(endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name))) {
+		ast_log(LOG_ERROR, "Unable to create Gulp channel - endpoint '%s' was not found", endpoint_name);
+		*cause = AST_CAUSE_NO_ROUTE_DESTINATION;
+		return NULL;
+	}
 
 	pj_thread_register_check();
 
-	if (!(session = ast_sip_session_create_outgoing(endpoint, data))) {
+	if (!(session = ast_sip_session_create_outgoing(endpoint, args.location, request_user))) {
+		ao2_cleanup(endpoint);
 		return NULL;
 	}
 

Modified: team/file/pimp_sip_location/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/include/asterisk/res_sip.h?view=diff&rev=381278&r1=381277&r2=381278
==============================================================================
--- team/file/pimp_sip_location/include/asterisk/res_sip.h (original)
+++ team/file/pimp_sip_location/include/asterisk/res_sip.h Tue Feb 12 12:08:30 2013
@@ -39,6 +39,7 @@
 struct pjsip_transport;
 struct pjsip_tpfactory;
 struct pjsip_tls_setting;
+struct pjsip_tpselector;
 
 /*!
  * \brief Opaque structure representing related SIP tasks
@@ -112,34 +113,19 @@
 };
 
 /*!
- * \brief Contact associated with an address of record
- */
-struct ast_sip_contact {
+ * \brief Location information for a SIP entity
+ */
+struct ast_sip_location {
+	/*! Sorcery object details, the id is the name of the location */
+	SORCERY_OBJECT(details);
 	AST_DECLARE_STRING_FIELDS(
-		/* XXX This may work better as an object instead of a string */
-		/*! Full URI of the contact */
+		/*! Full URI of the location */
 		AST_STRING_FIELD(uri);
+		/*! Optional explicit transport to use */
+		AST_STRING_FIELD(transport);
 	);
-	/*! Absolute time that this contact expires */
+	/*! Absolute time that this location is valid until */
 	time_t expiration_time;
-	/*! Next list item */
-	AST_LIST_ENTRY(ast_sip_contact) next;
-};
-
-/*!
- * \brief A SIP address of record
- */
-struct ast_sip_aor {
-	AST_DECLARE_STRING_FIELDS(
-		/*! Name of the address of record */
-		AST_STRING_FIELD(name);
-	);
-	/*! Default contact expiration if one is not provided in the contact */
-	int expiration;
-	/*! Domain for the AOR */
-	struct ast_sip_domain *domain;
-	/*! Contacts bound to this AOR */
-	AST_LIST_HEAD_NOLOCK(, ast_sip_contact) contacts;
 };
 
 /*!
@@ -209,31 +195,6 @@
 };
 
 /*!
- * \brief Given an endpoint, get its IP address
- *
- * \param endpoint The endpoint whose location is desired
- * \param[out] location_buf The IP address and port of the endpoint, as a string
- * \param size The size of the location buffer
- * \return void
- *
- * XXX The usefulness of retrieving an IP address is limited. It's more
- * useful to get a hostname or FQDN so that the location can be resolved.
- */
-void ast_sip_endpoint_get_location(const struct ast_sip_endpoint *endpoint, char *location_buf, size_t size);
-
-/*!
- * \brief Given an IP address, get the SIP endpoint that is located there.
- *
- * The returned endpoint will need to have its reference count decremented with ao2_ref()
- * once the caller has finished using it.
- *
- * \param addr The IP address
- * \retval NULL Could not find an endpoint with this IP address
- * \retval non-NULL The endpoint with this IP address
- */
-struct ast_sip_endpoint *ast_sip_get_endpoint_from_location(const char *addr);
- 
-/*!
  * \brief Data used for creating authentication challenges.
  * 
  * This data gets populated by an authenticator's get_authentication_credentials() callback.
@@ -448,6 +409,16 @@
 int ast_sip_initialize_sorcery_transport(struct ast_sorcery *sorcery);
 
 /*!
+ * \brief Initialize location support on a sorcery instance
+ *
+ * \param sorcery The sorcery instance
+ *
+ * \retval -1 failure
+ * \retval 0 success
+ */
+int ast_sip_initialize_sorcery_location(struct ast_sorcery *sorcery);
+
+/*!
  * \brief Create a new SIP work structure
  *
  * A SIP work is a means of grouping together SIP tasks. For instance, one
@@ -497,6 +468,19 @@
 	/*! The text to go in the body */
 	const char *body_text;
 };
+
+/*!
+ * \brief General purpose method for creating a dialog with an endpoint
+ *
+ * \param endpoint A pointer to the endpoint
+ * \param location_name Optional name of the location to target, may even be an explicit SIP URI
+ * \param request_user Optional user to place into the target URI
+ * \param selector Populated transport selector information, should be applied to dialog afterwards
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+ pjsip_dialog *ast_sip_create_dialog(const struct ast_sip_endpoint *endpoint, const char *location_name, const char *request_user, struct pjsip_tpselector *selector);
 
 /*!
  * \brief General purpose method for sending a SIP request

Modified: team/file/pimp_sip_location/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/include/asterisk/res_sip_session.h?view=diff&rev=381278&r1=381277&r2=381278
==============================================================================
--- team/file/pimp_sip_location/include/asterisk/res_sip_session.h (original)
+++ team/file/pimp_sip_location/include/asterisk/res_sip_session.h Tue Feb 12 12:08:30 2013
@@ -150,9 +150,10 @@
  * \brief Create a new outgoing SIP session
  *
  * \param endpoint The endpoint that this session uses for settings
- * \param uri The URI to call
- */
-struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *uri);
+ * \param location Optional name of the location to call, be it named location or explicit URI
+ * \param request_user Optional request user to place in the request URI if permitted
+ */
+struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user);
 
 /*!
  * \brief Register an SDP handler

Modified: team/file/pimp_sip_location/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/res/res_sip.c?view=diff&rev=381278&r1=381277&r2=381278
==============================================================================
--- team/file/pimp_sip_location/res/res_sip.c (original)
+++ team/file/pimp_sip_location/res/res_sip.c Tue Feb 12 12:08:30 2013
@@ -226,6 +226,134 @@
 	return ast_pjsip_endpoint;
 }
 
+static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *user, const pj_str_t *target, pjsip_tpselector *selector)
+{
+	pj_str_t tmp, local_addr;
+	pjsip_uri *uri;
+	pjsip_sip_uri *sip_uri;
+	pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
+	int local_port;
+
+	/* Parse the provided target URI so we can determine what transport it will end up using */
+	pj_strdup_with_null(pool, &tmp, target);
+
+	if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
+	    (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
+		return -1;
+	}
+
+	sip_uri = pjsip_uri_get_uri(uri);
+
+	/* Determine the transport type to use */
+	if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
+		type = PJSIP_TRANSPORT_TLS;
+	} else if (!sip_uri->transport_param.slen) {
+		type = PJSIP_TRANSPORT_UDP;
+	} else {
+		type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
+	}
+
+	if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
+		return -1;
+	}
+
+	/* If the host is IPv6 turn the transport into an IPv6 version */
+	if (pj_strchr(&sip_uri->host, ':')) {
+		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+	}
+
+	/* Get the local bound address for the transport that will be used when communicating with the provided URI */
+	if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), pool, type, selector,
+							      &local_addr, &local_port) != PJ_SUCCESS) {
+		return -1;
+	}
+
+	/* If IPv6 was not specified in the host but is in the transport, set the proper type */
+	if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
+		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
+	}
+
+	from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
+	from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
+				      "<%s:%s@%s%.*s%s:%d%s%s>",
+				      (pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) ? "sips" : "sip",
+				      user,
+				      (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
+				      (int)local_addr.slen,
+				      local_addr.ptr,
+				      (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
+				      local_port,
+				      (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
+				      (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
+
+	return 0;
+}
+
+
+
+pjsip_dialog *ast_sip_create_dialog(const struct ast_sip_endpoint *endpoint, const char *location_name, const char *request_user, pjsip_tpselector *selector)
+{
+	pj_str_t local_uri = pj_str("sip:temp at localhost"), remote_uri;
+	RAII_VAR(struct ast_sip_location *, location, NULL, ao2_cleanup);
+	pjsip_dialog *dlg = NULL;
+	const char *transport_name = endpoint->transport;
+	const pj_str_t HCONTACT = { "Contact", 7 };
+
+	/* Ensure no selector is used unless explicitly required */
+	selector->type = PJSIP_TPSELECTOR_NONE;
+
+	if (!ast_strlen_zero(location_name) && (location = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "location", location_name))) {
+		pj_cstr(&remote_uri, location->uri);
+		if (!ast_strlen_zero(location->transport)) {
+			transport_name = location->transport;
+		}
+	} else {
+		pj_cstr(&remote_uri, location_name);
+	}
+
+	if (pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, &remote_uri, NULL, &dlg) != PJ_SUCCESS) {
+		return NULL;
+	}
+
+	if (!ast_strlen_zero(transport_name)) {
+		RAII_VAR(struct ast_sip_transport *, transport, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name), ao2_cleanup);
+
+		if (!transport || !transport->state) {
+			pjsip_dlg_terminate(dlg);
+			return NULL;
+		}
+
+		if (transport->type == AST_SIP_TRANSPORT_UDP) {
+			selector->type = PJSIP_TPSELECTOR_TRANSPORT;
+			selector->u.transport = transport->state->transport;
+		} else if (transport->type == AST_SIP_TRANSPORT_TCP || transport->type == AST_SIP_TRANSPORT_TLS) {
+			selector->type = PJSIP_TPSELECTOR_LISTENER;
+			selector->u.listener = transport->state->factory;
+		} else {
+			pjsip_dlg_terminate(dlg);
+			return NULL;
+		}
+	}
+
+	if (sip_dialog_create_from(dlg->pool, &local_uri, "temp", &remote_uri, selector)) {
+		pjsip_dlg_terminate(dlg);
+		return NULL;
+	}
+
+	/* Update the dialog with the new local URI, we do it afterwards so we can use the dialog pool for construction */
+	pj_strdup_with_null(dlg->pool, &dlg->local.info_str, &local_uri);
+	dlg->local.info->uri = pjsip_parse_uri(dlg->pool, dlg->local.info_str.ptr, dlg->local.info_str.slen, 0);
+	dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, local_uri.ptr, local_uri.slen, NULL);
+
+	/* If a request user has been specified and we are permitted to change it, do so */
+	if (!ast_strlen_zero(request_user) && (PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target))) {
+		pjsip_sip_uri *target = pjsip_uri_get_uri(dlg->target);
+		pj_strdup2(dlg->pool, &target->user, request_user);
+	}
+
+	return dlg;
+}
+
 /* PJSIP doesn't know about the INFO method, so we have to define it ourselves */
 const pjsip_method pjsip_info_method = {PJSIP_OTHER_METHOD, {"INFO", 4} };
 

Modified: team/file/pimp_sip_location/res/res_sip.exports.in
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/res/res_sip.exports.in?view=diff&rev=381278&r1=381277&r2=381278
==============================================================================
--- team/file/pimp_sip_location/res/res_sip.exports.in (original)
+++ team/file/pimp_sip_location/res/res_sip.exports.in Tue Feb 12 12:08:30 2013
@@ -24,8 +24,7 @@
 		LINKER_SYMBOL_PREFIXast_sip_endpoint_alloc;
 		LINKER_SYMBOL_PREFIXast_copy_pj_str;
 		LINKER_SYMBOL_PREFIXast_sip_get_sorcery;
-		LINKER_SYMBOL_PREFIXast_sip_get_endpoint_from_location;
-		LINKER_SYMBOL_PREFIXast_sip_endpoint_get_location;
+		LINKER_SYMBOL_PREFIXast_sip_create_dialog;
 		LINKER_SYMBOL_PREFIXpj_*;
 		LINKER_SYMBOL_PREFIXpjsip_*;
 		LINKER_SYMBOL_PREFIXpjmedia_*;

Added: team/file/pimp_sip_location/res/res_sip/location.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/res/res_sip/location.c?view=auto&rev=381278
==============================================================================
--- team/file/pimp_sip_location/res/res_sip/location.c (added)
+++ team/file/pimp_sip_location/res/res_sip/location.c Tue Feb 12 12:08:30 2013
@@ -1,0 +1,69 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Joshua Colp <jcolp 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.
+ */
+
+#include "asterisk.h"
+#undef bzero
+#define bzero bzero
+#include "pjsip.h"
+#include "pjlib.h"
+
+#include "asterisk/res_sip.h"
+#include "asterisk/logger.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/sorcery.h"
+
+/*! \brief Destructor for location */
+ static void location_destroy(void *obj)
+ {
+ 	struct ast_sip_location *location = obj;
+
+ 	ast_string_field_free_memory(location);
+ }
+
+/*! \brief Allocator for location */
+static void *location_alloc(const char *name)
+{
+	struct ast_sip_location *location = ao2_alloc(sizeof(*location), location_destroy);
+
+	if (!location) {
+		return NULL;
+	}
+
+	if (ast_string_field_init(location, 256)) {
+		ao2_cleanup(location);
+		return NULL;
+	}
+
+	return location;
+}
+
+/*! \brief Initialize sorcery with location support */
+int ast_sip_initialize_sorcery_location(struct ast_sorcery *sorcery)
+{
+	ast_sorcery_apply_default(sorcery, "location", "config", "res_sip.conf,criteria=type=location");
+
+	if (ast_sorcery_object_register(sorcery, "location", location_alloc, NULL, NULL)) {
+		return -1;
+	}
+
+	ast_sorcery_object_field_register(sorcery, "location", "type", "", OPT_NOOP_T, 0, 0);
+	ast_sorcery_object_field_register(sorcery, "location", "uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_location, uri));
+	ast_sorcery_object_field_register(sorcery, "location", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_location, transport));
+
+	return 0;
+}

Propchange: team/file/pimp_sip_location/res/res_sip/location.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/file/pimp_sip_location/res/res_sip/location.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/file/pimp_sip_location/res/res_sip/location.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/file/pimp_sip_location/res/res_sip/sip_configuration.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/res/res_sip/sip_configuration.c?view=diff&rev=381278&r1=381277&r2=381278
==============================================================================
--- team/file/pimp_sip_location/res/res_sip/sip_configuration.c (original)
+++ team/file/pimp_sip_location/res/res_sip/sip_configuration.c Tue Feb 12 12:08:30 2013
@@ -21,17 +21,6 @@
 
 static struct ast_sorcery *sip_sorcery;
 
-/*!
- * \brief Structure used to map an IP address to an endpoint.
- *
- * This is useful for determining if an incoming request
- * is coming from a particular endpoint.
- */
-struct sip_location_to_endpoint {
-	SORCERY_OBJECT(details);
-	const char *endpoint_name;
-};
-
 static char *handle_cli_show_endpoints(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	RAII_VAR(struct ao2_container *, endpoints, NULL, ao2_cleanup);
@@ -72,71 +61,6 @@
 static struct ast_cli_entry cli_commands[] = {
 	AST_CLI_DEFINE(handle_cli_show_endpoints, "Show SIP Endpoints"),
 };
-
-static void sip_location_to_endpoint_destroy(void *obj)
-{
-	struct sip_location_to_endpoint *location_to_endpoint = obj;
-	ast_free((char *)location_to_endpoint->endpoint_name);
-}
-
-static void *sip_location_to_endpoint_alloc(const char *name)
-{
-	return ao2_alloc(sizeof(struct sip_location_to_endpoint), sip_location_to_endpoint_destroy);
-}
-/*!
- * \brief Structure used to map an endpoint name to its location
- *
- * Location is stored as a string so that a FQDN may be stored
- * and the location may be resolved.
- *
- * This is useful for determining the destination for an outgoing
- * request to a specific endpoint
- */
-struct sip_endpoint_to_location {
-	SORCERY_OBJECT(details);
-	const char *host;
-};
-
-static void sip_endpoint_to_location_destroy(void *obj)
-{
-	struct sip_endpoint_to_location *endpoint_to_location = obj;
-	ast_free((char *) endpoint_to_location->host);
-}
-
-static void *sip_endpoint_to_location_alloc(const char *name)
-{
-	return ao2_alloc(sizeof(struct sip_endpoint_to_location), sip_endpoint_to_location_destroy);
-}
-
-static int host_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
-{
-	RAII_VAR(struct sip_location_to_endpoint *, location_to_endpoint, NULL, ao2_cleanup);
-	RAII_VAR(struct sip_endpoint_to_location *, endpoint_to_location, NULL, ao2_cleanup);
-	const char *host = var->value;
-	const char *name = ast_sorcery_object_get_id(obj);
-
-	location_to_endpoint = ast_sorcery_alloc(sip_sorcery, "location_to_endpoint", host);
-	if (!location_to_endpoint) {
-		return -1;
-	}
-	endpoint_to_location = ast_sorcery_alloc(sip_sorcery, "endpoint_to_location", name);
-	if (!endpoint_to_location) {
-		return -1;
-	}
-
-	location_to_endpoint->endpoint_name = ast_strdup(name);
-	endpoint_to_location->host = ast_strdup(host);
-
-	if (ast_sorcery_create(sip_sorcery, location_to_endpoint)) {
-		return -1;
-	}
-	if (ast_sorcery_create(sip_sorcery, endpoint_to_location)) {
-		ast_sorcery_delete(sip_sorcery, location_to_endpoint);
-		return -1;
-	}
-
-	return 0;
-}
 
 static int dtmf_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
 {
@@ -207,25 +131,18 @@
 	ast_sorcery_apply_config(sip_sorcery, "res_sip");
 	ast_sorcery_apply_default(sip_sorcery, "endpoint", "config", "res_sip.conf,criteria=type=endpoint");
 
-	ast_sorcery_apply_default(sip_sorcery, "location_to_endpoint", "memory", NULL);
-	ast_sorcery_apply_default(sip_sorcery, "endpoint_to_location", "memory", NULL);
-
 	if (ast_sorcery_object_register(sip_sorcery, "endpoint", ast_sip_endpoint_alloc, NULL, NULL)) {
 		ast_log(LOG_ERROR, "Failed to register SIP endpoint object with sorcery\n");
 		ast_sorcery_unref(sip_sorcery);
 		sip_sorcery = NULL;
 		return -1;
 	}
-
-	ast_sorcery_object_register(sip_sorcery, "location_to_endpoint", sip_location_to_endpoint_alloc, NULL, NULL);
-	ast_sorcery_object_register(sip_sorcery, "endpoint_to_location", sip_endpoint_to_location_alloc, NULL, NULL);
 
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "type", "", OPT_NOOP_T, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "context", "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, context));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "disallow", "", OPT_CODEC_T, 0, FLDSET(struct ast_sip_endpoint, prefs, codecs));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow", "", OPT_CODEC_T, 1, FLDSET(struct ast_sip_endpoint, prefs, codecs));
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "qualify_frequency", 0, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_endpoint, qualify_frequency), 0, 86400);
-	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "host", "", host_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtmfmode", "rfc4733", dtmf_handler, NULL, 0, 0);
 	ast_sorcery_object_field_register(sip_sorcery, "endpoint", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, transport));
 	ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "100rel", "yes", prack_handler, NULL, 0, 0);
@@ -240,6 +157,13 @@
 		return -1;
 	}
 
+	if (ast_sip_initialize_sorcery_location(sip_sorcery)) {
+		ast_log(LOG_ERROR, "Failed to register SIP location support with sorcery\n");
+		ast_sorcery_unref(sip_sorcery);
+		sip_sorcery = NULL;
+		return -1;
+	}
+
 	ast_sorcery_load(sip_sorcery);
 
 	return 0;
@@ -291,30 +215,6 @@
 	return endpoint;
 }
 
-void ast_sip_endpoint_get_location(const struct ast_sip_endpoint *endpoint, char *location_buf, size_t size)
-{
-	struct sip_endpoint_to_location *endpoint_to_location;
-	endpoint_to_location = ast_sorcery_retrieve_by_id(sip_sorcery, "endpoint_to_location", ast_sorcery_object_get_id(endpoint));
-	if (!endpoint_to_location) {
-		return;
-	}
-	ast_copy_string(location_buf, endpoint_to_location->host, size);
-	ao2_ref(endpoint_to_location, -1);
-}
-
-struct ast_sip_endpoint *ast_sip_get_endpoint_from_location(const char *location)
-{
-	struct sip_location_to_endpoint *location_to_endpoint;
-	struct ast_sip_endpoint *endpoint;
-	location_to_endpoint = ast_sorcery_retrieve_by_id(sip_sorcery, "location_to_endpoint", location);
-	if (!location_to_endpoint) {
-		return NULL;
-	}
-	endpoint = ast_sorcery_retrieve_by_id(sip_sorcery, "endpoint", location_to_endpoint->endpoint_name);
-	ao2_ref(location_to_endpoint, -1);
-	return endpoint;
-}
-
 struct ao2_container *ast_res_sip_get_endpoints(void)
 {
 	struct ao2_container *endpoints;

Modified: team/file/pimp_sip_location/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/file/pimp_sip_location/res/res_sip_session.c?view=diff&rev=381278&r1=381277&r2=381278
==============================================================================
--- team/file/pimp_sip_location/res/res_sip_session.c (original)
+++ team/file/pimp_sip_location/res/res_sip_session.c Tue Feb 12 12:08:30 2013
@@ -478,113 +478,18 @@
 	return session;
 }
 
-static int sip_session_create_from(pj_pool_t *pool, pj_str_t *from, const char *user, const pj_str_t *target, pjsip_tpselector *selector)
-{
-	pj_str_t tmp, local_addr;
-	pjsip_uri *uri;
-	pjsip_sip_uri *sip_uri;
-	pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED;
-	int local_port;
-
-	/* Parse the provided target URI so we can determine what transport it will end up using */
-	pj_strdup_with_null(pool, &tmp, target);
-
-	if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
-	    (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
-		return -1;
-	}
-
-	sip_uri = pjsip_uri_get_uri(uri);
-
-	/* Determine the transport type to use */
-	if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
-		type = PJSIP_TRANSPORT_TLS;
-	} else if (!sip_uri->transport_param.slen) {
-		type = PJSIP_TRANSPORT_UDP;
-	} else {
-		type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
-	}
-
-	if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
-		return -1;
-	}
-
-	/* If the host is IPv6 turn the transport into an IPv6 version */
-	if (pj_strchr(&sip_uri->host, ':')) {
-		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
-	}
-
-	/* Get the local bound address for the transport that will be used when communicating with the provided URI */
-	if (pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(ast_sip_get_pjsip_endpoint()), pool, type, selector,
-							      &local_addr, &local_port) != PJ_SUCCESS) {
-		return -1;
-	}
-
-	/* If IPv6 was not specified in the host but is in the transport, set the proper type */
-	if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
-		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
-	}
-
-	from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
-	from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
-				      "<%s:%s@%s%.*s%s:%d%s%s>",
-				      (pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE) ? "sips" : "sip",
-				      user,
-				      (type & PJSIP_TRANSPORT_IPV6) ? "[" : "",
-				      (int)local_addr.slen,
-				      local_addr.ptr,
-				      (type & PJSIP_TRANSPORT_IPV6) ? "]" : "",
-				      local_port,
-				      (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
-				      (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
-
-	return 0;
-}
-
-struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *uri)
-{
-	pj_str_t local_uri = pj_str("sip:temp at localhost"), remote_uri = pj_str((char*)uri);
+struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user)
+{
+	pjsip_tpselector selector;
 	pjsip_dialog *dlg = NULL;
-	const pj_str_t HCONTACT = { "Contact", 7 };
 	pjsip_inv_session *inv_session = NULL;
 	struct ast_sip_session *session = NULL;
 	pjmedia_sdp_session *offer = NULL;
-	pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
 	pjsip_timer_setting timer;
 
-	if (pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri, NULL, &remote_uri, NULL, &dlg) != PJ_SUCCESS) {
-		return NULL;
-	}
-
-	if (!ast_strlen_zero(endpoint->transport)) {
-		RAII_VAR(struct ast_sip_transport *, transport, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", endpoint->transport), ao2_cleanup);
-
-		if (!transport || !transport->state) {
-			pjsip_dlg_terminate(dlg);
-			return NULL;
-		}
-
-		if (transport->type == AST_SIP_TRANSPORT_UDP) {
-			selector.type = PJSIP_TPSELECTOR_TRANSPORT;
-			selector.u.transport = transport->state->transport;
-		} else if (transport->type == AST_SIP_TRANSPORT_TCP || transport->type == AST_SIP_TRANSPORT_TLS) {
-			selector.type = PJSIP_TPSELECTOR_LISTENER;
-			selector.u.listener = transport->state->factory;
-		} else {
-			pjsip_dlg_terminate(dlg);
-			return NULL;
-		}
-	}
-
-	if (sip_session_create_from(dlg->pool, &local_uri, "test", &remote_uri, &selector)) {
-		pjsip_dlg_terminate(dlg);
-		return NULL;
-	}
-
-	/* Update the dialog with the new local URI, we do it afterwards so we can use the dialog pool for construction */
-	pj_strdup_with_null(dlg->pool, &dlg->local.info_str, &local_uri);
-	dlg->local.info->uri = pjsip_parse_uri(dlg->pool, dlg->local.info_str.ptr, dlg->local.info_str.slen, 0);
-	dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, local_uri.ptr, local_uri.slen, NULL);
+	if (!(dlg = ast_sip_create_dialog(endpoint, location, request_user, &selector))) {
+		return NULL;
+	}
 
 	if (pjsip_inv_create_uac(dlg, NULL, endpoint->extensions, &inv_session) != PJ_SUCCESS) {
 		pjsip_dlg_terminate(dlg);
@@ -597,7 +502,7 @@
 	timer.min_se = endpoint->min_se;
 	timer.sess_expires = endpoint->sess_expires;
 	pjsip_timer_init_session(inv_session, &timer);
-	
+
 	if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
 		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
 		return NULL;




More information about the asterisk-commits mailing list