Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Functions | Variables
location.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include <pjlib.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/logger.h"
#include "asterisk/astobj2.h"
#include "asterisk/paths.h"
#include "asterisk/sorcery.h"
#include "asterisk/taskprocessor.h"
#include "include/res_pjsip_private.h"
#include "asterisk/res_pjsip_cli.h"
#include "asterisk/statsd.h"
#include "asterisk/named_locks.h"
#include "asterisk/res_pjproject.h"
Include dependency graph for location.c:

Go to the source code of this file.

Functions

static int ami_show_aors (struct mansession *s, const struct message *m)
 
static void * aor_alloc (const char *name)
 Allocator for AOR. More...
 
static int aor_apply_handler (const struct ast_sorcery *sorcery, void *object)
 
static int aor_apply_outbound_proxy (void *obj, void *arg, int flags)
 
static void aor_deleted_observer (const void *object)
 
static void aor_destroy (void *obj)
 Destructor for AOR. More...
 
int ast_sip_contact_to_str (void *object, void *arg, int flags)
 Handler used to convert a contact to a string. More...
 
int ast_sip_destroy_sorcery_location (void)
 
int ast_sip_for_each_aor (const char *aors, ao2_callback_fn on_aor, void *arg)
 For every aor in the comma separated aors string call the given 'on_aor' handler. More...
 
int ast_sip_for_each_contact (const struct ast_sip_aor *aor, ao2_callback_fn on_contact, void *arg)
 For every contact on an AOR call the given 'on_contact' handler. More...
 
int ast_sip_initialize_sorcery_location (void)
 Initialize sorcery with location support. More...
 
int ast_sip_location_add_contact (struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time, const char *path_info, const char *user_agent, const char *via_addr, int via_port, const char *call_id, struct ast_sip_endpoint *endpoint)
 Add a new contact to an AOR. More...
 
int ast_sip_location_add_contact_nolock (struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time, const char *path_info, const char *user_agent, const char *via_addr, int via_port, const char *call_id, struct ast_sip_endpoint *endpoint)
 Add a new contact to an AOR without locking the AOR. More...
 
struct ast_sip_contactast_sip_location_create_contact (struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time, const char *path_info, const char *user_agent, const char *via_addr, int via_port, const char *call_id, int prune_on_boot, struct ast_sip_endpoint *endpoint)
 Create a new contact for an AOR without locking the AOR. More...
 
int ast_sip_location_delete_contact (struct ast_sip_contact *contact)
 Delete a contact. More...
 
void ast_sip_location_prune_boot_contacts (void)
 Prune the prune_on_boot contacts. More...
 
struct ast_sip_aorast_sip_location_retrieve_aor (const char *aor_name)
 Retrieve a named AOR. More...
 
struct ao2_containerast_sip_location_retrieve_aor_contacts (const struct ast_sip_aor *aor)
 Retrieve all contacts currently available for an AOR. More...
 
struct ao2_containerast_sip_location_retrieve_aor_contacts_filtered (const struct ast_sip_aor *aor, unsigned int flags)
 Retrieve all contacts currently available for an AOR and filter based on flags. More...
 
struct ao2_containerast_sip_location_retrieve_aor_contacts_nolock (const struct ast_sip_aor *aor)
 Retrieve all contacts currently available for an AOR without locking the AOR. More...
 
struct ao2_containerast_sip_location_retrieve_aor_contacts_nolock_filtered (const struct ast_sip_aor *aor, unsigned int flags)
 Retrieve all contacts currently available for an AOR without locking the AOR and filter based on flags. More...
 
struct ast_sip_contactast_sip_location_retrieve_contact (const char *contact_name)
 Retrieve a named contact. More...
 
void ast_sip_location_retrieve_contact_and_aor_from_list (const char *aor_list, struct ast_sip_aor **aor, struct ast_sip_contact **contact)
 Retrieve the first bound contact AND the AOR chosen from a list of AORs. More...
 
void ast_sip_location_retrieve_contact_and_aor_from_list_filtered (const char *aor_list, unsigned int flags, struct ast_sip_aor **aor, struct ast_sip_contact **contact)
 Retrieve the first bound contact AND the AOR chosen from a list of AORs and filter based on flags. More...
 
struct ast_sip_contactast_sip_location_retrieve_contact_from_aor_list (const char *aor_list)
 Retrieve the first bound contact from a list of AORs. More...
 
struct ao2_containerast_sip_location_retrieve_contacts_from_aor_list (const char *aor_list)
 Retrieve all contacts from a list of AORs. More...
 
struct ast_sip_contactast_sip_location_retrieve_first_aor_contact (const struct ast_sip_aor *aor)
 Retrieve the first bound contact for an AOR. More...
 
struct ast_sip_contactast_sip_location_retrieve_first_aor_contact_filtered (const struct ast_sip_aor *aor, unsigned int flags)
 Retrieve the first bound contact for an AOR and filter based on flags. More...
 
int ast_sip_location_update_contact (struct ast_sip_contact *contact)
 Update a contact. More...
 
int ast_sip_validate_uri_length (const char *contact_uri)
 
static int cli_aor_gather_contacts (void *obj, void *arg, int flags)
 
static struct ao2_containercli_aor_get_container (const char *regex)
 
static const char * cli_aor_get_id (const void *obj)
 
static int cli_aor_iterate (void *container, ao2_callback_fn callback, void *args)
 
static int cli_aor_print_body (void *obj, void *arg, int flags)
 
static int cli_aor_print_header (void *obj, void *arg, int flags)
 
static void * cli_aor_retrieve_by_id (const char *id)
 
static int cli_contact_compare (void *obj, void *arg, int flags)
 
static struct ao2_containercli_contact_get_container (const char *regex)
 
static const char * cli_contact_get_id (const void *obj)
 
static int cli_contact_iterate (void *container, ao2_callback_fn callback, void *args)
 
static int cli_contact_populate_container (void *obj, void *arg, int flags)
 
static int cli_contact_print_body (void *obj, void *arg, int flags)
 
static int cli_contact_print_header (void *obj, void *arg, int flags)
 
static void * cli_contact_retrieve_by_id (const char *id)
 
static int cli_contact_sort (const void *obj, const void *arg, int flags)
 
static int cli_filter_contacts (void *obj, void *arg, int flags)
 
static int cli_gather_contact (void *obj, void *arg, int flags)
 
static struct ao2_containercli_get_aors (void)
 
static void * contact_alloc (const char *name)
 Allocator for contact. More...
 
static int contact_apply_handler (const struct ast_sorcery *sorcery, void *object)
 Always create a contact_status for each contact. More...
 
static void contact_destroy (void *obj)
 Destructor for contact. More...
 
static int contact_expire (void *obj, void *arg, int flags)
 Internal callback function which deletes and unlinks any expired contacts. More...
 
static int contact_link_static (void *obj, void *arg, int flags)
 Internal callback function which links static contacts into another container. More...
 
static int contact_remove_unreachable (void *obj, void *arg, int flags)
 Internal callback function which removes any contact which is unreachable. More...
 
static int contact_to_var_list (void *object, void *arg, int flags)
 
static void contact_wrapper_destroy (void *obj)
 
static int contacts_to_str (const void *obj, const intptr_t *args, char **buf)
 
static int contacts_to_var_list (const void *obj, struct ast_variable **fields)
 
static int destroy_contact (void *obj, void *arg, int flags)
 Internal callback function which destroys the specified contact. More...
 
static int expiration_str2struct (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for translating from a string timeval to actual structure. More...
 
static int expiration_struct2str (const void *obj, const intptr_t *args, char **buf)
 Custom handler for translating from an actual structure timeval to string. More...
 
static int format_ami_aor_handler (void *obj, void *arg, int flags)
 
static int format_ami_aorlist_handler (void *obj, void *arg, int flags)
 
static int format_ami_endpoint_aor (const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)
 
static int gather_contacts_for_aor (void *obj, void *arg, int flags)
 
static int permanent_uri_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for permanent URIs. More...
 
static int permanent_uri_sort_fn (const void *obj_left, const void *obj_right, int flags)
 
static int prune_boot_contacts_cb (void *obj, void *arg, int flags)
 
static int sip_aor_to_ami (const struct ast_sip_aor *aor, struct ast_str **buf)
 
static int voicemail_extension_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int voicemail_extension_to_str (const void *obj, const intptr_t *args, char **buf)
 

Variables

struct ast_sip_cli_formatter_entryaor_formatter
 
static const struct ast_sorcery_observer aor_observer
 Observer for contacts so state can be updated on respective endpoints. More...
 
static struct ast_cli_entry cli_commands []
 
struct ast_sip_cli_formatter_entrycontact_formatter
 
struct ast_sip_endpoint_formatter endpoint_aor_formatter
 
static int pj_max_hostname = PJ_MAX_HOSTNAME
 
static int pjsip_max_url_size = PJSIP_MAX_URL_SIZE
 

Function Documentation

◆ ami_show_aors()

static int ami_show_aors ( struct mansession s,
const struct message m 
)
static

Definition at line 1269 of file location.c.

1270{
1271 struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
1272 struct ao2_container *aors;
1273
1274 aors = cli_get_aors();
1275 if (!aors) {
1276 astman_send_error(s, m, "Could not get AORs\n");
1277 return 0;
1278 }
1279
1280 if (!ao2_container_count(aors)) {
1281 astman_send_error(s, m, "No AORs found\n");
1282 ao2_ref(aors, -1);
1283 return 0;
1284 }
1285
1286 astman_send_listack(s, m, "A listing of AORs follows, presented as AorList events",
1287 "start");
1288
1290
1291 astman_send_list_complete_start(s, m, "AorListComplete", ami.count);
1293
1294 ao2_ref(aors, -1);
1295
1296 return 0;
1297}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ OBJ_NODATA
Definition: astobj2.h:1044
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:2028
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1986
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:2064
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2072
static int format_ami_aorlist_handler(void *obj, void *arg, int flags)
Definition: location.c:1248
static struct ao2_container * cli_get_aors(void)
Definition: location.c:1238
Generic container type.
AMI variable container.
Definition: res_pjsip.h:3200
struct mansession * s
Definition: res_pjsip.h:3202
const struct message * m
Definition: res_pjsip.h:3204

References ao2_callback, ao2_container_count(), ao2_ref, astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), cli_get_aors(), ast_sip_ami::count, format_ami_aorlist_handler(), ast_sip_ami::m, OBJ_NODATA, and ast_sip_ami::s.

Referenced by ast_sip_initialize_sorcery_location().

◆ aor_alloc()

static void * aor_alloc ( const char *  name)
static

Allocator for AOR.

Definition at line 50 of file location.c.

51{
52 void *lock;
53 struct ast_sip_aor *aor;
54
56 if (!lock) {
57 return NULL;
58 }
59
61 ao2_ref(lock, -1);
62
63 if (!aor) {
64 return NULL;
65 }
66 ast_string_field_init(aor, 128);
67
68 return aor;
69}
ast_mutex_t lock
Definition: app_sla.c:337
static const char name[]
Definition: format_mp3.c:68
#define ast_named_lock_get(lock_type, keyspace, key)
Geta named lock handle.
Definition: named_locks.h:83
@ AST_NAMED_LOCK_TYPE_MUTEX
Definition: named_locks.h:59
static void aor_destroy(void *obj)
Destructor for AOR.
Definition: location.c:40
#define NULL
Definition: resample.c:96
void * ast_sorcery_lockable_alloc(size_t size, ao2_destructor_fn destructor, void *lockobj)
Allocate a generic sorcery capable object with locking.
Definition: sorcery.c:1712
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
A SIP address of record.
Definition: res_pjsip.h:478

References ao2_ref, aor_destroy(), ast_named_lock_get, AST_NAMED_LOCK_TYPE_MUTEX, ast_sorcery_lockable_alloc(), ast_string_field_init, lock, name, and NULL.

Referenced by ast_sip_initialize_sorcery_location().

◆ aor_apply_handler()

static int aor_apply_handler ( const struct ast_sorcery sorcery,
void *  object 
)
static

Definition at line 1361 of file location.c.

1362{
1363 struct ast_sip_aor *aor = object;
1364
1366 return 0;
1367 }
1368
1370
1371 return 0;
1372}
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
static int aor_apply_outbound_proxy(void *obj, void *arg, int flags)
Definition: location.c:1351
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
struct ao2_container * permanent_contacts
Definition: res_pjsip.h:502
const ast_string_field outbound_proxy
Definition: res_pjsip.h:486

