Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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 1263 of file location.c.

1264 {
1265  struct ast_sip_ami ami = { .s = s, .m = m, .action_id = astman_get_header(m, "ActionID"), };
1266  struct ao2_container *aors;
1267 
1268  aors = cli_get_aors();
1269  if (!aors) {
1270  astman_send_error(s, m, "Could not get AORs\n");
1271  return 0;
1272  }
1273 
1274  if (!ao2_container_count(aors)) {
1275  astman_send_error(s, m, "No AORs found\n");
1276  ao2_ref(aors, -1);
1277  return 0;
1278  }
1279 
1280  astman_send_listack(s, m, "A listing of AORs follows, presented as AorList events",
1281  "start");
1282 
1284 
1285  astman_send_list_complete_start(s, m, "AorListComplete", ami.count);
1287 
1288  ao2_ref(aors, -1);
1289 
1290  return 0;
1291 }
#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:3208
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3166
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:3244
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3252
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:2827
static struct ao2_container * cli_get_aors(void)
Definition: location.c:1232
static int format_ami_aorlist_handler(void *obj, void *arg, int flags)
Definition: location.c:1242
Generic container type.
AMI variable container.
Definition: res_pjsip.h:2819
struct mansession * s
Definition: res_pjsip.h:2821
const struct message * m
Definition: res_pjsip.h:2823

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_meetme.c:1093
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:376

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 1355 of file location.c.

1356 {
1357  struct ast_sip_aor *aor = object;
1358 
1359  if (!aor->permanent_contacts || ast_strlen_zero(aor->outbound_proxy)) {
1360  return 0;
1361  }
1362 
1364 
1365  return 0;
1366 }
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
static int aor_apply_outbound_proxy(void *obj, void *arg, int flags)
Definition: location.c:1345
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:400
const ast_string_field outbound_proxy
Definition: res_pjsip.h:384

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 1345 of file location.c.

1346 {
1347  struct ast_sip_contact *contact = obj;
1348  struct ast_sip_aor *aor = arg;
1349 
1351 
1352  return 0;
1353 }
#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:297

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.
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:1984
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312

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:406

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 770 of file location.c.

771 {
772  struct ast_sip_contact_wrapper *wrapper = object;
773  struct ast_str **buf = arg;
774 
775  ast_str_append(buf, 0, "%s,", wrapper->contact_id);
776 
777  return 0;
778 }
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:1117
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:415
Support for dynamic strings.
Definition: strings.h:604

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 1471 of file location.c.

1472 {
1477  ast_manager_unregister("PJSIPShowAors");
1478 
1480 
1481  return 0;
1482 }
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:7268
static struct ast_cli_entry cli_commands[]
Definition: location.c:1293
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:1325
struct ast_sip_cli_formatter_entry * aor_formatter
Definition: location.c:1326
struct ast_sip_endpoint_formatter endpoint_aor_formatter
Definition: location.c:878
void ast_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Unregister an endpoint formatter.
Definition: res_pjsip.c:480
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:2418
#define ARRAY_LEN(a)
Definition: utils.h:661

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 687 of file location.c.

688 {
689  char *copy;
690  char *name;
691  int res;
692 
693  if (!on_aor || ast_strlen_zero(aors)) {
694  return 0;
695  }
696 
697  copy = ast_strdupa(aors);
698  while ((name = ast_strip(strsep(&copy, ",")))) {
699  struct ast_sip_aor *aor;
700 
702  if (aor) {
703  res = on_aor(aor, arg, 0);
704  ao2_ref(aor, -1);
705  if (res) {
706  return -1;
707  }
708  }
709  }
710  return 0;
711 }
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * strsep(char **str, const char *delims)
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_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 722 of file location.c.

