[asterisk-commits] file: branch file/pimp_sip_location r381426 - in /team/file/pimp_sip_location...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Feb 14 10:47:35 CST 2013
Author: file
Date: Thu Feb 14 10:47:31 2013
New Revision: 381426
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381426
Log:
Flush out more of the location AOR/contact stuff!
1. You can now specify static contacts on a per-AOR basis
2. Retrieving contacts for an AOR now works and takes into account contact expiration
3. Contacts can now be added to an AOR programatically
Now moving on to test some more stuff, and use it in res_sip/res_sip_session.
Modified:
team/file/pimp_sip_location/include/asterisk/res_sip.h
team/file/pimp_sip_location/res/res_sip.c
team/file/pimp_sip_location/res/res_sip/location.c
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=381426&r1=381425&r2=381426
==============================================================================
--- team/file/pimp_sip_location/include/asterisk/res_sip.h (original)
+++ team/file/pimp_sip_location/include/asterisk/res_sip.h Thu Feb 14 10:47:31 2013
@@ -136,28 +136,8 @@
unsigned int default_expiration;
/*! Maximum number of external contacts, 0 to disable */
unsigned int max_contacts;
-};
-
-/*!
- * \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(
- /*! Full URI of the location */
- AST_STRING_FIELD(uri);
- /*! Optional explicit transport to use */
- AST_STRING_FIELD(transport);
- /*! Outbound proxy to use */
- AST_STRING_FIELD(outbound_proxy);
- );
- /*! Whether the user portion of the request URI is permitted to be changed or not */
- unsigned int change_user;
- /*! Whether the URI of this location can be updated/changed or not */
- unsigned int update;
- /*! Absolute time that this location is valid until */
- struct timeval expiration;
+ /*! Any statically configured contacts */
+ struct ao2_container *static_contacts;
};
/*!
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=381426&r1=381425&r2=381426
==============================================================================
--- team/file/pimp_sip_location/res/res_sip.c (original)
+++ team/file/pimp_sip_location/res/res_sip.c Thu Feb 14 10:47:31 2013
@@ -294,23 +294,14 @@
pjsip_dialog *ast_sip_create_dialog(const struct ast_sip_endpoint *endpoint, const char *location_name, const char *request_user)
{
pj_str_t local_uri = pj_str("sip:temp at localhost"), remote_uri;
- RAII_VAR(struct ast_sip_location *, location, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
+ RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
pjsip_dialog *dlg = NULL;
const char *transport_name = endpoint->transport, *outbound_proxy = endpoint->outbound_proxy;
pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
const pj_str_t HCONTACT = { "Contact", 7 };
- if (!ast_strlen_zero(location_name) && (location = NULL)) {
- pj_cstr(&remote_uri, location->uri);
- if (!ast_strlen_zero(location->transport)) {
- transport_name = location->transport;
- }
- if (!ast_strlen_zero(location->outbound_proxy)) {
- outbound_proxy = location->outbound_proxy;
- }
- } else {
- pj_cstr(&remote_uri, location_name);
- }
+ 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;
@@ -347,8 +338,7 @@
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) && (!location || location->change_user) &&
- (PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target))) {
+ 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);
}
Modified: 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=diff&rev=381426&r1=381425&r2=381426
==============================================================================
--- team/file/pimp_sip_location/res/res_sip/location.c (original)
+++ team/file/pimp_sip_location/res/res_sip/location.c Thu Feb 14 10:47:31 2013
@@ -27,10 +27,18 @@
#include "asterisk/astobj2.h"
#include "asterisk/sorcery.h"
+/*! \brief Destructor for AOR */
+static void aor_destroy(void *obj)
+{
+ struct ast_sip_aor *aor = obj;
+
+ ao2_cleanup(aor->static_contacts);
+}
+
/*! \brief Allocator for AOR */
static void *aor_alloc(const char *name)
{
- struct ast_sip_aor *aor = ao2_alloc(sizeof(*aor), NULL);
+ struct ast_sip_aor *aor = ao2_alloc_options(sizeof(*aor), aor_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
if (!aor) {
return NULL;
@@ -50,7 +58,7 @@
/*! \brief Allocator for contact */
static void *contact_alloc(const char *name)
{
- struct ast_sip_contact *contact = ao2_alloc(sizeof(*contact), contact_destroy);
+ struct ast_sip_contact *contact = ao2_alloc_options(sizeof(*contact), contact_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
if (!contact) {
return NULL;
@@ -69,9 +77,49 @@
return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", aor_name);
}
+/*! \brief Internal callback function which deletes and unlinks any expired contacts */
+static int contact_expire(void *obj, void *arg, int flags)
+{
+ struct ast_sip_contact *contact = obj;
+
+ /* If the contact has not yet expired it is valid */
+ if (ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) > 0) {
+ return 0;
+ }
+
+ ast_sip_location_delete_contact(contact);
+
+ return CMP_MATCH;
+}
+
+/*! \brief Internal callback function which links static contacts into another container */
+static int contact_link_static(void *obj, void *arg, int flags)
+{
+ struct ao2_container *dest = arg;
+
+ ao2_link_flags(dest, obj, OBJ_NOLOCK);
+ return 0;
+}
+
struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
{
- return NULL;
+ /* Give enough space for ^ at the beginning and - at the end, since that is our object naming scheme */
+ char regex[strlen(ast_sorcery_object_get_id(aor)) + 3];
+ struct ao2_container *contacts;
+
+ snprintf(regex, sizeof(regex), "^%s-", ast_sorcery_object_get_id(aor));
+
+ if (!(contacts = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "contact", regex))) {
+ return NULL;
+ }
+
+ /* Prune any expired contacts and delete them, we do this first because static contacts can never expire */
+ ao2_callback(contacts, OBJ_NOLOCK | OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, contact_expire, NULL);
+
+ /* Add any static contacts from the AOR */
+ ao2_callback(aor->static_contacts, OBJ_NOLOCK | OBJ_NODATA, contact_link_static, contacts);
+
+ return contacts;
}
struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_name)
@@ -81,7 +129,19 @@
int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time)
{
- return -1;
+ char name[AST_UUID_STR_LEN];
+ RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+
+ snprintf(name, sizeof(name), "%s-%s", ast_sorcery_object_get_id(aor), uri);
+
+ if (!(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name))) {
+ return -1;
+ }
+
+ ast_string_field_set(contact, uri, uri);
+ contact->expiration_time = expiration_time;
+
+ return ast_sorcery_create(ast_sip_get_sorcery(), contact);
}
int ast_sip_location_update_contact(struct ast_sip_contact *contact)
@@ -106,6 +166,23 @@
{
const struct ast_sip_contact *contact = obj;
return (ast_asprintf(buf, "%lu", contact->expiration_time.tv_sec) < 0) ? -1 : 0;
+}
+
+/*! \brief Custom handler for static URIs */
+static int static_uri_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+ struct ast_sip_aor *aor = obj;
+ RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
+
+ if ((!aor->static_contacts && !(aor->static_contacts = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL))) ||
+ !(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", NULL))) {
+ return -1;
+ }
+
+ ast_string_field_set(contact, uri, var->value);
+ ao2_link_flags(aor->static_contacts, contact, OBJ_NOLOCK);
+
+ return 0;
}
/*! \brief Initialize sorcery with location support */
@@ -126,6 +203,7 @@
ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0);
ast_sorcery_object_field_register(sorcery, "aor", "default_expiration", "3600", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, default_expiration));
ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
+ ast_sorcery_object_field_register_custom(sorcery, "aor", "static", "", static_uri_handler, NULL, 0, 0);
return 0;
}
More information about the asterisk-commits
mailing list