References ao2_callback, aor_apply_outbound_proxy(), ast_strlen_zero(), OBJ_MULTIPLE, OBJ_NODATA, ast_sip_aor::outbound_proxy, and ast_sip_aor::permanent_contacts.

Referenced by ast_sip_initialize_sorcery_location().

◆ aor_apply_outbound_proxy()

static int aor_apply_outbound_proxy ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1351 of file location.c.

1352{
1353 struct ast_sip_contact *contact = obj;
1354 struct ast_sip_aor *aor = arg;
1355
1357
1358 return 0;
1359}
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
Contact associated with an address of record.
Definition: res_pjsip.h:390

References ast_string_field_set, and ast_sip_aor::outbound_proxy.

Referenced by aor_apply_handler().

◆ aor_deleted_observer()

static void aor_deleted_observer ( const void *  object)
static

Definition at line 81 of file location.c.

82{
83 const struct ast_sip_aor *aor = object;
84 const char *aor_id = ast_sorcery_object_get_id(object);
85 /* Give enough space for ;@ at the end, since that is our object naming scheme */
86 size_t prefix_len = strlen(aor_id) + sizeof(";@") - 1;
87 char prefix[prefix_len + 1];
88 struct ao2_container *contacts;
89
90 if (aor->permanent_contacts) {
92 }
93
94 sprintf(prefix, "%s;@", aor_id); /* Safe */
95 if (!(contacts = ast_sorcery_retrieve_by_prefix(ast_sip_get_sorcery(), "contact", prefix, prefix_len))) {
96 return;
97 }
98 /* Destroy any contacts that may still exist that were made for this AoR */
100
101 ao2_ref(contacts, -1);
102}
@ OBJ_UNLINK
Definition: astobj2.h:1039
static char prefix[MAX_PREFIX]
Definition: http.c:144
static int destroy_contact(void *obj, void *arg, int flags)
Internal callback function which destroys the specified contact.
Definition: location.c:72
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2317
struct ao2_container * ast_sorcery_retrieve_by_prefix(const struct ast_sorcery *sorcery, const char *type, const char *prefix, const size_t prefix_len)
Retrieve multiple objects whose id begins with the specified prefix.
Definition: sorcery.c:1989

References ao2_callback, ao2_ref, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_prefix(), destroy_contact(), NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, ast_sip_aor::permanent_contacts, and prefix.

◆ aor_destroy()

static void aor_destroy ( void *  obj)
static

Destructor for AOR.

Definition at line 40 of file location.c.

41{
42 struct ast_sip_aor *aor = obj;
43
47}
#define ast_free(a)
Definition: astmm.h:180
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
char * voicemail_extension
Definition: res_pjsip.h:508

References ao2_cleanup, ast_free, ast_string_field_free_memory, ast_sip_aor::permanent_contacts, and ast_sip_aor::voicemail_extension.

Referenced by aor_alloc().

◆ ast_sip_contact_to_str()

int ast_sip_contact_to_str ( void *  object,
void *  arg,
int  flags 
)

Handler used to convert a contact to a string.

Parameters
objectthe ast_sip_aor_contact_pair containing a list of contacts to iterate and the contact
arguser data passed to handler
flags
Return values
0Success, non-zero on failure

Definition at line 771 of file location.c.

772{
773 struct ast_sip_contact_wrapper *wrapper = object;
774 struct ast_str **buf = arg;
775
776 ast_str_append(buf, 0, "%s,", wrapper->contact_id);
777
778 return 0;
779}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
A wrapper for contact that adds the aor_id and a consistent contact id. Used by ast_sip_for_each_cont...
Definition: res_pjsip.h:519
Support for dynamic strings.
Definition: strings.h:623

References ast_str_append(), buf, and ast_sip_contact_wrapper::contact_id.

Referenced by contacts_to_str(), sip_contact_to_str(), and sip_endpoints_aors_ami().

◆ ast_sip_destroy_sorcery_location()

int ast_sip_destroy_sorcery_location ( void  )

Definition at line 1479 of file location.c.

1480{
1485 ast_manager_unregister("PJSIPShowAors");
1486
1488
1489 return 0;
1490}
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7697
static struct ast_cli_entry cli_commands[]
Definition: location.c:1299
static const struct ast_sorcery_observer aor_observer
Observer for contacts so state can be updated on respective endpoints.
Definition: location.c:105
struct ast_sip_cli_formatter_entry * contact_formatter
Definition: location.c:1331
struct ast_sip_cli_formatter_entry * aor_formatter
Definition: location.c:1332
struct ast_sip_endpoint_formatter endpoint_aor_formatter
Definition: location.c:879
void ast_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Unregister an endpoint formatter.
Definition: res_pjsip.c:487
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
Definition: pjsip_cli.c:326
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
Definition: sorcery.c:2423
#define ARRAY_LEN(a)
Definition: utils.h:666

References aor_formatter, aor_observer, ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), ast_sip_get_sorcery(), ast_sip_unregister_cli_formatter(), ast_sip_unregister_endpoint_formatter(), ast_sorcery_observer_remove(), cli_commands, contact_formatter, and endpoint_aor_formatter.

Referenced by ast_res_pjsip_destroy_configuration().

◆ ast_sip_for_each_aor()

int ast_sip_for_each_aor ( const char *  aors,
ao2_callback_fn  on_aor,
void *  arg 
)

For every aor in the comma separated aors string call the given 'on_aor' handler.

Parameters
aorsa comma separated list of aors
on_aorcallback for each aor
arguser data passed to handler
Return values
0Success, non-zero on failure

Definition at line 688 of file location.c.

689{
690 char *copy;
691 char *name;
692 int res;
693
694 if (!on_aor || ast_strlen_zero(aors)) {
695 return 0;
696 }
697
698 copy = ast_strdupa(aors);
699 while ((name = ast_strip(strsep(&copy, ",")))) {
700 struct ast_sip_aor *aor;
701
703 if (aor) {
704 res = on_aor(aor, arg, 0);
705 ao2_ref(aor, -1);
706 if (res) {
707 return -1;
708 }
709 }
710 }
711 return 0;
712}
static int copy(char *infile, char *outfile)
Utility function to copy a file.
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
Definition: location.c:147
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223

References ao2_ref, ast_sip_location_retrieve_aor(), ast_strdupa, ast_strip(), ast_strlen_zero(), copy(), name, and strsep().

Referenced by ami_registrations_endpoint(), ast_sip_location_retrieve_contacts_from_aor_list(), cli_aor_iterate(), format_ami_contact_status(), format_ami_endpoint_aor(), format_ami_endpoints(), mwi_new_subscribe(), and mwi_subscribe_all().

◆ ast_sip_for_each_contact()

int ast_sip_for_each_contact ( const struct ast_sip_aor aor,
ao2_callback_fn  on_contact,
void *  arg 
)

For every contact on an AOR call the given 'on_contact' handler.

Parameters
aorthe aor containing a list of contacts to iterate
on_contactcallback on each contact on an AOR. The object received by the callback will be a ast_sip_contact_wrapper structure.
arguser data passed to handler
Return values
0Success, non-zero on failure

Definition at line 723 of file location.c.