724 {
725  struct ao2_container *contacts;
726  struct ao2_iterator i;
727  int res = 0;
728  void *object = NULL;
729 
730  if (!on_contact ||
731  !(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
732  return 0;
733  }
734 
735  i = ao2_iterator_init(contacts, 0);
736  while ((object = ao2_iterator_next(&i))) {
737  RAII_VAR(struct ast_sip_contact *, contact, object, ao2_cleanup);
738  RAII_VAR(struct ast_sip_contact_wrapper *, wrapper, NULL, ao2_cleanup);
739  const char *aor_id = ast_sorcery_object_get_id(aor);
740 
741  wrapper = ao2_alloc_options(sizeof(struct ast_sip_contact_wrapper),
743  if (!wrapper) {
744  res = -1;
745  break;
746  }
747  wrapper->contact_id = ast_malloc(strlen(aor_id) + strlen(contact->uri) + 2);
748  if (!wrapper->contact_id) {
749  res = -1;
750  break;
751  }
752  sprintf(wrapper->contact_id, "%s/%s", aor_id, contact->uri);
753  wrapper->aor_id = ast_strdup(aor_id);
754  if (!wrapper->aor_id) {
755  res = -1;
756  break;
757  }
758  wrapper->contact = contact;
759  ao2_bump(wrapper->contact);
760 
761  if ((res = on_contact(wrapper, arg, 0))) {
762  break;
763  }
764  }
766  ao2_ref(contacts, -1);
767  return res;
768 }
#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:713
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:936

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 1369 of file location.c.

1370 {
1372  int i;
1373 
1374  ast_pjproject_get_buildopt("PJ_MAX_HOSTNAME", "%d", &pj_max_hostname);
1375  /* As of pjproject 2.4.5, PJSIP_MAX_URL_SIZE isn't exposed yet but we try anyway. */
1376  ast_pjproject_get_buildopt("PJSIP_MAX_URL_SIZE", "%d", &pjsip_max_url_size);
1377 
1378  ast_sorcery_apply_default(sorcery, "contact", "astdb", "registrar");
1381  ast_sorcery_apply_default(sorcery, "aor", "config", "pjsip.conf,criteria=type=aor");
1382 
1385  return -1;
1386  }
1387 
1389 
1390  ast_sorcery_object_field_register(sorcery, "contact", "type", "", OPT_NOOP_T, 0, 0);
1391  ast_sorcery_object_field_register(sorcery, "contact", "uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, uri));
1392  ast_sorcery_object_field_register(sorcery, "contact", "path", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, path));
1394  ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
1395  PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
1396  ast_sorcery_object_field_register(sorcery, "contact", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_contact, qualify_timeout));
1397  ast_sorcery_object_field_register(sorcery, "contact", "authenticate_qualify", "no", OPT_YESNO_T, 1, FLDSET(struct ast_sip_contact, authenticate_qualify));
1398  ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
1399  ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent));
1400  ast_sorcery_object_field_register(sorcery, "contact", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, endpoint_name));
1401  ast_sorcery_object_field_register(sorcery, "contact", "reg_server", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, reg_server));
1402  ast_sorcery_object_field_register(sorcery, "contact", "via_addr", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, via_addr));
1403  ast_sorcery_object_field_register(sorcery, "contact", "via_port", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_contact, via_port));
1404  ast_sorcery_object_field_register(sorcery, "contact", "call_id", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, call_id));
1405  ast_sorcery_object_field_register(sorcery, "contact", "prune_on_boot", "no", OPT_YESNO_T, 1, FLDSET(struct ast_sip_contact, prune_on_boot));
1406 
1407  ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0);
1408  ast_sorcery_object_field_register(sorcery, "aor", "minimum_expiration", "60", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, minimum_expiration));
1409  ast_sorcery_object_field_register(sorcery, "aor", "maximum_expiration", "7200", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, maximum_expiration));
1410  ast_sorcery_object_field_register(sorcery, "aor", "default_expiration", "3600", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, default_expiration));
1411  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);
1412  ast_sorcery_object_field_register(sorcery, "aor", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_aor, qualify_timeout));
1413  ast_sorcery_object_field_register(sorcery, "aor", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, authenticate_qualify));
1414  ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
1415  ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
1416  ast_sorcery_object_field_register(sorcery, "aor", "remove_unavailable", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_unavailable));
1420  ast_sorcery_object_field_register(sorcery, "aor", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, outbound_proxy));
1421  ast_sorcery_object_field_register(sorcery, "aor", "support_path", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, support_path));
1422 
1424 
1426  if (!contact_formatter) {
1427  ast_log(LOG_ERROR, "Unable to allocate memory for contact_formatter\n");
1428  return -1;
1429  }
1430  contact_formatter->name = "contact";
1437 
1439  if (!aor_formatter) {
1440  ast_log(LOG_ERROR, "Unable to allocate memory for aor_formatter\n");
1441  return -1;
1442  }
1443  aor_formatter->name = "aor";
1450 
1454 
1455  if (ast_manager_register_xml("PJSIPShowAors", EVENT_FLAG_SYSTEM, ami_show_aors)) {
1456  return -1;
1457  }
1458 
1459  /*
1460  * Reset StatsD gauges in case we didn't shut down cleanly.
1461  * Note that this must done here, as contacts will create the contact_status
1462  * object before PJSIP options handling is initialized.
1463  */
1464  for (i = 0; i <= REMOVED; i++) {
1465  ast_statsd_log_full_va("PJSIP.contacts.states.%s", AST_STATSD_GAUGE, 0, 1.0, ast_sip_get_contact_status_label(i));
1466  }
1467 
1468  return 0;
1469 }
#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:1329
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:482
static struct ao2_container * cli_aor_get_container(const char *regex)
Definition: location.c:882
static void * aor_alloc(const char *name)
Allocator for AOR.
Definition: location.c:50
static int cli_aor_print_body(void *obj, void *arg, int flags)
Definition: location.c:1186
static int contacts_to_var_list(const void *obj, struct ast_variable **fields)
Definition: location.c:660
static void * contact_alloc(const char *name)
Allocator for contact.
Definition: location.c:120
static struct ao2_container * cli_contact_get_container(const char *regex)
Definition: location.c:1029
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:979
static int voicemail_extension_to_str(const void *obj, const intptr_t *args, char **buf)
Definition: location.c:678
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:489
static const char * cli_aor_get_id(const void *obj)
Definition: location.c:1154
static int permanent_uri_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for permanent URIs.
Definition: location.c:592
static int voicemail_extension_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: location.c:669
static int contacts_to_str(const void *obj, const intptr_t *args, char **buf)
Definition: location.c:811
static int pj_max_hostname
Definition: location.c:36
static void * cli_contact_retrieve_by_id(const char *id)
Definition: location.c:1079
static int cli_aor_print_header(void *obj, void *arg, int flags)
Definition: location.c:1159
static int cli_contact_print_header(void *obj, void *arg, int flags)
Definition: location.c:1094
static int aor_apply_handler(const struct ast_sorcery *sorcery, void *object)
Definition: location.c:1355
static int cli_contact_print_body(void *obj, void *arg, int flags)
Definition: location.c:1109
static const char * cli_contact_get_id(const void *obj)
Definition: location.c:919
static void * cli_aor_retrieve_by_id(const char *id)
Definition: location.c:1149
static int cli_aor_iterate(void *container, ao2_callback_fn callback, void *args)
Definition: location.c:1142
static int ami_show_aors(struct mansession *s, const struct message *m)
Definition: location.c:1263
#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:191
static int default_expiration
Definition: pbx_dundi.c:199
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.
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.
void ast_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Register an endpoint formatter.
Definition: res_pjsip.c:474
@ REMOVED
Definition: res_pjsip.h:348
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:2386
#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:209
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
const char *(* get_id)(const void *obj)
Definition: res_pjsip_cli.h:70
struct ao2_container *(* get_container)(const char *regex)
Definition: res_pjsip_cli.h:64
void *(* retrieve_by_id)(const char *id)
Definition: res_pjsip_cli.h:68
const char * name
Definition: res_pjsip_cli.h:58
ao2_callback_fn * print_body
Definition: res_pjsip_cli.h:62
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 429 of file location.c.