725{
726 struct ao2_container *contacts;
727 struct ao2_iterator i;
728 int res = 0;
729 void *object = NULL;
730
731 if (!on_contact ||
732 !(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
733 return 0;
734 }
735
736 i = ao2_iterator_init(contacts, 0);
737 while ((object = ao2_iterator_next(&i))) {
738 RAII_VAR(struct ast_sip_contact *, contact, object, ao2_cleanup);
740 const char *aor_id = ast_sorcery_object_get_id(aor);
741
742 wrapper = ao2_alloc_options(sizeof(struct ast_sip_contact_wrapper),
744 if (!wrapper) {
745 res = -1;
746 break;
747 }
748 wrapper->contact_id = ast_malloc(strlen(aor_id) + strlen(contact->uri) + 2);
749 if (!wrapper->contact_id) {
750 res = -1;
751 break;
752 }
753 sprintf(wrapper->contact_id, "%s/%s", aor_id, contact->uri);
754 wrapper->aor_id = ast_strdup(aor_id);
755 if (!wrapper->aor_id) {
756 res = -1;
757 break;
758 }
759 wrapper->contact = contact;
760 ao2_bump(wrapper->contact);
761
762 if ((res = on_contact(wrapper, arg, 0))) {
763 break;
764 }
765 }
767 ao2_ref(contacts, -1);
768 return res;
769}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static void contact_wrapper_destroy(void *obj)
Definition: location.c:714
struct ao2_container * ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
Retrieve all contacts currently available for an AOR.
Definition: location.c:247
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_bump, ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_malloc, ast_sip_location_retrieve_aor_contacts(), ast_sorcery_object_get_id(), ast_strdup, contact_wrapper_destroy(), NULL, and RAII_VAR.

Referenced by ami_registrations_aor(), cli_aor_gather_contacts(), cli_contact_iterate(), contacts_to_str(), contacts_to_var_list(), format_contact_status_for_aor(), and sip_endpoints_aors_ami().

◆ ast_sip_initialize_sorcery_location()

int ast_sip_initialize_sorcery_location ( void  )

Initialize sorcery with location support.

Definition at line 1375 of file location.c.

1376{
1378 int i;
1379
1380 ast_pjproject_get_buildopt("PJ_MAX_HOSTNAME", "%d", &pj_max_hostname);
1381 /* As of pjproject 2.4.5, PJSIP_MAX_URL_SIZE isn't exposed yet but we try anyway. */
1382 ast_pjproject_get_buildopt("PJSIP_MAX_URL_SIZE", "%d", &pjsip_max_url_size);
1383
1384 ast_sorcery_apply_default(sorcery, "contact", "astdb", "registrar");
1387 ast_sorcery_apply_default(sorcery, "aor", "config", "pjsip.conf,criteria=type=aor");
1388
1391 return -1;
1392 }
1393
1395
1396 ast_sorcery_object_field_register(sorcery, "contact", "type", "", OPT_NOOP_T, 0, 0);
1398 ast_sorcery_object_field_register(sorcery, "contact", "path", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, path));
1400 ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
1401 PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
1402 ast_sorcery_object_field_register(sorcery, "contact", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_contact, qualify_timeout));
1403 ast_sorcery_object_field_register(sorcery, "contact", "qualify_2xx_only", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_contact, qualify_2xx_only));
1404 ast_sorcery_object_field_register(sorcery, "contact", "authenticate_qualify", "no", OPT_YESNO_T, 1, FLDSET(struct ast_sip_contact, authenticate_qualify));
1405 ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
1406 ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent));
1407 ast_sorcery_object_field_register(sorcery, "contact", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, endpoint_name));
1408 ast_sorcery_object_field_register(sorcery, "contact", "reg_server", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, reg_server));
1409 ast_sorcery_object_field_register(sorcery, "contact", "via_addr", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, via_addr));
1410 ast_sorcery_object_field_register(sorcery, "contact", "via_port", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_contact, via_port));
1411 ast_sorcery_object_field_register(sorcery, "contact", "call_id", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, call_id));
1412 ast_sorcery_object_field_register(sorcery, "contact", "prune_on_boot", "no", OPT_YESNO_T, 1, FLDSET(struct ast_sip_contact, prune_on_boot));
1413
1414 ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0);
1415 ast_sorcery_object_field_register(sorcery, "aor", "minimum_expiration", "60", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, minimum_expiration));
1416 ast_sorcery_object_field_register(sorcery, "aor", "maximum_expiration", "7200", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, maximum_expiration));
1417 ast_sorcery_object_field_register(sorcery, "aor", "default_expiration", "3600", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, default_expiration));
1418 ast_sorcery_object_field_register(sorcery, "aor", "qualify_frequency", 0, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_aor, qualify_frequency), 0, 86400);
1419 ast_sorcery_object_field_register(sorcery, "aor", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_aor, qualify_timeout));
1420 ast_sorcery_object_field_register(sorcery, "aor", "qualify_2xx_only", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, qualify_2xx_only));
1421 ast_sorcery_object_field_register(sorcery, "aor", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, authenticate_qualify));
1422 ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
1423 ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
1424 ast_sorcery_object_field_register(sorcery, "aor", "remove_unavailable", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_unavailable));
1428 ast_sorcery_object_field_register(sorcery, "aor", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, outbound_proxy));
1429 ast_sorcery_object_field_register(sorcery, "aor", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, support_path));
1430
1432
1434 if (!contact_formatter) {
1435 ast_log(LOG_ERROR, "Unable to allocate memory for contact_formatter\n");
1436 return -1;
1437 }
1438 contact_formatter->name = "contact";
1445
1447 if (!aor_formatter) {
1448 ast_log(LOG_ERROR, "Unable to allocate memory for aor_formatter\n");
1449 return -1;
1450 }
1451 aor_formatter->name = "aor";
1458
1462
1464 return -1;
1465 }
1466
1467 /*
1468 * Reset StatsD gauges in case we didn't shut down cleanly.
1469 * Note that this must done here, as contacts will create the contact_status
1470 * object before PJSIP options handling is initialized.
1471 */
1472 for (i = 0; i <= REMOVED; i++) {
1473 ast_statsd_log_full_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE, 0, 1.0, ast_sip_get_contact_status_label(i));
1474 }
1475
1476 return 0;
1477}
#define ast_log
Definition: astobj2.c:42
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_NOOP_T
Type for a default handler that should do nothing.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_YESNO_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_DOUBLE_T
Type for default option handler for doubles.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
#define LOG_ERROR
static int contact_apply_handler(const struct ast_sorcery *sorcery, void *object)
Always create a contact_status for each contact.
Definition: location.c:1335
static int expiration_str2struct(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for translating from a string timeval to actual structure.
Definition: location.c:483
static void * contact_alloc(const char *name)
Allocator for contact.
Definition: location.c:120
static int cli_aor_print_body(void *obj, void *arg, int flags)
Definition: location.c:1192
static int contacts_to_var_list(const void *obj, struct ast_variable **fields)
Definition: location.c:661
static int pjsip_max_url_size
Definition: location.c:37
static int cli_contact_iterate(void *container, ao2_callback_fn callback, void *args)
Definition: location.c:980
static int voicemail_extension_to_str(const void *obj, const intptr_t *args, char **buf)
Definition: location.c:679
static int expiration_struct2str(const void *obj, const intptr_t *args, char **buf)
Custom handler for translating from an actual structure timeval to string.
Definition: location.c:490
static const char * cli_contact_get_id(const void *obj)
Definition: location.c:920
static void * aor_alloc(const char *name)
Allocator for AOR.
Definition: location.c:50
static int permanent_uri_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for permanent URIs.
Definition: location.c:593
static int voicemail_extension_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: location.c:670
static void * cli_contact_retrieve_by_id(const char *id)
Definition: location.c:1080
static int contacts_to_str(const void *obj, const intptr_t *args, char **buf)
Definition: location.c:812
static int pj_max_hostname
Definition: location.c:36
static int cli_aor_print_header(void *obj, void *arg, int flags)
Definition: location.c:1165
static struct ao2_container * cli_contact_get_container(const char *regex)
Definition: location.c:1030
static const char * cli_aor_get_id(const void *obj)
Definition: location.c:1160
static struct ao2_container * cli_aor_get_container(const char *regex)
Definition: location.c:883
static void * cli_aor_retrieve_by_id(const char *id)
Definition: location.c:1155
static int cli_contact_print_header(void *obj, void *arg, int flags)
Definition: location.c:1095
static int aor_apply_handler(const struct ast_sorcery *sorcery, void *object)
Definition: location.c:1361
static int cli_contact_print_body(void *obj, void *arg, int flags)
Definition: location.c:1110
static int cli_aor_iterate(void *container, ao2_callback_fn callback, void *args)
Definition: location.c:1148
static int ami_show_aors(struct mansession *s, const struct message *m)
Definition: location.c:1269
#define EVENT_FLAG_SYSTEM
Definition: manager.h:75
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:192
static int default_expiration
Definition: pbx_dundi.c:208
static struct stasis_rest_handlers mailboxes
REST handler for /api-docs/mailboxes.json.
int ast_pjproject_get_buildopt(char *option, char *format_string,...)
Retrieve a pjproject build option.
void ast_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Register an endpoint formatter.
Definition: res_pjsip.c:481
const char * ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status)
translate ast_sip_contact_status_type to character string.
@ REMOVED
Definition: res_pjsip.h:443
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Registers a CLI formatter.
Definition: pjsip_cli.c:310
static struct ast_sorcery * sorcery
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:837
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
Definition: sorcery.c:2391
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
Definition: sorcery.h:1005
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:476
int ast_sorcery_object_set_congestion_levels(struct ast_sorcery *sorcery, const char *type, long low_water, long high_water)
Set the high and low alert water marks of the sorcery object type.
Definition: sorcery.c:1114
#define AST_STATSD_GAUGE
Support for publishing to a statsd server.
Definition: statsd.h:32
void ast_statsd_log_full_va(const char *metric_name, const char *metric_type, intmax_t value, double sample_rate,...)
Send a stat to the configured statsd server.
Definition: res_statsd.c:228
CLI Formatter Registry Entry.
Definition: res_pjsip_cli.h:52
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
Definition: res_pjsip_cli.h:66
ao2_callback_fn * print_header
Definition: res_pjsip_cli.h:60
void *(* retrieve_by_id)(const char *id)
Definition: res_pjsip_cli.h:68
const char *(* get_id)(const void *obj)
Definition: res_pjsip_cli.h:70
const char * name
Definition: res_pjsip_cli.h:58
ao2_callback_fn * print_body
Definition: res_pjsip_cli.h:62
struct ao2_container *(* get_container)(const char *regex)
Definition: res_pjsip_cli.h:64
Full structure for sorcery.
Definition: sorcery.c:230
#define AST_TASKPROCESSOR_HIGH_WATER_LEVEL
Definition: taskprocessor.h:64

References ami_show_aors(), ao2_alloc, aor_alloc(), aor_apply_handler(), aor_formatter, aor_observer, ARRAY_LEN, ast_cli_register_multiple, ast_log, ast_manager_register_xml, ast_pjproject_get_buildopt(), ast_sip_get_contact_status_label(), ast_sip_get_sorcery(), ast_sip_register_cli_formatter(), ast_sip_register_endpoint_formatter(), ast_sorcery_apply_default, ast_sorcery_object_field_register, ast_sorcery_object_field_register_custom, ast_sorcery_object_register, ast_sorcery_object_set_congestion_levels(), ast_sorcery_observer_add(), AST_STATSD_GAUGE, ast_statsd_log_full_va(), AST_TASKPROCESSOR_HIGH_WATER_LEVEL, cli_aor_get_container(), cli_aor_get_id(), cli_aor_iterate(), cli_aor_print_body(), cli_aor_print_header(), cli_aor_retrieve_by_id(), cli_commands, cli_contact_get_container(), cli_contact_get_id(), cli_contact_iterate(), cli_contact_print_body(), cli_contact_print_header(), cli_contact_retrieve_by_id(), contact_alloc(), contact_apply_handler(), contact_formatter, contacts_to_str(), contacts_to_var_list(), default_expiration, endpoint_aor_formatter, EVENT_FLAG_SYSTEM, expiration_str2struct(), expiration_struct2str(), FLDSET, ast_sip_cli_formatter_entry::get_container, ast_sip_cli_formatter_entry::get_id, ast_sip_cli_formatter_entry::iterate, LOG_ERROR, mailboxes, ast_sip_cli_formatter_entry::name, NULL, OPT_BOOL_T, OPT_DOUBLE_T, OPT_NOOP_T, OPT_STRINGFIELD_T, OPT_UINT_T, OPT_YESNO_T, PARSE_IN_RANGE, permanent_uri_handler(), pj_max_hostname, pjsip_max_url_size, ast_sip_cli_formatter_entry::print_body, ast_sip_cli_formatter_entry::print_header, REMOVED, ast_sip_cli_formatter_entry::retrieve_by_id, sorcery, STRFLDSET, voicemail_extension_handler(), and voicemail_extension_to_str().

Referenced by ast_res_pjsip_initialize_configuration().

◆ ast_sip_location_add_contact()

int ast_sip_location_add_contact ( struct ast_sip_aor aor,
const char *  uri,
struct timeval  expiration_time,
const char *  path_info,
const char *  user_agent,
const char *  via_addr,
int  via_port,
const char *  call_id,
struct ast_sip_endpoint endpoint 
)

Add a new contact to an AOR.

Parameters
aorPointer to the AOR
uriFull contact URI
expiration_timeOptional expiration time of the contact
path_infoPath information
user_agentUser-Agent header from REGISTER request
via_addr
via_port
call_id
endpointThe endpoint that resulted in the contact being added
Return values
-1failure
0success
Warning
This function holds a named write lock on the aor. If you already hold the lock you should call ast_sip_location_add_contact_nolock instead.

Definition at line 430 of file location.c.

434{
435 int res;
436
437 ao2_lock(aor);
438 res = ast_sip_location_add_contact_nolock(aor, uri, expiration_time, path_info, user_agent,
439 via_addr, via_port, call_id,
440 endpoint);
441 ao2_unlock(aor);
442
443 return res;
444}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time, const char *path_info, const char *user_agent, const char *via_addr, int via_port, const char *call_id, struct ast_sip_endpoint *endpoint)
Add a new contact to an AOR without locking the AOR.
Definition: location.c:417

References ao2_lock, ao2_unlock, ast_sip_contact::aor, ast_sip_location_add_contact_nolock(), ast_sip_contact::call_id, ast_sip_contact::endpoint, ast_sip_contact::expiration_time, ast_sip_contact::uri, ast_sip_contact::user_agent, ast_sip_contact::via_addr, and ast_sip_contact::via_port.

◆ ast_sip_location_add_contact_nolock()

int ast_sip_location_add_contact_nolock ( struct ast_sip_aor aor,
const char *  uri,
struct timeval  expiration_time,
const char *  path_info,
const char *  user_agent,
const char *  via_addr,
int  via_port,
const char *  call_id,
struct ast_sip_endpoint endpoint 
)

Add a new contact to an AOR without locking the AOR.

Since
13.9.0
Parameters
aorPointer to the AOR
uriFull contact URI
expiration_timeOptional expiration time of the contact
path_infoPath information
user_agentUser-Agent header from REGISTER request
via_addr
via_port
call_id
endpointThe endpoint that resulted in the contact being added
Return values
-1failure
0success
Warning
This function should only be called if you already hold a named write lock on the aor.

Definition at line 417 of file location.c.

421{
422 struct ast_sip_contact *contact;
423
426 ao2_cleanup(contact);
427 return contact ? 0 : -1;
428}
struct ast_sip_contact * ast_sip_location_create_contact(struct ast_sip_aor *aor, const char *uri, struct timeval expiration_time, const char *path_info, const char *user_agent, const char *via_addr, int via_port, const char *call_id, int prune_on_boot, struct ast_sip_endpoint *endpoint)
Create a new contact for an AOR without locking the AOR.
Definition: location.c:355
const ast_string_field uri
Definition: res_pjsip.h:412
struct ast_sip_endpoint * endpoint
Definition: res_pjsip.h:422
const ast_string_field via_addr
Definition: res_pjsip.h:412
const ast_string_field call_id
Definition: res_pjsip.h:412
const ast_string_field aor
Definition: res_pjsip.h:412
struct timeval expiration_time
Definition: res_pjsip.h:414
const ast_string_field user_agent
Definition: res_pjsip.h:412

References ao2_cleanup, ast_sip_contact::aor, ast_sip_location_create_contact(), ast_sip_contact::call_id, ast_sip_contact::endpoint, ast_sip_contact::expiration_time, ast_sip_contact::uri, ast_sip_contact::user_agent, ast_sip_contact::via_addr, and ast_sip_contact::via_port.

Referenced by ast_sip_location_add_contact().

◆ ast_sip_location_create_contact()

struct ast_sip_contact * ast_sip_location_create_contact ( struct ast_sip_aor aor,
const char *  uri,
struct timeval  expiration_time,
const char *  path_info,
const char *  user_agent,
const char *  via_addr,
int  via_port,
const char *  call_id,
int  prune_on_boot,
struct ast_sip_endpoint endpoint 
)

Create a new contact for an AOR without locking the AOR.