433 {
434  int res;
435 
436  ao2_lock(aor);
437  res = ast_sip_location_add_contact_nolock(aor, uri, expiration_time, path_info, user_agent,
438  via_addr, via_port, call_id,
439  endpoint);
440  ao2_unlock(aor);
441 
442  return res;
443 }
#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:416

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 416 of file location.c.

420 {
421  struct ast_sip_contact *contact;
422 
426  return contact ? 0 : -1;
427 }
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:319
struct ast_sip_endpoint * endpoint
Definition: res_pjsip.h:329
const ast_string_field via_addr
Definition: res_pjsip.h:319
const ast_string_field call_id
Definition: res_pjsip.h:319
const ast_string_field aor
Definition: res_pjsip.h:319
struct timeval expiration_time
Definition: res_pjsip.h:321
const ast_string_field user_agent
Definition: res_pjsip.h:319

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 
368  if (!contact) {
369  return NULL;
370  }
371 
373  contact->expiration_time = expiration_time;
374  contact->qualify_frequency = aor->qualify_frequency;
375  contact->qualify_timeout = aor->qualify_timeout;
376  contact->authenticate_qualify = aor->authenticate_qualify;
377  if (path_info && aor->support_path) {
378  ast_string_field_set(contact, path, path_info);
379  }
380 
381  if (!ast_strlen_zero(aor->outbound_proxy)) {
382  ast_string_field_set(contact, outbound_proxy, aor->outbound_proxy);
383  }
384 
385  if (!ast_strlen_zero(user_agent)) {
387  }
388 
391  }
392 
393  if (!ast_strlen_zero(via_addr)) {
395  }
396  contact->via_port = via_port;
397 
398  if (!ast_strlen_zero(call_id)) {
400  }
401 
402  contact->endpoint = ao2_bump(endpoint);
403  if (endpoint) {
405  }
406 
407  contact->prune_on_boot = prune_on_boot;
408 
410  ao2_ref(contact, -1);
411  return NULL;
412  }
413  return contact;
414 }
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:2057
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
Definition: sorcery.h:110
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
const ast_string_field outbound_proxy
Definition: res_pjsip.h:319
const ast_string_field path
Definition: res_pjsip.h:319
const ast_string_field endpoint_name
Definition: res_pjsip.h:319
const ast_string_field reg_server
Definition: res_pjsip.h:319
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
Definition: main/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::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::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 450 of file location.c.