Since
13.18.0
Parameters
aorPointer to the AOR
uriFull contact URI
expiration_timeOptional expiration time of the contact
path_infoPath information
user_agentUser-Agent header from REGISTER request
via_addr
via_port
call_id
prune_on_bootNon-zero if the contact cannot survive a restart/boot.
endpointThe endpoint that resulted in the contact being added
Returns
The created contact or NULL on failure.
Warning
This function should only be called if you already hold a named write lock on the aor.

Definition at line 355 of file location.c.

359{
360 struct ast_sip_contact *contact;
361 char name[MAX_OBJECT_FIELD * 2 + 3];
362 char hash[33];
363
364 ast_md5_hash(hash, uri);
365 snprintf(name, sizeof(name), "%s;@%s", ast_sorcery_object_get_id(aor), hash);
366
367 contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name);
368 if (!contact) {
369 return NULL;
370 }
371
372 ast_string_field_set(contact, uri, uri);
374 contact->qualify_frequency = aor->qualify_frequency;
375 contact->qualify_timeout = aor->qualify_timeout;
376 contact->qualify_2xx_only = aor->qualify_2xx_only;
377 contact->authenticate_qualify = aor->authenticate_qualify;
378 if (path_info && aor->support_path) {
379 ast_string_field_set(contact, path, path_info);
380 }
381
382 if (!ast_strlen_zero(aor->outbound_proxy)) {
383 ast_string_field_set(contact, outbound_proxy, aor->outbound_proxy);
384 }
385
388 }
389
392 }
393
396 }
397 contact->via_port = via_port;
398
399 if (!ast_strlen_zero(call_id)) {
401 }
402
403 contact->endpoint = ao2_bump(endpoint);
404 if (endpoint) {
406 }
407
408 contact->prune_on_boot = prune_on_boot;
409
410 if (ast_sorcery_create(ast_sip_get_sorcery(), contact)) {
411 ao2_ref(contact, -1);
412 return NULL;
413 }
414 return contact;
415}
const char * ast_config_AST_SYSTEM_NAME
Definition: options.c:170
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
Definition: sorcery.c:2062
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
Definition: sorcery.h:110
double qualify_timeout
Definition: res_pjsip.h:420
int qualify_2xx_only
Definition: res_pjsip.h:428
const ast_string_field outbound_proxy
Definition: res_pjsip.h:412
const ast_string_field path
Definition: res_pjsip.h:412
const ast_string_field endpoint_name
Definition: res_pjsip.h:412
int authenticate_qualify
Definition: res_pjsip.h:418
const ast_string_field reg_server
Definition: res_pjsip.h:412
unsigned int qualify_frequency
Definition: res_pjsip.h:416
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: utils.c:250

References ao2_bump, ao2_ref, ast_sip_contact::aor, ast_config_AST_SYSTEM_NAME, ast_md5_hash(), ast_sip_get_sorcery(), ast_sorcery_alloc(), ast_sorcery_create(), ast_sorcery_object_get_id(), ast_string_field_set, ast_strlen_zero(), ast_sip_contact::authenticate_qualify, ast_sip_contact::call_id, ast_sip_contact::endpoint, ast_sip_contact::endpoint_name, ast_sip_contact::expiration_time, MAX_OBJECT_FIELD, name, NULL, ast_sip_contact::outbound_proxy, ast_sip_contact::path, ast_sip_contact::prune_on_boot, ast_sip_contact::qualify_2xx_only, ast_sip_contact::qualify_frequency, ast_sip_contact::qualify_timeout, ast_sip_contact::reg_server, ast_sip_contact::uri, ast_sip_contact::user_agent, ast_sip_contact::via_addr, and ast_sip_contact::via_port.

Referenced by ast_sip_location_add_contact_nolock().

◆ ast_sip_location_delete_contact()

int ast_sip_location_delete_contact ( struct ast_sip_contact contact)

Delete a contact.

Parameters
contactContact object to delete
Return values
-1failure
0success

Definition at line 451 of file location.c.

452{
453 return ast_sorcery_delete(ast_sip_get_sorcery(), contact);
454}
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
Definition: sorcery.c:2238

References ast_sip_get_sorcery(), and ast_sorcery_delete().

Referenced by contact_expire(), destroy_contact(), prune_boot_contacts_cb(), and registrar_contact_delete().

◆ ast_sip_location_prune_boot_contacts()

void ast_sip_location_prune_boot_contacts ( void  )

Prune the prune_on_boot contacts.

Since
13.18.0

Definition at line 470 of file location.c.

471{
472 struct ao2_container *contacts;
473
476 if (contacts) {
478 ao2_ref(contacts, -1);
479 }
480}
static int prune_boot_contacts_cb(void *obj, void *arg, int flags)
Definition: location.c:456
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition: sorcery.h:123
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897

References ao2_callback, ao2_ref, AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_retrieve_by_fields(), NULL, and prune_boot_contacts_cb().

Referenced by load_module().

◆ ast_sip_location_retrieve_aor()

struct ast_sip_aor * ast_sip_location_retrieve_aor ( const char *  aor_name)

Retrieve a named AOR.

Parameters
aor_nameName of the AOR
Return values
NULLif not found
non-NULLif found

Definition at line 147 of file location.c.

148{
149 return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", aor_name);
150}
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853

References ast_sip_get_sorcery(), and ast_sorcery_retrieve_by_id().

Referenced by ast_sip_for_each_aor(), ast_sip_location_retrieve_contact_and_aor_from_list_filtered(), find_aor(), find_aor2(), find_aor_for_resource(), find_registrar_aor(), handle_slash(), notify_endpoint(), pjsip_acf_dial_contacts_read(), register_contact_transport_remove_cb(), send_unsolicited_mwi_notify(), and vec_contact_cmp().

◆ ast_sip_location_retrieve_aor_contacts()

struct ao2_container * ast_sip_location_retrieve_aor_contacts ( const struct ast_sip_aor aor)

Retrieve all contacts currently available for an AOR.

Parameters
aorPointer to the AOR
Return values
NULLif no contacts available
non-NULLif contacts available
Warning
Since this function prunes expired contacts before returning, it holds a named write lock on the aor. If you already hold the lock, call ast_sip_location_retrieve_aor_contacts_nolock instead.

Definition at line 247 of file location.c.

248{
250}
struct ao2_container * ast_sip_location_retrieve_aor_contacts_filtered(const struct ast_sip_aor *aor, unsigned int flags)
Retrieve all contacts currently available for an AOR and filter based on flags.
Definition: location.c:252
@ AST_SIP_CONTACT_FILTER_DEFAULT
Default filter flags.
Definition: res_pjsip.h:1422

References AST_SIP_CONTACT_FILTER_DEFAULT, and ast_sip_location_retrieve_aor_contacts_filtered().

Referenced by ast_sip_for_each_contact(), find_contact(), format_ami_aor_handler(), gather_contacts_for_aor(), notify_endpoint(), pjsip_aor_function_read(), and send_unsolicited_mwi_notify().

◆ ast_sip_location_retrieve_aor_contacts_filtered()

struct ao2_container * ast_sip_location_retrieve_aor_contacts_filtered ( const struct ast_sip_aor aor,
unsigned int  flags 
)

Retrieve all contacts currently available for an AOR and filter based on flags.

Since
13.16.0
Parameters
aorPointer to the AOR
flagsFiltering flags
Return values
NULLif no contacts available
non-NULLif contacts available
Warning
Since this function prunes expired contacts before returning, it holds a named write lock on the aor. If you already hold the lock, call ast_sip_location_retrieve_aor_contacts_nolock instead.

Definition at line 252 of file location.c.

254{
255 struct ao2_container *contacts;
256
257 /* ao2_lock / ao2_unlock do not actually write aor since it has an ao2 lockobj. */
258 ao2_lock((void*)aor);
260 ao2_unlock((void*)aor);
261
262 return contacts;
263}
struct ao2_container * ast_sip_location_retrieve_aor_contacts_nolock_filtered(const struct ast_sip_aor *aor, unsigned int flags)
Retrieve all contacts currently available for an AOR without locking the AOR and filter based on flag...
Definition: location.c:219

References ao2_lock, ao2_unlock, and ast_sip_location_retrieve_aor_contacts_nolock_filtered().

Referenced by ast_sip_location_retrieve_aor_contacts(), ast_sip_location_retrieve_first_aor_contact_filtered(), and pjsip_acf_dial_contacts_read().

◆ ast_sip_location_retrieve_aor_contacts_nolock()

struct ao2_container * ast_sip_location_retrieve_aor_contacts_nolock ( const struct ast_sip_aor aor)

Retrieve all contacts currently available for an AOR without locking the AOR.

Since
13.9.0
Parameters
aorPointer to the AOR
Return values
NULLif no contacts available
non-NULLif contacts available
Warning
This function should only be called if you already hold a named write lock on the aor.

Definition at line 214 of file location.c.

References AST_SIP_CONTACT_FILTER_DEFAULT, and ast_sip_location_retrieve_aor_contacts_nolock_filtered().

Referenced by register_aor().

◆ ast_sip_location_retrieve_aor_contacts_nolock_filtered()

struct ao2_container * ast_sip_location_retrieve_aor_contacts_nolock_filtered ( const struct ast_sip_aor aor,
unsigned int  flags 
)

Retrieve all contacts currently available for an AOR without locking the AOR and filter based on flags.

Since
13.16.0
Parameters
aorPointer to the AOR
flagsFiltering flags
Return values
NULLif no contacts available
non-NULLif contacts available
Warning
This function should only be called if you already hold a named write lock on the aor.

Definition at line 219 of file location.c.

221{
222 /* Give enough space for ;@ at the end, since that is our object naming scheme */
223 size_t prefix_len = strlen(ast_sorcery_object_get_id(aor)) + sizeof(";@") - 1;
224 char prefix[prefix_len + 1];
225 struct ao2_container *contacts;
226
227 sprintf(prefix, "%s;@", ast_sorcery_object_get_id(aor)); /* Safe */
228 if (!(contacts = ast_sorcery_retrieve_by_prefix(ast_sip_get_sorcery(), "contact", prefix, prefix_len))) {
229 return NULL;
230 }
231
232 /* Prune any expired contacts and delete them, we do this first because static contacts can never expire */
234
235 /* Add any permanent contacts from the AOR */
236 if (aor->permanent_contacts) {
238 }
239
242 }
243
244 return contacts;
245}
static int contact_link_static(void *obj, void *arg, int flags)
Internal callback function which links static contacts into another container.
Definition: location.c:168
static int contact_remove_unreachable(void *obj, void *arg, int flags)
Internal callback function which removes any contact which is unreachable.
Definition: location.c:177
static int contact_expire(void *obj, void *arg, int flags)
Internal callback function which deletes and unlinks any expired contacts.
Definition: location.c:153
@ AST_SIP_CONTACT_FILTER_REACHABLE
Return only reachable or unknown contacts.
Definition: res_pjsip.h:1425

References ao2_callback, AST_SIP_CONTACT_FILTER_REACHABLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_prefix(), contact_expire(), contact_link_static(), contact_remove_unreachable(), NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, ast_sip_aor::permanent_contacts, and prefix.

Referenced by ast_sip_location_retrieve_aor_contacts_filtered(), and ast_sip_location_retrieve_aor_contacts_nolock().

◆ ast_sip_location_retrieve_contact()

struct ast_sip_contact * ast_sip_location_retrieve_contact ( const char *  contact_name)

Retrieve a named contact.

Parameters
contact_nameName of the contact
Return values
NULLif not found
non-NULLif found

Definition at line 350 of file location.c.

351{
352 return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "contact", contact_name);
353}

References ast_sip_get_sorcery(), and ast_sorcery_retrieve_by_id().

Referenced by register_contact_transport_remove_cb().

◆ ast_sip_location_retrieve_contact_and_aor_from_list()

void ast_sip_location_retrieve_contact_and_aor_from_list ( const char *  aor_list,
struct ast_sip_aor **  aor,
struct ast_sip_contact **  contact 
)

Retrieve the first bound contact AND the AOR chosen from a list of AORs.

Parameters
aor_listA comma-separated list of AOR names
aorThe chosen AOR
contactThe chosen contact

Definition at line 266 of file location.c.

268{
270}
void ast_sip_location_retrieve_contact_and_aor_from_list_filtered(const char *aor_list, unsigned int flags, struct ast_sip_aor **aor, struct ast_sip_contact **contact)
Retrieve the first bound contact AND the AOR chosen from a list of AORs and filter based on flags.
Definition: location.c:272

References AST_SIP_CONTACT_FILTER_DEFAULT, and ast_sip_location_retrieve_contact_and_aor_from_list_filtered().

Referenced by ast_sip_location_retrieve_contact_from_aor_list().

◆ ast_sip_location_retrieve_contact_and_aor_from_list_filtered()

void ast_sip_location_retrieve_contact_and_aor_from_list_filtered ( const char *  aor_list,
unsigned int  flags,
struct ast_sip_aor **  aor,
struct ast_sip_contact **  contact 
)

Retrieve the first bound contact AND the AOR chosen from a list of AORs and filter based on flags.

Since
13.16.0
Parameters
aor_listA comma-separated list of AOR names
flagsFiltering flags
aorThe chosen AOR
contactThe chosen contact

Definition at line 272 of file location.c.

274{
275 char *aor_name;
276 char *rest;
277
278 /* If the location is still empty we have nowhere to go */
279 if (ast_strlen_zero(aor_list) || !(rest = ast_strdupa(aor_list))) {
280 ast_log(LOG_WARNING, "Unable to determine contacts from empty aor list\n");
281 return;
282 }
283
284 *aor = NULL;
285 *contact = NULL;
286
287 while ((aor_name = ast_strip(strsep(&rest, ",")))) {
288 *aor = ast_sip_location_retrieve_aor(aor_name);
289
290 if (!(*aor)) {
291 continue;
292 }
294 /* If a valid contact is available use its URI for dialing */
295 if (*contact) {
296 break;
297 }
298
299 ao2_ref(*aor, -1);
300 *aor = NULL;
301 }
302}
#define LOG_WARNING
struct ast_sip_contact * ast_sip_location_retrieve_first_aor_contact_filtered(const struct ast_sip_aor *aor, unsigned int flags)
Retrieve the first bound contact for an AOR and filter based on flags.
Definition: location.c:199

References ao2_ref, ast_log, ast_sip_location_retrieve_aor(), ast_sip_location_retrieve_first_aor_contact_filtered(), ast_strdupa, ast_strip(), ast_strlen_zero(), LOG_WARNING, NULL, and strsep().

Referenced by ast_sip_location_retrieve_contact_and_aor_from_list(), and ast_sip_session_create_outgoing().

◆ ast_sip_location_retrieve_contact_from_aor_list()

struct ast_sip_contact * ast_sip_location_retrieve_contact_from_aor_list ( const char *  aor_list)

Retrieve the first bound contact from a list of AORs.

Parameters
aor_listA comma-separated list of AOR names
Return values
NULLif no contacts available
non-NULLif contacts available

Definition at line 304 of file location.c.

305{
306 struct ast_sip_aor *aor;
307 struct ast_sip_contact *contact;
308
310
312
313 return contact;
314}
void ast_sip_location_retrieve_contact_and_aor_from_list(const char *aor_list, struct ast_sip_aor **aor, struct ast_sip_contact **contact)
Retrieve the first bound contact AND the AOR chosen from a list of AORs.
Definition: location.c:266

References ao2_cleanup, ast_sip_contact::aor, and ast_sip_location_retrieve_contact_and_aor_from_list().

Referenced by ast_sip_create_subscription(), create_out_of_dialog_request(), handle_atsign(), handle_single_token(), insert_user_in_contact_uri(), mwi_contact_deleted(), and transfer().

◆ ast_sip_location_retrieve_contacts_from_aor_list()

struct ao2_container * ast_sip_location_retrieve_contacts_from_aor_list ( const char *  aor_list)

Retrieve all contacts from a list of AORs.

Parameters
aor_listA comma-separated list of AOR names
Return values
NULLif no contacts available
non-NULLcontainer (which must be freed) if contacts available

Definition at line 335 of file location.c.

336{
337 struct ao2_container *contacts;
338
341 if (!contacts) {
342 return NULL;
343 }
344
346
347 return contacts;
348}
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
Definition: astobj2.h:1188
int ast_sip_for_each_aor(const char *aors, ao2_callback_fn on_aor, void *arg)
For every aor in the comma separated aors string call the given 'on_aor' handler.
Definition: location.c:688
static int permanent_uri_sort_fn(const void *obj_left, const void *obj_right, int flags)
Definition: location.c:499
static int gather_contacts_for_aor(void *obj, void *arg, int flags)
Definition: location.c:319

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ast_sip_for_each_aor(), gather_contacts_for_aor(), NULL, and permanent_uri_sort_fn().

Referenced by add_security_headers(), and handle_registration_response().

◆ ast_sip_location_retrieve_first_aor_contact()

struct ast_sip_contact * ast_sip_location_retrieve_first_aor_contact ( const struct ast_sip_aor aor)

Retrieve the first bound contact for an AOR.

Parameters
aorPointer to the AOR
Return values
NULLif no contacts available
non-NULLif contacts available

Definition at line 194 of file location.c.

References ast_sip_contact::aor, AST_SIP_CONTACT_FILTER_DEFAULT, and ast_sip_location_retrieve_first_aor_contact_filtered().

Referenced by handle_slash().

◆ ast_sip_location_retrieve_first_aor_contact_filtered()

struct ast_sip_contact * ast_sip_location_retrieve_first_aor_contact_filtered ( const struct ast_sip_aor aor,
unsigned int  flags 
)

Retrieve the first bound contact for an AOR and filter based on flags.

Since
13.16.0
Parameters
aorPointer to the AOR
flagsFiltering flags
Return values
NULLif no contacts available
non-NULLif contacts available

Definition at line 199 of file location.c.

201{
202 struct ao2_container *contacts;
203 struct ast_sip_contact *contact = NULL;
204
206 if (contacts && ao2_container_count(contacts)) {
207 /* Get the first AOR contact in the container. */
208 contact = ao2_callback(contacts, 0, NULL, NULL);
209 }
210 ao2_cleanup(contacts);
211 return contact;
212}

References ao2_callback, ao2_cleanup, ao2_container_count(), ast_sip_contact::aor, ast_sip_location_retrieve_aor_contacts_filtered(), and NULL.

Referenced by ast_sip_location_retrieve_contact_and_aor_from_list_filtered(), and ast_sip_location_retrieve_first_aor_contact().

◆ ast_sip_location_update_contact()

int ast_sip_location_update_contact ( struct ast_sip_contact contact)

Update a contact.

Parameters
contactNew contact object with details
Return values
-1failure
0success

Definition at line 446 of file location.c.

447{
448 return ast_sorcery_update(ast_sip_get_sorcery(), contact);
449}
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
Definition: sorcery.c:2150

References ast_sip_get_sorcery(), and ast_sorcery_update().

◆ ast_sip_validate_uri_length()

int ast_sip_validate_uri_length ( const char *  contact_uri)

Definition at line 529 of file location.c.

530{
531 int max_length = pj_max_hostname - 1;
532 char *contact = ast_strdupa(contact_uri);
533 char *host;
534 char *at;
535 int theres_a_port = 0;
536
537 if (strlen(contact_uri) > pjsip_max_url_size - 1) {
538 return -1;
539 }
540
541 contact = ast_strip_quoted(contact, "<", ">");
542
543 if (!strncasecmp(contact, "sip:", 4)) {
544 host = contact + 4;
545 } else if (!strncasecmp(contact, "sips:", 5)) {
546 host = contact + 5;
547 } else {
548 /* Not a SIP URI */
549 return -1;
550 }
551
552 at = strchr(contact, '@');
553 if (at) {
554 /* sip[s]:user@host */
555 host = at + 1;
556 }
557
558 if (host[0] == '[') {
559 /* Host is an IPv6 address. Just get up to the matching bracket */
560 char *close_bracket;
561
562 close_bracket = strchr(host, ']');
563 if (!close_bracket) {
564 return -1;
565 }
566 close_bracket++;
567 if (*close_bracket == ':') {
568 theres_a_port = 1;
569 }
570 *close_bracket = '\0';
571 } else {
572 /* uri parameters could contain ';' so trim them off first */
573 host = strsep(&host, ";?");
574 /* Host is FQDN or IPv4 address. Need to find closing delimiter */
575 if (strchr(host, ':')) {
576 theres_a_port = 1;
577 host = strsep(&host, ":");
578 }
579 }
580
581 if (!theres_a_port) {
582 max_length -= strlen("_sips.tcp.");
583 }
584
585 if (strlen(host) > max_length) {
586 return -1;
587 }
588
589 return 0;
590}
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
Definition: utils.c:1818

References ast_strdupa, ast_strip_quoted(), pj_max_hostname, pjsip_max_url_size, and strsep().

Referenced by permanent_uri_handler(), sip_outbound_registration_apply(), and validate_publish_config().

◆ cli_aor_gather_contacts()

static int cli_aor_gather_contacts ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 913 of file location.c.

914{
915 struct ast_sip_aor *aor = obj;
916
918}
int ast_sip_for_each_contact(const struct ast_sip_aor *aor, ao2_callback_fn on_contact, void *arg)
For every contact on an AOR call the given 'on_contact' handler.
Definition: location.c:723
static int cli_contact_populate_container(void *obj, void *arg, int flags)
Definition: location.c:906

References ast_sip_for_each_contact(), and cli_contact_populate_container().

Referenced by cli_contact_get_container().

◆ cli_aor_get_container()

static struct ao2_container * cli_aor_get_container ( const char *  regex)
static

Definition at line 883 of file location.c.

884{
885 struct ao2_container *container;
886 struct ao2_container *s_container;
887
889 if (!container) {
890 return NULL;
891 }
892
893 /* Create a sorted container of aors. */
896 if (s_container
897 && ao2_container_dup(s_container, container, 0)) {
898 ao2_ref(s_container, -1);
899 s_container = NULL;
900 }
901 ao2_ref(container, -1);
902
903 return s_container;
904}
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
struct ao2_container * container
Definition: res_fax.c:531
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
Definition: sorcery.c:1954
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2464
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2440

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_container_alloc_list, ao2_container_dup(), ao2_ref, ast_sip_get_sorcery(), ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), ast_sorcery_retrieve_by_regex(), container, NULL, and regex().

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_aor_get_id()

static const char * cli_aor_get_id ( const void *  obj)
static

Definition at line 1160 of file location.c.

1161{
1162 return ast_sorcery_object_get_id(obj);
1163}

References ast_sorcery_object_get_id().

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_aor_iterate()

static int cli_aor_iterate ( void *  container,
ao2_callback_fn  callback,
void *  args 
)
static

Definition at line 1148 of file location.c.

1149{
1150 const char *aor_list = container;
1151
1152 return ast_sip_for_each_aor(aor_list, callback, args);
1153}
const char * args

References args, ast_sip_for_each_aor(), and container.

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_aor_print_body()

static int cli_aor_print_body ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1192 of file location.c.