451 {
453 }
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
Definition: sorcery.c:2233

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 469 of file location.c.

470 {
471  struct ao2_container *contacts;
472 
473  contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "contact",
475  if (contacts) {
477  ao2_ref(contacts, -1);
478  }
479 }
static int prune_boot_contacts_cb(void *obj, void *arg, int flags)
Definition: location.c:455
@ 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 ast_res_pjsip_initialize_configuration().

◆ 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_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:1086

References AST_SIP_CONTACT_FILTER_DEFAULT, and ast_sip_location_retrieve_aor_contacts_filtered().

Referenced by ast_sip_for_each_contact(), format_ami_aor_handler(), gather_contacts_for_aor(), notify_endpoint(), 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 
240  if (flags & AST_SIP_CONTACT_FILTER_REACHABLE) {
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:1089

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 
311  ao2_cleanup(aor);
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 
345  ast_sip_for_each_aor(aor_list, gather_contacts_for_aor, contacts);
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:687
static int permanent_uri_sort_fn(const void *obj_left, const void *obj_right, int flags)
Definition: location.c:498
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().

◆ 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 445 of file location.c.

446 {
448 }
int ast_sorcery_update(const struct ast_sorcery *sorcery, void *object)
Update an object.
Definition: sorcery.c:2145

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 528 of file location.c.

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

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 912 of file location.c.

913 {
914  struct ast_sip_aor *aor = obj;
915 
917 }
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:722
static int cli_contact_populate_container(void *obj, void *arg, int flags)
Definition: location.c:905

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 882 of file location.c.

883 {
884  struct ao2_container *container;
885  struct ao2_container *s_container;
886 
888  if (!container) {
889  return NULL;
890  }
891 
892  /* Create a sorted container of aors. */
895  if (s_container
896  && ao2_container_dup(s_container, container, 0)) {
897  ao2_ref(s_container, -1);
898  s_container = NULL;
899  }
900  ao2_ref(container, -1);
901 
902  return s_container;
903 }
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:501
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:1949
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition: sorcery.c:2459
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition: sorcery.c:2435

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 1154 of file location.c.

1155 {
1156  return ast_sorcery_object_get_id(obj);
1157 }

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 1142 of file location.c.

1143 {
1144  const char *aor_list = container;
1145 
1146  return ast_sip_for_each_aor(aor_list, callback, args);
1147 }
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 1186 of file location.c.

1187 {
1188  struct ast_sip_aor *aor = obj;
1189  struct ast_sip_cli_context *context = arg;
1190  int indent;
1191  int flexwidth;
1192 
1193  ast_assert(context->output_buffer != NULL);
1194 
1195 // context->current_aor = aor;
1196 
1197  indent = CLI_INDENT_TO_SPACES(context->indent_level);
1198  flexwidth = CLI_LAST_TABSTOP - indent - 12;
1199 
1200  ast_str_append(&context->output_buffer, 0, "%*s: %-*.*s %12u\n",
1201  indent,
1202  "Aor",
1203  flexwidth, flexwidth,
1205 
1206  if (context->recurse) {
1207  struct ast_sip_cli_formatter_entry *formatter_entry;
1208 
1209  context->indent_level++;
1210 
1211  formatter_entry = ast_sip_lookup_cli_formatter("contact");
1212  if (formatter_entry) {
1213  formatter_entry->iterate(aor, formatter_entry->print_body, context);
1214  ao2_ref(formatter_entry, -1);
1215  }
1216 
1217  context->indent_level--;
1218 
1219  if (context->indent_level == 0) {
1220  ast_str_append(&context->output_buffer, 0, "\n");
1221  }
1222  }
1223 
1224  if (context->show_details || (context->show_details_only_level_0 && context->indent_level == 0)) {
1225  ast_str_append(&context->output_buffer, 0, "\n");
1227  }
1228 
1229  return 0;
1230 }
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120
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
#define CLI_LAST_TABSTOP
Definition: res_pjsip_cli.h:27
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_INDENT_TO_SPACES(x)
Definition: res_pjsip_cli.h:29
unsigned int max_contacts
Definition: res_pjsip.h:396
CLI Formatter Context passed to all formatters.
Definition: res_pjsip_cli.h:34
#define ast_assert(a)
Definition: utils.h:734

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, 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 1159 of file location.c.

1160 {
1161  struct ast_sip_cli_context *context = arg;
1162  int indent = CLI_INDENT_TO_SPACES(context->indent_level);
1163  int filler = CLI_LAST_TABSTOP - indent - 7;
1164 
1165  ast_assert(context->output_buffer != NULL);
1166 
1167  ast_str_append(&context->output_buffer, 0,
1168  "%*s: <Aor%*.*s> <MaxContact>\n",
1169  indent, "Aor", filler, filler, CLI_HEADER_FILLER);
1170 
1171  if (context->recurse) {
1172  struct ast_sip_cli_formatter_entry *formatter_entry;
1173 
1174  context->indent_level++;
1175  formatter_entry = ast_sip_lookup_cli_formatter("contact");
1176  if (formatter_entry) {
1177  formatter_entry->print_header(NULL, context, 0);
1178  ao2_ref(formatter_entry, -1);
1179  }
1180  context->indent_level--;
1181  }
1182 
1183  return 0;
1184 }
#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, 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 1149 of file location.c.

1150 {
1151  return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", id);
1152 }

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 950 of file location.c.

951 {
952  const struct ast_sip_contact_wrapper *left_wrapper = obj;
953  const struct ast_sip_contact_wrapper *right_wrapper = arg;
954  const char *right_key = arg;
955  int cmp = 0;
956 
957  switch (flags & OBJ_SEARCH_MASK) {
958  case OBJ_SEARCH_OBJECT:
959  right_key = right_wrapper->contact_id;
960  /* Fall through */
961  case OBJ_SEARCH_KEY:
962  if (strcmp(left_wrapper->contact_id, right_key) == 0) {;
963  cmp = CMP_MATCH | CMP_STOP;
964  }
965  break;
967  if (strncmp(left_wrapper->contact_id, right_key, strlen(right_key)) == 0) {
968  cmp = CMP_MATCH;
969  }
970  break;
971  default:
972  cmp = 0;
973  break;
974  }
975 
976  return cmp;
977 }
@ 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 1029 of file location.c.

1030 {
1031  RAII_VAR(struct ao2_container *, aors, NULL, ao2_cleanup);
1032  RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
1033  RAII_VAR(struct ast_variable *, var_aor, NULL, ast_variables_destroy);
1034  struct ao2_container *contacts_container;
1035  regex_t regexbuf;
1036 
1037  if (!(var_aor = ast_variable_new("contact !=", "", ""))) {
1038  return NULL;
1039  }
1040 
1041  /* Retrieving all the contacts may result in finding the same contact multiple
1042  * times. So that they don't get displayed multiple times we only allow a
1043  * single one to be placed into the container.
1044  */
1047  if (!contacts_container) {
1048  return NULL;
1049  }
1050 
1051  contacts = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "contact", regex);
1052  if (!contacts) {
1053  ao2_ref(contacts_container, -1);
1054  return NULL;
1055  }
1056  ao2_callback(contacts, OBJ_NODATA, cli_gather_contact, contacts_container);
1057 
1059  "aor", AST_RETRIEVE_FLAG_MULTIPLE, var_aor);
1060  if (!aors) {
1061  ao2_ref(contacts_container, -1);
1062  return NULL;
1063  }
1064 
1065  ao2_callback(aors, OBJ_NODATA, cli_aor_gather_contacts, contacts_container);
1066 
1067  if (!ast_strlen_zero(regex)) {
1068  if (regcomp(&regexbuf, regex, REG_EXTENDED | REG_NOSUB)) {
1069  ao2_ref(contacts_container, -1);
1070  return NULL;
1071  }
1072  ao2_callback(contacts_container, OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA, cli_filter_contacts, &regexbuf);
1073  regfree(&regexbuf);
1074  }
1075 
1076  return contacts_container;
1077 }
#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:984
static int cli_gather_contact(void *obj, void *arg, int flags)
Definition: location.c:996
static int cli_contact_compare(void *obj, void *arg, int flags)
Definition: location.c:950
static int cli_contact_sort(const void *obj, const void *arg, int flags)
Definition: location.c:925
static int cli_aor_gather_contacts(void *obj, void *arg, int flags)
Definition: location.c:912
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 919 of file location.c.

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

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 979 of file location.c.

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

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 905 of file location.c.