1193{
1194 struct ast_sip_aor *aor = obj;
1195 struct ast_sip_cli_context *context = arg;
1196 int indent;
1197 int flexwidth;
1198
1199 ast_assert(context->output_buffer != NULL);
1200
1201// context->current_aor = aor;
1202
1203 indent = CLI_INDENT_TO_SPACES(context->indent_level);
1204 flexwidth = CLI_LAST_TABSTOP - indent - 12;
1205
1206 ast_str_append(&context->output_buffer, 0, "%*s: %-*.*s %12u\n",
1207 indent,
1208 "Aor",
1209 flexwidth, flexwidth,
1211
1212 if (context->recurse) {
1213 struct ast_sip_cli_formatter_entry *formatter_entry;
1214
1215 context->indent_level++;
1216
1217 formatter_entry = ast_sip_lookup_cli_formatter("contact");
1218 if (formatter_entry) {
1219 formatter_entry->iterate(aor, formatter_entry->print_body, context);
1220 ao2_ref(formatter_entry, -1);
1221 }
1222
1223 context->indent_level--;
1224
1225 if (context->indent_level == 0) {
1226 ast_str_append(&context->output_buffer, 0, "\n");
1227 }
1228 }
1229
1230 if (context->show_details || (context->show_details_only_level_0 && context->indent_level == 0)) {
1231 ast_str_append(&context->output_buffer, 0, "\n");
1233 }
1234
1235 return 0;
1236}
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object's ast_variable list.
Definition: pjsip_cli.c:36
struct ast_sip_cli_formatter_entry * ast_sip_lookup_cli_formatter(const char *name)
Looks up a CLI formatter by type.
Definition: pjsip_cli.c:305
#define CLI_LAST_TABSTOP
Definition: res_pjsip_cli.h:27
#define CLI_INDENT_TO_SPACES(x)
Definition: res_pjsip_cli.h:29
unsigned int max_contacts
Definition: res_pjsip.h:498
CLI Formatter Context passed to all formatters.
Definition: res_pjsip_cli.h:34
#define ast_assert(a)
Definition: utils.h:739

References ao2_ref, ast_assert, ast_sip_cli_print_sorcery_objectset(), ast_sip_lookup_cli_formatter(), ast_sorcery_object_get_id(), ast_str_append(), CLI_INDENT_TO_SPACES, CLI_LAST_TABSTOP, voicemailpwcheck::context, ast_sip_cli_formatter_entry::iterate, ast_sip_aor::max_contacts, NULL, and ast_sip_cli_formatter_entry::print_body.

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_aor_print_header()

static int cli_aor_print_header ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1165 of file location.c.

1166{
1167 struct ast_sip_cli_context *context = arg;
1168 int indent = CLI_INDENT_TO_SPACES(context->indent_level);
1169 int filler = CLI_LAST_TABSTOP - indent - 7;
1170
1171 ast_assert(context->output_buffer != NULL);
1172
1173 ast_str_append(&context->output_buffer, 0,
1174 "%*s: <Aor%*.*s> <MaxContact>\n",
1175 indent, "Aor", filler, filler, CLI_HEADER_FILLER);
1176
1177 if (context->recurse) {
1178 struct ast_sip_cli_formatter_entry *formatter_entry;
1179
1180 context->indent_level++;
1181 formatter_entry = ast_sip_lookup_cli_formatter("contact");
1182 if (formatter_entry) {
1183 formatter_entry->print_header(NULL, context, 0);
1184 ao2_ref(formatter_entry, -1);
1185 }
1186 context->indent_level--;
1187 }
1188
1189 return 0;
1190}
#define CLI_HEADER_FILLER
Definition: res_pjsip_cli.h:24

References ao2_ref, ast_assert, ast_sip_lookup_cli_formatter(), ast_str_append(), CLI_HEADER_FILLER, CLI_INDENT_TO_SPACES, CLI_LAST_TABSTOP, voicemailpwcheck::context, NULL, and ast_sip_cli_formatter_entry::print_header.

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_aor_retrieve_by_id()

static void * cli_aor_retrieve_by_id ( const char *  id)
static

Definition at line 1155 of file location.c.

1156{
1158}

References ast_sip_get_sorcery(), and ast_sorcery_retrieve_by_id().

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_contact_compare()

static int cli_contact_compare ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 951 of file location.c.

952{
953 const struct ast_sip_contact_wrapper *left_wrapper = obj;
954 const struct ast_sip_contact_wrapper *right_wrapper = arg;
955 const char *right_key = arg;
956 int cmp = 0;
957
958 switch (flags & OBJ_SEARCH_MASK) {
960 right_key = right_wrapper->contact_id;
961 /* Fall through */
962 case OBJ_SEARCH_KEY:
963 if (strcmp(left_wrapper->contact_id, right_key) == 0) {;
964 cmp = CMP_MATCH | CMP_STOP;
965 }
966 break;
968 if (strncmp(left_wrapper->contact_id, right_key, strlen(right_key)) == 0) {
969 cmp = CMP_MATCH;
970 }
971 break;
972 default:
973 cmp = 0;
974 break;
975 }
976
977 return cmp;
978}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
@ OBJ_SEARCH_MASK
Search option field mask.
Definition: astobj2.h:1072
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101

References CMP_MATCH, CMP_STOP, ast_sip_contact_wrapper::contact_id, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by cli_contact_get_container().

◆ cli_contact_get_container()

static struct ao2_container * cli_contact_get_container ( const char *  regex)
static

Definition at line 1030 of file location.c.

1031{
1032 RAII_VAR(struct ao2_container *, aors, NULL, ao2_cleanup);
1033 RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
1034 RAII_VAR(struct ast_variable *, var_aor, NULL, ast_variables_destroy);
1035 struct ao2_container *contacts_container;
1036 regex_t regexbuf;
1037
1038 if (!(var_aor = ast_variable_new("contact !=", "", ""))) {
1039 return NULL;
1040 }
1041
1042 /* Retrieving all the contacts may result in finding the same contact multiple
1043 * times. So that they don't get displayed multiple times we only allow a
1044 * single one to be placed into the container.
1045 */
1048 if (!contacts_container) {
1049 return NULL;
1050 }
1051
1053 if (!contacts) {
1054 ao2_ref(contacts_container, -1);
1055 return NULL;
1056 }
1057 ao2_callback(contacts, OBJ_NODATA, cli_gather_contact, contacts_container);
1058
1060 "aor", AST_RETRIEVE_FLAG_MULTIPLE, var_aor);
1061 if (!aors) {
1062 ao2_ref(contacts_container, -1);
1063 return NULL;
1064 }
1065
1066 ao2_callback(aors, OBJ_NODATA, cli_aor_gather_contacts, contacts_container);
1067
1068 if (!ast_strlen_zero(regex)) {
1069 if (regcomp(&regexbuf, regex, REG_EXTENDED | REG_NOSUB)) {
1070 ao2_ref(contacts_container, -1);
1071 return NULL;
1072 }
1073 ao2_callback(contacts_container, OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA, cli_filter_contacts, &regexbuf);
1074 regfree(&regexbuf);
1075 }
1076
1077 return contacts_container;
1078}
#define ast_variable_new(name, value, filename)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
static int cli_filter_contacts(void *obj, void *arg, int flags)
Definition: location.c:985
static int cli_gather_contact(void *obj, void *arg, int flags)
Definition: location.c:997
static int cli_contact_compare(void *obj, void *arg, int flags)
Definition: location.c:951
static int cli_contact_sort(const void *obj, const void *arg, int flags)
Definition: location.c:926
static int cli_aor_gather_contacts(void *obj, void *arg, int flags)
Definition: location.c:913
Structure for variables, used for configurations and for channel variables.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_callback, ao2_cleanup, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_ref, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_retrieve_by_fields(), ast_sorcery_retrieve_by_regex(), ast_strlen_zero(), ast_variable_new, ast_variables_destroy(), cli_aor_gather_contacts(), cli_contact_compare(), cli_contact_sort(), cli_filter_contacts(), cli_gather_contact(), NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, RAII_VAR, and regex().

Referenced by ast_sip_initialize_sorcery_location(), and cli_contact_retrieve_by_id().

◆ cli_contact_get_id()

static const char * cli_contact_get_id ( const void *  obj)
static

Definition at line 920 of file location.c.

921{
922 const struct ast_sip_contact_wrapper *wrapper = obj;
923 return wrapper->contact_id;
924}

References ast_sip_contact_wrapper::contact_id.

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_contact_iterate()

static int cli_contact_iterate ( void *  container,
ao2_callback_fn  callback,
void *  args 
)
static

Definition at line 980 of file location.c.

981{
982 return ast_sip_for_each_contact(container, callback, args);
983}

References args, ast_sip_for_each_contact(), and container.

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_contact_populate_container()

static int cli_contact_populate_container ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 906 of file location.c.

907{
908 ao2_link(arg, obj);
909
910 return 0;
911}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532

References ao2_link.

Referenced by cli_aor_gather_contacts(), and gather_contacts_for_aor().

◆ cli_contact_print_body()

static int cli_contact_print_body ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1110 of file location.c.

1111{
1112 struct ast_sip_contact_wrapper *wrapper = obj;
1113 struct ast_sip_contact *contact = wrapper->contact;
1114 struct ast_sip_cli_context *context = arg;
1115 int indent;
1116 int flexwidth;
1117 const char *contact_id = ast_sorcery_object_get_id(contact);
1118 const char *hash_start = contact_id + strlen(contact->aor) + 2;
1120
1121 ast_assert(contact->uri != NULL);
1122 ast_assert(context->output_buffer != NULL);
1123
1125
1126 indent = CLI_INDENT_TO_SPACES(context->indent_level);
1127 flexwidth = CLI_LAST_TABSTOP - indent - 9 - strlen(contact->aor) + 1;
1128
1129 ast_str_append(&context->output_buffer, 0, "%*s: %s/%-*.*s %-10.10s %-7.7s %11.3f\n",
1130 indent,
1131 "Contact",
1132 contact->aor,
1133 flexwidth, flexwidth,
1134 contact->uri,
1135 hash_start,
1137 (status && (status->status == AVAILABLE)) ? ((long long) status->rtt) / 1000.0 : NAN);
1138
1139 if (context->show_details || (context->show_details_only_level_0 && context->indent_level == 0)) {
1140 ast_str_append(&context->output_buffer, 0, "\n");
1142 }
1143
1145 return 0;
1146}
jack_status_t status
Definition: app_jack.c:149
#define NAN
const char * ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status)
struct ast_sip_contact_status * ast_sip_get_contact_status(const struct ast_sip_contact *contact)
Retrieve the current status for a contact.
@ AVAILABLE
Definition: res_pjsip.h:438
@ UNKNOWN
Definition: res_pjsip.h:440
A contact's status.
Definition: res_pjsip.h:451
struct ast_sip_contact * contact
Definition: res_pjsip.h:525

References ao2_cleanup, ast_sip_contact::aor, ast_assert, ast_sip_cli_print_sorcery_objectset(), ast_sip_get_contact_short_status_label(), ast_sip_get_contact_status(), ast_sorcery_object_get_id(), ast_str_append(), AVAILABLE, CLI_INDENT_TO_SPACES, CLI_LAST_TABSTOP, ast_sip_contact_wrapper::contact, voicemailpwcheck::context, NAN, NULL, status, UNKNOWN, and ast_sip_contact::uri.

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_contact_print_header()

static int cli_contact_print_header ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1095 of file location.c.

1096{
1097 struct ast_sip_cli_context *context = arg;
1098 int indent = CLI_INDENT_TO_SPACES(context->indent_level);
1099 int filler = CLI_LAST_TABSTOP - indent - 23;
1100
1101 ast_assert(context->output_buffer != NULL);
1102
1103 ast_str_append(&context->output_buffer, 0,
1104 "%*s: <Aor/ContactUri%*.*s> <Hash....> <Status> <RTT(ms)..>\n",
1105 indent, "Contact", filler, filler, CLI_HEADER_FILLER);
1106
1107 return 0;
1108}

References ast_assert, ast_str_append(), CLI_HEADER_FILLER, CLI_INDENT_TO_SPACES, CLI_LAST_TABSTOP, voicemailpwcheck::context, and NULL.

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_contact_retrieve_by_id()

static void * cli_contact_retrieve_by_id ( const char *  id)
static

Definition at line 1080 of file location.c.

1081{
1082 struct ao2_container *container;
1083 void *obj;
1084
1086 if (!container) {
1087 return NULL;
1088 }
1089
1090 obj = ao2_find(container, id, OBJ_SEARCH_KEY);
1091 ao2_ref(container, -1);
1092 return obj;
1093}
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736

References ao2_find, ao2_ref, cli_contact_get_container(), container, NULL, and OBJ_SEARCH_KEY.

Referenced by ast_sip_initialize_sorcery_location().

◆ cli_contact_sort()

static int cli_contact_sort ( const void *  obj,
const void *  arg,
int  flags 
)
static

Definition at line 926 of file location.c.

927{
928 const struct ast_sip_contact_wrapper *left_wrapper = obj;
929 const struct ast_sip_contact_wrapper *right_wrapper = arg;
930 const char *right_key = arg;
931 int cmp = 0;
932
933 switch (flags & OBJ_SEARCH_MASK) {
935 right_key = right_wrapper->contact_id;
936 /* Fall through */
937 case OBJ_SEARCH_KEY:
938 cmp = strcmp(left_wrapper->contact_id, right_key);
939 break;
941 cmp = strncmp(left_wrapper->contact_id, right_key, strlen(right_key));
942 break;
943 default:
944 cmp = 0;
945 break;
946 }
947
948 return cmp;
949}

References ast_sip_contact_wrapper::contact_id, OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by cli_contact_get_container().

◆ cli_filter_contacts()

static int cli_filter_contacts ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 985 of file location.c.

986{
987 struct ast_sip_contact_wrapper *wrapper = obj;
988 regex_t *regexbuf = arg;
989
990 if (!regexec(regexbuf, wrapper->contact_id, 0, NULL, 0)) {
991 return 0;
992 }
993
994 return CMP_MATCH;
995}

References CMP_MATCH, ast_sip_contact_wrapper::contact_id, and NULL.

Referenced by cli_contact_get_container().

◆ cli_gather_contact()

static int cli_gather_contact ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 997 of file location.c.

998{
999 struct ast_sip_contact *contact = obj;
1000 RAII_VAR(struct ast_sip_contact_wrapper *, wrapper, NULL, ao2_cleanup);
1001
1002 if (strcmp(contact->reg_server, ast_config_AST_SYSTEM_NAME ?: "")) {
1003 return 0;
1004 }
1005
1006 wrapper = ao2_alloc_options(sizeof(struct ast_sip_contact_wrapper),
1008 if (!wrapper) {
1009 return -1;
1010 }
1011
1012 wrapper->contact_id = ast_malloc(strlen(contact->aor) + strlen(contact->uri) + 2);
1013 if (!wrapper->contact_id) {
1014 return -1;
1015 }
1016 sprintf(wrapper->contact_id, "%s/%s", contact->aor, contact->uri);
1017
1018 wrapper->aor_id = ast_strdup(contact->aor);
1019 if (!wrapper->aor_id) {
1020 return -1;
1021 }
1022
1023 wrapper->contact = ao2_bump(contact);
1024
1025 ao2_link(arg, wrapper);
1026
1027 return 0;
1028}

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_bump, ao2_cleanup, ao2_link, ast_sip_contact::aor, ast_config_AST_SYSTEM_NAME, ast_malloc, ast_strdup, contact_wrapper_destroy(), NULL, RAII_VAR, ast_sip_contact::reg_server, and ast_sip_contact::uri.

Referenced by cli_contact_get_container().

◆ cli_get_aors()

static struct ao2_container * cli_get_aors ( void  )
static

Definition at line 1238 of file location.c.

1239{
1240 struct ao2_container *aors;
1241
1244
1245 return aors;
1246}

References AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_retrieve_by_fields(), and NULL.

Referenced by ami_show_aors().

◆ contact_alloc()

static void * contact_alloc ( const char *  name)
static

Allocator for contact.

Definition at line 120 of file location.c.

121{
122 struct ast_sip_contact *contact = ast_sorcery_generic_alloc(sizeof(*contact), contact_destroy);
123 char *id = ast_strdupa(name);
124 char *aor = id;
125 char *aor_separator = NULL;
126
127 if (!contact) {
128 return NULL;
129 }
130
131 if (ast_string_field_init(contact, 256)) {
132 ao2_cleanup(contact);
133 return NULL;
134 }
135
136 /* Dynamic contacts are delimited with ";@" and static ones with "@@" */
137 if ((aor_separator = strstr(id, ";@")) || (aor_separator = strstr(id, "@@"))) {
138 *aor_separator = '\0';
139 }
140 ast_assert(aor_separator != NULL);
141
142 ast_string_field_set(contact, aor, aor);
143
144 return contact;
145}
enum queue_result id
Definition: app_queue.c:1808
static void contact_destroy(void *obj)
Destructor for contact.
Definition: location.c:111
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728

References ao2_cleanup, ast_sip_contact::aor, ast_assert, ast_sorcery_generic_alloc(), ast_strdupa, ast_string_field_init, ast_string_field_set, contact_destroy(), id, name, and NULL.

Referenced by ast_sip_initialize_sorcery_location().

◆ contact_apply_handler()

static int contact_apply_handler ( const struct ast_sorcery sorcery,
void *  object 
)
static

Always create a contact_status for each contact.

Definition at line 1335 of file location.c.

1336{
1338 struct ast_sip_contact *contact = object;
1339
1340 if (ast_strlen_zero(contact->uri)) {
1341 ast_log(LOG_ERROR, "A URI on dynamic contact '%s' is empty\n",
1342 ast_sorcery_object_get_id(contact));
1343 return -1;
1344 }
1347
1348 return status ? 0 : -1;
1349}
struct ast_sip_contact_status * ast_res_pjsip_find_or_create_contact_status(const struct ast_sip_contact *contact)

References ao2_cleanup, ast_log, ast_res_pjsip_find_or_create_contact_status(), ast_sorcery_object_get_id(), ast_strlen_zero(), LOG_ERROR, status, and ast_sip_contact::uri.

Referenced by ast_sip_initialize_sorcery_location().

◆ contact_destroy()

static void contact_destroy ( void *  obj)
static

Destructor for contact.

Definition at line 111 of file location.c.

112{
113 struct ast_sip_contact *contact = obj;
114
116 ao2_cleanup(contact->endpoint);
117}

References ao2_cleanup, ast_string_field_free_memory, and ast_sip_contact::endpoint.

Referenced by contact_alloc().

◆ contact_expire()

static int contact_expire ( void *  obj,
void *  arg,
int  flags 
)
static

Internal callback function which deletes and unlinks any expired contacts.

Definition at line 153 of file location.c.

154{
155 struct ast_sip_contact *contact = obj;
156
157 /* If the contact has not yet expired it is valid */
158 if (ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) > 0) {
159 return 0;
160 }
161
163
164 return CMP_MATCH;
165}
int ast_sip_location_delete_contact(struct ast_sip_contact *contact)
Delete a contact.
Definition: location.c:451
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ast_sip_location_delete_contact(), ast_tvdiff_ms(), ast_tvnow(), CMP_MATCH, and ast_sip_contact::expiration_time.

Referenced by ast_sip_location_retrieve_aor_contacts_nolock_filtered().

◆ contact_link_static()

static int contact_link_static ( void *  obj,
void *  arg,
int  flags 
)
static

Internal callback function which links static contacts into another container.

Definition at line 168 of file location.c.

169{
170 struct ao2_container *dest = arg;
171
172 ao2_link(dest, obj);
173 return 0;
174}

References ao2_link.

Referenced by ast_sip_location_retrieve_aor_contacts_nolock_filtered().

◆ contact_remove_unreachable()

static int contact_remove_unreachable ( void *  obj,
void *  arg,
int  flags 
)
static

Internal callback function which removes any contact which is unreachable.

Definition at line 177 of file location.c.

178{
179 struct ast_sip_contact *contact = obj;
181 int unreachable;
182
184 if (!status) {
185 return 0;
186 }
187
188 unreachable = (status->status == UNAVAILABLE);
189 ao2_ref(status, -1);
190
191 return unreachable ? CMP_MATCH : 0;
192}
@ UNAVAILABLE
Definition: res_pjsip.h:436

References ao2_ref, ast_sip_get_contact_status(), CMP_MATCH, status, and UNAVAILABLE.

Referenced by ast_sip_location_retrieve_aor_contacts_nolock_filtered().

◆ contact_to_var_list()

static int contact_to_var_list ( void *  object,
void *  arg,
int  flags 
)
static

Definition at line 651 of file location.c.

652{
653 struct ast_sip_contact_wrapper *wrapper = object;
654 struct ast_variable **var = arg;
655
656 ast_variable_list_append(&*var, ast_variable_new("contact", wrapper->contact->uri, ""));
657
658 return 0;
659}
#define var
Definition: ast_expr2f.c:605
#define ast_variable_list_append(head, new_var)

References ast_variable_list_append, ast_variable_new, ast_sip_contact_wrapper::contact, ast_sip_contact::uri, and var.

Referenced by contacts_to_var_list().

◆ contact_wrapper_destroy()

static void contact_wrapper_destroy ( void *  obj)
static

Definition at line 714 of file location.c.

715{
716 struct ast_sip_contact_wrapper *wrapper = obj;
717
718 ast_free(wrapper->aor_id);
719 ast_free(wrapper->contact_id);
720 ao2_cleanup(wrapper->contact);
721}

References ao2_cleanup, ast_sip_contact_wrapper::aor_id, ast_free, ast_sip_contact_wrapper::contact, and ast_sip_contact_wrapper::contact_id.

Referenced by ast_sip_for_each_contact(), and cli_gather_contact().

◆ contacts_to_str()

static int contacts_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 812 of file location.c.

813{
814 const struct ast_sip_aor *aor = obj;
815 struct ast_str *str;
816
818 if (!str) {
819 *buf = NULL;
820 return -1;
821 }
822
825
827 ast_free(str);
828
829 return *buf ? 0 : -1;
830}
const char * str
Definition: app_jack.c:150
int ast_sip_contact_to_str(void *object, void *arg, int flags)
Handler used to convert a contact to a string.
Definition: location.c:771
char * ast_str_truncate(struct ast_str *buf, ssize_t len)
Truncates the enclosed string to the given length.
Definition: strings.h:786
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659

References ast_free, ast_sip_contact_to_str(), ast_sip_for_each_contact(), ast_str_buffer(), ast_str_create, ast_str_truncate(), ast_strdup, buf, MAX_OBJECT_FIELD, NULL, and str.

Referenced by ast_sip_initialize_sorcery_location().

◆ contacts_to_var_list()

static int contacts_to_var_list ( const void *  obj,
struct ast_variable **  fields 
)
static

Definition at line 661 of file location.c.

662{
663 const struct ast_sip_aor *aor = obj;
664
666
667 return 0;
668}
static int contact_to_var_list(void *object, void *arg, int flags)
Definition: location.c:651

References ast_sip_for_each_contact(), and contact_to_var_list().

Referenced by ast_sip_initialize_sorcery_location().

◆ destroy_contact()

static int destroy_contact ( void *  obj,
void *  arg,
int  flags 
)
static

Internal callback function which destroys the specified contact.

Definition at line 72 of file location.c.

73{
74 struct ast_sip_contact *contact = obj;
75
77
78 return CMP_MATCH;
79}

References ast_sip_location_delete_contact(), and CMP_MATCH.

Referenced by aor_deleted_observer().

◆ expiration_str2struct()

static int expiration_str2struct ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Custom handler for translating from a string timeval to actual structure.

Definition at line 483 of file location.c.

484{
485 struct ast_sip_contact *contact = obj;
486 return ast_get_timeval(var->value, &contact->expiration_time, ast_tv(0, 0), NULL);
487}
int ast_get_timeval(const char *src, struct timeval *tv, struct timeval _default, int *consumed)
Parse a time (float) string.
Definition: utils.c:2419
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235

References ast_get_timeval(), ast_tv(), ast_sip_contact::expiration_time, NULL, and var.

Referenced by ast_sip_initialize_sorcery_location().

◆ expiration_struct2str()

static int expiration_struct2str ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Custom handler for translating from an actual structure timeval to string.

Definition at line 490 of file location.c.

491{
492 const struct ast_sip_contact *contact = obj;
493 char secs[AST_TIME_T_LEN];
494
495 ast_time_t_to_string(contact->expiration_time.tv_sec, secs, sizeof(secs));
496 return (ast_asprintf(buf, "%s", secs) < 0) ? -1 : 0;
497}
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
int ast_time_t_to_string(time_t time, char *buf, size_t length)
Converts to a string representation of a time_t as decimal seconds since the epoch....
Definition: time.c:152
#define AST_TIME_T_LEN
Definition: time.h:45

References ast_asprintf, AST_TIME_T_LEN, ast_time_t_to_string(), buf, and ast_sip_contact::expiration_time.

Referenced by ast_sip_initialize_sorcery_location().

◆ format_ami_aor_handler()

static int format_ami_aor_handler ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 832 of file location.c.