906 {
907  ao2_link(arg, obj);
908 
909  return 0;
910 }
#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 1109 of file location.c.

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

References ao2_cleanup, ast_assert, 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, context, NAN, NULL, status, and UNKNOWN.

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 1094 of file location.c.

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

References ast_assert, ast_str_append(), CLI_HEADER_FILLER, CLI_INDENT_TO_SPACES, CLI_LAST_TABSTOP, 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 1079 of file location.c.

1080 {
1081  struct ao2_container *container;
1082  void *obj;
1083 
1085  if (!container) {
1086  return NULL;
1087  }
1088 
1089  obj = ao2_find(container, id, OBJ_SEARCH_KEY);
1090  ao2_ref(container, -1);
1091  return obj;
1092 }
#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 925 of file location.c.

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

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 984 of file location.c.

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

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 996 of file location.c.

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

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_bump, ao2_cleanup, ao2_link, ast_config_AST_SYSTEM_NAME, ast_malloc, ast_strdup, contact_wrapper_destroy(), NULL, and RAII_VAR.

Referenced by cli_contact_get_container().

◆ cli_get_aors()

static struct ao2_container* cli_get_aors ( void  )
static

Definition at line 1232 of file location.c.

1233 {
1234  struct ao2_container *aors;
1235 
1238 
1239  return aors;
1240 }

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 {
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)) {
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 
143 
144  return contact;
145 }
enum queue_result id
Definition: app_queue.c:1640
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 1329 of file location.c.