833{
834 struct ast_sip_aor *aor = obj;
835 struct ast_sip_ami *ami = arg;
836 const struct ast_sip_endpoint *endpoint = ami->arg;
837 struct ast_str *buf;
838 struct ao2_container *contacts;
839 int total_contacts;
840 int num_permanent;
841
842 buf = ast_sip_create_ami_event("AorDetail", ami);
843 if (!buf) {
844 return -1;
845 }
847 if (!contacts) {
848 ast_free(buf);
849 return -1;
850 }
851
852 sip_aor_to_ami(aor, &buf);
853 total_contacts = ao2_container_count(contacts);
854 num_permanent = aor->permanent_contacts ?
856
857 ast_str_append(&buf, 0, "TotalContacts: %d\r\n", total_contacts);
858 ast_str_append(&buf, 0, "ContactsRegistered: %d\r\n",
859 total_contacts - num_permanent);
860 ast_str_append(&buf, 0, "EndpointName: %s\r\n",
861 ast_sorcery_object_get_id(endpoint));
862
863 astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
864 ami->count++;
865
866 ast_free(buf);
867 ao2_ref(contacts, -1);
868 return 0;
869}
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1907
static int sip_aor_to_ami(const struct ast_sip_aor *aor, struct ast_str **buf)
Definition: location.c:781
struct ast_str * ast_sip_create_ami_event(const char *event, struct ast_sip_ami *ami)
Creates a string to store AMI event data in.
void * arg
Definition: res_pjsip.h:3208
An entity with which Asterisk communicates.
Definition: res_pjsip.h:1051

References ao2_container_count(), ao2_ref, ast_sip_ami::arg, ast_free, ast_sip_create_ami_event(), ast_sip_location_retrieve_aor_contacts(), ast_sorcery_object_get_id(), ast_str_append(), ast_str_buffer(), astman_append(), buf, ast_sip_ami::count, ast_sip_aor::permanent_contacts, ast_sip_ami::s, and sip_aor_to_ami().

Referenced by format_ami_endpoint_aor().

◆ format_ami_aorlist_handler()

static int format_ami_aorlist_handler ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1248 of file location.c.

1249{
1250 struct ast_sip_aor *aor = obj;
1251 struct ast_sip_ami *ami = arg;
1252 struct ast_str *buf;
1253
1254 buf = ast_sip_create_ami_event("AorList", ami);
1255 if (!buf) {
1256 return -1;
1257 }
1258
1259 sip_aor_to_ami(aor, &buf);
1260
1261 astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
1262 ami->count++;
1263
1264 ast_free(buf);
1265
1266 return 0;
1267}

References ast_sip_ami::arg, ast_free, ast_sip_create_ami_event(), ast_str_buffer(), astman_append(), buf, ast_sip_ami::count, ast_sip_ami::s, and sip_aor_to_ami().

Referenced by ami_show_aors().

◆ format_ami_endpoint_aor()

static int format_ami_endpoint_aor ( const struct ast_sip_endpoint endpoint,
struct ast_sip_ami ami 
)
static

Definition at line 871 of file location.c.

873{
874 ami->arg = (void *)endpoint;
875 return ast_sip_for_each_aor(endpoint->aors,
877}
static int format_ami_aor_handler(void *obj, void *arg, int flags)
Definition: location.c:832
const ast_string_field aors
Definition: res_pjsip.h:1080

References ast_sip_endpoint::aors, ast_sip_ami::arg, ast_sip_for_each_aor(), and format_ami_aor_handler().

◆ gather_contacts_for_aor()

static int gather_contacts_for_aor ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 319 of file location.c.

320{
321 struct ao2_container *aor_contacts;
322 struct ast_sip_aor *aor = obj;
323 struct ao2_container *container = arg;
324
325 aor_contacts = ast_sip_location_retrieve_aor_contacts(aor);
326 if (!aor_contacts) {
327 return 0;
328 }
330 container);
331 ao2_ref(aor_contacts, -1);
332 return CMP_MATCH;
333}

References ao2_callback, ao2_ref, ast_sip_location_retrieve_aor_contacts(), cli_contact_populate_container(), CMP_MATCH, container, OBJ_MULTIPLE, and OBJ_NODATA.

Referenced by ast_sip_location_retrieve_contacts_from_aor_list().

◆ permanent_uri_handler()

static int permanent_uri_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Custom handler for permanent URIs.

Definition at line 593 of file location.c.

594{
595 struct ast_sip_aor *aor = obj;
596 const char *aor_id = ast_sorcery_object_get_id(aor);
597 char *contacts;
598 char *contact_uri;
599
600 if (ast_strlen_zero(var->value)) {
601 return 0;
602 }
603
604 contacts = ast_strdupa(var->value);
605 while ((contact_uri = ast_strip(strsep(&contacts, ",")))) {
606 struct ast_sip_contact *contact;
608 char hash[33];
609 char contact_id[strlen(aor_id) + sizeof(hash) + 2];
610
611 if (ast_strlen_zero(contact_uri)) {
612 continue;
613 }
614
615 if (ast_sip_validate_uri_length(contact_uri)) {
616 ast_log(LOG_ERROR, "Contact uri or hostname length exceeds pjproject limit or is not a sip(s) uri: %s\n", contact_uri);
617 return -1;
618 }
619
620 if (!aor->permanent_contacts) {
623 if (!aor->permanent_contacts) {
624 return -1;
625 }
626 }
627
628 ast_md5_hash(hash, contact_uri);
629 snprintf(contact_id, sizeof(contact_id), "%s@@%s", aor_id, hash);
630 contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", contact_id);
631 if (!contact) {
632 return -1;
633 }
634
635 ast_string_field_set(contact, uri, contact_uri);
636
638 if (!status) {
639 ao2_ref(contact, -1);
640 return -1;
641 }
642 ao2_ref(status, -1);
643
644 ao2_link(aor->permanent_contacts, contact);
645 ao2_ref(contact, -1);
646 }
647
648 return 0;
649}
int ast_sip_validate_uri_length(const char *contact_uri)
Definition: location.c:529
const ast_string_field uri
Definition: res_pjsip.h:457
const ast_string_field aor
Definition: res_pjsip.h:457

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, ao2_link, ao2_ref, ast_sip_contact_status::aor, ast_log, ast_md5_hash(), ast_res_pjsip_find_or_create_contact_status(), ast_sip_get_sorcery(), ast_sip_validate_uri_length(), ast_sorcery_alloc(), ast_sorcery_object_get_id(), ast_strdupa, ast_string_field_set, ast_strip(), ast_strlen_zero(), LOG_ERROR, NULL, permanent_uri_sort_fn(), status, strsep(), ast_sip_contact_status::uri, and var.

Referenced by ast_sip_initialize_sorcery_location().

◆ permanent_uri_sort_fn()

static int permanent_uri_sort_fn ( const void *  obj_left,
const void *  obj_right,
int  flags 
)
static

Definition at line 499 of file location.c.

500{
501 const struct ast_sip_contact *object_left = obj_left;
502 const struct ast_sip_contact *object_right = obj_right;
503 const char *right_key = obj_right;
504 int cmp;
505
506 switch (flags & OBJ_SEARCH_MASK) {
508 right_key = ast_sorcery_object_get_id(object_right);
509 /* Fall through */
510 case OBJ_SEARCH_KEY:
511 cmp = strcmp(ast_sorcery_object_get_id(object_left), right_key);
512 break;
514 /*
515 * We could also use a partial key struct containing a length
516 * so strlen() does not get called for every comparison instead.
517 */
518 cmp = strncmp(ast_sorcery_object_get_id(object_left), right_key, strlen(right_key));
519 break;
520 default:
521 /* Sort can only work on something with a full or partial key. */
522 ast_assert(0);
523 cmp = 0;
524 break;
525 }
526 return cmp;
527}

References ast_assert, ast_sorcery_object_get_id(), OBJ_SEARCH_KEY, OBJ_SEARCH_MASK, OBJ_SEARCH_OBJECT, and OBJ_SEARCH_PARTIAL_KEY.

Referenced by ast_sip_location_retrieve_contacts_from_aor_list(), and permanent_uri_handler().

◆ prune_boot_contacts_cb()

static int prune_boot_contacts_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 456 of file location.c.

457{
458 struct ast_sip_contact *contact = obj;
459
460 if (contact->prune_on_boot
461 && !strcmp(contact->reg_server, ast_config_AST_SYSTEM_NAME ?: "")) {
462 ast_verb(3, "Removed contact '%s' from AOR '%s' due to system boot\n",
463 contact->uri, contact->aor);
465 }
466
467 return 0;
468}
#define ast_verb(level,...)

References ast_sip_contact::aor, ast_config_AST_SYSTEM_NAME, ast_sip_location_delete_contact(), ast_verb, ast_sip_contact::prune_on_boot, ast_sip_contact::reg_server, and ast_sip_contact::uri.

Referenced by ast_sip_location_prune_boot_contacts().

◆ sip_aor_to_ami()

static int sip_aor_to_ami ( const struct ast_sip_aor aor,
struct ast_str **  buf 
)
static

Definition at line 781 of file location.c.

782{
783 struct ast_variable *objset;
784 struct ast_variable *i;
785
788 if (!objset) {
789 return -1;
790 }
791
792 ast_str_append(buf, 0, "ObjectType: %s\r\n",
794 ast_str_append(buf, 0, "ObjectName: %s\r\n",
796
797 for (i = objset; i; i = i->next) {
798 char *camel = ast_to_camel_case(i->name);
799
800 if (strcmp(camel, "Contact") == 0) {
801 ast_free(camel);
802 camel = NULL;
803 }
804 ast_str_append(buf, 0, "%s: %s\r\n", S_OR(camel, "Contacts"), i->value);
805 ast_free(camel);
806 }
807
808 ast_variables_destroy(objset);
809 return 0;
810}
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition: sorcery.c:2329
@ AST_HANDLER_ONLY_STRING
Use string handler only.
Definition: sorcery.h:137
struct ast_variable * ast_sorcery_objectset_create2(const struct ast_sorcery *sorcery, const void *object, enum ast_sorcery_field_handler_flags flags)
Create an object set (KVP list) for an object.
Definition: sorcery.c:1511
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
#define ast_to_camel_case(s)
Attempts to convert the given string to camel case using an underscore as the specified delimiter.
Definition: strings.h:546
struct ast_variable * next

References ast_free, AST_HANDLER_ONLY_STRING, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_object_get_type(), ast_sorcery_objectset_create2(), ast_str_append(), ast_to_camel_case, ast_variables_destroy(), buf, ast_variable::name, ast_variable::next, NULL, S_OR, and ast_variable::value.

Referenced by format_ami_aor_handler(), and format_ami_aorlist_handler().

◆ voicemail_extension_handler()

static int voicemail_extension_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 670 of file location.c.

671{
672 struct ast_sip_aor *aor = obj;
673
674 aor->voicemail_extension = ast_strdup(var->value);
675
676 return aor->voicemail_extension ? 0 : -1;
677}

References ast_strdup, var, and ast_sip_aor::voicemail_extension.

Referenced by ast_sip_initialize_sorcery_location().

◆ voicemail_extension_to_str()

static int voicemail_extension_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 679 of file location.c.

680{
681 const struct ast_sip_aor *aor = obj;
682
684
685 return 0;
686}

References ast_strdup, buf, and ast_sip_aor::voicemail_extension.

Referenced by ast_sip_initialize_sorcery_location().

Variable Documentation

◆ aor_formatter

struct ast_sip_cli_formatter_entry* aor_formatter

◆ aor_observer

const struct ast_sorcery_observer aor_observer
static
Initial value:
= {
}
static void aor_deleted_observer(const void *object)
Definition: location.c:81

Observer for contacts so state can be updated on respective endpoints.

Definition at line 105 of file location.c.

Referenced by ast_sip_destroy_sorcery_location(), and ast_sip_initialize_sorcery_location().

◆ cli_commands

struct ast_cli_entry cli_commands[]
static

◆ contact_formatter

struct ast_sip_cli_formatter_entry* contact_formatter

◆ endpoint_aor_formatter

struct ast_sip_endpoint_formatter endpoint_aor_formatter
Initial value:
= {
}
static int format_ami_endpoint_aor(const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)
Definition: location.c:871

Definition at line 879 of file location.c.

Referenced by ast_sip_destroy_sorcery_location(), and ast_sip_initialize_sorcery_location().

◆ pj_max_hostname

int pj_max_hostname = PJ_MAX_HOSTNAME
static

Definition at line 36 of file location.c.

Referenced by ast_sip_initialize_sorcery_location(), and ast_sip_validate_uri_length().

◆ pjsip_max_url_size

int pjsip_max_url_size = PJSIP_MAX_URL_SIZE
static

Definition at line 37 of file location.c.

Referenced by ast_sip_initialize_sorcery_location(), and ast_sip_validate_uri_length().