1330 {
1332  struct ast_sip_contact *contact = object;
1333 
1334  if (ast_strlen_zero(contact->uri)) {
1335  ast_log(LOG_ERROR, "A URI on dynamic contact '%s' is empty\n",
1337  return -1;
1338  }
1341 
1342  return status ? 0 : -1;
1343 }
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, and status.

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, and ast_string_field_free_memory.

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:450
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:105
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:157

References ast_sip_location_delete_contact(), ast_tvdiff_ms(), ast_tvnow(), and CMP_MATCH.

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:341

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 650 of file location.c.

651 {
652  struct ast_sip_contact_wrapper *wrapper = object;
653  struct ast_variable **var = arg;
654 
655  ast_variable_list_append(&*var, ast_variable_new("contact", wrapper->contact->uri, ""));
656 
657  return 0;
658 }
#define var
Definition: ast_expr2f.c:614
#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 713 of file location.c.

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

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 811 of file location.c.

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

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 660 of file location.c.

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

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 482 of file location.c.

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

References ast_get_timeval(), ast_tv(), 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 489 of file location.c.

490 {
491  const struct ast_sip_contact *contact = obj;
492  char secs[AST_TIME_T_LEN];
493 
494  ast_time_t_to_string(contact->expiration_time.tv_sec, secs, sizeof(secs));
495  return (ast_asprintf(buf, "%s", secs) < 0) ? -1 : 0;
496 }
#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:43

References ast_asprintf, AST_TIME_T_LEN, ast_time_t_to_string(), and buf.

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 831 of file location.c.

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

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().

◆ format_ami_aorlist_handler()

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

Definition at line 1242 of file location.c.

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

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 870 of file location.c.

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

◆ 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 592 of file location.c.

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

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 498 of file location.c.

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

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 455 of file location.c.

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

References ast_config_AST_SYSTEM_NAME, ast_sip_location_delete_contact(), and ast_verb.

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 780 of file location.c.

781 {
782  struct ast_variable *objset;
783  struct ast_variable *i;
784 
787  if (!objset) {
788  return -1;
789  }
790 
791  ast_str_append(buf, 0, "ObjectType: %s\r\n",
793  ast_str_append(buf, 0, "ObjectName: %s\r\n",
795 
796  for (i = objset; i; i = i->next) {
797  char *camel = ast_to_camel_case(i->name);
798 
799  if (strcmp(camel, "Contact") == 0) {
800  ast_free(camel);
801  camel = NULL;
802  }
803  ast_str_append(buf, 0, "%s: %s\r\n", S_OR(camel, "Contacts"), i->value);
804  ast_free(camel);
805  }
806 
807  ast_variables_destroy(objset);
808  return 0;
809 }
@ AST_HANDLER_ONLY_STRING
Use string handler only.
Definition: sorcery.h:137
const char * ast_sorcery_object_get_type(const void *object)
Get the type of a sorcery object.
Definition: sorcery.c:2324
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:527
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 669 of file location.c.

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

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 678 of file location.c.

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

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 81 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:870

Definition at line 870 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().